diff options
author | gzhao408 <gzhao408@berkeley.edu> | 2020-07-25 10:05:15 -0700 |
---|---|---|
committer | gzhao408 <gzhao408@berkeley.edu> | 2020-10-05 04:54:05 -0700 |
commit | 8f1290c60159a3171c27250bc95687548c5c1b84 (patch) | |
tree | eea0e386fb7add4d19609a8c2acb9ea442882a45 /src/node/transaction.cpp | |
parent | 3487e421a7fef4b28381efcf21a7e38483946cec (diff) |
[rpc/node] check for high fee before ATMP in clients
Check absurd fee in BroadcastTransaction and RPC,
return TransactionError::MAX_FEE_EXCEEDED instead
of TxValidationResult::TX_NOT_STANDARD because this
is client preference, not a node-wide policy.
Diffstat (limited to 'src/node/transaction.cpp')
-rw-r--r-- | src/node/transaction.cpp | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp index 9ae4700743..8162b79a0b 100644 --- a/src/node/transaction.cpp +++ b/src/node/transaction.cpp @@ -13,6 +13,18 @@ #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 +48,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, 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; + CAmount fee{0}; + if (max_tx_fee) { + // First, call ATMP with test_accept and check the fee. If ATMP + // fails here, return error immediately. + if (!AcceptToMemoryPool(*node.mempool, state, tx, + nullptr /* plTxnReplaced */, false /* bypass_limits */, /* absurdfee*/ 0, /* 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 */, max_tx_fee)) { + return HandleATMPError(state, err_string); + } // Transaction was accepted to the mempool. |