Bitcoin Core  0.20.99
P2P Digital Currency
transaction.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2019 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.connman 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.connman should never be null here.
34  assert(node.connman);
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  LOCK(cs_main);
42  // If the transaction is already confirmed in the chain, don't do anything
43  // and return early.
45  for (size_t o = 0; o < tx->vout.size(); o++) {
46  const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
47  // IsSpent doesn't mean the coin is spent, it means the output doesn't exist.
48  // So if the output does exist, then this transaction exists in the chain.
49  if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_CHAIN;
50  }
51  if (!node.mempool->exists(hashTx)) {
52  // Transaction is not already in the mempool.
53  TxValidationState state;
54  if (max_tx_fee > 0) {
55  // First, call ATMP with test_accept and check the fee. If ATMP
56  // fails here, return error immediately.
57  CAmount fee{0};
58  if (!AcceptToMemoryPool(*node.mempool, state, tx,
59  nullptr /* plTxnReplaced */, false /* bypass_limits */, /* test_accept */ true, &fee)) {
60  return HandleATMPError(state, err_string);
61  } else if (fee > max_tx_fee) {
63  }
64  }
65  // Try to submit the transaction to the mempool.
66  if (!AcceptToMemoryPool(*node.mempool, state, tx,
67  nullptr /* plTxnReplaced */, false /* bypass_limits */)) {
68  return HandleATMPError(state, err_string);
69  }
70 
71  // Transaction was accepted to the mempool.
72 
73  if (wait_callback) {
74  // For transactions broadcast from outside the wallet, make sure
75  // that the wallet has been notified of the transaction before
76  // continuing.
77  //
78  // This prevents a race where a user might call sendrawtransaction
79  // with a transaction to/from their wallet, immediately call some
80  // wallet RPC, and get a stale result because callbacks have not
81  // yet been processed.
83  promise.set_value();
84  });
85  callback_set = true;
86  }
87  }
88 
89  } // cs_main
90 
91  if (callback_set) {
92  // Wait until Validation Interface clients have been notified of the
93  // transaction entering the mempool.
94  promise.get_future().wait();
95  }
96 
97  if (relay) {
98  // the mempool tracks locally submitted transactions to make a
99  // best-effort of initial broadcast
100  node.mempool->AddUnbroadcastTx(hashTx);
101 
102  LOCK(cs_main);
103  RelayTransaction(hashTx, tx->GetWitnessHash(), *node.connman);
104  }
105 
106  return TransactionError::OK;
107 }
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:395
bool IsSpent() const
Definition: coins.h:76
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
Definition: coins.cpp:131
A UTXO entry.
Definition: coins.h:30
std::unique_ptr< CTxMemPool > mempool
Definition: context.h:38
transaction was missing some of its inputs
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
bool AcceptToMemoryPool(CTxMemPool &pool, TxValidationState &state, const CTransactionRef &tx, std::list< CTransactionRef > *plTxnReplaced, bool bypass_limits, bool test_accept, CAmount *fee_out)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
NodeContext struct containing references to chain state and connection state.
Definition: context.h:36
std::unique_ptr< CConnman > connman
Definition: context.h:37
#define LOCK(cs)
Definition: sync.h:230
std::string ToString() const
Definition: validation.h:125
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: validation.cpp:129
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
void RelayTransaction(const uint256 &txid, const uint256 &wtxid, const CConnman &connman)
Relay transaction to every node.
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
CChainState & ChainstateActive()
Please prefer the identical ChainstateManager::ActiveChainstate.
Definition: validation.cpp:106
TransactionError
Definition: error.h:22
bool IsInvalid() const
Definition: validation.h:120
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.h:590
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:236