Bitcoin Core  29.1.0
P2P Digital Currency
verify_script.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016-2022 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.
4 
5 #include <bench/bench.h>
6 #include <hash.h>
7 #include <key.h>
9 #include <pubkey.h>
10 #include <script/interpreter.h>
11 #include <script/script.h>
12 #include <span.h>
14 #include <uint256.h>
15 
16 #include <array>
17 #include <cassert>
18 #include <cstdint>
19 #include <vector>
20 
21 // Microbenchmark for verification of a basic P2WPKH script. Can be easily
22 // modified to measure performance of other types of scripts.
24 {
26 
28  const int witnessversion = 0;
29 
30  // Key pair.
31  CKey key;
32  static const std::array<unsigned char, 32> vchKey = {
33  {
34  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
35  }
36  };
37  key.Set(vchKey.begin(), vchKey.end(), false);
38  CPubKey pubkey = key.GetPubKey();
39  uint160 pubkeyHash;
40  CHash160().Write(pubkey).Finalize(pubkeyHash);
41 
42  // Script.
43  CScript scriptPubKey = CScript() << witnessversion << ToByteVector(pubkeyHash);
44  CScript scriptSig;
45  CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG;
46  const CMutableTransaction& txCredit = BuildCreditingTransaction(scriptPubKey, 1);
48  CScriptWitness& witness = txSpend.vin[0].scriptWitness;
49  witness.stack.emplace_back();
50  key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SigVersion::WITNESS_V0), witness.stack.back());
51  witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
52  witness.stack.push_back(ToByteVector(pubkey));
53 
54  // Benchmark.
55  bench.run([&] {
56  ScriptError err;
57  bool success = VerifyScript(
58  txSpend.vin[0].scriptSig,
59  txCredit.vout[0].scriptPubKey,
60  &txSpend.vin[0].scriptWitness,
61  flags,
63  &err);
64  assert(err == SCRIPT_ERR_OK);
65  assert(success);
66  });
67 }
68 
70 {
71  std::vector<std::vector<unsigned char>> stack;
73  for (int i = 0; i < 100; ++i) {
74  script << OP_1 << OP_IF;
75  }
76  for (int i = 0; i < 1000; ++i) {
77  script << OP_1;
78  }
79  for (int i = 0; i < 100; ++i) {
80  script << OP_ENDIF;
81  }
82  bench.run([&] {
83  auto stack_copy = stack;
84  ScriptError error;
85  bool ret = EvalScript(stack_copy, script, 0, BaseSignatureChecker(), SigVersion::BASE, &error);
86  assert(ret);
87  });
88 }
89 
CMutableTransaction BuildCreditingTransaction(const CScript &scriptPubKey, int nValue)
Witness v0 (P2WPKH and P2WSH); see BIP 141.
int ret
assert(!tx.IsCoinBase())
enum ScriptError_t ScriptError
RAII class initializing and deinitializing global state for elliptic curve support.
Definition: key.h:321
Definition: script.h:125
void Finalize(Span< unsigned char > output)
Definition: hash.h:55
ECC_Context ecc_context
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:182
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
std::vector< CTxIn > vin
Definition: transaction.h:379
std::vector< std::vector< unsigned char > > stack
Definition: script.h:588
CMutableTransaction BuildSpendingTransaction(const CScript &scriptSig, const CScriptWitness &scriptWitness, const CTransaction &txCredit)
Bare scripts and BIP16 P2SH-wrapped redeemscripts.
static void VerifyNestedIfScript(benchmark::Bench &bench)
Definition: script.h:83
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, bool grind=true, uint32_t test_case=0) const
Create a DER-serialized signature.
Definition: key.cpp:208
Definition: script.h:104
static void VerifyScriptBench(benchmark::Bench &bench)
Abort execution through assertion failure (for consensus code)
Bench & run(char const *benchmarkName, Op &&op)
Repeatedly calls op() based on the configuration, and performs measurements.
Definition: nanobench.h:1234
An encapsulated public key.
Definition: pubkey.h:33
std::vector< CTxOut > vout
Definition: transaction.h:380
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:103
BENCHMARK(VerifyScriptBench, benchmark::PriorityLevel::HIGH)
int flags
Definition: bitcoin-tx.cpp:536
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:67
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:414
uint256 SignatureHash(const CScript &scriptCode, const T &txTo, unsigned int nIn, int32_t nHashType, const CAmount &amount, SigVersion sigversion, const PrecomputedTransactionData *cache)
160-bit opaque blob.
Definition: uint256.h:189
A mutable version of CTransaction.
Definition: transaction.h:377
Main entry point to nanobench&#39;s benchmarking facility.
Definition: nanobench.h:627
An encapsulated private key.
Definition: key.h:34
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:295
A hasher class for Bitcoin&#39;s 160-bit hash (SHA-256 + RIPEMD-160).
Definition: hash.h:49
bool EvalScript(std::vector< std::vector< unsigned char > > &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, SigVersion sigversion, ScriptExecutionData &execdata, ScriptError *serror)
CHash160 & Write(Span< const unsigned char > input)
Definition: hash.h:62