Line data Source code
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 9485 : TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback) 17 : { 18 : // BroadcastTransaction can be called by either sendrawtransaction RPC or wallet RPCs. 19 : // node.connman is assigned both before chain clients and before RPC server is accepting calls, 20 : // and reset after chain clients and RPC sever are stopped. node.connman should never be null here. 21 9485 : assert(node.connman); 22 9485 : assert(node.mempool); 23 9485 : std::promise<void> promise; 24 9485 : uint256 hashTx = tx->GetHash(); 25 : bool callback_set = false; 26 : 27 : { // cs_main scope 28 9485 : LOCK(cs_main); 29 : // If the transaction is already confirmed in the chain, don't do anything 30 : // and return early. 31 9485 : CCoinsViewCache &view = ::ChainstateActive().CoinsTip(); 32 72169 : for (size_t o = 0; o < tx->vout.size(); o++) { 33 62684 : const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o)); 34 : // IsSpent doesn't mean the coin is spent, it means the output doesn't exist. 35 : // So if the output does exist, then this transaction exists in the chain. 36 62684 : if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_CHAIN; 37 62684 : } 38 9485 : if (!node.mempool->exists(hashTx)) { 39 : // Transaction is not already in the mempool. Submit it. 40 9422 : TxValidationState state; 41 18844 : if (!AcceptToMemoryPool(*node.mempool, state, std::move(tx), 42 9422 : nullptr /* plTxnReplaced */, false /* bypass_limits */, max_tx_fee)) { 43 508 : err_string = state.ToString(); 44 508 : if (state.IsInvalid()) { 45 508 : if (state.GetResult() == TxValidationResult::TX_MISSING_INPUTS) { 46 14 : return TransactionError::MISSING_INPUTS; 47 : } 48 494 : return TransactionError::MEMPOOL_REJECTED; 49 : } else { 50 0 : return TransactionError::MEMPOOL_ERROR; 51 : } 52 : } 53 : 54 : // Transaction was accepted to the mempool. 55 : 56 8914 : if (wait_callback) { 57 : // For transactions broadcast from outside the wallet, make sure 58 : // that the wallet has been notified of the transaction before 59 : // continuing. 60 : // 61 : // This prevents a race where a user might call sendrawtransaction 62 : // with a transaction to/from their wallet, immediately call some 63 : // wallet RPC, and get a stale result because callbacks have not 64 : // yet been processed. 65 15458 : CallFunctionInValidationInterfaceQueue([&promise] { 66 7729 : promise.set_value(); 67 7729 : }); 68 : callback_set = true; 69 7729 : } 70 9422 : } 71 : 72 9485 : } // cs_main 73 : 74 8977 : if (callback_set) { 75 : // Wait until Validation Interface clients have been notified of the 76 : // transaction entering the mempool. 77 7729 : promise.get_future().wait(); 78 7729 : } 79 : 80 8977 : if (relay) { 81 : // the mempool tracks locally submitted transactions to make a 82 : // best-effort of initial broadcast 83 8904 : node.mempool->AddUnbroadcastTx(hashTx, tx->GetWitnessHash()); 84 : 85 8904 : LOCK(cs_main); 86 8904 : RelayTransaction(hashTx, tx->GetWitnessHash(), *node.connman); 87 8904 : } 88 : 89 8977 : return TransactionError::OK; 90 9485 : }