LCOV - code coverage report
Current view: top level - src/node - transaction.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 37 38 97.4 %
Date: 2020-09-26 01:30:44 Functions: 2 2 100.0 %

          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 : }

Generated by: LCOV version 1.15