aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2018-11-23 11:15:04 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2019-03-05 11:58:13 +0000
commit238401d4e950dad6a243fb895027dd26d2992ee6 (patch)
treeace8c69b75f6e6db2d2bdad69456ce346348b48c /src
parentblockchain: avoid unneeded block copy (diff)
downloadmonero-238401d4e950dad6a243fb895027dd26d2992ee6.tar.xz
core: avoid double parsing blocks after hoh
Diffstat (limited to 'src')
-rw-r--r--src/blockchain_utilities/blockchain_import.cpp12
-rw-r--r--src/cryptonote_core/blockchain.cpp4
-rw-r--r--src/cryptonote_core/blockchain.h5
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp25
-rw-r--r--src/cryptonote_core/cryptonote_core.h5
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.inl24
6 files changed, 50 insertions, 25 deletions
diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp
index d2c2b1ea9..d7a88f935 100644
--- a/src/blockchain_utilities/blockchain_import.cpp
+++ b/src/blockchain_utilities/blockchain_import.cpp
@@ -193,8 +193,16 @@ int check_flush(cryptonote::core &core, std::vector<block_complete_entry> &block
}
core.prevalidate_block_hashes(core.get_blockchain_storage().get_db().height(), hashes);
- core.prepare_handle_incoming_blocks(blocks);
+ std::vector<block> pblocks;
+ core.prepare_handle_incoming_blocks(blocks, pblocks);
+ if (!pblocks.empty() && pblocks.size() != blocks.size())
+ {
+ MERROR("Unexpected parsed blocks size");
+ core.cleanup_handle_incoming_blocks();
+ return 1;
+ }
+ size_t blockidx = 0;
for(const block_complete_entry& block_entry: blocks)
{
// process transactions
@@ -215,7 +223,7 @@ int check_flush(cryptonote::core &core, std::vector<block_complete_entry> &block
block_verification_context bvc = boost::value_initialized<block_verification_context>();
- core.handle_incoming_block(block_entry.block, bvc, false); // <--- process block
+ core.handle_incoming_block(block_entry.block, pblocks.empty() ? NULL : &pblocks[blockidx++], bvc, false); // <--- process block
if(bvc.m_verifivation_failed)
{
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index a1bee09dc..2890af628 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -4211,13 +4211,14 @@ uint64_t Blockchain::prevalidate_block_hashes(uint64_t height, const std::vector
// vs [k_image, output_keys] (m_scan_table). This is faster because it takes advantage of bulk queries
// and is threaded if possible. The table (m_scan_table) will be used later when querying output
// keys.
-bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete_entry> &blocks_entry)
+bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete_entry> &blocks_entry, std::vector<block> &blocks)
{
MTRACE("Blockchain::" << __func__);
TIME_MEASURE_START(prepare);
bool stop_batch;
uint64_t bytes = 0;
size_t total_txs = 0;
+ blocks.clear();
// Order of locking must be:
// m_incoming_tx_lock (optional)
@@ -4264,7 +4265,6 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
bool blocks_exist = false;
tools::threadpool& tpool = tools::threadpool::getInstance();
unsigned threads = tpool.get_max_concurrency();
- std::vector<block> blocks;
blocks.resize(blocks_entry.size());
if (1)
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 6e966781d..9d928e386 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -230,11 +230,12 @@ namespace cryptonote
/**
* @brief performs some preprocessing on a group of incoming blocks to speed up verification
*
- * @param blocks a list of incoming blocks
+ * @param blocks_entry a list of incoming blocks
+ * @param blocks the parsed blocks
*
* @return false on erroneous blocks, else true
*/
- bool prepare_handle_incoming_blocks(const std::vector<block_complete_entry> &blocks);
+ bool prepare_handle_incoming_blocks(const std::vector<block_complete_entry> &blocks_entry, std::vector<block> &blocks);
/**
* @brief incoming blocks post-processing, cleanup, and disk sync
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 0d29f996a..bab0e2dd9 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -1330,7 +1330,8 @@ namespace cryptonote
m_miner.resume();
return false;
}
- prepare_handle_incoming_blocks(blocks);
+ std::vector<block> pblocks;
+ prepare_handle_incoming_blocks(blocks, pblocks);
m_blockchain_storage.add_new_block(b, bvc);
cleanup_handle_incoming_blocks(true);
//anyway - update miner template
@@ -1381,10 +1382,10 @@ namespace cryptonote
}
//-----------------------------------------------------------------------------------------------
- bool core::prepare_handle_incoming_blocks(const std::vector<block_complete_entry> &blocks)
+ bool core::prepare_handle_incoming_blocks(const std::vector<block_complete_entry> &blocks_entry, std::vector<block> &blocks)
{
m_incoming_tx_lock.lock();
- m_blockchain_storage.prepare_handle_incoming_blocks(blocks);
+ m_blockchain_storage.prepare_handle_incoming_blocks(blocks_entry, blocks);
return true;
}
@@ -1401,7 +1402,7 @@ namespace cryptonote
}
//-----------------------------------------------------------------------------------------------
- bool core::handle_incoming_block(const blobdata& block_blob, block_verification_context& bvc, bool update_miner_blocktemplate)
+ bool core::handle_incoming_block(const blobdata& block_blob, const block *b, block_verification_context& bvc, bool update_miner_blocktemplate)
{
TRY_ENTRY();
@@ -1417,14 +1418,18 @@ namespace cryptonote
return false;
}
- block b = AUTO_VAL_INIT(b);
- if(!parse_and_validate_block_from_blob(block_blob, b))
+ block lb;
+ if (!b)
{
- LOG_PRINT_L1("Failed to parse and validate new block");
- bvc.m_verifivation_failed = true;
- return false;
+ if(!parse_and_validate_block_from_blob(block_blob, lb))
+ {
+ LOG_PRINT_L1("Failed to parse and validate new block");
+ bvc.m_verifivation_failed = true;
+ return false;
+ }
+ b = &lb;
}
- add_new_block(b, bvc);
+ add_new_block(*b, bvc);
if(update_miner_blocktemplate && bvc.m_added_to_main_chain)
update_miner_block_template();
return true;
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index 131440511..6d0ff098d 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -146,20 +146,21 @@ namespace cryptonote
* optionally updates the miner's block template.
*
* @param block_blob the block to be added
+ * @param block the block to be added, or NULL
* @param bvc return-by-reference metadata context about the block's validity
* @param update_miner_blocktemplate whether or not to update the miner's block template
*
* @return false if loading new checkpoints fails, or the block is not
* added, otherwise true
*/
- bool handle_incoming_block(const blobdata& block_blob, block_verification_context& bvc, bool update_miner_blocktemplate = true);
+ bool handle_incoming_block(const blobdata& block_blob, const block *b, block_verification_context& bvc, bool update_miner_blocktemplate = true);
/**
* @copydoc Blockchain::prepare_handle_incoming_blocks
*
* @note see Blockchain::prepare_handle_incoming_blocks
*/
- bool prepare_handle_incoming_blocks(const std::vector<block_complete_entry> &blocks);
+ bool prepare_handle_incoming_blocks(const std::vector<block_complete_entry> &blocks_entry, std::vector<block> &blocks);
/**
* @copydoc Blockchain::cleanup_handle_incoming_blocks
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index 8fada4e3c..9c2e1df88 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
@@ -418,7 +418,8 @@ namespace cryptonote
m_core.pause_mine();
std::vector<block_complete_entry> blocks;
blocks.push_back(arg.b);
- m_core.prepare_handle_incoming_blocks(blocks);
+ std::vector<block> pblocks;
+ m_core.prepare_handle_incoming_blocks(blocks, pblocks);
for(auto tx_blob_it = arg.b.txs.begin(); tx_blob_it!=arg.b.txs.end();tx_blob_it++)
{
cryptonote::tx_verification_context tvc = AUTO_VAL_INIT(tvc);
@@ -434,7 +435,7 @@ namespace cryptonote
}
block_verification_context bvc = boost::value_initialized<block_verification_context>();
- m_core.handle_incoming_block(arg.b.block, bvc); // got block from handle_notify_new_block
+ m_core.handle_incoming_block(arg.b.block, pblocks.empty() ? NULL : &pblocks[0], bvc); // got block from handle_notify_new_block
if (!m_core.cleanup_handle_incoming_blocks(true))
{
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
@@ -697,10 +698,11 @@ namespace cryptonote
std::vector<block_complete_entry> blocks;
blocks.push_back(b);
- m_core.prepare_handle_incoming_blocks(blocks);
+ std::vector<block> pblocks;
+ m_core.prepare_handle_incoming_blocks(blocks, pblocks);
block_verification_context bvc = boost::value_initialized<block_verification_context>();
- m_core.handle_incoming_block(arg.b.block, bvc); // got block from handle_notify_new_block
+ m_core.handle_incoming_block(arg.b.block, pblocks.empty() ? NULL : &pblocks[0], bvc); // got block from handle_notify_new_block
if (!m_core.cleanup_handle_incoming_blocks(true))
{
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
@@ -1174,10 +1176,17 @@ namespace cryptonote
}
}
- m_core.prepare_handle_incoming_blocks(blocks);
+ std::vector<block> pblocks;
+ m_core.prepare_handle_incoming_blocks(blocks, pblocks);
+ if (!pblocks.empty() && pblocks.size() != blocks.size())
+ {
+ m_core.cleanup_handle_incoming_blocks();
+ LOG_ERROR_CCONTEXT("Internal error: blocks.size() != block_entry.txs.size()");
+ return 1;
+ }
uint64_t block_process_time_full = 0, transactions_process_time_full = 0;
- size_t num_txs = 0;
+ size_t num_txs = 0, blockidx = 0;
for(const block_complete_entry& block_entry: blocks)
{
if (m_stopping)
@@ -1229,7 +1238,7 @@ namespace cryptonote
TIME_MEASURE_START(block_process_time);
block_verification_context bvc = boost::value_initialized<block_verification_context>();
- m_core.handle_incoming_block(block_entry.block, bvc, false); // <--- process block
+ m_core.handle_incoming_block(block_entry.block, pblocks.empty() ? NULL : &pblocks[blockidx], bvc, false); // <--- process block
if(bvc.m_verifivation_failed)
{
@@ -1272,6 +1281,7 @@ namespace cryptonote
TIME_MEASURE_FINISH(block_process_time);
block_process_time_full += block_process_time;
+ ++blockidx;
} // each download block