13
13
14
14
#include < future>
15
15
16
+ static TransactionError HandleATMPError (const TxValidationState& state, std::string& err_string_out) {
17
+ err_string_out = state.ToString ();
18
+ if (state.IsInvalid ()) {
19
+ if (state.GetResult () == TxValidationResult::TX_MISSING_INPUTS) {
20
+ return TransactionError::MISSING_INPUTS;
21
+ }
22
+ return TransactionError::MEMPOOL_REJECTED;
23
+ } else {
24
+ return TransactionError::MEMPOOL_ERROR;
25
+ }
26
+ }
27
+
16
28
TransactionError BroadcastTransaction (NodeContext& node, const CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback)
17
29
{
18
30
// BroadcastTransaction can be called by either sendrawtransaction RPC or wallet RPCs.
@@ -36,20 +48,24 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
36
48
if (!existingCoin.IsSpent ()) return TransactionError::ALREADY_IN_CHAIN;
37
49
}
38
50
if (!node.mempool ->exists (hashTx)) {
39
- // Transaction is not already in the mempool. Submit it.
51
+ // Transaction is not already in the mempool.
40
52
TxValidationState state;
41
- if (!AcceptToMemoryPool (*node.mempool , state, tx,
42
- nullptr /* plTxnReplaced */ , false /* bypass_limits */ , max_tx_fee)) {
43
- err_string = state.ToString ();
44
- if (state.IsInvalid ()) {
45
- if (state.GetResult () == TxValidationResult::TX_MISSING_INPUTS) {
46
- return TransactionError::MISSING_INPUTS;
47
- }
48
- return TransactionError::MEMPOOL_REJECTED;
49
- } else {
50
- return TransactionError::MEMPOOL_ERROR;
53
+ CAmount fee{0 };
54
+ if (max_tx_fee) {
55
+ // First, call ATMP with test_accept and check the fee. If ATMP
56
+ // fails here, return error immediately.
57
+ if (!AcceptToMemoryPool (*node.mempool , state, tx,
58
+ nullptr /* plTxnReplaced */ , false /* bypass_limits */ , /* absurdfee*/ 0 , /* test_accept */ true , &fee)) {
59
+ return HandleATMPError (state, err_string);
60
+ } else if (fee > max_tx_fee) {
61
+ return TransactionError::MAX_FEE_EXCEEDED;
51
62
}
52
63
}
64
+ // Try to submit the transaction to the mempool.
65
+ if (!AcceptToMemoryPool (*node.mempool , state, tx,
66
+ nullptr /* plTxnReplaced */ , false /* bypass_limits */ , max_tx_fee)) {
67
+ return HandleATMPError (state, err_string);
68
+ }
53
69
54
70
// Transaction was accepted to the mempool.
55
71
0 commit comments