CPP   31

verify script

Guest on 6th July 2022 06:32:23 PM

  1. // Copyright (c)  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)
  8. #include <script/bitcoinconsensus.h>
  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. {
  56.     const int flags = SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH;
  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.     CHash160().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_HASH160 << 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;
  99.         int csuccess = bitcoinconsensus_verify_script_with_amount(
  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);

Raw Paste


Login or Register to edit or fork this paste. It's free.