Relay CMerkleBlocks when asked for MSG_FILTERED_BLOCK
This commit is contained in:
parent
2878c67cb5
commit
b02ddbedcb
24
src/main.cpp
24
src/main.cpp
@ -3068,7 +3068,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
if (fDebugNet || (vInv.size() == 1))
|
if (fDebugNet || (vInv.size() == 1))
|
||||||
printf("received getdata for: %s\n", inv.ToString().c_str());
|
printf("received getdata for: %s\n", inv.ToString().c_str());
|
||||||
|
|
||||||
if (inv.type == MSG_BLOCK)
|
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
|
||||||
{
|
{
|
||||||
// Send block from disk
|
// Send block from disk
|
||||||
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
|
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
|
||||||
@ -3076,7 +3076,29 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||||||
{
|
{
|
||||||
CBlock block;
|
CBlock block;
|
||||||
block.ReadFromDisk((*mi).second);
|
block.ReadFromDisk((*mi).second);
|
||||||
|
if (inv.type == MSG_BLOCK)
|
||||||
pfrom->PushMessage("block", block);
|
pfrom->PushMessage("block", block);
|
||||||
|
else // MSG_FILTERED_BLOCK)
|
||||||
|
{
|
||||||
|
LOCK(pfrom->cs_filter);
|
||||||
|
if (pfrom->pfilter)
|
||||||
|
{
|
||||||
|
CMerkleBlock merkleBlock(block, *pfrom->pfilter);
|
||||||
|
typedef boost::tuple<unsigned int, uint256, std::vector<uint256> > TupleType;
|
||||||
|
// CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
|
||||||
|
// This avoids hurting performance by pointlessly requiring a round-trip
|
||||||
|
// Note that there is currently no way for a node to request any single transactions we didnt send here -
|
||||||
|
// they must either disconnect and retry or request the full block.
|
||||||
|
// Thus, the protocol spec specified allows for us to provide duplicate txn here,
|
||||||
|
// however we MUST always provide at least what the remote peer needs
|
||||||
|
BOOST_FOREACH(TupleType& tuple, merkleBlock.vtx)
|
||||||
|
if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, get<1>(tuple))))
|
||||||
|
pfrom->PushMessage("tx", block.vtx[get<0>(tuple)]);
|
||||||
|
pfrom->PushMessage("merkleblock", merkleBlock);
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// no response
|
||||||
|
}
|
||||||
|
|
||||||
// Trigger them to send a getblocks request for the next batch of inventory
|
// Trigger them to send a getblocks request for the next batch of inventory
|
||||||
if (inv.hash == pfrom->hashContinue)
|
if (inv.hash == pfrom->hashContinue)
|
||||||
|
@ -17,6 +17,7 @@ static const char* ppszTypeName[] =
|
|||||||
"ERROR",
|
"ERROR",
|
||||||
"tx",
|
"tx",
|
||||||
"block",
|
"block",
|
||||||
|
"filtered block"
|
||||||
};
|
};
|
||||||
|
|
||||||
CMessageHeader::CMessageHeader()
|
CMessageHeader::CMessageHeader()
|
||||||
|
@ -138,6 +138,9 @@ enum
|
|||||||
{
|
{
|
||||||
MSG_TX = 1,
|
MSG_TX = 1,
|
||||||
MSG_BLOCK,
|
MSG_BLOCK,
|
||||||
|
// Nodes may always request a MSG_FILTERED_BLOCK in a getdata, however,
|
||||||
|
// MSG_FILTERED_BLOCK should not appear in any invs except as a part of getdata.
|
||||||
|
MSG_FILTERED_BLOCK,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __INCLUDED_PROTOCOL_H__
|
#endif // __INCLUDED_PROTOCOL_H__
|
||||||
|
Loading…
Reference in New Issue
Block a user