MCPcopy Create free account
hub / github.com/ElementsProject/elements / BroadcastTransaction

Function BroadcastTransaction

src/node/transaction.cpp:33–123  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

31}
32
33TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback)
34{
35 // BroadcastTransaction can be called by either sendrawtransaction RPC or the wallet.
36 // chainman, mempool and peerman are initialized before the RPC server and wallet are started
37 // and reset after the RPC sever and wallet are stopped.
38 assert(node.chainman);
39 assert(node.mempool);
40 assert(node.peerman);
41
42 std::promise<void> promise;
43 uint256 txid = tx->GetHash();
44 uint256 wtxid = tx->GetWitnessHash();
45 bool callback_set = false;
46
47 {
48 LOCK(cs_main);
49
50 // If the transaction is already confirmed in the chain, don't do anything
51 // and return early.
52 CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip();
53 for (size_t o = 0; o < tx->vout.size(); o++) {
54 const Coin& existingCoin = view.AccessCoin(COutPoint(txid, o));
55 // IsSpent doesn't mean the coin is spent, it means the output doesn't exist.
56 // So if the output does exist, then this transaction exists in the chain.
57 if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_CHAIN;
58 }
59
60 if (auto mempool_tx = node.mempool->get(txid); mempool_tx) {
61 // There's already a transaction in the mempool with this txid. Don't
62 // try to submit this transaction to the mempool (since it'll be
63 // rejected as a TX_CONFLICT), but do attempt to reannounce the mempool
64 // transaction if relay=true.
65 //
66 // The mempool transaction may have the same or different witness (and
67 // wtxid) as this transaction. Use the mempool's wtxid for reannouncement.
68 wtxid = mempool_tx->GetWitnessHash();
69 } else {
70 // Transaction is not already in the mempool.
71 if (max_tx_fee > 0) {
72 // First, call ATMP with test_accept and check the fee. If ATMP
73 // fails here, return error immediately.
74 const MempoolAcceptResult result = node.chainman->ProcessTransaction(tx, /*test_accept=*/ true);
75 if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
76 return HandleATMPError(result.m_state, err_string);
77 } else if (result.m_base_fees.value() > max_tx_fee) {
78 return TransactionError::MAX_FEE_EXCEEDED;
79 }
80 }
81 // Try to submit the transaction to the mempool.
82 const MempoolAcceptResult result = node.chainman->ProcessTransaction(tx, /*test_accept=*/ false);
83 if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
84 return HandleATMPError(result.m_state, err_string);
85 }
86
87 // Transaction was accepted to the mempool.
88
89 if (relay) {
90 // the mempool tracks locally submitted transactions to make a

Callers 3

sendrawtransactionFunction · 0.85
broadcastTransactionMethod · 0.85
broadcastTransactionMethod · 0.85

Calls 12

HandleATMPErrorFunction · 0.85
ProcessTransactionMethod · 0.80
AddUnbroadcastTxMethod · 0.80
waitMethod · 0.80
RelayTransactionMethod · 0.80
COutPointClass · 0.70
GetHashMethod · 0.45
sizeMethod · 0.45
IsSpentMethod · 0.45
getMethod · 0.45
valueMethod · 0.45

Tested by

no test coverage detected