@@ -150,132 +150,6 @@ bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid)
150
150
return res == feebumper::Result::OK;
151
151
}
152
152
153
- Result CreateTotalBumpTransaction (const CWallet* wallet, const uint256& txid, const CCoinControl& coin_control, CAmount total_fee, std::vector<std::string>& errors,
154
- CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx)
155
- {
156
- new_fee = total_fee;
157
-
158
- auto locked_chain = wallet->chain ().lock ();
159
- LOCK (wallet->cs_wallet );
160
- errors.clear ();
161
- auto it = wallet->mapWallet .find (txid);
162
- if (it == wallet->mapWallet .end ()) {
163
- errors.push_back (" Invalid or non-wallet transaction id" );
164
- return Result::INVALID_ADDRESS_OR_KEY;
165
- }
166
- const CWalletTx& wtx = it->second ;
167
-
168
- Result result = PreconditionChecks (*wallet, wtx, errors);
169
- if (result != Result::OK) {
170
- return result;
171
- }
172
-
173
- // figure out which output was change
174
- // if there was no change output or multiple change outputs, fail
175
- int nOutput = -1 ;
176
- for (size_t i = 0 ; i < wtx.tx ->vout .size (); ++i) {
177
- if (wallet->IsChange (wtx.tx ->vout [i])) {
178
- if (nOutput != -1 ) {
179
- errors.push_back (" Transaction has multiple change outputs" );
180
- return Result::WALLET_ERROR;
181
- }
182
- nOutput = i;
183
- }
184
- }
185
- if (nOutput == -1 ) {
186
- errors.push_back (" Transaction does not have a change output" );
187
- return Result::WALLET_ERROR;
188
- }
189
-
190
- // Calculate the expected size of the new transaction.
191
- int64_t txSize = GetVirtualTransactionSize (*(wtx.tx ));
192
- const int64_t maxNewTxSize = CalculateMaximumSignedTxSize (*wtx.tx , wallet);
193
- if (maxNewTxSize < 0 ) {
194
- errors.push_back (" Transaction contains inputs that cannot be signed" );
195
- return Result::INVALID_ADDRESS_OR_KEY;
196
- }
197
-
198
- // calculate the old fee and fee-rate
199
- isminefilter filter = wallet->GetLegacyScriptPubKeyMan () && wallet->IsWalletFlagSet (WALLET_FLAG_DISABLE_PRIVATE_KEYS) ? ISMINE_WATCH_ONLY : ISMINE_SPENDABLE;
200
- old_fee = wtx.GetDebit (filter) - wtx.tx ->GetValueOut ();
201
- CFeeRate nOldFeeRate (old_fee, txSize);
202
- // The wallet uses a conservative WALLET_INCREMENTAL_RELAY_FEE value to
203
- // future proof against changes to network wide policy for incremental relay
204
- // fee that our node may not be aware of.
205
- CFeeRate nodeIncrementalRelayFee = wallet->chain ().relayIncrementalFee ();
206
- CFeeRate walletIncrementalRelayFee = CFeeRate (WALLET_INCREMENTAL_RELAY_FEE);
207
- if (nodeIncrementalRelayFee > walletIncrementalRelayFee) {
208
- walletIncrementalRelayFee = nodeIncrementalRelayFee;
209
- }
210
-
211
- CAmount minTotalFee = nOldFeeRate.GetFee (maxNewTxSize) + nodeIncrementalRelayFee.GetFee (maxNewTxSize);
212
- if (total_fee < minTotalFee) {
213
- errors.push_back (strprintf (" Insufficient totalFee, must be at least %s (oldFee %s + incrementalFee %s)" ,
214
- FormatMoney (minTotalFee), FormatMoney (nOldFeeRate.GetFee (maxNewTxSize)), FormatMoney (nodeIncrementalRelayFee.GetFee (maxNewTxSize))));
215
- return Result::INVALID_PARAMETER;
216
- }
217
- CAmount requiredFee = GetRequiredFee (*wallet, maxNewTxSize);
218
- if (total_fee < requiredFee) {
219
- errors.push_back (strprintf (" Insufficient totalFee (cannot be less than required fee %s)" ,
220
- FormatMoney (requiredFee)));
221
- return Result::INVALID_PARAMETER;
222
- }
223
-
224
- // Check that in all cases the new fee doesn't violate maxTxFee
225
- const CAmount max_tx_fee = wallet->m_default_max_tx_fee ;
226
- if (new_fee > max_tx_fee) {
227
- errors.push_back (strprintf (" Specified or calculated fee %s is too high (cannot be higher than -maxtxfee %s)" ,
228
- FormatMoney (new_fee), FormatMoney (max_tx_fee)));
229
- return Result::WALLET_ERROR;
230
- }
231
-
232
- // check that fee rate is higher than mempool's minimum fee
233
- // (no point in bumping fee if we know that the new tx won't be accepted to the mempool)
234
- // This may occur if the user set TotalFee or paytxfee too low, if fallbackfee is too low, or, perhaps,
235
- // in a rare situation where the mempool minimum fee increased significantly since the fee estimation just a
236
- // moment earlier. In this case, we report an error to the user, who may use total_fee to make an adjustment.
237
- CFeeRate minMempoolFeeRate = wallet->chain ().mempoolMinFee ();
238
- CFeeRate nNewFeeRate = CFeeRate (total_fee, maxNewTxSize);
239
- if (nNewFeeRate.GetFeePerK () < minMempoolFeeRate.GetFeePerK ()) {
240
- errors.push_back (strprintf (
241
- " New fee rate (%s) is lower than the minimum fee rate (%s) to get into the mempool -- "
242
- " the totalFee value should be at least %s to add transaction" ,
243
- FormatMoney (nNewFeeRate.GetFeePerK ()),
244
- FormatMoney (minMempoolFeeRate.GetFeePerK ()),
245
- FormatMoney (minMempoolFeeRate.GetFee (maxNewTxSize))));
246
- return Result::WALLET_ERROR;
247
- }
248
-
249
- // Now modify the output to increase the fee.
250
- // If the output is not large enough to pay the fee, fail.
251
- CAmount nDelta = new_fee - old_fee;
252
- assert (nDelta > 0 );
253
- mtx = CMutableTransaction{*wtx.tx };
254
- CTxOut* poutput = &(mtx.vout [nOutput]);
255
- if (poutput->nValue < nDelta) {
256
- errors.push_back (" Change output is too small to bump the fee" );
257
- return Result::WALLET_ERROR;
258
- }
259
-
260
- // If the output would become dust, discard it (converting the dust to fee)
261
- poutput->nValue -= nDelta;
262
- if (poutput->nValue <= GetDustThreshold (*poutput, GetDiscardRate (*wallet))) {
263
- wallet->WalletLogPrintf (" Bumping fee and discarding dust output\n " );
264
- new_fee += poutput->nValue ;
265
- mtx.vout .erase (mtx.vout .begin () + nOutput);
266
- }
267
-
268
- // Mark new tx not replaceable, if requested.
269
- if (!coin_control.m_signal_bip125_rbf .get_value_or (wallet->m_signal_rbf )) {
270
- for (auto & input : mtx.vin ) {
271
- if (input.nSequence < 0xfffffffe ) input.nSequence = 0xfffffffe ;
272
- }
273
- }
274
-
275
- return Result::OK;
276
- }
277
-
278
-
279
153
Result CreateRateBumpTransaction (CWallet& wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<std::string>& errors,
280
154
CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx)
281
155
{
0 commit comments