git / moonbite-core / src/bench/verify_script.cpp · raw
// Copyright (c) 2016-2020 The Bitcoin Core developers// Distributed under the MIT software license, see the accompanying// file COPYING or http://www.opensource.org/licenses/mit-license.php.#include <bench/bench.h>#include <key.h>#if defined(HAVE_CONSENSUS_LIB)#include <script/bitcoinconsensus.h>#endif#include <script/script.h>#include <script/standard.h>#include <streams.h>#include <test/util/transaction_utils.h>#include <array>// Microbenchmark for verification of a basic P2WPKH script. Can be easily// modified to measure performance of other types of scripts.static void VerifyScriptBench(benchmark::Bench& bench){ const ECCVerifyHandle verify_handle; ECC_Start(); const int flags = SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH; const int witnessversion = 0; // Keypair. CKey key; static const std::array<unsigned char, 32> vchKey = { { 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 } }; key.Set(vchKey.begin(), vchKey.end(), false); CPubKey pubkey = key.GetPubKey(); uint160 pubkeyHash; CHash160().Write(pubkey).Finalize(pubkeyHash); // Script. CScript scriptPubKey = CScript() << witnessversion << ToByteVector(pubkeyHash); CScript scriptSig; CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG; const CMutableTransaction& txCredit = BuildCreditingTransaction(scriptPubKey, 1); CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, CScriptWitness(), CTransaction(txCredit)); CScriptWitness& witness = txSpend.vin[0].scriptWitness; witness.stack.emplace_back(); key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SigVersion::WITNESS_V0), witness.stack.back()); witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL)); witness.stack.push_back(ToByteVector(pubkey)); // Benchmark. bench.run([&] { ScriptError err; bool success = VerifyScript( txSpend.vin[0].scriptSig, txCredit.vout[0].scriptPubKey, &txSpend.vin[0].scriptWitness, flags, MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue), &err); assert(err == SCRIPT_ERR_OK); assert(success);#if defined(HAVE_CONSENSUS_LIB) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); stream << txSpend; int csuccess = bitcoinconsensus_verify_script_with_amount( txCredit.vout[0].scriptPubKey.data(), txCredit.vout[0].scriptPubKey.size(), txCredit.vout[0].nValue, (const unsigned char*)stream.data(), stream.size(), 0, flags, nullptr); assert(csuccess == 1);#endif }); ECC_Stop();}static void VerifyNestedIfScript(benchmark::Bench& bench){ std::vector<std::vector<unsigned char>> stack; CScript script; for (int i = 0; i < 100; ++i) { script << OP_1 << OP_IF; } for (int i = 0; i < 1000; ++i) { script << OP_1; } for (int i = 0; i < 100; ++i) { script << OP_ENDIF; } bench.run([&] { auto stack_copy = stack; ScriptError error; bool ret = EvalScript(stack_copy, script, 0, BaseSignatureChecker(), SigVersion::BASE, &error); assert(ret); });}BENCHMARK(VerifyScriptBench);BENCHMARK(VerifyNestedIfScript);