// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-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. #ifndef BITCOIN_NET_PROCESSING_H #define BITCOIN_NET_PROCESSING_H #include #include #include #include class CChainParams; class CTxMemPool; class ChainstateManager; extern RecursiveMutex cs_main; extern RecursiveMutex g_cs_orphans; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default number of orphan+recently-replaced txn to keep around for block reconstruction */ static const unsigned int DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN = 100; static const bool DEFAULT_PEERBLOOMFILTERS = false; static const bool DEFAULT_PEERBLOCKFILTERS = false; /** Threshold for marking a node to be discouraged, e.g. disconnected and added to the discouragement filter. */ static const int DISCOURAGEMENT_THRESHOLD{100}; class PeerLogicValidation final : public CValidationInterface, public NetEventsInterface { public: PeerLogicValidation(CConnman& connman, BanMan* banman, CScheduler& scheduler, ChainstateManager& chainman, CTxMemPool& pool); /** * Overridden from CValidationInterface. */ void BlockConnected(const std::shared_ptr& pblock, const CBlockIndex* pindexConnected) override; void BlockDisconnected(const std::shared_ptr &block, const CBlockIndex* pindex) override; /** * Overridden from CValidationInterface. */ void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override; /** * Overridden from CValidationInterface. */ void BlockChecked(const CBlock& block, const BlockValidationState& state) override; /** * Overridden from CValidationInterface. */ void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr& pblock) override; /** Initialize a peer by adding it to mapNodeState and pushing a message requesting its version */ void InitializeNode(CNode* pnode) override; /** Handle removal of a peer by updating various state and removing it from mapNodeState */ void FinalizeNode(NodeId nodeid, bool& fUpdateConnectionTime) override; /** * Process protocol messages received from a given node * * @param[in] pfrom The node which we have received messages from. * @param[in] interrupt Interrupt condition for processing threads */ bool ProcessMessages(CNode* pfrom, std::atomic& interrupt) override; /** * Send queued protocol messages to be sent to a give node. * * @param[in] pto The node which we are sending messages to. * @return True if there is more work to be done */ bool SendMessages(CNode* pto) override EXCLUSIVE_LOCKS_REQUIRED(pto->cs_sendProcessing); /** Consider evicting an outbound peer based on the amount of time they've been behind our tip */ void ConsiderEviction(CNode& pto, int64_t time_in_seconds) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** Evict extra outbound peers. If we think our tip may be stale, connect to an extra outbound */ void CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams); /** If we have extra outbound peers, try to disconnect the one with the oldest block announcement */ void EvictExtraOutboundPeers(int64_t time_in_seconds) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** Retrieve unbroadcast transactions from the mempool and reattempt sending to peers */ void ReattemptInitialBroadcast(CScheduler& scheduler) const; /** Process a single message from a peer. Public for fuzz testing */ void ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataStream& vRecv, const std::chrono::microseconds time_received, const CChainParams& chainparams, const std::atomic& interruptMsgProc); private: /** Maybe disconnect a peer and discourage future connections from its address. * * @param[in] pnode The node to check. * @return True if the peer was marked for disconnection in this function */ bool MaybeDiscourageAndDisconnect(CNode& pnode); CConnman& m_connman; /** Pointer to this node's banman. May be nullptr - check existence before dereferencing. */ BanMan* const m_banman; ChainstateManager& m_chainman; CTxMemPool& m_mempool; int64_t m_stale_tip_check_time; //!< Next time to check for stale tip }; struct CNodeStateStats { int m_misbehavior_score = 0; int nSyncHeight = -1; int nCommonHeight = -1; std::vector vHeightInFlight; }; /** Get statistics from node state */ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats); /** Relay transaction to every node */ void RelayTransaction(const uint256& txid, const uint256& wtxid, const CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(cs_main); #endif // BITCOIN_NET_PROCESSING_H