Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 49: [PATCH 49/68] wallet: snapshot sweep fee settings under lock

src/wallet/spend.cpp

Before: src/wallet/spend.cpp · After: src/wallet/spend.cpp

File metadata
index 587575b2d2c582aef54b8a865918fe32995bdc5d..8e1788be94d3e4f523ee61092f0a07afc05d5d0b 100644

Download original patch · Release notes

Diff rows 1–31 of 31. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.

src/wallet/spend.cpp CHANGED
@@ -45,7 +45,7 @@ TRACEPOINT_SEMAPHORE(coin_selection, attempting_aps_create_tx);
45
  TRACEPOINT_SEMAPHORE(coin_selection, aps_create_tx_internal);
46
 
47
  namespace wallet {
48
- util::Result<SweepTransactionResult> CreateSweepTransaction(CWallet& wallet, FlatSigningProvider& provider,
49
  const std::map<COutPoint, Coin>& coins,
50
  const CScript& destination, const SweepBroadcastFn& broadcast,
51
  interfaces::SweepAuthorization& authorization)
@@ -61,16 +61,20 @@ util::Result<SweepTransactionResult> CreateSweepTransaction(CWallet& wallet, Fla
61
  tx.vout.emplace_back(amount, destination);
62
  std::map<int, bilingual_str> errors;
63
  if (!::SignTransaction(tx, &provider, coins, SIGHASH_DEFAULT, errors)) return util::Error{Untranslated("Unable to sign all swept inputs")};
 
 
 
 
64
  CAmount fee{0};
65
  for (int attempts{0}; attempts < 10; ++attempts) {
66
- fee = GetMinimumFee(wallet, GetVirtualTransactionSize(CTransaction{tx}), CCoinControl{}, nullptr);
67
  if (fee >= amount) return util::Error{Untranslated("Fee exceeds swept value")};
68
  tx.vout[0].nValue = amount - fee;
69
  errors.clear();
70
  if (!::SignTransaction(tx, &provider, coins, SIGHASH_DEFAULT, errors)) return util::Error{Untranslated("Unable to sign all swept inputs")};
71
- if (fee >= GetMinimumFee(wallet, GetVirtualTransactionSize(CTransaction{tx}), CCoinControl{}, nullptr)) break;
72
  }
73
- if (fee < GetMinimumFee(wallet, GetVirtualTransactionSize(CTransaction{tx}), CCoinControl{}, nullptr)) {
74
  return util::Error{Untranslated("Unable to calculate a stable sweep fee")};
75
  }
76
  if (IsDust(tx.vout[0], wallet.chain().relayMinFee())) return util::Error{Untranslated("Swept output would be dust")};
 
45
  TRACEPOINT_SEMAPHORE(coin_selection, aps_create_tx_internal);
46
 
47
  namespace wallet {
48
+ util::Result<SweepTransactionResult> CreateSweepTransaction(CWallet& wallet, const SigningProvider& provider,
49
  const std::map<COutPoint, Coin>& coins,
50
  const CScript& destination, const SweepBroadcastFn& broadcast,
51
  interfaces::SweepAuthorization& authorization)
 
61
  tx.vout.emplace_back(amount, destination);
62
  std::map<int, bilingual_str> errors;
63
  if (!::SignTransaction(tx, &provider, coins, SIGHASH_DEFAULT, errors)) return util::Error{Untranslated("Unable to sign all swept inputs")};
64
+ // Fee settings can change while the UTXO scan runs. Take one synchronized
65
+ // snapshot for every signing iteration without holding the wallet lock
66
+ // during signing or broadcast.
67
+ const CFeeRate fee_rate{WITH_LOCK(wallet.cs_wallet, return GetMinimumFeeRate(wallet, CCoinControl{}, nullptr))};
68
  CAmount fee{0};
69
  for (int attempts{0}; attempts < 10; ++attempts) {
70
+ fee = fee_rate.GetFee(GetVirtualTransactionSize(CTransaction{tx}));
71
  if (fee >= amount) return util::Error{Untranslated("Fee exceeds swept value")};
72
  tx.vout[0].nValue = amount - fee;
73
  errors.clear();
74
  if (!::SignTransaction(tx, &provider, coins, SIGHASH_DEFAULT, errors)) return util::Error{Untranslated("Unable to sign all swept inputs")};
75
+ if (fee >= fee_rate.GetFee(GetVirtualTransactionSize(CTransaction{tx}))) break;
76
  }
77
+ if (fee < fee_rate.GetFee(GetVirtualTransactionSize(CTransaction{tx}))) {
78
  return util::Error{Untranslated("Unable to calculate a stable sweep fee")};
79
  }
80
  if (IsDust(tx.vout[0], wallet.chain().relayMinFee())) return util::Error{Untranslated("Swept output would be dust")};