diff options
Diffstat (limited to '')
-rw-r--r-- | src/crypto/hash-extra-jh.c | 6 | ||||
-rw-r--r-- | src/crypto/hash-extra-skein.c | 6 | ||||
-rw-r--r-- | src/cryptonote_basic/cryptonote_format_utils.cpp | 4 | ||||
-rw-r--r-- | src/cryptonote_config.h | 3 | ||||
-rw-r--r-- | src/cryptonote_core/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 2 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_tx_utils.cpp | 27 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_tx_utils.h | 4 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.cpp | 96 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.h | 13 |
10 files changed, 112 insertions, 50 deletions
diff --git a/src/crypto/hash-extra-jh.c b/src/crypto/hash-extra-jh.c index 4d7481c07..52efd4ae3 100644 --- a/src/crypto/hash-extra-jh.c +++ b/src/crypto/hash-extra-jh.c @@ -36,7 +36,9 @@ #include "jh.h" #include "hash-ops.h" +#define JH_HASH_BITLEN HASH_SIZE * 8 + void hash_extra_jh(const void *data, size_t length, char *hash) { - int r = jh_hash(HASH_SIZE * 8, data, 8 * length, (uint8_t*)hash); - assert(SUCCESS == r); + // No need to check for failure b/c jh_hash only fails for invalid hash size + jh_hash(JH_HASH_BITLEN, data, 8 * length, (uint8_t*)hash); } diff --git a/src/crypto/hash-extra-skein.c b/src/crypto/hash-extra-skein.c index 9ea9c4faa..3eacaba58 100644 --- a/src/crypto/hash-extra-skein.c +++ b/src/crypto/hash-extra-skein.c @@ -34,7 +34,9 @@ #include "hash-ops.h" #include "skein.h" +#define SKEIN_HASH_BITLEN HASH_SIZE * 8 + void hash_extra_skein(const void *data, size_t length, char *hash) { - int r = skein_hash(8 * HASH_SIZE, data, 8 * length, (uint8_t*)hash); - assert(SKEIN_SUCCESS == r); + // No need to check for failure b/c skein_hash only fails for invalid hash size + skein_hash(SKEIN_HASH_BITLEN, data, 8 * length, (uint8_t*)hash); } diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index f101f10c5..388013f96 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -1042,7 +1042,7 @@ namespace cryptonote crypto::public_key subaddress_spendkey; if (out_can_be_to_acc(view_tag_opt, derivation, output_index)) { - hwdev.derive_subaddress_public_key(out_key, derivation, output_index, subaddress_spendkey); + CHECK_AND_ASSERT_MES(hwdev.derive_subaddress_public_key(out_key, derivation, output_index, subaddress_spendkey), boost::none, "Failed to derive subaddress public key"); auto found = subaddresses.find(subaddress_spendkey); if (found != subaddresses.end()) return subaddress_receive_info{ found->second, derivation }; @@ -1054,7 +1054,7 @@ namespace cryptonote CHECK_AND_ASSERT_MES(output_index < additional_derivations.size(), boost::none, "wrong number of additional derivations"); if (out_can_be_to_acc(view_tag_opt, additional_derivations[output_index], output_index)) { - hwdev.derive_subaddress_public_key(out_key, additional_derivations[output_index], output_index, subaddress_spendkey); + CHECK_AND_ASSERT_MES(hwdev.derive_subaddress_public_key(out_key, additional_derivations[output_index], output_index, subaddress_spendkey), boost::none, "Failed to derive subaddress public key"); auto found = subaddresses.find(subaddress_spendkey); if (found != subaddresses.end()) return subaddress_receive_info{ found->second, additional_derivations[output_index] }; diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index f2a8e9b79..2ec194ef8 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -239,12 +239,15 @@ namespace config const unsigned char HASH_KEY_MEMORY = 'k'; const unsigned char HASH_KEY_MULTISIG[] = {'M', 'u', 'l', 't' , 'i', 's', 'i', 'g', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const unsigned char HASH_KEY_MULTISIG_KEY_AGGREGATION[] = "Multisig_key_agg"; + const unsigned char HASH_KEY_CLSAG_ROUND_MULTISIG[] = "CLSAG_round_ms_merge_factor"; const unsigned char HASH_KEY_TXPROOF_V2[] = "TXPROOF_V2"; const unsigned char HASH_KEY_CLSAG_ROUND[] = "CLSAG_round"; const unsigned char HASH_KEY_CLSAG_AGG_0[] = "CLSAG_agg_0"; const unsigned char HASH_KEY_CLSAG_AGG_1[] = "CLSAG_agg_1"; const char HASH_KEY_MESSAGE_SIGNING[] = "MoneroMessageSignature"; const unsigned char HASH_KEY_MM_SLOT = 'm'; + const constexpr char HASH_KEY_MULTISIG_TX_PRIVKEYS_SEED[] = "multisig_tx_privkeys_seed"; + const constexpr char HASH_KEY_MULTISIG_TX_PRIVKEYS[] = "multisig_tx_privkeys"; // Multisig const uint32_t MULTISIG_MAX_SIGNERS{16}; diff --git a/src/cryptonote_core/CMakeLists.txt b/src/cryptonote_core/CMakeLists.txt index e272b94f0..69411e379 100644 --- a/src/cryptonote_core/CMakeLists.txt +++ b/src/cryptonote_core/CMakeLists.txt @@ -49,7 +49,6 @@ target_link_libraries(cryptonote_core common cncrypto blockchain_db - multisig ringct device hardforks diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 5b7b4353d..c37dfe9e7 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -5604,7 +5604,7 @@ void Blockchain::cancel() } #if defined(PER_BLOCK_CHECKPOINT) -static const char expected_block_hashes_hash[] = "8da80ca560793f252d1d4ed449c85d75c74867f3f86b8832c8e3f88b1cbb6ae3"; +static const char expected_block_hashes_hash[] = "e9371004b9f6be59921b27bc81e28b4715845ade1c6d16891d5c455f72e21365"; void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints) { if (get_checkpoints == nullptr || !m_fast_sync) diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index 1d2024a05..472026217 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -203,7 +203,7 @@ namespace cryptonote return addr.m_view_public_key; } //--------------------------------------------------------------- - bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout, bool shuffle_outs, bool use_view_tags) + bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool shuffle_outs, bool use_view_tags) { hw::device &hwdev = sender_account_keys.get_device(); @@ -216,10 +216,6 @@ namespace cryptonote std::vector<rct::key> amount_keys; tx.set_null(); amount_keys.clear(); - if (msout) - { - msout->c.clear(); - } tx.version = rct ? 2 : 1; tx.unlock_time = unlock_time; @@ -333,8 +329,8 @@ namespace cryptonote return false; } - //check that derivated key is equal with real output key (if non multisig) - if(!msout && !(in_ephemeral.pub == src_entr.outputs[src_entr.real_output].second.dest) ) + //check that derivated key is equal with real output key + if(!(in_ephemeral.pub == src_entr.outputs[src_entr.real_output].second.dest) ) { LOG_ERROR("derived public key mismatch with output public key at index " << idx << ", real out " << src_entr.real_output << "! "<< ENDL << "derived_key:" << string_tools::pod_to_hex(in_ephemeral.pub) << ENDL << "real output_public_key:" @@ -347,7 +343,7 @@ namespace cryptonote //put key image into tx input txin_to_key input_to_key; input_to_key.amount = src_entr.amount; - input_to_key.k_image = msout ? rct::rct2ki(src_entr.multisig_kLRki.ki) : img; + input_to_key.k_image = img; //fill outputs array and use relative offsets for(const tx_source_entry::output_entry& out_entry: src_entr.outputs) @@ -529,7 +525,6 @@ namespace cryptonote rct::keyV destinations; std::vector<uint64_t> inamounts, outamounts; std::vector<unsigned int> index; - std::vector<rct::multisig_kLRki> kLRki; for (size_t i = 0; i < sources.size(); ++i) { rct::ctkey ctkey; @@ -543,10 +538,6 @@ namespace cryptonote memwipe(&ctkey, sizeof(rct::ctkey)); // inPk: (public key, commitment) // will be done when filling in mixRing - if (msout) - { - kLRki.push_back(sources[i].multisig_kLRki); - } } for (size_t i = 0; i < tx.vout.size(); ++i) { @@ -598,9 +589,9 @@ namespace cryptonote get_transaction_prefix_hash(tx, tx_prefix_hash, hwdev); rct::ctkeyV outSk; if (use_simple_rct) - tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, msout ? &kLRki : NULL, msout, index, outSk, rct_config, hwdev); + tx.rct_signatures = rct::genRctSimple(rct::hash2rct(tx_prefix_hash), inSk, destinations, inamounts, outamounts, amount_in - amount_out, mixRing, amount_keys, index, outSk, rct_config, hwdev); else - tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, msout ? &kLRki[0] : NULL, msout, sources[0].real_output, outSk, rct_config, hwdev); // same index assumption + tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, sources[0].real_output, outSk, rct_config, hwdev); // same index assumption memwipe(inSk.data(), inSk.size() * sizeof(rct::ctkey)); CHECK_AND_ASSERT_MES(tx.vout.size() == outSk.size(), false, "outSk size does not match vout"); @@ -613,7 +604,7 @@ namespace cryptonote return true; } //--------------------------------------------------------------- - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, rct::multisig_out *msout, bool use_view_tags) + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct, const rct::RCTConfig &rct_config, bool use_view_tags) { hw::device &hwdev = sender_account_keys.get_device(); hwdev.open_tx(tx_key); @@ -634,7 +625,7 @@ namespace cryptonote } bool shuffle_outs = true; - bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, msout, shuffle_outs, use_view_tags); + bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, shuffle_outs, use_view_tags); hwdev.close_tx(); return r; } catch(...) { @@ -650,7 +641,7 @@ namespace cryptonote crypto::secret_key tx_key; std::vector<crypto::secret_key> additional_tx_keys; std::vector<tx_destination_entry> destinations_copy = destinations; - return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0}, NULL, false); + return construct_tx_and_get_tx_key(sender_account_keys, subaddresses, sources, destinations_copy, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, false, { rct::RangeProofBorromean, 0}); } //--------------------------------------------------------------- bool generate_genesis_block( diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h index f4ffb98ff..12d6b8ce5 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.h +++ b/src/cryptonote_core/cryptonote_tx_utils.h @@ -119,8 +119,8 @@ namespace cryptonote //--------------------------------------------------------------- crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const boost::optional<cryptonote::account_public_address>& change_addr); bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time); - bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL, bool shuffle_outs = true, bool use_view_tags = false); - bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL, bool use_view_tags = false); + bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool shuffle_outs = true, bool use_view_tags = false); + bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, bool use_view_tags = false); bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key, const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index, const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys, diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index a68da0e62..757ce1d73 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -402,6 +402,19 @@ namespace cryptonote m_txpool_max_weight = bytes; } //--------------------------------------------------------------------------------- + void tx_memory_pool::reduce_txpool_weight(size_t weight) + { + if (weight > m_txpool_weight) + { + MERROR("Underflow in txpool weight"); + m_txpool_weight = 0; + } + else + { + m_txpool_weight -= weight; + } + } + //--------------------------------------------------------------------------------- void tx_memory_pool::prune(size_t bytes) { CRITICAL_REGION_LOCAL(m_transactions_lock); @@ -423,8 +436,14 @@ namespace cryptonote txpool_tx_meta_t meta; if (!m_blockchain.get_txpool_tx_meta(txid, meta)) { - MERROR("Failed to find tx_meta in txpool"); - return; + static bool warned = false; + if (!warned) + { + MERROR("Failed to find tx_meta in txpool (will only print once)"); + warned = true; + } + --it; + continue; } // don't prune the kept_by_block ones, they're likely added because we're adding a block with those if (meta.kept_by_block) @@ -442,7 +461,7 @@ namespace cryptonote // remove first, in case this throws, so key images aren't removed MINFO("Pruning tx " << txid << " from txpool: weight: " << meta.weight << ", fee/byte: " << it->first.first); m_blockchain.remove_txpool_tx(txid); - m_txpool_weight -= meta.weight; + reduce_txpool_weight(meta.weight); remove_transaction_keyimages(tx, txid); MINFO("Pruned tx " << txid << " from txpool: weight: " << meta.weight << ", fee/byte: " << it->first.first); m_txs_by_fee_and_receive_time.erase(it--); @@ -562,7 +581,7 @@ namespace cryptonote // remove first, in case this throws, so key images aren't removed m_blockchain.remove_txpool_tx(id); - m_txpool_weight -= tx_weight; + reduce_txpool_weight(tx_weight); remove_transaction_keyimages(tx, id); lock.commit(); } @@ -725,7 +744,7 @@ namespace cryptonote { // remove first, so we only remove key images if the tx removal succeeds m_blockchain.remove_txpool_tx(txid); - m_txpool_weight -= entry.second; + reduce_txpool_weight(entry.second); remove_transaction_keyimages(tx, txid); } } @@ -917,26 +936,61 @@ namespace cryptonote { CRITICAL_REGION_LOCAL(m_transactions_lock); CRITICAL_REGION_LOCAL1(m_blockchain); - const relay_category category = include_sensitive ? relay_category::all : relay_category::broadcasted; - backlog.reserve(m_blockchain.get_txpool_tx_count(include_sensitive)); - txpool_tx_meta_t tmp_meta; - m_blockchain.for_all_txpool_txes([this, &backlog, &tmp_meta](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){ - transaction tx; - if (!(meta.pruned ? parse_and_validate_tx_base_from_blob(*bd, tx) : parse_and_validate_tx_from_blob(*bd, tx))) + + std::vector<tx_block_template_backlog_entry> tmp; + uint64_t total_weight = 0; + + // First get everything from the mempool, filter it later + m_blockchain.for_all_txpool_txes([&tmp, &total_weight](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref*){ + tmp.emplace_back(tx_block_template_backlog_entry{txid, meta.weight, meta.fee}); + total_weight += meta.weight; + return true; + }, false, include_sensitive ? relay_category::all : relay_category::broadcasted); + + // Limit backlog to 112.5% of current median weight. This is enough to mine a full block with the optimal block reward + const uint64_t median_weight = m_blockchain.get_current_cumulative_block_weight_median(); + const uint64_t max_backlog_weight = median_weight + (median_weight / 8); + + // If the total weight is too high, choose the best paying transactions + if (total_weight > max_backlog_weight) + std::sort(tmp.begin(), tmp.end(), [](const auto& a, const auto& b){ return a.fee * b.weight > b.fee * a.weight; }); + + backlog.clear(); + uint64_t w = 0; + + std::unordered_set<crypto::key_image> k_images; + + for (const tx_block_template_backlog_entry& e : tmp) + { + try { - MERROR("Failed to parse tx from txpool"); - // continue - return true; - } - tx.set_hash(txid); + txpool_tx_meta_t meta; + if (!m_blockchain.get_txpool_tx_meta(e.id, meta)) + continue; - tmp_meta = meta; + cryptonote::blobdata txblob; + if (!m_blockchain.get_txpool_tx_blob(e.id, txblob, relay_category::all)) + continue; - if (is_transaction_ready_to_go(tmp_meta, txid, *bd, tx)) - backlog.push_back({txid, meta.weight, meta.fee}); + cryptonote::transaction tx; + if (is_transaction_ready_to_go(meta, e.id, txblob, tx)) + { + if (have_key_images(k_images, tx)) + continue; + append_key_images(k_images, tx); - return true; - }, true, category); + backlog.push_back(e); + w += e.weight; + if (w > max_backlog_weight) + break; + } + } + catch (const std::exception &e) + { + MERROR("Failed to check transaction readiness: " << e.what()); + // continue, not fatal + } + } } //------------------------------------------------------------------ void tx_memory_pool::get_transaction_stats(struct txpool_stats& stats, bool include_sensitive) const diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 62bef6c06..d4a300a2f 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -266,7 +266,11 @@ namespace cryptonote void get_transaction_backlog(std::vector<tx_backlog_entry>& backlog, bool include_sensitive = false) const; /** - * @brief get (hash, weight, fee) for all transactions in the pool - the minimum required information to create a block template + * @brief get (hash, weight, fee) for transactions in the pool - the minimum required information to create a block template + * + * Not all transactions in the pool will be returned for performance reasons + * If there are too many transactions in the pool, only the highest-paying transactions + * will be returned - but enough for the miner to create a full block * * @param backlog return-by-reference that data * @param include_sensitive return stempool, anonymity-pool, and unrelayed txes @@ -406,6 +410,13 @@ namespace cryptonote */ void set_txpool_max_weight(size_t bytes); + /** + * @brief reduce the cumulative txpool weight by the weight provided + * + * @param weight the weight to reduce the total txpool weight by + */ + void reduce_txpool_weight(size_t weight); + #define CURRENT_MEMPOOL_ARCHIVE_VER 11 #define CURRENT_MEMPOOL_TX_DETAILS_ARCHIVE_VER 13 |