diff options
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r-- | src/cryptonote_core/account.cpp | 8 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 32 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 23 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.h | 9 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.cpp | 48 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.h | 29 |
6 files changed, 93 insertions, 56 deletions
diff --git a/src/cryptonote_core/account.cpp b/src/cryptonote_core/account.cpp index 602561489..bd703eee2 100644 --- a/src/cryptonote_core/account.cpp +++ b/src/cryptonote_core/account.cpp @@ -82,7 +82,9 @@ DISABLE_VS_WARNINGS(4244 4345) if (recover) { - m_creation_timestamp = std::max(mktime(×tamp), (long)0); + m_creation_timestamp = mktime(×tamp); + if (m_creation_timestamp == (uint64_t)-1) // failure + m_creation_timestamp = 0; // lowest value } else { @@ -105,7 +107,9 @@ DISABLE_VS_WARNINGS(4244 4345) timestamp.tm_min = 0; timestamp.tm_sec = 0; - m_creation_timestamp = std::max(mktime(×tamp), (long)0); + m_creation_timestamp = mktime(×tamp); + if (m_creation_timestamp == (uint64_t)-1) // failure + m_creation_timestamp = 0; // lowest value } //----------------------------------------------------------------- void account_base::create_from_viewkey(const cryptonote::account_public_address& address, const crypto::secret_key& viewkey) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 00068467e..535eb1a2d 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -375,6 +375,7 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const cryptonote::te LOG_PRINT_GREEN("Blockchain initialized. last block: " << m_db->height() - 1 << ", " << epee::misc_utils::get_time_interval_string(timestamp_diff) << " time ago, current difficulty: " << get_difficulty_for_next_block(), LOG_LEVEL_0); m_db->block_txn_stop(); + update_next_cumulative_size_limit(); return true; } //------------------------------------------------------------------ @@ -508,7 +509,7 @@ block Blockchain::pop_block_from_blockchain() // that might not be always true. Unlikely though, and always relaying // these again might cause a spike of traffic as many nodes re-relay // all the transactions in a popped block when a reorg happens. - bool r = m_tx_pool.add_tx(tx, tvc, true, true, version); + bool r = m_tx_pool.add_tx(tx, tvc, true, true, false, version); if (!r) { LOG_ERROR("Error returning transaction to tx_pool"); @@ -532,6 +533,7 @@ bool Blockchain::reset_and_set_genesis_block(const block& b) block_verification_context bvc = boost::value_initialized<block_verification_context>(); add_new_block(b, bvc); + update_next_cumulative_size_limit(); return bvc.m_added_to_main_chain && !bvc.m_verifivation_failed; } //------------------------------------------------------------------ @@ -2970,7 +2972,7 @@ void Blockchain::return_tx_to_pool(const std::vector<transaction> &txs) // that might not be always true. Unlikely though, and always relaying // these again might cause a spike of traffic as many nodes re-relay // all the transactions in a popped block when a reorg happens. - if (!m_tx_pool.add_tx(tx, tvc, true, true, version)) + if (!m_tx_pool.add_tx(tx, tvc, true, true, false, version)) { LOG_PRINT_L0("Failed to return taken transaction with hash: " << get_transaction_hash(tx) << " to tx_pool"); } @@ -2987,9 +2989,9 @@ bool Blockchain::flush_txes_from_pool(const std::list<crypto::hash> &txids) cryptonote::transaction tx; size_t blob_size; uint64_t fee; - bool relayed; + bool relayed, do_not_relay; LOG_PRINT_L1("Removing txid " << txid << " from the pool"); - if(m_tx_pool.have_tx(txid) && !m_tx_pool.take_tx(txid, tx, blob_size, fee, relayed)) + if(m_tx_pool.have_tx(txid) && !m_tx_pool.take_tx(txid, tx, blob_size, fee, relayed, do_not_relay)) { LOG_PRINT_L0("Failed to remove txid " << txid << " from the pool"); res = false; @@ -3150,7 +3152,7 @@ leave: transaction tx; size_t blob_size = 0; uint64_t fee = 0; - bool relayed = false; + bool relayed = false, do_not_relay = false; TIME_MEASURE_START(aa); // XXX old code does not check whether tx exists @@ -3167,7 +3169,7 @@ leave: TIME_MEASURE_START(bb); // get transaction with hash <tx_id> from tx_pool - if(!m_tx_pool.take_tx(tx_id, tx, blob_size, fee, relayed)) + if(!m_tx_pool.take_tx(tx_id, tx, blob_size, fee, relayed, do_not_relay)) { LOG_PRINT_L1("Block with id: " << id << " has at least one unknown transaction with id: " << tx_id); bvc.m_verifivation_failed = true; @@ -3378,9 +3380,10 @@ bool Blockchain::add_new_block(const block& bl_, block_verification_context& bvc void Blockchain::check_against_checkpoints(const checkpoints& points, bool enforce) { const auto& pts = points.get_points(); + bool stop_batch; CRITICAL_REGION_LOCAL(m_blockchain_lock); - m_db->batch_start(); + stop_batch = m_db->batch_start(); for (const auto& pt : pts) { // if the checkpoint is for a block we don't have yet, move on @@ -3404,7 +3407,8 @@ void Blockchain::check_against_checkpoints(const checkpoints& points, bool enfor } } } - m_db->batch_stop(); + if (stop_batch) + m_db->batch_stop(); } //------------------------------------------------------------------ // returns false if any of the checkpoints loading returns false. @@ -3478,6 +3482,7 @@ bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync) CRITICAL_REGION_LOCAL(m_blockchain_lock); TIME_MEASURE_START(t1); + m_db->batch_stop(); if (m_sync_counter > 0) { if (force_sync) @@ -3542,11 +3547,18 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::list<block_complete_e { LOG_PRINT_YELLOW("Blockchain::" << __func__, LOG_LEVEL_3); TIME_MEASURE_START(prepare); + bool stop_batch; CRITICAL_REGION_LOCAL(m_blockchain_lock); if(blocks_entry.size() == 0) return false; + while (!(stop_batch = m_db->batch_start(blocks_entry.size()))) { + m_blockchain_lock.unlock(); + epee::misc_utils::sleep_no_w(1000); + m_blockchain_lock.lock(); + } + if ((m_db->height() + blocks_entry.size()) < m_blocks_hash_check.size()) return true; @@ -3951,12 +3963,12 @@ void Blockchain::load_compiled_in_block_hashes() size_t blob_size; uint64_t fee; - bool relayed; + bool relayed, do_not_relay; transaction pool_tx; for(const transaction &tx : txs) { crypto::hash tx_hash = get_transaction_hash(tx); - m_tx_pool.take_tx(tx_hash, pool_tx, blob_size, fee, relayed); + m_tx_pool.take_tx(tx_hash, pool_tx, blob_size, fee, relayed, do_not_relay); } } } diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index ea27df500..ede7ed748 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -313,9 +313,9 @@ namespace cryptonote LOG_PRINT_L0("Loading blockchain from folder " << folder.string() << " ..."); const std::string filename = folder.string(); - // temporarily default to fastest:async:1000 + // default to fast:async:1 blockchain_db_sync_mode sync_mode = db_async; - uint64_t blocks_per_sync = 1000; + uint64_t blocks_per_sync = 1; try { @@ -328,12 +328,12 @@ namespace cryptonote for(const auto &option : options) LOG_PRINT_L0("option: " << option); - // default to fast:async:1000 + // default to fast:async:1 uint64_t DEFAULT_FLAGS = DBS_FAST_MODE; if(options.size() == 0) { - // temporarily default to fastest:async:1000 + // default to fast:async:1 db_flags = DEFAULT_FLAGS; } @@ -349,7 +349,10 @@ namespace cryptonote else if(options[0] == "fast") db_flags = DBS_FAST_MODE; else if(options[0] == "fastest") + { db_flags = DBS_FASTEST_MODE; + blocks_per_sync = 1000; // default to fastest:async:1000 + } else db_flags = DEFAULT_FLAGS; } @@ -453,7 +456,7 @@ namespace cryptonote return false; } //----------------------------------------------------------------------------------------------- - bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed) + bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) { tvc = boost::value_initialized<tx_verification_context>(); //want to process all transactions sequentially @@ -518,7 +521,7 @@ namespace cryptonote return false; } - bool r = add_new_tx(tx, tx_hash, tx_prefixt_hash, tx_blob.size(), tvc, keeped_by_block, relayed); + bool r = add_new_tx(tx, tx_hash, tx_prefixt_hash, tx_blob.size(), tvc, keeped_by_block, relayed, do_not_relay); if(tvc.m_verifivation_failed) {LOG_PRINT_RED_L1("Transaction verification failed: " << tx_hash);} else if(tvc.m_verifivation_impossible) @@ -684,13 +687,13 @@ namespace cryptonote return true; } //----------------------------------------------------------------------------------------------- - bool core::add_new_tx(const transaction& tx, tx_verification_context& tvc, bool keeped_by_block, bool relayed) + bool core::add_new_tx(const transaction& tx, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) { crypto::hash tx_hash = get_transaction_hash(tx); crypto::hash tx_prefix_hash = get_transaction_prefix_hash(tx); blobdata bl; t_serializable_object_to_blob(tx, bl); - return add_new_tx(tx, tx_hash, tx_prefix_hash, bl.size(), tvc, keeped_by_block, relayed); + return add_new_tx(tx, tx_hash, tx_prefix_hash, bl.size(), tvc, keeped_by_block, relayed, do_not_relay); } //----------------------------------------------------------------------------------------------- size_t core::get_blockchain_total_transactions() const @@ -698,7 +701,7 @@ namespace cryptonote return m_blockchain_storage.get_total_transactions(); } //----------------------------------------------------------------------------------------------- - bool core::add_new_tx(const transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prefix_hash, size_t blob_size, tx_verification_context& tvc, bool keeped_by_block, bool relayed) + bool core::add_new_tx(const transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prefix_hash, size_t blob_size, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) { if(m_mempool.have_tx(tx_hash)) { @@ -713,7 +716,7 @@ namespace cryptonote } uint8_t version = m_blockchain_storage.get_current_hard_fork_version(); - return m_mempool.add_tx(tx, tx_hash, blob_size, tvc, keeped_by_block, relayed, version); + return m_mempool.add_tx(tx, tx_hash, blob_size, tvc, keeped_by_block, relayed, do_not_relay, version); } //----------------------------------------------------------------------------------------------- bool core::relay_txpool_transactions() diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index a9e80aeee..fa67ff265 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -107,10 +107,11 @@ namespace cryptonote * @param tvc metadata about the transaction's validity * @param keeped_by_block if the transaction has been in a block * @param relayed whether or not the transaction was relayed to us + * @param do_not_relay whether to prevent the transaction from being relayed * * @return true if the transaction made it to the transaction pool, otherwise false */ - bool handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed); + bool handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay); /** * @brief handles an incoming block @@ -641,9 +642,10 @@ namespace cryptonote * @param tx_prefix_hash the transaction prefix' hash * @param blob_size the size of the transaction * @param relayed whether or not the transaction was relayed to us + * @param do_not_relay whether to prevent the transaction from being relayed * */ - bool add_new_tx(const transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prefix_hash, size_t blob_size, tx_verification_context& tvc, bool keeped_by_block, bool relayed); + bool add_new_tx(const transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prefix_hash, size_t blob_size, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay); /** * @brief add a new transaction to the transaction pool @@ -654,12 +656,13 @@ namespace cryptonote * @param tvc return-by-reference metadata about the transaction's verification process * @param keeped_by_block whether or not the transaction has been in a block * @param relayed whether or not the transaction was relayed to us + * @param do_not_relay whether to prevent the transaction from being relayed * * @return true if the transaction is already in the transaction pool, * is already in a block on the Blockchain, or is successfully added * to the transaction pool */ - bool add_new_tx(const transaction& tx, tx_verification_context& tvc, bool keeped_by_block, bool relayed); + bool add_new_tx(const transaction& tx, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay); /** * @copydoc Blockchain::add_new_block diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 59ac534fe..78d75f41f 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -83,7 +83,7 @@ namespace cryptonote } //--------------------------------------------------------------------------------- - bool tx_memory_pool::add_tx(const transaction &tx, /*const crypto::hash& tx_prefix_hash,*/ const crypto::hash &id, size_t blob_size, tx_verification_context& tvc, bool kept_by_block, bool relayed, uint8_t version) + bool tx_memory_pool::add_tx(const transaction &tx, /*const crypto::hash& tx_prefix_hash,*/ const crypto::hash &id, size_t blob_size, tx_verification_context& tvc, bool kept_by_block, bool relayed, bool do_not_relay, uint8_t version) { PERF_TIMER(add_tx); if (tx.version == 0) @@ -177,6 +177,8 @@ namespace cryptonote return false; } + time_t receive_time = time(nullptr); + crypto::hash max_used_block_id = null_hash; uint64_t max_used_block_height = 0; tx_details txd; @@ -198,9 +200,10 @@ namespace cryptonote txd_p.first->second.last_failed_height = 0; txd_p.first->second.last_failed_id = null_hash; txd_p.first->second.kept_by_block = kept_by_block; - txd_p.first->second.receive_time = time(nullptr); + txd_p.first->second.receive_time = receive_time; txd_p.first->second.last_relayed_time = time(NULL); txd_p.first->second.relayed = relayed; + txd_p.first->second.do_not_relay = do_not_relay; tvc.m_verifivation_impossible = true; tvc.m_added_to_pool = true; }else @@ -221,12 +224,13 @@ namespace cryptonote txd_p.first->second.max_used_block_height = max_used_block_height; txd_p.first->second.last_failed_height = 0; txd_p.first->second.last_failed_id = null_hash; - txd_p.first->second.receive_time = time(nullptr); + txd_p.first->second.receive_time = receive_time; txd_p.first->second.last_relayed_time = time(NULL); txd_p.first->second.relayed = relayed; + txd_p.first->second.do_not_relay = do_not_relay; tvc.m_added_to_pool = true; - if(txd_p.first->second.fee > 0) + if(txd_p.first->second.fee > 0 && !do_not_relay) tvc.m_should_be_relayed = true; } @@ -246,17 +250,17 @@ namespace cryptonote tvc.m_verifivation_failed = false; - m_txs_by_fee.emplace((double)blob_size / fee, id); + m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>((double)blob_size / fee, receive_time), id); return true; } //--------------------------------------------------------------------------------- - bool tx_memory_pool::add_tx(const transaction &tx, tx_verification_context& tvc, bool keeped_by_block, bool relayed, uint8_t version) + bool tx_memory_pool::add_tx(const transaction &tx, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay, uint8_t version) { crypto::hash h = null_hash; size_t blob_size = 0; get_transaction_hash(tx, h, blob_size); - return add_tx(tx, h, blob_size, tvc, keeped_by_block, relayed, version); + return add_tx(tx, h, blob_size, tvc, keeped_by_block, relayed, do_not_relay, version); } //--------------------------------------------------------------------------------- //FIXME: Can return early before removal of all of the key images. @@ -292,7 +296,7 @@ namespace cryptonote return true; } //--------------------------------------------------------------------------------- - bool tx_memory_pool::take_tx(const crypto::hash &id, transaction &tx, size_t& blob_size, uint64_t& fee, bool &relayed) + bool tx_memory_pool::take_tx(const crypto::hash &id, transaction &tx, size_t& blob_size, uint64_t& fee, bool &relayed, bool &do_not_relay) { CRITICAL_REGION_LOCAL(m_transactions_lock); auto it = m_transactions.find(id); @@ -301,16 +305,17 @@ namespace cryptonote auto sorted_it = find_tx_in_sorted_container(id); - if (sorted_it == m_txs_by_fee.end()) + if (sorted_it == m_txs_by_fee_and_receive_time.end()) return false; tx = it->second.tx; blob_size = it->second.blob_size; fee = it->second.fee; relayed = it->second.relayed; + do_not_relay = it->second.do_not_relay; remove_transaction_keyimages(it->second.tx); m_transactions.erase(it); - m_txs_by_fee.erase(sorted_it); + m_txs_by_fee_and_receive_time.erase(sorted_it); return true; } //--------------------------------------------------------------------------------- @@ -321,7 +326,7 @@ namespace cryptonote //--------------------------------------------------------------------------------- sorted_tx_container::iterator tx_memory_pool::find_tx_in_sorted_container(const crypto::hash& id) const { - return std::find_if( m_txs_by_fee.begin(), m_txs_by_fee.end() + return std::find_if( m_txs_by_fee_and_receive_time.begin(), m_txs_by_fee_and_receive_time.end() , [&](const sorted_tx_container::value_type& a){ return a.second == id; } @@ -342,13 +347,13 @@ namespace cryptonote LOG_PRINT_L1("Tx " << it->first << " removed from tx pool due to outdated, age: " << tx_age ); remove_transaction_keyimages(it->second.tx); auto sorted_it = find_tx_in_sorted_container(it->first); - if (sorted_it == m_txs_by_fee.end()) + if (sorted_it == m_txs_by_fee_and_receive_time.end()) { LOG_PRINT_L1("Removing tx " << it->first << " from tx pool, but it was not found in the sorted txs container!"); } else { - m_txs_by_fee.erase(sorted_it); + m_txs_by_fee_and_receive_time.erase(sorted_it); } m_timed_out_transactions.insert(it->first); auto pit = it++; @@ -367,7 +372,7 @@ namespace cryptonote for(auto it = m_transactions.begin(); it!= m_transactions.end();) { // 0 fee transactions are never relayed - if(it->second.fee > 0 && now - it->second.last_relayed_time > get_relay_delay(now, it->second.receive_time)) + if(it->second.fee > 0 && !it->second.do_not_relay && now - it->second.last_relayed_time > get_relay_delay(now, it->second.receive_time)) { // if the tx is older than half the max lifetime, we don't re-relay it, to avoid a problem // mentioned by smooth where nodes would flush txes at slightly different times, causing @@ -431,6 +436,7 @@ namespace cryptonote txi.receive_time = txd.receive_time; txi.relayed = txd.relayed; txi.last_relayed_time = txd.last_relayed_time; + txi.do_not_relay = txd.do_not_relay; tx_infos.push_back(txi); } @@ -608,9 +614,9 @@ namespace cryptonote size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; std::unordered_set<crypto::key_image> k_images; - LOG_PRINT_L2("Filling block template, median size " << median_size << ", " << m_txs_by_fee.size() << " txes in the pool"); - auto sorted_it = m_txs_by_fee.begin(); - while (sorted_it != m_txs_by_fee.end()) + LOG_PRINT_L2("Filling block template, median size " << median_size << ", " << m_txs_by_fee_and_receive_time.size() << " txes in the pool"); + auto sorted_it = m_txs_by_fee_and_receive_time.begin(); + while (sorted_it != m_txs_by_fee_and_receive_time.end()) { auto tx_it = m_transactions.find(sorted_it->second); LOG_PRINT_L2("Considering " << tx_it->first << ", size " << tx_it->second.blob_size << ", current block size " << total_size << "/" << max_total_size << ", current coinbase " << print_money(best_coinbase)); @@ -675,13 +681,13 @@ namespace cryptonote LOG_PRINT_L1("Transaction " << get_transaction_hash(it->second.tx) << " is too big (" << it->second.blob_size << " bytes), removing it from pool"); remove_transaction_keyimages(it->second.tx); auto sorted_it = find_tx_in_sorted_container(it->first); - if (sorted_it == m_txs_by_fee.end()) + if (sorted_it == m_txs_by_fee_and_receive_time.end()) { LOG_PRINT_L1("Removing tx " << it->first << " from tx pool, but it was not found in the sorted txs container!"); } else { - m_txs_by_fee.erase(sorted_it); + m_txs_by_fee_and_receive_time.erase(sorted_it); } auto pit = it++; m_transactions.erase(pit); @@ -712,14 +718,14 @@ namespace cryptonote LOG_ERROR("Failed to load memory pool from file " << state_file_path); m_transactions.clear(); - m_txs_by_fee.clear(); + m_txs_by_fee_and_receive_time.clear(); m_spent_key_images.clear(); } // no need to store queue of sorted transactions, as it's easy to generate. for (const auto& tx : m_transactions) { - m_txs_by_fee.emplace((double)tx.second.blob_size / tx.second.fee, tx.first); + m_txs_by_fee_and_receive_time.emplace(std::pair<double, time_t>((double)tx.second.blob_size / tx.second.fee, tx.second.receive_time), tx.first); } // Ignore deserialization error diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 32a05b0f4..2712f75bb 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -54,23 +54,25 @@ namespace cryptonote /************************************************************************/ //! pair of <transaction fee, transaction hash> for organization - typedef std::pair<double, crypto::hash> tx_by_fee_entry; + typedef std::pair<std::pair<double, std::time_t>, crypto::hash> tx_by_fee_and_receive_time_entry; class txCompare { public: - bool operator()(const tx_by_fee_entry& a, const tx_by_fee_entry& b) + bool operator()(const tx_by_fee_and_receive_time_entry& a, const tx_by_fee_and_receive_time_entry& b) { // sort by greatest first, not least - if (a.first > b.first) return true; - else if (a.first < b.first) return false; + if (a.first.first > b.first.first) return true; + else if (a.first.first < b.first.first) return false; + else if (a.first.second < b.first.second) return true; + else if (a.first.second > b.first.second) return false; else if (a.second != b.second) return true; else return false; } }; //! container for sorting transactions by fee per unit size - typedef std::set<tx_by_fee_entry, txCompare> sorted_tx_container; + typedef std::set<tx_by_fee_and_receive_time_entry, txCompare> sorted_tx_container; /** * @brief Transaction pool, handles transactions which are not part of a block @@ -103,7 +105,7 @@ namespace cryptonote * @param id the transaction's hash * @param blob_size the transaction's size */ - bool add_tx(const transaction &tx, const crypto::hash &id, size_t blob_size, tx_verification_context& tvc, bool kept_by_block, bool relayed, uint8_t version); + bool add_tx(const transaction &tx, const crypto::hash &id, size_t blob_size, tx_verification_context& tvc, bool kept_by_block, bool relayed, bool do_not_relay, uint8_t version); /** * @brief add a transaction to the transaction pool @@ -117,11 +119,12 @@ namespace cryptonote * @param tvc return-by-reference status about the transaction verification * @param kept_by_block has this transaction been in a block? * @param relayed was this transaction from the network or a local client? + * @param do_not_relay to avoid relaying the transaction to the network * @param version the version used to create the transaction * * @return true if the transaction passes validations, otherwise false */ - bool add_tx(const transaction &tx, tx_verification_context& tvc, bool kept_by_block, bool relayed, uint8_t version); + bool add_tx(const transaction &tx, tx_verification_context& tvc, bool kept_by_block, bool relayed, bool do_not_relay, uint8_t version); /** * @brief takes a transaction with the given hash from the pool @@ -131,10 +134,11 @@ namespace cryptonote * @param blob_size return-by-reference the transaction's size * @param fee the transaction fee * @param relayed return-by-reference was transaction relayed to us by the network? + * @param do_not_relay return-by-reference is transaction not to be relayed to the network? * * @return true unless the transaction cannot be found in the pool */ - bool take_tx(const crypto::hash &id, transaction &tx, size_t& blob_size, uint64_t& fee, bool &relayed); + bool take_tx(const crypto::hash &id, transaction &tx, size_t& blob_size, uint64_t& fee, bool &relayed, bool &do_not_relay); /** * @brief checks if the pool has a transaction with the given hash @@ -303,7 +307,7 @@ namespace cryptonote #define CURRENT_MEMPOOL_ARCHIVE_VER 11 -#define CURRENT_MEMPOOL_TX_DETAILS_ARCHIVE_VER 11 +#define CURRENT_MEMPOOL_TX_DETAILS_ARCHIVE_VER 12 /** * @brief serialize the transaction pool to/from disk @@ -362,6 +366,7 @@ namespace cryptonote time_t last_relayed_time; //!< the last time the transaction was relayed to the network bool relayed; //!< whether or not the transaction has been relayed to the network + bool do_not_relay; //!< to avoid relay this transaction to the network }; private: @@ -473,7 +478,8 @@ private: epee::math_helper::once_a_time_seconds<30> m_remove_stuck_tx_interval; //TODO: look into doing this better - sorted_tx_container m_txs_by_fee; //!< container for transactions organized by fee per size + //!< container for transactions organized by fee per size and receive time + sorted_tx_container m_txs_by_fee_and_receive_time; /** * @brief get an iterator to a transaction in the sorted container @@ -515,6 +521,9 @@ namespace boost if (version < 11) return; ar & td.kept_by_block; + if (version < 12) + return; + ar & td.do_not_relay; } } } |