Bitcoin Core  31.0.0
P2P Digital Currency
transaction.cpp
Go to the documentation of this file.
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 <consensus/validation.h>
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 <node/types.h>
13 #include <txmempool.h>
14 #include <validation.h>
15 #include <validationinterface.h>
16 #include <node/transaction.h>
17 
18 namespace node {
19 static 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 
33  const CTransactionRef tx,
34  std::string& err_string,
35  const CAmount& max_tx_fee,
36  TxBroadcast broadcast_method,
37  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  assert(node.chainman);
43  assert(node.mempool);
44  assert(node.peerman);
45 
46  Txid txid = tx->GetHash();
47  Wtxid wtxid = tx->GetWitnessHash();
48  bool callback_set = false;
49 
50  {
51  LOCK(cs_main);
52 
53  // If the transaction is already confirmed in the chain, don't do anything
54  // and return early.
55  CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip();
56  for (size_t o = 0; o < tx->vout.size(); o++) {
57  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  if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_UTXO_SET;
61  }
62 
63  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  wtxid = mempool_tx->GetWitnessHash();
72  } else {
73  // Transaction is not already in the mempool.
74  const bool check_max_fee{max_tx_fee > 0};
75  if (check_max_fee || broadcast_method == TxBroadcast::NO_MEMPOOL_PRIVATE_BROADCAST) {
76  // First, call ATMP with test_accept and check the fee. If ATMP
77  // fails here, return error immediately.
78  const MempoolAcceptResult result = node.chainman->ProcessTransaction(tx, /*test_accept=*/ true);
79  if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
80  return HandleATMPError(result.m_state, err_string);
81  } else if (check_max_fee && result.m_base_fees.value() > max_tx_fee) {
83  }
84  }
85 
86  switch (broadcast_method) {
89  // Try to submit the transaction to the mempool.
90  {
92  node.chainman->ProcessTransaction(tx, /*test_accept=*/false);
93  if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
94  return HandleATMPError(result.m_state, err_string);
95  }
96  }
97  // Transaction was accepted to the mempool.
98 
99  if (broadcast_method == TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL) {
100  // the mempool tracks locally submitted transactions to make a
101  // best-effort of initial broadcast
102  node.mempool->AddUnbroadcastTx(txid);
103  }
104  break;
106  break;
107  }
108 
109  if (wait_callback && node.validation_signals) {
110  // For transactions broadcast from outside the wallet, make sure
111  // that the wallet has been notified of the transaction before
112  // continuing.
113  //
114  // This prevents a race where a user might call sendrawtransaction
115  // with a transaction to/from their wallet, immediately call some
116  // wallet RPC, and get a stale result because callbacks have not
117  // yet been processed.
118  callback_set = true;
119  }
120  }
121  } // cs_main
122 
123  if (callback_set) {
124  // Wait until Validation Interface clients have been notified of the
125  // transaction entering the mempool.
126  node.validation_signals->SyncWithValidationInterfaceQueue();
127  }
128 
129  switch (broadcast_method) {
131  break;
133  node.peerman->InitiateTxBroadcastToAll(txid, wtxid);
134  break;
136  node.peerman->InitiateTxBroadcastPrivate(tx);
137  break;
138  }
139 
140  return TransactionError::OK;
141 }
142 
143 CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const Txid& hash, const BlockManager& blockman, uint256& hashBlock)
144 {
145  if (mempool && !block_index) {
146  CTransactionRef ptx = mempool->get(hash);
147  if (ptx) return ptx;
148  }
149  if (g_txindex) {
150  CTransactionRef tx;
151  uint256 block_hash;
152  if (g_txindex->FindTx(hash, block_hash, tx)) {
153  if (!block_index || block_index->GetBlockHash() == 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  hashBlock = block_hash;
158  return tx;
159  }
160  }
161  }
162  if (block_index) {
163  CBlock block;
164  if (blockman.ReadBlock(block, *block_index)) {
165  for (const auto& tx : block.vtx) {
166  if (tx->GetHash() == hash) {
167  hashBlock = block_index->GetBlockHash();
168  return tx;
169  }
170  }
171  }
172  }
173  return nullptr;
174 }
175 } // namespace node
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:403
TransactionError
Definition: types.h:28
bool IsSpent() const
Either this coin never existed (see e.g.
Definition: coins.h:83
TxBroadcast
How to broadcast a local transaction.
Definition: types.h:165
assert(!tx.IsCoinBase())
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:179
A UTXO entry.
Definition: coins.h:34
Definition: block.h:73
Omit the mempool and directly send the transaction via a few dedicated connections to peers on privac...
transaction was missing some of its inputs
CTransactionRef get(const Txid &hash) const
Definition: txmempool.cpp:621
Add the transaction to the mempool and broadcast to all peers for which tx relay is enabled...
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
uint256 GetBlockHash() const
Definition: chain.h:198
NodeContext struct containing references to chain state and connection state.
Definition: context.h:56
#define LOCK(cs)
Definition: sync.h:258
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
Definition: txindex.cpp:34
std::string ToString() const
Definition: validation.h:111
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
Definition: blockstorage.h:191
Result GetResult() const
Definition: validation.h:108
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:28
Validation result for a transaction evaluated by MemPoolAccept (single or package).
Definition: validation.h:131
CTransactionRef GetTransaction(const CBlockIndex *const block_index, const CTxMemPool *const mempool, const Txid &hash, const BlockManager &blockman, uint256 &hashBlock)
Return transaction with a given hash.
Definition: messages.h:21
256-bit opaque blob.
Definition: uint256.h:195
std::vector< CTransactionRef > vtx
Definition: block.h:77
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:186
auto result
Definition: common-types.h:74
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:93
Add the transaction to the mempool, but don&#39;t broadcast to anybody.
bool IsInvalid() const
Definition: validation.h:106
bool ReadBlock(CBlock &block, const FlatFilePos &pos, const std::optional< uint256 > &expected_hash) const
Functions for disk access for blocks.
TransactionError BroadcastTransaction(NodeContext &node, const CTransactionRef tx, std::string &err_string, const CAmount &max_tx_fee, TxBroadcast broadcast_method, bool wait_callback)
Submit a transaction to the mempool and (optionally) relay it to all P2P peers.
Definition: transaction.cpp:32
static TransactionError HandleATMPError(const TxValidationState &state, std::string &err_string_out)
Definition: transaction.cpp:19
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:367
is a home for public enum and struct type definitions that are used internally by node code...
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: cs_main.cpp:8
transaction_identifier represents the two canonical transaction identifier types (txid, wtxid).