Skip to content

Commit

Permalink
generate the value for parentBeaconBlockRootGenerator
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristopherDedominici committed Feb 9, 2024
1 parent a7937da commit 847f4a0
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export interface Snapshot {
userProvidedNextBlockBaseFeePerGas: bigint | undefined;
coinbase: string;
mixHashGenerator: RandomBufferGenerator;
parentBeaconBlockRootGenerator: RandomBufferGenerator;
}

export type SendTransactionResult =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ export class HardhatNode extends EventEmitter {

const hardfork = getHardforkName(config.hardfork);
const mixHashGenerator = RandomBufferGenerator.create("randomMixHashSeed");
const parentBeaconBlockRootGenerator = RandomBufferGenerator.create(
"randomParentBeaconBlockRootSeed"
);

let forkClient: JsonRpcClient | undefined;

const common = makeCommon(config);
Expand Down Expand Up @@ -255,6 +259,7 @@ export class HardhatNode extends EventEmitter {
stateTrie,
hardfork,
mixHashGenerator.next(),
parentBeaconBlockRootGenerator.next(),
genesisBlockBaseFeePerGas
);

Expand Down Expand Up @@ -304,6 +309,7 @@ export class HardhatNode extends EventEmitter {
hardfork,
hardforkActivations,
mixHashGenerator,
parentBeaconBlockRootGenerator,
allowUnlimitedContractSize,
allowBlocksWithSameTimestamp,
tracingConfig,
Expand Down Expand Up @@ -392,6 +398,7 @@ Hardhat Network's forking functionality only works with blocks from at least spu
public readonly hardfork: HardforkName,
private readonly _hardforkActivations: HardforkHistoryConfig,
private _mixHashGenerator: RandomBufferGenerator,
private _parentBeaconBlockRootGenerator: RandomBufferGenerator,
public readonly allowUnlimitedContractSize: boolean,
private _allowBlocksWithSameTimestamp: boolean,
tracingConfig?: TracingConfig,
Expand Down Expand Up @@ -1068,6 +1075,8 @@ Hardhat Network's forking functionality only works with blocks from at least spu
this.getUserProvidedNextBlockBaseFeePerGas(),
coinbase: this.getCoinbaseAddress().toString(),
mixHashGenerator: this._mixHashGenerator.clone(),
parentBeaconBlockRootGenerator:
this._parentBeaconBlockRootGenerator.clone(),
};

this._irregularStatesByBlockNumber = new Map(
Expand Down Expand Up @@ -1124,6 +1133,8 @@ Hardhat Network's forking functionality only works with blocks from at least spu
this._coinbase = snapshot.coinbase;

this._mixHashGenerator = snapshot.mixHashGenerator;
this._parentBeaconBlockRootGenerator =
snapshot.parentBeaconBlockRootGenerator;

// We delete this and the following snapshots, as they can only be used
// once in Ganache
Expand Down Expand Up @@ -1852,6 +1863,10 @@ Hardhat Network's forking functionality only works with blocks from at least spu
headerData.mixHash = this._getNextMixHash();
}

if (this.isPostCancunHardfork()) {
headerData.parentBeaconBlockRoot = this._getNextParentBeaconBlockRoot();
}

headerData.baseFeePerGas = await this.getNextBlockBaseFeePerGas();

const blockBuilder = await this._vm.buildBlock({
Expand Down Expand Up @@ -2724,6 +2739,10 @@ Hardhat Network's forking functionality only works with blocks from at least spu
return hardforkGte(this.hardfork, HardforkName.MERGE);
}

public isPostCancunHardfork(): boolean {
return hardforkGte(this.hardfork, HardforkName.CANCUN);
}

public setPrevRandao(prevRandao: Buffer): void {
this._mixHashGenerator.setNext(prevRandao);
}
Expand Down Expand Up @@ -2779,6 +2798,10 @@ Hardhat Network's forking functionality only works with blocks from at least spu
return this._mixHashGenerator.next();
}

private _getNextParentBeaconBlockRoot(): Uint8Array {
return this._parentBeaconBlockRootGenerator.next();
}

private async _getEstimateGasFeePriceFields(
callParams: CallParams,
blockNumberOrPending: bigint | "pending"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export async function putGenesisBlock(
stateTrie: Trie,
hardfork: HardforkName,
initialMixHash: Uint8Array,
initialParentBeaconBlockRoot: Uint8Array,
initialBaseFee?: bigint
) {
const initialBlockTimestamp =
Expand All @@ -24,6 +25,7 @@ export async function putGenesisBlock(
: getCurrentTimestamp();

const isPostMerge = hardforkGte(hardfork, HardforkName.MERGE);
const isPostCancun = hardforkGte(hardfork, HardforkName.CANCUN);

const header: HeaderData = {
timestamp: `0x${initialBlockTimestamp.toString(16)}`,
Expand All @@ -38,6 +40,10 @@ export async function putGenesisBlock(
header.mixHash = initialMixHash;
}

if (isPostCancun) {
header.parentBeaconBlockRoot = initialParentBeaconBlockRoot;
}

if (initialBaseFee !== undefined) {
header.baseFeePerGas = initialBaseFee;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
DEFAULT_NETWORK_ID,
} from "../helpers/providers";
import { sleep } from "../helpers/sleep";
import { bufferToRpcData } from "../../../../src/internal/core/jsonrpc/types/base-types";
import { runFullBlock } from "./utils/runFullBlock";

function toBuffer(x: Parameters<typeof toBytes>[0]) {
Expand Down Expand Up @@ -1375,5 +1376,63 @@ describe("HardhatNode", () => {
assert.isUndefined(estimateGasResult.error);
});
});

describe("cancun hardfork", function () {
describe("parentBeaconBlockRoot property", function () {
beforeEach(async () => {
[, node] = await HardhatNode.create({
...config,
hardfork: "cancun",
});
});

it("should have the parentBeaconBlockRoot property only after cancun", async () => {
[, node] = await HardhatNode.create({
...config,
hardfork: "shanghai",
});

const block = await node.getBlockByNumber(0n);

assert.isUndefined(block!.header.parentBeaconBlockRoot);
});

it("should have a non empty parentBeaconBlockRoot in the genesis block and the value should be an expected one", async () => {
const block = await node.getBlockByNumber(0n);

assert.equal(
bufferToRpcData(block!.header.parentBeaconBlockRoot!),
"0xdd8876ba5af271ae9d93ececb192d6a7b4e6094ca5999756336279fd796b8619"
);
});

it("should have different parentBeaconBlockRoot values in different blocks", async () => {
const block1 = await node.getBlockByNumber(0n);
const parentBeaconBlockRoot1 = bufferToRpcData(
block1!.header.parentBeaconBlockRoot!
);

await node.mineBlock();

const block2 = await node.getBlockByNumber(1n);
const parentBeaconBlockRoot2 = bufferToRpcData(
block2!.header.parentBeaconBlockRoot!
);

assert.notEqual(parentBeaconBlockRoot1, parentBeaconBlockRoot2);
});

it("should have the parentBeaconBlockRoot value different from the mixhash value", async () => {
const block = await node.getBlockByNumber(0n);

const mixHash = bufferToRpcData(block!.header.mixHash);
const parentBeaconBlockRoot = bufferToRpcData(
block!.header.parentBeaconBlockRoot!
);

assert.notEqual(parentBeaconBlockRoot, mixHash);
});
});
});
});
});

0 comments on commit 847f4a0

Please sign in to comment.