Skip to main content

parse_coinbase_height

Function parse_coinbase_height 

Source
pub(crate) fn parse_coinbase_height(
    script_sig: &[u8],
) -> Result<(Height, Vec<u8>), SerializationError>
Expand description

Parses the BIP-34 block-height prefix of a non-genesis coinbase script and returns the height along with the trailing miner data. Also enforces the coinbase script length bound, since every production parse path for coinbase inputs goes through this function.

§Consensus

A coinbase transaction script MUST have length in {2 .. 100} bytes.

A coinbase transaction for a block at block height greater than 0 MUST have a script that, as its first item, encodes the block height height as follows. For height in the range {1 .. 16}, the encoding is a single byte of value 0x50 + height. Otherwise, let heightBytes be the signed little-endian representation of height, using the minimum nonzero number of bytes such that the most significant byte is < 0x80. The length of heightBytes MUST be in the range {1 .. 5}. Then the encoding is the length of heightBytes encoded as one byte, followed by heightBytes itself. This matches the encoding used by Bitcoin in the implementation of BIP-34 (but the description here is to be considered normative).

https://zips.z.cash/protocol/protocol.pdf#txnconsensus

§Strategy

Rather than parsing the height bytes ourselves, we read a candidate height directly off the wire (using the prefix shape to locate the bytes), then re-encode it via zcash_script::pattern::push_num — the same primitive used by [zcash_transparent::bundle::TxIn::coinbase] to build coinbase inputs — and require byte-exact equality. Any non-canonical input (wrong shape, non-minimal length, oversize, negative, signed-bit games) fails this check.