diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 499b4d3864..36d24f582a 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -1,84 +1,82 @@ # Copyright (c) 2015-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. bin_PROGRAMS += bench/bench_bitcoin BENCH_SRCDIR = bench BENCH_BINARY = bench/bench_bitcoin$(EXEEXT) RAW_BENCH_FILES = \ bench/data/block413567.raw GENERATED_BENCH_FILES = $(RAW_BENCH_FILES:.raw=.raw.h) bench_bench_bitcoin_SOURCES = \ $(RAW_BENCH_FILES) \ bench/bench_bitcoin.cpp \ bench/bench.cpp \ bench/bench.h \ bench/cashaddr.cpp \ bench/checkblock.cpp \ bench/checkqueue.cpp \ bench/Examples.cpp \ bench/rollingbloom.cpp \ bench/crypto_aes.cpp \ bench/crypto_hash.cpp \ bench/ccoins_caching.cpp \ bench/gcs_filter.cpp \ bench/merkle_root.cpp \ bench/mempool_eviction.cpp \ bench/base58.cpp \ bench/lockedpool.cpp \ - bench/perf.cpp \ - bench/perf.h \ bench/prevector.cpp nodist_bench_bench_bitcoin_SOURCES = $(GENERATED_BENCH_FILES) bench_bench_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CLFAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/ bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bench_bench_bitcoin_LDADD = \ $(LIBBITCOIN_SERVER) \ $(LIBBITCOIN_WALLET) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBLEVELDB) \ $(LIBLEVELDB_SSE42) \ $(LIBMEMENV) \ $(LIBSECP256K1) \ $(LIBUNIVALUE) if ENABLE_ZMQ bench_bench_bitcoin_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif if ENABLE_WALLET bench_bench_bitcoin_SOURCES += bench/coin_selection.cpp endif bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) bench_bench_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_BENCH_FILES) CLEANFILES += $(CLEAN_BITCOIN_BENCH) bench/checkblock.cpp: bench/data/block413567.raw.h bitcoin_bench: $(BENCH_BINARY) bench: $(BENCH_BINARY) FORCE $(BENCH_BINARY) bitcoin_bench_clean : FORCE rm -f $(CLEAN_BITCOIN_BENCH) $(bench_bench_bitcoin_OBJECTS) $(BENCH_BINARY) %.raw.h: %.raw @$(MKDIR_P) $(@D) @{ \ echo "static unsigned const char $(*F)[] = {" && \ $(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' && \ echo "};"; \ } > "$@.new" && mv -f "$@.new" "$@" @echo "Generated $@" diff --git a/src/bench/CMakeLists.txt b/src/bench/CMakeLists.txt index 9610a684be..6c95ab4b3d 100644 --- a/src/bench/CMakeLists.txt +++ b/src/bench/CMakeLists.txt @@ -1,37 +1,36 @@ # Copyright (c) 2018 The Bitcoin developers project(bitcoin-bench) add_executable(bitcoin-bench EXCLUDE_FROM_ALL base58.cpp bench.cpp bench_bitcoin.cpp cashaddr.cpp ccoins_caching.cpp # checkblock.cpp TODO Fix including bench/data/*.raw files checkqueue.cpp crypto_aes.cpp crypto_hash.cpp Examples.cpp gcs_filter.cpp lockedpool.cpp mempool_eviction.cpp merkle_root.cpp - perf.cpp prevector.cpp rollingbloom.cpp ) target_link_libraries(bitcoin-bench common bitcoinconsensus server) if(BUILD_BITCOIN_WALLET) target_sources(bitcoin-bench PRIVATE coin_selection.cpp) endif() add_custom_target(bench-bitcoin COMMAND ./bitcoin-bench DEPENDS bitcoin-bench ) diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp index 3139790dd9..97a8285355 100644 --- a/src/bench/bench.cpp +++ b/src/bench/bench.cpp @@ -1,144 +1,140 @@ // Copyright (c) 2015-2016 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 void benchmark::ConsolePrinter::header() { std::cout << "# Benchmark, evals, iterations, total, min, max, median" << std::endl; } void benchmark::ConsolePrinter::result(const State &state) { auto results = state.m_elapsed_results; std::sort(results.begin(), results.end()); double total = state.m_num_iters * std::accumulate(results.begin(), results.end(), 0.0); double front = 0; double back = 0; double median = 0; if (!results.empty()) { front = results.front(); back = results.back(); size_t mid = results.size() / 2; median = results[mid]; if (0 == results.size() % 2) { median = (results[mid] + results[mid + 1]) / 2; } } std::cout << std::setprecision(6); std::cout << state.m_name << ", " << state.m_num_evals << ", " << state.m_num_iters << ", " << total << ", " << front << ", " << back << ", " << median << std::endl; } void benchmark::ConsolePrinter::footer() {} benchmark::PlotlyPrinter::PlotlyPrinter(std::string plotly_url, int64_t width, int64_t height) : m_plotly_url(plotly_url), m_width(width), m_height(height) {} void benchmark::PlotlyPrinter::header() { std::cout << "" << "" << "
" << ""; } benchmark::BenchRunner::BenchmarkMap &benchmark::BenchRunner::benchmarks() { static std::map benchmarks_map; return benchmarks_map; } benchmark::BenchRunner::BenchRunner(std::string name, benchmark::BenchFunction func, uint64_t num_iters_for_one_second) { benchmarks().insert( std::make_pair(name, Bench{func, num_iters_for_one_second})); } void benchmark::BenchRunner::RunAll(Printer &printer, uint64_t num_evals, double scaling, const std::string &filter, bool is_list_only) { - perf_init(); if (!std::ratio_less_equal::value) { std::cerr << "WARNING: Clock precision is worse than microsecond - " "benchmarks may be less accurate!\n"; } std::regex reFilter(filter); std::smatch baseMatch; printer.header(); for (const auto &p : benchmarks()) { if (!std::regex_match(p.first, baseMatch, reFilter)) { continue; } uint64_t num_iters = static_cast(p.second.num_iters_for_one_second * scaling); if (0 == num_iters) { num_iters = 1; } State state(p.first, num_evals, num_iters, printer); if (!is_list_only) { p.second.func(state); } printer.result(state); } printer.footer(); - - perf_fini(); } bool benchmark::State::UpdateTimer(const benchmark::time_point current_time) { if (m_start_time != time_point()) { std::chrono::duration diff = current_time - m_start_time; m_elapsed_results.push_back(diff.count() / m_num_iters); if (m_elapsed_results.size() == m_num_evals) { return false; } } m_num_iters_left = m_num_iters - 1; return true; } diff --git a/src/bench/perf.cpp b/src/bench/perf.cpp deleted file mode 100644 index f7f306a5e7..0000000000 --- a/src/bench/perf.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2016 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 - -#if defined(__i386__) || defined(__x86_64__) - -/* These architectures support querying the cycle counter - * from user space, no need for any syscall overhead. - */ -void perf_init(void) {} -void perf_fini(void) {} - -#elif defined(__linux__) - -#include -#include -#include - -static int fd = -1; -static struct perf_event_attr attr; - -void perf_init(void) { - attr.type = PERF_TYPE_HARDWARE; - attr.config = PERF_COUNT_HW_CPU_CYCLES; - fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0); -} - -void perf_fini(void) { - if (fd != -1) { - close(fd); - } -} - -uint64_t perf_cpucycles(void) { - uint64_t result = 0; - if (fd == -1 || - read(fd, &result, sizeof(result)) < (ssize_t)sizeof(result)) { - return 0; - } - return result; -} - -#else /* Unhandled platform */ - -void perf_init(void) {} -void perf_fini(void) {} -uint64_t perf_cpucycles(void) { - return 0; -} - -#endif diff --git a/src/bench/perf.h b/src/bench/perf.h deleted file mode 100644 index 5d2cfb48c0..0000000000 --- a/src/bench/perf.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2016 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -/** Functions for measurement of CPU cycles */ -#ifndef H_PERF -#define H_PERF - -#include - -#if defined(__i386__) - -static inline uint64_t perf_cpucycles(void) { - uint64_t x; - __asm__ volatile(".byte 0x0f, 0x31" : "=A"(x)); - return x; -} - -#elif defined(__x86_64__) - -static inline uint64_t perf_cpucycles(void) { - uint32_t hi, lo; - __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi)); - return ((uint64_t)lo) | (((uint64_t)hi) << 32); -} -#else - -uint64_t perf_cpucycles(void); - -#endif - -void perf_init(void); -void perf_fini(void); - -#endif // H_PERF diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index 57f5c454ca..4f1fc073b7 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -1,320 +1,313 @@ // 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 #if defined(HAVE_CONFIG_H) #include #endif #ifdef ENABLE_WALLET #include #include #define CHECK_WALLET(x) x #else #define CHECK_WALLET(x) \ throw std::logic_error("Wallet function called in non-wallet build.") #endif #include #include #include class HTTPRPCRequestProcessor; namespace interfaces { namespace { class NodeImpl : public Node { void parseParameters(int argc, const char *const argv[]) override { gArgs.ParseParameters(argc, argv); } void readConfigFiles() override { gArgs.ReadConfigFiles(); } 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); } std::string getNetwork() override { return Params().NetworkIDString(); } void initLogging() override { InitLogging(); } void initParameterInteraction() override { InitParameterInteraction(); } std::string getWarnings(const std::string &type) override { return GetWarnings(type); } bool baseInitialize(Config &config) override { return AppInitBasicSetup() && AppInitParameterInteraction(config) && AppInitSanityChecks() && AppInitLockDataDirectory(); } bool appInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor) override { return AppInitMain(config, rpcServer, httpRPCRequestProcessor); } void appShutdown() override { Interrupt(); Shutdown(); } 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(); } bool getProxy(Network net, proxyType &proxy_info) override { return GetProxy(net, proxy_info); } size_t getNodeCount(CConnman::NumConnections flags) override { return g_connman ? g_connman->GetNodeCount(flags) : 0; } bool getNodesStats(NodesStats &stats) override { stats.clear(); if (g_connman) { std::vector stats_temp; g_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 (g_connman) { g_connman->GetBanned(banmap); return true; } return false; } bool ban(const CNetAddr &net_addr, BanReason reason, int64_t ban_time_offset) override { if (g_connman) { g_connman->Ban(net_addr, reason, ban_time_offset); return true; } return false; } bool unban(const CSubNet &ip) override { if (g_connman) { g_connman->Unban(ip); return true; } return false; } bool disconnect(NodeId id) override { if (g_connman) { return g_connman->DisconnectNode(id); } return false; } int64_t getTotalBytesRecv() override { return g_connman ? g_connman->GetTotalBytesRecv() : 0; } int64_t getTotalBytesSent() override { return g_connman ? g_connman->GetTotalBytesSent() : 0; } size_t getMempoolSize() override { return g_mempool.size(); } size_t getMempoolDynamicUsage() override { return g_mempool.DynamicMemoryUsage(); } 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(); } // 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 IsInitialBlockDownload(); } bool getReindex() override { return ::fReindex; } bool getImporting() override { return ::fImporting; } void setNetworkActive(bool active) override { if (g_connman) { g_connman->SetNetworkActive(active); } } bool getNetworkActive() override { return g_connman && g_connman->GetNetworkActive(); } Amount getMinimumFee(unsigned int tx_bytes, const CCoinControl &coin_control) override { Amount result; CHECK_WALLET(result = GetMinimumFee(tx_bytes, coin_control, g_mempool)); return result; } Amount getMaxTxFee() override { return ::maxTxFee; } CFeeRate estimateSmartFee() override { return g_mempool.estimateFee(); } CFeeRate getDustRelayFee() override { return ::dustRelayFee; } - CFeeRate getFallbackFee() override { - CHECK_WALLET(return CWallet::fallbackFee); - } - CFeeRate getPayTxFee() override { CHECK_WALLET(return ::payTxFee); } - void setPayTxFee(CFeeRate rate) override { - CHECK_WALLET(::payTxFee = rate); - } UniValue executeRpc(Config &config, const std::string &command, const UniValue ¶ms, const std::string &uri) override { JSONRPCRequest req; 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 ::pcoinsTip->GetCoin(output, coin); } std::vector> getWallets() override { #ifdef ENABLE_WALLET std::vector> wallets; for (CWalletRef wallet : ::vpwallets) { wallets.emplace_back(MakeWallet(*wallet)); } return wallets; #else throw std::logic_error( "Node::getWallets() called in non-wallet build."); #endif } 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 { CHECK_WALLET(return MakeHandler(::uiInterface.LoadWallet.connect( [fn](CWallet *wallet) { fn(MakeWallet(*wallet)); }))); } 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](bool initial_download, const CBlockIndex *block) { fn(initial_download, block->nHeight, block->GetBlockTime(), GuessVerificationProgress(Params().TxData(), block)); })); } std::unique_ptr handleNotifyHeaderTip(NotifyHeaderTipFn fn) override { return MakeHandler(::uiInterface.NotifyHeaderTip.connect( [fn](bool initial_download, const CBlockIndex *block) { fn(initial_download, block->nHeight, block->GetBlockTime(), GuessVerificationProgress(Params().TxData(), block)); })); } }; } // namespace std::unique_ptr MakeNode() { return std::make_unique(); } } // namespace interfaces diff --git a/src/interfaces/node.h b/src/interfaces/node.h index b1a8cec449..6a2ee8212f 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -1,266 +1,257 @@ // 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 banmap_t #include // For Amount #include // For CConnman::NumConnections #include // For Network #include #include #include #include #include #include #include class CCoinControl; class CFeeRate; struct CNodeStateStats; struct CNodeStats; class Coin; class Config; class HTTPRPCRequestProcessor; class proxyType; class RPCServer; class RPCTimerInterface; class UniValue; namespace interfaces { class Handler; class Wallet; //! Top-level interface for a bitcoin node (bitcoind process). class Node { public: virtual ~Node() {} //! Set command line arguments. virtual void parseParameters(int argc, const char *const argv[]) = 0; //! Set a command line argument if it doesn't already have a value virtual bool softSetArg(const std::string &arg, const std::string &value) = 0; //! Set a command line boolean argument if it doesn't already have a value virtual bool softSetBoolArg(const std::string &arg, bool value) = 0; //! Load settings from configuration file. virtual void readConfigFiles() = 0; //! Choose network parameters. virtual void selectParams(const std::string &network) = 0; //! Get network name. virtual std::string getNetwork() = 0; //! Init logging. virtual void initLogging() = 0; //! Init parameter interaction. virtual void initParameterInteraction() = 0; //! Get warnings. virtual std::string getWarnings(const std::string &type) = 0; //! Initialize app dependencies. virtual bool baseInitialize(Config &config) = 0; //! Start node. virtual bool appInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor) = 0; //! Stop node. virtual void appShutdown() = 0; //! Start shutdown. virtual void startShutdown() = 0; //! Return whether shutdown was requested. virtual bool shutdownRequested() = 0; //! Setup arguments virtual void setupServerArgs() = 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, BanReason reason, int64_t ban_time_offset) = 0; //! Unban node. virtual bool unban(const CSubNet &ip) = 0; //! Disconnect node. virtual bool disconnect(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 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; //! Get minimum fee. virtual Amount getMinimumFee(unsigned int tx_bytes, const CCoinControl &coin_control) = 0; //! Get max tx fee. virtual Amount getMaxTxFee() = 0; //! Estimate smart fee. virtual CFeeRate estimateSmartFee() = 0; //! Get dust relay fee. virtual CFeeRate getDustRelayFee() = 0; - //! Get fallback fee. - virtual CFeeRate getFallbackFee() = 0; - - //! Get pay tx fee. - virtual CFeeRate getPayTxFee() = 0; - - //! Set pay tx fee. - virtual void setPayTxFee(CFeeRate rate) = 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 interfaces for accessing wallets (if any). virtual std::vector> getWallets() = 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; }; //! Return implementation of Node interface. std::unique_ptr MakeNode(); } // namespace interfaces #endif // BITCOIN_INTERFACES_NODE_H