Missing exactly one transaction after "merkleblock"-message

+3 votes


I've come across an "issue" where after a "merkleblock"-message Multichain leaves out exactly one of transactions in the following "tx"-messages. I'm not sure whether this is intended behavior and I just misunderstood the Bitcoin documentation or an actual problem.

Here's the setup:
I'm using Multichain as a single full node in combination with a browser based Bitcoin SPV node (bcoin).
When the SPV node creates and announces a new unconfirmed transaction Multichain receives, validates and adds it to the next block as expected. Multichain proceeds to announce the new block ("inv"-message) and the SPV node requests it ("getdata"-message) as should be. In response, Multichain sends a "merkleblock"-message to the SPV node as well as separate "tx"-messages for all but one transaction of the newly created block.

From the Bitcoin documentation [1]:
The merkleblock message is a reply to a getdata message which requested a block using the inventory type MSG_MERKLEBLOCK. It is only part of the reply: if any matching transactions are found, they will be sent separately as tx messages.

And from [2]:
After a merkleblock, transactions matching the bloom filter are automatically sent in tx messages.

Since I didn't set a bloom filter I expected one "tx"-message for every transaction that is included in the block. However, Multichain leaves out exactly one of those transactions.
I've noticed that the missing transaction is always the one the SPV node announced earlier. My best guess here is that Multichain assumes the SPV node won't need that transaction a second time since it announced it in the first place? Is this intended behavior by Multichain or am I missing something here?

Thanks in advance and best regards

[1] https://bitcoin.org/en/developer-reference#merkleblock
[2] https://en.bitcoin.it/wiki/Protocol_documentation#filterload.2C_filteradd.2C_filterclear.2C_merkleblock

asked May 4, 2020 by anonymous

1 Answer

0 votes
Best answer

You are right. MultiChain doesn't send back transactions received from the SPV node. This behaviour is identical to that of Bitcoin (at least 0.10 Multichain was forked from). This is a comment I see in the source code:

// 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

I see exactly the same comment in the latest Bitcoin code here:


But looking at the code,  I suspect this comment is no longer true and all transactions are returned. So, if you see different behaviour from Bitcoin and it returns all transactions, this behavior was changed in the latest versions.




answered May 5, 2020 by Michael