node: Refactor BroadcastTransaction to accept a CFeeRate maximum

This commit is contained in:
Luke Dashjr 2023-09-05 02:10:58 +00:00
parent 4b3cc3d48e
commit 1cee5b1ac7
4 changed files with 19 additions and 7 deletions

View File

@ -20,6 +20,7 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <variant>
#include <vector> #include <vector>
class BanMan; class BanMan;
@ -214,7 +215,7 @@ public:
virtual std::optional<Coin> getUnspentOutput(const COutPoint& output) = 0; virtual std::optional<Coin> getUnspentOutput(const COutPoint& output) = 0;
//! Broadcast transaction. //! Broadcast transaction.
virtual node::TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, std::string& err_string) = 0; virtual node::TransactionError broadcastTransaction(CTransactionRef tx, const std::variant<CAmount, CFeeRate>& max_tx_fee, std::string& err_string) = 0;
//! Get wallet loader. //! Get wallet loader.
virtual WalletLoader& walletLoader() = 0; virtual WalletLoader& walletLoader() = 0;

View File

@ -355,7 +355,7 @@ public:
if (chainman().ActiveChainstate().CoinsTip().GetCoin(output, coin)) return coin; if (chainman().ActiveChainstate().CoinsTip().GetCoin(output, coin)) return coin;
return {}; return {};
} }
TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, std::string& err_string) override TransactionError broadcastTransaction(CTransactionRef tx, const std::variant<CAmount, CFeeRate>& max_tx_fee, std::string& err_string) override
{ {
return BroadcastTransaction(*m_context, std::move(tx), err_string, max_tx_fee, /*relay=*/ true, /*wait_callback=*/ false); return BroadcastTransaction(*m_context, std::move(tx), err_string, max_tx_fee, /*relay=*/ true, /*wait_callback=*/ false);
} }

View File

@ -31,7 +31,7 @@ static TransactionError HandleATMPError(const TxValidationState& state, std::str
} }
} }
TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback) TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef tx, std::string& err_string, const std::variant<CAmount, CFeeRate>& max_tx_fee, bool relay, bool wait_callback)
{ {
// BroadcastTransaction can be called by RPC or by the wallet. // BroadcastTransaction can be called by RPC or by the wallet.
// chainman, mempool and peerman are initialized before the RPC server and wallet are started // chainman, mempool and peerman are initialized before the RPC server and wallet are started
@ -69,14 +69,23 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
wtxid = mempool_tx->GetWitnessHash(); wtxid = mempool_tx->GetWitnessHash();
} else { } else {
// Transaction is not already in the mempool. // Transaction is not already in the mempool.
if (max_tx_fee > 0) { const bool max_tx_fee_set{(std::holds_alternative<CAmount>(max_tx_fee) ? std::get<CAmount>(max_tx_fee) : std::get<CFeeRate>(max_tx_fee).GetFeePerK()) > 0};
if (max_tx_fee_set) {
// First, call ATMP with test_accept and check the fee. If ATMP // First, call ATMP with test_accept and check the fee. If ATMP
// fails here, return error immediately. // fails here, return error immediately.
const MempoolAcceptResult result = node.chainman->ProcessTransaction(tx, /*test_accept=*/ true); const MempoolAcceptResult result = node.chainman->ProcessTransaction(tx, /*test_accept=*/ true);
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) { if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
return HandleATMPError(result.m_state, err_string); return HandleATMPError(result.m_state, err_string);
} else if (result.m_base_fees.value() > max_tx_fee) { } else {
return TransactionError::MAX_FEE_EXCEEDED; CAmount max_tx_fee_abs;
if (std::holds_alternative<CFeeRate>(max_tx_fee)) {
max_tx_fee_abs = std::get<CFeeRate>(max_tx_fee).GetFee(*Assert(result.m_vsize));
} else {
max_tx_fee_abs = std::get<CAmount>(max_tx_fee);
}
if (result.m_base_fees.value() > max_tx_fee_abs) {
return TransactionError::MAX_FEE_EXCEEDED;
}
} }
} }
// Try to submit the transaction to the mempool. // Try to submit the transaction to the mempool.

View File

@ -9,6 +9,8 @@
#include <policy/feerate.h> #include <policy/feerate.h>
#include <primitives/transaction.h> #include <primitives/transaction.h>
#include <variant>
class CBlockIndex; class CBlockIndex;
class CTxMemPool; class CTxMemPool;
namespace Consensus { namespace Consensus {
@ -49,7 +51,7 @@ static const CAmount DEFAULT_MAX_BURN_AMOUNT{0};
* @param[in] wait_callback wait until callbacks have been processed to avoid stale result due to a sequentially RPC. * @param[in] wait_callback wait until callbacks have been processed to avoid stale result due to a sequentially RPC.
* return error * return error
*/ */
[[nodiscard]] TransactionError BroadcastTransaction(NodeContext& node, CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback); [[nodiscard]] TransactionError BroadcastTransaction(NodeContext& node, CTransactionRef tx, std::string& err_string, const std::variant<CAmount, CFeeRate>& max_tx_fee, bool relay, bool wait_callback);
/** /**
* Return transaction with a given hash. * Return transaction with a given hash.