aboutsummaryrefslogtreecommitdiff
path: root/src/node/transaction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/node/transaction.cpp')
-rw-r--r--src/node/transaction.cpp41
1 files changed, 29 insertions, 12 deletions
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);