Initial Vexta Core v0.1.0 release

This commit is contained in:
Capri 2026-07-15 14:07:28 +00:00
commit 25c454329d
2481 changed files with 689289 additions and 0 deletions

19
src/interfaces/README.md Normal file
View file

@ -0,0 +1,19 @@
# Internal c++ interfaces
The following interfaces are defined here:
* [`Chain`](chain.h) — used by wallet to access blockchain and mempool state. Added in [#14437](https://github.com/digibyte/digibyte/pull/14437), [#14711](https://github.com/digibyte/digibyte/pull/14711), [#15288](https://github.com/digibyte/digibyte/pull/15288), and [#10973](https://github.com/digibyte/digibyte/pull/10973).
* [`ChainClient`](chain.h) — used by node to start & stop `Chain` clients. Added in [#14437](https://github.com/digibyte/digibyte/pull/14437).
* [`Node`](node.h) — used by GUI to start & stop digibyte node. Added in [#10244](https://github.com/digibyte/digibyte/pull/10244).
* [`Wallet`](wallet.h) — used by GUI to access wallets. Added in [#10244](https://github.com/digibyte/digibyte/pull/10244).
* [`Handler`](handler.h) — returned by `handleEvent` methods on interfaces above and used to manage lifetimes of event handlers.
* [`Init`](init.h) — used by multiprocess code to access interfaces above on startup. Added in [#19160](https://github.com/digibyte/digibyte/pull/19160).
* [`Ipc`](ipc.h) — used by multiprocess code to access `Init` interface across processes. Added in [#19160](https://github.com/digibyte/digibyte/pull/19160).
The interfaces above define boundaries between major components of digibyte code (node, wallet, and gui), making it possible for them to run in [different processes](../../doc/multiprocess.md), and be tested, developed, and understood independently. These interfaces are not currently designed to be stable or to be used externally.

319
src/interfaces/chain.h Normal file
View file

@ -0,0 +1,319 @@
// Copyright (c) 2018-2020 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_INTERFACES_CHAIN_H
#define DIGIBYTE_INTERFACES_CHAIN_H
#include <primitives/transaction.h> // For CTransactionRef
#include <util/settings.h> // For util::SettingsValue
#include <functional>
#include <memory>
#include <optional>
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
class ArgsManager;
class CBlock;
class CFeeRate;
class CRPCCommand;
class CScheduler;
class Coin;
class uint256;
enum class MemPoolRemovalReason;
enum class RBFTransactionState;
struct bilingual_str;
struct CBlockLocator;
struct FeeCalculation;
struct NodeContext;
namespace interfaces {
class Handler;
class Wallet;
//! Helper for findBlock to selectively return pieces of block data.
class FoundBlock
{
public:
FoundBlock& hash(uint256& 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; }
//! Return whether block is in the active (most-work) chain.
FoundBlock& inActiveChain(bool& in_active_chain) { m_in_active_chain = &in_active_chain; return *this; }
//! Return next block in the active chain if current block is in the active chain.
FoundBlock& nextBlock(const FoundBlock& next_block) { m_next_block = &next_block; 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; }
uint256* m_hash = nullptr;
int* m_height = nullptr;
int64_t* m_time = nullptr;
int64_t* m_max_time = nullptr;
int64_t* m_mtp_time = nullptr;
bool* m_in_active_chain = nullptr;
const FoundBlock* m_next_block = 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 Vexta 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/digibyte/digibyte/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.
//!
//! * `guessVerificationProgress` and similar methods can go away if rescan
//! logic moves out of the wallet, and the wallet just requests scans from the
//! node (https://github.com/digibyte/digibyte/issues/11756)
class Chain
{
public:
virtual ~Chain() {}
//! Get current chain height, not including genesis block (returns 0 if
//! chain only contains genesis block, nullopt if chain does not contain
//! any blocks)
virtual std::optional<int> getHeight() = 0;
//! Get block hash. Height must be valid or this function will abort.
virtual uint256 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;
//! 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<int> findLocatorFork(const CBlockLocator& locator) = 0;
//! Check if transaction will be final given chain height current time.
virtual bool checkFinalTx(const CTransaction& tx) = 0;
//! Return whether node has the block and optionally return block metadata
//! or contents.
virtual bool findBlock(const uint256& 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 ancestor of block at specified height and optionally return
//! ancestor information.
virtual bool findAncestorByHeight(const uint256& 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 uint256& block_hash,
const uint256& ancestor_hash,
const FoundBlock& ancestor_out={}) = 0;
//! Find most recent common ancestor between two blocks and optionally
//! return block information.
virtual bool findCommonAncestor(const uint256& block_hash1,
const uint256& 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<COutPoint, Coin>& coins) = 0;
//! Estimate fraction of total transactions verified if blocks up to
//! the specified block hash are verified.
virtual double guessVerificationProgress(const uint256& 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 uint256& block_hash, int min_height = 0, std::optional<int> max_height = {}) = 0;
//! Check if transaction is RBF opt in.
virtual RBFTransactionState isRBFOptIn(const CTransaction& tx) = 0;
//! Check if transaction is in mempool.
virtual bool isInMempool(const uint256& txid) = 0;
//! Check if transaction has descendants in mempool.
virtual bool hasDescendantsInMempool(const uint256& 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 CTransactionRef& tx,
const CAmount& max_tx_fee,
bool relay,
std::string& err_string) = 0;
//! Calculate mempool ancestor and descendant counts for the given transaction.
virtual void getTransactionAncestry(const uint256& 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(unsigned int& limit_ancestor_count, unsigned int& limit_descendant_count) = 0;
//! Check if transaction will pass the mempool's chain limits.
virtual bool checkChainLimits(const 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;
//! Mempool minimum fee.
virtual CFeeRate mempoolMinFee() = 0;
//! Relay current minimum fee (from -minrelaytxfee and -incrementalrelayfee settings).
virtual CFeeRate relayMinFee() = 0;
//! Relay incremental fee setting (-incrementalrelayfee), reflecting cost of relay.
virtual CFeeRate relayIncrementalFee() = 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, uint64_t mempool_sequence) {}
virtual void transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) {}
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<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) = 0;
//! Wait for pending notifications to be processed unless block hash points to the current
//! chain tip.
virtual void waitForNotificationsIfTipChanged(const uint256& 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<Handler> 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<void()> fn, int64_t seconds) = 0;
//! Current RPC serialization flags.
virtual int rpcSerializationFlags() = 0;
//! Return <datadir>/settings.json setting value.
virtual util::SettingsValue getRwSetting(const std::string& name) = 0;
//! Write a setting to <datadir>/settings.json.
virtual bool updateRwSetting(const std::string& name, const util::SettingsValue& value) = 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& notifications) = 0;
//! Check if Taproot has activated
virtual bool isTaprootActive() 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() = 0;
//! Load saved state.
virtual bool load() = 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 implementation of Chain interface.
std::unique_ptr<Chain> MakeChain(NodeContext& node);
} // namespace interfaces
#endif // DIGIBYTE_INTERFACES_CHAIN_H

18
src/interfaces/echo.cpp Normal file
View file

@ -0,0 +1,18 @@
// Copyright (c) 2021 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <interfaces/echo.h>
#include <memory>
namespace interfaces {
namespace {
class EchoImpl : public Echo
{
public:
std::string echo(const std::string& echo) override { return echo; }
};
} // namespace
std::unique_ptr<Echo> MakeEcho() { return std::make_unique<EchoImpl>(); }
} // namespace interfaces

26
src/interfaces/echo.h Normal file
View file

@ -0,0 +1,26 @@
// Copyright (c) 2021 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_INTERFACES_ECHO_H
#define DIGIBYTE_INTERFACES_ECHO_H
#include <memory>
#include <string>
namespace interfaces {
//! Simple string echoing interface for testing.
class Echo
{
public:
virtual ~Echo() {}
//! Echo provided string.
virtual std::string echo(const std::string& echo) = 0;
};
//! Return implementation of Echo interface.
std::unique_ptr<Echo> MakeEcho();
} // namespace interfaces
#endif // DIGIBYTE_INTERFACES_ECHO_H

View file

@ -0,0 +1,46 @@
// Copyright (c) 2018-2020 The Bitcoin Core developers
// Copyright (c) 2018-2020 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <interfaces/handler.h>
#include <boost/signals2/connection.hpp>
#include <utility>
namespace interfaces {
namespace {
class HandlerImpl : public Handler
{
public:
explicit HandlerImpl(boost::signals2::connection connection) : m_connection(std::move(connection)) {}
void disconnect() override { m_connection.disconnect(); }
boost::signals2::scoped_connection m_connection;
};
class CleanupHandler : public Handler
{
public:
explicit CleanupHandler(std::function<void()> cleanup) : m_cleanup(std::move(cleanup)) {}
~CleanupHandler() override { if (!m_cleanup) return; m_cleanup(); m_cleanup = nullptr; }
void disconnect() override { if (!m_cleanup) return; m_cleanup(); m_cleanup = nullptr; }
std::function<void()> m_cleanup;
};
} // namespace
std::unique_ptr<Handler> MakeHandler(boost::signals2::connection connection)
{
return std::make_unique<HandlerImpl>(std::move(connection));
}
std::unique_ptr<Handler> MakeHandler(std::function<void()> cleanup)
{
return std::make_unique<CleanupHandler>(std::move(cleanup));
}
} // namespace interfaces

40
src/interfaces/handler.h Normal file
View file

@ -0,0 +1,40 @@
// Copyright (c) 2018-2020 The Bitcoin Core developers
// Copyright (c) 2018-2020 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_INTERFACES_HANDLER_H
#define DIGIBYTE_INTERFACES_HANDLER_H
#include <functional>
#include <memory>
namespace boost {
namespace signals2 {
class connection;
} // namespace signals2
} // namespace boost
namespace interfaces {
//! Generic interface for managing an event handler or callback function
//! registered with another interface. Has a single disconnect method to cancel
//! the registration and prevent any future notifications.
class Handler
{
public:
virtual ~Handler() {}
//! Disconnect the handler.
virtual void disconnect() = 0;
};
//! Return handler wrapping a boost signal connection.
std::unique_ptr<Handler> MakeHandler(boost::signals2::connection connection);
//! Return handler wrapping a cleanup function.
std::unique_ptr<Handler> MakeHandler(std::function<void()> cleanup);
} // namespace interfaces
#endif // DIGIBYTE_INTERFACES_HANDLER_H

17
src/interfaces/init.cpp Normal file
View file

@ -0,0 +1,17 @@
// Copyright (c) 2021 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <interfaces/chain.h>
#include <interfaces/echo.h>
#include <interfaces/init.h>
#include <interfaces/node.h>
#include <interfaces/wallet.h>
namespace interfaces {
std::unique_ptr<Node> Init::makeNode() { return {}; }
std::unique_ptr<Chain> Init::makeChain() { return {}; }
std::unique_ptr<WalletClient> Init::makeWalletClient(Chain& chain) { return {}; }
std::unique_ptr<Echo> Init::makeEcho() { return {}; }
Ipc* Init::ipc() { return nullptr; }
} // namespace interfaces

52
src/interfaces/init.h Normal file
View file

@ -0,0 +1,52 @@
// Copyright (c) 2021 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_INTERFACES_INIT_H
#define DIGIBYTE_INTERFACES_INIT_H
#include <memory>
struct NodeContext;
namespace interfaces {
class Chain;
class Echo;
class Ipc;
class Node;
class WalletClient;
//! Initial interface created when a process is first started, and used to give
//! and get access to other interfaces (Node, Chain, Wallet, etc).
//!
//! There is a different Init interface implementation for each process
//! (vexta-gui, vexta-node, digibyte-wallet, vextad, vexta-qt) and each
//! implementation can implement the make methods for interfaces it supports.
//! The default make methods all return null.
class Init
{
public:
virtual ~Init() = default;
virtual std::unique_ptr<Node> makeNode();
virtual std::unique_ptr<Chain> makeChain();
virtual std::unique_ptr<WalletClient> makeWalletClient(Chain& chain);
virtual std::unique_ptr<Echo> makeEcho();
virtual Ipc* ipc();
};
//! Return implementation of Init interface for the node process. If the argv
//! indicates that this is a child process spawned to handle requests from a
//! parent process, this blocks and handles requests, then returns null and a
//! status code to exit with. If this returns non-null, the caller can start up
//! normally and use the Init object to spawn and connect to other processes
//! while it is running.
std::unique_ptr<Init> MakeNodeInit(NodeContext& node, int argc, char* argv[], int& exit_status);
//! Return implementation of Init interface for the wallet process.
std::unique_ptr<Init> MakeWalletInit(int argc, char* argv[], int& exit_status);
//! Return implementation of Init interface for the gui process.
std::unique_ptr<Init> MakeGuiInit(int argc, char* argv[]);
} // namespace interfaces
#endif // DIGIBYTE_INTERFACES_INIT_H

71
src/interfaces/ipc.h Normal file
View file

@ -0,0 +1,71 @@
// Copyright (c) 2021 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_INTERFACES_IPC_H
#define DIGIBYTE_INTERFACES_IPC_H
#include <functional>
#include <memory>
#include <typeindex>
namespace interfaces {
class Init;
//! Interface providing access to interprocess-communication (IPC)
//! functionality. The IPC implementation is responsible for establishing
//! connections between a controlling process and a process being controlled.
//! When a connection is established, the process being controlled returns an
//! interfaces::Init pointer to the controlling process, which the controlling
//! process can use to get access to other interfaces and functionality.
//!
//! When spawning a new process, the steps are:
//!
//! 1. The controlling process calls interfaces::Ipc::spawnProcess(), which
//! calls ipc::Process::spawn(), which spawns a new process and returns a
//! socketpair file descriptor for communicating with it.
//! interfaces::Ipc::spawnProcess() then calls ipc::Protocol::connect()
//! passing the socketpair descriptor, which returns a local proxy
//! interfaces::Init implementation calling remote interfaces::Init methods.
//! 2. The spawned process calls interfaces::Ipc::startSpawnProcess(), which
//! calls ipc::Process::checkSpawned() to read command line arguments and
//! determine whether it is a spawned process and what socketpair file
//! descriptor it should use. It then calls ipc::Protocol::serve() to handle
//! incoming requests from the socketpair and invoke interfaces::Init
//! interface methods, and exit when the socket is closed.
//! 3. The controlling process calls local proxy interfaces::Init object methods
//! to make other proxy objects calling other remote interfaces. It can also
//! destroy the initial interfaces::Init object to close the connection and
//! shut down the spawned process.
class Ipc
{
public:
virtual ~Ipc() = default;
//! Spawn a child process returning pointer to its Init interface.
virtual std::unique_ptr<Init> spawnProcess(const char* exe_name) = 0;
//! If this is a spawned process, block and handle requests from the parent
//! process by forwarding them to this process's Init interface, then return
//! true. If this is not a spawned child process, return false.
virtual bool startSpawnedProcess(int argc, char* argv[], int& exit_status) = 0;
//! Add cleanup callback to remote interface that will run when the
//! interface is deleted.
template<typename Interface>
void addCleanup(Interface& iface, std::function<void()> cleanup)
{
addCleanup(typeid(Interface), &iface, std::move(cleanup));
}
protected:
//! Internal implementation of public addCleanup method (above) as a
//! type-erased virtual function, since template functions can't be virtual.
virtual void addCleanup(std::type_index type, void* iface, std::function<void()> cleanup) = 0;
};
//! Return implementation of Ipc interface.
std::unique_ptr<Ipc> MakeIpc(const char* exe_name, const char* process_argv0, Init& init);
} // namespace interfaces
#endif // DIGIBYTE_INTERFACES_IPC_H

245
src/interfaces/node.h Normal file
View file

@ -0,0 +1,245 @@
// Copyright (c) 2018-2020 The Bitcoin Core developers
// Copyright (c) 2018-2020 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_INTERFACES_NODE_H
#define DIGIBYTE_INTERFACES_NODE_H
#include <amount.h> // For CAmount
#include <external_signer.h>
#include <net.h> // For NodeId
#include <net_types.h> // For banmap_t
#include <netaddress.h> // For Network
#include <netbase.h> // For ConnectionDirection
#include <support/allocators/secure.h> // For SecureString
#include <util/translation.h>
#include <functional>
#include <memory>
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <tuple>
#include <vector>
class BanMan;
class CCoinControl;
class CFeeRate;
class CNodeStats;
class Coin;
class RPCTimerInterface;
class UniValue;
class proxyType;
enum class SynchronizationState;
struct CNodeStateStats;
struct NodeContext;
struct bilingual_str;
namespace interfaces {
class Handler;
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 Vexta node (vextad 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;
// Get log flags.
virtual uint32_t getLogCategories() = 0;
//! Initialize app dependencies.
virtual bool baseInitialize() = 0;
//! Start node.
virtual bool appInitMain(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, bool use_natpmp) = 0;
//! Get proxy.
virtual bool getProxy(Network net, proxyType& proxy_info) = 0;
//! Get number of connections.
virtual size_t getNodeCount(ConnectionDirection flags) = 0;
//! Get stats for connected nodes.
using NodesStats = std::vector<std::tuple<CNodeStats, bool, CNodeStateStats>>;
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;
//! List external signers
virtual std::vector<ExternalSigner> externalSigners() = 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 uint256 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;
//! Get dust relay fee.
virtual CFeeRate getDustRelayFee() = 0;
//! Execute rpc command.
virtual UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) = 0;
//! List rpc commands.
virtual std::vector<std::string> 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;
//! Get wallet client.
virtual WalletClient& walletClient() = 0;
//! Register handler for init messages.
using InitMessageFn = std::function<void(const std::string& message)>;
virtual std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) = 0;
//! Register handler for message box messages.
using MessageBoxFn =
std::function<bool(const bilingual_str& message, const std::string& caption, unsigned int style)>;
virtual std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) = 0;
//! Register handler for question messages.
using QuestionFn = std::function<bool(const bilingual_str& message,
const std::string& non_interactive_message,
const std::string& caption,
unsigned int style)>;
virtual std::unique_ptr<Handler> handleQuestion(QuestionFn fn) = 0;
//! Register handler for progress messages.
using ShowProgressFn = std::function<void(const std::string& title, int progress, bool resume_possible)>;
virtual std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) = 0;
//! Register handler for number of connections changed messages.
using NotifyNumConnectionsChangedFn = std::function<void(int new_num_connections)>;
virtual std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) = 0;
//! Register handler for network active messages.
using NotifyNetworkActiveChangedFn = std::function<void(bool network_active)>;
virtual std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn) = 0;
//! Register handler for notify alert messages.
using NotifyAlertChangedFn = std::function<void()>;
virtual std::unique_ptr<Handler> handleNotifyAlertChanged(NotifyAlertChangedFn fn) = 0;
//! Register handler for ban list messages.
using BannedListChangedFn = std::function<void()>;
virtual std::unique_ptr<Handler> handleBannedListChanged(BannedListChangedFn fn) = 0;
//! Register handler for block tip messages.
using NotifyBlockTipFn =
std::function<void(SynchronizationState, interfaces::BlockTip tip, double verification_progress)>;
virtual std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) = 0;
//! Register handler for header tip messages.
using NotifyHeaderTipFn =
std::function<void(SynchronizationState, interfaces::BlockTip tip, double verification_progress)>;
virtual std::unique_ptr<Handler> 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<Node> 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;
uint256 block_hash;
};
} // namespace interfaces
#endif // DIGIBYTE_INTERFACES_NODE_H

