Skip to content

Commit 9c837d5

Browse files
committed
Add sender-side protocol implementation for CMPCTBLOCK stuff
1 parent 00c4078 commit 9c837d5

File tree

1 file changed

+95
-15
lines changed

1 file changed

+95
-15
lines changed

src/main.cpp

Lines changed: 95 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,10 @@ struct CNodeState {
274274
bool fPreferredDownload;
275275
//! Whether this peer wants invs or headers (when possible) for block announcements.
276276
bool fPreferHeaders;
277+
//! Whether this peer wants invs or cmpctblocks (when possible) for block announcements.
278+
bool fPreferHeaderAndIDs;
279+
//! Whether this peer will send us cmpctblocks if we request them
280+
bool fProvidesHeaderAndIDs;
277281

278282
CNodeState() {
279283
fCurrentlyConnected = false;
@@ -290,6 +294,8 @@ struct CNodeState {
290294
nBlocksInFlightValidHeaders = 0;
291295
fPreferredDownload = false;
292296
fPreferHeaders = false;
297+
fPreferHeaderAndIDs = false;
298+
fProvidesHeaderAndIDs = false;
293299
}
294300
};
295301

@@ -4454,7 +4460,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
44544460
boost::this_thread::interruption_point();
44554461
it++;
44564462

4457-
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
4463+
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK || inv.type == MSG_CMPCT_BLOCK)
44584464
{
44594465
bool send = false;
44604466
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
@@ -4496,7 +4502,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
44964502
assert(!"cannot load block from disk");
44974503
if (inv.type == MSG_BLOCK)
44984504
pfrom->PushMessage(NetMsgType::BLOCK, block);
4499-
else // MSG_FILTERED_BLOCK)
4505+
else if (inv.type == MSG_FILTERED_BLOCK)
45004506
{
45014507
LOCK(pfrom->cs_filter);
45024508
if (pfrom->pfilter)
@@ -4516,6 +4522,18 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
45164522
// else
45174523
// no response
45184524
}
4525+
else if (inv.type == MSG_CMPCT_BLOCK)
4526+
{
4527+
// If a peer is asking for old blocks, we're almost guaranteed
4528+
// they wont have a useful mempool to match against a compact block,
4529+
// and we dont feel like constructing the object for them, so
4530+
// instead we respond with the full, non-compact block.
4531+
if (mi->second->nHeight >= chainActive.Height() - 10) {
4532+
CBlockHeaderAndShortTxIDs cmpctblock(block);
4533+
pfrom->PushMessage(NetMsgType::CMPCTBLOCK, cmpctblock);
4534+
} else
4535+
pfrom->PushMessage(NetMsgType::BLOCK, block);
4536+
}
45194537

45204538
// Trigger the peer node to send a getblocks request for the next batch of inventory
45214539
if (inv.hash == pfrom->hashContinue)
@@ -4839,6 +4857,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
48394857
State(pfrom->GetId())->fPreferHeaders = true;
48404858
}
48414859

4860+
else if (strCommand == NetMsgType::SENDCMPCT)
4861+
{
4862+
bool fAnnounceUsingCMPCTBLOCK = false;
4863+
uint64_t nCMPCTBLOCKVersion = 1;
4864+
vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
4865+
if (nCMPCTBLOCKVersion == 1) {
4866+
LOCK(cs_main);
4867+
State(pfrom->GetId())->fProvidesHeaderAndIDs = true;
4868+
State(pfrom->GetId())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK;
4869+
}
4870+
}
4871+
48424872

48434873
else if (strCommand == NetMsgType::INV)
48444874
{
@@ -4982,6 +5012,39 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
49825012
}
49835013

49845014

