mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 06:58:57 +01:00
Use 72 byte dummy signatures when watching only inputs may be used
With watching only inputs, we do not know how large the signatures for those inputs will be as their signers may not have implemented 71 byte signatures. Thus we estimate their fees using the 72 byte dummy signature to ensure that we pay enough fees. This only effects fundrawtransaction when includeWatching is true.
This commit is contained in:
@@ -1541,29 +1541,28 @@ int64_t CWalletTx::GetTxTime() const
|
||||
}
|
||||
|
||||
// Helper for producing a max-sized low-S low-R signature (eg 71 bytes)
|
||||
bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout) const
|
||||
// or a max-sized low-S signature (e.g. 72 bytes) if use_max_sig is true
|
||||
bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout, bool use_max_sig) const
|
||||
{
|
||||
// Fill in dummy signatures for fee calculation.
|
||||
const CScript& scriptPubKey = txout.scriptPubKey;
|
||||
SignatureData sigdata;
|
||||
|
||||
if (!ProduceSignature(*this, DUMMY_SIGNATURE_CREATOR, scriptPubKey, sigdata))
|
||||
{
|
||||
if (!ProduceSignature(*this, use_max_sig ? DUMMY_MAXIMUM_SIGNATURE_CREATOR : DUMMY_SIGNATURE_CREATOR, scriptPubKey, sigdata)) {
|
||||
return false;
|
||||
} else {
|
||||
UpdateInput(tx_in, sigdata);
|
||||
}
|
||||
UpdateInput(tx_in, sigdata);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper for producing a bunch of max-sized low-S low-R signatures (eg 71 bytes)
|
||||
bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts) const
|
||||
bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts, bool use_max_sig) const
|
||||
{
|
||||
// Fill in dummy signatures for fee calculation.
|
||||
int nIn = 0;
|
||||
for (const auto& txout : txouts)
|
||||
{
|
||||
if (!DummySignInput(txNew.vin[nIn], txout)) {
|
||||
if (!DummySignInput(txNew.vin[nIn], txout, use_max_sig)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1572,7 +1571,7 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut>
|
||||
return true;
|
||||
}
|
||||
|
||||
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet)
|
||||
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, bool use_max_sig)
|
||||
{
|
||||
std::vector<CTxOut> txouts;
|
||||
// Look up the inputs. We should have already checked that this transaction
|
||||
@@ -1586,14 +1585,14 @@ int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wall
|
||||
assert(input.prevout.n < mi->second.tx->vout.size());
|
||||
txouts.emplace_back(mi->second.tx->vout[input.prevout.n]);
|
||||
}
|
||||
return CalculateMaximumSignedTxSize(tx, wallet, txouts);
|
||||
return CalculateMaximumSignedTxSize(tx, wallet, txouts, use_max_sig);
|
||||
}
|
||||
|
||||
// txouts needs to be in the order of tx.vin
|
||||
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts)
|
||||
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts, bool use_max_sig)
|
||||
{
|
||||
CMutableTransaction txNew(tx);
|
||||
if (!wallet->DummySignTx(txNew, txouts)) {
|
||||
if (!wallet->DummySignTx(txNew, txouts, use_max_sig)) {
|
||||
// This should never happen, because IsAllFromMe(ISMINE_SPENDABLE)
|
||||
// implies that we can sign for every input.
|
||||
return -1;
|
||||
@@ -1601,11 +1600,11 @@ int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wall
|
||||
return GetVirtualTransactionSize(txNew);
|
||||
}
|
||||
|
||||
int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* wallet)
|
||||
int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* wallet, bool use_max_sig)
|
||||
{
|
||||
CMutableTransaction txn;
|
||||
txn.vin.push_back(CTxIn(COutPoint()));
|
||||
if (!wallet->DummySignInput(txn.vin[0], txout)) {
|
||||
if (!wallet->DummySignInput(txn.vin[0], txout, use_max_sig)) {
|
||||
// This should never happen, because IsAllFromMe(ISMINE_SPENDABLE)
|
||||
// implies that we can sign for every input.
|
||||
return -1;
|
||||
@@ -2332,7 +2331,7 @@ void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const
|
||||
bool solvable = IsSolvable(*this, pcoin->tx->vout[i].scriptPubKey);
|
||||
bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
|
||||
|
||||
vCoins.push_back(COutput(pcoin, i, nDepth, spendable, solvable, safeTx));
|
||||
vCoins.push_back(COutput(pcoin, i, nDepth, spendable, solvable, safeTx, (coinControl && coinControl->fAllowWatchOnly)));
|
||||
|
||||
// Checks the sum amount of all UTXO's.
|
||||
if (nMinimumSumAmount != MAX_MONEY) {
|
||||
@@ -2881,7 +2880,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
||||
txNew.vin.push_back(CTxIn(coin.outpoint,CScript()));
|
||||
}
|
||||
|
||||
nBytes = CalculateMaximumSignedTxSize(txNew, this);
|
||||
nBytes = CalculateMaximumSignedTxSize(txNew, this, coin_control.fAllowWatchOnly);
|
||||
if (nBytes < 0) {
|
||||
strFailReason = _("Signing transaction failed");
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user