diff --git a/src/net.h b/src/net.h index 8cc4da3db..77649247d 100644 --- a/src/net.h +++ b/src/net.h @@ -1199,17 +1199,6 @@ public: return nLocalServices; } - bool SupportsMWEB() const noexcept { return (nLocalServices & NODE_MWEB); } - - uint64_t GetCmpctBlockVersion() const noexcept - { - if (nLocalServices & NODE_MWEB) { - return 3; - } - - return (nLocalServices & NODE_WITNESS) ? 2 : 1; - } - std::string GetAddrName() const; //! Sets the addrName only if it was not previously set void MaybeSetAddrName(const std::string& addrNameIn); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 8ee530608..3c75a8a1c 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -339,6 +339,17 @@ struct CNodeState { */ bool fSupportsDesiredCmpctVersion; + int GetCmpctBlockVersion() + { + if (fWantsCmpctMWEB) { + return 3; + } else if (fWantsCmpctWitness) { + return 2; + } else { + return 1; + } + } + /** State used to enforce CHAIN_SYNC_TIMEOUT and EXTRA_PEER_CHECK_INTERVAL logic. * * Both are only in effect for outbound, non-manual, non-protected connections. @@ -641,7 +652,7 @@ static void MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid, CConnman& connma } connman.ForNode(nodeid, [&connman](CNode* pfrom) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { AssertLockHeld(::cs_main); - uint64_t nCMPCTBLOCKVersion = pfrom->GetCmpctBlockVersion(); + uint64_t nCMPCTBLOCKVersion = State(pfrom->GetId())->GetCmpctBlockVersion(); if (lNodesAnnouncingHeaderAndIDs.size() >= 3) { // As per BIP152, we only get 3 of our peers to announce // blocks using compact encodings. @@ -1349,6 +1360,10 @@ void PeerManager::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockInde const int nNewHeight = pindexNew->nHeight; m_connman.SetBestHeight(nNewHeight); + if (!GetDesireMWEBFlag() && IsMWEBEnabled(pindexNew, m_chainparams.GetConsensus())) { + SetDesireMWEBFlag(true); + } + SetServiceFlagsIBDCache(!fInitialDownload); if (!fInitialDownload) { // Find the hashes of all blocks that weren't previously in the best chain. @@ -1727,7 +1742,7 @@ void static ProcessGetData(CNode& pfrom, Peer& peer, const CChainParams& chainpa CTransactionRef tx = FindTxForGetData(mempool, pfrom, ToGenTxid(inv), mempool_req, now); if (tx) { // WTX and WITNESS_TX imply we serialize with witness - int nSendFlags = (inv.IsMsgTx() ? SERIALIZE_TRANSACTION_NO_WITNESS | SERIALIZE_NO_MWEB : (pfrom.SupportsMWEB() ? 0 : SERIALIZE_NO_MWEB)); + int nSendFlags = (inv.IsMsgTx() ? SERIALIZE_TRANSACTION_NO_WITNESS | SERIALIZE_NO_MWEB : (State(pfrom.GetId())->fHaveMWEB ? 0 : SERIALIZE_NO_MWEB)); connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::TX, *tx)); mempool.RemoveUnbroadcastTx(tx->GetHash()); // As we're going to send tx, make sure its unconfirmed parents are made requestable. @@ -3214,7 +3229,7 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat LOCK(cs_main); CBlockIndex* pTip = ::ChainActive().Tip(); assert(pTip); - if (!IsMWEBEnabled(pTip->pprev, m_chainparams.GetConsensus()) && !State(pfrom.GetId())->fWantsCmpctMWEB) { + if (!State(pfrom.GetId())->fWantsCmpctMWEB) { vRecv.SetVersion(vRecv.GetVersion() | SERIALIZE_NO_MWEB); } } @@ -3300,7 +3315,7 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat if (!fAlreadyInFlight && !CanDirectFetch(m_chainparams.GetConsensus())) return; - if (IsWitnessEnabled(pindex->pprev, m_chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) { + if (IsWitnessEnabled(pindex->pprev, m_chainparams.GetConsensus()) && !nodestate->fWantsCmpctWitness) { // Don't bother trying to process compact blocks from v1 peers // after segwit activates. return; diff --git a/src/protocol.cpp b/src/protocol.cpp index 44da30ea2..722c84a5b 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -10,6 +10,7 @@ #include static std::atomic g_initial_block_download_completed(false); +static std::atomic g_desire_mweb_flag(false); namespace NetMsgType { const char *VERSION="version"; @@ -137,16 +138,20 @@ bool CMessageHeader::IsCommandValid() const ServiceFlags GetDesirableServiceFlags(ServiceFlags services) { + ServiceFlags mweb_flags = g_desire_mweb_flag ? NODE_MWEB : NODE_NONE; if ((services & NODE_NETWORK_LIMITED) && g_initial_block_download_completed) { - return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS | NODE_MWEB); + return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS | mweb_flags); } - return ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_MWEB); + return ServiceFlags(NODE_NETWORK | NODE_WITNESS | mweb_flags); } void SetServiceFlagsIBDCache(bool state) { g_initial_block_download_completed = state; } +bool GetDesireMWEBFlag() { return g_desire_mweb_flag; } +void SetDesireMWEBFlag(const bool val) { g_desire_mweb_flag = val; } + CInv::CInv() { type = 0; diff --git a/src/protocol.h b/src/protocol.h index 6879580ae..b4f7f78c3 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -340,6 +340,9 @@ ServiceFlags GetDesirableServiceFlags(ServiceFlags services); /** Set the current IBD status in order to figure out the desirable service flags */ void SetServiceFlagsIBDCache(bool status); +bool GetDesireMWEBFlag(); +void SetDesireMWEBFlag(const bool val); + /** * A shortcut for (services & GetDesirableServiceFlags(services)) * == GetDesirableServiceFlags(services), ie determines whether the given