Skip to content

Commit e306be7

Browse files
committed
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.
1 parent 48b1473 commit e306be7

File tree

4 files changed

+45
-37
lines changed

4 files changed

+45
-37
lines changed

src/script/sign.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -417,22 +417,25 @@ class DummySignatureChecker final : public BaseSignatureChecker
417417
const DummySignatureChecker DUMMY_CHECKER;
418418

419419
class DummySignatureCreator final : public BaseSignatureCreator {
420+
private:
421+
char m_r_len = 32;
422+
char m_s_len = 32;
420423
public:
421-
DummySignatureCreator() {}
424+
DummySignatureCreator(char r_len, char s_len) : m_r_len(r_len), m_s_len(s_len) {}
422425
const BaseSignatureChecker& Checker() const override { return DUMMY_CHECKER; }
423426
bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override
424427
{
425428
// Create a dummy signature that is a valid DER-encoding
426-
vchSig.assign(71, '\000');
429+
vchSig.assign(m_r_len + m_s_len + 7, '\000');
427430
vchSig[0] = 0x30;
428-
vchSig[1] = 68;
431+
vchSig[1] = m_r_len + m_s_len + 4;
429432
vchSig[2] = 0x02;
430-
vchSig[3] = 32;
433+
vchSig[3] = m_r_len;
431434
vchSig[4] = 0x01;
432-
vchSig[4 + 32] = 0x02;
433-
vchSig[5 + 32] = 32;
434-
vchSig[6 + 32] = 0x01;
435-
vchSig[6 + 32 + 32] = SIGHASH_ALL;
435+
vchSig[4 + m_r_len] = 0x02;
436+
vchSig[5 + m_r_len] = m_s_len;
437+
vchSig[6 + m_r_len] = 0x01;
438+
vchSig[6 + m_r_len + m_s_len] = SIGHASH_ALL;
436439
return true;
437440
}
438441
};
@@ -450,7 +453,8 @@ bool LookupHelper(const M& map, const K& key, V& value)
450453

451454
}
452455

453-
const BaseSignatureCreator& DUMMY_SIGNATURE_CREATOR = DummySignatureCreator();
456+
const BaseSignatureCreator& DUMMY_SIGNATURE_CREATOR = DummySignatureCreator(32, 32);
457+
const BaseSignatureCreator& DUMMY_MAXIMUM_SIGNATURE_CREATOR = DummySignatureCreator(33, 32);
454458
const SigningProvider& DUMMY_SIGNING_PROVIDER = SigningProvider();
455459

456460
bool IsSolvable(const SigningProvider& provider, const CScript& script)

src/script/sign.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,10 @@ class MutableTransactionSignatureCreator : public BaseSignatureCreator {
8080
bool CreateSig(const SigningProvider& provider, std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const override;
8181
};
8282

83-
/** A signature creator that just produces 72-byte empty signatures. */
83+
/** A signature creator that just produces 71-byte empty signatures. */
8484
extern const BaseSignatureCreator& DUMMY_SIGNATURE_CREATOR;
85+
/** A signature creator that just produces 72-byte empty signatures. */
86+
extern const BaseSignatureCreator& DUMMY_MAXIMUM_SIGNATURE_CREATOR;
8587

8688
typedef std::pair<CPubKey, std::vector<unsigned char>> SigPair;
8789

src/wallet/wallet.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,29 +1541,28 @@ int64_t CWalletTx::GetTxTime() const
15411541
}
15421542