5015+
else if (strCommand == NetMsgType::GETBLOCKTXN)
5016+
{
5017+
BlockTransactionsRequest req;
5018+
vRecv >> req;
5019+
5020+
BlockMap::iterator it = mapBlockIndex.find(req.blockhash);
5021+
if (it == mapBlockIndex.end() || !(it->second->nStatus & BLOCK_HAVE_DATA)) {
5022+
Misbehaving(pfrom->GetId(), 100);
5023+
LogPrintf("Peer %d sent us a getblocktxn for a block we don't have", pfrom->id);
5024+
return true;
5025+
}
5026+
5027+
if (it->second->nHeight < chainActive.Height() - 10) {
5028+
LogPrint("net", "Peer %d sent us a getblocktxn for a block > 10 deep", pfrom->id);
5029+
return true;
5030+
}
5031+
5032+
CBlock block;
5033+
assert(ReadBlockFromDisk(block, it->second, chainparams.GetConsensus()));
5034+
5035+
BlockTransactions resp(req);
5036+
for (size_t i = 0; i < req.indexes.size(); i++) {
5037+
if (req.indexes[i] >= block.vtx.size()) {
5038+
Misbehaving(pfrom->GetId(), 100);
5039+
LogPrintf("Peer %d sent us a getblocktxn with out-of-bounds tx indices", pfrom->id);
5040+
return true;
5041+
}
5042+
resp.txn[i] = block.vtx[req.indexes[i]];
5043+
}
5044+
pfrom->PushMessage(NetMsgType::BLOCKTXN, resp);
5045+
}
5046+
5047+
49855048
else if (strCommand == NetMsgType::GETHEADERS)
49865049
{
49875050
CBlockLocator locator;
@@ -5824,7 +5887,9 @@ bool SendMessages(CNode* pto)
58245887
// add all to the inv queue.
58255888
LOCK(pto->cs_inventory);
58265889
vector<CBlock> vHeaders;
5827-
bool fRevertToInv = (!state.fPreferHeaders || pto->vBlockHashesToAnnounce.size() > MAX_BLOCKS_TO_ANNOUNCE);
5890+
bool fRevertToInv = ((!state.fPreferHeaders &&
5891+
(!state.fPreferHeaderAndIDs || pto->vBlockHashesToAnnounce.size() > 1)) ||
5892+
pto->vBlockHashesToAnnounce.size() > MAX_BLOCKS_TO_ANNOUNCE);
58285893
CBlockIndex *pBestIndex = NULL; // last header queued for delivery
58295894
ProcessBlockAvailability(pto->id); // ensure pindexBestKnownBlock is up-to-date
58305895

@@ -5876,6 +5941,33 @@ bool SendMessages(CNode* pto)
58765941
}
58775942
}
58785943
}
5944+
if (!fRevertToInv && !vHeaders.empty()) {
5945+
if (vHeaders.size() == 1 && state.fPreferHeaderAndIDs) {
5946+
// We only send up to 1 block as header-and-ids, as otherwise
5947+
// probably means we're doing an initial-ish-sync or they're slow
5948+
LogPrint("net", "%s sending header-and-ids %s to peer %d\n", __func__,
5949+
vHeaders.front().GetHash().ToString(), pto->id);
5950+
//TODO: Shouldn't need to reload block from disk, but requires refactor
5951+
CBlock block;
5952+
assert(ReadBlockFromDisk(block, pBestIndex, consensusParams));
5953+
CBlockHeaderAndShortTxIDs cmpctblock(block);
5954+
pto->PushMessage(NetMsgType::CMPCTBLOCK, cmpctblock);
5955+
state.pindexBestHeaderSent = pBestIndex;
5956+
} else if (state.fPreferHeaders) {
5957+
if (vHeaders.size() > 1) {
5958+
LogPrint("net", "%s: %u headers, range (%s, %s), to peer=%d\n", __func__,
5959+
vHeaders.size(),
5960+
vHeaders.front().GetHash().ToString(),
5961+
vHeaders.back().GetHash().ToString(), pto->id);
5962+
} else {
5963+
LogPrint("net", "%s: sending header %s to peer=%d\n", __func__,
5964+
vHeaders.front().GetHash().ToString(), pto->id);
5965+
}
5966+
pto->PushMessage(NetMsgType::HEADERS, vHeaders);
5967+
state.pindexBestHeaderSent = pBestIndex;
5968+
} else
5969+
fRevertToInv = true;
5970+
}
58795971
if (fRevertToInv) {
58805972
// If falling back to using an inv, just try to inv the tip.
58815973
// The last entry in vBlockHashesToAnnounce was our tip at some point
@@ -5901,18 +5993,6 @@ bool SendMessages(CNode* pto)
59015993
pto->id, hashToAnnounce.ToString());
59025994
}
59035995
}
5904-
} else if (!vHeaders.empty()) {
5905-
if (vHeaders.size() > 1) {
5906-
LogPrint("net", "%s: %u headers, range (%s, %s), to peer=%d\n", __func__,
5907-
vHeaders.size(),
5908-
vHeaders.front().GetHash().ToString(),
5909-
vHeaders.back().GetHash().ToString(), pto->id);
5910-
} else {
5911-
LogPrint("net", "%s: sending header %s to peer=%d\n", __func__,
5912-
vHeaders.front().GetHash().ToString(), pto->id);
5913-
}
5914-
pto->PushMessage(NetMsgType::HEADERS, vHeaders);
5915-
state.pindexBestHeaderSent = pBestIndex;
59165996
}
59175997
pto->vBlockHashesToAnnounce.clear();
59185998
}

0 commit comments

Comments
 (0)