Bitcoin Core  21.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 
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 wallet RPCs.
32  // node.peerman is assigned both before chain clients and before RPC server is accepting calls,
33  // and reset after chain clients and RPC sever are stopped. node.peerman should never be null here.
34  assert(node.peerman);
35  assert(node.mempool);
36  std::promise<void> promise;
37  uint256 hashTx = tx->GetHash();
38  bool callback_set = false;
39 
40  { // cs_main scope
41  assert(node.chainman);
42  LOCK(cs_main);
43  assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate()));
44  // If the transaction is already confirmed in the chain, don't do anything
45  // and return early.
46  CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip();
47  for (size_t o = 0; o < tx->vout.size(); o++) {
48  const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
49  // IsSpent doesn't mean the coin is spent, it means the output doesn't exist.
50  // So if the output does exist, then this transaction exists in the chain.
51  if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_CHAIN;
52  }
53  if (!node.mempool->exists(hashTx)) {
54  // Transaction is not already in the mempool.
55  if (max_tx_fee > 0) {
56  // First, call ATMP with test_accept and check the fee. If ATMP
57  // fails here, return error immediately.
58  const MempoolAcceptResult result = AcceptToMemoryPool(node.chainman->ActiveChainstate(), *node.mempool, tx, false /* bypass_limits */,
59  true /* test_accept */);
61  return HandleATMPError(result.m_state, err_string);
62  } else if (result.m_base_fees.value() > max_tx_fee) {
64  }
65  }
66  // Try to submit the transaction to the mempool.
67  const MempoolAcceptResult result = AcceptToMemoryPool(node.chainman->ActiveChainstate(), *node.mempool, tx, false /* bypass_limits */,
68  false /* test_accept */);
70  return HandleATMPError(result.m_state, err_string);
71  }
72 
73  // Transaction was accepted to the mempool.
74 
75  if (wait_callback) {
76  // For transactions broadcast from outside the wallet, make sure
77  // that the wallet has been notified of the transaction before
78  // continuing.
79  //
80  // This prevents a race where a user might call sendrawtransaction
81  // with a transaction to/from their wallet, immediately call some
82  // wallet RPC, and get a stale result because callbacks have not
83  // yet been processed.
85  promise.set_value();
86  });
87  callback_set = true;
88  }
89  }
90 
91  } // cs_main
92 
93  if (callback_set) {
94  // Wait until Validation Interface clients have been notified of the
95  // transaction entering the mempool.
96  promise.get_future().wait();
97  }
98 
99  if (relay) {
100  // the mempool tracks locally submitted transactions to make a
101  // best-effort of initial broadcast
102  node.mempool->AddUnbroadcastTx(hashTx);
103 
104  LOCK(cs_main);
105  node.peerman->RelayTransaction(hashTx, tx->GetWitnessHash());
106  }
107 
108  return TransactionError::OK;
109 }
TransactionError::MEMPOOL_REJECTED
@ MEMPOOL_REJECTED
MempoolAcceptResult::m_base_fees
std::optional< CAmount > m_base_fees
Raw base fees.
Definition: validation.h:205
AcceptToMemoryPool
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.
Definition: validation.cpp:1118
validationinterface.h
validation.h
TransactionError::MEMPOOL_ERROR
@ MEMPOOL_ERROR
CCoinsViewCache::AccessCoin
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:137
CTransactionRef
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:386
cs_main
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: validation.cpp:131
context.h
ChainstateActive
CChainState & ChainstateActive()
Please prefer the identical ChainstateManager::ActiveChainstate.
Definition: validation.cpp:108
ValidationState::ToString
std::string ToString() const
Definition: validation.h:125
transaction.h
TxValidationState
Definition: validation.h:139
TransactionError
TransactionError
Definition: error.h:22
Coin
A UTXO entry.
Definition: coins.h:32
HandleATMPError
static TransactionError HandleATMPError(const TxValidationState &state, std::string &err_string_out)
Definition: transaction.cpp:16
MempoolAcceptResult::m_state
TxValidationState m_state
Definition: validation.h:199
CAmount
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
uint256
256-bit opaque blob.
Definition: uint256.h:124
net_processing.h
ValidationState::GetResult
Result GetResult() const
Definition: validation.h:122
MempoolAcceptResult::ResultType::VALID
@ VALID
BroadcastTransaction
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
CCoinsViewCache
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:215
TxValidationResult::TX_MISSING_INPUTS
@ TX_MISSING_INPUTS
transaction was missing some of its inputs
LOCK
#define LOCK(cs)
Definition: sync.h:232
TransactionError::OK
@ OK
No error.
MempoolAcceptResult
Validation result for a single transaction mempool acceptance.
Definition: validation.h:190
node
Definition: interfaces.cpp:66
COutPoint
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:26
MempoolAcceptResult::m_result_type
ResultType m_result_type
Definition: validation.h:198
Coin::IsSpent
bool IsSpent() const
Either this coin never existed (see e.g.
Definition: coins.h:81
NodeContext
NodeContext struct containing references to chain state and connection state.
Definition: context.h:38
net.h
CallFunctionInValidationInterfaceQueue
void CallFunctionInValidationInterfaceQueue(std::function< void()> func)
Pushes a function to callback onto the notification queue, guaranteeing any callbacks generated prior...
Definition: validationinterface.cpp:155
TransactionError::MISSING_INPUTS
@ MISSING_INPUTS
assert
assert(std::addressof(::ChainstateActive().CoinsTip())==std::addressof(coins_cache))
TransactionError::MAX_FEE_EXCEEDED
@ MAX_FEE_EXCEEDED
ValidationState::IsInvalid
bool IsInvalid() const
Definition: validation.h:120
TransactionError::ALREADY_IN_CHAIN
@ ALREADY_IN_CHAIN