23
23
// calculation, but we should be able to refactor after priority is removed).
24
24
// NOTE: this requires that all inputs must be in mapWallet (eg the tx should
25
25
// be IsAllFromMe).
26
- int64_t CalculateMaximumSignedTxSize (const CTransaction &tx, const CWallet *wallet)
26
+ static int64_t CalculateMaximumSignedTxSize (const CTransaction &tx, const CWallet *wallet)
27
27
{
28
28
CMutableTransaction txNew (tx);
29
29
std::vector<CInputCoin> vCoins;
@@ -43,10 +43,12 @@ int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wall
43
43
return GetVirtualTransactionSize (txNew);
44
44
}
45
45
46
+ namespace feebumper {
47
+
46
48
bool FeeBumper::preconditionChecks (const CWallet *wallet, const CWalletTx& wtx) {
47
49
if (wallet->HasWalletSpend (wtx.GetHash ())) {
48
50
errors.push_back (" Transaction has descendants in the wallet" );
49
- current_result = BumpFeeResult ::INVALID_PARAMETER;
51
+ current_result = Result ::INVALID_PARAMETER;
50
52
return false ;
51
53
}
52
54
@@ -55,14 +57,14 @@ bool FeeBumper::preconditionChecks(const CWallet *wallet, const CWalletTx& wtx)
55
57
auto it_mp = mempool.mapTx .find (wtx.GetHash ());
56
58
if (it_mp != mempool.mapTx .end () && it_mp->GetCountWithDescendants () > 1 ) {
57
59
errors.push_back (" Transaction has descendants in the mempool" );
58
- current_result = BumpFeeResult ::INVALID_PARAMETER;
60
+ current_result = Result ::INVALID_PARAMETER;
59
61
return false ;
60
62
}
61
63
}
62
64
63
65
if (wtx.GetDepthInMainChain () != 0 ) {
64
66
errors.push_back (" Transaction has been mined, or is conflicted with a mined transaction" );
65
- current_result = BumpFeeResult ::WALLET_ERROR;
67
+ current_result = Result ::WALLET_ERROR;
66
68
return false ;
67
69
}
68
70
return true ;
@@ -80,7 +82,7 @@ FeeBumper::FeeBumper(const CWallet *wallet, const uint256 txid_in, const CCoinCo
80
82
auto it = wallet->mapWallet .find (txid);
81
83
if (it == wallet->mapWallet .end ()) {
82
84
errors.push_back (" Invalid or non-wallet transaction id" );
83
- current_result = BumpFeeResult ::INVALID_ADDRESS_OR_KEY;
85
+ current_result = Result ::INVALID_ADDRESS_OR_KEY;
84
86
return ;
85
87
}
86
88
const CWalletTx& wtx = it->second ;
@@ -91,21 +93,21 @@ FeeBumper::FeeBumper(const CWallet *wallet, const uint256 txid_in, const CCoinCo
91
93
92
94
if (!SignalsOptInRBF (*wtx.tx )) {
93
95
errors.push_back (" Transaction is not BIP 125 replaceable" );
94
- current_result = BumpFeeResult ::WALLET_ERROR;
96
+ current_result = Result ::WALLET_ERROR;
95
97
return ;
96
98
}
97
99
98
100
if (wtx.mapValue .count (" replaced_by_txid" )) {
99
101
errors.push_back (strprintf (" Cannot bump transaction %s which was already bumped by transaction %s" , txid.ToString (), wtx.mapValue .at (" replaced_by_txid" )));
100
- current_result = BumpFeeResult ::WALLET_ERROR;
102
+ current_result = Result ::WALLET_ERROR;
101
103
return ;
102
104
}
103
105
104
106
// check that original tx consists entirely of our inputs
105
107
// 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)
106
108
if (!wallet->IsAllFromMe (*wtx.tx , ISMINE_SPENDABLE)) {
107
109
errors.push_back (" Transaction contains inputs that don't belong to this wallet" );
108
- current_result = BumpFeeResult ::WALLET_ERROR;
110
+ current_result = Result ::WALLET_ERROR;
109
111
return ;
110
112
}
111
113
@@ -116,15 +118,15 @@ FeeBumper::FeeBumper(const CWallet *wallet, const uint256 txid_in, const CCoinCo
116
118
if (wallet->IsChange (wtx.tx ->vout [i])) {
117
119
if (nOutput != -1 ) {
118
120
errors.push_back (" Transaction has multiple change outputs" );
119
- current_result = BumpFeeResult ::WALLET_ERROR;
121
+ current_result = Result ::WALLET_ERROR;
120
122
return ;
121
123
}
122
124
nOutput = i;
123
125
}
124
126
}
125
127
if (nOutput == -1 ) {
126
128
errors.push_back (" Transaction does not have a change output" );
127
- current_result = BumpFeeResult ::WALLET_ERROR;
129
+ current_result = Result ::WALLET_ERROR;
128
130
return ;
129
131
}
130
132
@@ -133,7 +135,7 @@ FeeBumper::FeeBumper(const CWallet *wallet, const uint256 txid_in, const CCoinCo
133
135
const int64_t maxNewTxSize = CalculateMaximumSignedTxSize (*wtx.tx , wallet);
134
136
if (maxNewTxSize < 0 ) {
135
137
errors.push_back (" Transaction contains inputs that cannot be signed" );
136
- current_result = BumpFeeResult ::INVALID_ADDRESS_OR_KEY;
138
+ current_result = Result ::INVALID_ADDRESS_OR_KEY;
137
139
return ;
138
140
}
139
141
@@ -154,14 +156,14 @@ FeeBumper::FeeBumper(const CWallet *wallet, const uint256 txid_in, const CCoinCo
154
156
if (total_fee < minTotalFee) {
155
157
errors.push_back (strprintf (" Insufficient totalFee, must be at least %s (oldFee %s + incrementalFee %s)" ,
156
158
FormatMoney (minTotalFee), FormatMoney (nOldFeeRate.GetFee (maxNewTxSize)), FormatMoney (::incrementalRelayFee.GetFee (maxNewTxSize))));
157
- current_result = BumpFeeResult ::INVALID_PARAMETER;
159
+ current_result = Result ::INVALID_PARAMETER;
158
160
return ;
159
161
}
160
162
CAmount requiredFee = GetRequiredFee (maxNewTxSize);
161
163
if (total_fee < requiredFee) {
162
164
errors.push_back (strprintf (" Insufficient totalFee (cannot be less than required fee %s)" ,
163
165
FormatMoney (requiredFee)));
164
- current_result = BumpFeeResult ::INVALID_PARAMETER;
166
+ current_result = Result ::INVALID_PARAMETER;
165
167
return ;
166
168
}
167
169
new_fee = total_fee;
@@ -185,7 +187,7 @@ FeeBumper::FeeBumper(const CWallet *wallet, const uint256 txid_in, const CCoinCo
185
187
if (new_fee > maxTxFee) {
186
188
errors.push_back (strprintf (" Specified or calculated fee %s is too high (cannot be higher than maxTxFee %s)" ,
187
189
FormatMoney (new_fee), FormatMoney (maxTxFee)));
188
- current_result = BumpFeeResult ::WALLET_ERROR;
190
+ current_result = Result ::WALLET_ERROR;
189
191
return ;
190
192
}
191
193
@@ -203,7 +205,7 @@ FeeBumper::FeeBumper(const CWallet *wallet, const uint256 txid_in, const CCoinCo
203
205
FormatMoney (minMempoolFeeRate.GetFeePerK ()),
204
206
FormatMoney (minMempoolFeeRate.GetFee (maxNewTxSize)),
205
207
FormatMoney (minMempoolFeeRate.GetFeePerK ())));
206
- current_result = BumpFeeResult ::WALLET_ERROR;
208
+ current_result = Result ::WALLET_ERROR;
207
209
return ;
208
210
}
209
211
@@ -215,7 +217,7 @@ FeeBumper::FeeBumper(const CWallet *wallet, const uint256 txid_in, const CCoinCo
215
217
CTxOut* poutput = &(mtx.vout [nOutput]);
216
218
if (poutput->nValue < nDelta) {
217
219
errors.push_back (" Change output is too small to bump the fee" );
218
- current_result = BumpFeeResult ::WALLET_ERROR;
220
+ current_result = Result ::WALLET_ERROR;
219
221
return ;
220
222
}
221
223
@@ -234,7 +236,7 @@ FeeBumper::FeeBumper(const CWallet *wallet, const uint256 txid_in, const CCoinCo
234
236
}
235
237
}
236
238
237
- current_result = BumpFeeResult ::OK;
239
+ current_result = Result ::OK;
238
240
}
239
241
240
242
bool FeeBumper::signTransaction (CWallet *wallet)
@@ -245,13 +247,13 @@ bool FeeBumper::signTransaction(CWallet *wallet)
245
247
bool FeeBumper::commit (CWallet *wallet)
246
248
{
247
249
AssertLockHeld (wallet->cs_wallet );
248
- if (!errors.empty () || current_result != BumpFeeResult ::OK) {
250
+ if (!errors.empty () || current_result != Result ::OK) {
249
251
return false ;
250
252
}
251
253
auto it = txid.IsNull () ? wallet->mapWallet .end () : wallet->mapWallet .find (txid);
252
254
if (it == wallet->mapWallet .end ()) {
253
255
errors.push_back (" Invalid or non-wallet transaction id" );
254
- current_result = BumpFeeResult ::MISC_ERROR;
256
+ current_result = Result ::MISC_ERROR;
255
257
return false ;
256
258
}
257
259
CWalletTx& oldWtx = it->second ;
@@ -295,3 +297,5 @@ bool FeeBumper::commit(CWallet *wallet)
295
297
return true ;
296
298
}
297
299
300
+ } // namespace feebumper
301
+
0 commit comments