Bitcoin Core  21.99.0
P2P Digital Currency
verify_script.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016-2020 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 {
21  const ECCVerifyHandle verify_handle;
22  ECC_Start();
23 
25  const int witnessversion = 0;
26 
27  // Key pair.
28  CKey key;
29  static const std::array<unsigned char, 32> vchKey = {
30  {
31  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
32  }
33  };
34  key.Set(vchKey.begin(), vchKey.end(), false);
35  CPubKey pubkey = key.GetPubKey();
36  uint160 pubkeyHash;
37  CHash160().Write(pubkey).Finalize(pubkeyHash);
38 
39  // Script.
40  CScript scriptPubKey = CScript() << witnessversion << ToByteVector(pubkeyHash);
41  CScript scriptSig;
42  CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG;
43  const CMutableTransaction& txCredit = BuildCreditingTransaction(scriptPubKey, 1);
44  CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, CScriptWitness(), CTransaction(txCredit));
45  CScriptWitness& witness = txSpend.vin[0].scriptWitness;
46  witness.stack.emplace_back();
47  key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SigVersion::WITNESS_V0), witness.stack.back());
48  witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
49  witness.stack.push_back(ToByteVector(pubkey));
50 
51  // Benchmark.
52  bench.run([&] {
53  ScriptError err;
54  bool success = VerifyScript(
55  txSpend.vin[0].scriptSig,
56  txCredit.vout[0].scriptPubKey,
57  &txSpend.vin[0].scriptWitness,
58  flags,
60  &err);
61  assert(err == SCRIPT_ERR_OK);
62  assert(success);
63 
64 #if defined(HAVE_CONSENSUS_LIB)
66  stream << txSpend;
68  txCredit.vout[0].scriptPubKey.data(),
69  txCredit.vout[0].scriptPubKey.size(),
70  txCredit.vout[0].nValue,
71  (const unsigned char*)stream.data(), stream.size(), 0, flags, nullptr);
72  assert(csuccess == 1);
73 #endif
74  });
75  ECC_Stop();
76 }
77 
79 {
80  std::vector<std::vector<unsigned char>> stack;
81  CScript script;
82  for (int i = 0; i < 100; ++i) {
83  script << OP_1 << OP_IF;
84  }
85  for (int i = 0; i < 1000; ++i) {
86  script << OP_1;
87  }
88  for (int i = 0; i < 100; ++i) {
89  script << OP_ENDIF;
90  }
91  bench.run([&] {
92  auto stack_copy = stack;
94  bool ret = EvalScript(stack_copy, script, 0, BaseSignatureChecker(), SigVersion::BASE, &error);
95  assert(ret);
96  });
97 }
98 
CMutableTransaction::vin
std::vector< CTxIn > vin
Definition: transaction.h:346
SCRIPT_VERIFY_WITNESS
@ SCRIPT_VERIFY_WITNESS
Definition: interpreter.h:105
VerifyNestedIfScript
static void VerifyNestedIfScript(benchmark::Bench &bench)
Definition: verify_script.cpp:78
SigVersion::BASE
@ BASE
Bare scripts and BIP16 P2SH-wrapped redeemscripts.
flags
int flags
Definition: bitcoin-tx.cpp:512
streams.h
SCRIPT_ERR_OK
@ SCRIPT_ERR_OK
Definition: script_error.h:13
CDataStream::data
value_type * data()
Definition: streams.h:264
CKey::Set
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:74
GenericTransactionSignatureChecker
Definition: interpreter.h:260
ToByteVector
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:59
ankerl::nanobench::Bench
Main entry point to nanobench's benchmarking facility.
Definition: nanobench.h:583
OP_HASH160
@ OP_HASH160
Definition: script.h:179
BaseSignatureChecker
Definition: interpreter.h:224
VerifyScript
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
Definition: interpreter.cpp:1960
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:259
ScriptError
enum ScriptError_t ScriptError
CScriptWitness
Definition: script.h:556
bitcoinconsensus.h
ECC_Stop
void ECC_Stop()
Deinitialize the elliptic curve support.
Definition: key.cpp:365
CHash160
A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160).
Definition: hash.h:49
OP_DUP
@ OP_DUP
Definition: script.h:117
ankerl::nanobench::Bench::run
Bench & run(char const *benchmarkName, Op &&op)
Repeatedly calls op() based on the configuration, and performs measurements.
Definition: nanobench.h:1134
CHash160::Finalize
void Finalize(Span< unsigned char > output)
Definition: hash.h:55
CKey::Sign
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
standard.h
SigVersion::WITNESS_V0
@ WITNESS_V0
Witness v0 (P2WPKH and P2WSH); see BIP 141.
CKey::GetPubKey
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:184
MissingDataBehavior::ASSERT_FAIL
@ ASSERT_FAIL
Abort execution through assertion failure (for consensus code)
OP_CHECKSIG
@ OP_CHECKSIG
Definition: script.h:182
CScript
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:404
bench.h
CDataStream::size
size_type size() const
Definition: streams.h:255
SCRIPT_VERIFY_P2SH
@ SCRIPT_VERIFY_P2SH
Definition: interpreter.h:46
CMutableTransaction::vout
std::vector< CTxOut > vout
Definition: transaction.h:347
ECC_Start
void ECC_Start()
Initialize the elliptic curve support.
Definition: key.cpp:348
key.h
SIGHASH_ALL
@ SIGHASH_ALL
Definition: interpreter.h:26
uint160
160-bit opaque blob.
Definition: uint256.h:113
CPubKey
An encapsulated public key.
Definition: pubkey.h:31
ECCVerifyHandle
Users of this module must hold an ECCVerifyHandle.
Definition: pubkey.h:268
CKey
An encapsulated private key.
Definition: key.h:27
SignatureHash
uint256 SignatureHash(const CScript &scriptCode, const T &txTo, unsigned int nIn, int nHashType, const CAmount &amount, SigVersion sigversion, const PrecomputedTransactionData *cache)
Definition: interpreter.cpp:1591
EvalScript
bool EvalScript(std::vector< std::vector< unsigned char > > &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, SigVersion sigversion, ScriptExecutionData &execdata, ScriptError *serror)
Definition: interpreter.cpp:431
CHash160::Write
CHash160 & Write(Span< const unsigned char > input)
Definition: hash.h:62
VerifyScriptBench
static void VerifyScriptBench(benchmark::Bench &bench)
Definition: verify_script.cpp:19
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:204
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:166
OP_IF
@ OP_IF
Definition: script.h:96
script.h
BENCHMARK
BENCHMARK(VerifyScriptBench)
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:50
CMutableTransaction
A mutable version of CTransaction.
Definition: transaction.h:344
bitcoinconsensus_verify_script_with_amount
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)
Definition: bitcoinconsensus.cpp:101
assert
assert(std::addressof(::ChainstateActive().CoinsTip())==std::addressof(coins_cache))
OP_EQUALVERIFY
@ OP_EQUALVERIFY
Definition: script.h:139
OP_1
@ OP_1
Definition: script.h:75
CScriptWitness::stack
std::vector< std::vector< unsigned char > > stack
Definition: script.h:560
PROTOCOL_VERSION
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12
OP_ENDIF
@ OP_ENDIF
Definition: script.h:101