Exemplo n.º 1
0
//---------------------------------------------------------------------------------
bool tx_memory_pool::fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, uint64_t already_donated_coins, size_t &total_size, uint64_t &fee) {
    typedef transactions_container::value_type txv;
    CRITICAL_REGION_LOCAL(m_transactions_lock);

    std::vector<txv *> txs(m_transactions.size());
    std::transform(m_transactions.begin(), m_transactions.end(), txs.begin(), [](txv &a) -> txv * { return &a; });
    std::sort(txs.begin(), txs.end(), [](txv *a, txv *b) -> bool {
        uint64_t a_hi, a_lo = mul128(a->second.fee, b->second.blob_size, &a_hi);
        uint64_t b_hi, b_lo = mul128(b->second.fee, a->second.blob_size, &b_hi);
        return a_hi > b_hi || (a_hi == b_hi && a_lo > b_lo);
    });

    size_t current_size = 0;
    uint64_t current_fee = 0;
    uint64_t best_money;
    uint64_t max_donation = 0;
    if (!get_block_reward(median_size, CURRENCY_COINBASE_BLOB_RESERVED_SIZE, already_generated_coins, already_donated_coins, best_money, max_donation)) {
        LOG_ERROR("Block with just a miner transaction is already too large!");
        return false;
    }
    size_t best_position = 0;
    total_size = 0;
    fee = 0;

    std::unordered_set<crypto::key_image> k_images;

    for (size_t i = 0; i < txs.size(); i++) {
        txv &tx(*txs[i]);

        if(!is_transaction_ready_to_go(tx.second) || have_key_images(k_images, tx.second.tx)) {
            txs[i] = NULL;
            continue;
        }
        append_key_images(k_images, tx.second.tx);

        current_size += tx.second.blob_size;
        current_fee += tx.second.fee;

        uint64_t current_reward;
        if (!get_block_reward(median_size, current_size + CURRENCY_COINBASE_BLOB_RESERVED_SIZE, already_generated_coins, already_donated_coins, current_reward, max_donation)) {
            break;
        }

        if (best_money < current_reward + current_fee) {
            best_money = current_reward + current_fee;
            best_position = i + 1;
            total_size = current_size;
            fee = current_fee;
        }
    }

    for (size_t i = 0; i < best_position; i++) {
        if (txs[i]) {
            bl.tx_hashes.push_back(txs[i]->first);
        }
    }

    return true;
}
Exemplo n.º 2
0
  //---------------------------------------------------------------------------------
  bool tx_memory_pool::fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee)
  {
    // Warning: This function takes already_generated_
    // coins as an argument and appears to do nothing
    // with it.

    CRITICAL_REGION_LOCAL(m_transactions_lock);

    total_size = 0;
    fee = 0;

    // Maximum block size is 130% of the median block size.  This gives a
    // little extra headroom for the max size transaction.
    size_t max_total_size = (130 * median_size) / 100 - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
    std::unordered_set<crypto::key_image> k_images;

    auto sorted_it = m_txs_by_fee.begin();
    while (sorted_it != m_txs_by_fee.end())
    {
      auto tx_it = m_transactions.find(sorted_it->second);

      // Can not exceed maximum block size
      if (max_total_size < total_size + tx_it->second.blob_size)
      {
        sorted_it++;
        continue;
      }

      // If adding this tx will make the block size
      // greater than CRYPTONOTE_GETBLOCKTEMPLATE_MAX
      // _BLOCK_SIZE bytes, reject the tx; this will 
      // keep block sizes from becoming too unwieldly
      // to propagate at 60s block times.
      if ( (total_size + tx_it->second.blob_size) > CRYPTONOTE_GETBLOCKTEMPLATE_MAX_BLOCK_SIZE )
      {
        sorted_it++;
        continue;
      }

      // If we've exceeded the penalty free size,
      // stop including more tx
      if (total_size > median_size)
        break;      

      // Skip transactions that are not ready to be
      // included into the blockchain or that are
      // missing key images
      if (!is_transaction_ready_to_go(tx_it->second) || have_key_images(k_images, tx_it->second.tx))
      {
        sorted_it++;
        continue;
      }

      bl.tx_hashes.push_back(tx_it->first);
      total_size += tx_it->second.blob_size;
      fee += tx_it->second.fee;
      append_key_images(k_images, tx_it->second.tx);
      sorted_it++;
    }

    return true;
  }
Exemplo n.º 3
0
  //---------------------------------------------------------------------------------
  bool tx_memory_pool::fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee)
  {
    // Warning: This function takes already_generated_
    // coins as an argument and appears to do nothing
    // with it.

    CRITICAL_REGION_LOCAL(m_transactions_lock);

    total_size = 0;
    fee = 0;

    size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; // Max block size
    std::unordered_set<crypto::key_image> k_images;

    // Tx size limit as in wallet2.h
    // tx_pool.cpp uses size_t for tx sizes, whereas
    // wallet2.h uses uint64_t; just use size_t here 
    // for now
    size_t upper_transaction_size_limit = ((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;

    // Calculate size limit based on median too; useful
    // for when we actually fix wallet2.h's maximum
    // allowable tx size
    //
    // Can be removed when wallet2.h calculates max
    // tx size based on the median too; just use
    // upper_transaction_size_limit_median in all cases
    size_t upper_transaction_size_limit_median = ((median_size * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
    if (upper_transaction_size_limit_median > upper_transaction_size_limit)
      upper_transaction_size_limit = upper_transaction_size_limit_median;

    BOOST_FOREACH(transactions_container::value_type& tx, m_transactions)
    {
      // Can not exceed maximum block size
      if (max_total_size < total_size + tx.second.blob_size)
        continue;

      // Check to see if the minimum fee is included;
      // exclude tx missing minimum fee
      if (tx.second.fee < DEFAULT_FEE)
        continue;

      // Skip transactions that are too large
      // TODO: Correct upper_transactions_size_limit
      // such that it is based on median block size;
      // We need to make a similar patch for
      // wallet2.h
      if (tx.second.blob_size > upper_transaction_size_limit)
        continue;

      // If adding this tx will make the block size
      // greater than 130% of the median, reject the
      // tx; this will keep down largely punitive tx
      // from being included
      if ( (total_size + tx.second.blob_size) > ((130 * median_size) / 100) )
        continue;

      // If we've exceeded the penalty free size,
      // stop including more tx
      if (total_size > median_size)
        break;      

      // Skip transactions that are not ready to be
      // included into the blockchain or that are
      // missing key images
      if (!is_transaction_ready_to_go(tx.second) || have_key_images(k_images, tx.second.tx))
        continue;

      bl.tx_hashes.push_back(tx.first);
      total_size += tx.second.blob_size;
      fee += tx.second.fee;
      append_key_images(k_images, tx.second.tx);
    }

    return true;
  }