diff options
author | MarcoFalke <falke.marco@gmail.com> | 2019-03-04 13:13:21 -0500 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2019-03-04 13:13:36 -0500 |
commit | 45f434f44d0b55d137eaebb8c0486f9cebabc869 (patch) | |
tree | 9ab40a819ccf523042a40be61476f04494ae59ec /src/interfaces | |
parent | 57acfcb9fd051556fc1f68ba49f109512c0cc846 (diff) | |
parent | f7efd87c8fb49f82e268a95e989909d453500e2b (diff) |
Merge #15288: Remove wallet -> node global function calls
f7efd87c8f Change brace formatting (Russell Yanofsky)
a1df1b48a8 Remove use of IsInitialBlockDownload in wallet code (Russell Yanofsky)
1106a6fde4 Remove use of uiInterface.LoadWallet in wallet code (Russell Yanofsky)
318f41fb2c circular-dependencies: Avoid treating some .h/.cpp files as a unit (Russell Yanofsky)
d02b34c8a8 Remove use of AcceptToMemoryPool in wallet code (Russell Yanofsky)
e2c8ba9f6e Remove uses of InitMessage/Warning/Error in wallet code (Russell Yanofsky)
c5e59a96a8 Remove uses of GetAdjustedTime in wallet code (Russell Yanofsky)
6d6bcc77c0 Remove use of g_connman / PushInventory in wallet code (Russell Yanofsky)
00dfb2a440 Remove uses of g_connman in wallet code (Russell Yanofsky)
cc3836e8f9 Remove uses of fPruneMode in wallet code (Russell Yanofsky)
cc02c796d3 Remove uses of fee globals in wallet code (Russell Yanofsky)
1fb0a4a04e Remove use of CalculateMemPoolAncestors in wallet code (Russell Yanofsky)
cd32160af0 Remove use of GetTransactionAncestry in wallet code (Russell Yanofsky)
291276f7f4 Remove use of GetCountWithDescendants in wallet code (Russell Yanofsky)
bdc6628683 Remove use of IsRBFOptIn in wallet code (Russell Yanofsky)
80f52a2267 Remove uses of CheckFinalTx in wallet code (Russell Yanofsky)
Pull request description:
This change removes wallet calls to node functions that access global chain and mempool state.
This is the next step in the larger #10973 refactoring change, which removes all other accesses to node global variables from wallet code. Doing this is useful to provide a better defined interface between the wallet and node, and necessary to allow wallet and node code to run in separate processes in #10102.
Tree-SHA512: 40dbaf1f59fb22b32e70b054b30ba5638d638aa3240fa30e0f721d53c721cd6138a7ab4d423a24d7d2fda0b956e68d44c733abc2c9259c3d6c9fd6d4be89aa23
Diffstat (limited to 'src/interfaces')
-rw-r--r-- | src/interfaces/chain.cpp | 77 | ||||
-rw-r--r-- | src/interfaces/chain.h | 70 | ||||
-rw-r--r-- | src/interfaces/node.cpp | 2 | ||||
-rw-r--r-- | src/interfaces/wallet.cpp | 8 |
4 files changed, 151 insertions, 6 deletions
diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index da810bc5e6..fb634e73da 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -6,8 +6,19 @@ #include <chain.h> #include <chainparams.h> +#include <interfaces/wallet.h> +#include <net.h> +#include <policy/fees.h> +#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> +#include <timedata.h> +#include <txmempool.h> +#include <ui_interface.h> #include <uint256.h> #include <util/system.h> #include <validation.h> @@ -132,6 +143,17 @@ class LockImpl : public Chain::Lock } return nullopt; } + bool checkFinalTx(const CTransaction& tx) override + { + 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> @@ -177,6 +199,61 @@ public: LOCK(cs_main); return GuessVerificationProgress(Params().TxData(), LookupBlockIndex(block_hash)); } + RBFTransactionState isRBFOptIn(const CTransaction& tx) override + { + LOCK(::mempool.cs); + return IsRBFOptIn(tx, ::mempool); + } + bool hasDescendantsInMempool(const uint256& txid) override + { + LOCK(::mempool.cs); + auto it_mp = ::mempool.mapTx.find(txid); + return it_mp != ::mempool.mapTx.end() && it_mp->GetCountWithDescendants() > 1; + } + void relayTransaction(const uint256& txid) override + { + CInv inv(MSG_TX, txid); + g_connman->ForEachNode([&inv](CNode* node) { node->PushInventory(inv); }); + } + void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants) override + { + ::mempool.GetTransactionAncestry(txid, ancestors, descendants); + } + bool checkChainLimits(CTransactionRef tx) override + { + LockPoints lp; + CTxMemPoolEntry entry(tx, 0, 0, 0, false, 0, lp); + CTxMemPool::setEntries ancestors; + auto limit_ancestor_count = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); + auto limit_ancestor_size = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT) * 1000; + auto limit_descendant_count = gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT); + auto limit_descendant_size = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000; + std::string unused_error_string; + LOCK(::mempool.cs); + return ::mempool.CalculateMemPoolAncestors(entry, ancestors, limit_ancestor_count, limit_ancestor_size, + limit_descendant_count, limit_descendant_size, unused_error_string); + } + CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc) override + { + return ::feeEstimator.estimateSmartFee(num_blocks, calc, conservative); + } + unsigned int estimateMaxBlocks() override + { + return ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE); + } + CFeeRate mempoolMinFee() override + { + 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; } + bool isInitialBlockDownload() override { return IsInitialBlockDownload(); } + int64_t getAdjustedTime() override { return GetAdjustedTime(); } + void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); } + void initWarning(const std::string& message) override { InitWarning(message); } + void initError(const std::string& message) override { InitError(message); } + void loadWallet(std::unique_ptr<Wallet> wallet) override { ::uiInterface.LoadWallet(wallet); } }; } // namespace diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index 3a54b9164e..60f8570e36 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -5,20 +5,27 @@ #ifndef BITCOIN_INTERFACES_CHAIN_H #define BITCOIN_INTERFACES_CHAIN_H -#include <optional.h> +#include <optional.h> // For Optional and nullopt +#include <policy/rbf.h> // For RBFTransactionState +#include <primitives/transaction.h> // For CTransactionRef #include <memory> +#include <stddef.h> #include <stdint.h> #include <string> #include <vector> class CBlock; class CScheduler; +class CValidationState; class uint256; struct CBlockLocator; +struct FeeCalculation; namespace interfaces { +class Wallet; + //! Interface for giving wallet processes access to blockchain state. class Chain { @@ -102,6 +109,13 @@ public: //! is guaranteed to be an ancestor of the block used to create the //! locator. virtual Optional<int> findLocatorFork(const CBlockLocator& locator) = 0; + + //! 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 @@ -127,6 +141,60 @@ public: //! Estimate fraction of total transactions verified if blocks up to //! the specified block hash are verified. virtual double guessVerificationProgress(const uint256& block_hash) = 0; + + //! Check if transaction is RBF opt in. + virtual RBFTransactionState isRBFOptIn(const CTransaction& tx) = 0; + + //! Check if transaction has descendants in mempool. + virtual bool hasDescendantsInMempool(const uint256& txid) = 0; + + //! Relay transaction. + virtual void relayTransaction(const uint256& txid) = 0; + + //! Calculate mempool ancestor and descendant counts for the given transaction. + virtual void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants) = 0; + + //! Check chain limits. + virtual bool checkChainLimits(CTransactionRef tx) = 0; + + //! Estimate smart fee. + virtual CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc = nullptr) = 0; + + //! Fee estimator max target. + virtual unsigned int estimateMaxBlocks() = 0; + + //! 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; + + //! Check if p2p enabled. + virtual bool p2pEnabled() = 0; + + // Check if in IBD. + virtual bool isInitialBlockDownload() = 0; + + //! Get adjusted time. + virtual int64_t getAdjustedTime() = 0; + + //! Send init message. + virtual void initMessage(const std::string& message) = 0; + + //! Send init warning. + virtual void initWarning(const std::string& message) = 0; + + //! Send init error. + virtual void initError(const std::string& message) = 0; + + //! Send wallet load notification to the GUI. + virtual void loadWallet(std::unique_ptr<Wallet> wallet) = 0; }; //! Interface to let node manage chain clients (wallets, or maybe tools for diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index 96bde7e9f2..6f7dce0c24 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -275,7 +275,7 @@ public: } std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override { - return MakeHandler(::uiInterface.LoadWallet_connect([fn](std::shared_ptr<CWallet> wallet) { fn(MakeWallet(wallet)); })); + return MakeHandler(::uiInterface.LoadWallet_connect([fn](std::unique_ptr<Wallet>& wallet) { fn(std::move(wallet)); })); } std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override { diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp index 0dac75834e..7abbee0912 100644 --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -56,7 +56,7 @@ public: auto locked_chain = m_wallet.chain().lock(); LOCK(m_wallet.cs_wallet); CValidationState state; - if (!m_wallet.CommitTransaction(m_tx, std::move(value_map), std::move(order_form), m_key, g_connman.get(), state)) { + if (!m_wallet.CommitTransaction(m_tx, std::move(value_map), std::move(order_form), m_key, state)) { reject_reason = state.GetRejectReason(); return false; } @@ -99,7 +99,7 @@ WalletTx MakeWalletTx(interfaces::Chain::Lock& locked_chain, CWallet& wallet, co //! Construct wallet tx status struct. WalletTxStatus MakeWalletTxStatus(interfaces::Chain::Lock& locked_chain, const CWalletTx& wtx) { - LockAnnotation lock(::cs_main); // Temporary, for CheckFinalTx below. Removed in upcoming commit. + LockAnnotation lock(::cs_main); // Temporary, for mapBlockIndex below. Removed in upcoming commit. WalletTxStatus result; auto mi = ::mapBlockIndex.find(wtx.hashBlock); @@ -109,7 +109,7 @@ WalletTxStatus MakeWalletTxStatus(interfaces::Chain::Lock& locked_chain, const C result.depth_in_main_chain = wtx.GetDepthInMainChain(locked_chain); result.time_received = wtx.nTimeReceived; result.lock_time = wtx.tx->nLockTime; - result.is_final = CheckFinalTx(*wtx.tx); + result.is_final = locked_chain.checkFinalTx(*wtx.tx); result.is_trusted = wtx.IsTrusted(locked_chain); result.is_abandoned = wtx.isAbandoned(); result.is_coinbase = wtx.IsCoinBase(); @@ -457,7 +457,7 @@ public: { FeeCalculation fee_calc; CAmount result; - result = GetMinimumFee(*m_wallet, tx_bytes, coin_control, ::mempool, ::feeEstimator, &fee_calc); + result = GetMinimumFee(*m_wallet, tx_bytes, coin_control, &fee_calc); if (returned_target) *returned_target = fee_calc.returnedTarget; if (reason) *reason = fee_calc.reason; return result; |