diff options
author | Sjors Provoost <sjors@sprovoost.nl> | 2023-02-23 18:30:12 +0100 |
---|---|---|
committer | Sjors Provoost <sjors@sprovoost.nl> | 2023-02-23 18:30:12 +0100 |
commit | 807de2cebdad960c2b52185528ca8960ec694f49 (patch) | |
tree | 3d4c81ef3f7681a1107b495eaa581c7a7679915a /src/wallet/wallet.cpp | |
parent | 72b763e4521e674990da5dd1999b7a8c7bd3ba8c (diff) |
wallet: skip R-value grinding for external signers
When producing a dummy signature for the purpose of estimating the transaction fee, do not assume an external signer performs R-value grinding on the signature.
In particular, this avoids a scenario where the fee rate is 1 sat / vbyte and a transaction with a 72 byte signature is not accepted into our mempool.
This commit also drops the nullptr default for CCoinControl arguments for functions that it touches. This is because having a boolean argument right next to an optional pointer is error prone.
Co-Authored-By: S3RK <1466284+S3RK@users.noreply.github.com>
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r-- | src/wallet/wallet.cpp | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index daddd6446d..e5c03849af 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1642,7 +1642,7 @@ void CWallet::InitWalletFlags(uint64_t flags) // Helper for producing a max-sized low-S low-R signature (eg 71 bytes) // or a max-sized low-S signature (e.g. 72 bytes) depending on coin_control -bool DummySignInput(const SigningProvider& provider, CTxIn &tx_in, const CTxOut &txout, const CCoinControl* coin_control) +bool DummySignInput(const SigningProvider& provider, CTxIn &tx_in, const CTxOut &txout, bool can_grind_r, const CCoinControl* coin_control) { // Fill in dummy signatures for fee calculation. const CScript& scriptPubKey = txout.scriptPubKey; @@ -1650,7 +1650,7 @@ bool DummySignInput(const SigningProvider& provider, CTxIn &tx_in, const CTxOut // Use max sig if watch only inputs were used or if this particular input is an external input // to ensure a sufficient fee is attained for the requested feerate. - const bool use_max_sig = coin_control && (coin_control->fAllowWatchOnly || coin_control->IsExternalSelected(tx_in.prevout)); + const bool use_max_sig = coin_control && (coin_control->fAllowWatchOnly || coin_control->IsExternalSelected(tx_in.prevout) || !can_grind_r); if (!ProduceSignature(provider, use_max_sig ? DUMMY_MAXIMUM_SIGNATURE_CREATOR : DUMMY_SIGNATURE_CREATOR, scriptPubKey, sigdata)) { return false; } @@ -1706,6 +1706,7 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> { // Fill in dummy signatures for fee calculation. int nIn = 0; + const bool can_grind_r = CanGrindR(); for (const auto& txout : txouts) { CTxIn& txin = txNew.vin[nIn]; @@ -1718,8 +1719,8 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> continue; } const std::unique_ptr<SigningProvider> provider = GetSolvingProvider(txout.scriptPubKey); - if (!provider || !DummySignInput(*provider, txin, txout, coin_control)) { - if (!coin_control || !DummySignInput(coin_control->m_external_provider, txin, txout, coin_control)) { + if (!provider || !DummySignInput(*provider, txin, txout, can_grind_r, coin_control)) { + if (!coin_control || !DummySignInput(coin_control->m_external_provider, txin, txout, can_grind_r, coin_control)) { return false; } } @@ -4081,6 +4082,11 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error) return true; } +bool CWallet::CanGrindR() const +{ + return !IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER); +} + bool DoMigration(CWallet& wallet, WalletContext& context, bilingual_str& error, MigrationResult& res) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) { AssertLockHeld(wallet.cs_wallet); |