Removed on_idle() calls to Blockchain::store_blockchain() for lmdb.
Added option to cache tx-input verification results.
This commit is contained in:
parent
2e293a563e
commit
94ea3e8ed2
@ -290,16 +290,15 @@ void BlockchainLMDB::do_resize(uint64_t increase_size)
|
|||||||
|
|
||||||
mdb_env_stat(m_env, &mst);
|
mdb_env_stat(m_env, &mst);
|
||||||
|
|
||||||
uint64_t new_mapsize = (double)mei.me_mapsize * RESIZE_FACTOR;
|
// add 1Gb per resize, instead of doing a percentage increase
|
||||||
|
uint64_t new_mapsize = (double) mei.me_mapsize + add_size;
|
||||||
|
|
||||||
// If given, use increase_size intead of above way of resizing.
|
// If given, use increase_size intead of above way of resizing.
|
||||||
// This is currently used for increasing by an estimated size at start of new
|
// This is currently used for increasing by an estimated size at start of new
|
||||||
// batch txn.
|
// batch txn.
|
||||||
if (increase_size > 0)
|
if (increase_size > 0)
|
||||||
new_mapsize = mei.me_mapsize + increase_size;
|
new_mapsize = mei.me_mapsize + increase_size;
|
||||||
|
|
||||||
// add 1Gb per resize, instead of doing a percentage increase
|
|
||||||
// uint64_t new_mapsize = (double) mei.me_mapsize + add_size;
|
|
||||||
|
|
||||||
new_mapsize += (new_mapsize % mst.ms_psize);
|
new_mapsize += (new_mapsize % mst.ms_psize);
|
||||||
|
|
||||||
mdb_txn_safe::prevent_new_txns();
|
mdb_txn_safe::prevent_new_txns();
|
||||||
|
@ -1990,6 +1990,14 @@ bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_bloc
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto it = m_check_txin_table.find(tx_prefix_hash);
|
||||||
|
if(it == m_check_txin_table.end())
|
||||||
|
{
|
||||||
|
m_check_txin_table.emplace(tx_prefix_hash, std::unordered_map<crypto::key_image, bool>());
|
||||||
|
it = m_check_txin_table.find(tx_prefix_hash);
|
||||||
|
assert(it != m_check_txin_table.end());
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t t_t1 = 0;
|
uint64_t t_t1 = 0;
|
||||||
std::vector<std::vector<crypto::public_key>> pubkeys(tx.vin.size());
|
std::vector<std::vector<crypto::public_key>> pubkeys(tx.vin.size());
|
||||||
std::vector < uint64_t > results;
|
std::vector < uint64_t > results;
|
||||||
@ -2027,11 +2035,28 @@ bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_bloc
|
|||||||
// basically, make sure number of inputs == number of signatures
|
// basically, make sure number of inputs == number of signatures
|
||||||
CHECK_AND_ASSERT_MES(sig_index < tx.signatures.size(), false, "wrong transaction: not signature entry for input with index= " << sig_index);
|
CHECK_AND_ASSERT_MES(sig_index < tx.signatures.size(), false, "wrong transaction: not signature entry for input with index= " << sig_index);
|
||||||
|
|
||||||
|
#if defined(CACHE_VIN_RESULTS)
|
||||||
|
auto itk = it->second.find(in_to_key.k_image);
|
||||||
|
if(itk != it->second.end())
|
||||||
|
{
|
||||||
|
if(!itk->second)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L1("Failed ring signature for tx " << get_transaction_hash(tx) << " vin key with k_image: " << in_to_key.k_image << " sig_index: " << sig_index);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// txin has been verified already, skip
|
||||||
|
sig_index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// make sure that output being spent matches up correctly with the
|
// make sure that output being spent matches up correctly with the
|
||||||
// signature spending it.
|
// signature spending it.
|
||||||
TIME_MEASURE_START(aa);
|
TIME_MEASURE_START(aa);
|
||||||
if (!check_tx_input(in_to_key, tx_prefix_hash, tx.signatures[sig_index], pubkeys[sig_index], pmax_used_block_height))
|
if (!check_tx_input(in_to_key, tx_prefix_hash, tx.signatures[sig_index], pubkeys[sig_index], pmax_used_block_height))
|
||||||
{
|
{
|
||||||
|
it->second[in_to_key.k_image] = false;
|
||||||
LOG_PRINT_L1("Failed to check ring signature for tx " << get_transaction_hash(tx) << " vin key with k_image: " << in_to_key.k_image << " sig_index: " << sig_index);
|
LOG_PRINT_L1("Failed to check ring signature for tx " << get_transaction_hash(tx) << " vin key with k_image: " << in_to_key.k_image << " sig_index: " << sig_index);
|
||||||
if (pmax_used_block_height) // a default value of NULL is used when called from Blockchain::handle_block_to_main_chain()
|
if (pmax_used_block_height) // a default value of NULL is used when called from Blockchain::handle_block_to_main_chain()
|
||||||
{
|
{
|
||||||
@ -2054,6 +2079,7 @@ bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_bloc
|
|||||||
check_ring_signature(tx_prefix_hash, in_to_key.k_image, pubkeys[sig_index], tx.signatures[sig_index], results[sig_index]);
|
check_ring_signature(tx_prefix_hash, in_to_key.k_image, pubkeys[sig_index], tx.signatures[sig_index], results[sig_index]);
|
||||||
if (!results[sig_index])
|
if (!results[sig_index])
|
||||||
{
|
{
|
||||||
|
it->second[in_to_key.k_image] = false;
|
||||||
LOG_PRINT_L1("Failed to check ring signature for tx " << get_transaction_hash(tx) << " vin key with k_image: " << in_to_key.k_image << " sig_index: " << sig_index);
|
LOG_PRINT_L1("Failed to check ring signature for tx " << get_transaction_hash(tx) << " vin key with k_image: " << in_to_key.k_image << " sig_index: " << sig_index);
|
||||||
|
|
||||||
if (pmax_used_block_height) // a default value of NULL is used when called from Blockchain::handle_block_to_main_chain()
|
if (pmax_used_block_height) // a default value of NULL is used when called from Blockchain::handle_block_to_main_chain()
|
||||||
@ -2064,6 +2090,7 @@ bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_bloc
|
|||||||
KILL_IOSERVICE();
|
KILL_IOSERVICE();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
it->second[in_to_key.k_image] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sig_index++;
|
sig_index++;
|
||||||
@ -2073,13 +2100,20 @@ bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_bloc
|
|||||||
|
|
||||||
if (threads > 1)
|
if (threads > 1)
|
||||||
{
|
{
|
||||||
|
// save results to table, passed or otherwise
|
||||||
|
bool failed = false;
|
||||||
for (size_t i = 0; i < tx.vin.size(); i++)
|
for (size_t i = 0; i < tx.vin.size(); i++)
|
||||||
{
|
{
|
||||||
if (!results[i])
|
const txin_to_key& in_to_key = boost::get<txin_to_key>(tx.vin[i]);
|
||||||
{
|
it->second[in_to_key.k_image] = results[i];
|
||||||
LOG_PRINT_L1("Failed to check ring signatures!");
|
if(!failed && !results[i])
|
||||||
return false;
|
failed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
LOG_PRINT_L1("Failed to check ring signatures!, t_loop: " << t_t1);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_PRINT_L1("t_loop: " << t_t1);
|
LOG_PRINT_L1("t_loop: " << t_t1);
|
||||||
@ -2714,6 +2748,7 @@ bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync)
|
|||||||
m_scan_table.clear();
|
m_scan_table.clear();
|
||||||
m_check_tx_inputs_table.clear();
|
m_check_tx_inputs_table.clear();
|
||||||
m_blocks_txs_check.clear();
|
m_blocks_txs_check.clear();
|
||||||
|
m_check_txin_table.clear();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2859,6 +2894,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::list<block_complete_e
|
|||||||
|
|
||||||
m_scan_table.clear();
|
m_scan_table.clear();
|
||||||
m_check_tx_inputs_table.clear();
|
m_check_tx_inputs_table.clear();
|
||||||
|
m_check_txin_table.clear();
|
||||||
|
|
||||||
TIME_MEASURE_FINISH(prepare);
|
TIME_MEASURE_FINISH(prepare);
|
||||||
m_fake_pow_calc_time = prepare / blocks_entry.size();
|
m_fake_pow_calc_time = prepare / blocks_entry.size();
|
||||||
|
@ -191,6 +191,7 @@ namespace cryptonote
|
|||||||
std::unordered_map<crypto::hash, std::unordered_map<crypto::key_image, std::vector<output_data_t>>> m_scan_table;
|
std::unordered_map<crypto::hash, std::unordered_map<crypto::key_image, std::vector<output_data_t>>> m_scan_table;
|
||||||
std::unordered_map<crypto::hash, std::pair<bool, uint64_t>> m_check_tx_inputs_table;
|
std::unordered_map<crypto::hash, std::pair<bool, uint64_t>> m_check_tx_inputs_table;
|
||||||
std::unordered_map<crypto::hash, crypto::hash> m_blocks_longhash_table;
|
std::unordered_map<crypto::hash, crypto::hash> m_blocks_longhash_table;
|
||||||
|
std::unordered_map<crypto::hash, std::unordered_map<crypto::key_image, bool>> m_check_txin_table;
|
||||||
|
|
||||||
// SHA-3 hashes for each block and for fast pow checking
|
// SHA-3 hashes for each block and for fast pow checking
|
||||||
std::vector<crypto::hash> m_blocks_hash_check;
|
std::vector<crypto::hash> m_blocks_hash_check;
|
||||||
|
@ -811,7 +811,7 @@ namespace cryptonote
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if BLOCKCHAIN_DB == DB_LMDB
|
#if BLOCKCHAIN_DB == DB_LMDB
|
||||||
m_store_blockchain_interval.do_call(boost::bind(&Blockchain::store_blockchain, &m_blockchain_storage));
|
// m_store_blockchain_interval.do_call(boost::bind(&Blockchain::store_blockchain, &m_blockchain_storage));
|
||||||
#else
|
#else
|
||||||
m_store_blockchain_interval.do_call(boost::bind(&blockchain_storage::store_blockchain, &m_blockchain_storage));
|
m_store_blockchain_interval.do_call(boost::bind(&blockchain_storage::store_blockchain, &m_blockchain_storage));
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user