Microbenchmark for verification of a basic P2WPKH script. Can be easily modified to measure performance of other types of scripts.
| 17 | // Microbenchmark for verification of a basic P2WPKH script. Can be easily |
| 18 | // modified to measure performance of other types of scripts. |
| 19 | static void VerifyScriptBench(benchmark::Bench& bench) |
| 20 | { |
| 21 | const ECCVerifyHandle verify_handle; |
| 22 | ECC_Start(); |
| 23 | |
| 24 | const uint32_t flags{SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH}; |
| 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 | txSpend.witness.vtxinwit.resize(1); |
| 46 | CScriptWitness& witness = txSpend.witness.vtxinwit[0].scriptWitness; |
| 47 | witness.stack.emplace_back(); |
| 48 | key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SigVersion::WITNESS_V0, 0), witness.stack.back()); |
| 49 | witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL)); |
| 50 | witness.stack.push_back(ToByteVector(pubkey)); |
| 51 | |
| 52 | // Benchmark. |
| 53 | bench.run([&] { |
| 54 | ScriptError err; |
| 55 | bool success = VerifyScript( |
| 56 | txSpend.vin[0].scriptSig, |
| 57 | txCredit.vout[0].scriptPubKey, |
| 58 | &txSpend.witness.vtxinwit[0].scriptWitness, |
| 59 | flags, |
| 60 | MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), |
| 61 | &err); |
| 62 | assert(err == SCRIPT_ERR_OK); |
| 63 | assert(success); |
| 64 | |
| 65 | #if defined(HAVE_CONSENSUS_LIB) |
| 66 | CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); |
| 67 | stream << txSpend; |
| 68 | CDataStream streamVal(SER_NETWORK, PROTOCOL_VERSION); |
| 69 | streamVal << txCredit.vout[0].nValue; |
| 70 | int csuccess = bitcoinconsensus_verify_script_with_amount( |
| 71 | NULL, |
| 72 | txCredit.vout[0].scriptPubKey.data(), |
| 73 | txCredit.vout[0].scriptPubKey.size(), |
| 74 | (const unsigned char*)&streamVal[0], streamVal.size(), |
| 75 | (const unsigned char*)stream.data(), stream.size(), 0, flags, nullptr); |
| 76 | assert(csuccess == 1); |
nothing calls this directly
no test coverage detected