Bitcoin Core 22.99.0
P2P Digital Currency
transaction.cpp
Go to the documentation of this file.
1// Copyright (c) 2010 Satoshi Nakamoto
2// Copyright (c) 2009-2020 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
7#include <index/txindex.h>
8#include <net.h>
9#include <net_processing.h>
10#include <node/blockstorage.h>
11#include <node/context.h>
12#include <txmempool.h>
13#include <validation.h>
14#include <validationinterface.h>
15#include <node/transaction.h>
16
17#include <future>
18
19static TransactionError HandleATMPError(const TxValidationState& state, std::string& err_string_out)
20{
21 err_string_out = state.ToString();
22 if (state.IsInvalid()) {
25 }
27 } else {
29 }
30}
31
32TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback)
33{
34 // BroadcastTransaction can be called by either sendrawtransaction RPC or the wallet.
35 // chainman, mempool and peerman are initialized before the RPC server and wallet are started
36 // and reset after the RPC sever and wallet are stopped.
37 assert(node.chainman);
38 assert(node.mempool);
39 assert(node.peerman);
40
41 std::promise<void> promise;
42 uint256 txid = tx->GetHash();
43 uint256 wtxid = tx->GetWitnessHash();
44 bool callback_set = false;
45
46 {
48
49 // If the transaction is already confirmed in the chain, don't do anything
50 // and return early.
51 CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip();
52 for (size_t o = 0; o < tx->vout.size(); o++) {
53 const Coin& existingCoin = view.AccessCoin(COutPoint(txid, o));
54 // IsSpent doesn't mean the coin is spent, it means the output doesn't exist.
55 // So if the output does exist, then this transaction exists in the chain.
56 if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_CHAIN;
57 }
58
59 if (auto mempool_tx = node.mempool->get(txid); mempool_tx) {
60 // There's already a transaction in the mempool with this txid. Don't
61 // try to submit this transaction to the mempool (since it'll be
62 // rejected as a TX_CONFLICT), but do attempt to reannounce the mempool
63 // transaction if relay=true.
64 //
65 // The mempool transaction may have the same or different witness (and
66 // wtxid) as this transaction. Use the mempool's wtxid for reannouncement.
67 wtxid = mempool_tx->GetWitnessHash();
68 } else {
69 // Transaction is not already in the mempool.
70 if (max_tx_fee > 0) {
71 // First, call ATMP with test_accept and check the fee. If ATMP
72 // fails here, return error immediately.
73 const MempoolAcceptResult result = AcceptToMemoryPool(node.chainman->ActiveChainstate(), *node.mempool, tx, false /* bypass_limits */,
74 true /* test_accept */);
76 return HandleATMPError(result.m_state, err_string);
77 } else if (result.m_base_fees.value() > max_tx_fee) {
79 }
80 }
81 // Try to submit the transaction to the mempool.
82 const MempoolAcceptResult result = AcceptToMemoryPool(node.chainman->ActiveChainstate(), *node.mempool, tx, false /* bypass_limits */,
83 false /* test_accept */);
85 return HandleATMPError(result.m_state, err_string);
86 }
87
88 // Transaction was accepted to the mempool.
89
90 if (relay) {
91 // the mempool tracks locally submitted transactions to make a
92 // best-effort of initial broadcast
93 node.mempool->AddUnbroadcastTx(txid);
94 }
95
96 if (wait_callback) {
97 // For transactions broadcast from outside the wallet, make sure
98 // that the wallet has been notified of the transaction before
99 // continuing.
100 //
101 // This prevents a race where a user might call sendrawtransaction
102 // with a transaction to/from their wallet, immediately call some
103 // wallet RPC, and get a stale result because callbacks have not
104 // yet been processed.
106 promise.set_value();
107 });
108 callback_set = true;
109 }
110 }
111 } // cs_main
112
113 if (callback_set) {
114 // Wait until Validation Interface clients have been notified of the
115 // transaction entering the mempool.
116 promise.get_future().wait();
117 }
118
119 if (relay) {
120 node.peerman->RelayTransaction(txid, wtxid);
121 }
122
124}
125
126CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock)
127{
128 if (mempool && !block_index) {
129 CTransactionRef ptx = mempool->get(hash);
130 if (ptx) return ptx;
131 }
132 if (g_txindex) {
134 uint256 block_hash;
135 if (g_txindex->FindTx(hash, block_hash, tx)) {
136 if (!block_index || block_index->GetBlockHash() == block_hash) {
137 // Don't return the transaction if the provided block hash doesn't match.
138 // The case where a transaction appears in multiple blocks (e.g. reorgs or
139 // BIP30) is handled by the block lookup below.
140 hashBlock = block_hash;
141 return tx;
142 }
143 }
144 }
145 if (block_index) {
146 CBlock block;
147 if (ReadBlockFromDisk(block, block_index, consensusParams)) {
148 for (const auto& tx : block.vtx) {
149 if (tx->GetHash() == hash) {
150 hashBlock = block_index->GetBlockHash();
151 return tx;
152 }
153 }
154 }
155 }
156 return nullptr;
157}
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: validation.cpp:118
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
Definition: block.h:63
std::vector< CTransactionRef > vtx
Definition: block.h:66
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:146
uint256 GetBlockHash() const
Definition: chain.h:254
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:214
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:137
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:27
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:424
CTransactionRef get(const uint256 &hash) const
Definition: txmempool.cpp:911
A UTXO entry.
Definition: coins.h:31
bool IsSpent() const
Either this coin never existed (see e.g.
Definition: coins.h:79
Result GetResult() const
Definition: validation.h:122
std::string ToString() const
Definition: validation.h:125
bool IsInvalid() const
Definition: validation.h:120
256-bit opaque blob.
Definition: uint256.h:124
@ TX_MISSING_INPUTS
transaction was missing some of its inputs
TransactionError
Definition: error.h:22
static TransactionError HandleATMPError(const TxValidationState &state, std::string &err_string_out)
Definition: transaction.cpp:19
TransactionError BroadcastTransaction(NodeContext &node, const CTransactionRef tx, std::string &err_string, const CAmount &max_tx_fee, bool relay, bool wait_callback)
Submit a transaction to the mempool and (optionally) relay it to all P2P peers.
Definition: transaction.cpp:32
CTransactionRef GetTransaction(const CBlockIndex *const block_index, const CTxMemPool *const mempool, const uint256 &hash, const Consensus::Params &consensusParams, uint256 &hashBlock)
Return transaction with a given hash.
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:386
Parameters that influence chain consensus.
Definition: params.h:70
Validation result for a single transaction mempool acceptance.
Definition: validation.h:149
const ResultType m_result_type
Definition: validation.h:155
const std::optional< CAmount > m_base_fees
Raw base fees in satoshis.
Definition: validation.h:162
const TxValidationState m_state
Definition: validation.h:156
NodeContext struct containing references to chain state and connection state.
Definition: context.h:39
#define LOCK(cs)
Definition: sync.h:226
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
Definition: txindex.cpp:14
MempoolAcceptResult AcceptToMemoryPool(CChainState &active_chainstate, CTxMemPool &pool, const CTransactionRef &tx, bool bypass_limits, bool test_accept)
(Try to) add a transaction to the memory pool.
assert(!tx.IsCoinBase())
void CallFunctionInValidationInterfaceQueue(std::function< void()> func)
Pushes a function to callback onto the notification queue, guaranteeing any callbacks generated prior...