aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorMatt Corallo <git@bluematt.me>2012-08-18 23:45:19 -0400
committerMatt Corallo <git@bluematt.me>2013-01-16 12:48:02 -0500
commitb02ddbedcba4f9d86b1aabeb71fe18ec03f9a41a (patch)
tree95b8b58eb53300a67d47b2419f218a1269de1ca8 /src/main.cpp
parent2878c67cb5e19c6ea8a013b606e82339c8fb8209 (diff)
Relay CMerkleBlocks when asked for MSG_FILTERED_BLOCK
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/main.cpp b/src/main.cpp
index bd5b2408a0..abb0174edd 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3068,7 +3068,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (fDebugNet || (vInv.size() == 1))
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
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
@@ -3076,7 +3076,29 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
CBlock block;
block.ReadFromDisk((*mi).second);
- pfrom->PushMessage("block", block);
+ if (inv.type == MSG_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
if (inv.hash == pfrom->hashContinue)