diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp index e84dd0d34..448db00cc 100644 --- a/src/dummywallet.cpp +++ b/src/dummywallet.cpp @@ -1,88 +1,48 @@ // Copyright (c) 2018 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include -#include #include #include class CChainParams; class CWallet; -enum class WalletCreationStatus; -struct bilingual_str; namespace interfaces { class Chain; class Handler; class Wallet; } // namespace interfaces class DummyWalletInit : public WalletInitInterface { public: bool HasWalletSupport() const override { return false; } void AddWalletOptions(ArgsManager &argsman) const override; bool ParameterInteraction() const override { return true; } void Construct(NodeContext &node) const override { LogPrintf("No wallet support compiled in!\n"); } }; void DummyWalletInit::AddWalletOptions(ArgsManager &argsman) const { std::vector opts = { "-avoidpartialspends", "-disablewallet", "-fallbackfee=", "-keypool=", "-maxapsfee=", "-maxtxfee=", "-mintxfee=", "-paytxfee=", "-rescan", "-salvagewallet", "-spendzeroconfchange", "-upgradewallet", "-wallet=", "-walletbroadcast", "-walletdir=", "-walletnotify=", "-zapwallettxes=", // Wallet debug options "-dblogsize=", "-flushwallet", "-privdb", "-walletrejectlongchains"}; argsman.AddHiddenArgs(opts); } const WalletInitInterface &g_wallet_init_interface = DummyWalletInit(); -fs::path GetWalletDir() { - throw std::logic_error("Wallet function called in non-wallet build."); -} - -std::vector ListWalletDir() { - throw std::logic_error("Wallet function called in non-wallet build."); -} - -std::vector> GetWallets() { - throw std::logic_error("Wallet function called in non-wallet build."); -} - -std::shared_ptr LoadWallet(const CChainParams &chainParams, - interfaces::Chain &chain, - const std::string &name, - bilingual_str &error, - std::vector &warnings) { - throw std::logic_error("Wallet function called in non-wallet build."); -} - -WalletCreationStatus CreateWallet(const CChainParams &chainParams, - interfaces::Chain &chain, - const SecureString &passphrase, - uint64_t wallet_creation_flags, - const std::string &name, bilingual_str &error, - std::vector &warnings, - std::shared_ptr &result) { - throw std::logic_error("Wallet function called in non-wallet build."); -} - -using LoadWalletFn = - std::function wallet)>; -std::unique_ptr -HandleLoadWallet(LoadWalletFn load_wallet) { - throw std::logic_error("Wallet function called in non-wallet build."); -} - namespace interfaces { std::unique_ptr MakeWallet(const std::shared_ptr &wallet) { throw std::logic_error("Wallet function called in non-wallet build."); } } // namespace interfaces diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index 58ea78543..ceb2e9b9c 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -1,370 +1,355 @@ // Copyright (c) 2018-2019 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_INTERFACES_CHAIN_H #define BITCOIN_INTERFACES_CHAIN_H #include #include #include #include #include #include #include #include #include class ArgsManager; class CBlock; class CChainParams; class Coin; class Config; class CRPCCommand; class CScheduler; class TxValidationState; enum class MemPoolRemovalReason; struct BlockHash; struct bilingual_str; struct CBlockLocator; struct NodeContext; namespace Consensus { struct Params; } namespace interfaces { class Handler; class Wallet; //! Helper for findBlock to selectively return pieces of block data. class FoundBlock { public: FoundBlock &hash(BlockHash &hash) { m_hash = &hash; return *this; } FoundBlock &height(int &height) { m_height = &height; return *this; } FoundBlock &time(int64_t &time) { m_time = &time; return *this; } FoundBlock &maxTime(int64_t &max_time) { m_max_time = &max_time; return *this; } FoundBlock &mtpTime(int64_t &mtp_time) { m_mtp_time = &mtp_time; return *this; } //! Read block data from disk. If the block exists but doesn't have data //! (for example due to pruning), the CBlock variable will be set to null. FoundBlock &data(CBlock &data) { m_data = &data; return *this; } BlockHash *m_hash = nullptr; int *m_height = nullptr; int64_t *m_time = nullptr; int64_t *m_max_time = nullptr; int64_t *m_mtp_time = nullptr; CBlock *m_data = nullptr; }; //! Interface giving clients (wallet processes, maybe other analysis tools in //! the future) ability to access to the chain state, receive notifications, //! estimate fees, and submit transactions. //! //! TODO: Current chain methods are too low level, exposing too much of the //! internal workings of the bitcoin node, and not being very convenient to use. //! Chain methods should be cleaned up and simplified over time. Examples: //! //! * The initMessages() and showProgress() methods which the wallet uses to //! send //! notifications to the GUI should go away when GUI and wallet can directly //! communicate with each other without going through the node //! (https://github.com/bitcoin/bitcoin/pull/15288#discussion_r253321096). //! //! * The handleRpc, registerRpcs, rpcEnableDeprecated methods and other RPC //! methods can go away if wallets listen for HTTP requests on their own //! ports instead of registering to handle requests on the node HTTP port. //! //! * Move fee estimation queries to an asynchronous interface and let the //! wallet cache it, fee estimation being driven by node mempool, wallet //! should be the consumer. //! //! * The `guessVerificationProgress`, `getBlockHeight`, `getBlockHash`, etc //! methods can go away if rescan logic is moved on the node side, and wallet //! only register rescan request. class Chain { public: virtual ~Chain() {} //! Get current chain height, not including genesis block (returns 0 if //! chain only contains genesis block, std::nullopt if chain does not //! contain any blocks) virtual std::optional getHeight() = 0; //! Get block height above genesis block. Returns 0 for genesis block, //! 1 for following block, and so on. Returns std::nullopt for a block not //! included in the current chain. virtual std::optional getBlockHeight(const BlockHash &hash) = 0; //! Get block hash. Height must be valid or this function will abort. virtual BlockHash getBlockHash(int height) = 0; //! Check that the block is available on disk (i.e. has not been //! pruned), and contains transactions. virtual bool haveBlockOnDisk(int height) = 0; //! Return height of the first block in the chain with timestamp equal //! or greater than the given time and height equal or greater than the //! given height, or std::nullopt if there is no block with a high enough //! timestamp and height. Also return the block hash as an optional output //! parameter (to avoid the cost of a second lookup in case this information //! is needed.) virtual std::optional findFirstBlockWithTimeAndHeight(int64_t time, int height, BlockHash *hash) = 0; //! Get locator for the current chain tip. virtual CBlockLocator getTipLocator() = 0; //! Return height of the highest block on chain in common with the locator, //! which will either be the original block used to create the locator, //! or one of its ancestors. virtual std::optional findLocatorFork(const CBlockLocator &locator) = 0; //! Check if transaction will be final given chain height current time. virtual bool contextualCheckTransactionForCurrentBlock(const CTransaction &tx, TxValidationState &state) = 0; //! Return whether node has the block and optionally return block metadata //! or contents. virtual bool findBlock(const BlockHash &hash, const FoundBlock &block = {}) = 0; //! Find first block in the chain with timestamp >= the given time //! and height >= than the given height, return false if there is no block //! with a high enough timestamp and height. Optionally return block //! information. virtual bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock &block = {}) = 0; //! Find next block if block is part of current chain. Also flag if //! there was a reorg and the specified block hash is no longer in the //! current chain, and optionally return block information. virtual bool findNextBlock(const BlockHash &block_hash, int block_height, const FoundBlock &next = {}, bool *reorg = nullptr) = 0; //! Find ancestor of block at specified height and optionally return //! ancestor information. virtual bool findAncestorByHeight(const BlockHash &block_hash, int ancestor_height, const FoundBlock &ancestor_out = {}) = 0; //! Return whether block descends from a specified ancestor, and //! optionally return ancestor information. virtual bool findAncestorByHash(const BlockHash &block_hash, const BlockHash &ancestor_hash, const FoundBlock &ancestor_out = {}) = 0; //! Find most recent common ancestor between two blocks and optionally //! return block information. virtual bool findCommonAncestor(const BlockHash &block_hash1, const BlockHash &block_hash2, const FoundBlock &ancestor_out = {}, const FoundBlock &block1_out = {}, const FoundBlock &block2_out = {}) = 0; //! Look up unspent output information. Returns coins in the mempool and in //! the current chain UTXO set. Iterates through all the keys in the map and //! populates the values. virtual void findCoins(std::map &coins) = 0; //! Estimate fraction of total transactions verified if blocks up to //! the specified block hash are verified. virtual double guessVerificationProgress(const BlockHash &block_hash) = 0; //! Return true if data is available for all blocks in the specified range //! of blocks. This checks all blocks that are ancestors of block_hash in //! the height range from min_height to max_height, inclusive. virtual bool hasBlocks(const BlockHash &block_hash, int min_height = 0, std::optional max_height = {}) = 0; //! Check if transaction has descendants in mempool. virtual bool hasDescendantsInMempool(const TxId &txid) = 0; //! Transaction is added to memory pool, if the transaction fee is below the //! amount specified by max_tx_fee, and broadcast to all peers if relay is //! set to true. Return false if the transaction could not be added due to //! the fee or for another reason. virtual bool broadcastTransaction(const Config &config, const CTransactionRef &tx, const Amount &max_tx_fee, bool relay, std::string &err_string) = 0; //! Calculate mempool ancestor and descendant counts for the given //! transaction. virtual void getTransactionAncestry(const TxId &txid, size_t &ancestors, size_t &descendants) = 0; //! Get the node's package limits. //! Currently only returns the ancestor and descendant count limits, but //! could be enhanced to return more policy settings. virtual void getPackageLimits(size_t &limit_ancestor_count, size_t &limit_descendant_count) = 0; //! Check if transaction will pass the mempool's chain limits. virtual bool checkChainLimits(const CTransactionRef &tx) = 0; //! Estimate fee virtual CFeeRate estimateFee() const = 0; //! Relay current minimum fee (from -minrelaytxfee settings). virtual CFeeRate relayMinFee() = 0; //! Relay dust fee setting (-dustrelayfee), reflecting lowest rate it's //! economical to spend. virtual CFeeRate relayDustFee() = 0; //! Check if any block has been pruned. virtual bool havePruned() = 0; //! Check if the node is ready to broadcast transactions. virtual bool isReadyToBroadcast() = 0; //! Check if in IBD. virtual bool isInitialBlockDownload() = 0; //! Check if shutdown requested. virtual bool shutdownRequested() = 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 bilingual_str &message) = 0; //! Send init error. virtual void initError(const bilingual_str &message) = 0; //! Send progress indicator. virtual void showProgress(const std::string &title, int progress, bool resume_possible) = 0; //! Chain notifications. class Notifications { public: virtual ~Notifications() {} virtual void transactionAddedToMempool(const CTransactionRef &tx) {} virtual void transactionRemovedFromMempool(const CTransactionRef &ptx, MemPoolRemovalReason reason) {} virtual void blockConnected(const CBlock &block, int height) {} virtual void blockDisconnected(const CBlock &block, int height) {} virtual void updatedBlockTip() {} virtual void chainStateFlushed(const CBlockLocator &locator) {} }; //! Register handler for notifications. virtual std::unique_ptr handleNotifications(std::shared_ptr notifications) = 0; //! Wait for pending notifications to be processed unless block hash points //! to the current chain tip. virtual void waitForNotificationsIfTipChanged(const BlockHash &old_tip) = 0; //! Register handler for RPC. Command is not copied, so reference //! needs to remain valid until Handler is disconnected. virtual std::unique_ptr handleRpc(const CRPCCommand &command) = 0; //! Check if deprecated RPC is enabled. virtual bool rpcEnableDeprecated(const std::string &method) = 0; //! Run function after given number of seconds. Cancel any previous calls //! with same name. virtual void rpcRunLater(const std::string &name, std::function fn, int64_t seconds) = 0; //! Current RPC serialization flags. virtual int rpcSerializationFlags() = 0; //! Synchronously send transactionAddedToMempool notifications about all //! current mempool transactions to the specified handler and return after //! the last one is sent. These notifications aren't coordinated with async //! notifications sent by handleNotifications, so out of date async //! notifications from handleNotifications can arrive during and after //! synchronous notifications from requestMempoolTransactions. Clients need //! to be prepared to handle this by ignoring notifications about unknown //! removed transactions and already added new transactions. virtual void requestMempoolTransactions(Notifications ¬ifications) = 0; //! This Chain's parameters virtual const CChainParams ¶ms() const = 0; }; //! Interface to let node manage chain clients (wallets, or maybe tools for //! monitoring and analysis in the future). class ChainClient { public: virtual ~ChainClient() {} //! Register rpcs. virtual void registerRpcs() = 0; //! Check for errors before loading. virtual bool verify(const CChainParams &chainParams) = 0; //! Load saved state. virtual bool load(const CChainParams &chainParams) = 0; //! Start client execution and provide a scheduler. virtual void start(CScheduler &scheduler) = 0; //! Save state to disk. virtual void flush() = 0; //! Shut down client. virtual void stop() = 0; //! Set mock time. virtual void setMockTime(int64_t time) = 0; - - //! Return interfaces for accessing wallets (if any). - virtual std::vector> getWallets() = 0; }; //! Return implementation of Chain interface. std::unique_ptr MakeChain(NodeContext &node, const CChainParams ¶ms); -//! Return implementation of ChainClient interface for a wallet client. This -//! function will be undefined in builds where ENABLE_WALLET is false. -//! -//! Currently, wallets are the only chain clients. But in the future, other -//! types of chain clients could be added, such as tools for monitoring, -//! analysis, or fee estimation. These clients need to expose their own -//! MakeXXXClient functions returning their implementations of the ChainClient -//! interface. -std::unique_ptr -MakeWalletClient(Chain &chain, ArgsManager &args, - std::vector wallet_filenames); - } // namespace interfaces #endif // BITCOIN_INTERFACES_CHAIN_H diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index 7b20c519b..d3c37a125 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -1,376 +1,322 @@ // Copyright (c) 2018 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #include #include #include #include #if defined(HAVE_CONFIG_H) #include #endif #include #include class HTTPRPCRequestProcessor; -class CWallet; -fs::path GetWalletDir(); -std::vector ListWalletDir(); -std::vector> GetWallets(); -std::shared_ptr LoadWallet(const CChainParams &chainParams, - interfaces::Chain &chain, - const std::string &name, - bilingual_str &error, - std::vector &warnings); -WalletCreationStatus CreateWallet(const CChainParams ¶ms, - interfaces::Chain &chain, - const SecureString &passphrase, - uint64_t wallet_creation_flags, - const std::string &name, bilingual_str &error, - std::vector &warnings, - std::shared_ptr &result); -std::unique_ptr -HandleLoadWallet(interfaces::Node::LoadWalletFn load_wallet); - namespace interfaces { - namespace { class NodeImpl : public Node { public: NodeImpl(NodeContext *context) { setContext(context); } void initLogging() override { InitLogging(*Assert(m_context->args)); } void initParameterInteraction() override { InitParameterInteraction(*Assert(m_context->args)); } bilingual_str getWarnings() override { return GetWarnings(true); } bool baseInitialize(Config &config) override { return AppInitBasicSetup(gArgs) && AppInitParameterInteraction(config, gArgs) && AppInitSanityChecks() && AppInitLockDataDirectory() && AppInitInterfaces(*m_context); } bool appInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, interfaces::BlockAndHeaderTipInfo *tip_info) override { return AppInitMain(config, rpcServer, httpRPCRequestProcessor, *m_context, tip_info); } void appShutdown() override { Interrupt(*m_context); Shutdown(*m_context); } void startShutdown() override { StartShutdown(); // Stop RPC for clean shutdown if any of waitfor* commands is // executed. if (gArgs.GetBoolArg("-server", false)) { InterruptRPC(); StopRPC(); } } bool shutdownRequested() override { return ShutdownRequested(); } void mapPort(bool use_upnp) override { if (use_upnp) { StartMapPort(); } else { InterruptMapPort(); StopMapPort(); } } bool getProxy(Network net, proxyType &proxy_info) override { return GetProxy(net, proxy_info); } size_t getNodeCount(CConnman::NumConnections flags) override { return m_context->connman ? m_context->connman->GetNodeCount(flags) : 0; } bool getNodesStats(NodesStats &stats) override { stats.clear(); if (m_context->connman) { std::vector stats_temp; m_context->connman->GetNodeStats(stats_temp); stats.reserve(stats_temp.size()); for (auto &node_stats_temp : stats_temp) { stats.emplace_back(std::move(node_stats_temp), false, CNodeStateStats()); } // Try to retrieve the CNodeStateStats for each node. TRY_LOCK(::cs_main, lockMain); if (lockMain) { for (auto &node_stats : stats) { std::get<1>(node_stats) = GetNodeStateStats(std::get<0>(node_stats).nodeid, std::get<2>(node_stats)); } } return true; } return false; } bool getBanned(banmap_t &banmap) override { if (m_context->banman) { m_context->banman->GetBanned(banmap); return true; } return false; } bool ban(const CNetAddr &net_addr, int64_t ban_time_offset) override { if (m_context->banman) { m_context->banman->Ban(net_addr, ban_time_offset); return true; } return false; } bool unban(const CSubNet &ip) override { if (m_context->banman) { m_context->banman->Unban(ip); return true; } return false; } bool disconnectByAddress(const CNetAddr &net_addr) override { if (m_context->connman) { return m_context->connman->DisconnectNode(net_addr); } return false; } bool disconnectById(NodeId id) override { if (m_context->connman) { return m_context->connman->DisconnectNode(id); } return false; } int64_t getTotalBytesRecv() override { return m_context->connman ? m_context->connman->GetTotalBytesRecv() : 0; } int64_t getTotalBytesSent() override { return m_context->connman ? m_context->connman->GetTotalBytesSent() : 0; } size_t getMempoolSize() override { return m_context->mempool ? m_context->mempool->size() : 0; } size_t getMempoolDynamicUsage() override { return m_context->mempool ? m_context->mempool->DynamicMemoryUsage() : 0; } bool getHeaderTip(int &height, int64_t &block_time) override { LOCK(::cs_main); if (::pindexBestHeader) { height = ::pindexBestHeader->nHeight; block_time = ::pindexBestHeader->GetBlockTime(); return true; } return false; } int getNumBlocks() override { LOCK(::cs_main); return ::ChainActive().Height(); } BlockHash getBestBlockHash() override { const CBlockIndex *tip = WITH_LOCK(::cs_main, return ::ChainActive().Tip()); return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash(); } int64_t getLastBlockTime() override { LOCK(::cs_main); if (::ChainActive().Tip()) { return ::ChainActive().Tip()->GetBlockTime(); } // Genesis block's time of current network return Params().GenesisBlock().GetBlockTime(); } double getVerificationProgress() override { const CBlockIndex *tip; { LOCK(::cs_main); tip = ::ChainActive().Tip(); } return GuessVerificationProgress(Params().TxData(), tip); } bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); } bool getReindex() override { return ::fReindex; } bool getImporting() override { return ::fImporting; } void setNetworkActive(bool active) override { if (m_context->connman) { m_context->connman->SetNetworkActive(active); } } bool getNetworkActive() override { return m_context->connman && m_context->connman->GetNetworkActive(); } CFeeRate estimateSmartFee() override { return m_context->mempool ? m_context->mempool->estimateFee() : CFeeRate(); } CFeeRate getDustRelayFee() override { return ::dustRelayFee; } UniValue executeRpc(Config &config, const std::string &command, const UniValue ¶ms, const std::string &uri) override { JSONRPCRequest req(m_context_ref); req.params = params; req.strMethod = command; req.URI = uri; return ::tableRPC.execute(config, req); } std::vector listRpcCommands() override { return ::tableRPC.listCommands(); } void rpcSetTimerInterfaceIfUnset(RPCTimerInterface *iface) override { RPCSetTimerInterfaceIfUnset(iface); } void rpcUnsetTimerInterface(RPCTimerInterface *iface) override { RPCUnsetTimerInterface(iface); } bool getUnspentOutput(const COutPoint &output, Coin &coin) override { LOCK(::cs_main); return ::ChainstateActive().CoinsTip().GetCoin(output, coin); } - std::string getWalletDir() override { return GetWalletDir().string(); } - std::vector listWalletDir() override { - std::vector paths; - for (auto &path : ListWalletDir()) { - paths.push_back(path.string()); - } - return paths; - } - std::vector> getWallets() override { - std::vector> wallets; - for (auto &client : m_context->chain_clients) { - auto client_wallets = client->getWallets(); - std::move(client_wallets.begin(), client_wallets.end(), - std::back_inserter(wallets)); - } - return wallets; - } - std::unique_ptr - loadWallet(const CChainParams ¶ms, const std::string &name, - bilingual_str &error, - std::vector &warnings) const override { - return MakeWallet( - LoadWallet(params, *m_context->chain, name, error, warnings)); - } - std::unique_ptr - createWallet(const CChainParams ¶ms, const SecureString &passphrase, - uint64_t wallet_creation_flags, const std::string &name, - bilingual_str &error, std::vector &warnings, - WalletCreationStatus &status) override { - std::shared_ptr wallet; - status = CreateWallet(params, *m_context->chain, passphrase, - wallet_creation_flags, name, error, warnings, - wallet); - return MakeWallet(wallet); + WalletClient &walletClient() override { + return *Assert(m_context->wallet_client); } std::unique_ptr handleInitMessage(InitMessageFn fn) override { return MakeHandler(::uiInterface.InitMessage_connect(fn)); } std::unique_ptr handleMessageBox(MessageBoxFn fn) override { return MakeHandler(::uiInterface.ThreadSafeMessageBox_connect(fn)); } std::unique_ptr handleQuestion(QuestionFn fn) override { return MakeHandler(::uiInterface.ThreadSafeQuestion_connect(fn)); } std::unique_ptr handleShowProgress(ShowProgressFn fn) override { return MakeHandler(::uiInterface.ShowProgress_connect(fn)); } - std::unique_ptr handleLoadWallet(LoadWalletFn fn) override { - return HandleLoadWallet(std::move(fn)); - } std::unique_ptr handleNotifyNumConnectionsChanged( NotifyNumConnectionsChangedFn fn) override { return MakeHandler( ::uiInterface.NotifyNumConnectionsChanged_connect(fn)); } std::unique_ptr handleNotifyNetworkActiveChanged( NotifyNetworkActiveChangedFn fn) override { return MakeHandler( ::uiInterface.NotifyNetworkActiveChanged_connect(fn)); } std::unique_ptr handleNotifyAlertChanged(NotifyAlertChangedFn fn) override { return MakeHandler(::uiInterface.NotifyAlertChanged_connect(fn)); } std::unique_ptr handleBannedListChanged(BannedListChangedFn fn) override { return MakeHandler(::uiInterface.BannedListChanged_connect(fn)); } std::unique_ptr handleNotifyBlockTip(NotifyBlockTipFn fn) override { return MakeHandler(::uiInterface.NotifyBlockTip_connect( [fn](SynchronizationState sync_state, const CBlockIndex *block) { fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()}, GuessVerificationProgress(Params().TxData(), block)); })); } std::unique_ptr handleNotifyHeaderTip(NotifyHeaderTipFn fn) override { /* verification progress is unused when a header was received */ return MakeHandler(::uiInterface.NotifyHeaderTip_connect( [fn](SynchronizationState sync_state, const CBlockIndex *block) { fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()}, 0); })); } NodeContext *context() override { return m_context; } void setContext(NodeContext *context) override { m_context = context; if (context) { m_context_ref.Set(*context); } else { m_context_ref.Clear(); } } NodeContext *m_context{nullptr}; util::Ref m_context_ref{m_context}; }; } // namespace std::unique_ptr MakeNode(NodeContext *context) { return std::make_unique(context); } } // namespace interfaces diff --git a/src/interfaces/node.h b/src/interfaces/node.h index 66cfb308a..46a961a4f 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -1,285 +1,259 @@ // Copyright (c) 2018 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_INTERFACES_NODE_H #define BITCOIN_INTERFACES_NODE_H #include // For Amount #include // For CConnman::NumConnections #include // For banmap_t #include // For Network #include // For SecureString #include #include #include #include #include #include #include #include class BanMan; class CCoinControl; class CFeeRate; struct CNodeStateStats; struct CNodeStats; class Coin; class Config; class HTTPRPCRequestProcessor; struct NodeContext; class proxyType; class RPCServer; class RPCTimerInterface; enum class SynchronizationState; class UniValue; -enum class WalletCreationStatus; struct bilingual_str; namespace interfaces { class Handler; -class Wallet; +class WalletClient; struct BlockTip; //! Block and header tip information struct BlockAndHeaderTipInfo { int block_height; int64_t block_time; int header_height; int64_t header_time; double verification_progress; }; //! Top-level interface for a bitcoin node (bitcoind process). class Node { public: virtual ~Node() {} //! Init logging. virtual void initLogging() = 0; //! Init parameter interaction. virtual void initParameterInteraction() = 0; //! Get warnings. virtual bilingual_str getWarnings() = 0; //! Initialize app dependencies. virtual bool baseInitialize(Config &config) = 0; //! Start node. virtual bool appInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, interfaces::BlockAndHeaderTipInfo *tip_info = nullptr) = 0; //! Stop node. virtual void appShutdown() = 0; //! Start shutdown. virtual void startShutdown() = 0; //! Return whether shutdown was requested. virtual bool shutdownRequested() = 0; //! Map port. virtual void mapPort(bool use_upnp) = 0; //! Get proxy. virtual bool getProxy(Network net, proxyType &proxy_info) = 0; //! Get number of connections. virtual size_t getNodeCount(CConnman::NumConnections flags) = 0; //! Get stats for connected nodes. using NodesStats = std::vector>; virtual bool getNodesStats(NodesStats &stats) = 0; //! Get ban map entries. virtual bool getBanned(banmap_t &banmap) = 0; //! Ban node. virtual bool ban(const CNetAddr &net_addr, int64_t ban_time_offset) = 0; //! Unban node. virtual bool unban(const CSubNet &ip) = 0; //! Disconnect node by address. virtual bool disconnectByAddress(const CNetAddr &net_addr) = 0; //! Disconnect node by id. virtual bool disconnectById(NodeId id) = 0; //! Get total bytes recv. virtual int64_t getTotalBytesRecv() = 0; //! Get total bytes sent. virtual int64_t getTotalBytesSent() = 0; //! Get mempool size. virtual size_t getMempoolSize() = 0; //! Get mempool dynamic usage. virtual size_t getMempoolDynamicUsage() = 0; //! Get header tip height and time. virtual bool getHeaderTip(int &height, int64_t &block_time) = 0; //! Get num blocks. virtual int getNumBlocks() = 0; //! Get best block hash. virtual BlockHash getBestBlockHash() = 0; //! Get last block time. virtual int64_t getLastBlockTime() = 0; //! Get verification progress. virtual double getVerificationProgress() = 0; //! Is initial block download. virtual bool isInitialBlockDownload() = 0; //! Get reindex. virtual bool getReindex() = 0; //! Get importing. virtual bool getImporting() = 0; //! Set network active. virtual void setNetworkActive(bool active) = 0; //! Get network active. virtual bool getNetworkActive() = 0; //! Estimate smart fee. virtual CFeeRate estimateSmartFee() = 0; //! Get dust relay fee. virtual CFeeRate getDustRelayFee() = 0; //! Execute rpc command. virtual UniValue executeRpc(Config &config, const std::string &command, const UniValue ¶ms, const std::string &uri) = 0; //! List rpc commands. virtual std::vector listRpcCommands() = 0; //! Set RPC timer interface if unset. virtual void rpcSetTimerInterfaceIfUnset(RPCTimerInterface *iface) = 0; //! Unset RPC timer interface. virtual void rpcUnsetTimerInterface(RPCTimerInterface *iface) = 0; //! Get unspent outputs associated with a transaction. virtual bool getUnspentOutput(const COutPoint &output, Coin &coin) = 0; - //! Return default wallet directory. - virtual std::string getWalletDir() = 0; - - //! Return available wallets in wallet directory. - virtual std::vector listWalletDir() = 0; - - //! Return interfaces for accessing wallets (if any). - virtual std::vector> getWallets() = 0; - - //! Attempts to load a wallet from file or directory. - //! The loaded wallet is also notified to handlers previously registered - //! with handleLoadWallet. - virtual std::unique_ptr - loadWallet(const CChainParams ¶ms, const std::string &name, - bilingual_str &error, - std::vector &warnings) const = 0; - - //! Create a wallet from file - virtual std::unique_ptr - createWallet(const CChainParams ¶ms, const SecureString &passphrase, - uint64_t wallet_creation_flags, const std::string &name, - bilingual_str &error, std::vector &warnings, - WalletCreationStatus &status) = 0; + //! Get wallet client. + virtual WalletClient &walletClient() = 0; //! Register handler for init messages. using InitMessageFn = std::function; virtual std::unique_ptr handleInitMessage(InitMessageFn fn) = 0; //! Register handler for message box messages. using MessageBoxFn = std::function; virtual std::unique_ptr handleMessageBox(MessageBoxFn fn) = 0; //! Register handler for question messages. using QuestionFn = std::function; virtual std::unique_ptr handleQuestion(QuestionFn fn) = 0; //! Register handler for progress messages. using ShowProgressFn = std::function; virtual std::unique_ptr handleShowProgress(ShowProgressFn fn) = 0; - //! Register handler for load wallet messages. - using LoadWalletFn = std::function wallet)>; - virtual std::unique_ptr handleLoadWallet(LoadWalletFn fn) = 0; - //! Register handler for number of connections changed messages. using NotifyNumConnectionsChangedFn = std::function; virtual std::unique_ptr handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) = 0; //! Register handler for network active messages. using NotifyNetworkActiveChangedFn = std::function; virtual std::unique_ptr handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn) = 0; //! Register handler for notify alert messages. using NotifyAlertChangedFn = std::function; virtual std::unique_ptr handleNotifyAlertChanged(NotifyAlertChangedFn fn) = 0; //! Register handler for ban list messages. using BannedListChangedFn = std::function; virtual std::unique_ptr handleBannedListChanged(BannedListChangedFn fn) = 0; //! Register handler for block tip messages. using NotifyBlockTipFn = std::function; virtual std::unique_ptr handleNotifyBlockTip(NotifyBlockTipFn fn) = 0; //! Register handler for header tip messages. using NotifyHeaderTipFn = std::function; virtual std::unique_ptr handleNotifyHeaderTip(NotifyHeaderTipFn fn) = 0; //! Get and set internal node context. Useful for testing, but not //! accessible across processes. virtual NodeContext *context() { return nullptr; } virtual void setContext(NodeContext *context) {} }; //! Return implementation of Node interface. std::unique_ptr MakeNode(NodeContext *context = nullptr); //! Block tip (could be a header or not, depends on the subscribed signal). struct BlockTip { int block_height; int64_t block_time; BlockHash block_hash; }; } // namespace interfaces #endif // BITCOIN_INTERFACES_NODE_H diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp index 674d49eaf..dc76f43cc 100644 --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -1,534 +1,570 @@ // Copyright (c) 2018 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include #include #include #include #include #include