1

I was able to follow the code to validation.cpp:

// Size limits
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_BASE_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_BASE_SIZE)
    return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed");

and serialize.h:

template <typename T>
size_t GetSerializeSize(const T& t, int nType, int nVersion = 0)
{
    return (CSizeComputer(nType, nVersion) << t).size();
}

But for the life of me I can't figure out what CSizeComputer is doing. Does GetSerializeSize include the block header in the value it returns?

Murch
  • 75,206
  • 34
  • 186
  • 622
Rich Apodaca
  • 2,361
  • 2
  • 15
  • 34

1 Answers1

3

CSizeComputer is a serialization stream that discards all data written, and just counts how many bytes were produced. It is inlined, and the compiler in most cases actually avoids computing the bytes.

So, GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) just computes how many bytes would be produced when serializing a block for the network ignoring witnesses.

As blocks on the network indeed are prefixed by their header (and transaction count), those do contribute towards the maximum block size.

Pieter Wuille
  • 105,497
  • 9
  • 194
  • 308