15431543
// Helper for producing a max-sized low-S low-R signature (eg 71 bytes)
1544-
bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout) const
1544+
// or a max-sized low-S signature (e.g. 72 bytes) if use_max_sig is true
1545+
bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout, bool use_max_sig) const
15451546
{
15461547
// Fill in dummy signatures for fee calculation.
15471548
const CScript& scriptPubKey = txout.scriptPubKey;
15481549
SignatureData sigdata;
15491550

1550-
if (!ProduceSignature(*this, DUMMY_SIGNATURE_CREATOR, scriptPubKey, sigdata))
1551-
{
1551+
if (!ProduceSignature(*this, use_max_sig ? DUMMY_MAXIMUM_SIGNATURE_CREATOR : DUMMY_SIGNATURE_CREATOR, scriptPubKey, sigdata)) {
15521552
return false;
1553-
} else {
1554-
UpdateInput(tx_in, sigdata);
15551553
}
1554+
UpdateInput(tx_in, sigdata);
15561555
return true;
15571556
}
15581557

15591558
// Helper for producing a bunch of max-sized low-S low-R signatures (eg 71 bytes)
1560-
bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts) const
1559+
bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts, bool use_max_sig) const
15611560
{
15621561
// Fill in dummy signatures for fee calculation.
15631562
int nIn = 0;
15641563
for (const auto& txout : txouts)
15651564
{
1566-
if (!DummySignInput(txNew.vin[nIn], txout)) {
1565+
if (!DummySignInput(txNew.vin[nIn], txout, use_max_sig)) {
15671566
return false;
15681567
}
15691568

@@ -1572,7 +1571,7 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut>
15721571
return true;
15731572
}
15741573

1575-
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet)
1574+
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, bool use_max_sig)
15761575
{
15771576
std::vector<CTxOut> txouts;
15781577
// Look up the inputs. We should have already checked that this transaction
@@ -1586,26 +1585,26 @@ int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wall
15861585
assert(input.prevout.n < mi->second.tx->vout.size());
15871586
txouts.emplace_back(mi->second.tx->vout[input.prevout.n]);
15881587
}
1589-
return CalculateMaximumSignedTxSize(tx, wallet, txouts);
1588+
return CalculateMaximumSignedTxSize(tx, wallet, txouts, use_max_sig);
15901589
}
15911590

