Branch data Line data Source code
1 : : // Copyright (c) 2010 Satoshi Nakamoto
2 : : // Copyright (c) 2009-present The Bitcoin Core developers
3 : : // Distributed under the MIT software license, see the accompanying
4 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 : :
6 : : #include <node/transaction.h>
7 : :
8 : : #include <consensus/validation.h>
9 : : #include <index/txindex.h>
10 : : #include <net.h>
11 : : #include <net_processing.h>
12 : : #include <node/blockstorage.h>
13 : : #include <node/context.h>
14 : : #include <node/types.h>
15 : : #include <policy/feerate.h>
16 : : #include <tinyformat.h>
17 : : #include <txmempool.h>
18 : : #include <validation.h>
19 : : #include <validationinterface.h>
20 : :
21 : : #include <stdexcept>
22 : :
23 : : namespace node {
24 : 4478 : static TransactionError HandleATMPError(const TxValidationState& state, std::string& err_string_out)
25 : : {
26 : 4478 : err_string_out = state.ToString();
27 [ + - ]: 4478 : if (state.IsInvalid()) {
28 [ + + ]: 4478 : if (state.GetResult() == TxValidationResult::TX_MISSING_INPUTS) {
29 : : return TransactionError::MISSING_INPUTS;
30 : : }
31 : 4469 : return TransactionError::MEMPOOL_REJECTED;
32 : : } else {
33 : : return TransactionError::MEMPOOL_ERROR;
34 : : }
35 : : }
36 : :
37 : 38173 : TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, const CFeeRate& max_tx_fee_rate, TxBroadcast broadcast_method, bool wait_callback)
38 : : {
39 : : // BroadcastTransaction can be called by RPC or by the wallet.
40 : : // chainman, mempool and peerman are initialized before the RPC server and wallet are started
41 : : // and reset after the RPC sever and wallet are stopped.
42 [ - + ]: 38173 : assert(node.chainman);
43 [ - + ]: 38173 : assert(node.mempool);
44 [ - + ]: 38173 : assert(node.peerman);
45 : :
46 : 38173 : Txid txid = tx->GetHash();
47 : 38173 : Wtxid wtxid = tx->GetWitnessHash();
48 : 38173 : bool callback_set = false;
49 : :
50 : 38173 : {
51 : 38173 : LOCK(cs_main);
52 : :
53 : : // If the transaction is already confirmed in the chain, don't do anything
54 : : // and return early.
55 [ + - + - ]: 38173 : CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip();
56 [ - + + + ]: 119784 : for (size_t o = 0; o < tx->vout.size(); o++) {
57 [ + - ]: 81614 : const Coin& existingCoin = view.AccessCoin(COutPoint(txid, o));
58 : : // IsSpent doesn't mean the coin is spent, it means the output doesn't exist.
59 : : // So if the output does exist, then this transaction exists in the chain.
60 [ + + ]: 81614 : if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_UTXO_SET;
61 : : }
62 : :
63 [ + - + + ]: 38170 : if (auto mempool_tx = node.mempool->get(txid); mempool_tx) {
64 : : // There's already a transaction in the mempool with this txid. Don't
65 : : // try to submit this transaction to the mempool (since it'll be
66 : : // rejected as a TX_CONFLICT), but do attempt to reannounce the mempool
67 : : // transaction if broadcast_method is not TxBroadcast::MEMPOOL_NO_BROADCAST.
68 : : //
69 : : // The mempool transaction may have the same or different witness (and
70 : : // wtxid) as this transaction. Use the mempool's wtxid for reannouncement.
71 : 6026 : wtxid = mempool_tx->GetWitnessHash();
72 : : } else {
73 : : // Transaction is not already in the mempool.
74 : 32144 : const bool check_max_fee{max_tx_fee > 0};
75 [ + + ]: 32144 : const bool check_max_feerate{max_tx_fee_rate > CFeeRate(0)};
76 [ + + + + ]: 32144 : if (check_max_fee || check_max_feerate || broadcast_method == TxBroadcast::NO_MEMPOOL_PRIVATE_BROADCAST) {
77 : : // First, call ATMP with test_accept and check the fee. If ATMP
78 : : // fails here, return error immediately.
79 [ + - ]: 16973 : const MempoolAcceptResult result = node.chainman->ProcessTransaction(tx, /*test_accept=*/ true);
80 [ + + ]: 16973 : if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
81 [ + - ]: 143 : return HandleATMPError(result.m_state, err_string);
82 [ + + + - ]: 18545 : } else if (check_max_fee && result.m_base_fees.value() > max_tx_fee) {
83 : : return TransactionError::MAX_FEE_EXCEEDED;
84 [ + + + - : 33659 : } else if (check_max_feerate && result.m_base_fees.value() > max_tx_fee_rate.GetFee(result.m_vsize.value())) {
+ - + + ]
85 : : return TransactionError::MAX_FEE_RATE_EXCEEDED;
86 : : }
87 : 16973 : }
88 : :
89 [ + + ]: 31996 : switch (broadcast_method) {
90 : 21979 : case TxBroadcast::MEMPOOL_NO_BROADCAST:
91 : 21979 : case TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL:
92 : : // Try to submit the transaction to the mempool.
93 : 21979 : {
94 : 21979 : const MempoolAcceptResult result =
95 [ + - ]: 21979 : node.chainman->ProcessTransaction(tx, /*test_accept=*/false);
96 [ + + ]: 21979 : if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
97 [ + - ]: 4335 : return HandleATMPError(result.m_state, err_string);
98 : : }
99 : 21979 : }
100 : : // Transaction was accepted to the mempool.
101 : :
102 [ + + ]: 17644 : if (broadcast_method == TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL) {
103 : : // the mempool tracks locally submitted transactions to make a
104 : : // best-effort of initial broadcast
105 [ + - ]: 17606 : node.mempool->AddUnbroadcastTx(txid);
106 : : }
107 : : break;
108 : : case TxBroadcast::NO_MEMPOOL_PRIVATE_BROADCAST:
109 : : break;
110 : : }
111 : :
112 [ + + - + ]: 27661 : if (wait_callback && node.validation_signals) {
113 : : // For transactions broadcast from outside the wallet, make sure
114 : : // that the wallet has been notified of the transaction before
115 : : // continuing.
116 : : //
117 : : // This prevents a race where a user might call sendrawtransaction
118 : : // with a transaction to/from their wallet, immediately call some
119 : : // wallet RPC, and get a stale result because callbacks have not
120 : : // yet been processed.
121 : : callback_set = true;
122 : : }
123 [ + - ]: 38170 : }
124 : 4486 : } // cs_main
125 : :
126 [ + + ]: 33687 : if (callback_set) {
127 : : // Wait until Validation Interface clients have been notified of the
128 : : // transaction entering the mempool.
129 : 25949 : node.validation_signals->SyncWithValidationInterfaceQueue();
130 : : }
131 : :
132 [ + + + ]: 33687 : switch (broadcast_method) {
133 : : case TxBroadcast::MEMPOOL_NO_BROADCAST:
134 : : break;
135 : 23538 : case TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL:
136 : 23538 : node.peerman->InitiateTxBroadcastToAll(wtxid);
137 : 23538 : break;
138 : 10018 : case TxBroadcast::NO_MEMPOOL_PRIVATE_BROADCAST:
139 : 10018 : return node.peerman->InitiateTxBroadcastPrivate(tx);
140 : : }
141 : :
142 : : return TransactionError::OK;
143 : : }
144 : :
145 : 3702 : CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const Txid& hash, const BlockManager& blockman, uint256& hashBlock)
146 : : {
147 [ + + ]: 3702 : if (mempool && !block_index) {
148 : 3662 : CTransactionRef ptx = mempool->get(hash);
149 [ + + ]: 3662 : if (ptx) return ptx;
150 : 101 : }
151 [ + + ]: 101 : if (g_txindex) {
152 [ + + ]: 48 : if (auto result{g_txindex->FindTx(hash)}) {
153 [ + + + + ]: 44 : if (!block_index || block_index->GetBlockHash() == result->block_hash) {
154 : : // Don't return the transaction if the provided block hash doesn't match.
155 : : // The case where a transaction appears in multiple blocks (e.g. reorgs or
156 : : // BIP30) is handled by the block lookup below.
157 [ + - ]: 39 : hashBlock = result->block_hash;
158 [ + - ]: 78 : return result->tx;
159 : : }
160 : 44 : }
161 : : }
162 [ + + ]: 58 : if (block_index) {
163 : 32 : CBlock block;
164 [ + - + + ]: 32 : if (!blockman.ReadBlock(block, *block_index)) {
165 [ + - + - : 4 : throw std::runtime_error{strprintf("I/O error reading block data for block %s", block_index->GetBlockHash().ToString())};
+ - ]
166 : : }
167 [ + + ]: 60 : for (const auto& tx : block.vtx) {
168 [ + + ]: 58 : if (tx->GetHash() == hash) {
169 : 28 : hashBlock = block_index->GetBlockHash();
170 [ + - ]: 56 : return tx;
171 : : }
172 : : }
173 : 30 : }
174 : 28 : return nullptr;
175 : : }
176 : : } // namespace node
|