From 18dacf9bd25154e184b097ee4e8f786d9be25637 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Sun, 2 Oct 2016 17:38:48 -0400 Subject: Add microbenchmarks to profile more code paths. The new benchmarks exercise script validation, CCoinsDBView caching, mempool eviction, and wallet coin selection code. All of the benchmarks added here are extremely simple and don't necessarily mirror common real world conditions or interesting performance edge cases. Details about how specific benchmarks can be improved are noted in comments. Github-Issue: #7883 --- src/bench/verify_script.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/bench/verify_script.cpp (limited to 'src/bench/verify_script.cpp') diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp new file mode 100644 index 000000000..dc3940cdb --- /dev/null +++ b/src/bench/verify_script.cpp @@ -0,0 +1,103 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "bench.h" +#include "key.h" +#if defined(HAVE_CONSENSUS_LIB) +#include "script/bitcoinconsensus.h" +#endif +#include "script/script.h" +#include "script/sign.h" +#include "streams.h" + +// FIXME: Dedup with BuildCreditingTransaction in test/script_tests.cpp. +static CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey) +{ + CMutableTransaction txCredit; + txCredit.nVersion = 1; + txCredit.nLockTime = 0; + txCredit.vin.resize(1); + txCredit.vout.resize(1); + txCredit.vin[0].prevout.SetNull(); + txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0); + txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL; + txCredit.vout[0].scriptPubKey = scriptPubKey; + txCredit.vout[0].nValue = 1; + + return txCredit; +} + +// FIXME: Dedup with BuildSpendingTransaction in test/script_tests.cpp. +static CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMutableTransaction& txCredit) +{ + CMutableTransaction txSpend; + txSpend.nVersion = 1; + txSpend.nLockTime = 0; + txSpend.vin.resize(1); + txSpend.vout.resize(1); + txSpend.wit.vtxinwit.resize(1); + txSpend.vin[0].prevout.hash = txCredit.GetHash(); + txSpend.vin[0].prevout.n = 0; + txSpend.vin[0].scriptSig = scriptSig; + txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL; + txSpend.vout[0].scriptPubKey = CScript(); + txSpend.vout[0].nValue = txCredit.vout[0].nValue; + + return txSpend; +} + +// Microbenchmark for verification of a basic P2WPKH script. Can be easily +// modified to measure performance of other types of scripts. +static void VerifyScriptBench(benchmark::State& state) +{ + const int flags = SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH; + const int witnessversion = 0; + + // Keypair. + CKey key; + const unsigned char vchKey[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + key.Set(vchKey, vchKey + 32, false); + CPubKey pubkey = key.GetPubKey(); + uint160 pubkeyHash; + CHash160().Write(pubkey.begin(), pubkey.size()).Finalize(pubkeyHash.begin()); + + // Script. + CScript scriptPubKey = CScript() << witnessversion << ToByteVector(pubkeyHash); + CScript scriptSig; + CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG; + CTransaction txCredit = BuildCreditingTransaction(scriptPubKey); + CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit); + CScriptWitness& witness = txSpend.wit.vtxinwit[0].scriptWitness; + witness.stack.emplace_back(); + key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SIGVERSION_WITNESS_V0), witness.stack.back(), 0); + witness.stack.back().push_back(static_cast(SIGHASH_ALL)); + witness.stack.push_back(ToByteVector(pubkey)); + + // Benchmark. + while (state.KeepRunning()) { + ScriptError err; + bool success = VerifyScript( + txSpend.vin[0].scriptSig, + txCredit.vout[0].scriptPubKey, + &txSpend.wit.vtxinwit[0].scriptWitness, + flags, + MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue), + &err); + assert(err == SCRIPT_ERR_OK); + assert(success); + +#if defined(HAVE_CONSENSUS_LIB) + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << txSpend; + int csuccess = bitcoinconsensus_verify_script_with_amount( + begin_ptr(txCredit.vout[0].scriptPubKey), + txCredit.vout[0].scriptPubKey.size(), + txCredit.vout[0].nValue, + (const unsigned char*)&stream[0], stream.size(), 0, flags, nullptr); + assert(csuccess == 1); +#endif + } +} + +BENCHMARK(VerifyScriptBench); -- cgit v1.2.3 From f6fb7acda4aefd01b8ef6cd77063bfc0c4f4ab36 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 4 Aug 2016 02:49:16 +0200 Subject: Move CTxInWitness inside CTxIn --- src/bench/verify_script.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/bench/verify_script.cpp') diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp index dc3940cdb..4aca1c7eb 100644 --- a/src/bench/verify_script.cpp +++ b/src/bench/verify_script.cpp @@ -36,7 +36,6 @@ static CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, co txSpend.nLockTime = 0; txSpend.vin.resize(1); txSpend.vout.resize(1); - txSpend.wit.vtxinwit.resize(1); txSpend.vin[0].prevout.hash = txCredit.GetHash(); txSpend.vin[0].prevout.n = 0; txSpend.vin[0].scriptSig = scriptSig; @@ -68,7 +67,7 @@ static void VerifyScriptBench(benchmark::State& state) CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG; CTransaction txCredit = BuildCreditingTransaction(scriptPubKey); CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit); - CScriptWitness& witness = txSpend.wit.vtxinwit[0].scriptWitness; + CScriptWitness& witness = txSpend.vin[0].scriptWitness; witness.stack.emplace_back(); key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SIGVERSION_WITNESS_V0), witness.stack.back(), 0); witness.stack.back().push_back(static_cast(SIGHASH_ALL)); @@ -80,7 +79,7 @@ static void VerifyScriptBench(benchmark::State& state) bool success = VerifyScript( txSpend.vin[0].scriptSig, txCredit.vout[0].scriptPubKey, - &txSpend.wit.vtxinwit[0].scriptWitness, + &txSpend.vin[0].scriptWitness, flags, MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue), &err); -- cgit v1.2.3 From 8c1dbc5e9ddbafb77e60e8c4e6eb275a3a76ac12 Mon Sep 17 00:00:00 2001 From: Karl-Johan Alm Date: Fri, 9 Dec 2016 12:01:37 +0900 Subject: Refactor: Removed begin/end_ptr functions. --- src/bench/verify_script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/bench/verify_script.cpp') diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp index dc3940cdb..91b8c4447 100644 --- a/src/bench/verify_script.cpp +++ b/src/bench/verify_script.cpp @@ -91,7 +91,7 @@ static void VerifyScriptBench(benchmark::State& state) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << txSpend; int csuccess = bitcoinconsensus_verify_script_with_amount( - begin_ptr(txCredit.vout[0].scriptPubKey), + txCredit.vout[0].scriptPubKey.data(), txCredit.vout[0].scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)&stream[0], stream.size(), 0, flags, nullptr); -- cgit v1.2.3 From e2300ff65e380bfe1454d0ea42a88abeeb6b8911 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 15 Dec 2016 17:30:17 +0100 Subject: bench: Use CDataStream.data() --- src/bench/verify_script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/bench/verify_script.cpp') diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp index 91b8c4447..d5fdeb731 100644 --- a/src/bench/verify_script.cpp +++ b/src/bench/verify_script.cpp @@ -94,7 +94,7 @@ static void VerifyScriptBench(benchmark::State& state) txCredit.vout[0].scriptPubKey.data(), txCredit.vout[0].scriptPubKey.size(), txCredit.vout[0].nValue, - (const unsigned char*)&stream[0], stream.size(), 0, flags, nullptr); + (const unsigned char*)stream.data(), stream.size(), 0, flags, nullptr); assert(csuccess == 1); #endif } -- cgit v1.2.3