Move CTxInWitness inside CTxIn
[bitcoinplatinum.git] / src / bench / verify_script.cpp
blob4aca1c7eb3d4b56bf81904c085148ab791826ef4
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.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 // FIXME: Dedup with BuildCreditingTransaction in test/script_tests.cpp.
15 static CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
17 CMutableTransaction txCredit;
18 txCredit.nVersion = 1;
19 txCredit.nLockTime = 0;
20 txCredit.vin.resize(1);
21 txCredit.vout.resize(1);
22 txCredit.vin[0].prevout.SetNull();
23 txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0);
24 txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
25 txCredit.vout[0].scriptPubKey = scriptPubKey;
26 txCredit.vout[0].nValue = 1;
28 return txCredit;
31 // FIXME: Dedup with BuildSpendingTransaction in test/script_tests.cpp.
32 static CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMutableTransaction& txCredit)
34 CMutableTransaction txSpend;
35 txSpend.nVersion = 1;
36 txSpend.nLockTime = 0;
37 txSpend.vin.resize(1);
38 txSpend.vout.resize(1);
39 txSpend.vin[0].prevout.hash = txCredit.GetHash();
40 txSpend.vin[0].prevout.n = 0;
41 txSpend.vin[0].scriptSig = scriptSig;
42 txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
43 txSpend.vout[0].scriptPubKey = CScript();
44 txSpend.vout[0].nValue = txCredit.vout[0].nValue;
46 return txSpend;
49 // Microbenchmark for verification of a basic P2WPKH script. Can be easily
50 // modified to measure performance of other types of scripts.
51 static void VerifyScriptBench(benchmark::State& state)
53 const int flags = SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH;
54 const int witnessversion = 0;
56 // Keypair.
57 CKey key;
58 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};
59 key.Set(vchKey, vchKey + 32, false);
60 CPubKey pubkey = key.GetPubKey();
61 uint160 pubkeyHash;
62 CHash160().Write(pubkey.begin(), pubkey.size()).Finalize(pubkeyHash.begin());
64 // Script.
65 CScript scriptPubKey = CScript() << witnessversion << ToByteVector(pubkeyHash);
66 CScript scriptSig;
67 CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG;
68 CTransaction txCredit = BuildCreditingTransaction(scriptPubKey);
69 CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit);
70 CScriptWitness& witness = txSpend.vin[0].scriptWitness;
71 witness.stack.emplace_back();
72 key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SIGVERSION_WITNESS_V0), witness.stack.back(), 0);
73 witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
74 witness.stack.push_back(ToByteVector(pubkey));
76 // Benchmark.
77 while (state.KeepRunning()) {
78 ScriptError err;
79 bool success = VerifyScript(
80 txSpend.vin[0].scriptSig,
81 txCredit.vout[0].scriptPubKey,
82 &txSpend.vin[0].scriptWitness,
83 flags,
84 MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue),
85 &err);
86 assert(err == SCRIPT_ERR_OK);
87 assert(success);
89 #if defined(HAVE_CONSENSUS_LIB)
90 CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
91 stream << txSpend;
92 int csuccess = bitcoinconsensus_verify_script_with_amount(
93 begin_ptr(txCredit.vout[0].scriptPubKey),
94 txCredit.vout[0].scriptPubKey.size(),
95 txCredit.vout[0].nValue,
96 (const unsigned char*)&stream[0], stream.size(), 0, flags, nullptr);
97 assert(csuccess == 1);
98 #endif
102 BENCHMARK(VerifyScriptBench);