15921591
// txouts needs to be in the order of tx.vin
1593-
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts)
1592+
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts, bool use_max_sig)
15941593
{
15951594
CMutableTransaction txNew(tx);
1596-
if (!wallet->DummySignTx(txNew, txouts)) {
1595+
if (!wallet->DummySignTx(txNew, txouts, use_max_sig)) {
15971596
// This should never happen, because IsAllFromMe(ISMINE_SPENDABLE)
15981597
// implies that we can sign for every input.
15991598
return -1;
16001599
}
16011600
return GetVirtualTransactionSize(txNew);
16021601
}
16031602

1604-
int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* wallet)
1603+
int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* wallet, bool use_max_sig)
16051604
{
16061605
CMutableTransaction txn;
16071606
txn.vin.push_back(CTxIn(COutPoint()));
1608-
if (!wallet->DummySignInput(txn.vin[0], txout)) {
1607+
if (!wallet->DummySignInput(txn.vin[0], txout, use_max_sig)) {
16091608
// This should never happen, because IsAllFromMe(ISMINE_SPENDABLE)
16101609
// implies that we can sign for every input.
16111610
return -1;
@@ -2332,7 +2331,7 @@ void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const
23322331
bool solvable = IsSolvable(*this, pcoin->tx->vout[i].scriptPubKey);
23332332
bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
23342333

2335-
vCoins.push_back(COutput(pcoin, i, nDepth, spendable, solvable, safeTx));
2334+
vCoins.push_back(COutput(pcoin, i, nDepth, spendable, solvable, safeTx, (coinControl && coinControl->fAllowWatchOnly)));
23362335

23372336
// Checks the sum amount of all UTXO's.
23382337
if (nMinimumSumAmount != MAX_MONEY) {
@@ -2881,7 +2880,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
28812880
txNew.vin.push_back(CTxIn(coin.outpoint,CScript()));
28822881
}
28832882

2884-
nBytes = CalculateMaximumSignedTxSize(txNew, this);
2883+
nBytes = CalculateMaximumSignedTxSize(txNew, this, coin_control.fAllowWatchOnly);
28852884
if (nBytes < 0) {
28862885
strFailReason = _("Signing transaction failed");
28872886
return false;

src/wallet/wallet.h

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ class CMerkleTx
276276
};
277277

278278
//Get the marginal bytes of spending the specified output
279-
int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* pwallet);
279+
int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* pwallet, bool use_max_sig = false);
280280

281281
/**
282282
* A transaction with a bunch of additional info that only the owner cares about.
@@ -461,9 +461,9 @@ class CWalletTx : public CMerkleTx
461461
CAmount GetChange() const;
462462

463463
// Get the marginal bytes if spending the specified output from this transaction
464-
int GetSpendSize(unsigned int out) const
464+
int GetSpendSize(unsigned int out, bool use_max_sig = false) const
465465
{
466-
return CalculateMaximumSignedInputSize(tx->vout[out], pwallet);
466+
return CalculateMaximumSignedInputSize(tx->vout[out], pwallet, use_max_sig);
467467
}
468468

469469
void GetAmounts(std::list<COutputEntry>& listReceived,
@@ -507,20 +507,23 @@ class COutput
507507
/** Whether we know how to spend this output, ignoring the lack of keys */
508508
bool fSolvable;
509509

510+
/** Whether to use the maximum sized, 72 byte signature when calculating the size of the input spend. This should only be set when watch-only outputs are allowed */
511+
bool use_max_sig;
512+
510513
/**
511514
* Whether this output is considered safe to spend. Unconfirmed transactions
512515
* from outside keys and unconfirmed replacement transactions are considered
513516
* unsafe and will not be used to fund new spending transactions.
514517
*/
515518
bool fSafe;
516519

517-
COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn, bool fSolvableIn, bool fSafeIn)
520+
COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn, bool fSolvableIn, bool fSafeIn, bool use_max_sig_in = false)
518521
{
519-
tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; fSolvable = fSolvableIn; fSafe = fSafeIn; nInputBytes = -1;
522+
tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; fSolvable = fSolvableIn; fSafe = fSafeIn; nInputBytes = -1; use_max_sig = use_max_sig_in;
520523
// If known and signable by the given wallet, compute nInputBytes
521524
// Failure will keep this value -1
522525
if (fSpendable && tx) {
523-
nInputBytes = tx->GetSpendSize(i);
526+
nInputBytes = tx->GetSpendSize(i, use_max_sig);
524527
}
525528
}
526529

@@ -976,14 +979,14 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
976979
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries);
977980
bool AddAccountingEntry(const CAccountingEntry&);
978981
bool AddAccountingEntry(const CAccountingEntry&, WalletBatch *batch);
979-
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts) const
982+
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts, bool use_max_sig = false) const
980983
{
981984
std::vector<CTxOut> v_txouts(txouts.size());
982985
std::copy(txouts.begin(), txouts.end(), v_txouts.begin());
983-
return DummySignTx(txNew, v_txouts);
986+
return DummySignTx(txNew, v_txouts, use_max_sig);
984987
}
985-
bool DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts) const;
986-
bool DummySignInput(CTxIn &tx_in, const CTxOut &txout) const;
988+
bool DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts, bool use_max_sig = false) const;
989+
bool DummySignInput(CTxIn &tx_in, const CTxOut &txout, bool use_max_sig = false) const;
987990

988991
CFeeRate m_pay_tx_fee{DEFAULT_PAY_TX_FEE};
989992
unsigned int m_confirm_target{DEFAULT_TX_CONFIRM_TARGET};
@@ -1311,6 +1314,6 @@ class WalletRescanReserver
13111314
// Use DummySignatureCreator, which inserts 71 byte signatures everywhere.
13121315
// NOTE: this requires that all inputs must be in mapWallet (eg the tx should
13131316
// be IsAllFromMe).
1314-
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet);
1315-
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts);
1317+
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, bool use_max_sig = false);
1318+
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts, bool use_max_sig = false);
13161319
#endif // BITCOIN_WALLET_WALLET_H

0 commit comments

Comments
 (0)