Fabcoin Core  0.16.2
P2P Digital Currency
verify_script.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016-2017 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 <streams.h>
13 
14 #include <array>
15 
16 // FIXME: Dedup with BuildCreditingTransaction in test/script_tests.cpp.
17 static CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
18 {
19  CMutableTransaction txCredit;
20  txCredit.nVersion = 1;
21  txCredit.nLockTime = 0;
22  txCredit.vin.resize(1);
23  txCredit.vout.resize(1);
24  txCredit.vin[0].prevout.SetNull();
25  txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0);
26  txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
27  txCredit.vout[0].scriptPubKey = scriptPubKey;
28  txCredit.vout[0].nValue = 1;
29 
30  return txCredit;
31 }
32 
33 // FIXME: Dedup with BuildSpendingTransaction in test/script_tests.cpp.
34 static CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMutableTransaction& txCredit)
35 {
36  CMutableTransaction txSpend;
37  txSpend.nVersion = 1;
38  txSpend.nLockTime = 0;
39  txSpend.vin.resize(1);
40  txSpend.vout.resize(1);
41  txSpend.vin[0].prevout.hash = txCredit.GetHash();
42  txSpend.vin[0].prevout.n = 0;
43  txSpend.vin[0].scriptSig = scriptSig;
44  txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
45  txSpend.vout[0].scriptPubKey = CScript();
46  txSpend.vout[0].nValue = txCredit.vout[0].nValue;
47 
48  return txSpend;
49 }
50 
51 // Microbenchmark for verification of a basic P2WPKH script. Can be easily
52 // modified to measure performance of other types of scripts.
53 static void VerifyScriptBench(benchmark::State& state)
54 {
55  const int flags = SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH;
56  const int witnessversion = 0;
57 
58  // Keypair.
59  CKey key;
60  static const std::array<unsigned char, 32> vchKey = {
61  {
62  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
63  }
64  };
65  key.Set(vchKey.begin(), vchKey.end(), false);
66  CPubKey pubkey = key.GetPubKey();
67  uint160 pubkeyHash;
68  CHash160().Write(pubkey.begin(), pubkey.size()).Finalize(pubkeyHash.begin());
69 
70  // Script.
71  CScript scriptPubKey = CScript() << witnessversion << ToByteVector(pubkeyHash);
72  CScript scriptSig;
73  CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG;
74  CTransaction txCredit = BuildCreditingTransaction(scriptPubKey);
75  CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit);
76  CScriptWitness& witness = txSpend.vin[0].scriptWitness;
77  witness.stack.emplace_back();
78  key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SIGVERSION_WITNESS_V0), witness.stack.back(), 0);
79  witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
80  witness.stack.push_back(ToByteVector(pubkey));
81 
82  // Benchmark.
83  while (state.KeepRunning()) {
84  ScriptError err;
85  bool success = VerifyScript(
86  txSpend.vin[0].scriptSig,
87  txCredit.vout[0].scriptPubKey,
88  &txSpend.vin[0].scriptWitness,
89  flags,
90  MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue),
91  &err);
92  assert(err == SCRIPT_ERR_OK);
93  assert(success);
94 
95 #if defined(HAVE_CONSENSUS_LIB)
96  CDataStream stream(SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_BLOCK_LEGACY);
97  stream << txSpend;
99  txCredit.vout[0].scriptPubKey.data(),
100  txCredit.vout[0].scriptPubKey.size(),
101  txCredit.vout[0].nValue,
102  (const unsigned char*)stream.data(), stream.size(), 0, flags, nullptr);
103  assert(csuccess == 1);
104 #endif
105  }
106 }
107 
108 BENCHMARK(VerifyScriptBench, 6300);
enum ScriptError_t ScriptError
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:392
static const uint32_t SEQUENCE_FINAL
Only serialized through CTransaction.
Definition: transaction.h:71
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:97
std::vector< std::vector< unsigned char > > stack
Definition: script.h:724
bool KeepRunning()
Definition: bench.h:70
assert(len-trim+(2 *lenIndices)<=WIDTH)
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:146
unsigned char * begin()
Definition: uint256.h:65
uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, unsigned int nIn, int nHashType, const CAmount &amount, SigVersion sigversion, const PrecomputedTransactionData *cache)
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:147
An encapsulated public key.
Definition: pubkey.h:39
const std::vector< CTxOut > vout
Definition: transaction.h:293
CHash160 & Write(const unsigned char *data, size_t len)
Definition: hash.h:57
std::vector< CTxOut > vout
Definition: transaction.h:393
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:73
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
Definition: transaction.cpp:61
const unsigned char * begin() const
Definition: pubkey.h:98
int fabcoinconsensus_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, fabcoinconsensus_error *err)
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:417
160-bit opaque blob.
Definition: uint256.h:120
A mutable version of CTransaction.
Definition: transaction.h:390
BENCHMARK(VerifyScriptBench, 6300)
An encapsulated private key.
Definition: key.h:35
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:275
A hasher class for Fabcoin&#39;s 160-bit hash (SHA-256 + RIPEMD-160).
Definition: hash.h:45
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, uint32_t test_case=0) const
Create a DER-serialized signature.
Definition: key.cpp:160
Definition: script.h:100
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:42