Bitcoin Core  0.19.99
P2P Digital Currency
verify_script.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016-2019 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 <key.h>
7 #if defined(HAVE_CONSENSUS_LIB)
9 #endif
10 #include <script/script.h>
11 #include <script/standard.h>
12 #include <streams.h>
13 #include <test/util/transaction_utils.h>
14 
15 #include <array>
16 
17 // Microbenchmark for verification of a basic P2WPKH script. Can be easily
18 // modified to measure performance of other types of scripts.
20 {
22  const int witnessversion = 0;
23 
24  // Keypair.
25  CKey key;
26  static const std::array<unsigned char, 32> vchKey = {
27  {
28  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
29  }
30  };
31  key.Set(vchKey.begin(), vchKey.end(), false);
32  CPubKey pubkey = key.GetPubKey();
33  uint160 pubkeyHash;
34  CHash160().Write(pubkey.begin(), pubkey.size()).Finalize(pubkeyHash.begin());
35 
36  // Script.
37  CScript scriptPubKey = CScript() << witnessversion << ToByteVector(pubkeyHash);
38  CScript scriptSig;
39  CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG;
40  const CMutableTransaction& txCredit = BuildCreditingTransaction(scriptPubKey, 1);
41  CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, CScriptWitness(), CTransaction(txCredit));
42  CScriptWitness& witness = txSpend.vin[0].scriptWitness;
43  witness.stack.emplace_back();
44  key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SigVersion::WITNESS_V0), witness.stack.back());
45  witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
46  witness.stack.push_back(ToByteVector(pubkey));
47 
48  // Benchmark.
49  while (state.KeepRunning()) {
50  ScriptError err;
51  bool success = VerifyScript(
52  txSpend.vin[0].scriptSig,
53  txCredit.vout[0].scriptPubKey,
54  &txSpend.vin[0].scriptWitness,
55  flags,
56  MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue),
57  &err);
58  assert(err == SCRIPT_ERR_OK);
59  assert(success);
60 
61 #if defined(HAVE_CONSENSUS_LIB)
63  stream << txSpend;
65  txCredit.vout[0].scriptPubKey.data(),
66  txCredit.vout[0].scriptPubKey.size(),
67  txCredit.vout[0].nValue,
68  (const unsigned char*)stream.data(), stream.size(), 0, flags, nullptr);
69  assert(csuccess == 1);
70 #endif
71  }
72 }
73 
75  std::vector<std::vector<unsigned char>> stack;
76  CScript script;
77  for (int i = 0; i < 100; ++i) {
78  script << OP_1 << OP_IF;
79  }
80  for (int i = 0; i < 1000; ++i) {
81  script << OP_1;
82  }
83  for (int i = 0; i < 100; ++i) {
84  script << OP_ENDIF;
85  }
86  while (state.KeepRunning()) {
87  auto stack_copy = stack;
89  bool ret = EvalScript(stack_copy, script, 0, BaseSignatureChecker(), SigVersion::BASE, &error);
90  assert(ret);
91  }
92 }
93 
94 
96 
enum ScriptError_t ScriptError
Definition: script.h:85
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:184
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:368
value_type * data()
Definition: streams.h:301
std::vector< std::vector< unsigned char > > stack
Definition: script.h:574
bool KeepRunning()
Definition: bench.h:72
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:201
unsigned char * begin()
Definition: uint256.h:54
const unsigned char * begin() const
Definition: pubkey.h:111
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:210
size_type size() const
Definition: streams.h:292
An encapsulated public key.
Definition: pubkey.h:30
Definition: script.h:64
CHash160 & Write(const unsigned char *data, size_t len)
Definition: hash.h:58
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:109
std::vector< CTxOut > vout
Definition: transaction.h:369
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:74
bool EvalScript(std::vector< std::vector< unsigned char > > &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, SigVersion sigversion, ScriptError *serror)
int flags
Definition: bitcoin-tx.cpp:509
int bitcoinconsensus_verify_script_with_amount(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount, const unsigned char *txTo, unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error *err)
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:390
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12
uint256 SignatureHash(const CScript &scriptCode, const T &txTo, unsigned int nIn, int nHashType, const CAmount &amount, SigVersion sigversion, const PrecomputedTransactionData *cache)
160-bit opaque blob.
Definition: uint256.h:109
static void VerifyNestedIfScript(benchmark::State &state)
A mutable version of CTransaction.
Definition: transaction.h:366
BENCHMARK(VerifyScriptBench, 6300)
An encapsulated private key.
Definition: key.h:27
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:270
A hasher class for Bitcoin&#39;s 160-bit hash (SHA-256 + RIPEMD-160).
Definition: hash.h:46
static void VerifyScriptBench(benchmark::State &state)
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
Definition: script.h:106
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:48