core: avoid double parsing blocks after hoh
This commit is contained in:
parent
dc5a76095c
commit
238401d4e9
|
@ -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.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)
|
for(const block_complete_entry& block_entry: blocks)
|
||||||
{
|
{
|
||||||
// process transactions
|
// 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>();
|
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)
|
if(bvc.m_verifivation_failed)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
// 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
|
// and is threaded if possible. The table (m_scan_table) will be used later when querying output
|
||||||
// keys.
|
// 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__);
|
MTRACE("Blockchain::" << __func__);
|
||||||
TIME_MEASURE_START(prepare);
|
TIME_MEASURE_START(prepare);
|
||||||
bool stop_batch;
|
bool stop_batch;
|
||||||
uint64_t bytes = 0;
|
uint64_t bytes = 0;
|
||||||
size_t total_txs = 0;
|
size_t total_txs = 0;
|
||||||
|
blocks.clear();
|
||||||
|
|
||||||
// Order of locking must be:
|
// Order of locking must be:
|
||||||
// m_incoming_tx_lock (optional)
|
// m_incoming_tx_lock (optional)
|
||||||
|
@ -4264,7 +4265,6 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
|
||||||
bool blocks_exist = false;
|
bool blocks_exist = false;
|
||||||
tools::threadpool& tpool = tools::threadpool::getInstance();
|
tools::threadpool& tpool = tools::threadpool::getInstance();
|
||||||
unsigned threads = tpool.get_max_concurrency();
|
unsigned threads = tpool.get_max_concurrency();
|
||||||
std::vector<block> blocks;
|
|
||||||
blocks.resize(blocks_entry.size());
|
blocks.resize(blocks_entry.size());
|
||||||
|
|
||||||
if (1)
|
if (1)
|
||||||
|
|
|
@ -230,11 +230,12 @@ namespace cryptonote
|
||||||
/**
|
/**
|
||||||
* @brief performs some preprocessing on a group of incoming blocks to speed up verification
|
* @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
|
* @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
|
* @brief incoming blocks post-processing, cleanup, and disk sync
|
||||||
|
|
|
@ -1330,7 +1330,8 @@ namespace cryptonote
|
||||||
m_miner.resume();
|
m_miner.resume();
|
||||||
return false;
|
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);
|
m_blockchain_storage.add_new_block(b, bvc);
|
||||||
cleanup_handle_incoming_blocks(true);
|
cleanup_handle_incoming_blocks(true);
|
||||||
//anyway - update miner template
|
//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_incoming_tx_lock.lock();
|
||||||
m_blockchain_storage.prepare_handle_incoming_blocks(blocks);
|
m_blockchain_storage.prepare_handle_incoming_blocks(blocks_entry, blocks);
|
||||||
return true;
|
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();
|
TRY_ENTRY();
|
||||||
|
|
||||||
|
@ -1417,14 +1418,18 @@ namespace cryptonote
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
block b = AUTO_VAL_INIT(b);
|
block lb;
|
||||||
if(!parse_and_validate_block_from_blob(block_blob, b))
|
if (!b)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L1("Failed to parse and validate new block");
|
if(!parse_and_validate_block_from_blob(block_blob, lb))
|
||||||
bvc.m_verifivation_failed = true;
|
{
|
||||||
return false;
|
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)
|
if(update_miner_blocktemplate && bvc.m_added_to_main_chain)
|
||||||
update_miner_block_template();
|
update_miner_block_template();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -146,20 +146,21 @@ namespace cryptonote
|
||||||
* optionally updates the miner's block template.
|
* optionally updates the miner's block template.
|
||||||
*
|
*
|
||||||
* @param block_blob the block to be added
|
* @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 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
|
* @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
|
* @return false if loading new checkpoints fails, or the block is not
|
||||||
* added, otherwise true
|
* 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
|
* @copydoc Blockchain::prepare_handle_incoming_blocks
|
||||||
*
|
*
|
||||||
* @note see 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
|
* @copydoc Blockchain::cleanup_handle_incoming_blocks
|
||||||
|
|
|
@ -418,7 +418,8 @@ namespace cryptonote
|
||||||
m_core.pause_mine();
|
m_core.pause_mine();
|
||||||
std::vector<block_complete_entry> blocks;
|
std::vector<block_complete_entry> blocks;
|
||||||
blocks.push_back(arg.b);
|
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++)
|
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);
|
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>();
|
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))
|
if (!m_core.cleanup_handle_incoming_blocks(true))
|
||||||
{
|
{
|
||||||
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
|
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
|
||||||
|
@ -697,10 +698,11 @@ namespace cryptonote
|
||||||
|
|
||||||
std::vector<block_complete_entry> blocks;
|
std::vector<block_complete_entry> blocks;
|
||||||
blocks.push_back(b);
|
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>();
|
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))
|
if (!m_core.cleanup_handle_incoming_blocks(true))
|
||||||
{
|
{
|
||||||
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
|
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;
|
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)
|
for(const block_complete_entry& block_entry: blocks)
|
||||||
{
|
{
|
||||||
if (m_stopping)
|
if (m_stopping)
|
||||||
|
@ -1229,7 +1238,7 @@ namespace cryptonote
|
||||||
TIME_MEASURE_START(block_process_time);
|
TIME_MEASURE_START(block_process_time);
|
||||||
block_verification_context bvc = boost::value_initialized<block_verification_context>();
|
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)
|
if(bvc.m_verifivation_failed)
|
||||||
{
|
{
|
||||||
|
@ -1272,6 +1281,7 @@ namespace cryptonote
|
||||||
|
|
||||||
TIME_MEASURE_FINISH(block_process_time);
|
TIME_MEASURE_FINISH(block_process_time);
|
||||||
block_process_time_full += block_process_time;
|
block_process_time_full += block_process_time;
|
||||||
|
++blockidx;
|
||||||
|
|
||||||
} // each download block
|
} // each download block
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue