aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interfaces/chain.cpp8
-rw-r--r--src/interfaces/chain.h13
-rw-r--r--src/wallet/wallet.cpp13
-rw-r--r--src/wallet/wallet.h2
4 files changed, 26 insertions, 10 deletions
diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp
index 4f60448958..9f02514df3 100644
--- a/src/interfaces/chain.cpp
+++ b/src/interfaces/chain.cpp
@@ -11,6 +11,7 @@
#include <policy/policy.h>
#include <policy/rbf.h>
#include <primitives/block.h>
+#include <primitives/transaction.h>
#include <protocol.h>
#include <sync.h>
#include <threadsafety.h>
@@ -146,6 +147,12 @@ class LockImpl : public Chain::Lock
LockAnnotation lock(::cs_main);
return CheckFinalTx(tx);
}
+ bool submitToMemoryPool(CTransactionRef tx, CAmount absurd_fee, CValidationState& state) override
+ {
+ LockAnnotation lock(::cs_main);
+ return AcceptToMemoryPool(::mempool, state, tx, nullptr /* missing inputs */, nullptr /* txn replaced */,
+ false /* bypass limits */, absurd_fee);
+ }
};
class LockingStateImpl : public LockImpl, public UniqueLock<CCriticalSection>
@@ -237,6 +244,7 @@ public:
{
return ::mempool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
}
+ CAmount maxTxFee() override { return ::maxTxFee; }
bool getPruneMode() override { return ::fPruneMode; }
bool p2pEnabled() override { return g_connman != nullptr; }
int64_t getAdjustedTime() override { return GetAdjustedTime(); }
diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h
index b1e3f59452..be486bd4fc 100644
--- a/src/interfaces/chain.h
+++ b/src/interfaces/chain.h
@@ -7,6 +7,7 @@
#include <optional.h> // For Optional and nullopt
#include <policy/rbf.h> // For RBFTransactionState
+#include <primitives/transaction.h> // For CTransactionRef
#include <memory>
#include <stddef.h>
@@ -16,7 +17,7 @@
class CBlock;
class CScheduler;
-class CTransaction;
+class CValidationState;
class uint256;
struct CBlockLocator;
struct FeeCalculation;
@@ -109,6 +110,10 @@ public:
//! Check if transaction will be final given chain height current time.
virtual bool checkFinalTx(const CTransaction& tx) = 0;
+
+ //! Add transaction to memory pool if the transaction fee is below the
+ //! amount specified by absurd_fee (as a safeguard). */
+ virtual bool submitToMemoryPool(CTransactionRef tx, CAmount absurd_fee, CValidationState& state) = 0;
};
//! Return Lock interface. Chain is locked when this is called, and
@@ -159,6 +164,12 @@ public:
//! Pool min fee.
virtual CFeeRate mempoolMinFee() = 0;
+ //! Get node max tx fee setting (-maxtxfee).
+ //! This could be replaced by a per-wallet max fee, as proposed at
+ //! https://github.com/bitcoin/bitcoin/issues/15355
+ //! But for the time being, wallets call this to access the node setting.
+ virtual CAmount maxTxFee() = 0;
+
//! Check if pruning is enabled.
virtual bool getPruneMode() = 0;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 2a1744fa68..fb4bd8811f 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1886,7 +1886,7 @@ void CWallet::ReacceptWalletTransactions()
for (const std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
CWalletTx& wtx = *(item.second);
CValidationState state;
- wtx.AcceptToMemoryPool(*locked_chain, maxTxFee, state);
+ wtx.AcceptToMemoryPool(*locked_chain, state);
}
}
@@ -1897,7 +1897,7 @@ bool CWalletTx::RelayWalletTransaction(interfaces::Chain::Lock& locked_chain)
{
CValidationState state;
/* GetDepthInMainChain already catches known conflicts. */
- if (InMempool() || AcceptToMemoryPool(locked_chain, maxTxFee, state)) {
+ if (InMempool() || AcceptToMemoryPool(locked_chain, state)) {
pwallet->WalletLogPrintf("Relaying wtx %s\n", GetHash().ToString());
if (pwallet->chain().p2pEnabled()) {
pwallet->chain().relayTransaction(GetHash());
@@ -3180,7 +3180,7 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
if (fBroadcastTransactions)
{
// Broadcast
- if (!wtx.AcceptToMemoryPool(*locked_chain, maxTxFee, state)) {
+ if (!wtx.AcceptToMemoryPool(*locked_chain, state)) {
WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", FormatStateMessage(state));
// TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
} else {
@@ -4474,17 +4474,14 @@ bool CMerkleTx::IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const
return GetBlocksToMaturity(locked_chain) > 0;
}
-bool CWalletTx::AcceptToMemoryPool(interfaces::Chain::Lock& locked_chain, const CAmount& nAbsurdFee, CValidationState& state)
+bool CWalletTx::AcceptToMemoryPool(interfaces::Chain::Lock& locked_chain, CValidationState& state)
{
- LockAnnotation lock(::cs_main); // Temporary, for AcceptToMemoryPool below. Removed in upcoming commit.
-
// We must set fInMempool here - while it will be re-set to true by the
// 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
// because we think that this newly generated transaction's change is
// unavailable as we're not yet aware that it is in the mempool.
- bool ret = ::AcceptToMemoryPool(mempool, state, tx, nullptr /* pfMissingInputs */,
- nullptr /* plTxnReplaced */, false /* bypass_limits */, nAbsurdFee);
+ bool ret = locked_chain.submitToMemoryPool(tx, pwallet->chain().maxTxFee(), state);
fInMempool |= ret;
return ret;
}
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 41bb4bd8c7..3cfcf7a27d 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -538,7 +538,7 @@ public:
bool RelayWalletTransaction(interfaces::Chain::Lock& locked_chain);
/** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */
- bool AcceptToMemoryPool(interfaces::Chain::Lock& locked_chain, const CAmount& nAbsurdFee, CValidationState& state);
+ bool AcceptToMemoryPool(interfaces::Chain::Lock& locked_chain, CValidationState& state);
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation