diff --git a/src/init.cpp b/src/init.cpp index fa131288d8..87c5127189 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1852,6 +1852,8 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA nLocalServices = ServiceFlags(nLocalServices | NODE_WITNESS); } + nLocalServices = ServiceFlags(nLocalServices | NODE_MWEB); + // ********************************************************* Step 11: import blocks if (!CheckDiskSpace(GetDataDir())) { diff --git a/src/net.h b/src/net.h index 77649247d9..7776db4f69 100644 --- a/src/net.h +++ b/src/net.h @@ -1199,6 +1199,8 @@ public: return nLocalServices; } + bool SupportsMWEB() const noexcept { return (nLocalServices & NODE_MWEB); } + 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 f123238866..22228fd399 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -327,6 +327,8 @@ struct CNodeState { bool fProvidesHeaderAndIDs; //! Whether this peer can give us witnesses bool fHaveWitness; + //! Whether this peer can give us MWEB data + bool fHaveMWEB; //! Whether this peer wants witnesses in cmpctblocks/blocktxns bool fWantsCmpctWitness; /** @@ -407,6 +409,7 @@ struct CNodeState { fPreferHeaderAndIDs = false; fProvidesHeaderAndIDs = false; fHaveWitness = false; + fHaveMWEB = false; fWantsCmpctWitness = false; fSupportsDesiredCmpctVersion = false; m_chain_sync = { 0, nullptr, false, false }; @@ -736,6 +739,10 @@ static void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vec // We wouldn't download this block or its descendants from this peer. return; } + if (!State(nodeid)->fHaveMWEB && IsMWEBEnabled(pindex->pprev, consensusParams)) { + // MWEB: Can't download this block from this peer. + return; + } if (pindex->nStatus & BLOCK_HAVE_DATA || ::ChainActive().Contains(pindex)) { if (pindex->HaveTxsDownloaded()) state->pindexLastCommonBlock = pindex; @@ -1698,7 +1705,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 : 0); + int nSendFlags = (inv.IsMsgTx() ? SERIALIZE_TRANSACTION_NO_WITNESS | SERIALIZE_NO_MWEB : (pfrom.SupportsMWEB() ? 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. @@ -1887,7 +1894,8 @@ void PeerManager::ProcessHeadersMessage(CNode& pfrom, const std::vectornStatus & BLOCK_HAVE_DATA) && !mapBlocksInFlight.count(pindexWalk->GetBlockHash()) && - (!IsWitnessEnabled(pindexWalk->pprev, m_chainparams.GetConsensus()) || State(pfrom.GetId())->fHaveWitness)) { + (!IsWitnessEnabled(pindexWalk->pprev, m_chainparams.GetConsensus()) || State(pfrom.GetId())->fHaveWitness) && + (!IsMWEBEnabled(pindexWalk->pprev, m_chainparams.GetConsensus()) || State(pfrom.GetId())->fHaveMWEB)) { // We don't have this block, and it's not yet in flight. vToFetch.push_back(pindexWalk); } @@ -2401,6 +2409,10 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat { LOCK(cs_main); State(pfrom.GetId())->fHaveWitness = true; + + if (nServices & NODE_MWEB) { + State(pfrom.GetId())->fHaveMWEB = true; + } } // Potentially mark this peer as a preferred download peer. diff --git a/src/protocol.cpp b/src/protocol.cpp index dc8f795a0c..2a994c7a7a 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -137,9 +137,9 @@ bool CMessageHeader::IsCommandValid() const ServiceFlags GetDesirableServiceFlags(ServiceFlags services) { if ((services & NODE_NETWORK_LIMITED) && g_initial_block_download_completed) { - return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS); + return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS | NODE_MWEB); } - return ServiceFlags(NODE_NETWORK | NODE_WITNESS); + return ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_MWEB); } void SetServiceFlagsIBDCache(bool state) { @@ -208,6 +208,7 @@ static std::string serviceFlagToStr(size_t bit) case NODE_WITNESS: return "WITNESS"; case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS"; case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED"; + case NODE_MWEB: return "MWEB"; // Not using default, so we get warned when a case is missing } diff --git a/src/protocol.h b/src/protocol.h index 309fac621c..4d9906091b 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -291,8 +291,11 @@ enum ServiceFlags : uint64_t { // serving the last 288 (2 day) blocks // See BIP159 for details on how this is implemented. NODE_NETWORK_LIMITED = (1 << 10), + // NODE_MWEB indicates that a node can be asked for blocks and transactions including + // MWEB data. + NODE_MWEB = (1 << 24) - // Bits 24-31 are reserved for temporary experiments. Just pick a bit that + // Bits 25-31 are reserved for temporary experiments. Just pick a bit that // isn't getting used, or one not being used much, and notify the // bitcoin-development mailing list. Remember that service bits are just // unauthenticated advertisements, so your code must be robust against