mirror of https://github.com/bitcoin/bitcoin.git
Merge 1197919eab
into b510893d00
This commit is contained in:
commit
2f630da7b3
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <blockfilter.h>
|
#include <blockfilter.h>
|
||||||
#include <common/settings.h>
|
#include <common/settings.h>
|
||||||
|
#include <node/types.h>
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <util/result.h>
|
#include <util/result.h>
|
||||||
|
|
||||||
|
@ -206,12 +207,18 @@ public:
|
||||||
//! Check if transaction has descendants in mempool.
|
//! Check if transaction has descendants in mempool.
|
||||||
virtual bool hasDescendantsInMempool(const Txid& txid) = 0;
|
virtual bool hasDescendantsInMempool(const Txid& txid) = 0;
|
||||||
|
|
||||||
//! Transaction is added to memory pool, if the transaction fee is below the
|
//! Consume a local transaction, optionally adding it to the mempool and
|
||||||
//! amount specified by max_tx_fee, and broadcast to all peers if relay is set to true.
|
//! optionally broadcasting it to the network.
|
||||||
//! Return false if the transaction could not be added due to the fee or for another reason.
|
//! @param[in] tx Transaction to process.
|
||||||
|
//! @param[in] max_tx_fee Don't add the transaction to the mempool or
|
||||||
|
//! broadcast it if its fee is higher than this.
|
||||||
|
//! @param[in] broadcast_method Whether to add the transaction to the
|
||||||
|
//! mempool and how/whether to broadcast it.
|
||||||
|
//! @param[out] err_string Set if an error occurs.
|
||||||
|
//! @return False if the transaction could not be added due to the fee or for another reason.
|
||||||
virtual bool broadcastTransaction(const CTransactionRef& tx,
|
virtual bool broadcastTransaction(const CTransactionRef& tx,
|
||||||
const CAmount& max_tx_fee,
|
const CAmount& max_tx_fee,
|
||||||
bool relay,
|
node::TxBroadcastMethod broadcast_method,
|
||||||
std::string& err_string) = 0;
|
std::string& err_string) = 0;
|
||||||
|
|
||||||
//! Calculate mempool ancestor and descendant counts for the given transaction.
|
//! Calculate mempool ancestor and descendant counts for the given transaction.
|
||||||
|
|
|
@ -363,7 +363,12 @@ public:
|
||||||
}
|
}
|
||||||
TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, std::string& err_string) override
|
TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, std::string& err_string) override
|
||||||
{
|
{
|
||||||
return BroadcastTransaction(*m_context, std::move(tx), err_string, max_tx_fee, /*relay=*/ true, /*wait_callback=*/ false);
|
return BroadcastTransaction(*m_context,
|
||||||
|
std::move(tx),
|
||||||
|
err_string,
|
||||||
|
max_tx_fee,
|
||||||
|
ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL,
|
||||||
|
/*wait_callback=*/false);
|
||||||
}
|
}
|
||||||
WalletLoader& walletLoader() override
|
WalletLoader& walletLoader() override
|
||||||
{
|
{
|
||||||
|
@ -672,10 +677,10 @@ public:
|
||||||
}
|
}
|
||||||
bool broadcastTransaction(const CTransactionRef& tx,
|
bool broadcastTransaction(const CTransactionRef& tx,
|
||||||
const CAmount& max_tx_fee,
|
const CAmount& max_tx_fee,
|
||||||
bool relay,
|
TxBroadcastMethod broadcast_method,
|
||||||
std::string& err_string) override
|
std::string& err_string) override
|
||||||
{
|
{
|
||||||
const TransactionError err = BroadcastTransaction(m_node, tx, err_string, max_tx_fee, relay, /*wait_callback=*/false);
|
const TransactionError err = BroadcastTransaction(m_node, tx, err_string, max_tx_fee, broadcast_method, /*wait_callback=*/false);
|
||||||
// Chain clients only care about failures to accept the tx to the mempool. Disregard non-mempool related failures.
|
// Chain clients only care about failures to accept the tx to the mempool. Disregard non-mempool related failures.
|
||||||
// Note: this will need to be updated if BroadcastTransactions() is updated to return other non-mempool failures
|
// Note: this will need to be updated if BroadcastTransactions() is updated to return other non-mempool failures
|
||||||
// that Chain clients do not need to know about.
|
// that Chain clients do not need to know about.
|
||||||
|
|
|
@ -31,7 +31,12 @@ static TransactionError HandleATMPError(const TxValidationState& state, std::str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback)
|
TransactionError BroadcastTransaction(NodeContext& node,
|
||||||
|
const CTransactionRef tx,
|
||||||
|
std::string& err_string,
|
||||||
|
const CAmount& max_tx_fee,
|
||||||
|
TxBroadcastMethod broadcast_method,
|
||||||
|
bool wait_callback)
|
||||||
{
|
{
|
||||||
// BroadcastTransaction can be called by RPC or by the wallet.
|
// BroadcastTransaction can be called by RPC or by the wallet.
|
||||||
// chainman, mempool and peerman are initialized before the RPC server and wallet are started
|
// chainman, mempool and peerman are initialized before the RPC server and wallet are started
|
||||||
|
@ -62,7 +67,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
|
||||||
// There's already a transaction in the mempool with this txid. Don't
|
// There's already a transaction in the mempool with this txid. Don't
|
||||||
// try to submit this transaction to the mempool (since it'll be
|
// try to submit this transaction to the mempool (since it'll be
|
||||||
// rejected as a TX_CONFLICT), but do attempt to reannounce the mempool
|
// rejected as a TX_CONFLICT), but do attempt to reannounce the mempool
|
||||||
// transaction if relay=true.
|
// transaction if broadcast_method is not ADD_TO_MEMPOOL_NO_BROADCAST.
|
||||||
//
|
//
|
||||||
// The mempool transaction may have the same or different witness (and
|
// The mempool transaction may have the same or different witness (and
|
||||||
// wtxid) as this transaction. Use the mempool's wtxid for reannouncement.
|
// wtxid) as this transaction. Use the mempool's wtxid for reannouncement.
|
||||||
|
@ -79,19 +84,27 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
|
||||||
return TransactionError::MAX_FEE_EXCEEDED;
|
return TransactionError::MAX_FEE_EXCEEDED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (broadcast_method) {
|
||||||
|
case ADD_TO_MEMPOOL_NO_BROADCAST:
|
||||||
|
case ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL:
|
||||||
// Try to submit the transaction to the mempool.
|
// Try to submit the transaction to the mempool.
|
||||||
const MempoolAcceptResult result = node.chainman->ProcessTransaction(tx, /*test_accept=*/ false);
|
{
|
||||||
|
const MempoolAcceptResult result =
|
||||||
|
node.chainman->ProcessTransaction(tx, /*test_accept=*/false);
|
||||||
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
|
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
|
||||||
return HandleATMPError(result.m_state, err_string);
|
return HandleATMPError(result.m_state, err_string);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Transaction was accepted to the mempool.
|
// Transaction was accepted to the mempool.
|
||||||
|
|
||||||
if (relay) {
|
if (broadcast_method == ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL) {
|
||||||
// the mempool tracks locally submitted transactions to make a
|
// the mempool tracks locally submitted transactions to make a
|
||||||
// best-effort of initial broadcast
|
// best-effort of initial broadcast
|
||||||
node.mempool->AddUnbroadcastTx(txid);
|
node.mempool->AddUnbroadcastTx(txid);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (wait_callback && node.validation_signals) {
|
if (wait_callback && node.validation_signals) {
|
||||||
// For transactions broadcast from outside the wallet, make sure
|
// For transactions broadcast from outside the wallet, make sure
|
||||||
|
@ -116,8 +129,12 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
|
||||||
promise.get_future().wait();
|
promise.get_future().wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (relay) {
|
switch (broadcast_method) {
|
||||||
|
case ADD_TO_MEMPOOL_NO_BROADCAST:
|
||||||
|
break;
|
||||||
|
case ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL:
|
||||||
node.peerman->RelayTransaction(txid, wtxid);
|
node.peerman->RelayTransaction(txid, wtxid);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TransactionError::OK;
|
return TransactionError::OK;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define BITCOIN_NODE_TRANSACTION_H
|
#define BITCOIN_NODE_TRANSACTION_H
|
||||||
|
|
||||||
#include <common/messages.h>
|
#include <common/messages.h>
|
||||||
|
#include <node/types.h>
|
||||||
#include <policy/feerate.h>
|
#include <policy/feerate.h>
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
|
|
||||||
|
@ -45,11 +46,16 @@ static const CAmount DEFAULT_MAX_BURN_AMOUNT{0};
|
||||||
* @param[in] tx the transaction to broadcast
|
* @param[in] tx the transaction to broadcast
|
||||||
* @param[out] err_string reference to std::string to fill with error string if available
|
* @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] 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] broadcast_method whether to add the transaction to the mempool and/if how to broadcast it
|
||||||
* @param[in] wait_callback wait until callbacks have been processed to avoid stale result due to a sequentially RPC.
|
* @param[in] wait_callback wait until callbacks have been processed to avoid stale result due to a sequentially RPC.
|
||||||
* return error
|
* return error
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] TransactionError BroadcastTransaction(NodeContext& node, CTransactionRef tx, std::string& err_string, const CAmount& max_tx_fee, bool relay, bool wait_callback);
|
[[nodiscard]] TransactionError BroadcastTransaction(NodeContext& node,
|
||||||
|
CTransactionRef tx,
|
||||||
|
std::string& err_string,
|
||||||
|
const CAmount& max_tx_fee,
|
||||||
|
TxBroadcastMethod broadcast_method,
|
||||||
|
bool wait_callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return transaction with a given hash.
|
* Return transaction with a given hash.
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include <consensus/amount.h>
|
#include <consensus/amount.h>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include <policy/policy.h>
|
#include <policy/policy.h>
|
||||||
#include <script/script.h>
|
#include <script/script.h>
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
|
@ -97,6 +98,18 @@ struct BlockCheckOptions {
|
||||||
*/
|
*/
|
||||||
bool check_pow{true};
|
bool check_pow{true};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods to broadcast a local transaction.
|
||||||
|
* Used to influence `BroadcastTransaction()` and its callers.
|
||||||
|
*/
|
||||||
|
enum TxBroadcastMethod : uint8_t {
|
||||||
|
/// Add the transaction to the mempool and broadcast to all peers for which tx relay is enabled.
|
||||||
|
ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL,
|
||||||
|
/// Add the transaction to the mempool, but don't broadcast to anybody.
|
||||||
|
ADD_TO_MEMPOOL_NO_BROADCAST,
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
|
||||||
#endif // BITCOIN_NODE_TYPES_H
|
#endif // BITCOIN_NODE_TYPES_H
|
||||||
|
|
|
@ -97,7 +97,12 @@ static RPCHelpMan sendrawtransaction()
|
||||||
std::string err_string;
|
std::string err_string;
|
||||||
AssertLockNotHeld(cs_main);
|
AssertLockNotHeld(cs_main);
|
||||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
const TransactionError err = BroadcastTransaction(node, tx, err_string, max_raw_tx_fee, /*relay=*/true, /*wait_callback=*/true);
|
const TransactionError err = BroadcastTransaction(node,
|
||||||
|
tx,
|
||||||
|
err_string,
|
||||||
|
max_raw_tx_fee,
|
||||||
|
node::ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL,
|
||||||
|
/*wait_callback=*/true);
|
||||||
if (TransactionError::OK != err) {
|
if (TransactionError::OK != err) {
|
||||||
throw JSONRPCTransactionError(err, err_string);
|
throw JSONRPCTransactionError(err, err_string);
|
||||||
}
|
}
|
||||||
|
@ -1066,7 +1071,12 @@ static RPCHelpMan submitpackage()
|
||||||
|
|
||||||
// We do not expect an error here; we are only broadcasting things already/still in mempool
|
// We do not expect an error here; we are only broadcasting things already/still in mempool
|
||||||
std::string err_string;
|
std::string err_string;
|
||||||
const auto err = BroadcastTransaction(node, tx, err_string, /*max_tx_fee=*/0, /*relay=*/true, /*wait_callback=*/true);
|
const auto err = BroadcastTransaction(node,
|
||||||
|
tx,
|
||||||
|
err_string,
|
||||||
|
/*max_tx_fee=*/0,
|
||||||
|
node::ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL,
|
||||||
|
/*wait_callback=*/true);
|
||||||
if (err != TransactionError::OK) {
|
if (err != TransactionError::OK) {
|
||||||
throw JSONRPCTransactionError(err,
|
throw JSONRPCTransactionError(err,
|
||||||
strprintf("transaction broadcast failed: %s (%d transactions were broadcast successfully)",
|
strprintf("transaction broadcast failed: %s (%d transactions were broadcast successfully)",
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
#include <merkleblock.h>
|
#include <merkleblock.h>
|
||||||
|
#include <node/types.h>
|
||||||
#include <rpc/util.h>
|
#include <rpc/util.h>
|
||||||
#include <script/descriptor.h>
|
#include <script/descriptor.h>
|
||||||
#include <script/script.h>
|
#include <script/script.h>
|
||||||
|
@ -400,7 +401,7 @@ RPCHelpMan importdescriptors()
|
||||||
// Rescan the blockchain using the lowest timestamp
|
// Rescan the blockchain using the lowest timestamp
|
||||||
if (rescan) {
|
if (rescan) {
|
||||||
int64_t scanned_time = pwallet->RescanFromTime(lowest_timestamp, reserver, /*update=*/true);
|
int64_t scanned_time = pwallet->RescanFromTime(lowest_timestamp, reserver, /*update=*/true);
|
||||||
pwallet->ResubmitWalletTransactions(/*relay=*/false, /*force=*/true);
|
pwallet->ResubmitWalletTransactions(node::ADD_TO_MEMPOOL_NO_BROADCAST, /*force=*/true);
|
||||||
|
|
||||||
if (pwallet->IsAbortingRescan()) {
|
if (pwallet->IsAbortingRescan()) {
|
||||||
throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
|
throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted by user.");
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
#include <node/blockstorage.h>
|
#include <node/blockstorage.h>
|
||||||
|
#include <node/types.h>
|
||||||
#include <policy/policy.h>
|
#include <policy/policy.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
#include <script/solver.h>
|
#include <script/solver.h>
|
||||||
|
@ -618,7 +619,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
|
||||||
auto block_tx = TestSimpleSpend(*m_coinbase_txns[0], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
auto block_tx = TestSimpleSpend(*m_coinbase_txns[0], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
||||||
m_coinbase_txns.push_back(CreateAndProcessBlock({block_tx}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
|
m_coinbase_txns.push_back(CreateAndProcessBlock({block_tx}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
|
||||||
auto mempool_tx = TestSimpleSpend(*m_coinbase_txns[1], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
auto mempool_tx = TestSimpleSpend(*m_coinbase_txns[1], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
||||||
BOOST_CHECK(m_node.chain->broadcastTransaction(MakeTransactionRef(mempool_tx), DEFAULT_TRANSACTION_MAXFEE, false, error));
|
BOOST_CHECK(m_node.chain->broadcastTransaction(MakeTransactionRef(mempool_tx), DEFAULT_TRANSACTION_MAXFEE, node::ADD_TO_MEMPOOL_NO_BROADCAST, error));
|
||||||
|
|
||||||
|
|
||||||
// Reload wallet and make sure new transactions are detected despite events
|
// Reload wallet and make sure new transactions are detected despite events
|
||||||
|
@ -660,7 +661,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
|
||||||
block_tx = TestSimpleSpend(*m_coinbase_txns[2], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
block_tx = TestSimpleSpend(*m_coinbase_txns[2], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
||||||
m_coinbase_txns.push_back(CreateAndProcessBlock({block_tx}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
|
m_coinbase_txns.push_back(CreateAndProcessBlock({block_tx}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
|
||||||
mempool_tx = TestSimpleSpend(*m_coinbase_txns[3], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
mempool_tx = TestSimpleSpend(*m_coinbase_txns[3], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
||||||
BOOST_CHECK(m_node.chain->broadcastTransaction(MakeTransactionRef(mempool_tx), DEFAULT_TRANSACTION_MAXFEE, false, error));
|
BOOST_CHECK(m_node.chain->broadcastTransaction(MakeTransactionRef(mempool_tx), DEFAULT_TRANSACTION_MAXFEE, node::ADD_TO_MEMPOOL_NO_BROADCAST, error));
|
||||||
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
});
|
});
|
||||||
wallet = TestLoadWallet(context);
|
wallet = TestLoadWallet(context);
|
||||||
|
|
|
@ -1959,7 +1959,9 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string, bool relay) const
|
bool CWallet::SubmitTxMemoryPoolAndRelay(CWalletTx& wtx,
|
||||||
|
std::string& err_string,
|
||||||
|
node::TxBroadcastMethod broadcast_method) const
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet);
|
AssertLockHeld(cs_wallet);
|
||||||
|
|
||||||
|
@ -1973,8 +1975,16 @@ bool CWallet::SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string
|
||||||
// Don't try to submit conflicted or confirmed transactions.
|
// Don't try to submit conflicted or confirmed transactions.
|
||||||
if (GetTxDepthInMainChain(wtx) != 0) return false;
|
if (GetTxDepthInMainChain(wtx) != 0) return false;
|
||||||
|
|
||||||
// Submit transaction to mempool for relay
|
const char* what{""};
|
||||||
WalletLogPrintf("Submitting wtx %s to mempool for relay\n", wtx.GetHash().ToString());
|
switch (broadcast_method) {
|
||||||
|
case node::ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL:
|
||||||
|
what = "to mempool and for broadcast to peers";
|
||||||
|
break;
|
||||||
|
case node::ADD_TO_MEMPOOL_NO_BROADCAST:
|
||||||
|
what = "to mempool without broadcast";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
WalletLogPrintf("Submitting wtx %s %s\n", wtx.GetHash().ToString(), what);
|
||||||
// We must set TxStateInMempool here. Even though it will also be set later by the
|
// We must set TxStateInMempool here. Even though it will also be set later by the
|
||||||
// entered-mempool callback, if we did not there would be a race where a
|
// entered-mempool callback, if we did not there would be a race where a
|
||||||
// user could call sendmoney in a loop and hit spurious out of funds errors
|
// user could call sendmoney in a loop and hit spurious out of funds errors
|
||||||
|
@ -1984,7 +1994,7 @@ bool CWallet::SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string
|
||||||
// If broadcast fails for any reason, trying to set wtx.m_state here would be incorrect.
|
// If broadcast fails for any reason, trying to set wtx.m_state here would be incorrect.
|
||||||
// If transaction was previously in the mempool, it should be updated when
|
// If transaction was previously in the mempool, it should be updated when
|
||||||
// TransactionRemovedFromMempool fires.
|
// TransactionRemovedFromMempool fires.
|
||||||
bool ret = chain().broadcastTransaction(wtx.tx, m_default_max_tx_fee, relay, err_string);
|
bool ret = chain().broadcastTransaction(wtx.tx, m_default_max_tx_fee, broadcast_method, err_string);
|
||||||
if (ret) wtx.m_state = TxStateInMempool{};
|
if (ret) wtx.m_state = TxStateInMempool{};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -2039,10 +2049,11 @@ NodeClock::time_point CWallet::GetDefaultNextResend() { return FastRandomContext
|
||||||
//
|
//
|
||||||
// The `force` option results in all unconfirmed transactions being submitted to
|
// The `force` option results in all unconfirmed transactions being submitted to
|
||||||
// the mempool. This does not necessarily result in those transactions being relayed,
|
// the mempool. This does not necessarily result in those transactions being relayed,
|
||||||
// that depends on the `relay` option. Periodic rebroadcast uses the pattern
|
// that depends on the `broadcast_method` option. Periodic rebroadcast uses the pattern
|
||||||
// relay=true force=false, while loading into the mempool
|
// broadcast_method=ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL force=false, while loading into
|
||||||
// (on start, or after import) uses relay=false force=true.
|
// the mempool (on start, or after import) uses
|
||||||
void CWallet::ResubmitWalletTransactions(bool relay, bool force)
|
// broadcast_method=ADD_TO_MEMPOOL_NO_BROADCAST force=true.
|
||||||
|
void CWallet::ResubmitWalletTransactions(node::TxBroadcastMethod broadcast_method, bool force)
|
||||||
{
|
{
|
||||||
// Don't attempt to resubmit if the wallet is configured to not broadcast,
|
// Don't attempt to resubmit if the wallet is configured to not broadcast,
|
||||||
// even if forcing.
|
// even if forcing.
|
||||||
|
@ -2068,7 +2079,7 @@ void CWallet::ResubmitWalletTransactions(bool relay, bool force)
|
||||||
// Now try submitting the transactions to the memory pool and (optionally) relay them.
|
// Now try submitting the transactions to the memory pool and (optionally) relay them.
|
||||||
for (auto wtx : to_submit) {
|
for (auto wtx : to_submit) {
|
||||||
std::string unused_err_string;
|
std::string unused_err_string;
|
||||||
if (SubmitTxMemoryPoolAndRelay(*wtx, unused_err_string, relay)) ++submitted_tx_count;
|
if (SubmitTxMemoryPoolAndRelay(*wtx, unused_err_string, broadcast_method)) ++submitted_tx_count;
|
||||||
}
|
}
|
||||||
} // cs_wallet
|
} // cs_wallet
|
||||||
|
|
||||||
|
@ -2083,7 +2094,7 @@ void MaybeResendWalletTxs(WalletContext& context)
|
||||||
{
|
{
|
||||||
for (const std::shared_ptr<CWallet>& pwallet : GetWallets(context)) {
|
for (const std::shared_ptr<CWallet>& pwallet : GetWallets(context)) {
|
||||||
if (!pwallet->ShouldResend()) continue;
|
if (!pwallet->ShouldResend()) continue;
|
||||||
pwallet->ResubmitWalletTransactions(/*relay=*/true, /*force=*/false);
|
pwallet->ResubmitWalletTransactions(node::ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL, /*force=*/false);
|
||||||
pwallet->SetNextResend();
|
pwallet->SetNextResend();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2284,7 +2295,7 @@ void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string err_string;
|
std::string err_string;
|
||||||
if (!SubmitTxMemoryPoolAndRelay(*wtx, err_string, true)) {
|
if (!SubmitTxMemoryPoolAndRelay(*wtx, err_string, node::ADD_TO_MEMPOOL_AND_BROADCAST_TO_ALL)) {
|
||||||
WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
|
WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
|
||||||
// TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
|
// TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
|
||||||
}
|
}
|
||||||
|
@ -3233,7 +3244,7 @@ void CWallet::postInitProcess()
|
||||||
{
|
{
|
||||||
// Add wallet transactions that aren't already in a block to mempool
|
// Add wallet transactions that aren't already in a block to mempool
|
||||||
// Do this here as mempool requires genesis block to be loaded
|
// Do this here as mempool requires genesis block to be loaded
|
||||||
ResubmitWalletTransactions(/*relay=*/false, /*force=*/true);
|
ResubmitWalletTransactions(node::ADD_TO_MEMPOOL_NO_BROADCAST, /*force=*/true);
|
||||||
|
|
||||||
// Update wallet transactions with current mempool transactions.
|
// Update wallet transactions with current mempool transactions.
|
||||||
WITH_LOCK(cs_wallet, chain().requestMempoolTransactions(*this));
|
WITH_LOCK(cs_wallet, chain().requestMempoolTransactions(*this));
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <interfaces/handler.h>
|
#include <interfaces/handler.h>
|
||||||
#include <kernel/cs_main.h>
|
#include <kernel/cs_main.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
#include <node/types.h>
|
||||||
#include <outputtype.h>
|
#include <outputtype.h>
|
||||||
#include <policy/feerate.h>
|
#include <policy/feerate.h>
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
|
@ -654,7 +655,7 @@ public:
|
||||||
void SetNextResend() { m_next_resend = GetDefaultNextResend(); }
|
void SetNextResend() { m_next_resend = GetDefaultNextResend(); }
|
||||||
/** Return true if all conditions for periodically resending transactions are met. */
|
/** Return true if all conditions for periodically resending transactions are met. */
|
||||||
bool ShouldResend() const;
|
bool ShouldResend() const;
|
||||||
void ResubmitWalletTransactions(bool relay, bool force);
|
void ResubmitWalletTransactions(node::TxBroadcastMethod broadcast_method, bool force);
|
||||||
|
|
||||||
OutputType TransactionChangeType(const std::optional<OutputType>& change_type, const std::vector<CRecipient>& vecSend) const;
|
OutputType TransactionChangeType(const std::optional<OutputType>& change_type, const std::vector<CRecipient>& vecSend) const;
|
||||||
|
|
||||||
|
@ -698,8 +699,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm);
|
void CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm);
|
||||||
|
|
||||||
/** Pass this transaction to node for mempool insertion and relay to peers if flag set to true */
|
/** Pass this transaction to node for optional mempool insertion and relay to peers. */
|
||||||
bool SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string, bool relay) const
|
bool SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string, node::TxBroadcastMethod broadcast_method) const
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||||
|
|
||||||
/** Updates wallet birth time if 'time' is below it */
|
/** Updates wallet birth time if 'time' is below it */
|
||||||
|
|
Loading…
Reference in New Issue