From 94ea3e8ed2835a7694c4c653f0092adc2d3b8e70 Mon Sep 17 00:00:00 2001 From: NoodleDoodleNoodleDoodleNoodleDoodleNoo Date: Tue, 14 Jul 2015 22:47:07 -0700 Subject: [PATCH] Removed on_idle() calls to Blockchain::store_blockchain() for lmdb. Added option to cache tx-input verification results. --- src/blockchain_db/lmdb/db_lmdb.cpp | 7 ++-- src/cryptonote_core/blockchain.cpp | 48 +++++++++++++++++++++---- src/cryptonote_core/blockchain.h | 1 + src/cryptonote_core/cryptonote_core.cpp | 2 +- src/cryptonote_core/tx_pool.cpp | 12 +++---- 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 1304795f..63ac5417 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -290,16 +290,15 @@ void BlockchainLMDB::do_resize(uint64_t increase_size) 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. // This is currently used for increasing by an estimated size at start of new // batch txn. if (increase_size > 0) 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); mdb_txn_safe::prevent_new_txns(); diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 31e517ff..ea107abb 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1990,6 +1990,14 @@ bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_bloc 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()); + it = m_check_txin_table.find(tx_prefix_hash); + assert(it != m_check_txin_table.end()); + } + uint64_t t_t1 = 0; std::vector> pubkeys(tx.vin.size()); 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 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 // signature spending it. 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)) { + 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); 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]); 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); 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(); return false; } + it->second[in_to_key.k_image] = true; } sig_index++; @@ -2073,13 +2100,20 @@ bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_bloc if (threads > 1) { - for (size_t i = 0; i < tx.vin.size(); i++) + // save results to table, passed or otherwise + bool failed = false; + for (size_t i = 0; i < tx.vin.size(); i++) + { + const txin_to_key& in_to_key = boost::get(tx.vin[i]); + it->second[in_to_key.k_image] = results[i]; + if(!failed && !results[i]) + failed = true; + } + + if (failed) { - if (!results[i]) - { - LOG_PRINT_L1("Failed to check ring signatures!"); - return false; - } + LOG_PRINT_L1("Failed to check ring signatures!, t_loop: " << t_t1); + return false; } } 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_check_tx_inputs_table.clear(); m_blocks_txs_check.clear(); + m_check_txin_table.clear(); return true; } @@ -2859,6 +2894,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::list>> m_scan_table; std::unordered_map> m_check_tx_inputs_table; std::unordered_map m_blocks_longhash_table; + std::unordered_map> m_check_txin_table; // SHA-3 hashes for each block and for fast pow checking std::vector m_blocks_hash_check; diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 7b96988e..31e46b53 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -811,7 +811,7 @@ namespace cryptonote } #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 m_store_blockchain_interval.do_call(boost::bind(&blockchain_storage::store_blockchain, &m_blockchain_storage)); #endif diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index ac71a0e5..12fd3fe6 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -511,8 +511,8 @@ namespace cryptonote // Can not exceed maximum block size if (max_total_size < total_size + tx_it->second.blob_size) { - sorted_it++; - continue; + sorted_it++; + continue; } // If adding this tx will make the block size @@ -522,8 +522,8 @@ namespace cryptonote // to propagate at 60s block times. if ( (total_size + tx_it->second.blob_size) > CRYPTONOTE_GETBLOCKTEMPLATE_MAX_BLOCK_SIZE ) { - sorted_it++; - continue; + sorted_it++; + continue; } // If we've exceeded the penalty free size, @@ -536,8 +536,8 @@ namespace cryptonote // missing key images if (!is_transaction_ready_to_go(tx_it->second) || have_key_images(k_images, tx_it->second.tx)) { - sorted_it++; - continue; + sorted_it++; + continue; } bl.tx_hashes.push_back(tx_it->first);