17
17
18
18
// ! Check whether transaction has descendant in wallet or mempool, or has been
19
19
// ! mined, or conflicts with a mined transaction. Return a feebumper::Result.
20
- static feebumper::Result PreconditionChecks (interfaces::Chain::Lock& locked_chain, const CWallet* wallet, const CWalletTx& wtx, std::vector<std::string>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet-> cs_wallet)
20
+ static feebumper::Result PreconditionChecks (interfaces::Chain::Lock& locked_chain, const CWallet& wallet, const CWalletTx& wtx, std::vector<std::string>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet. cs_wallet)
21
21
{
22
- if (wallet-> HasWalletSpend (wtx.GetHash ())) {
22
+ if (wallet. HasWalletSpend (wtx.GetHash ())) {
23
23
errors.push_back (" Transaction has descendants in the wallet" );
24
24
return feebumper::Result::INVALID_PARAMETER;
25
25
}
26
26
27
27
{
28
- if (wallet-> chain ().hasDescendantsInMempool (wtx.GetHash ())) {
28
+ if (wallet. chain ().hasDescendantsInMempool (wtx.GetHash ())) {
29
29
errors.push_back (" Transaction has descendants in the mempool" );
30
30
return feebumper::Result::INVALID_PARAMETER;
31
31
}
@@ -48,7 +48,7 @@ static feebumper::Result PreconditionChecks(interfaces::Chain::Lock& locked_chai
48
48
49
49
// check that original tx consists entirely of our inputs
50
50
// if not, we can't bump the fee, because the wallet has no way of knowing the value of the other inputs (thus the fee)
51
- if (!wallet-> IsAllFromMe (*wtx.tx , ISMINE_SPENDABLE)) {
51
+ if (!wallet. IsAllFromMe (*wtx.tx , ISMINE_SPENDABLE)) {
52
52
errors.push_back (" Transaction contains inputs that don't belong to this wallet" );
53
53
return feebumper::Result::WALLET_ERROR;
54
54
}
@@ -58,13 +58,13 @@ static feebumper::Result PreconditionChecks(interfaces::Chain::Lock& locked_chai
58
58
}
59
59
60
60
// ! Check if the user provided a valid feeRate
61
- static feebumper::Result CheckFeeRate (const CWallet* wallet, const CWalletTx& wtx, const CFeeRate& newFeerate, const int64_t maxTxSize, std::vector<std::string>& errors) {
61
+ static feebumper::Result CheckFeeRate (const CWallet& wallet, const CWalletTx& wtx, const CFeeRate& newFeerate, const int64_t maxTxSize, std::vector<std::string>& errors) {
62
62
// check that fee rate is higher than mempool's minimum fee
63
63
// (no point in bumping fee if we know that the new tx won't be accepted to the mempool)
64
64
// This may occur if the user set FeeRate, TotalFee or paytxfee too low, if fallbackfee is too low, or, perhaps,
65
65
// in a rare situation where the mempool minimum fee increased significantly since the fee estimation just a
66
66
// moment earlier. In this case, we report an error to the user, who may adjust the fee.
67
- CFeeRate minMempoolFeeRate = wallet-> chain ().mempoolMinFee ();
67
+ CFeeRate minMempoolFeeRate = wallet. chain ().mempoolMinFee ();
68
68
69
69
if (newFeerate.GetFeePerK () < minMempoolFeeRate.GetFeePerK ()) {
70
70
errors.push_back (strprintf (
@@ -76,7 +76,7 @@ static feebumper::Result CheckFeeRate(const CWallet* wallet, const CWalletTx& wt
76
76
77
77
CAmount new_total_fee = newFeerate.GetFee (maxTxSize);
78
78
79
- CFeeRate incrementalRelayFee = std::max (wallet-> chain ().relayIncrementalFee (), CFeeRate (WALLET_INCREMENTAL_RELAY_FEE));
79
+ CFeeRate incrementalRelayFee = std::max (wallet. chain ().relayIncrementalFee (), CFeeRate (WALLET_INCREMENTAL_RELAY_FEE));
80
80
81
81
// Given old total fee and transaction size, calculate the old feeRate
82
82
CAmount old_fee = wtx.GetDebit (ISMINE_SPENDABLE) - wtx.tx ->GetValueOut ();
@@ -91,15 +91,15 @@ static feebumper::Result CheckFeeRate(const CWallet* wallet, const CWalletTx& wt
91
91
return feebumper::Result::INVALID_PARAMETER;
92
92
}
93
93
94
- CAmount requiredFee = GetRequiredFee (* wallet, maxTxSize);
94
+ CAmount requiredFee = GetRequiredFee (wallet, maxTxSize);
95
95
if (new_total_fee < requiredFee) {
96
96
errors.push_back (strprintf (" Insufficient total fee (cannot be less than required fee %s)" ,
97
97
FormatMoney (requiredFee)));
98
98
return feebumper::Result::INVALID_PARAMETER;
99
99
}
100
100
101
101
// Check that in all cases the new fee doesn't violate maxTxFee
102
- const CAmount max_tx_fee = wallet-> m_default_max_tx_fee ;
102
+ const CAmount max_tx_fee = wallet. m_default_max_tx_fee ;
103
103
if (new_total_fee > max_tx_fee) {
104
104
errors.push_back (strprintf (" Specified or calculated fee %s is too high (cannot be higher than -maxtxfee %s)" ,
105
105
FormatMoney (new_total_fee), FormatMoney (max_tx_fee)));
@@ -109,7 +109,7 @@ static feebumper::Result CheckFeeRate(const CWallet* wallet, const CWalletTx& wt
109
109
return feebumper::Result::OK;
110
110
}
111
111
112
- static CFeeRate EstimateFeeRate (CWallet* wallet, const CWalletTx& wtx, CCoinControl& coin_control, CAmount& old_fee)
112
+ static CFeeRate EstimateFeeRate (const CWallet& wallet, const CWalletTx& wtx, CCoinControl& coin_control, CAmount& old_fee)
113
113
{
114
114
// Get the fee rate of the original transaction. This is calculated from
115
115
// the tx fee/vsize, so it may have been rounded down. Add 1 satoshi to the
@@ -126,24 +126,24 @@ static CFeeRate EstimateFeeRate(CWallet* wallet, const CWalletTx& wtx, CCoinCont
126
126
// aware of. This ensures we're over the required relay fee rate
127
127
// (BIP 125 rule 4). The replacement tx will be at least as large as the
128
128
// original tx, so the total fee will be greater (BIP 125 rule 3)
129
- CFeeRate node_incremental_relay_fee = wallet-> chain ().relayIncrementalFee ();
129
+ CFeeRate node_incremental_relay_fee = wallet. chain ().relayIncrementalFee ();
130
130
CFeeRate wallet_incremental_relay_fee = CFeeRate (WALLET_INCREMENTAL_RELAY_FEE);
131
131
feerate += std::max (node_incremental_relay_fee, wallet_incremental_relay_fee);
132
132
133
133
// Fee rate must also be at least the wallet's GetMinimumFeeRate
134
- CFeeRate min_feerate (GetMinimumFeeRate (* wallet, coin_control, /* feeCalc */ nullptr ));
134
+ CFeeRate min_feerate (GetMinimumFeeRate (wallet, coin_control, /* feeCalc */ nullptr ));
135
135
136
136
// Set the required fee rate for the replacement transaction in coin control.
137
137
return std::max (feerate, min_feerate);
138
138
}
139
139
140
140
namespace feebumper {
141
141
142
- bool TransactionCanBeBumped (const CWallet* wallet, const uint256& txid)
142
+ bool TransactionCanBeBumped (const CWallet& wallet, const uint256& txid)
143
143
{
144
- auto locked_chain = wallet-> chain ().lock ();
145
- LOCK (wallet-> cs_wallet );
146
- const CWalletTx* wtx = wallet-> GetWalletTx (txid);
144
+ auto locked_chain = wallet. chain ().lock ();
145
+ LOCK (wallet. cs_wallet );
146
+ const CWalletTx* wtx = wallet. GetWalletTx (txid);
147
147
if (wtx == nullptr ) return false ;
148
148
149
149
std::vector<std::string> errors_dummy;
@@ -166,7 +166,7 @@ Result CreateTotalBumpTransaction(const CWallet* wallet, const uint256& txid, co
166
166
}
167
167
const CWalletTx& wtx = it->second ;
168
168
169
- Result result = PreconditionChecks (*locked_chain, wallet, wtx, errors);
169
+ Result result = PreconditionChecks (*locked_chain, * wallet, wtx, errors);
170
170
if (result != Result::OK) {
171
171
return result;
172
172
}
@@ -276,17 +276,17 @@ Result CreateTotalBumpTransaction(const CWallet* wallet, const uint256& txid, co
276
276
}
277
277
278
278
279
- Result CreateRateBumpTransaction (CWallet* wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<std::string>& errors,
279
+ Result CreateRateBumpTransaction (CWallet& wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<std::string>& errors,
280
280
CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx)
281
281
{
282
282
// We are going to modify coin control later, copy to re-use
283
283
CCoinControl new_coin_control (coin_control);
284
284
285
- auto locked_chain = wallet-> chain ().lock ();
286
- LOCK (wallet-> cs_wallet );
285
+ auto locked_chain = wallet. chain ().lock ();
286
+ LOCK (wallet. cs_wallet );
287
287
errors.clear ();
288
- auto it = wallet-> mapWallet .find (txid);
289
- if (it == wallet-> mapWallet .end ()) {
288
+ auto it = wallet. mapWallet .find (txid);
289
+ if (it == wallet. mapWallet .end ()) {
290
290
errors.push_back (" Invalid or non-wallet transaction id" );
291
291
return Result::INVALID_ADDRESS_OR_KEY;
292
292
}
@@ -300,7 +300,7 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
300
300
// Fill in recipients(and preserve a single change key if there is one)
301
301
std::vector<CRecipient> recipients;
302
302
for (const auto & output : wtx.tx ->vout ) {
303
- if (!wallet-> IsChange (output)) {
303
+ if (!wallet. IsChange (output)) {
304
304
CRecipient recipient = {output.scriptPubKey , output.nValue , false };
305
305
recipients.push_back (recipient);
306
306
} else {
@@ -313,7 +313,7 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
313
313
if (coin_control.m_feerate ) {
314
314
// The user provided a feeRate argument.
315
315
// We calculate this here to avoid compiler warning on the cs_wallet lock
316
- const int64_t maxTxSize = CalculateMaximumSignedTxSize (*wtx.tx , wallet);
316
+ const int64_t maxTxSize = CalculateMaximumSignedTxSize (*wtx.tx , & wallet);
317
317
Result res = CheckFeeRate (wallet, wtx, *new_coin_control.m_feerate , maxTxSize, errors);
318
318
if (res != Result::OK) {
319
319
return res;
@@ -342,7 +342,7 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
342
342
CAmount fee_ret;
343
343
int change_pos_in_out = -1 ; // No requested location for change
344
344
std::string fail_reason;
345
- if (!wallet-> CreateTransaction (*locked_chain, recipients, tx_new, fee_ret, change_pos_in_out, fail_reason, new_coin_control, false )) {
345
+ if (!wallet. CreateTransaction (*locked_chain, recipients, tx_new, fee_ret, change_pos_in_out, fail_reason, new_coin_control, false )) {
346
346
errors.push_back (" Unable to create transaction: " + fail_reason);
347
347
return Result::WALLET_ERROR;
348
348
}
@@ -353,7 +353,7 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
353
353
// Write back transaction
354
354
mtx = CMutableTransaction (*tx_new);
355
355
// Mark new tx not replaceable, if requested.
356
- if (!coin_control.m_signal_bip125_rbf .get_value_or (wallet-> m_signal_rbf )) {
356
+ if (!coin_control.m_signal_bip125_rbf .get_value_or (wallet. m_signal_rbf )) {
357
357
for (auto & input : mtx.vin ) {
358
358
if (input.nSequence < 0xfffffffe ) input.nSequence = 0xfffffffe ;
359
359
}
@@ -362,21 +362,21 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
362
362
return Result::OK;
363
363
}
364
364
365
- bool SignTransaction (CWallet* wallet, CMutableTransaction& mtx) {
366
- auto locked_chain = wallet-> chain ().lock ();
367
- LOCK (wallet-> cs_wallet );
368
- return wallet-> SignTransaction (mtx);
365
+ bool SignTransaction (CWallet& wallet, CMutableTransaction& mtx) {
366
+ auto locked_chain = wallet. chain ().lock ();
367
+ LOCK (wallet. cs_wallet );
368
+ return wallet. SignTransaction (mtx);
369
369
}
370
370
371
- Result CommitTransaction (CWallet* wallet, const uint256& txid, CMutableTransaction&& mtx, std::vector<std::string>& errors, uint256& bumped_txid)
371
+ Result CommitTransaction (CWallet& wallet, const uint256& txid, CMutableTransaction&& mtx, std::vector<std::string>& errors, uint256& bumped_txid)
372
372
{
373
- auto locked_chain = wallet-> chain ().lock ();
374
- LOCK (wallet-> cs_wallet );
373
+ auto locked_chain = wallet. chain ().lock ();
374
+ LOCK (wallet. cs_wallet );
375
375
if (!errors.empty ()) {
376
376
return Result::MISC_ERROR;
377
377
}
378
- auto it = txid.IsNull () ? wallet-> mapWallet .end () : wallet-> mapWallet .find (txid);
379
- if (it == wallet-> mapWallet .end ()) {
378
+ auto it = txid.IsNull () ? wallet. mapWallet .end () : wallet. mapWallet .find (txid);
379
+ if (it == wallet. mapWallet .end ()) {
380
380
errors.push_back (" Invalid or non-wallet transaction id" );
381
381
return Result::MISC_ERROR;
382
382
}
@@ -394,7 +394,7 @@ Result CommitTransaction(CWallet* wallet, const uint256& txid, CMutableTransacti
394
394
mapValue[" replaces_txid" ] = oldWtx.GetHash ().ToString ();
395
395
396
396
CValidationState state;
397
- if (!wallet-> CommitTransaction (tx, std::move (mapValue), oldWtx.vOrderForm , state)) {
397
+ if (!wallet. CommitTransaction (tx, std::move (mapValue), oldWtx.vOrderForm , state)) {
398
398
// NOTE: CommitTransaction never returns false, so this should never happen.
399
399
errors.push_back (strprintf (" The transaction was rejected: %s" , FormatStateMessage (state)));
400
400
return Result::WALLET_ERROR;
@@ -408,7 +408,7 @@ Result CommitTransaction(CWallet* wallet, const uint256& txid, CMutableTransacti
408
408
}
409
409
410
410
// mark the original tx as bumped
411
- if (!wallet-> MarkReplaced (oldWtx.GetHash (), bumped_txid)) {
411
+ if (!wallet. MarkReplaced (oldWtx.GetHash (), bumped_txid)) {
412
412
// TODO: see if JSON-RPC has a standard way of returning a response
413
413
// along with an exception. It would be good to return information about
414
414
// wtxBumped to the caller even if marking the original transaction
0 commit comments