Skip to content

Commit

Permalink
[wallet]: ensure 1kvb tx with -maxtxfee base fee has feerate atleas…
Browse files Browse the repository at this point in the history
…t minrelaytxfee

- Wallet prevents creating transactions with fee rates lower than `-minrelaytxfee`.
  Also prevents creating a transaction with a base fee above `-maxtxfee`.

- Ensure that a 1kvb transaction, with a base fee set to `-maxtxfee`, maintains a
  fee rate of at least `-minrelaytxfee`.
  Otherwise transactions with fee rates greater than or equal to the `-minrelaytxfee`
  will also likely exceed `-maxtxfee`, the wallet won't be able to create transactions.
  In such cases just shut down early.
  • Loading branch information
ismaelsadeeq committed Feb 13, 2024
1 parent d0507d2 commit 1d9dcd7
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3056,6 +3056,16 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
return nullptr;
} else if (max_fee.value() > HIGH_MAX_TX_FEE) {
warnings.push_back(strprintf(_("%s is set very high! Fees this large could be paid on a single transaction."), "-maxtxfee"));

// Wallet prevents creating transactions with fee rates lower than minrelaytxfee.
// Also the wallet prevents creating transaction with base fee above maxtxfee.
// Ensure that a 1kvb transaction, with a base fee set to maxtxfee, maintains a fee rate of at least minrelaytxfee.
// Otherwise transactions with fee rate greater than or equal to the minrelaytxfee will likely exceed maxtxfee.
// In such cases, the wallet won't be able to create transactions. Therefore, shut down early.
} else if (chain && CFeeRate(max_fee.value(), 1000) < chain->relayMinFee()) {
error = strprintf(_("Invalid amount for %s=<amount>: '%s' conflicts with the minrelay fee of %s. Consider adjusting %s or %s."),
"-maxtxfee", args.GetArg("-maxtxfee", ""), chain->relayMinFee().ToString(), "-maxtxfee", "-minrelaytxfee");
return nullptr;
}

walletInstance->m_max_tx_fee = max_fee.value();
Expand All @@ -3072,7 +3082,6 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
"-maxfeerate", args.GetArg("-maxfeerate", ""), chain->relayMinFee().ToString());
return nullptr;
}

walletInstance->m_max_tx_fee_rate = CFeeRate(max_fee_rate.value());
}

Expand Down
11 changes: 11 additions & 0 deletions test/functional/wallet_bumpfee.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,17 @@ def test_maxtxfee_fails(self, rbf_node, dest_address):

# When user passed fee rate causes base fee to be above maxtxfee we fail early
assert_raises_rpc_error(-4, "Specified or calculated fee 0.0000282 is too high (cannot be higher than -maxtxfee 0.000025)", rbf_node.bumpfee, rbfid, fee_rate=20)

self.log.info("Test that a low -maxtxfee that will likely prevents txs fee rate to reach -minrelaytxfee should fail at startup")
low_max_tx_fee = '0.000001'
high_max_tx_fee = '0.001'
high_min_relay_fee = '0.0002'
msg = f"Error: Invalid amount for -maxtxfee=<amount>: '{low_max_tx_fee}' conflicts with the minrelay fee of {format(float(high_min_relay_fee), '.8f')} BTC/kvB. Consider adjusting -maxtxfee or -minrelaytxfee."
self.stop_node(1)
self.nodes[1].assert_start_raises_init_error(extra_args=[f'-minrelaytxfee={high_min_relay_fee}', f'-maxtxfee={low_max_tx_fee}'], expected_msg=msg)

self.log.info("Test that -maxtxfee that will not result in preventing a transaction fee rate from reaching -minrelaytxfee should start normally")
self.start_node(1, extra_args=[f'-minrelaytxfee={high_min_relay_fee}', f'-maxtxfee={high_max_tx_fee}'])
self.restart_node(1, self.extra_args[1])
rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
self.connect_nodes(1, 0)
Expand Down

0 comments on commit 1d9dcd7

Please sign in to comment.