aere-contracts/test/header-rlp.js
Aere Network a13a649b77
Some checks are pending
contracts-ci / Install (lockfile) → compile → full test suite (push) Waiting to run
contracts-ci / PQC known-answer tests (NIST vectors) (push) Waiting to run
contracts-ci / Coverage (scoped, with artifacts) (push) Waiting to run
Initial public release
Aere Network public source. Everything here can be checked against the live
chain (chain id 2800, https://rpc.aere.network).

Scope note, stated up front rather than buried: consensus on chain 2800 is
classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at
the signature, precompile, account and transport layers. Nothing here makes the
consensus post-quantum, and no document in it should be read as claiming so.
2026-07-20 01:02:37 +03:00

57 lines
2.2 KiB
JavaScript

// Shared RLP block-header encoder used by the anchor tests.
//
// Adaptive standard-Ethereum header encoder: it appends the London / Shanghai /
// Cancun / Prague trailing fields only when the block object carries them, which
// mirrors how a node serializes its header. This lets one function reconstruct
// - AERE's genesis block (Shanghai layout, 17 fields), which it matches exactly, and
// - the local hardhat block under either the "shanghai" or "cancun" hardfork.
//
// QBFT note: AERE is a Hyperledger Besu QBFT chain. For the canonical block
// hash of a NON-genesis block, Besu strips the commit seals out of extraData
// before hashing, and the exact post-Cancun serialization was not reproducible
// from eth_getBlockByNumber alone (see the deploy script's header sourcing).
// The anchor CONTRACT is agnostic to all of this: it only checks
// keccak256(header) == blockhash and reads stateRoot at a fixed offset.
const { ethers } = require("ethers");
// RLP-encode an integer quantity with minimal big-endian bytes (0 -> "0x").
function q(hexOrNum) {
let v = BigInt(hexOrNum);
if (v === 0n) return "0x";
let s = v.toString(16);
if (s.length % 2) s = "0" + s;
return "0x" + s;
}
// Build the RLP header bytes for a standard-Ethereum header object `b`
// (fields are 0x-hex strings as returned by eth_getBlockByNumber).
function encodeHeader(b) {
const fields = [
b.parentHash,
b.sha3Uncles,
b.miner,
b.stateRoot,
b.transactionsRoot,
b.receiptsRoot,
b.logsBloom,
q(b.difficulty),
q(b.number),
q(b.gasLimit),
q(b.gasUsed),
q(b.timestamp),
b.extraData && b.extraData !== "0x" ? b.extraData : "0x",
b.mixHash,
b.nonce,
];
if (b.baseFeePerGas != null) fields.push(q(b.baseFeePerGas)); // London
if (b.withdrawalsRoot != null) fields.push(b.withdrawalsRoot); // Shanghai
if (b.blobGasUsed != null) fields.push(q(b.blobGasUsed)); // Cancun
if (b.excessBlobGas != null) fields.push(q(b.excessBlobGas)); // Cancun
if (b.parentBeaconBlockRoot != null) fields.push(b.parentBeaconBlockRoot); // Cancun
if (b.requestsHash != null) fields.push(b.requestsHash); // Prague
return ethers.encodeRlp(fields);
}
module.exports = { q, encodeHeader };