diff options
Diffstat (limited to 'src/node')
-rw-r--r-- | src/node/context.cpp | 1 | ||||
-rw-r--r-- | src/node/context.h | 6 | ||||
-rw-r--r-- | src/node/transaction.cpp | 41 |
3 files changed, 33 insertions, 15 deletions
diff --git a/src/node/context.cpp b/src/node/context.cpp index 0238aab0d9..49d0c37235 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -9,6 +9,7 @@ #include <net.h> #include <net_processing.h> #include <scheduler.h> +#include <txmempool.h> NodeContext::NodeContext() {} NodeContext::~NodeContext() {} diff --git a/src/node/context.h b/src/node/context.h index 793c9dfc34..3228831ed1 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -16,7 +16,7 @@ class CConnman; class CScheduler; class CTxMemPool; class ChainstateManager; -class PeerLogicValidation; +class PeerManager; namespace interfaces { class Chain; class ChainClient; @@ -35,8 +35,8 @@ class WalletClient; //! be used without pulling in unwanted dependencies or functionality. struct NodeContext { std::unique_ptr<CConnman> connman; - CTxMemPool* mempool{nullptr}; // Currently a raw pointer because the memory is not managed by this struct - std::unique_ptr<PeerLogicValidation> peer_logic; + std::unique_ptr<CTxMemPool> mempool; + std::unique_ptr<PeerManager> peerman; ChainstateManager* chainman{nullptr}; // Currently a raw pointer because the memory is not managed by this struct std::unique_ptr<BanMan> banman; ArgsManager* args{nullptr}; // Currently a raw pointer because the memory is not managed by this struct diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp index 5633abe817..97d5aad8e4 100644 --- a/src/node/transaction.cpp +++ b/src/node/transaction.cpp @@ -13,6 +13,19 @@ #include <future> +static TransactionError HandleATMPError(const TxValidationState& state, std::string& err_string_out) +{ + err_string_out = state.ToString(); + if (state.IsInvalid()) { + if (state.GetResult() == TxValidationResult::TX_MISSING_INPUTS) { + return TransactionError::MISSING_INPUTS; + } + return TransactionError::MEMPOOL_REJECTED; + } else { + return TransactionError::MEMPOOL_ERROR; + } +} + TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback) { // BroadcastTransaction can be called by either sendrawtransaction RPC or wallet RPCs. @@ -36,20 +49,24 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_CHAIN; } if (!node.mempool->exists(hashTx)) { - // Transaction is not already in the mempool. Submit it. + // Transaction is not already in the mempool. TxValidationState state; - if (!AcceptToMemoryPool(*node.mempool, state, std::move(tx), - nullptr /* plTxnReplaced */, false /* bypass_limits */, max_tx_fee)) { - err_string = state.ToString(); - if (state.IsInvalid()) { - if (state.GetResult() == TxValidationResult::TX_MISSING_INPUTS) { - return TransactionError::MISSING_INPUTS; - } - return TransactionError::MEMPOOL_REJECTED; - } else { - return TransactionError::MEMPOOL_ERROR; + if (max_tx_fee > 0) { + // First, call ATMP with test_accept and check the fee. If ATMP + // fails here, return error immediately. + CAmount fee{0}; + if (!AcceptToMemoryPool(*node.mempool, state, tx, + nullptr /* plTxnReplaced */, false /* bypass_limits */, /* test_accept */ true, &fee)) { + return HandleATMPError(state, err_string); + } else if (fee > max_tx_fee) { + return TransactionError::MAX_FEE_EXCEEDED; } } + // Try to submit the transaction to the mempool. + if (!AcceptToMemoryPool(*node.mempool, state, tx, + nullptr /* plTxnReplaced */, false /* bypass_limits */)) { + return HandleATMPError(state, err_string); + } // Transaction was accepted to the mempool. @@ -80,7 +97,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t if (relay) { // the mempool tracks locally submitted transactions to make a // best-effort of initial broadcast - node.mempool->AddUnbroadcastTx(hashTx, tx->GetWitnessHash()); + node.mempool->AddUnbroadcastTx(hashTx); LOCK(cs_main); RelayTransaction(hashTx, tx->GetWitnessHash(), *node.connman); |