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.
57 lines
2.2 KiB
JavaScript
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 };
|