Tidy up BroadcastTransaction()
This commit is contained in:
parent
b8eecf8e79
commit
fb62f128bb
2 changed files with 30 additions and 16 deletions
|
@ -23,15 +23,17 @@ TransactionError BroadcastTransaction(const CTransactionRef tx, std::string& err
|
|||
|
||||
{ // cs_main scope
|
||||
LOCK(cs_main);
|
||||
// If the transaction is already confirmed in the chain, don't do anything
|
||||
// and return early.
|
||||
CCoinsViewCache &view = *pcoinsTip;
|
||||
bool fHaveChain = false;
|
||||
for (size_t o = 0; !fHaveChain && o < tx->vout.size(); o++) {
|
||||
for (size_t o = 0; o < tx->vout.size(); o++) {
|
||||
const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
|
||||
fHaveChain = !existingCoin.IsSpent();
|
||||
// IsSpent doesnt mean the coin is spent, it means the output doesnt' exist.
|
||||
// So if the output does exist, then this transaction exists in the chain.
|
||||
if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_CHAIN;
|
||||
}
|
||||
bool fHaveMempool = mempool.exists(hashTx);
|
||||
if (!fHaveMempool && !fHaveChain) {
|
||||
// push to local node and sync with wallets
|
||||
if (!mempool.exists(hashTx)) {
|
||||
// Transaction is not already in the mempool. Submit it.
|
||||
CValidationState state;
|
||||
bool fMissingInputs;
|
||||
if (!AcceptToMemoryPool(mempool, state, std::move(tx), &fMissingInputs,
|
||||
|
@ -46,24 +48,31 @@ TransactionError BroadcastTransaction(const CTransactionRef tx, std::string& err
|
|||
err_string = FormatStateMessage(state);
|
||||
return TransactionError::MEMPOOL_ERROR;
|
||||
}
|
||||
} else if (wait_callback) {
|
||||
// If wallet is enabled, ensure that the wallet has been made aware
|
||||
// of the new transaction prior to returning. This prevents a race
|
||||
// where a user might call sendrawtransaction with a transaction
|
||||
// to/from their wallet, immediately call some wallet RPC, and get
|
||||
// a stale result because callbacks have not yet been processed.
|
||||
}
|
||||
|
||||
// Transaction was accepted to the mempool.
|
||||
|
||||
if (wait_callback) {
|
||||
// For transactions broadcast from outside the wallet, make sure
|
||||
// that the wallet has been notified of the transaction before
|
||||
// continuing.
|
||||
//
|
||||
// This prevents a race where a user might call sendrawtransaction
|
||||
// with a transaction to/from their wallet, immediately call some
|
||||
// wallet RPC, and get a stale result because callbacks have not
|
||||
// yet been processed.
|
||||
CallFunctionInValidationInterfaceQueue([&promise] {
|
||||
promise.set_value();
|
||||
});
|
||||
callback_set = true;
|
||||
}
|
||||
} else if (fHaveChain) {
|
||||
return TransactionError::ALREADY_IN_CHAIN;
|
||||
}
|
||||
|
||||
} // cs_main
|
||||
|
||||
if (callback_set) {
|
||||
// Wait until Validation Interface clients have been notified of the
|
||||
// transaction entering the mempool.
|
||||
promise.get_future().wait();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,14 +11,19 @@
|
|||
#include <util/error.h>
|
||||
|
||||
/**
|
||||
* Broadcast a transaction
|
||||
* Submit a transaction to the mempool and (optionally) relay it to all P2P peers.
|
||||
*
|
||||
* Mempool submission can be synchronous (will await mempool entry notification
|
||||
* over the CValidationInterface) or asynchronous (will submit and not wait for
|
||||
* notification), depending on the value of wait_callback. wait_callback MUST
|
||||
* NOT be set while cs_main, cs_mempool or cs_wallet are held to avoid
|
||||
* deadlock.
|
||||
*
|
||||
* @param[in] tx the transaction to broadcast
|
||||
* @param[out] &err_string reference to std::string to fill with error string if available
|
||||
* @param[in] max_tx_fee reject txs with fees higher than this (if 0, accept any fee)
|
||||
* @param[in] relay flag if both mempool insertion and p2p relay are requested
|
||||
* @param[in] wait_callback, wait until callbacks have been processed to avoid stale result due to a sequentially RPC.
|
||||
* It MUST NOT be set while cs_main, cs_mempool or cs_wallet are held to avoid deadlock
|
||||
* return error
|
||||
*/
|
||||
NODISCARD TransactionError BroadcastTransaction(CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback);
|
||||
|
|
Loading…
Add table
Reference in a new issue