BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
verify_script.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016-2018 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/sign.h>
12 #include <script/standard.h>
13 #include <streams.h>
14 
15 #include <array>
16 
17 // FIXME: Dedup with BuildCreditingTransaction in test/script_tests.cpp.
18 static CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
19 {
20  CMutableTransaction txCredit;
21  txCredit.nVersion = 1;
22  txCredit.nLockTime = 0;
23  txCredit.vin.resize(1);
24  txCredit.vout.resize(1);
25  txCredit.vin[0].prevout.SetNull();
26  txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0);
27  txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
28  txCredit.vout[0].scriptPubKey = scriptPubKey;
29  txCredit.vout[0].nValue = 1;
30 
31  return txCredit;
32 }
33 
34 // FIXME: Dedup with BuildSpendingTransaction in test/script_tests.cpp.
35 static CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMutableTransaction& txCredit)
36 {
37  CMutableTransaction txSpend;
38  txSpend.nVersion = 1;
39  txSpend.nLockTime = 0;
40  txSpend.vin.resize(1);
41  txSpend.vout.resize(1);
42  txSpend.vin[0].prevout.hash = txCredit.GetHash();
43  txSpend.vin[0].prevout.n = 0;
44  txSpend.vin[0].scriptSig = scriptSig;
45  txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
46  txSpend.vout[0].scriptPubKey = CScript();
47  txSpend.vout[0].nValue = txCredit.vout[0].nValue;
48 
49  return txSpend;
50 }
51 
52 // Microbenchmark for verification of a basic P2WPKH script. Can be easily
53 // modified to measure performance of other types of scripts.
54 static void VerifyScriptBench(benchmark::State& state)
55 {
57  const int witnessversion = 0;
58 
59  // Keypair.
60  CKey key;
61  static const std::array<unsigned char, 32> vchKey = {
62  {
63  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
64  }
65  };
66  key.Set(vchKey.begin(), vchKey.end(), false);
67  CPubKey pubkey = key.GetPubKey();
68  uint160 pubkeyHash;
69  CHash360().Write(pubkey.begin(), pubkey.size()).Finalize(pubkeyHash.begin());
70 
71  // Script.
72  CScript scriptPubKey = CScript() << witnessversion << ToByteVector(pubkeyHash);
73  CScript scriptSig;
74  CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH360 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG;
75  const CMutableTransaction& txCredit = BuildCreditingTransaction(scriptPubKey);
76  CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit);
77  CScriptWitness& witness = txSpend.vin[0].scriptWitness;
78  witness.stack.emplace_back();
79  key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SigVersion::WITNESS_V0), witness.stack.back());
80  witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
81  witness.stack.push_back(ToByteVector(pubkey));
82 
83  // Benchmark.
84  while (state.KeepRunning()) {
85  ScriptError err;
86  bool success = VerifyScript(
87  txSpend.vin[0].scriptSig,
88  txCredit.vout[0].scriptPubKey,
89  &txSpend.vin[0].scriptWitness,
90  flags,
91  MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue),
92  &err);
93  assert(err == SCRIPT_ERR_OK);
94  assert(success);
95 
96 #if defined(HAVE_CONSENSUS_LIB)
97  CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
98  stream << txSpend;
100  txCredit.vout[0].scriptPubKey.data(),
101  txCredit.vout[0].scriptPubKey.size(),
102  txCredit.vout[0].nValue,
103  (const unsigned char*)stream.data(), stream.size(), 0, flags, nullptr);
104  assert(csuccess == 1);
105 #endif
106  }
107 }
108 
109 BENCHMARK(VerifyScriptBench, 6300);
enum ScriptError_t ScriptError
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:179
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:362
static const uint32_t SEQUENCE_FINAL
Definition: transaction.h:71
std::vector< std::vector< unsigned char > > stack
Definition: script.h:566
bool KeepRunning()
Definition: bench.h:70
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:221
unsigned char * begin()
Definition: uint256.h:56
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:205
An encapsulated public key.
Definition: pubkey.h:30
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:363
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:74
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)
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
Definition: transaction.cpp:60
CHash360 & Write(const unsigned char *data, size_t len)
Definition: hash.h:82
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:384
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:111
A mutable version of CTransaction.
Definition: transaction.h:360
int flags
Definition: bsha3-tx.cpp:509
BENCHMARK(VerifyScriptBench, 6300)
An encapsulated private key.
Definition: key.h:27
A hasher class for Bitcoin&#39;s 160-bit hash (SHA3-256 + RIPEMD-160).
Definition: hash.h:70
Definition: script.h:100
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:42