Hi,

not sure if headergolf was mentioned yet. It's about very similar ideas: 
https://github.com/alecalve/headergolf









‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Friday, May 8, 2020 2:31 PM, Will Clark via bitcoin-dev 
<bitcoin-dev@lists.linuxfoundation.org> wrote:

> Hello list,
>
> I would like to propose a compressed block header scheme for IBD and block 
> announcements. This proposal is derivative of previous proposals found on 
> this list (see links in spec below) with some modifications and 
> clarifications.
>
> The below specification (also found at 
> https://github.com/willcl-ark/compressed-block-headers/blob/v1.0/compressed-block-headers.adoc
>  ) details the compression recommended along with the generated bandwidth 
> savings in the best-case scenario.
>
> I look forward to any feedback anyone has to offer on the specification 
> itself, as well as any additions or objections to the motivation.
>
> Cheers,
> Will
>
> = Compressed block headers
> Will Clark will8cl...@gmail.com
> v1.0, May 2020:
> :toc: preamble
> :toclevels: 4
>
> This work is a derivation of these mailing list posts:
>
> 1.  
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-August/014876.html[bitcoin-dev:
>  "Compressed" headers stream - 2017] (with resurrection 
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-December/015385.html[here])
> 2.  
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-March/015851.html[bitcoin-dev:
>  Optimized Header Sync]
>
>     '''
>
>     == Motivation
>
>     Block headers as exchanged by nodes over the p2p network are currently 81 
> bytes each.
>
>     For low bandwidth nodes who are doing a headers-only sync, reducing the 
> size of the headers can provide a significant bandwidth saving. Also, nodes 
> can support more header-only peers for IBD and protection against eclipse 
> attacks if header bandwidth is reduced.
>
>     === Background
>
>     Currently headers are sent over the p2p network as a vector of 
> `block_headers`, which are composed of the following sized fields:
>
>     [cols="<,>"]
>
>
> |===
> |Field |Size
>
> |Version |4 bytes
> |Previous block hash |32 bytes
> |Merkle root hash |32 bytes
> |Time |4 bytes
> |nBits |4 bytes
> |nonce |4 bytes
> |txn_count |1 byte
> |Total |81 bytes
> |===
>
> Some fields can be removed completely, others can be compressed under certain 
> conditions.
>
> == Proposed specification
>
> === block_header2 data type
>
> The following table illustrates the proposed `block_header2` data type 
> specification.
>
> [cols="<,>,>"]
> |===
> |Field |Size |Compressed
>
> |Bitfield |1 byte | 1 byte
> |Version |4 bytes |0 \| 4 bytes
> |Previous block hash |32 bytes |0 \| 32 bytes
> |Merkle root hash |32 bytes |32 bytes
> |Time |4 bytes |2 \| 4 bytes
> |nBits |4 bytes |0 \| 4 bytes
> |nonce |4 bytes |4 bytes
> |Total |81 bytes |range: 39 - 81 bytes
> |===
>
> This compression results in a maximum reduction from an 81 byte header to 
> best-case 39 byte header. With 629,474 blocks in the current blockchain, a 
> continuous header sync from genesis (requiring a single full 81 byte header 
> followed by only compressed `block_header2`) has been tested to have its 
> required bandwidth reduced from 50.98MB down to 25.86MB, a saving of 49%.
>
> ==== Bitfield
>
> To make parsing of header messages easier and further increase header 
> compression, a single byte bitfield was suggested by gmaxwell 
> footnote:[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-December/015397.html].
>  We propose the following amended bitfield meanings (bits re-ordered to match 
> `headers2` field order):
>
> [cols="<,<"]
> |===
> |Bit |Meaning + field size to read
>
> |0 +
> 1 +
> 2 |version: same as the last distinct value 1st ... 7th (0 byte field) or a 
> new 32bit distinct value (4 byte field).
> |3 |prev_block_hash: is omitted (0 byte field) or included (32 byte field)
> |4 |timestamp: as small offset (2 byte field) or full (4 byte field).
> |5 |nbits: same as last header (0 byte field) or new (4 byte field).
> |6 |possibly to signal "more headers follow" to make the encoding 
> self-delimiting.
> |7 |currently undefined
> |===
>
> This bitfield adds 1 byte for every block in the chain, for a current total 
> increase of 629,474B.
>
> ==== Version
>
> In most cases the Version field will be identical to one referenced in one of 
> the previous 7 unique versions, as indicated by bits 0,1,2 of the Bitfield.
>
> To block 629,474 there were 616,137 blocks whose version was in the previous 
> 7 distinct versions, and only 13,338 blocks whose version was not, this 
> includes any version bit manipulation done via overt ASIC boost.
>
> [cols=">,>,>,>"]
> |===
> |Genesis to block |Current (B) |Compressed (B) |Saving (%)
>
> |629,474 |2,517,896 |53,352 |98
> |===
>
> ==== Previous block hash
>
> The previous block hash will always be the
> `SHA256(SHA256(<previous_header>))` so is redundant, presuming you have the 
> previous header in the chain.
>
> [cols=">,>,>,>"]
> |===
> |Genesis to block |Current (B) |Compressed (B) |Saving (%)
>
> |629,474 |20,143,168 |0 |100
> |===
>
> ==== Time
>
> The timestamp (in seconds) is consensus bound, based both on the time in the 
> previous
> header: `MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60 = 7200`, and being greater than 
> the `MedianTimePast` of the previous 11 blocks. Therefore this can be safely 
> represented as an offset from the previous headers' timestamp using a 2 byte 
> `signed short int`.
>
> [cols=">,>,>,>"]
> |===
> |Genesis to block |Current (B) |Compressed (B) |Saving (%)
>
> |629,474 |2,517,896 |1,258,952 |50
> |===
>
> ==== nBits
>
> nBits currently changes once every 2016 blocks. It could be entirely 
> calculated by the client from the timestamps of the previous 2015 blocks 
> footnote:[2015 blocks are used in the adjustment calculation due to an 
> off-by-one error: 
> https://bitcointalk.org/index.php?topic=43692.msg521772#msg521772";].
>
> To simplify 'light' client implementations which would otherwise require 
> consensus-valid calculation of the adjustments, we propose to transmit this 
> according to the <<Bitfield>> specification above.
>
> To block 629,474 there have been 298 nBits adjustments (vs an expected 311 -- 
> there was none before block 32,256).
>
> [cols=">,>,>,>"]
> |===
> |Genesis to block |Current (B) |Compressed (B) |Saving (%)
>
> |629,474 |2,517,896 |1,196 |99.6
> |===
>
> ==== txn_count
>
> txn_count is included to make parsing of these messages compatible with 
> parsing of `block` messages 
> footnote:[https://bitcoin.stackexchange.com/questions/2104/why-is-the-block-header-txn-count-field-always-zero].
>  Therefore this field and its associated byte can be removed for transmission 
> of compact headers.
>
> [cols=">,>,>,>"]
> |===
> |Genesis to block |Current (B) |Compressed (B) |Saving (%)
>
> |629,474 |629,474 |0 |100
> |===
>
> === Service Bit
>
> A new service bit would be required so that the nodes can advertise their 
> ability to supply compact headers.
>
> === P2P Messages
>
> Three new messages would be used by nodes that enable compact block header 
> support, two query messages: `getheaders2` and `sendheaders2` and one 
> response: `headers2`.
>
> ==== `getheaders2` -- Requesting compact headers
>
> The new p2p message required to request compact block headers would require 
> the same fields as the current `getheaders` message:
>
> [cols=">,<,<,<"]
> |===
> |Field Size |Description |Data type |Comments
>
> |4 |version |uint32_t |the protocol version
> |1+ |hash count |var_int |number of block locator hash entries
> |32+ |block locator hashes |char[32] |block locator object; newest back to 
> genesis block (dense to start, but then sparse)
> |32 |hash_stop |char[32] |hash of the last desired block header; set to zero 
> to get as many blocks as possible (2000)
> |===
>
> ==== `sendheaders2` -- Request compact header announcements
>
> Since 
> https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki[BIP-130], 
> nodes have been able to request to receive new headers directly in `headers` 
> messages, rather than via an `inv` of the new block hash and subsequent 
> `getheader` request and `headers` response (followed by a final `getdata` to 
> get the tip block itself, if desired). This is requested by transmitting an 
> empty `sendheaders` message after the version handshake is complete.]
>
> Upon receipt of this message, the node is permitted, but not required, to 
> preemptively announce new headers with the `headers2` message (instead of 
> `inv`). Preemptive header announcement is supported by the protocol version ≥ 
> 70012 | Bitcoin Core version ≥ 0.12.0.
>
> For the motivational use-case it makes sense to also update this mechanism to 
> support sending header updates using compact headers using a new message.
>
> ==== `headers2` -- Receiving compact headers
>
> A `headers2` message is returned in response to `getheaders2` or at new 
> header announcement following a `sendheaders2` request. It contains both 
> `length` and `headers` fields. The `headers` field contains a variable length 
> vector of `block_header2`:
>
> |===
> |Field Size |Description |Data type |Comments
>
> |1+ |length |var_int |Length of `headers`
> |39-81x? |headers |block_header2[] |Compressed block headers in 
> <<block_header2 data type>> format
> |===
>
> === Implementation
>
> -   The first header in the first `block_header2[]` vector to a 
> newly-connected client MUST contain the full 
> nBits`,`timestamp`,`version`and`prev_block_hash`fields, along with a 
> correctly populated`bitfield` byte.
>
> -   Subsequent headers in a contiguous vector SHOULD follow the compressed 
> <<block_header2 data type>> format.
>
> -   Subsequent compressed headers supplied to an already-connected client 
> (requesting compressed headers), SHOULD follow the compressed <<block_header2 
> data type>> format.
>
>
> bitcoin-dev mailing list
> bitcoin-dev@lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


_______________________________________________
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev

Reply via email to