From a26f6fead69e25279b21dcec952eff40ccebb49d Mon Sep 17 00:00:00 2001 From: sanket1729 Date: Mon, 25 Jan 2021 19:38:15 -0800 Subject: [PATCH] Expose only blockchain hash twice in header --- src/bench/verify_script.cpp | 2 +- src/chainparams.h | 2 +- src/script/bitcoinconsensus.cpp | 15 ++++++------- src/script/bitcoinconsensus.h | 4 ++-- src/script/interpreter.cpp | 6 +++--- src/script/interpreter.h | 4 ++-- src/test/fuzz/script_bitcoin_consensus.cpp | 6 ++++-- src/test/script_tests.cpp | 25 +++++++++++----------- src/validation.cpp | 7 ++++-- 9 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp index b81e7c5f7f..c372f2607e 100644 --- a/src/bench/verify_script.cpp +++ b/src/bench/verify_script.cpp @@ -68,7 +68,7 @@ static void VerifyScriptBench(benchmark::Bench& bench) CDataStream streamVal(SER_NETWORK, PROTOCOL_VERSION); streamVal << txCredit.vout[0].nValue; int csuccess = bitcoinconsensus_verify_script_with_amount( - NULL, NULL, + NULL, txCredit.vout[0].scriptPubKey.data(), txCredit.vout[0].scriptPubKey.size(), (const unsigned char*)&streamVal[0], streamVal.size(), diff --git a/src/chainparams.h b/src/chainparams.h index 26c01beac1..4c203f00ba 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -98,7 +98,7 @@ public: const ChainTxData& TxData() const { return chainTxData; } // ELEMENTS extra fields: const uint256& ParentGenesisBlockHash() const { return parentGenesisBlockHash; } - const CAsset& ParentPeggedAsset() const { return consensus.parent_pegged_asset; } + const uint256& HashGenesisBlock() const { return consensus.hashGenesisBlock; } bool anyonecanspend_aremine; const std::string& ParentBech32HRP() const { return parent_bech32_hrp; } const std::string& ParentBlech32HRP() const { return parent_blech32_hrp; } diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 4c10eed2ca..5c5e01b6fb 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -77,7 +77,7 @@ static bool verify_flags(unsigned int flags) return (flags & ~(bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL)) == 0; } -static int verify_script(const unsigned char *parent_genesis_hash, const unsigned char *parent_pegged_asset, +static int verify_script(const unsigned char *hash_genesis_block, const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, CConfidentialValue amount, const unsigned char *txTo , unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err) @@ -96,9 +96,8 @@ static int verify_script(const unsigned char *parent_genesis_hash, const unsigne // Regardless of the verification result, the tx did not error. set_error(err, bitcoinconsensus_ERR_OK); - auto parent_genesis_hash_ = parent_genesis_hash ? uint256{parent_genesis_hash, 32} : uint256{}; - auto parent_pegged_asset_ = CAsset(parent_pegged_asset ? uint256{parent_pegged_asset, 32} : uint256{}); - PrecomputedTransactionData txdata(parent_genesis_hash_, parent_pegged_asset_); + auto hash_genesis_block_ = hash_genesis_block ? uint256{hash_genesis_block, 32} : uint256{}; + PrecomputedTransactionData txdata(hash_genesis_block_); txdata.Init(tx, {}); const CScriptWitness* pScriptWitness = (tx.witness.vtxinwit.size() > nIn ? &tx.witness.vtxinwit[nIn].scriptWitness : NULL); return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), pScriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata), NULL); @@ -107,7 +106,7 @@ static int verify_script(const unsigned char *parent_genesis_hash, const unsigne } } -int bitcoinconsensus_verify_script_with_amount(const unsigned char *parent_genesis_hash, const unsigned char *parent_pegged_asset, +int bitcoinconsensus_verify_script_with_amount(const unsigned char *hash_genesis_block, const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char *amount, unsigned int amountLen, const unsigned char *txTo , unsigned int txToLen, @@ -118,14 +117,14 @@ int bitcoinconsensus_verify_script_with_amount(const unsigned char *parent_genes CConfidentialValue am; stream >> am; - return ::verify_script(parent_genesis_hash, parent_pegged_asset, scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, nIn, flags, err); + return ::verify_script(hash_genesis_block, scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, nIn, flags, err); } catch (const std::exception&) { return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing } } -int bitcoinconsensus_verify_script(const unsigned char *parent_genesis_hash, const unsigned char *parent_pegged_asset, +int bitcoinconsensus_verify_script(const unsigned char *hash_genesis_block, const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char *txTo , unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err) @@ -135,7 +134,7 @@ int bitcoinconsensus_verify_script(const unsigned char *parent_genesis_hash, con } CConfidentialValue am(0); - return ::verify_script(parent_genesis_hash, parent_pegged_asset, scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, nIn, flags, err); + return ::verify_script(hash_genesis_block, scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, nIn, flags, err); } unsigned int bitcoinconsensus_version() diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index 472aaf5a16..e317a08e3a 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -64,12 +64,12 @@ enum /// txTo correctly spends the scriptPubKey pointed to by scriptPubKey under /// the additional constraints specified by flags. /// If not nullptr, err will contain an error/success code for the operation -EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *parent_genesis_hash, const unsigned char *parent_pegged_asset, +EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *hash_genesis_block, const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char *txTo , unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err); -EXPORT_SYMBOL int bitcoinconsensus_verify_script_with_amount(const unsigned char *parent_genesis_hash, const unsigned char *parent_pegged_asset, +EXPORT_SYMBOL int bitcoinconsensus_verify_script_with_amount(const unsigned char *hash_genesis_block, const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char *amount, unsigned int amountLen, const unsigned char *txTo , unsigned int txToLen, diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 57c116b812..7ba3c67aea 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1896,7 +1896,7 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector&& spent template PrecomputedTransactionData::PrecomputedTransactionData(const T& txTo) - : PrecomputedTransactionData(uint256{}, CAsset{}) + : PrecomputedTransactionData(uint256{}) { Init(txTo, {}); } @@ -1912,8 +1912,8 @@ static const CHashWriter HASHER_TAPBRANCH = TaggedHash("TapBranch"); static const CHashWriter HASHER_TAPTWEAK = TaggedHash("TapTweak"); static const CHashWriter HASHER_TAPSIGHASH = TaggedHash("TapSighash"); -PrecomputedTransactionData::PrecomputedTransactionData(const uint256& parent_genesis_hash, const CAsset& parent_pegged_asset) - : m_tapsighash_hasher(CHashWriter(HASHER_TAPSIGHASH) << parent_genesis_hash << parent_pegged_asset) {} +PrecomputedTransactionData::PrecomputedTransactionData(const uint256& hash_genesis_block) + : m_tapsighash_hasher(CHashWriter(HASHER_TAPSIGHASH) << hash_genesis_block << hash_genesis_block) {} template bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache) diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 8be688c105..a5429eae4e 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -182,8 +182,8 @@ struct PrecomputedTransactionData //! ELEMENTS: parent genesis hash CHashWriter m_tapsighash_hasher; - explicit PrecomputedTransactionData(const uint256& parent_genesis_hash, const CAsset& parent_pegged_asset); - explicit PrecomputedTransactionData() : PrecomputedTransactionData(uint256{}, CAsset()) {} + explicit PrecomputedTransactionData(const uint256& hash_genesis_block); + explicit PrecomputedTransactionData() : PrecomputedTransactionData(uint256{}) {} template void Init(const T& tx, std::vector&& spent_outputs); diff --git a/src/test/fuzz/script_bitcoin_consensus.cpp b/src/test/fuzz/script_bitcoin_consensus.cpp index 22ed4b021e..1880bf65df 100644 --- a/src/test/fuzz/script_bitcoin_consensus.cpp +++ b/src/test/fuzz/script_bitcoin_consensus.cpp @@ -17,6 +17,8 @@ void test_one_input(const std::vector& buffer) FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); const std::vector random_bytes_1 = ConsumeRandomLengthByteVector(fuzzed_data_provider); const std::vector random_bytes_2 = ConsumeRandomLengthByteVector(fuzzed_data_provider); + const uint256 random_hash = ConsumeUInt256(fuzzed_data_provider); + const std::optional money = ConsumeDeserializable(fuzzed_data_provider); bitcoinconsensus_error err; bitcoinconsensus_error* err_p = fuzzed_data_provider.ConsumeBool() ? &err : nullptr; @@ -26,10 +28,10 @@ void test_one_input(const std::vector& buffer) if ((flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) { return; } - (void)bitcoinconsensus_verify_script(random_bytes_1.data(), random_bytes_1.size(), random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p); + (void)bitcoinconsensus_verify_script(random_hash.begin() ,random_bytes_1.data(), random_bytes_1.size(), random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p); if (money) { CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION); data_stream << *money; - (void)bitcoinconsensus_verify_script_with_amount(random_bytes_1.data(), random_bytes_1.size(), (unsigned char*) data_stream.data(), data_stream.size(), random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p); + (void)bitcoinconsensus_verify_script_with_amount(random_hash.begin(), random_bytes_1.data(), random_bytes_1.size(), (unsigned char*) data_stream.data(), data_stream.size(), random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p); } } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index cd1365b776..5a6e45ad3d 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -159,10 +159,10 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript if (libconsensus_flags == flags) { int expectedSuccessCode = expect ? 1 : 0; if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) { - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(NULL, NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&streamVal[0], streamVal.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&streamVal[0], streamVal.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); } else { - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(NULL, NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&streamVal0[0], streamVal0.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); - BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(NULL, NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&streamVal0[0], streamVal0.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); } } #endif @@ -1524,7 +1524,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_returns_true) stream << spendTx; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(NULL, NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 1); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_OK); } @@ -1547,7 +1547,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_index_err) stream << spendTx; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(NULL, NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_INDEX); } @@ -1570,7 +1570,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_size) stream << spendTx; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(NULL, NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size() * 2, nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size() * 2, nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH); } @@ -1593,7 +1593,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_serialization) stream << 0xffffffff; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(NULL, NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_DESERIALIZE); } @@ -1616,7 +1616,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_amount_required_err) stream << spendTx; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(NULL, NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED); } @@ -1639,7 +1639,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_invalid_flags) stream << spendTx; bitcoinconsensus_error err; - int result = bitcoinconsensus_verify_script(NULL, NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err); + int result = bitcoinconsensus_verify_script(NULL, scriptPubKey.data(), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), nIn, libconsensus_flags, &err); BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_INVALID_FLAGS); } @@ -1686,14 +1686,13 @@ static void AssetTest(const UniValue& test) unsigned int test_flags = ParseScriptFlags(test["flags"].get_str()); bool fin = test.exists("final") && test["final"].get_bool(); // ELEMENTS FIXME: update feature_taproot.py --dumptests to actually output these - uint256 parent_genesis_hash = test.exists("parent_genesis_hash") ? uint256S(test["parent_genesis_hash"].get_str()) : uint256{}; - CAsset parent_pegged_asset = test.exists("parent_pegged_asset") ? CAsset{uint256S(test["parent_pegged_asset"].get_str())} : CAsset{}; + uint256 hash_genesis_block = test.exists("hash_genesis_block") ? uint256S(test["hash_genesis_block"].get_str()) : uint256{}; if (test.exists("success")) { mtx.vin[idx].scriptSig = ScriptFromHex(test["success"]["scriptSig"].get_str()); mtx.witness.vtxinwit[idx].scriptWitness = ScriptWitnessFromJSON(test["success"]["witness"]); CTransaction tx(mtx); - PrecomputedTransactionData txdata(parent_genesis_hash, parent_pegged_asset); + PrecomputedTransactionData txdata(hash_genesis_block); txdata.Init(tx, std::vector(prevouts)); CachingTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, true, txdata); for (const auto flags : ALL_CONSENSUS_FLAGS) { @@ -1710,7 +1709,7 @@ static void AssetTest(const UniValue& test) mtx.vin[idx].scriptSig = ScriptFromHex(test["failure"]["scriptSig"].get_str()); mtx.witness.vtxinwit[idx].scriptWitness = ScriptWitnessFromJSON(test["failure"]["witness"]); CTransaction tx(mtx); - PrecomputedTransactionData txdata(parent_genesis_hash, parent_pegged_asset); + PrecomputedTransactionData txdata(hash_genesis_block); txdata.Init(tx, std::vector(prevouts)); CachingTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, true, txdata); for (const auto flags : ALL_CONSENSUS_FLAGS) { diff --git a/src/validation.cpp b/src/validation.cpp index ae2669a3ed..df5f4ee8ab 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1120,7 +1120,7 @@ bool MemPoolAccept::AcceptSingleTransaction(const CTransactionRef& ptx, ATMPArgs // scripts (ie, other policy checks pass). We perform the inexpensive // checks first and avoid hashing and signature verification unless those // checks pass, to mitigate CPU exhaustion denial-of-service attacks. - PrecomputedTransactionData txdata(args.m_chainparams.ParentGenesisBlockHash(), args.m_chainparams.ParentPeggedAsset()); + PrecomputedTransactionData txdata(args.m_chainparams.HashGenesisBlock()); if (!PolicyScriptChecks(args, workspace, txdata)) return false; @@ -2296,7 +2296,10 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, // doesn't invalidate pointers into the vector, and keep txsdata in scope // for as long as `control`. CCheckQueueControl control(fScriptChecks && g_parallel_script_checks ? &scriptcheckqueue : nullptr); - std::vector txsdata(block.vtx.size()); + std::vector txsdata; + for (unsigned int i = 0; i< block.vtx.size(); i++ ){ + txsdata.push_back(PrecomputedTransactionData(chainparams.HashGenesisBlock())); + } std::vector prevheights; CAmountMap fee_map;