422
src/interfaces/wallet.h Normal file
View file

@ -0,0 +1,422 @@
// Copyright (c) 2018-2020 The Bitcoin Core developers
// Copyright (c) 2018-2020 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_INTERFACES_WALLET_H
#define DIGIBYTE_INTERFACES_WALLET_H
#include <amount.h> // For CAmount
#include <interfaces/chain.h> // For ChainClient
#include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation)
#include <script/standard.h> // For CTxDestination
#include <support/allocators/secure.h> // For SecureString
#include <util/message.h>
#include <util/ui_change_type.h>
#include <functional>
#include <map>
#include <memory>
#include <stdint.h>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
class CCoinControl;
class CFeeRate;
class CKey;
class CWallet;
enum class FeeReason;
enum class OutputType;
enum class TransactionError;
enum isminetype : unsigned int;
struct CRecipient;
struct PartiallySignedTransaction;
struct WalletContext;
struct bilingual_str;
typedef uint8_t isminefilter;
namespace interfaces {
class Handler;
struct WalletAddress;
struct WalletBalances;
struct WalletTx;
struct WalletTxOut;
struct WalletTxStatus;
using WalletOrderForm = std::vector<std::pair<std::string, std::string>>;
using WalletValueMap = std::map<std::string, std::string>;
//! Interface for accessing a wallet.
class Wallet
{
public:
virtual ~Wallet() {}
//! Encrypt wallet.
virtual bool encryptWallet(const SecureString& wallet_passphrase) = 0;
//! Return whether wallet is encrypted.
virtual bool isCrypted() = 0;
//! Lock wallet.
virtual bool lock() = 0;
//! Unlock wallet.
virtual bool unlock(const SecureString& wallet_passphrase) = 0;
//! Return whether wallet is locked.
virtual bool isLocked() = 0;
//! Change wallet passphrase.
virtual bool changeWalletPassphrase(const SecureString& old_wallet_passphrase,
const SecureString& new_wallet_passphrase) = 0;
//! Abort a rescan.
virtual void abortRescan() = 0;
//! Back up wallet.
virtual bool backupWallet(const std::string& filename) = 0;
//! Get wallet name.
virtual std::string getWalletName() = 0;
// Get a new address.
virtual bool getNewDestination(const OutputType type, const std::string label, CTxDestination& dest) = 0;
//! Get public key.
virtual bool getPubKey(const CScript& script, const CKeyID& address, CPubKey& pub_key) = 0;
//! Sign message
virtual SigningResult signMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) = 0;
//! Return whether wallet has private key.
virtual bool isSpendable(const CTxDestination& dest) = 0;
//! Return whether wallet has watch only keys.
virtual bool haveWatchOnly() = 0;
//! Add or update address.
virtual bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) = 0;
// Remove address.
virtual bool delAddressBook(const CTxDestination& dest) = 0;
//! Look up address in wallet, return whether exists.
virtual bool getAddress(const CTxDestination& dest,
std::string* name,
isminetype* is_mine,
std::string* purpose) = 0;
//! Get wallet address list.
virtual std::vector<WalletAddress> getAddresses() = 0;
//! Get receive requests.
virtual std::vector<std::string> getAddressReceiveRequests() = 0;
//! Save or remove receive request.
virtual bool setAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& value) = 0;
//! Display address on external signer
virtual bool displayAddress(const CTxDestination& dest) = 0;
//! Lock coin.
virtual void lockCoin(const COutPoint& output) = 0;
//! Unlock coin.
virtual void unlockCoin(const COutPoint& output) = 0;
//! Return whether coin is locked.
virtual bool isLockedCoin(const COutPoint& output) = 0;
//! List locked coins.
virtual void listLockedCoins(std::vector<COutPoint>& outputs) = 0;
//! Create transaction.
virtual CTransactionRef createTransaction(const std::vector<CRecipient>& recipients,
const CCoinControl& coin_control,
bool sign,
int& change_pos,
CAmount& fee,
bilingual_str& fail_reason) = 0;
//! Commit transaction.
virtual void commitTransaction(CTransactionRef tx,
WalletValueMap value_map,
WalletOrderForm order_form) = 0;
//! Return whether transaction can be abandoned.
virtual bool transactionCanBeAbandoned(const uint256& txid) = 0;
//! Abandon transaction.
virtual bool abandonTransaction(const uint256& txid) = 0;
//! Return whether transaction can be bumped.
virtual bool transactionCanBeBumped(const uint256& txid) = 0;
//! Create bump transaction.
virtual bool createBumpTransaction(const uint256& txid,
const CCoinControl& coin_control,
std::vector<bilingual_str>& errors,
CAmount& old_fee,
CAmount& new_fee,
CMutableTransaction& mtx) = 0;
//! Sign bump transaction.
virtual bool signBumpTransaction(CMutableTransaction& mtx) = 0;
//! Commit bump transaction.
virtual bool commitBumpTransaction(const uint256& txid,
CMutableTransaction&& mtx,
std::vector<bilingual_str>& errors,
uint256& bumped_txid) = 0;
//! Get a transaction.
virtual CTransactionRef getTx(const uint256& txid) = 0;
//! Get transaction information.
virtual WalletTx getWalletTx(const uint256& txid) = 0;
//! Get list of all wallet transactions.
virtual std::vector<WalletTx> getWalletTxs() = 0;
//! Try to get updated status for a particular transaction, if possible without blocking.
virtual bool tryGetTxStatus(const uint256& txid,
WalletTxStatus& tx_status,
int& num_blocks,
int64_t& block_time) = 0;
//! Get transaction details.
virtual WalletTx getWalletTxDetails(const uint256& txid,
WalletTxStatus& tx_status,
WalletOrderForm& order_form,
bool& in_mempool,
int& num_blocks) = 0;
//! Fill PSBT.
virtual TransactionError fillPSBT(int sighash_type,
bool sign,
bool bip32derivs,
size_t* n_signed,
PartiallySignedTransaction& psbtx,
bool& complete) = 0;
//! Get balances.
virtual WalletBalances getBalances() = 0;
//! Get balances if possible without blocking.
virtual bool tryGetBalances(WalletBalances& balances, uint256& block_hash) = 0;
//! Get balance.
virtual CAmount getBalance() = 0;
//! Get available balance.
virtual CAmount getAvailableBalance(const CCoinControl& coin_control) = 0;
//! Return whether transaction input belongs to wallet.
virtual isminetype txinIsMine(const CTxIn& txin) = 0;
//! Return whether transaction output belongs to wallet.
virtual isminetype txoutIsMine(const CTxOut& txout) = 0;
//! Return debit amount if transaction input belongs to wallet.
virtual CAmount getDebit(const CTxIn& txin, isminefilter filter) = 0;
//! Return credit amount if transaction input belongs to wallet.
virtual CAmount getCredit(const CTxOut& txout, isminefilter filter) = 0;
//! Return AvailableCoins + LockedCoins grouped by wallet address.
//! (put change in one group with wallet address)
using CoinsList = std::map<CTxDestination, std::vector<std::tuple<COutPoint, WalletTxOut>>>;
virtual CoinsList listCoins() = 0;
//! Return wallet transaction output information.
virtual std::vector<WalletTxOut> getCoins(const std::vector<COutPoint>& outputs) = 0;
//! Get required fee.
virtual CAmount getRequiredFee(unsigned int tx_bytes) = 0;
//! Get minimum fee.
virtual CAmount getMinimumFee(unsigned int tx_bytes,
const CCoinControl& coin_control,
int* returned_target,
FeeReason* reason) = 0;
//! Get tx confirm target.
virtual unsigned int getConfirmTarget() = 0;
// Return whether HD enabled.
virtual bool hdEnabled() = 0;
// Return whether the wallet is blank.
virtual bool canGetAddresses() = 0;
// Return whether private keys enabled.
virtual bool privateKeysDisabled() = 0;
// Return whether wallet uses an external signer.
virtual bool hasExternalSigner() = 0;
// Get default address type.
virtual OutputType getDefaultAddressType() = 0;
//! Get max tx fee.
virtual CAmount getDefaultMaxTxFee() = 0;
// Remove wallet.
virtual void remove() = 0;
//! Return whether is a legacy wallet
virtual bool isLegacy() = 0;
//! Register handler for unload message.
using UnloadFn = std::function<void()>;
virtual std::unique_ptr<Handler> handleUnload(UnloadFn fn) = 0;
//! Register handler for show progress messages.
using ShowProgressFn = std::function<void(const std::string& title, int progress)>;
virtual std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) = 0;
//! Register handler for status changed messages.
using StatusChangedFn = std::function<void()>;
virtual std::unique_ptr<Handler> handleStatusChanged(StatusChangedFn fn) = 0;
//! Register handler for address book changed messages.
using AddressBookChangedFn = std::function<void(const CTxDestination& address,
const std::string& label,
bool is_mine,
const std::string& purpose,
ChangeType status)>;
virtual std::unique_ptr<Handler> handleAddressBookChanged(AddressBookChangedFn fn) = 0;
//! Register handler for transaction changed messages.
using TransactionChangedFn = std::function<void(const uint256& txid, ChangeType status)>;
virtual std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn) = 0;
//! Register handler for watchonly changed messages.
using WatchOnlyChangedFn = std::function<void(bool have_watch_only)>;
virtual std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) = 0;
//! Register handler for keypool changed messages.
using CanGetAddressesChangedFn = std::function<void()>;
virtual std::unique_ptr<Handler> handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) = 0;
//! Return pointer to internal wallet class, useful for testing.
virtual CWallet* wallet() { return nullptr; }
};
//! Wallet chain client that in addition to having chain client methods for
//! starting up, shutting down, and registering RPCs, also has additional
//! methods (called by the GUI) to load and create wallets.
class WalletClient : public ChainClient
{
public:
//! Create new wallet.
virtual std::unique_ptr<Wallet> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings) = 0;
//! Load existing wallet.
virtual std::unique_ptr<Wallet> loadWallet(const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings) = 0;
//! Return default wallet directory.
virtual std::string getWalletDir() = 0;
//! Return available wallets in wallet directory.
virtual std::vector<std::string> listWalletDir() = 0;
//! Return interfaces for accessing wallets (if any).
virtual std::vector<std::unique_ptr<Wallet>> getWallets() = 0;
//! Register handler for load wallet messages. This callback is triggered by
//! createWallet and loadWallet above, and also triggered when wallets are
//! loaded at startup or by RPC.
using LoadWalletFn = std::function<void(std::unique_ptr<Wallet> wallet)>;
virtual std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) = 0;
};
//! Information about one wallet address.
struct WalletAddress
{
CTxDestination dest;
isminetype is_mine;
std::string name;
std::string purpose;
WalletAddress(CTxDestination dest, isminetype is_mine, std::string name, std::string purpose)
: dest(std::move(dest)), is_mine(is_mine), name(std::move(name)), purpose(std::move(purpose))
{
}
};
//! Collection of wallet balances.
struct WalletBalances
{
CAmount balance = 0;
CAmount unconfirmed_balance = 0;
CAmount immature_balance = 0;
bool have_watch_only = false;
CAmount watch_only_balance = 0;
CAmount unconfirmed_watch_only_balance = 0;
CAmount immature_watch_only_balance = 0;
bool balanceChanged(const WalletBalances& prev) const
{
return balance != prev.balance || unconfirmed_balance != prev.unconfirmed_balance ||
immature_balance != prev.immature_balance || watch_only_balance != prev.watch_only_balance ||
unconfirmed_watch_only_balance != prev.unconfirmed_watch_only_balance ||
immature_watch_only_balance != prev.immature_watch_only_balance;
}
};
// Wallet transaction information.
struct WalletTx
{
CTransactionRef tx;
std::vector<isminetype> txin_is_mine;
std::vector<isminetype> txout_is_mine;
std::vector<CTxDestination> txout_address;
std::vector<isminetype> txout_address_is_mine;
CAmount credit;
CAmount debit;
CAmount change;
int64_t time;
std::map<std::string, std::string> value_map;
bool is_coinbase;
};
//! Updated transaction status.
struct WalletTxStatus
{
int block_height;
int blocks_to_maturity;
int depth_in_main_chain;
unsigned int time_received;
uint32_t lock_time;
bool is_final;
bool is_trusted;
bool is_abandoned;
bool is_coinbase;
bool is_in_main_chain;
};
//! Wallet transaction output.
struct WalletTxOut
{
CTxOut txout;
int64_t time;
int depth_in_main_chain = -1;
bool is_spent = false;
};
//! Return implementation of Wallet interface. This function is defined in
//! dummywallet.cpp and throws if the wallet component is not compiled.
std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet);
//! Return implementation of ChainClient interface for a wallet client. This
//! function will be undefined in builds where ENABLE_WALLET is false.
std::unique_ptr<WalletClient> MakeWalletClient(Chain& chain, ArgsManager& args);
} // namespace interfaces
#endif // DIGIBYTE_INTERFACES_WALLET_H