aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core/blockchain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_core/blockchain.cpp')
-rw-r--r--src/cryptonote_core/blockchain.cpp81
1 files changed, 18 insertions, 63 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 8edb33b5a..28d52a2d1 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -57,6 +57,7 @@
#include "common/notify.h"
#include "common/varint.h"
#include "common/pruning.h"
+#include "common/data_cache.h"
#include "time_helper.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
@@ -98,7 +99,8 @@ Blockchain::Blockchain(tx_memory_pool& tx_pool) :
m_difficulty_for_next_block(1),
m_btc_valid(false),
m_batch_success(true),
- m_prepare_height(0)
+ m_prepare_height(0),
+ m_rct_ver_cache()
{
LOG_PRINT_L3("Blockchain::" << __func__);
}
@@ -3211,7 +3213,7 @@ bool Blockchain::have_tx_keyimges_as_spent(const transaction &tx) const
}
return false;
}
-bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector<std::vector<rct::ctkey>> &pubkeys) const
+bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector<std::vector<rct::ctkey>> &pubkeys)
{
PERF_TIMER(expand_transaction_2);
CHECK_AND_ASSERT_MES(tx.version == 2, false, "Transaction version is not 2");
@@ -3534,6 +3536,13 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
false, "Transaction spends at least one output which is too young");
}
+ // Warn that new RCT types are present, and thus the cache is not being used effectively
+ static constexpr const std::uint8_t RCT_CACHE_TYPE = rct::RCTTypeBulletproofPlus;
+ if (tx.rct_signatures.type > RCT_CACHE_TYPE)
+ {
+ MWARNING("RCT cache is not caching new verification results. Please update RCT_CACHE_TYPE!");
+ }
+
if (tx.version == 1)
{
if (threads > 1)
@@ -3555,12 +3564,6 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
}
else
{
- if (!expand_transaction_2(tx, tx_prefix_hash, pubkeys))
- {
- MERROR_VER("Failed to expand rct signatures!");
- return false;
- }
-
// from version 2, check ringct signatures
// obviously, the original and simple rct APIs use a mixRing that's indexes
// in opposite orders, because it'd be too simple otherwise...
@@ -3578,61 +3581,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
case rct::RCTTypeCLSAG:
case rct::RCTTypeBulletproofPlus:
{
- // check all this, either reconstructed (so should really pass), or not
- {
- if (pubkeys.size() != rv.mixRing.size())
- {
- MERROR_VER("Failed to check ringct signatures: mismatched pubkeys/mixRing size");
- return false;
- }
- for (size_t i = 0; i < pubkeys.size(); ++i)
- {
- if (pubkeys[i].size() != rv.mixRing[i].size())
- {
- MERROR_VER("Failed to check ringct signatures: mismatched pubkeys/mixRing size");
- return false;
- }
- }
-
- for (size_t n = 0; n < pubkeys.size(); ++n)
- {
- for (size_t m = 0; m < pubkeys[n].size(); ++m)
- {
- if (pubkeys[n][m].dest != rct::rct2pk(rv.mixRing[n][m].dest))
- {
- MERROR_VER("Failed to check ringct signatures: mismatched pubkey at vin " << n << ", index " << m);
- return false;
- }
- if (pubkeys[n][m].mask != rct::rct2pk(rv.mixRing[n][m].mask))
- {
- MERROR_VER("Failed to check ringct signatures: mismatched commitment at vin " << n << ", index " << m);
- return false;
- }
- }
- }
- }
-
- const size_t n_sigs = rct::is_rct_clsag(rv.type) ? rv.p.CLSAGs.size() : rv.p.MGs.size();
- if (n_sigs != tx.vin.size())
- {
- MERROR_VER("Failed to check ringct signatures: mismatched MGs/vin sizes");
- return false;
- }
- for (size_t n = 0; n < tx.vin.size(); ++n)
- {
- bool error;
- if (rct::is_rct_clsag(rv.type))
- error = memcmp(&boost::get<txin_to_key>(tx.vin[n]).k_image, &rv.p.CLSAGs[n].I, 32);
- else
- error = rv.p.MGs[n].II.empty() || memcmp(&boost::get<txin_to_key>(tx.vin[n]).k_image, &rv.p.MGs[n].II[0], 32);
- if (error)
- {
- MERROR_VER("Failed to check ringct signatures: mismatched key image");
- return false;
- }
- }
-
- if (!rct::verRctNonSemanticsSimpleCached(rv))
+ if (!ver_rct_non_semantics_simple_cached(tx, pubkeys, m_rct_ver_cache, RCT_CACHE_TYPE))
{
MERROR_VER("Failed to check ringct signatures!");
return false;
@@ -3641,6 +3590,12 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
}
case rct::RCTTypeFull:
{
+ if (!expand_transaction_2(tx, tx_prefix_hash, pubkeys))
+ {
+ MERROR_VER("Failed to expand rct signatures!");
+ return false;
+ }
+
// check all this, either reconstructed (so should really pass), or not
{
bool size_matches = true;