Skip to content

Commit b02ddbe

Browse files
committed
Relay CMerkleBlocks when asked for MSG_FILTERED_BLOCK
1 parent 2878c67 commit b02ddbe

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

src/main.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3068,15 +3068,37 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
30683068
if (fDebugNet || (vInv.size() == 1))
30693069
printf("received getdata for: %s\n", inv.ToString().c_str());
30703070

3071-
if (inv.type == MSG_BLOCK)
3071+
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
30723072
{
30733073
// Send block from disk
30743074
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
30753075
if (mi != mapBlockIndex.end())
30763076
{
30773077
CBlock block;
30783078
block.ReadFromDisk((*mi).second);
3079-
pfrom->PushMessage("block", block);
3079+
if (inv.type == MSG_BLOCK)
3080+
pfrom->PushMessage("block", block);
3081+
else // MSG_FILTERED_BLOCK)
3082+
{
3083+
LOCK(pfrom->cs_filter);
3084+
if (pfrom->pfilter)
3085+
{
3086+
CMerkleBlock merkleBlock(block, *pfrom->pfilter);
3087+
typedef boost::tuple<unsigned int, uint256, std::vector<uint256> > TupleType;
3088+
// CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
3089+
// This avoids hurting performance by pointlessly requiring a round-trip
3090+
// Note that there is currently no way for a node to request any single transactions we didnt send here -
3091+
// they must either disconnect and retry or request the full block.
3092+
// Thus, the protocol spec specified allows for us to provide duplicate txn here,
3093+
// however we MUST always provide at least what the remote peer needs
3094+
BOOST_FOREACH(TupleType& tuple, merkleBlock.vtx)
3095+
if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, get<1>(tuple))))
3096+
pfrom->PushMessage("tx", block.vtx[get<0>(tuple)]);
3097+
pfrom->PushMessage("merkleblock", merkleBlock);
3098+
}
3099+
// else
3100+
// no response
3101+
}
30803102

30813103
// Trigger them to send a getblocks request for the next batch of inventory
30823104
if (inv.hash == pfrom->hashContinue)

src/protocol.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ static const char* ppszTypeName[] =
1717
"ERROR",
1818
"tx",
1919
"block",
20+
"filtered block"
2021
};
2122

2223
CMessageHeader::CMessageHeader()

src/protocol.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ enum
138138
{
139139
MSG_TX = 1,
140140
MSG_BLOCK,
141+
// Nodes may always request a MSG_FILTERED_BLOCK in a getdata, however,
142+
// MSG_FILTERED_BLOCK should not appear in any invs except as a part of getdata.
143+
MSG_FILTERED_BLOCK,
141144
};
142145

143146
#endif // __INCLUDED_PROTOCOL_H__

0 commit comments

Comments
 (0)