diff options
author | Pieter Wuille <pieter@wuille.net> | 2021-03-04 14:27:20 -0800 |
---|---|---|
committer | Pieter Wuille <pieter@wuille.net> | 2021-06-12 12:38:17 -0700 |
commit | 458a345b0590fd2fa04c7d8d70beb8d57e34bbc8 (patch) | |
tree | 61cd60377c39986ac8a66617c5d3a446c363812c | |
parent | c0f0c8eccb04f90940007e0c6aaff56bf2ab35b5 (diff) |
Add support for SIGHASH_DEFAULT in RPCs, and make it default
For non-Taproot signatures, this is interpreted as SIGHASH_ALL.
-rw-r--r-- | src/bitcoin-tx.cpp | 3 | ||||
-rw-r--r-- | src/core_read.cpp | 1 | ||||
-rw-r--r-- | src/rpc/rawtransaction.cpp | 3 | ||||
-rw-r--r-- | src/script/sign.cpp | 7 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 12 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 2 |
6 files changed, 18 insertions, 10 deletions
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 93ac4b8f7e..3fc87ae1ff 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -506,11 +506,12 @@ static void MutateTxDelOutput(CMutableTransaction& tx, const std::string& strOut tx.vout.erase(tx.vout.begin() + outIdx); } -static const unsigned int N_SIGHASH_OPTS = 6; +static const unsigned int N_SIGHASH_OPTS = 7; static const struct { const char *flagStr; int flags; } sighashOptions[N_SIGHASH_OPTS] = { + {"DEFAULT", SIGHASH_DEFAULT}, {"ALL", SIGHASH_ALL}, {"NONE", SIGHASH_NONE}, {"SINGLE", SIGHASH_SINGLE}, diff --git a/src/core_read.cpp b/src/core_read.cpp index b5fc93886d..6108961010 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -260,6 +260,7 @@ int ParseSighashString(const UniValue& sighash) int hash_type = SIGHASH_ALL; if (!sighash.isNull()) { static std::map<std::string, int> map_sighash_values = { + {std::string("DEFAULT"), int(SIGHASH_DEFAULT)}, {std::string("ALL"), int(SIGHASH_ALL)}, {std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)}, {std::string("NONE"), int(SIGHASH_NONE)}, diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 2fa033aee3..ccb3123714 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -753,7 +753,8 @@ static RPCHelpMan signrawtransactionwithkey() }, }, }, - {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"ALL"}, "The signature hash type. Must be one of:\n" + {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT"}, "The signature hash type. Must be one of:\n" + " \"DEFAULT\"\n" " \"ALL\"\n" " \"NONE\"\n" " \"SINGLE\"\n" diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 749bcc173c..65276f641f 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -44,10 +44,13 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid // Signing without known amount does not work in witness scripts. if (sigversion == SigVersion::WITNESS_V0 && !MoneyRange(amount)) return false; - uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, m_txdata); + // BASE/WITNESS_V0 signatures don't support explicit SIGHASH_DEFAULT, use SIGHASH_ALL instead. + const int hashtype = nHashType == SIGHASH_DEFAULT ? SIGHASH_ALL : nHashType; + + uint256 hash = SignatureHash(scriptCode, *txTo, nIn, hashtype, amount, sigversion, m_txdata); if (!key.Sign(hash, vchSig)) return false; - vchSig.push_back((unsigned char)nHashType); + vchSig.push_back((unsigned char)hashtype); return true; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 534c974178..ab34af2329 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3320,7 +3320,8 @@ RPCHelpMan signrawtransactionwithwallet() }, }, }, - {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"ALL"}, "The signature hash type. Must be one of\n" + {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT"}, "The signature hash type. Must be one of\n" + " \"DEFAULT\"\n" " \"ALL\"\n" " \"NONE\"\n" " \"SINGLE\"\n" @@ -3542,7 +3543,7 @@ static RPCHelpMan bumpfee_helper(std::string method_name) } else { PartiallySignedTransaction psbtx(mtx); bool complete = false; - const TransactionError err = pwallet->FillPSBT(psbtx, complete, SIGHASH_ALL, false /* sign */, true /* bip32derivs */); + const TransactionError err = pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, false /* sign */, true /* bip32derivs */); CHECK_NONFATAL(err == TransactionError::OK); CHECK_NONFATAL(!complete); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); @@ -4175,8 +4176,8 @@ static RPCHelpMan send() // First fill transaction with our data without signing, // so external signers are not asked sign more than once. bool complete; - pwallet->FillPSBT(psbtx, complete, SIGHASH_ALL, false, true); - const TransactionError err = pwallet->FillPSBT(psbtx, complete, SIGHASH_ALL, true, false); + pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, false, true); + const TransactionError err = pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, true, false); if (err != TransactionError::OK) { throw JSONRPCTransactionError(err); } @@ -4291,7 +4292,8 @@ static RPCHelpMan walletprocesspsbt() { {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction base64 string"}, {"sign", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also sign the transaction when updating"}, - {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"ALL"}, "The signature hash type to sign with if not specified by the PSBT. Must be one of\n" + {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT"}, "The signature hash type to sign with if not specified by the PSBT. Must be one of\n" + " \"DEFAULT\"\n" " \"ALL\"\n" " \"NONE\"\n" " \"SINGLE\"\n" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ac96e8fcaf..2485a955ca 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1807,7 +1807,7 @@ bool CWallet::SignTransaction(CMutableTransaction& tx) const coins[input.prevout] = Coin(wtx.tx->vout[input.prevout.n], wtx.m_confirm.block_height, wtx.IsCoinBase()); } std::map<int, std::string> input_errors; - return SignTransaction(tx, coins, SIGHASH_ALL, input_errors); + return SignTransaction(tx, coins, SIGHASH_DEFAULT, input_errors); } bool CWallet::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const |