MWEB: P2P: Allow sync from non-MWEB peers before MWEB activation

This commit is contained in:
David Burkett 2022-01-30 20:23:20 -05:00 committed by Loshan T
parent 17b65055ba
commit 493e8288ab
4 changed files with 29 additions and 17 deletions

View File

@ -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);

View File

@ -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;

View File

@ -10,6 +10,7 @@
#include <util/system.h>
static std::atomic<bool> g_initial_block_download_completed(false);
static std::atomic<bool> 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;

View File

@ -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