aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
authorNoodleDoodleNoodleDoodleNoodleDoodleNoo <xeven77@outlook.com>2015-07-14 22:47:07 -0700
committerNoodleDoodleNoodleDoodleNoodleDoodleNoo <xeven77@outlook.com>2015-07-15 23:20:25 -0700
commit94ea3e8ed2835a7694c4c653f0092adc2d3b8e70 (patch)
tree916e82da3f91771d4e74172d2e6b7b61385fc6ee /src/cryptonote_core
parentFixed binary size issue due to embedded checkpoint data. (diff)
downloadmonero-94ea3e8ed2835a7694c4c653f0092adc2d3b8e70.tar.xz
Removed on_idle() calls to Blockchain::store_blockchain() for lmdb.
Added option to cache tx-input verification results.
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/blockchain.cpp48
-rw-r--r--src/cryptonote_core/blockchain.h1
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp2
-rw-r--r--src/cryptonote_core/tx_pool.cpp12
4 files changed, 50 insertions, 13 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 31e517ff0..ea107abb6 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<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;
std::vector<std::vector<crypto::public_key>> 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<txin_to_key>(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<block_complete_e
m_scan_table.clear();
m_check_tx_inputs_table.clear();
+ m_check_txin_table.clear();
TIME_MEASURE_FINISH(prepare);
m_fake_pow_calc_time = prepare / blocks_entry.size();
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index c3d01c65a..1c6f58dbf 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -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::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, std::unordered_map<crypto::key_image, bool>> m_check_txin_table;
// SHA-3 hashes for each block and for fast pow checking
std::vector<crypto::hash> m_blocks_hash_check;
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 7b96988e3..31e46b534 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 ac71a0e52..12fd3fe62 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);