Skip to content

Commit b8a9749

Browse files
committed
BIP144: Handshake and relay (receiver side)
Service bit logic by Nicolas Dorier. Only download blocks from witness peers after fork.
1 parent 8b49040 commit b8a9749

File tree

6 files changed

+60
-9
lines changed

6 files changed

+60
-9
lines changed

src/init.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,18 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
13771377
}
13781378
}
13791379

1380+
if (Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0) {
1381+
// Only advertize witness capabilities if they have a reasonable start time.
1382+
// This allows us to have the code merged without a defined softfork, by setting its
1383+
// end time to 0.
1384+
// Note that setting NODE_WITNESS is never required: the only downside from not
1385+
// doing so is that after activation, no upgraded nodes will fetch from you.
1386+
nLocalServices = ServiceFlags(nLocalServices | NODE_WITNESS);
1387+
// Only care about others providing witness capabilities if there is a softfork
1388+
// defined.
1389+
nRelevantServices = ServiceFlags(nRelevantServices | NODE_WITNESS);
1390+
}
1391+
13801392
// ********************************************************* Step 10: import blocks
13811393

13821394
if (mapArgs.count("-blocknotify"))

src/main.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ struct CNodeState {
313313
fPreferHeaders = false;
314314
fPreferHeaderAndIDs = false;
315315
fProvidesHeaderAndIDs = false;
316+
fHaveWitness = false;
316317
}
317318
};
318319

@@ -4812,6 +4813,14 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
48124813
}
48134814
}
48144815

