diff --git a/src/bench/sign_transaction.cpp b/src/bench/sign_transaction.cpp index 5405265b230..63a5d97f519 100644 --- a/src/bench/sign_transaction.cpp +++ b/src/bench/sign_transaction.cpp @@ -68,7 +68,7 @@ static void SignTransactionSingleInput(benchmark::Bench& bench, InputType input_ const CScript& prev_spk = prev_spks[(iter++) % prev_spks.size()]; coins[prevout] = Coin(CTxOut(10000, prev_spk), /*nHeightIn=*/100, /*fCoinBaseIn=*/false); std::map input_errors; - bool complete = SignTransaction(tx, &keystore, coins, SIGHASH_ALL, input_errors); + bool complete = SignTransaction(tx, &keystore, coins, {.sighash_type = SIGHASH_ALL}, input_errors); assert(complete); }); } diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp index 0a92a057947..8f07fd34fd1 100644 --- a/src/bench/verify_script.cpp +++ b/src/bench/verify_script.cpp @@ -77,7 +77,8 @@ static void VerifyScriptBench(benchmark::Bench& bench, ScriptType script_type) {txSpend.vin[0].prevout, Coin(txCredit.vout[0], /*nHeightIn=*/100, /*fCoinBaseIn=*/false)} }; std::map input_errors; - assert(SignTransaction(txSpend, &keystore, coins, SIGHASH_ALL, input_errors)); + bool complete = SignTransaction(txSpend, &keystore, coins, {.sighash_type = SIGHASH_ALL}, input_errors); + assert(complete); // Weak sanity check on witness data to ensure we produced the intended spending type assert(txSpend.vin[0].scriptWitness.stack.size() == ExpectedWitnessStackSize(script_type)); txdata.Init(txSpend, /*spent_outputs=*/{txCredit.vout[0]}); diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp index d3a1b875807..f8b6e20875c 100644 --- a/src/rpc/rawtransaction_util.cpp +++ b/src/rpc/rawtransaction_util.cpp @@ -318,7 +318,7 @@ void SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, // Script verification errors std::map input_errors; - bool complete = SignTransaction(mtx, keystore, coins, *nHashType, input_errors); + bool complete = SignTransaction(mtx, keystore, coins, {.sighash_type = *nHashType}, input_errors); SignTransactionResultToJSON(mtx, complete, coins, input_errors, result); } diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 9ea2157f349..6184cc54151 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -1006,9 +1006,9 @@ bool IsSegWitOutput(const SigningProvider& provider, const CScript& script) return false; } -bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, const std::map& coins, int nHashType, std::map& input_errors) +bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, const std::map& coins, const SignOptions& options, std::map& input_errors) { - bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); + bool fHashSingle = ((options.sighash_type & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); // Use CTransaction for the constant parts of the // transaction to avoid rehashing. @@ -1044,7 +1044,7 @@ bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, SignatureData sigdata = DataFromTransaction(mtx, i, coin->second.out); // Only sign SIGHASH_SINGLE if there's a corresponding output: if (!fHashSingle || (i < mtx.vout.size())) { - ProduceSignature(*keystore, MutableTransactionSignatureCreator(mtx, i, amount, &txdata, nHashType), prevPubKey, sigdata); + ProduceSignature(*keystore, MutableTransactionSignatureCreator(mtx, i, amount, &txdata, options.sighash_type), prevPubKey, sigdata); } UpdateInput(txin, sigdata); diff --git a/src/script/sign.h b/src/script/sign.h index 8d50275510b..c0b1b7683ef 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -25,6 +25,10 @@ struct bilingual_str; struct CMutableTransaction; struct SignatureData; +struct SignOptions { + int sighash_type{SIGHASH_DEFAULT}; +}; + /** Interface for signature creators. */ class BaseSignatureCreator { public: @@ -120,6 +124,6 @@ void UpdateInput(CTxIn& input, const SignatureData& data); bool IsSegWitOutput(const SigningProvider& provider, const CScript& script); /** Sign the CMutableTransaction */ -bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* provider, const std::map& coins, int sighash, std::map& input_errors); +bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* provider, const std::map& coins, const SignOptions& options, std::map& input_errors); #endif // BITCOIN_SCRIPT_SIGN_H diff --git a/src/test/fuzz/script_sign.cpp b/src/test/fuzz/script_sign.cpp index e4cf8c2aad3..c709a902bbe 100644 --- a/src/test/fuzz/script_sign.cpp +++ b/src/test/fuzz/script_sign.cpp @@ -132,7 +132,7 @@ FUZZ_TARGET(script_sign, .init = initialize_script_sign) } std::map coins{ConsumeCoins(fuzzed_data_provider)}; std::map input_errors; - (void)SignTransaction(sign_transaction_tx_to, &provider, coins, fuzzed_data_provider.ConsumeIntegral(), input_errors); + (void)SignTransaction(sign_transaction_tx_to, &provider, coins, {.sighash_type = fuzzed_data_provider.ConsumeIntegral()}, input_errors); } } diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 5c50553e9f4..39c691c3364 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -481,7 +481,7 @@ std::pair TestChain100Setup::CreateValidTransactio // - Default signature hashing type int nHashType = SIGHASH_ALL; std::map input_errors; - assert(SignTransaction(mempool_txn, &keystore, input_coins, nHashType, input_errors)); + assert(SignTransaction(mempool_txn, &keystore, input_coins, {.sighash_type = nHashType}, input_errors)); CAmount current_fee = inputs_amount - std::accumulate(outputs.begin(), outputs.end(), CAmount(0), [](const CAmount& acc, const CTxOut& out) { return acc + out.nValue; @@ -498,7 +498,7 @@ std::pair TestChain100Setup::CreateValidTransactio mempool_txn.vout[fee_output.value()].nValue -= deduction; // Re-sign since an output has changed input_errors.clear(); - assert(SignTransaction(mempool_txn, &keystore, input_coins, nHashType, input_errors)); + assert(SignTransaction(mempool_txn, &keystore, input_coins, {.sighash_type = nHashType}, input_errors)); current_fee = target_fee; } } diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index 92152e7c751..911b247d4ef 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -1285,7 +1285,7 @@ bool DescriptorScriptPubKeyMan::SignTransaction(CMutableTransaction& tx, const s keys->Merge(std::move(*coin_keys)); } - return ::SignTransaction(tx, keys.get(), coins, sighash, input_errors); + return ::SignTransaction(tx, keys.get(), coins, {.sighash_type = sighash}, input_errors); } SigningResult DescriptorScriptPubKeyMan::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const @@ -1376,7 +1376,7 @@ std::optional DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTran } } - PSBTError res = SignPSBTInput(HidingSigningProvider(keys.get(), /*hide_secret=*/!options.sign, /*hide_origin=*/!options.bip32_derivs), psbtx, i, &txdata, options, nullptr); + PSBTError res = SignPSBTInput(HidingSigningProvider(keys.get(), /*hide_secret=*/!options.sign, /*hide_origin=*/!options.bip32_derivs), psbtx, i, &txdata, options, /*out_sigdata=*/nullptr); if (res != PSBTError::OK && res != PSBTError::INCOMPLETE) { return res; } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 54f453623e9..5cd47f67225 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -55,7 +55,7 @@ static CMutableTransaction TestSimpleSpend(const CTransaction& from, uint32_t in std::map coins; coins[mtx.vin[0].prevout].out = from.vout[index]; std::map input_errors; - BOOST_CHECK(SignTransaction(mtx, &keystore, coins, SIGHASH_ALL, input_errors)); + BOOST_CHECK(SignTransaction(mtx, &keystore, coins, {.sighash_type = SIGHASH_ALL}, input_errors)); return mtx; }