Add support for SIGHASH_DEFAULT in RPCs, and make it default

For non-Taproot signatures, this is interpreted as SIGHASH_ALL.
This commit is contained in:
Pieter Wuille 2021-03-04 14:27:20 -08:00
parent c0f0c8eccb
commit 458a345b05
6 changed files with 18 additions and 10 deletions

View file

@ -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},

View file

@ -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)},

View file

@ -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"

View file

@ -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;
}

View file

@ -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"

View file

@ -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