4816+
uint32_t GetFetchFlags(CNode* pfrom, CBlockIndex* pprev, const Consensus::Params& chainparams) {
4817+
uint32_t nFetchFlags = 0;
4818+
if (IsWitnessEnabled(pprev, chainparams) && State(pfrom->GetId())->fHaveWitness) {
4819+
nFetchFlags |= MSG_WITNESS_FLAG;
4820+
}
4821+
return nFetchFlags;
4822+
}
4823+
48154824
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams)
48164825
{
48174826
LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
@@ -4918,6 +4927,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
49184927

49194928
pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
49204929

4930+
if((pfrom->nServices & NODE_WITNESS))
4931+
{
4932+
LOCK(cs_main);
4933+
State(pfrom->GetId())->fHaveWitness = true;
4934+
}
4935+
49214936
// Potentially mark this peer as a preferred download peer.
49224937
{
49234938
LOCK(cs_main);
@@ -5119,17 +5134,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
51195134

51205135
LOCK(cs_main);
51215136

5137+
uint32_t nFetchFlags = GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus());
5138+
51225139
std::vector<CInv> vToFetch;
51235140

51245141
for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
51255142
{
5126-
const CInv &inv = vInv[nInv];
5143+
CInv &inv = vInv[nInv];
51275144

51285145
boost::this_thread::interruption_point();
51295146

51305147
bool fAlreadyHave = AlreadyHave(inv);
51315148
LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
51325149

5150+
if (inv.type == MSG_TX) {
5151+
inv.type |= nFetchFlags;
5152+
}
5153+
51335154
if (inv.type == MSG_BLOCK) {
51345155
UpdateBlockAvailability(pfrom->GetId(), inv.hash);
51355156
if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
@@ -5144,7 +5165,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
51445165
pfrom->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), inv.hash);
51455166
CNodeState *nodestate = State(pfrom->GetId());
51465167
if (CanDirectFetch(chainparams.GetConsensus()) &&
5147-
nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
5168+
nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER &&
5169+
(!IsWitnessEnabled(chainActive.Tip(), chainparams.GetConsensus()) || State(pfrom->GetId())->fHaveWitness)) {
5170+
inv.type |= nFetchFlags;
51485171
if (nodestate->fProvidesHeaderAndIDs)
51495172
vToFetch.push_back(CInv(MSG_CMPCT_BLOCK, inv.hash));
51505173
else
@@ -5730,7 +5753,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
57305753
// Calculate all the blocks we'd need to switch to pindexLast, up to a limit.
57315754
while (pindexWalk && !chainActive.Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
57325755
if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
5733-
!mapBlocksInFlight.count(pindexWalk->GetBlockHash())) {
5756+
!mapBlocksInFlight.count(pindexWalk->GetBlockHash()) &&
5757+
(!IsWitnessEnabled(pindexWalk->pprev, chainparams.GetConsensus()) || State(pfrom->GetId())->fHaveWitness)) {
57345758
// We don't have this block, and it's not yet in flight.
57355759
vToFetch.push_back(pindexWalk);
57365760
}
@@ -5752,7 +5776,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
57525776
// Can't download any more from this peer
57535777
break;
57545778
}
5755-
vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
5779+
uint32_t nFetchFlags = GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus());
5780+
vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash()));
57565781
MarkBlockAsInFlight(pfrom->GetId(), pindex->GetBlockHash(), chainparams.GetConsensus(), pindex);
57575782
LogPrint("net", "Requesting block %s from peer=%d\n",
57585783
pindex->GetBlockHash().ToString(), pfrom->id);
@@ -6598,10 +6623,13 @@ bool SendMessages(CNode* pto)
65986623
NodeId staller = -1;
65996624
FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
66006625
BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
6601-
vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
6602-
MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
6603-
LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
6604-
pindex->nHeight, pto->id);
6626+
if (State(pto->GetId())->fHaveWitness || !IsWitnessEnabled(pindex->pprev, consensusParams)) {
6627+
uint32_t nFetchFlags = GetFetchFlags(pto, pindex->pprev, consensusParams);
6628+
vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash()));
6629+
MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
6630+
LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
6631+
pindex->nHeight, pto->id);
6632+
}
66056633
}
66066634
if (state.nBlocksInFlight == 0 && staller != -1) {
66076635
if (State(staller)->nStallingSince == 0) {

src/net.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ namespace {
7272
const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
7373

7474
/** Services this node implementation cares about */
75-
static const ServiceFlags nRelevantServices = NODE_NETWORK;
75+
ServiceFlags nRelevantServices = NODE_NETWORK;
7676

7777
//
7878
// Global state variables
@@ -1676,6 +1676,10 @@ void ThreadOpenConnections()
16761676
if (nANow - addr.nLastTry < 600 && nTries < 30)
16771677
continue;
16781678

1679+
// only consider nodes missing relevant services after 40 failed attemps
1680+
if ((addr.nServices & nRelevantServices) != nRelevantServices && nTries < 40)
1681+
continue;
1682+
16791683
// do not allow non-default ports, unless after 50 invalid addresses selected already
16801684
if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
16811685
continue;

src/net.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
156156
extern bool fDiscover;
157157
extern bool fListen;
158158
extern ServiceFlags nLocalServices;
159+
extern ServiceFlags nRelevantServices;
159160
extern bool fRelayTxes;
160161
extern uint64_t nLocalHostNonce;
161162
extern CAddrMan addrman;

src/protocol.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@ enum ServiceFlags : uint64_t {
264264
// Bitcoin Core nodes used to support this by default, without advertising this bit,
265265
// but no longer do as of protocol version 70011 (= NO_BLOOM_VERSION)
266266
NODE_BLOOM = (1 << 2),
267+
// Indicates that a node can be asked for blocks and transactions including
268+
// witness data.
269+
NODE_WITNESS = (1 << 3),
267270

268271
// Bits 24-31 are reserved for temporary experiments. Just pick a bit that
269272
// isn't getting used, or one not being used much, and notify the

src/qt/guiutil.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,9 @@ QString formatServicesStr(quint64 mask)
909909
case NODE_BLOOM:
910910
strList.append("BLOOM");
911911
break;
912+
case NODE_WITNESS:
913+
strList.append("WITNESS");
914+
break;
912915
default:
913916
strList.append(QString("%1[%2]").arg("UNKNOWN").arg(check));
914917
}

0 commit comments

Comments
 (0)