Merge #11667: Add scripts to dumpwallet RPC
[bitcoinplatinum.git] / src / bench / verify_script.cpp
blobbfa5806c9d4d1a40cc6b9cffc40e520f2f4166a2
1 // Copyright (c) 2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include <bench/bench.h>
6 #include <key.h>
7 #if defined(HAVE_CONSENSUS_LIB)
8 #include <script/bitcoinconsensus.h>
9 #endif
10 #include <script/script.h>
11 #include <script/sign.h>
12 #include <streams.h>
14 #include <array>
16 // FIXME: Dedup with BuildCreditingTransaction in test/script_tests.cpp.
17 static CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
19 CMutableTransaction txCredit;
20 txCredit.nVersion = 1;
21 txCredit.nLockTime = 0;
22 txCredit.vin.resize(1);
23 txCredit.vout.resize(1);
24 txCredit.vin[0].prevout.SetNull();
25 txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0);
26 txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
27 txCredit.vout[0].scriptPubKey = scriptPubKey;
28 txCredit.vout[0].nValue = 1;
30 return txCredit;
33 // FIXME: Dedup with BuildSpendingTransaction in test/script_tests.cpp.
34 static CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMutableTransaction& txCredit)
36 CMutableTransaction txSpend;
37 txSpend.nVersion = 1;
38 txSpend.nLockTime = 0;
39 txSpend.vin.resize(1);
40 txSpend.vout.resize(1);
41 txSpend.vin[0].prevout.hash = txCredit.GetHash();
42 txSpend.vin[0].prevout.n = 0;
43 txSpend.vin[0].scriptSig = scriptSig;
44 txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
45 txSpend.vout[0].scriptPubKey = CScript();
46 txSpend.vout[0].nValue = txCredit.vout[0].nValue;
48 return txSpend;
51 // Microbenchmark for verification of a basic P2WPKH script. Can be easily
52 // modified to measure performance of other types of scripts.
53 static void VerifyScriptBench(benchmark::State& state)
55 const int flags = SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH;
56 const int witnessversion = 0;
58 // Keypair.
59 CKey key;
60 static const std::array<unsigned char, 32> vchKey = {
62 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
65 key.Set(vchKey.begin(), vchKey.end(), false);
66 CPubKey pubkey = key.GetPubKey();
67 uint160 pubkeyHash;
68 CHash160().Write(pubkey.begin(), pubkey.size()).Finalize(pubkeyHash.begin());
70 // Script.
71 CScript scriptPubKey = CScript() << witnessversion << ToByteVector(pubkeyHash);
72 CScript scriptSig;
73 CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG;
74 CTransaction txCredit = BuildCreditingTransaction(scriptPubKey);
75 CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit);
76 CScriptWitness& witness = txSpend.vin[0].scriptWitness;
77 witness.stack.emplace_back();
78 key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SIGVERSION_WITNESS_V0), witness.stack.back(), 0);
79 witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
80 witness.stack.push_back(ToByteVector(pubkey));
82 // Benchmark.
83 while (state.KeepRunning()) {
84 ScriptError err;
85 bool success = VerifyScript(
86 txSpend.vin[0].scriptSig,
87 txCredit.vout[0].scriptPubKey,
88 &txSpend.vin[0].scriptWitness,
89 flags,
90 MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue),
91 &err);
92 assert(err == SCRIPT_ERR_OK);
93 assert(success);
95 #if defined(HAVE_CONSENSUS_LIB)
96 CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
97 stream << txSpend;
98 int csuccess = bitcoinconsensus_verify_script_with_amount(
99 txCredit.vout[0].scriptPubKey.data(),
100 txCredit.vout[0].scriptPubKey.size(),
101 txCredit.vout[0].nValue,
102 (const unsigned char*)stream.data(), stream.size(), 0, flags, nullptr);
103 assert(csuccess == 1);
104 #endif
108 BENCHMARK(VerifyScriptBench);