mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-06 03:02:37 +02:00
FillPSBT: report number of inputs signed (or would sign)
In FillPSBT, optionally report the number of inputs we successfully signed, as an out parameter. If "sign" is false, instead report the number of inputs for which GetSigningProvider does not return nullptr. (This is a potentially overbroad estimate of inputs we could sign.)
This commit is contained in:
@@ -335,9 +335,10 @@ public:
|
|||||||
bool sign,
|
bool sign,
|
||||||
bool bip32derivs,
|
bool bip32derivs,
|
||||||
PartiallySignedTransaction& psbtx,
|
PartiallySignedTransaction& psbtx,
|
||||||
bool& complete) override
|
bool& complete,
|
||||||
|
size_t* n_signed) override
|
||||||
{
|
{
|
||||||
return m_wallet->FillPSBT(psbtx, complete, sighash_type, sign, bip32derivs);
|
return m_wallet->FillPSBT(psbtx, complete, sighash_type, sign, bip32derivs, n_signed);
|
||||||
}
|
}
|
||||||
WalletBalances getBalances() override
|
WalletBalances getBalances() override
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -197,7 +197,8 @@ public:
|
|||||||
bool sign,
|
bool sign,
|
||||||
bool bip32derivs,
|
bool bip32derivs,
|
||||||
PartiallySignedTransaction& psbtx,
|
PartiallySignedTransaction& psbtx,
|
||||||
bool& complete) = 0;
|
bool& complete,
|
||||||
|
size_t* n_signed) = 0;
|
||||||
|
|
||||||
//! Get balances.
|
//! Get balances.
|
||||||
virtual WalletBalances getBalances() = 0;
|
virtual WalletBalances getBalances() = 0;
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ void SendCoinsDialog::on_sendButton_clicked()
|
|||||||
CMutableTransaction mtx = CMutableTransaction{*(m_current_transaction->getWtx())};
|
CMutableTransaction mtx = CMutableTransaction{*(m_current_transaction->getWtx())};
|
||||||
PartiallySignedTransaction psbtx(mtx);
|
PartiallySignedTransaction psbtx(mtx);
|
||||||
bool complete = false;
|
bool complete = false;
|
||||||
const TransactionError err = model->wallet().fillPSBT(SIGHASH_ALL, false /* sign */, true /* bip32derivs */, psbtx, complete);
|
const TransactionError err = model->wallet().fillPSBT(SIGHASH_ALL, false /* sign */, true /* bip32derivs */, psbtx, complete, nullptr);
|
||||||
assert(!complete);
|
assert(!complete);
|
||||||
assert(err == TransactionError::OK);
|
assert(err == TransactionError::OK);
|
||||||
// Serialize the PSBT
|
// Serialize the PSBT
|
||||||
|
|||||||
@@ -536,7 +536,7 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
|
|||||||
if (create_psbt) {
|
if (create_psbt) {
|
||||||
PartiallySignedTransaction psbtx(mtx);
|
PartiallySignedTransaction psbtx(mtx);
|
||||||
bool complete = false;
|
bool complete = false;
|
||||||
const TransactionError err = wallet().fillPSBT(SIGHASH_ALL, false /* sign */, true /* bip32derivs */, psbtx, complete);
|
const TransactionError err = wallet().fillPSBT(SIGHASH_ALL, false /* sign */, true /* bip32derivs */, psbtx, complete, nullptr);
|
||||||
if (err != TransactionError::OK || complete) {
|
if (err != TransactionError::OK || complete) {
|
||||||
QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Can't draft transaction."));
|
QMessageBox::critical(nullptr, tr("Fee bump error"), tr("Can't draft transaction."));
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -585,8 +585,11 @@ SigningResult LegacyScriptPubKeyMan::SignMessage(const std::string& message, con
|
|||||||
return SigningResult::SIGNING_FAILED;
|
return SigningResult::SIGNING_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionError LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, int sighash_type, bool sign, bool bip32derivs) const
|
TransactionError LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, int sighash_type, bool sign, bool bip32derivs, int* n_signed) const
|
||||||
{
|
{
|
||||||
|
if (n_signed) {
|
||||||
|
*n_signed = 0;
|
||||||
|
}
|
||||||
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
||||||
const CTxIn& txin = psbtx.tx->vin[i];
|
const CTxIn& txin = psbtx.tx->vin[i];
|
||||||
PSBTInput& input = psbtx.inputs.at(i);
|
PSBTInput& input = psbtx.inputs.at(i);
|
||||||
@@ -617,6 +620,14 @@ TransactionError LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psb
|
|||||||
SignatureData sigdata;
|
SignatureData sigdata;
|
||||||
input.FillSignatureData(sigdata);
|
input.FillSignatureData(sigdata);
|
||||||
SignPSBTInput(HidingSigningProvider(this, !sign, !bip32derivs), psbtx, i, sighash_type);
|
SignPSBTInput(HidingSigningProvider(this, !sign, !bip32derivs), psbtx, i, sighash_type);
|
||||||
|
|
||||||
|
bool signed_one = PSBTInputSigned(input);
|
||||||
|
if (n_signed && (signed_one || !sign)) {
|
||||||
|
// If sign is false, we assume that we _could_ sign if we get here. This
|
||||||
|
// will never have false negatives; it is hard to tell under what i
|
||||||
|
// circumstances it could have false positives.
|
||||||
|
(*n_signed)++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change
|
// Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change
|
||||||
@@ -2064,8 +2075,11 @@ SigningResult DescriptorScriptPubKeyMan::SignMessage(const std::string& message,
|
|||||||
return SigningResult::OK;
|
return SigningResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, int sighash_type, bool sign, bool bip32derivs) const
|
TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psbtx, int sighash_type, bool sign, bool bip32derivs, int* n_signed) const
|
||||||
{
|
{
|
||||||
|
if (n_signed) {
|
||||||
|
*n_signed = 0;
|
||||||
|
}
|
||||||
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
||||||
const CTxIn& txin = psbtx.tx->vin[i];
|
const CTxIn& txin = psbtx.tx->vin[i];
|
||||||
PSBTInput& input = psbtx.inputs.at(i);
|
PSBTInput& input = psbtx.inputs.at(i);
|
||||||
@@ -2117,6 +2131,14 @@ TransactionError DescriptorScriptPubKeyMan::FillPSBT(PartiallySignedTransaction&
|
|||||||
}
|
}
|
||||||
|
|
||||||
SignPSBTInput(HidingSigningProvider(keys.get(), !sign, !bip32derivs), psbtx, i, sighash_type);
|
SignPSBTInput(HidingSigningProvider(keys.get(), !sign, !bip32derivs), psbtx, i, sighash_type);
|
||||||
|
|
||||||
|
bool signed_one = PSBTInputSigned(input);
|
||||||
|
if (n_signed && (signed_one || !sign)) {
|
||||||
|
// If sign is false, we assume that we _could_ sign if we get here. This
|
||||||
|
// will never have false negatives; it is hard to tell under what i
|
||||||
|
// circumstances it could have false positives.
|
||||||
|
(*n_signed)++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change
|
// Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ public:
|
|||||||
/** Sign a message with the given script */
|
/** Sign a message with the given script */
|
||||||
virtual SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const { return SigningResult::SIGNING_FAILED; };
|
virtual SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const { return SigningResult::SIGNING_FAILED; };
|
||||||
/** Adds script and derivation path information to a PSBT, and optionally signs it. */
|
/** Adds script and derivation path information to a PSBT, and optionally signs it. */
|
||||||
virtual TransactionError FillPSBT(PartiallySignedTransaction& psbt, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false) const { return TransactionError::INVALID_PSBT; }
|
virtual TransactionError FillPSBT(PartiallySignedTransaction& psbt, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr) const { return TransactionError::INVALID_PSBT; }
|
||||||
|
|
||||||
virtual uint256 GetID() const { return uint256(); }
|
virtual uint256 GetID() const { return uint256(); }
|
||||||
|
|
||||||
@@ -393,7 +393,7 @@ public:
|
|||||||
|
|
||||||
bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const override;
|
bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const override;
|
||||||
SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override;
|
SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override;
|
||||||
TransactionError FillPSBT(PartiallySignedTransaction& psbt, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false) const override;
|
TransactionError FillPSBT(PartiallySignedTransaction& psbt, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr) const override;
|
||||||
|
|
||||||
uint256 GetID() const override;
|
uint256 GetID() const override;
|
||||||
|
|
||||||
@@ -596,7 +596,7 @@ public:
|
|||||||
|
|
||||||
bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const override;
|
bool SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const override;
|
||||||
SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override;
|
SigningResult SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const override;
|
||||||
TransactionError FillPSBT(PartiallySignedTransaction& psbt, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false) const override;
|
TransactionError FillPSBT(PartiallySignedTransaction& psbt, int sighash_type = 1 /* SIGHASH_ALL */, bool sign = true, bool bip32derivs = false, int* n_signed = nullptr) const override;
|
||||||
|
|
||||||
uint256 GetID() const override;
|
uint256 GetID() const override;
|
||||||
|
|
||||||
|
|||||||
@@ -2471,8 +2471,11 @@ bool CWallet::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& complete, int sighash_type, bool sign, bool bip32derivs) const
|
TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& complete, int sighash_type, bool sign, bool bip32derivs, size_t * n_signed) const
|
||||||
{
|
{
|
||||||
|
if (n_signed) {
|
||||||
|
*n_signed = 0;
|
||||||
|
}
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
// Get all of the previous transactions
|
// Get all of the previous transactions
|
||||||
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
|
||||||
@@ -2503,10 +2506,15 @@ TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& comp
|
|||||||
|
|
||||||
// Fill in information from ScriptPubKeyMans
|
// Fill in information from ScriptPubKeyMans
|
||||||
for (ScriptPubKeyMan* spk_man : GetAllScriptPubKeyMans()) {
|
for (ScriptPubKeyMan* spk_man : GetAllScriptPubKeyMans()) {
|
||||||
TransactionError res = spk_man->FillPSBT(psbtx, sighash_type, sign, bip32derivs);
|
int n_signed_this_spkm = 0;
|
||||||
|
TransactionError res = spk_man->FillPSBT(psbtx, sighash_type, sign, bip32derivs, &n_signed_this_spkm);
|
||||||
if (res != TransactionError::OK) {
|
if (res != TransactionError::OK) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n_signed) {
|
||||||
|
(*n_signed) += n_signed_this_spkm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete if every input is now signed
|
// Complete if every input is now signed
|
||||||
|
|||||||
@@ -964,7 +964,8 @@ public:
|
|||||||
bool& complete,
|
bool& complete,
|
||||||
int sighash_type = 1 /* SIGHASH_ALL */,
|
int sighash_type = 1 /* SIGHASH_ALL */,
|
||||||
bool sign = true,
|
bool sign = true,
|
||||||
bool bip32derivs = true) const;
|
bool bip32derivs = true,
|
||||||
|
size_t* n_signed = nullptr) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new transaction paying the recipients with a set of coins
|
* Create a new transaction paying the recipients with a set of coins
|
||||||
|
|||||||
Reference in New Issue
Block a user