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
heightas follows. Forheightin the range {1 .. 16}, the encoding is a single byte of value0x50+height. Otherwise, letheightBytesbe the signed little-endian representation ofheight, using the minimum nonzero number of bytes such that the most significant byte is <0x80. The length ofheightBytesMUST be in the range {1 .. 5}. Then the encoding is the length ofheightBytesencoded as one byte, followed byheightBytesitself. 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.