mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-06 13:47:56 +02:00
bench: add script verification benchmark for P2TR key path spends
This commit is contained in:
@@ -20,36 +20,45 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// Microbenchmark for verification of a basic P2WPKH script. Can be easily
|
enum class ScriptType {
|
||||||
// modified to measure performance of other types of scripts.
|
P2WPKH, // segwitv0, witness-pubkey-hash (ECDSA signature)
|
||||||
static void VerifyScriptBench(benchmark::Bench& bench)
|
P2TR, // segwitv1, taproot key-path spend (Schnorr signature)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Microbenchmark for verification of standard scripts.
|
||||||
|
static void VerifyScriptBench(benchmark::Bench& bench, ScriptType script_type)
|
||||||
{
|
{
|
||||||
ECC_Context ecc_context{};
|
ECC_Context ecc_context{};
|
||||||
|
|
||||||
// Create deterministic key material needed for output script creation / signing
|
// Create deterministic key material needed for output script creation / signing
|
||||||
FlatSigningProvider keystore;
|
CKey privkey;
|
||||||
CPubKey pubkey;
|
privkey.Set(uint256::ONE.begin(), uint256::ONE.end(), /*fCompressedIn=*/true);
|
||||||
{
|
CPubKey pubkey = privkey.GetPubKey();
|
||||||
CKey privkey;
|
CKeyID key_id = pubkey.GetID();
|
||||||
privkey.Set(uint256::ONE.begin(), uint256::ONE.end(), /*fCompressedIn=*/true);
|
|
||||||
pubkey = privkey.GetPubKey();
|
|
||||||
CKeyID key_id = pubkey.GetID();
|
|
||||||
keystore.keys.emplace(key_id, privkey);
|
|
||||||
keystore.pubkeys.emplace(key_id, pubkey);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create crediting and spending transactions
|
FlatSigningProvider keystore;
|
||||||
CScript scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(pubkey));
|
keystore.keys.emplace(key_id, privkey);
|
||||||
const CMutableTransaction& txCredit = BuildCreditingTransaction(scriptPubKey, 1);
|
keystore.pubkeys.emplace(key_id, pubkey);
|
||||||
|
|
||||||
|
// Create crediting and spending transactions with provided input type
|
||||||
|
CTxDestination dest;
|
||||||
|
switch (script_type) {
|
||||||
|
case ScriptType::P2WPKH: dest = WitnessV0KeyHash(pubkey); break;
|
||||||
|
case ScriptType::P2TR: dest = WitnessV1Taproot(XOnlyPubKey{pubkey}); break;
|
||||||
|
default: assert(false);
|
||||||
|
}
|
||||||
|
const CMutableTransaction& txCredit = BuildCreditingTransaction(GetScriptForDestination(dest), 1);
|
||||||
CMutableTransaction txSpend = BuildSpendingTransaction(/*scriptSig=*/{}, /*scriptWitness=*/{}, CTransaction(txCredit));
|
CMutableTransaction txSpend = BuildSpendingTransaction(/*scriptSig=*/{}, /*scriptWitness=*/{}, CTransaction(txCredit));
|
||||||
|
|
||||||
// Sign spending transaction
|
// Sign spending transaction, precompute transaction data
|
||||||
|
PrecomputedTransactionData txdata;
|
||||||
{
|
{
|
||||||
std::map<COutPoint, Coin> coins;
|
std::map<COutPoint, Coin> coins;
|
||||||
coins[txSpend.vin[0].prevout] = Coin(txCredit.vout[0], /*nHeightIn=*/100, /*fCoinBaseIn=*/false);
|
coins[txSpend.vin[0].prevout] = Coin(txCredit.vout[0], /*nHeightIn=*/100, /*fCoinBaseIn=*/false);
|
||||||
std::map<int, bilingual_str> input_errors;
|
std::map<int, bilingual_str> input_errors;
|
||||||
bool complete = SignTransaction(txSpend, &keystore, coins, SIGHASH_ALL, input_errors);
|
bool complete = SignTransaction(txSpend, &keystore, coins, SIGHASH_ALL, input_errors);
|
||||||
assert(complete);
|
assert(complete);
|
||||||
|
txdata.Init(txSpend, /*spent_outputs=*/{txCredit.vout[0]});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Benchmark.
|
// Benchmark.
|
||||||
@@ -60,13 +69,16 @@ static void VerifyScriptBench(benchmark::Bench& bench)
|
|||||||
txCredit.vout[0].scriptPubKey,
|
txCredit.vout[0].scriptPubKey,
|
||||||
&txSpend.vin[0].scriptWitness,
|
&txSpend.vin[0].scriptWitness,
|
||||||
STANDARD_SCRIPT_VERIFY_FLAGS,
|
STANDARD_SCRIPT_VERIFY_FLAGS,
|
||||||
MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL),
|
MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue, txdata, MissingDataBehavior::ASSERT_FAIL),
|
||||||
&err);
|
&err);
|
||||||
assert(err == SCRIPT_ERR_OK);
|
assert(err == SCRIPT_ERR_OK);
|
||||||
assert(success);
|
assert(success);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void VerifyScriptP2WPKH(benchmark::Bench& bench) { VerifyScriptBench(bench, ScriptType::P2WPKH); }
|
||||||
|
static void VerifyScriptP2TR(benchmark::Bench& bench) { VerifyScriptBench(bench, ScriptType::P2TR); }
|
||||||
|
|
||||||
static void VerifyNestedIfScript(benchmark::Bench& bench)
|
static void VerifyNestedIfScript(benchmark::Bench& bench)
|
||||||
{
|
{
|
||||||
std::vector<std::vector<unsigned char>> stack;
|
std::vector<std::vector<unsigned char>> stack;
|
||||||
@@ -88,5 +100,6 @@ static void VerifyNestedIfScript(benchmark::Bench& bench)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
BENCHMARK(VerifyScriptBench);
|
BENCHMARK(VerifyScriptP2WPKH);
|
||||||
|
BENCHMARK(VerifyScriptP2TR);
|
||||||
BENCHMARK(VerifyNestedIfScript);
|
BENCHMARK(VerifyNestedIfScript);
|
||||||
|
|||||||
Reference in New Issue
Block a user