pub(crate) fn parse_coinbase_height(
    mut data: Vec<u8>,
) -> Result<(block::Height, CoinbaseData), SerializationError> {
    use block::Height;
    match (data.get(0), data.len()) {
        // Blocks 1 through 16 inclusive encode block height with OP_N opcodes.
        (Some(op_n @ 0x51..=0x60), len) if len >= 1 => Ok((
            Height((op_n - 0x50) as u32),
            CoinbaseData(data.split_off(1)),
        )),
        // Blocks 17 through 128 exclusive encode block height with the `0x01` opcode.
        // The Bitcoin encoding requires that the most significant byte is below 0x80.
        (Some(0x01), len) if len >= 2 && data[1] < 0x80 => {
            let h = data[1] as u32;
            if (17..128).contains(&h) {
                Ok((Height(h), CoinbaseData(data.split_off(2))))
            } else {
                Err(SerializationError::Parse("Invalid block height"))
            }
        }
        // Blocks 128 through 32768 exclusive encode block height with the `0x02` opcode.
        // The Bitcoin encoding requires that the most significant byte is below 0x80.
        (Some(0x02), len) if len >= 3 && data[2] < 0x80 => {
            let h = data[1] as u32 + ((data[2] as u32) << 8);
            if (128..32_768).contains(&h) {
                Ok((Height(h), CoinbaseData(data.split_off(3))))
            } else {
                Err(SerializationError::Parse("Invalid block height"))
            }
        }
        // Blocks 32768 through 2**23 exclusive encode block height with the `0x03` opcode.
        // The Bitcoin encoding requires that the most significant byte is below 0x80.
        (Some(0x03), len) if len >= 4 && data[3] < 0x80 => {
            let h = data[1] as u32 + ((data[2] as u32) << 8) + ((data[3] as u32) << 16);
            if (32_768..8_388_608).contains(&h) {
                Ok((Height(h), CoinbaseData(data.split_off(4))))
            } else {
                Err(SerializationError::Parse("Invalid block height"))
            }
        }
        // The genesis block does not encode the block height by mistake; special case it.
        // The first five bytes are [4, 255, 255, 7, 31], the little-endian encoding of
        // 520_617_983.
        //
        // In the far future, Zcash might reach this height, and the miner might use the
        // same coinbase data as the genesis block. So we need an updated consensus rule
        // to handle this edge case.
        //
        // TODO: update this check based on the consensus rule changes in
        //       https://github.com/zcash/zips/issues/540
        (Some(0x04), _) if data[..] == GENESIS_COINBASE_DATA[..] => {
            Ok((Height(0), CoinbaseData(data)))
        }
        // As noted above, this is included for completeness.
        // The Bitcoin encoding requires that the most significant byte is below 0x80.
        (Some(0x04), len) if len >= 5 && data[4] < 0x80 => {
            let h = data[1] as u32
                + ((data[2] as u32) << 8)
                + ((data[3] as u32) << 16)
                + ((data[4] as u32) << 24);
            if (8_388_608..=Height::MAX.0).contains(&h) {
                Ok((Height(h), CoinbaseData(data.split_off(5))))
            } else {
                Err(SerializationError::Parse("Invalid block height"))
            }
        }
        _ => Err(SerializationError::Parse(
            "Could not parse BIP34 height in coinbase data",
        )),
    }
}
/// Split `data` into a block height and remaining miner-controlled coinbase data.
///
/// The height may consume `0..=5` bytes at the stat of the coinbase data.
/// The genesis block does not include an encoded coinbase height.
Split `data` into a block height and remaining miner-controlled coinbase data.
The height may consume `0..=5` bytes at the stat of the coinbase data.
The genesis block does not include an encoded coinbase height.
Split ` data ` into a block height and remaining miner - controlled coinbase data . The height may consume ` 0 .. = 5 ` bytes at the stat of the coinbase data . The genesis block does not include an encoded coinbase height .
pub(crate) fn parse_coinbase_height(
    mut data: Vec<u8>,
) -> Result<(block::Height, CoinbaseData), SerializationError> {
    use block::Height;
    match (data.get(0), data.len()) {
        // Blocks 1 through 16 inclusive encode block height with OP_N opcodes.
        (Some(op_n @ 0x51..=0x60), len) if len >= 1 => Ok((
            Height((op_n - 0x50) as u32),
            CoinbaseData(data.split_off(1)),
        )),
        // Blocks 17 through 128 exclusive encode block height with the `0x01` opcode.
        // The Bitcoin encoding requires that the most significant byte is below 0x80.
        (Some(0x01), len) if len >= 2 && data[1] < 0x80 => {
            let h = data[1] as u32;
            if (17..128).contains(&h) {
                Ok((Height(h), CoinbaseData(data.split_off(2))))
            } else {
                Err(SerializationError::Parse("Invalid block height"))
            }
        }
        // Blocks 128 through 32768 exclusive encode block height with the `0x02` opcode.
        // The Bitcoin encoding requires that the most significant byte is below 0x80.
        (Some(0x02), len) if len >= 3 && data[2] < 0x80 => {
            let h = data[1] as u32 + ((data[2] as u32) << 8);
            if (128..32_768).contains(&h) {
                Ok((Height(h), CoinbaseData(data.split_off(3))))
            } else {
                Err(SerializationError::Parse("Invalid block height"))
            }
        }
        // Blocks 32768 through 2**23 exclusive encode block height with the `0x03` opcode.
        // The Bitcoin encoding requires that the most significant byte is below 0x80.
        (Some(0x03), len) if len >= 4 && data[3] < 0x80 => {
            let h = data[1] as u32 + ((data[2] as u32) << 8) + ((data[3] as u32) << 16);
            if (32_768..8_388_608).contains(&h) {
                Ok((Height(h), CoinbaseData(data.split_off(4))))
            } else {
                Err(SerializationError::Parse("Invalid block height"))
            }
        }
        // The genesis block does not encode the block height by mistake; special case it.
        // The first five bytes are [4, 255, 255, 7, 31], the little-endian encoding of
        // 520_617_983.
        //
        // In the far future, Zcash might reach this height, and the miner might use the
        // same coinbase data as the genesis block. So we need an updated consensus rule
        // to handle this edge case.
        //
        // TODO: update this check based on the consensus rule changes in
        //       https://github.com/zcash/zips/issues/540
        (Some(0x04), _) if data[..] == GENESIS_COINBASE_DATA[..] => {
            Ok((Height(0), CoinbaseData(data)))
        }
        // As noted above, this is included for completeness.
        // The Bitcoin encoding requires that the most significant byte is below 0x80.
        (Some(0x04), len) if len >= 5 && data[4] < 0x80 => {
            let h = data[1] as u32
                + ((data[2] as u32) << 8)
                + ((data[3] as u32) << 16)
                + ((data[4] as u32) << 24);
            if (8_388_608..=Height::MAX.0).contains(&h) {
                Ok((Height(h), CoinbaseData(data.split_off(5))))
            } else {
                Err(SerializationError::Parse("Invalid block height"))
            }
        }
        _ => Err(SerializationError::Parse(
            "Could not parse BIP34 height in coinbase data",
        )),
    }
}
pub ( crate ) fn parse_coinbase_height ( mut data : Vec < u8 > , ) -> Result < ( block :: Height , CoinbaseData ) , SerializationError > { use block :: Height ; match ( data . get ( 0 ) , data . len ( ) ) { // Blocks 1 through 16 inclusive encode block height with OP_N opcodes. ( Some ( op_n @ 0x51 ..= 0x60 ) , len ) if len >= 1 => Ok ( ( Height ( ( op_n - 0x50 ) as u32 ) , CoinbaseData ( data . split_off ( 1 ) ) , ) ) , // Blocks 17 through 128 exclusive encode block height with the `0x01` opcode. // The Bitcoin encoding requires that the most significant byte is below 0x80. ( Some ( 0x01 ) , len ) if len >= 2 && data [ 1 ] < 0x80 => { let h = data [ 1 ] as u32 ; if ( 17 .. 128 ) . contains ( & h ) { Ok ( ( Height ( h ) , CoinbaseData ( data . split_off ( 2 ) ) ) ) } else { Err ( SerializationError :: Parse ( " " ) ) } } // Blocks 128 through 32768 exclusive encode block height with the `0x02` opcode. // The Bitcoin encoding requires that the most significant byte is below 0x80. ( Some ( 0x02 ) , len ) if len >= 3 && data [ 2 ] < 0x80 => { let h = data [ 1 ] as u32 + ( ( data [ 2 ] as u32 ) << 8 ) ; if ( 128 .. 32_768 ) . contains ( & h ) { Ok ( ( Height ( h ) , CoinbaseData ( data . split_off ( 3 ) ) ) ) } else { Err ( SerializationError :: Parse ( " " ) ) } } // Blocks 32768 through 2**23 exclusive encode block height with the `0x03` opcode. // The Bitcoin encoding requires that the most significant byte is below 0x80. ( Some ( 0x03 ) , len ) if len >= 4 && data [ 3 ] < 0x80 => { let h = data [ 1 ] as u32 + ( ( data [ 2 ] as u32 ) << 8 ) + ( ( data [ 3 ] as u32 ) << 16 ) ; if ( 32_768 .. 8_388_608 ) . contains ( & h ) { Ok ( ( Height ( h ) , CoinbaseData ( data . split_off ( 4 ) ) ) ) } else { Err ( SerializationError :: Parse ( " " ) ) } } // The genesis block does not encode the block height by mistake; special case it. // The first five bytes are [4, 255, 255, 7, 31], the little-endian encoding of // 520_617_983. // // In the far future, Zcash might reach this height, and the miner might use the // same coinbase data as the genesis block. So we need an updated consensus rule // to handle this edge case. // // TODO: update this check based on the consensus rule changes in //       https://github.com/zcash/zips/issues/540 ( Some ( 0x04 ) , _ ) if data [ .. ] == GENESIS_COINBASE_DATA [ .. ] => { Ok ( ( Height ( 0 ) , CoinbaseData ( data ) ) ) } // As noted above, this is included for completeness. // The Bitcoin encoding requires that the most significant byte is below 0x80. ( Some ( 0x04 ) , len ) if len >= 5 && data [ 4 ] < 0x80 => { let h = data [ 1 ] as u32 + ( ( data [ 2 ] as u32 ) << 8 ) + ( ( data [ 3 ] as u32 ) << 16 ) + ( ( data [ 4 ] as u32 ) << 24 ) ; if ( 8_388_608 ..= Height :: MAX . 0 ) . contains ( & h ) { Ok ( ( Height ( h ) , CoinbaseData ( data . split_off ( 5 ) ) ) ) } else { Err ( SerializationError :: Parse ( " " ) ) } } _ => Err ( SerializationError :: Parse ( " " , ) ) , } }
Split `data` into a block height and remaining miner-controlled coinbase data.
Split ` data ` into a block height and remaining miner - controlled coinbase data .
data
Vec<u8>