From f2a91a05f9e4ca71109b934806541714b8ddc13f Mon Sep 17 00:00:00 2001 From: timemarkovqtum Date: Mon, 24 Jun 2024 15:36:50 +0200 Subject: [PATCH] Port tx mempool --- src/interfaces/chain.h | 73 ++++++++++++++++ src/interfaces/node.h | 35 +++++++- src/node/interfaces.cpp | 131 +++++++++++++++++++++++++++- src/txmempool.cpp | 178 +++++++++++++++++++++++++++++++++++++- src/txmempool.h | 176 ++++++++++++++++++++++++++++++++++++- src/util/message.cpp | 3 +- src/util/signstr.h | 6 +- src/util/strencodings.cpp | 15 ++++ src/util/strencodings.h | 3 + src/wallet/init.cpp | 19 ++++ 10 files changed, 629 insertions(+), 10 deletions(-) diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index 9da5cb9637..045693721f 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -9,6 +9,7 @@ #include #include // For CTransactionRef #include +#include // For ConnectionDirection #include #include @@ -17,6 +18,11 @@ #include #include #include +#include + +#if defined(HAVE_CONFIG_H) +#include +#endif class ArgsManager; class CBlock; @@ -35,6 +41,17 @@ struct FeeCalculation; namespace node { struct NodeContext; } // namespace node +class ChainstateManager; +class CTxMemPool; +class CBlockIndex; +class CCoinsViewCache; + +#ifdef ENABLE_WALLET +namespace wallet { +class CWallet; +} // namespace wallet +#endif +struct Delegation; namespace interfaces { @@ -58,6 +75,8 @@ class FoundBlock 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 has delagation. + FoundBlock& hasDelegation(bool& has_delegation) { m_has_delegation = &has_delegation; 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 locator if block is in the active chain. @@ -73,6 +92,7 @@ class FoundBlock int64_t* m_time = nullptr; int64_t* m_max_time = nullptr; int64_t* m_mtp_time = nullptr; + bool* m_has_delegation = nullptr; bool* m_in_active_chain = nullptr; CBlockLocator* m_locator = nullptr; const FoundBlock* m_next_block = nullptr; @@ -125,6 +145,12 @@ class Chain public: virtual ~Chain() {} + //! Get chain state manager + virtual ChainstateManager& chainman() = 0; + + //! Get mempool + virtual const CTxMemPool& mempool() = 0; + //! Get current chain height, not including genesis block (returns 0 if //! chain only contains genesis block, nullopt if chain does not contain //! any blocks) @@ -184,6 +210,9 @@ class Chain const FoundBlock& block1_out={}, const FoundBlock& block2_out={}) = 0; + //! Get map of the immature stakes. + virtual std::map getImmatureStakes() = 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. @@ -284,6 +313,9 @@ class Chain //! Check if any block has been pruned. virtual bool havePruned() = 0; + //! Is loading blocks. + virtual bool isLoadingBlocks() = 0; + //! Check if the node is ready to broadcast transactions. virtual bool isReadyToBroadcast() = 0; @@ -364,6 +396,47 @@ class Chain //! Get internal node context. Useful for testing, but not //! accessible across processes. virtual node::NodeContext* context() { return nullptr; } + + //! Get chain tip + virtual CBlockIndex* getTip() const = 0; + + //! Get unspent outputs associated with a transaction. + virtual bool getUnspentOutput(const COutPoint& output, Coin& coin) = 0; + + //! Get coins tip. + virtual CCoinsViewCache& getCoinsTip() = 0; + + //! Get number of connections. + virtual size_t getNodeCount(ConnectionDirection flags) = 0; + + //! Get transaction gas fee. + virtual CAmount getTxGasFee(const CMutableTransaction& tx) = 0; + +#ifdef ENABLE_WALLET + //! Start staking qtums. + virtual void startStake(wallet::CWallet& wallet) = 0; + + //! Stop staking qtums. + virtual void stopStake(wallet::CWallet& wallet) = 0; + + //! get stake weight. + virtual uint64_t getStakeWeight(const wallet::CWallet& wallet, uint64_t* pStakerWeight = nullptr, uint64_t* pDelegateWeight = nullptr) = 0; + + //! refresh delegates. + virtual void refreshDelegates(wallet::CWallet *pwallet, bool myDelegates, bool stakerDelegates) = 0; + + //! get contract RPC commands. + virtual Span getContractRPCCommands() = 0; + + //! get mining RPC commands. + virtual Span getMiningRPCCommands() = 0; +#endif + + //! get delegation for an address. + virtual bool getDelegation(const uint160& address, Delegation& delegation) = 0; + + //! verify delegation for an address. + virtual bool verifyDelegation(const uint160& address, const Delegation& delegation) = 0; }; //! Interface to let node manage chain clients (wallets, or maybe tools for diff --git a/src/interfaces/node.h b/src/interfaces/node.h index aeb2612c07..fb0ddd68f3 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -84,7 +84,7 @@ class Node virtual int getExitStatus() = 0; // Get log flags. - virtual uint32_t getLogCategories() = 0; + virtual uint64_t getLogCategories() = 0; //! Initialize app dependencies. virtual bool baseInitialize() = 0; @@ -174,12 +174,21 @@ class Node //! Get last block time. virtual int64_t getLastBlockTime() = 0; + //! Get block hash. + virtual uint256 getBlockHash(int blockNumber) = 0; + + //! Get block time. + virtual int64_t getBlockTime(int blockNumber) = 0; + //! Get verification progress. virtual double getVerificationProgress() = 0; //! Is initial block download. virtual bool isInitialBlockDownload() = 0; + //! Is -addresstype set. + virtual bool isAddressTypeSet() = 0; + //! Is loading blocks. virtual bool isLoadingBlocks() = 0; @@ -189,6 +198,12 @@ class Node //! Get network active. virtual bool getNetworkActive() = 0; + //! Get node synchronization information. + virtual void getSyncInfo(int& numBlocks, bool& isSyncing) = 0; + + //! Try get node synchronization information. + virtual bool tryGetSyncInfo(int& numBlocks, bool& isSyncing) = 0; + //! Get dust relay fee. virtual CFeeRate getDustRelayFee() = 0; @@ -213,6 +228,24 @@ class Node //! Get wallet loader. virtual WalletLoader& walletLoader() = 0; + //! Get the information about the needed gas + virtual void getGasInfo(uint64_t& blockGasLimit, uint64_t& minGasPrice, uint64_t& nGasPrice) = 0; + + //! Get the reward for the block at some specific height + virtual int64_t getBlockSubsidy(int nHeight) = 0; + + //! Get the network stake weight + virtual uint64_t getNetworkStakeWeight() = 0; + + //! Get the estimated annual roi + virtual double getEstimatedAnnualROI() = 0; + + //! Get the money supply + virtual int64_t getMoneySupply() = 0; + + //! Get PoS kernel PS + virtual double getPoSKernelPS() = 0; + //! Register handler for init messages. using InitMessageFn = std::function; virtual std::unique_ptr handleInitMessage(InitMessageFn fn) = 0; diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 5a8b7fc105..dcaa02a983 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -93,7 +94,7 @@ class NodeImpl : public Node void initParameterInteraction() override { InitParameterInteraction(args()); } bilingual_str getWarnings() override { return GetWarnings(true); } int getExitStatus() override { return Assert(m_context)->exit_status.load(); } - uint32_t getLogCategories() override { return LogInstance().GetCategoryMask(); } + uint64_t getLogCategories() override { return LogInstance().GetCategoryMask(); } bool baseInitialize() override { if (!AppInitBasicSetup(args(), Assert(context())->exit_status)) return false; @@ -298,6 +299,18 @@ class NodeImpl : public Node } return chainman().GetParams().GenesisBlock().GetBlockTime(); // Genesis block's time of current network } + uint256 getBlockHash(int blockNumber) override + { + LOCK(::cs_main); + CBlockIndex* index = chainman().ActiveChain()[blockNumber]; + return index ? index->GetBlockHash() : uint256(); + } + int64_t getBlockTime(int blockNumber) override + { + LOCK(::cs_main); + CBlockIndex* index = chainman().ActiveChain()[blockNumber]; + return index ? index->GetBlockTime() : 0; + } double getVerificationProgress() override { return GuessVerificationProgress(chainman().GetParams().TxData(), WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip())); @@ -306,6 +319,7 @@ class NodeImpl : public Node { return chainman().IsInitialBlockDownload(); } + bool isAddressTypeSet() override { return !::gArgs.GetArg("-addresstype", "").empty(); } bool isLoadingBlocks() override { return chainman().m_blockman.LoadingBlocks(); } void setNetworkActive(bool active) override { @@ -346,6 +360,56 @@ class NodeImpl : public Node { return *Assert(m_context->wallet_loader); } + void getGasInfo(uint64_t& blockGasLimit, uint64_t& minGasPrice, uint64_t& nGasPrice) override + { + } + void getSyncInfo(int& numBlocks, bool& isSyncing) override + { + LOCK(::cs_main); + // Get node synchronization information with minimal locks + numBlocks = chainman().ActiveChain().Height(); + int64_t blockTime = chainman().ActiveChain().Tip() ? chainman().ActiveChain().Tip()->GetBlockTime() : + Params().GenesisBlock().GetBlockTime(); + int64_t secs = GetTime() - blockTime; + isSyncing = secs >= 90*60 ? true : false; + } + bool tryGetSyncInfo(int& numBlocks, bool& isSyncing) override + { + TRY_LOCK(::cs_main, lockMain); + if (lockMain) { + // Get node synchronization information with minimal locks + numBlocks = chainman().ActiveChain().Height(); + int64_t blockTime = chainman().ActiveChain().Tip() ? chainman().ActiveChain().Tip()->GetBlockTime() : + Params().GenesisBlock().GetBlockTime(); + int64_t secs = GetTime() - blockTime; + isSyncing = secs >= 90*60 ? true : false; + return true; + } + + return false; + } + int64_t getBlockSubsidy(int nHeight) override + { + const CChainParams& chainparams = Params(); + return GetBlockSubsidy(nHeight, chainparams.GetConsensus()); + } + uint64_t getNetworkStakeWeight() override + { + return {}; + } + double getEstimatedAnnualROI() override + { + return {}; + } + int64_t getMoneySupply() override + { + auto best_header = chainman().m_best_header; + return best_header ? best_header->nMoneySupply : 0; + } + double getPoSKernelPS() override + { + return {}; + } std::unique_ptr handleInitMessage(InitMessageFn fn) override { return MakeSignalHandler(::uiInterface.InitMessage_connect(fn)); @@ -414,6 +478,7 @@ bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLockGetBlockTime(); if (block.m_max_time) *block.m_max_time = index->GetBlockTimeMax(); if (block.m_mtp_time) *block.m_mtp_time = index->GetMedianTimePast(); + if (block.m_has_delegation) *block.m_has_delegation = index->HasProofOfDelegation(); if (block.m_in_active_chain) *block.m_in_active_chain = active[index->nHeight] == index; if (block.m_locator) { *block.m_locator = GetLocator(index); } if (block.m_next_block) FillBlock(active[index->nHeight] == index ? active[index->nHeight + 1] : nullptr, *block.m_next_block, lock, active, blockman); @@ -546,6 +611,10 @@ class ChainImpl : public Chain const CBlockIndex* index = chainman().m_blockman.LookupBlockIndex(block_hash); return GetLocator(index); } + std::map getImmatureStakes() override + { + return {}; + } std::optional findLocatorFork(const CBlockLocator& locator) override { LOCK(::cs_main); @@ -746,6 +815,7 @@ class ChainImpl : public Chain LOCK(::cs_main); return chainman().m_blockman.m_have_pruned; } + bool isLoadingBlocks() override { return chainman().m_blockman.LoadingBlocks(); } bool isReadyToBroadcast() override { return !chainman().m_blockman.LoadingBlocks() && !isInitialBlockDownload(); } bool isInitialBlockDownload() override { @@ -821,7 +891,64 @@ class ChainImpl : public Chain NodeContext* context() override { return &m_node; } ArgsManager& args() { return *Assert(m_node.args); } - ChainstateManager& chainman() { return *Assert(m_node.chainman); } + ChainstateManager& chainman() override { return *Assert(m_node.chainman); } + const CTxMemPool& mempool() override { return *Assert(m_node.mempool); } + + CBlockIndex* getTip() const override + { + LOCK(::cs_main); + CBlockIndex* tip = Assert(m_node.chainman)->ActiveChain().Tip(); + return tip; + } + bool getUnspentOutput(const COutPoint& output, Coin& coin) override + { + LOCK(::cs_main); + return chainman().ActiveChainstate().CoinsTip().GetCoin(output, coin); + } + CCoinsViewCache& getCoinsTip() override + { + LOCK(::cs_main); + return chainman().ActiveChainstate().CoinsTip(); + } + size_t getNodeCount(ConnectionDirection flags) override + { + return Assert(m_node.connman) ? m_node.connman->GetNodeCount(flags) : 0; + } + CAmount getTxGasFee(const CMutableTransaction& tx) override + { + return {}; + } +#ifdef ENABLE_WALLET + void startStake(wallet::CWallet& wallet) override + { + } + void stopStake(wallet::CWallet& wallet) override + { + } + uint64_t getStakeWeight(const wallet::CWallet& wallet, uint64_t* pStakerWeight, uint64_t* pDelegateWeight) override + { + return {}; + } + void refreshDelegates(wallet::CWallet *pwallet, bool myDelegates, bool stakerDelegates) override + { + } + Span getContractRPCCommands() override + { + return {}; + } + Span getMiningRPCCommands() override + { + return {}; + } +#endif + bool getDelegation(const uint160& address, Delegation& delegation) override + { + return {}; + } + bool verifyDelegation(const uint160& address, const Delegation& delegation) override + { + return {}; + } NodeContext& m_node; }; } // namespace diff --git a/src/txmempool.cpp b/src/txmempool.cpp index ac8e06df37..62a9e70d33 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -23,13 +23,17 @@ #include #include #include +#include #include +#include