Bitcoin Core  22.0.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 
6 #include <consensus/validation.h>
7 #include <net.h>
8 #include <net_processing.h>
9 #include <node/context.h>
10 #include <validation.h>
11 #include <validationinterface.h>
12 #include <node/transaction.h>
13 
14 #include <future>
15 
16 static TransactionError HandleATMPError(const TxValidationState& state, std::string& err_string_out)
17 {
18  err_string_out = state.ToString();
19  if (state.IsInvalid()) {
22  }
24  } else {
26  }
27 }
28 
29 TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback)
30 {
31  // BroadcastTransaction can be called by either sendrawtransaction RPC or the wallet.
32  // chainman, mempool and peerman are initialized before the RPC server and wallet are started
33  // and reset after the RPC sever and wallet are stopped.
34  assert(node.chainman);
35  assert(node.mempool);
36  assert(node.peerman);
37 
38  std::promise<void> promise;
39  uint256 txid = tx->GetHash();
40  uint256 wtxid = tx->GetWitnessHash();
41  bool callback_set = false;
42 
43  {
44  LOCK(cs_main);
45 
46  // If the transaction is already confirmed in the chain, don't do anything
47  // and return early.
48  CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip();
49  for (size_t o = 0; o < tx->vout.size(); o++) {
50  const Coin& existingCoin = view.AccessCoin(COutPoint(txid, o));
51  // IsSpent doesn't mean the coin is spent, it means the output doesn't exist.
52  // So if the output does exist, then this transaction exists in the chain.
53  if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_CHAIN;
54  }
55 
56  if (auto mempool_tx = node.mempool->get(txid); mempool_tx) {
57  // There's already a transaction in the mempool with this txid. Don't
58  // try to submit this transaction to the mempool (since it'll be
59  // rejected as a TX_CONFLICT), but do attempt to reannounce the mempool
60  // transaction if relay=true.
61  //
62  // The mempool transaction may have the same or different witness (and
63  // wtxid) as this transaction. Use the mempool's wtxid for reannouncement.
64  wtxid = mempool_tx->GetWitnessHash();
65  } else {
66  // Transaction is not already in the mempool.
67  if (max_tx_fee > 0) {
68  // First, call ATMP with test_accept and check the fee. If ATMP
69  // fails here, return error immediately.
70  const MempoolAcceptResult result = AcceptToMemoryPool(node.chainman->ActiveChainstate(), *node.mempool, tx, false /* bypass_limits */,
71  true /* test_accept */);
73  return HandleATMPError(result.m_state, err_string);
74  } else if (result.m_base_fees.value() > max_tx_fee) {
76  }
77  }
78  // Try to submit the transaction to the mempool.
79  const MempoolAcceptResult result = AcceptToMemoryPool(node.chainman->ActiveChainstate(), *node.mempool, tx, false /* bypass_limits */,
80  false /* test_accept */);
82  return HandleATMPError(result.m_state, err_string);
83  }
84 
85  // Transaction was accepted to the mempool.
86 
87  if (relay) {
88  // the mempool tracks locally submitted transactions to make a
89  // best-effort of initial broadcast
90  node.mempool->AddUnbroadcastTx(txid);
91  }
92 
93  if (wait_callback) {
94  // For transactions broadcast from outside the wallet, make sure
95  // that the wallet has been notified of the transaction before
96  // continuing.
97  //
98  // This prevents a race where a user might call sendrawtransaction
99  // with a transaction to/from their wallet, immediately call some
100  // wallet RPC, and get a stale result because callbacks have not
101  // yet been processed.
103  promise.set_value();
104  });
105  callback_set = true;
106  }
107  }
108  } // cs_main
109 
110  if (callback_set) {
111  // Wait until Validation Interface clients have been notified of the
112  // transaction entering the mempool.
113  promise.get_future().wait();
114  }
115 
116  if (relay) {
117  node.peerman->RelayTransaction(txid, wtxid);
118  }
119 
120  return TransactionError::OK;
121 }
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:386
bool IsSpent() const
Either this coin never existed (see e.g.
Definition: coins.h:79
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:137
A UTXO entry.
Definition: coins.h:30
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.
transaction was missing some of its inputs
const TxValidationState m_state
Definition: validation.h:176
const std::optional< CAmount > m_base_fees
Raw base fees in satoshis.
Definition: validation.h:182
const ResultType m_result_type
Definition: validation.h:175
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
NodeContext struct containing references to chain state and connection state.
Definition: context.h:39
#define LOCK(cs)
Definition: sync.h:232
std::string ToString() const
Definition: validation.h:125
static TransactionError HandleATMPError(const TxValidationState &state, std::string &err_string_out)
Definition: transaction.cpp:16
Result GetResult() const
Definition: validation.h:122
void CallFunctionInValidationInterfaceQueue(std::function< void()> func)
Pushes a function to callback onto the notification queue, guaranteeing any callbacks generated prior...
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:26
Validation result for a single transaction mempool acceptance.
Definition: validation.h:169
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: validation.cpp:115
256-bit opaque blob.
Definition: uint256.h:124
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:29
TransactionError
Definition: error.h:22
bool IsInvalid() const
Definition: validation.h:120
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:213