// Copyright (c) 2018-2020 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 #if defined(HAVE_CONFIG_H) #include #endif #include #include class CWallet; fs::path GetWalletDir(); std::vector ListWalletDir(); std::vector> GetWallets(); std::shared_ptr LoadWallet(interfaces::Chain& chain, const std::string& name, bilingual_str& error, std::vector& warnings); WalletCreationStatus CreateWallet(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: void initError(const std::string& message) override { InitError(Untranslated(message)); } bool parseParameters(int argc, const char* const argv[], std::string& error) override { return gArgs.ParseParameters(argc, argv, error); } bool readConfigFiles(std::string& error) override { return gArgs.ReadConfigFiles(error, true); } void forceSetArg(const std::string& arg, const std::string& value) override { gArgs.ForceSetArg(arg, value); } bool softSetArg(const std::string& arg, const std::string& value) override { return gArgs.SoftSetArg(arg, value); } bool softSetBoolArg(const std::string& arg, bool value) override { return gArgs.SoftSetBoolArg(arg, value); } void selectParams(const std::string& network) override { SelectParams(network); } uint64_t getAssumedBlockchainSize() override { return Params().AssumedBlockchainSize(); } uint64_t getAssumedChainStateSize() override { return Params().AssumedChainStateSize(); } std::string getNetwork() override { return Params().NetworkIDString(); } void initLogging() override { InitLogging(); } void initParameterInteraction() override { InitParameterInteraction(); } std::string getWarnings() override { return GetWarnings(true); } uint32_t getLogCategories() override { return LogInstance().GetCategoryMask(); } bool baseInitialize() override { return AppInitBasicSetup() && AppInitParameterInteraction() && AppInitSanityChecks() && AppInitLockDataDirectory(); } bool appInitMain() override { m_context.chain = MakeChain(m_context); return AppInitMain(m_context); } void appShutdown() override { Interrupt(m_context); Shutdown(m_context); } void startShutdown() override { StartShutdown(); } bool shutdownRequested() override { return ShutdownRequested(); } void mapPort(bool use_upnp) override { if (use_upnp) { StartMapPort(); } else { InterruptMapPort(); StopMapPort(); } } void setupServerArgs() override { return SetupServerArgs(m_context); } 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, BanReason reason, int64_t ban_time_offset) override { if (m_context.banman) { m_context.banman->Ban(net_addr, reason, 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(); } int64_t getLastBlockTime() override { LOCK(::cs_main); if (::ChainActive().Tip()) { return ::ChainActive().Tip()->GetBlockTime(); } return Params().GenesisBlock().GetBlockTime(); // Genesis block's time of current network } 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(int num_blocks, bool conservative, int* returned_target = nullptr) override { FeeCalculation fee_calc; CFeeRate result = ::feeEstimator.estimateSmartFee(num_blocks, &fee_calc, conservative); if (returned_target) { *returned_target = fee_calc.returnedTarget; } return result; } CFeeRate getDustRelayFee() override { return ::dustRelayFee; } UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override { JSONRPCRequest req; req.params = params; req.strMethod = command; req.URI = uri; return ::tableRPC.execute(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 std::string& name, bilingual_str& error, std::vector& warnings) override { return MakeWallet(LoadWallet(*m_context.chain, name, error, warnings)); } std::unique_ptr createWallet(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(*m_context.chain, passphrase, wallet_creation_flags, name, error, warnings, wallet); return MakeWallet(wallet); } 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, block->nHeight, block->GetBlockTime(), GuessVerificationProgress(Params().TxData(), block)); })); } std::unique_ptr handleNotifyHeaderTip(NotifyHeaderTipFn fn) override { return MakeHandler( ::uiInterface.NotifyHeaderTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) { fn(sync_state, block->nHeight, block->GetBlockTime(), /* verification progress is unused when a header was received */ 0); })); } NodeContext* context() override { return &m_context; } NodeContext m_context; }; } // namespace std::unique_ptr MakeNode() { return MakeUnique(); } } // namespace interfaces