pub struct Blake2bV2Header {Show 16 fields
pub version: u32,
pub prev_block_hash: BlockHash,
pub merkle_root: [u8; 32],
pub time_on_wire: u32,
pub bits: u32,
pub nonce: u32,
pub nonce2: u32,
pub nonce3: u32,
pub extranonce: [u8; 16],
pub time_offset: u32,
pub tx_count: u16,
pub flags: u8,
pub xor_key_mask_clear_bits: u8,
pub xor_key: [u8; 16],
pub height: u32,
pub mm_rhs: [u8; 32],
}Expand description
The 164-byte header used from the BLAKE2b fork height — on a sidestr chain
beside a BLAKE2b parent, from height 0 (siding/lib/overlay.mjs:
blake2bHeight: 0).
The layout below is the kernel’s knots:BlockHeaderV2 struct with its
field comments adapted. The first 80 bytes keep the classic layout
(version with bit 31 set; the wire time may be offset); proof of work is
the BLAKE2b construction over a commitment tree of these fields, not
SHA-256d of the bytes.
| offset | size | field | wire |
|---|---|---|---|
| 0 | 4 | version | u32le, bit 31 set |
| 4 | 32 | prev_block_hash | hash256 |
| 36 | 32 | merkle_root | hash256 |
| 68 | 4 | time_on_wire | u32le |
| 72 | 4 | bits | u32le |
| 76 | 4 | nonce | u32le |
| 80 | 4 | nonce2 | u32le |
| 84 | 4 | nonce3 | u32le |
| 88 | 16 | extranonce | bytes, wire order |
| 104 | 4 | time_offset | u32le |
| 108 | 2 | tx_count | u16le |
| 110 | 1 | flags | u8 |
| 111 | 1 | xor_key_mask_clear_bits | u8 |
| 112 | 16 | xor_key | bytes, wire order |
| 128 | 4 | height | i32le |
| 132 | 32 | mm_rhs | hash256 |
Beside a BLAKE2b parent siding’s buildBlock sets version = 0xa000_0000, every nonce, the extranonce, the XOR key and mm_rhs to
zero, flags = 0, tx_count to the block’s transaction count and
height to the block’s height; only nonce moves while the block is
sealed against powLimit.
use sidestr_header::{Blake2bV2Header, fork};
// txbt4 block 150,308, the fork block: the first v2 / BLAKE2b header.
// Captured from a Knots 29.4.1 node (bitcoin-desktop/schema test vectors).
let bytes = hex::decode(
"000000a0ccb157caa788400a667f6c19858ee913c701a42c8d1cd85122ec17000000000043d2e57990429ae581621ce01aa5fbf5e4c2723996be18660a4930b91e96d6c871b4946affff001dce0ac801d123881f71b4946a00000000b10cf00d0100000000000000000000008e00000000000000000000000000000000000000244b02000000000000000000000000000000000000000000000000000000000000000000",
).unwrap();
let h = Blake2bV2Header::decode(&bytes).unwrap();
assert_eq!(h.height, fork::TXBT4_FORK_HEIGHT);
assert_eq!(h.hash(), fork::TXBT4_FORK_HASH);
assert_eq!(h.tx_count, 142);
assert_eq!(h.flags, 0); // ASIC profile 0, no time offset
assert_eq!(h.encode().as_slice(), bytes.as_slice());Fields§
§version: u32Raw wire version: bit 31 set marks a v2 header; the low bits carry the usual version.
prev_block_hash: BlockHashThe previous block’s hash.
merkle_root: [u8; 32]The transaction merkle root in wire (internal) order.
time_on_wire: u32Block time as serialised. The consensus time is time_on_wire + time_offset when flags bit 2 is set; see Self::time.
bits: u32Compact proof-of-work target.
nonce: u32The first nonce.
nonce2: u32The second nonce.
nonce3: u32The third nonce.
extranonce: [u8; 16]128-bit extranonce, wire order (bitcoind’s RPC shows it byte-reversed).
time_offset: u32The offset added to time_on_wire when flags bit 2 is set; also a
nonce input to the second BLAKE2b round.
tx_count: u16Committed transaction count; must equal the block’s transaction count
(knots:rule-block-txcount).
flags: u8Bits 0–1: ASIC layout profile; bit 2: time offset in use; bits 6–7 reserved for future hardforks (must be 0).
xor_key_mask_clear_bits: u8How many leading bits of the PoW XOR mask are cleared.
xor_key: [u8; 16]128-bit PoW XOR key, wire order.
height: u32Committed height; must equal the previous header’s height + 1
(knots:rule-header-height). Serialised i32le; held unsigned.
mm_rhs: [u8; 32]Merge-mining hook right-hand side, wire order (reserved; all zeros so far).
Implementations§
Source§impl Blake2bV2Header
impl Blake2bV2Header
Sourcepub fn decode(bytes: &[u8]) -> Result<Self, Error>
pub fn decode(bytes: &[u8]) -> Result<Self, Error>
Decodes exactly 164 bytes. Rejects any other length
(Error::WrongLength) and a version with bit 31 clear
(Error::VersionBit31Clear). Reserved flag bits are not checked
here — the kernel decodes them and its rule rejects them — see
Self::check_flags.
Sourcepub fn time(&self) -> u32
pub fn time(&self) -> u32
The consensus block time: time_on_wire + time_offset (wrapping)
when flags bit 2 is set, else time_on_wire (headerTime in the
kernel).
Sourcepub fn uses_time_offset(&self) -> bool
pub fn uses_time_offset(&self) -> bool
Whether flags bit 2 is set.
Sourcepub fn asic_profile(&self) -> u8
pub fn asic_profile(&self) -> u8
flags & 3: which ASIC input layout the second BLAKE2b round uses.
Sourcepub fn check_flags(&self) -> Result<(), Error>
pub fn check_flags(&self) -> Result<(), Error>
knots:rule-header-flags-reserved: bits 6–7 of flags must be zero.
Sourcepub fn hash(&self) -> BlockHash
pub fn hash(&self) -> BlockHash
The block hash, which is the proof-of-work hash (hashHeaderV2):
h1 = tagged("Bitcoin block header 1",
version ‖ prev(display) ‖ height ‖ merkle(wire) ‖ time_on_wire ‖ 0x00
‖ bits ‖ tx_count as u32 ‖ flags ‖ clear_bits ‖ tagged("…XOR key", xor_key))
h2 = tagged("Merge-mining hook", h1 ‖ 0¹⁶ ‖ 0¹⁶ ‖ mm_rhs(wire))
b1 = blake2b-256(0u32 ‖ h2 ‖ extranonce)
b2 = blake2b-256(profile-dependent layout of prev_hidden / h2, nonces, b1)
hash = b2 XOR mask(xor_key, clear_bits) (display-order bytes)Note the two byte orders inside round one: prev_block_hash enters
in display order (Knots’ hashPrevBlock.ReversedBytes()) while the
merkle root enters in wire order.
Sourcepub fn hash_stages(&self) -> V2HashStages
pub fn hash_stages(&self) -> V2HashStages
The pipeline with every intermediate exposed.
Sourcepub fn meets_target(&self) -> bool
pub fn meets_target(&self) -> bool
hash ≤ target(bits): the kernel’s checkProofOfWork. False when
bits does not decode.
Sourcepub fn check_pow(&self, pow_limit: &Target) -> Result<(), Error>
pub fn check_pow(&self, pow_limit: &Target) -> Result<(), Error>
SPEC 4 step 1 as siding applies it: bits must be the compact form
of pow_limit and the hash must meet it.
Sourcepub fn signet_preimage(&self, stripped_merkle_root: [u8; 32]) -> [u8; 72]
pub fn signet_preimage(&self, stripped_merkle_root: [u8; 32]) -> [u8; 72]
The first 72 header bytes — version ‖ prev ‖ merkle_root ‖ time_on_wire — with merkle_root replaced by stripped_merkle_root.
Same shape as the stock family’s, which is what makes the BIP-325
block data family-agnostic (siding/lib/block.mjs blockData).
Trait Implementations§
Source§impl Clone for Blake2bV2Header
impl Clone for Blake2bV2Header
impl Copy for Blake2bV2Header
Source§impl Debug for Blake2bV2Header
impl Debug for Blake2bV2Header
impl Eq for Blake2bV2Header
Source§impl PartialEq for Blake2bV2Header
impl PartialEq for Blake2bV2Header
impl StructuralPartialEq for Blake2bV2Header
Auto Trait Implementations§
impl Freeze for Blake2bV2Header
impl RefUnwindSafe for Blake2bV2Header
impl Send for Blake2bV2Header
impl Sync for Blake2bV2Header
impl Unpin for Blake2bV2Header
impl UnsafeUnpin for Blake2bV2Header
impl UnwindSafe for Blake2bV2Header
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.