## Block Broadcasting - Unsolicited Block Push

1

Can someone, please, direct me to the source code section(s) relevant for an Unsolicited Block Push as described in the Bitcoin Developer Guide?

I've been going through main.cpp and searched for the term MSG_BLOCK, serving as a beagle for finding the correct place in the code.
But as I'm reading further, it seems to me as if a freshly mined block is not appended to a inventory message, with MSG_BLOCK, in order to send it as a "package" as response to a request (GetData Response) BUT is sent as a single message of this structure:

To me, up to now, the best canditate for Unsolicited Block Push seems to be main.cpp#L2393 part of main.cpp but I'm confused since I don't know if there is more of possibly relevant code (like main.cpp#L3830) for Unsolicited Block Push in /src/.

2

We can find all instances in the code where the client will send a block message by searching for PushMessage("block". This is the only match:

void static ProcessGetData(CNode* pfrom)
{
[...]
pfrom->PushMessage("block", block);


(Source.)

This means that the standard client only ever sends a block message when specifically asked for it. That incoming getdata message is probably triggered in turn by sending the remote node an inv message. (Though that's not necessary - you can ask for a block that the other node hasn't advertised.) This is the code that sends inventory messages:

//
// Message: inventory
//
vector<CInv> vInv;
vector<CInv> vInvWait;
{
LOCK(pto->cs_inventory);
vInv.reserve(pto->vInventoryToSend.size());
vInvWait.reserve(pto->vInventoryToSend.size());
BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
{
// If the other node already knows the message, don't send
if (pto->setInventoryKnown.count(inv))
continue;

// trickle out tx inv to protect privacy
[...]

// returns true if remote node hasn't seen it
if (pto->setInventoryKnown.insert(inv).second)
{
// Add to the list of inventory messages to send
vInv.push_back(inv);
// If there's 1000 inventory messages queued up, send them
// (Protocol limit is 50000 at a time.)
if (vInv.size() >= 1000)
{
pto->PushMessage("inv", vInv);
vInv.clear();
}
}
}
pto->vInventoryToSend = vInvWait;
}
// Send any that are left over.
if (!vInv.empty())
pto->PushMessage("inv", vInv);


(Source.)

(pto represents the remote node in the above code.)

So the page you're looking at describes a behavior that you could implement, and that other clients will accept, but it doesn't describe the current core client behavior.

2

"describes a behavior that you could implement, and that other clients will accept, but it doesn't describe the current core client behavior." I wrote the docs linked above, and I didn't realize that wasn't obvious. Sorry. It should be updated shortly: https://github.com/bitcoin/bitcoin.org/commit/b847610e1b129a85b3fd00c251b97864f2f89781

– David A. Harding – 2015-06-05T18:15:52.017

1@DavidA.Harding That was fast. :) – Nick ODell – 2015-06-05T18:16:41.707

@NickODell: Thanks, Nick! One thing is still not completely clear. You say: "This means that the standard client only ever sends a block message when specifically asked for it. That incoming getdata message is probably triggered in turn by sending the remote node an inv message." - does this mean: (1) node1 & node2 are both at height n on a common active chain (2) node1 is faster and finds a block n+1 and pushes it to an inv message and sends this inv message to node2 and gets a getdata message from node2 asking for block n+1 (3) node1 sends a single block message with block n+1 ? – Aliakbar Ahmadi – 2015-06-06T13:57:50.037

@AliakbarAhmadi Yes. – Nick ODell – 2015-06-06T14:48:02.820

@NickODell: Ok but in what case will a unsolicited single block message be broadcasted to peers then??? Never? Is a freshly mined block sent unsolicitedly only inside an inv message? – Aliakbar Ahmadi – 2015-06-06T15:08:17.193

@AliakbarAhmadi Never. Unless you modify your client. – Nick ODell – 2015-06-06T15:09:33.523