diff options
Diffstat (limited to 'src/bench/verify_script.cpp')
-rw-r--r-- | src/bench/verify_script.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp new file mode 100644 index 0000000000..dc3940cdbd --- /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<unsigned char>(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); |