Grin: Is there any good solution for slimming the block header?

Created on 19 Sep 2018  路  6Comments  路  Source: mimblewimble/grin

for better tracking of this discussion which started at dev meeting of 18th Sep, I create this issue for us.

Current format of a Block Header:

| Field | Description | Size |
|:-------------|:-------------|:-----|
| version | Version of the block | 2 bytes |
| - | - | - |
| height | Height of this block since the genesis block (height 0) | 8 bytes |
| timestamp | Timestamp at which the block was built | 8 bytes |
| total_difficulty | Total accumulated difficulty since genesis block | 8 bytes |
| output_mmr_size | Total size of the output MMR after applying this block. | 8 bytes |
| kernel_mmr_size | Total size of the kernel MMR after applying this block. | 8 bytes |
| nonce | Nonce increment used to mine this block. | 8 bytes |
| scaling_difficulty | Difficulty scaling factor between the different proofs of work. | 8 bytes |
| - | - | - |
| previous | Hash of the block previous to this in the chain | 32 bytes |
| output_root | Merkle root of all the commitments in the TxHashSet | 32 bytes |
| range_proof_root | Merkle root of all range proofs in the TxHashSet | 32 bytes |
| kernel_root | Merkle root of all transaction kernels in the TxHashSet | 32 bytes |
| total_kernel_offset | Total accumulated sum of kernel offsets since genesis block. | 32 bytes |
| total_kernel_sum | Total accumulated sum of kernel commitments since genesis block. | 33 bytes |
| - | - | - |
| pow | Proof of work data | in case cuckoo 30: 154 bytes.
cuckoo_size: 1byte
cuckoo_solution: 42*29bits=153bytes |
| | | Total: 405 bytes |

Note: it was 397 bytes before the hard fork of T3, without the scaling_difficulty parameter.

405 bytes block header is several times compared to some other chains for example Bitcoin block header 80 bytes. We're discussing if there's any feasible solution to have a slim block header for Grin.

question research

All 6 comments

It would be great to add this in a document in /doc

@kargakis Block Header format? it's already in Wiki: https://github.com/mimblewimble/docs/wiki/Block-Header , no need to put into /doc .

Related - #1568.

I think somebody mentioned not necessarily needing the height in the serialized header as you _know_ locally the height is simply prev_height+1.

This got me thinking - maybe its worth (at some point) having different serialization strategies for

  • over the wire, vs.
  • local persistence

Height would be ommitted when transmitting the header "over the wire" to another peer.
But locally we would persist it with the height included.

Maybe there are other fields we can do this for?
total_difficulty comes to mind - instead of verifying the value is correct (by reproducing the calculation locally) we would not include it when sending the header. And the receiver would fill it in and then verify it was indeed correct via the overall hash (which should still match).

@antiochp Bitcoin does this for several of their data structures (see SER_NETWORK, SER_DISK, SER_GETHASH in https://github.com/bitcoin/bitcoin/blob/master/src/serialize.h). From working with bitcoin's code, I've found that having multiple serialization modes can lead to slightly messier code.

More importantly, I've also found not having height for a block header can lead to additional complexity during forks and in cases where blocks are received from peers that point to previous headers that are not yet in your local chain state (where do you store them temporarily? What index do you use, since you don't yet know the height? How do you know when it's safe to discard them? etc.) They're all solvable problems, but not without increasing code complexity.

In the end, it only offers the potential to reduce bandwidth usage during initial sync of 8 bytes per header, ~400KB for a year's worth of blocks. Just my $.02

Closing, no active discussions for a while

Was this page helpful?
0 / 5 - 0 ratings