From fdb065832005e3e4311a3c7109e8b562414480ac Mon Sep 17 00:00:00 2001 From: harkamal Date: Fri, 30 Jun 2023 14:38:12 +0530 Subject: [PATCH 01/10] blockchain: remove genesis state dependancy from blockchain fix the blockchain init and statepassing from client pass custom genesis from client's chain to blockchain simplify stateroot fetch remove need to genesis state in blockchain remove package dependancy rebase fixes lint fix statemanager spec fix vm spec fix client spec fix client spec --- package-lock.json | 4 +- packages/blockchain/package.json | 1 - packages/blockchain/src/blockchain.ts | 68 +++++++++------- packages/blockchain/src/types.ts | 80 +++++++++---------- packages/client/bin/cli.ts | 1 + packages/client/src/blockchain/chain.ts | 9 ++- packages/client/src/client.ts | 3 + packages/client/src/execution/execution.ts | 5 ++ packages/client/src/execution/vmexecution.ts | 9 ++- .../client/src/service/ethereumservice.ts | 3 + .../client/src/service/fullethereumservice.ts | 1 + .../client/test/rpc/eth/estimateGas.spec.ts | 2 +- .../client/test/rpc/eth/getBalance.spec.ts | 2 +- .../getBlockTransactionCountByNumber.spec.ts | 4 +- packages/client/test/rpc/eth/getCode.spec.ts | 2 +- .../test/rpc/eth/getTransactionCount.spec.ts | 2 +- packages/client/test/rpc/helpers.ts | 9 ++- .../client/test/rpc/txpool/content.spec.ts | 2 +- packages/common/src/enums.ts | 26 ++++++ packages/statemanager/package.json | 1 + packages/statemanager/test/vmState.spec.ts | 12 +-- packages/vm/src/types.ts | 4 +- packages/vm/src/vm.ts | 29 ++++--- packages/vm/test/api/customChain.spec.ts | 8 +- 24 files changed, 170 insertions(+), 117 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8a640d434e..7478420d23 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21050,7 +21050,6 @@ "@ethereumjs/block": "^4.2.2", "@ethereumjs/common": "^3.1.2", "@ethereumjs/ethash": "^2.0.5", - "@ethereumjs/genesis": "^0.0.1", "@ethereumjs/rlp": "^4.0.1", "@ethereumjs/trie": "^5.0.5", "@ethereumjs/tx": "^4.1.2", @@ -21406,6 +21405,7 @@ }, "devDependencies": { "@ethereumjs/block": "^4.2.2", + "@ethereumjs/genesis": "^0.0.1", "@ethereumjs/trie": "^5.0.5", "@ethereumjs/util": "^8.0.6", "@types/tape": "^4.13.2", @@ -23222,7 +23222,6 @@ "@ethereumjs/block": "^4.2.2", "@ethereumjs/common": "^3.1.2", "@ethereumjs/ethash": "^2.0.5", - "@ethereumjs/genesis": "^0.0.1", "@ethereumjs/rlp": "^4.0.1", "@ethereumjs/trie": "^5.0.5", "@ethereumjs/tx": "^4.1.2", @@ -23493,6 +23492,7 @@ "requires": { "@ethereumjs/block": "^4.2.2", "@ethereumjs/common": "^3.1.2", + "@ethereumjs/genesis": "^0.0.1", "@ethereumjs/rlp": "^4.0.1", "@ethereumjs/trie": "^5.0.5", "@ethereumjs/util": "^8.0.6", diff --git a/packages/blockchain/package.json b/packages/blockchain/package.json index d1d9879571..51ff516e65 100644 --- a/packages/blockchain/package.json +++ b/packages/blockchain/package.json @@ -47,7 +47,6 @@ "@ethereumjs/block": "^4.2.2", "@ethereumjs/common": "^3.1.2", "@ethereumjs/ethash": "^2.0.5", - "@ethereumjs/genesis": "^0.0.1", "@ethereumjs/rlp": "^4.0.1", "@ethereumjs/trie": "^5.0.5", "@ethereumjs/tx": "^4.1.2", diff --git a/packages/blockchain/src/blockchain.ts b/packages/blockchain/src/blockchain.ts index 2ee0e89a46..aafcb4f042 100644 --- a/packages/blockchain/src/blockchain.ts +++ b/packages/blockchain/src/blockchain.ts @@ -1,7 +1,13 @@ import { Block, BlockHeader } from '@ethereumjs/block' -import { Chain, Common, ConsensusAlgorithm, ConsensusType, Hardfork } from '@ethereumjs/common' -import { getGenesis } from '@ethereumjs/genesis' -import { genesisStateRoot } from '@ethereumjs/trie' +import { + Chain, + ChainGenesis, + Common, + ConsensusAlgorithm, + ConsensusType, + Hardfork, +} from '@ethereumjs/common' +import { genesisStateRoot as genGenesisStateRoot } from '@ethereumjs/trie' import { KECCAK256_RLP, Lock, @@ -10,7 +16,6 @@ import { bytesToUnprefixedHex, concatBytes, equalsBytes, - hexToBytes, } from '@ethereumjs/util' import { CasperConsensus, CliqueConsensus, EthashConsensus } from './consensus/index.js' @@ -24,7 +29,13 @@ import { import { DBManager } from './db/manager.js' import { DBTarget } from './db/operation.js' -import type { BlockchainInterface, BlockchainOptions, Consensus, OnBlock } from './types.js' +import type { + BlockchainInterface, + BlockchainOptions, + Consensus, + GenesisOptions, + OnBlock, +} from './types.js' import type { BlockData } from '@ethereumjs/block' import type { CliqueConfig } from '@ethereumjs/common' import type { BigIntLike, DB, DBObject, GenesisState } from '@ethereumjs/util' @@ -75,7 +86,8 @@ export class Blockchain implements BlockchainInterface { public static async create(opts: BlockchainOptions = {}) { const blockchain = new Blockchain(opts) - await blockchain._init(opts.genesisBlock) + + await blockchain._init(opts) return blockchain } @@ -198,27 +210,27 @@ export class Blockchain implements BlockchainInterface { * * @hidden */ - private async _init(genesisBlock?: Block): Promise { + private async _init(opts: GenesisOptions = {}): Promise { await this.consensus.setup({ blockchain: this }) - if (this._isInitialized) return + let stateRoot = opts.genesisBlock?.header.stateRoot ?? opts.genesisStateRoot + if (stateRoot === undefined) { + if (this._customGenesisState !== undefined) { + stateRoot = await genGenesisStateRoot(this._customGenesisState) + } else { + // eslint-disable-next-line @typescript-eslint/no-use-before-define + stateRoot = await getGenesisStateRoot(Number(this.common.chainId()) as Chain) + } + } + + const genesisBlock = opts.genesisBlock ?? this.createGenesisBlock(stateRoot) + let genesisHash = await this.dbManager.numberToHash(BigInt(0)) const dbGenesisBlock = genesisHash !== undefined ? await this.dbManager.getBlock(genesisHash) : undefined - if (genesisBlock === undefined) { - let stateRoot - if (this.common.chainId() === BigInt(1) && this._customGenesisState === undefined) { - // For mainnet use the known genesis stateRoot to quicken setup - stateRoot = hexToBytes('0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544') - } else { - stateRoot = await genesisStateRoot(this.genesisState()) - } - genesisBlock = this.createGenesisBlock(stateRoot) - } - // If the DB has a genesis block, then verify that the genesis block in the // DB is indeed the Genesis block generated or assigned. if (dbGenesisBlock !== undefined && !equalsBytes(genesisBlock.hash(), dbGenesisBlock.hash())) { @@ -1338,16 +1350,12 @@ export class Blockchain implements BlockchainInterface { { common } ) } +} - /** - * Returns the genesis state of the blockchain. - * All values are provided as hex-prefixed strings. - */ - genesisState(): GenesisState { - if (this._customGenesisState) { - return this._customGenesisState - } - - return getGenesis(Number(this.common.chainId()) as Chain) ?? {} - } +/** + * Returns the genesis state root + */ +async function getGenesisStateRoot(chainId: Chain): Promise { + const chainGenesis = ChainGenesis[chainId] + return chainGenesis !== undefined ? chainGenesis.stateRoot : genGenesisStateRoot({}) } diff --git a/packages/blockchain/src/types.ts b/packages/blockchain/src/types.ts index 4e8aaf4dbe..84a0d0740e 100644 --- a/packages/blockchain/src/types.ts +++ b/packages/blockchain/src/types.ts @@ -76,21 +76,54 @@ export interface BlockchainInterface { getTotalDifficulty?(hash: Uint8Array, number?: bigint): Promise /** - * Returns the genesis state of the blockchain. - * All values are provided as hex-prefixed strings. + * Returns the latest full block in the canonical chain. */ - genesisState(): GenesisState + getCanonicalHeadBlock(): Promise +} +export interface GenesisOptions { /** - * Returns the latest full block in the canonical chain. + * The blockchain only initializes successfully if it has a genesis block. If + * there is no block available in the DB and a `genesisBlock` is provided, + * then the provided `genesisBlock` will be used as genesis. If no block is + * present in the DB and no block is provided, then the genesis block as + * provided from the `common` will be used. */ - getCanonicalHeadBlock(): Promise + genesisBlock?: Block + + /** + * If you are using a custom chain {@link Common}, pass the genesis state. + * + * Pattern 1 (with genesis state see {@link GenesisState} for format): + * + * ```javascript + * { + * '0x0...01': '0x100', // For EoA + * } + * ``` + * + * Pattern 2 (with complex genesis state, containing contract accounts and storage). + * Note that in {@link AccountState} there are two + * accepted types. This allows to easily insert accounts in the genesis state: + * + * A complex genesis state with Contract and EoA states would have the following format: + * + * ```javascript + * { + * '0x0...01': '0x100', // For EoA + * '0x0...02': ['0x1', '0xRUNTIME_BYTECODE', [[storageKey1, storageValue1], [storageKey2, storageValue2]]] // For contracts + * } + * ``` + */ + genesisState?: GenesisState + + genesisStateRoot?: Uint8Array } /** * This are the options that the Blockchain constructor can receive. */ -export interface BlockchainOptions { +export interface BlockchainOptions extends GenesisOptions { /** * Specify the chain and hardfork by passing a {@link Common} instance. * @@ -135,41 +168,6 @@ export interface BlockchainOptions { */ validateBlocks?: boolean - /** - * The blockchain only initializes successfully if it has a genesis block. If - * there is no block available in the DB and a `genesisBlock` is provided, - * then the provided `genesisBlock` will be used as genesis. If no block is - * present in the DB and no block is provided, then the genesis block as - * provided from the `common` will be used. - */ - genesisBlock?: Block - - /** - * If you are using a custom chain {@link Common}, pass the genesis state. - * - * Pattern 1 (with genesis state see {@link GenesisState} for format): - * - * ```javascript - * { - * '0x0...01': '0x100', // For EoA - * } - * ``` - * - * Pattern 2 (with complex genesis state, containing contract accounts and storage). - * Note that in {@link AccountState} there are two - * accepted types. This allows to easily insert accounts in the genesis state: - * - * A complex genesis state with Contract and EoA states would have the following format: - * - * ```javascript - * { - * '0x0...01': '0x100', // For EoA - * '0x0...02': ['0x1', '0xRUNTIME_BYTECODE', [[storageKey1, storageValue1], [storageKey2, storageValue2]]] // For contracts - * } - * ``` - */ - genesisState?: GenesisState - /** * Optional custom consensus that implements the {@link Consensus} class */ diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index 59189ce37c..4671560ecc 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -452,6 +452,7 @@ async function startClient(config: Config, customGenesisState?: GenesisState) { const client = await EthereumClient.create({ config, blockchain, + genesisState: customGenesisState, ...dbs, }) await client.open() diff --git a/packages/client/src/blockchain/chain.ts b/packages/client/src/blockchain/chain.ts index 4a0b1a1ce3..8063af1027 100644 --- a/packages/client/src/blockchain/chain.ts +++ b/packages/client/src/blockchain/chain.ts @@ -7,7 +7,7 @@ import { LevelDB } from '../execution/level' import { Event } from '../types' import type { Config } from '../config' -import type { DB, DBObject } from '@ethereumjs/util' +import type { DB, DBObject, GenesisState } from '@ethereumjs/util' import type { AbstractLevel } from 'abstract-level' /** @@ -28,6 +28,8 @@ export interface ChainOptions { * Specify a blockchain which implements the Chain interface */ blockchain?: Blockchain + + genesisState?: GenesisState } /** @@ -102,6 +104,8 @@ export class Chain { public config: Config public chainDB: DB public blockchain: Blockchain + public _customGenesisState?: GenesisState + public opened: boolean private _headers: ChainHeaders = { @@ -158,6 +162,7 @@ export class Chain { this.blockchain = options.blockchain! this.chainDB = this.blockchain.db + this._customGenesisState = options.genesisState this.opened = false } @@ -216,7 +221,7 @@ export class Chain { async open(): Promise { if (this.opened) return false await this.blockchain.db.open() - await (this.blockchain as any)._init() + await (this.blockchain as any)._init({ genesisState: this._customGenesisState }) this.opened = true await this.update(false) diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 65fd52617a..c7db2fbe01 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -8,6 +8,7 @@ import { Event } from './types' import type { Config } from './config' import type { MultiaddrLike } from './types' import type { Blockchain } from '@ethereumjs/blockchain' +import type { GenesisState } from '@ethereumjs/util' import type { AbstractLevel } from 'abstract-level' export interface EthereumClientOptions { @@ -49,6 +50,7 @@ export interface EthereumClientOptions { /* How often to discover new peers */ refreshInterval?: number + genesisState?: GenesisState } /** @@ -89,6 +91,7 @@ export class EthereumClient { chainDB: options.chainDB, stateDB: options.stateDB, metaDB: options.metaDB, + genesisState: options.genesisState, chain, }), ] diff --git a/packages/client/src/execution/execution.ts b/packages/client/src/execution/execution.ts index c0c43c1ddd..8d51514009 100644 --- a/packages/client/src/execution/execution.ts +++ b/packages/client/src/execution/execution.ts @@ -1,5 +1,6 @@ import type { Chain } from '../blockchain' import type { Config } from '../config' +import type { GenesisState } from '@ethereumjs/util' import type { AbstractLevel } from 'abstract-level' export interface ExecutionOptions { @@ -14,6 +15,8 @@ export interface ExecutionOptions { /** Chain */ chain: Chain + + genesisState?: GenesisState } export abstract class Execution { @@ -22,6 +25,7 @@ export abstract class Execution { protected stateDB?: AbstractLevel protected metaDB?: AbstractLevel protected chain: Chain + protected _customGenesisState?: GenesisState /** Custom genesis state */ public running: boolean = false public started: boolean = false @@ -35,6 +39,7 @@ export abstract class Execution { this.chain = options.chain this.stateDB = options.stateDB this.metaDB = options.metaDB + this._customGenesisState = options.genesisState } /** diff --git a/packages/client/src/execution/vmexecution.ts b/packages/client/src/execution/vmexecution.ts index 120dd7d838..8a03dd2c24 100644 --- a/packages/client/src/execution/vmexecution.ts +++ b/packages/client/src/execution/vmexecution.ts @@ -5,6 +5,7 @@ import { DBSetTD, } from '@ethereumjs/blockchain' import { ConsensusType, Hardfork } from '@ethereumjs/common' +import { getGenesis } from '@ethereumjs/genesis' import { CacheType, DefaultStateManager } from '@ethereumjs/statemanager' import { Trie } from '@ethereumjs/trie' import { Lock, bytesToHex, equalsBytes } from '@ethereumjs/util' @@ -132,10 +133,12 @@ export class VMExecution extends Execution { this.hardfork = this.config.execCommon.hardfork() this.config.logger.info(`Initializing VM execution hardfork=${this.hardfork}`) if (number === BigInt(0)) { - if (typeof this.vm.blockchain.genesisState !== 'function') { - throw new Error('cannot get iterator head: blockchain has no genesisState function') + const genesisState = + this._customGenesisState ?? getGenesis(Number(this.vm.common.chainId())) + if (!genesisState) { + throw new Error('genesisState not available') } - await this.vm.stateManager.generateCanonicalGenesis(this.vm.blockchain.genesisState()) + await this.vm.stateManager.generateCanonicalGenesis(genesisState) } await super.open() // TODO: Should a run be started to execute any left over blocks? diff --git a/packages/client/src/service/ethereumservice.ts b/packages/client/src/service/ethereumservice.ts index eb340c7774..e80ec90fe9 100644 --- a/packages/client/src/service/ethereumservice.ts +++ b/packages/client/src/service/ethereumservice.ts @@ -7,6 +7,7 @@ import { Service } from './service' import type { Synchronizer } from '../sync' import type { V8Engine } from '../util' import type { ServiceOptions } from './service' +import type { GenesisState } from '@ethereumjs/util' import type { AbstractLevel } from 'abstract-level' export interface EthereumServiceOptions extends ServiceOptions { @@ -27,6 +28,8 @@ export interface EthereumServiceOptions extends ServiceOptions { /* Protocol timeout in ms (default: 6000) */ timeout?: number + + genesisState?: GenesisState } /** diff --git a/packages/client/src/service/fullethereumservice.ts b/packages/client/src/service/fullethereumservice.ts index b6fcf59b86..431ca3b7e4 100644 --- a/packages/client/src/service/fullethereumservice.ts +++ b/packages/client/src/service/fullethereumservice.ts @@ -49,6 +49,7 @@ export class FullEthereumService extends EthereumService { config: options.config, stateDB: options.stateDB, metaDB: options.metaDB, + genesisState: options.genesisState, chain: this.chain, }) diff --git a/packages/client/test/rpc/eth/estimateGas.spec.ts b/packages/client/test/rpc/eth/estimateGas.spec.ts index d7aae4f20a..2c13480877 100644 --- a/packages/client/test/rpc/eth/estimateGas.spec.ts +++ b/packages/client/test/rpc/eth/estimateGas.spec.ts @@ -30,7 +30,7 @@ tape(`${method}: call with valid arguments`, async (t) => { const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService t.notEqual(execution, undefined, 'should have valid execution') const { vm } = execution - await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState()) + await vm.stateManager.generateCanonicalGenesis({}) // genesis address with balance const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/eth/getBalance.spec.ts b/packages/client/test/rpc/eth/getBalance.spec.ts index b91740dec1..102ca0fe31 100644 --- a/packages/client/test/rpc/eth/getBalance.spec.ts +++ b/packages/client/test/rpc/eth/getBalance.spec.ts @@ -28,7 +28,7 @@ tape(`${method}: ensure balance deducts after a tx`, async (t) => { // since synchronizer.run() is not executed in the mock setup, // manually run stateManager.generateCanonicalGenesis() - await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState()) + await vm.stateManager.generateCanonicalGenesis({}) // genesis address with balance const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts index 24600f8988..2141e8f006 100644 --- a/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts +++ b/packages/client/test/rpc/eth/getBlockTransactionCountByNumber.spec.ts @@ -30,7 +30,7 @@ tape(`${method}: call with valid arguments`, async (t) => { t.notEqual(execution, undefined, 'should have valid execution') const { vm } = execution - await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState()) + await vm.stateManager.generateCanonicalGenesis({}) const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') @@ -81,7 +81,7 @@ tape(`${method}: call with valid arguments (multiple transactions)`, async (t) = t.notEqual(execution, undefined, 'should have valid execution') const { vm } = execution - await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState()) + await vm.stateManager.generateCanonicalGenesis({}) const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/eth/getCode.spec.ts b/packages/client/test/rpc/eth/getCode.spec.ts index 293145d24c..5302360461 100644 --- a/packages/client/test/rpc/eth/getCode.spec.ts +++ b/packages/client/test/rpc/eth/getCode.spec.ts @@ -25,7 +25,7 @@ tape(`${method}: call with valid arguments`, async (t) => { const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService t.notEqual(execution, undefined, 'should have valid execution') const { vm } = execution - await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState()) + await vm.stateManager.generateCanonicalGenesis({}) // genesis address const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/eth/getTransactionCount.spec.ts b/packages/client/test/rpc/eth/getTransactionCount.spec.ts index 08a9432084..704ca4d499 100644 --- a/packages/client/test/rpc/eth/getTransactionCount.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionCount.spec.ts @@ -32,7 +32,7 @@ tape(`${method}: call with valid arguments`, async (t) => { // since synchronizer.run() is not executed in the mock setup, // manually run stateManager.generateCanonicalGenesis() - await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState()) + await vm.stateManager.generateCanonicalGenesis({}) // a genesis address const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/helpers.ts b/packages/client/test/rpc/helpers.ts index 89ef83fbb0..60ae8594ac 100644 --- a/packages/client/test/rpc/helpers.ts +++ b/packages/client/test/rpc/helpers.ts @@ -20,6 +20,7 @@ import { mockBlockchain } from './mockBlockchain' import type { EthereumClient } from '../../src/client' import type { FullEthereumService } from '../../src/service' import type { TypedTransaction } from '@ethereumjs/tx' +import type { GenesisState } from '@ethereumjs/util' import type { IncomingMessage } from 'connect' import type { HttpServer } from 'jayson/promise' import type * as tape from 'tape' @@ -42,6 +43,7 @@ type createClientArgs = { blockchain: Blockchain chain: any // Could be anything that implements a portion of the Chain interface (varies by test) opened: boolean + genesisState: GenesisState } export function startRPC( methods: any, @@ -69,6 +71,7 @@ export function createManager(client: EthereumClient) { export function createClient(clientOpts: Partial = {}) { const common: Common = clientOpts.commonChain ?? new Common({ chain: ChainEnum.Mainnet }) + const genesisState = clientOpts.genesisState ?? {} const config = new Config({ transports: [], common, @@ -80,7 +83,8 @@ export function createClient(clientOpts: Partial = {}) { const blockchain = clientOpts.blockchain ?? mockBlockchain() // @ts-ignore TODO Move to async Chain.create() initialization - const chain = clientOpts.chain ?? new Chain({ config, blockchain: blockchain as any }) + const chain = + clientOpts.chain ?? new Chain({ config, blockchain: blockchain as any, genesisState }) chain.opened = true const defaultClientConfig = { @@ -122,7 +126,7 @@ export function createClient(clientOpts: Partial = {}) { let execution if (!(clientOpts.includeVM === false)) { const metaDB: any = clientOpts.enableMetaDB === true ? new MemoryLevel() : undefined - execution = new VMExecution({ config, chain, metaDB }) + execution = new VMExecution({ config, chain, metaDB, genesisState }) } let peers = [1, 2, 3] @@ -243,6 +247,7 @@ export async function setupChain(genesisFile: any, chainName = 'dev', clientOpts blockchain, includeVM: true, enableMetaDB: true, + genesisState, }) const manager = createManager(client) const engineMethods = clientOpts.engine === true ? manager.getMethods(true) : {} diff --git a/packages/client/test/rpc/txpool/content.spec.ts b/packages/client/test/rpc/txpool/content.spec.ts index fbc2f9afa7..536cfa0802 100644 --- a/packages/client/test/rpc/txpool/content.spec.ts +++ b/packages/client/test/rpc/txpool/content.spec.ts @@ -25,7 +25,7 @@ tape(`${method}: call with valid arguments`, async (t) => { const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService t.notEqual(execution, undefined, 'should have valid execution') const { vm } = execution - await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState()) + await vm.stateManager.generateCanonicalGenesis({}) const gasLimit = 2000000 const parent = await blockchain.getCanonicalHeadHeader() const block = Block.fromBlockData( diff --git a/packages/common/src/enums.ts b/packages/common/src/enums.ts index e84616943d..5f066d63ef 100644 --- a/packages/common/src/enums.ts +++ b/packages/common/src/enums.ts @@ -1,9 +1,35 @@ +import { hexToBytes } from '@ethereumjs/util' + export enum Chain { Mainnet = 1, Goerli = 5, Sepolia = 11155111, } +// Genesis meta gives the genesis state info which is uncoupled with common's genesis params +type GenesiState = { + /* blockNumber that can be used to update and track the regenesis marker */ + blockNumber: bigint + /* stateRoot of the chain at the blockNumber */ + stateRoot: Uint8Array +} + +// Having this info as record will force typescript to make sure no chain is missed +export const ChainGenesis: Record = { + [Chain.Mainnet]: { + blockNumber: BigInt(0), + stateRoot: hexToBytes('0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544'), + }, + [Chain.Goerli]: { + blockNumber: BigInt(0), + stateRoot: hexToBytes('0x5d6cded585e73c4e322c30c2f782a336316f17dd85a4863b9d838d2d4b8b3008'), + }, + [Chain.Sepolia]: { + blockNumber: BigInt(0), + stateRoot: hexToBytes('0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494'), + }, +} + export enum Hardfork { Chainstart = 'chainstart', Homestead = 'homestead', diff --git a/packages/statemanager/package.json b/packages/statemanager/package.json index 110afb78bc..9d01b99f31 100644 --- a/packages/statemanager/package.json +++ b/packages/statemanager/package.json @@ -57,6 +57,7 @@ }, "devDependencies": { "@ethereumjs/block": "^4.2.2", + "@ethereumjs/genesis": "^0.0.1", "@ethereumjs/trie": "^5.0.5", "@ethereumjs/util": "^8.0.6", "@types/tape": "^4.13.2", diff --git a/packages/statemanager/test/vmState.spec.ts b/packages/statemanager/test/vmState.spec.ts index e36fb5fee6..ed6be71b2a 100644 --- a/packages/statemanager/test/vmState.spec.ts +++ b/packages/statemanager/test/vmState.spec.ts @@ -1,5 +1,5 @@ -import { Blockchain } from '@ethereumjs/blockchain' -import { Chain, Common, Hardfork } from '@ethereumjs/common' +import { Chain } from '@ethereumjs/common' +import { getGenesis } from '@ethereumjs/genesis' import { Account, Address, hexToBytes, utf8ToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -21,14 +21,12 @@ describe('stateManager', () => { if (isBrowser()) { return } - const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Petersburg }) const expectedStateRoot = hexToBytes( '0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544' ) const stateManager = new StateManager({}) - const blockchain = await Blockchain.create({ common }) - await stateManager.generateCanonicalGenesis(blockchain.genesisState()) + await stateManager.generateCanonicalGenesis(getGenesis(Chain.Mainnet)) const stateRoot = await stateManager.getStateRoot() assert.deepEqual( @@ -51,11 +49,9 @@ describe('stateManager', () => { ] for (const [chain, expectedStateRoot] of chains) { - const common = new Common({ chain, hardfork: Hardfork.Chainstart }) const stateManager = new DefaultStateManager({}) - const blockchain = await Blockchain.create({ common }) - await stateManager.generateCanonicalGenesis(blockchain.genesisState()) + await stateManager.generateCanonicalGenesis(getGenesis(chain)) const stateRoot = await stateManager.getStateRoot() assert.deepEqual( diff --git a/packages/vm/src/types.ts b/packages/vm/src/types.ts index 7fa6bc15bc..184166cf2c 100644 --- a/packages/vm/src/types.ts +++ b/packages/vm/src/types.ts @@ -4,7 +4,7 @@ import type { BlockchainInterface } from '@ethereumjs/blockchain' import type { Common, EVMStateManagerInterface } from '@ethereumjs/common' import type { EVM, EVMResult, Log } from '@ethereumjs/evm' import type { AccessList, TypedTransaction } from '@ethereumjs/tx' -import type { BigIntLike, WithdrawalData } from '@ethereumjs/util' +import type { BigIntLike, GenesisState, WithdrawalData } from '@ethereumjs/util' export type TxReceipt = PreByzantiumTxReceipt | PostByzantiumTxReceipt | EIP4844BlobTxReceipt /** @@ -126,7 +126,7 @@ export interface VMOpts { * * Default: `false` */ - activateGenesisState?: boolean + genesisState?: GenesisState /** * Set the hardfork either by timestamp (for HFs from Shanghai onwards) or by block number diff --git a/packages/vm/src/vm.ts b/packages/vm/src/vm.ts index 676347ac87..c26b5645b4 100644 --- a/packages/vm/src/vm.ts +++ b/packages/vm/src/vm.ts @@ -20,7 +20,7 @@ import type { } from './types.js' import type { BlockchainInterface } from '@ethereumjs/blockchain' import type { EVMStateManagerInterface } from '@ethereumjs/common' -import type { BigIntLike } from '@ethereumjs/util' +import type { BigIntLike, GenesisState } from '@ethereumjs/util' /** * Execution engine which can be used to run a blockchain, individual @@ -76,7 +76,11 @@ export class VM { */ static async create(opts: VMOpts = {}): Promise { const vm = new this(opts) - await vm.init() + const genesisStateOpts = + opts.stateManager === undefined && opts.genesisState === undefined + ? { genesisState: {} } + : undefined + await vm.init({ ...genesisStateOpts, ...opts }) return vm } @@ -131,22 +135,17 @@ export class VM { typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false } - async init(): Promise { + async init({ genesisState }: { genesisState?: GenesisState } = {}): Promise { if (this._isInitialized) return - if (typeof (this.blockchain)._init === 'function') { - await (this.blockchain as any)._init() + + if (genesisState !== undefined) { + await this.stateManager.generateCanonicalGenesis(genesisState) + } else if (this._opts.stateManager === undefined) { + throw Error('genesisState state required to set genesis for stateManager') } - if (!this._opts.stateManager) { - if (this._opts.activateGenesisState === true) { - if (typeof (this.blockchain).genesisState === 'function') { - await this.stateManager.generateCanonicalGenesis((this.blockchain).genesisState()) - } else { - throw new Error( - 'cannot activate genesis state: blockchain object has no `genesisState` method' - ) - } - } + if (typeof (this.blockchain)._init === 'function') { + await (this.blockchain as any)._init({ genesisState }) } if (this._opts.activatePrecompiles === true && typeof this._opts.stateManager === 'undefined') { diff --git a/packages/vm/test/api/customChain.spec.ts b/packages/vm/test/api/customChain.spec.ts index 28b3eb1f8c..a5622cc95e 100644 --- a/packages/vm/test/api/customChain.spec.ts +++ b/packages/vm/test/api/customChain.spec.ts @@ -63,7 +63,7 @@ const privateKey = hexToBytes('0xe331b6d69882b4cb4ea581d88e0b604039a3de5967688d3 describe('VM initialized with custom state', () => { it('should transfer eth from already existent account', async () => { const blockchain = await Blockchain.create({ common, genesisState }) - const vm = await VM.create({ blockchain, common, activateGenesisState: true }) + const vm = await VM.create({ blockchain, common, genesisState }) const to = '0x00000000000000000000000000000000000000ff' const tx = TransactionFactory.fromTxData( @@ -91,7 +91,7 @@ describe('VM initialized with custom state', () => { it('should retrieve value from storage', async () => { const blockchain = await Blockchain.create({ common, genesisState }) common.setHardfork(Hardfork.London) - const vm = await VM.create({ blockchain, common, activateGenesisState: true }) + const vm = await VM.create({ blockchain, common, genesisState }) const sigHash = new Interface(['function retrieve()']).getSighash('retrieve') const callResult = await vm.evm.runCall({ @@ -110,10 +110,10 @@ describe('VM initialized with custom state', () => { const customChains = [testnetMerge] const common = new Common({ chain: 'testnetMerge', hardfork: Hardfork.Istanbul, customChains }) - let vm = await VM.create({ common, setHardfork: true }) + let vm = await VM.create({ common, setHardfork: true, genesisState: {} }) assert.equal((vm as any)._setHardfork, true, 'should set setHardfork option') - vm = await VM.create({ common, setHardfork: 5001 }) + vm = await VM.create({ common, setHardfork: 5001, genesisState: {} }) assert.equal((vm as any)._setHardfork, BigInt(5001), 'should set setHardfork option') }) }) From 43d6b45d6e7b5a00866423ebcb746b2c16eb66aa Mon Sep 17 00:00:00 2001 From: harkamal Date: Tue, 4 Jul 2023 22:21:16 +0530 Subject: [PATCH 02/10] lint --- packages/client/test/rpc/helpers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/test/rpc/helpers.ts b/packages/client/test/rpc/helpers.ts index 60ae8594ac..320b94c73d 100644 --- a/packages/client/test/rpc/helpers.ts +++ b/packages/client/test/rpc/helpers.ts @@ -82,8 +82,8 @@ export function createClient(clientOpts: Partial = {}) { }) const blockchain = clientOpts.blockchain ?? mockBlockchain() - // @ts-ignore TODO Move to async Chain.create() initialization const chain = + // @ts-ignore TODO Move to async Chain.create() initialization clientOpts.chain ?? new Chain({ config, blockchain: blockchain as any, genesisState }) chain.opened = true From df837453e3dde8d19965b9cbc46471afdbb8f0e7 Mon Sep 17 00:00:00 2001 From: harkamal Date: Tue, 4 Jul 2023 22:38:32 +0530 Subject: [PATCH 03/10] address genesisstate in test helper --- packages/client/test/rpc/helpers.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/client/test/rpc/helpers.ts b/packages/client/test/rpc/helpers.ts index 320b94c73d..b9f9d46b42 100644 --- a/packages/client/test/rpc/helpers.ts +++ b/packages/client/test/rpc/helpers.ts @@ -1,6 +1,7 @@ import { BlockHeader } from '@ethereumjs/block' import { Blockchain } from '@ethereumjs/blockchain' import { Chain as ChainEnum, Common, parseGethGenesis } from '@ethereumjs/common' +import { getGenesis } from '@ethereumjs/genesis' import { Address, KECCAK256_RLP, hexToBytes, parseGethGenesisState } from '@ethereumjs/util' import { Server as RPCServer } from 'jayson/promise' import { MemoryLevel } from 'memory-level' @@ -71,7 +72,7 @@ export function createManager(client: EthereumClient) { export function createClient(clientOpts: Partial = {}) { const common: Common = clientOpts.commonChain ?? new Common({ chain: ChainEnum.Mainnet }) - const genesisState = clientOpts.genesisState ?? {} + const genesisState = clientOpts.genesisState ?? getGenesis(Number(common.chainId())) ?? {} const config = new Config({ transports: [], common, From 1f75f170168435fcae630dbfc0871529fb979c3a Mon Sep 17 00:00:00 2001 From: harkamal Date: Wed, 5 Jul 2023 13:43:27 +0530 Subject: [PATCH 04/10] fix client spec --- packages/client/test/rpc/eth/getBalance.spec.ts | 4 +++- packages/client/test/rpc/eth/getCode.spec.ts | 4 +++- packages/client/test/rpc/eth/getTransactionCount.spec.ts | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/client/test/rpc/eth/getBalance.spec.ts b/packages/client/test/rpc/eth/getBalance.spec.ts index 102ca0fe31..8e96e39bb0 100644 --- a/packages/client/test/rpc/eth/getBalance.spec.ts +++ b/packages/client/test/rpc/eth/getBalance.spec.ts @@ -1,6 +1,7 @@ import { Block } from '@ethereumjs/block' import { Blockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' +import { getGenesis } from '@ethereumjs/genesis' import { LegacyTransaction } from '@ethereumjs/tx' import { Address, bigIntToHex } from '@ethereumjs/util' import * as tape from 'tape' @@ -28,7 +29,8 @@ tape(`${method}: ensure balance deducts after a tx`, async (t) => { // since synchronizer.run() is not executed in the mock setup, // manually run stateManager.generateCanonicalGenesis() - await vm.stateManager.generateCanonicalGenesis({}) + const genesisState = getGenesis(Chain.Mainnet) + await vm.stateManager.generateCanonicalGenesis(genesisState) // genesis address with balance const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/eth/getCode.spec.ts b/packages/client/test/rpc/eth/getCode.spec.ts index 5302360461..27d21bd6e0 100644 --- a/packages/client/test/rpc/eth/getCode.spec.ts +++ b/packages/client/test/rpc/eth/getCode.spec.ts @@ -1,6 +1,7 @@ import { Block } from '@ethereumjs/block' import { Blockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' +import { getGenesis } from '@ethereumjs/genesis' import { LegacyTransaction } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' import * as tape from 'tape' @@ -25,7 +26,8 @@ tape(`${method}: call with valid arguments`, async (t) => { const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService t.notEqual(execution, undefined, 'should have valid execution') const { vm } = execution - await vm.stateManager.generateCanonicalGenesis({}) + const genesisState = getGenesis(Chain.Mainnet) + await vm.stateManager.generateCanonicalGenesis(genesisState) // genesis address const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') diff --git a/packages/client/test/rpc/eth/getTransactionCount.spec.ts b/packages/client/test/rpc/eth/getTransactionCount.spec.ts index 704ca4d499..a28ef716e2 100644 --- a/packages/client/test/rpc/eth/getTransactionCount.spec.ts +++ b/packages/client/test/rpc/eth/getTransactionCount.spec.ts @@ -1,6 +1,7 @@ import { Block } from '@ethereumjs/block' import { Blockchain } from '@ethereumjs/blockchain' import { Chain, Common, Hardfork } from '@ethereumjs/common' +import { getGenesis } from '@ethereumjs/genesis' import { LegacyTransaction } from '@ethereumjs/tx' import { Address } from '@ethereumjs/util' import * as tape from 'tape' @@ -32,7 +33,8 @@ tape(`${method}: call with valid arguments`, async (t) => { // since synchronizer.run() is not executed in the mock setup, // manually run stateManager.generateCanonicalGenesis() - await vm.stateManager.generateCanonicalGenesis({}) + const genesisState = getGenesis(Chain.Mainnet) + await vm.stateManager.generateCanonicalGenesis(genesisState) // a genesis address const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997') From 28b2d6555de107248a1cdd79f8fba5cbceba6592 Mon Sep 17 00:00:00 2001 From: harkamal Date: Wed, 5 Jul 2023 13:57:47 +0530 Subject: [PATCH 05/10] add as a dev dependancy in trie for tests --- package-lock.json | 2 ++ packages/trie/package.json | 1 + 2 files changed, 3 insertions(+) diff --git a/package-lock.json b/package-lock.json index 7478420d23..b9a1913d9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21445,6 +21445,7 @@ "readable-stream": "^3.6.0" }, "devDependencies": { + "@ethereumjs/genesis": "^0.0.1", "@types/benchmark": "^1.0.33", "0x": "^4.9.1", "abstract-level": "^1.0.3", @@ -23525,6 +23526,7 @@ "@ethereumjs/trie": { "version": "file:packages/trie", "requires": { + "@ethereumjs/genesis": "^0.0.1", "@ethereumjs/rlp": "^4.0.1", "@ethereumjs/util": "^8.0.6", "@types/benchmark": "^1.0.33", diff --git a/packages/trie/package.json b/packages/trie/package.json index 7c74d03807..0e8286dd44 100644 --- a/packages/trie/package.json +++ b/packages/trie/package.json @@ -59,6 +59,7 @@ "readable-stream": "^3.6.0" }, "devDependencies": { + "@ethereumjs/genesis": "^0.0.1", "0x": "^4.9.1", "@types/benchmark": "^1.0.33", "abstract-level": "^1.0.3", From 2337f06fe050662c347d253d3fe0e1ab18adb4ef Mon Sep 17 00:00:00 2001 From: harkamal Date: Wed, 5 Jul 2023 14:21:32 +0530 Subject: [PATCH 06/10] cleanup genesis state references in client and add some comments --- packages/blockchain/src/blockchain.ts | 4 +++- packages/blockchain/src/types.ts | 3 +++ packages/client/src/execution/execution.ts | 5 ----- packages/client/src/execution/vmexecution.ts | 2 +- packages/client/src/service/fullethereumservice.ts | 1 - packages/client/test/rpc/helpers.ts | 2 +- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/blockchain/src/blockchain.ts b/packages/blockchain/src/blockchain.ts index aafcb4f042..0bd3a6c299 100644 --- a/packages/blockchain/src/blockchain.ts +++ b/packages/blockchain/src/blockchain.ts @@ -208,6 +208,8 @@ export class Blockchain implements BlockchainInterface { * values from the DB and makes these available to the consumers of * Blockchain. * + * @param opts An options object to provide genesisBlock or ways to contruct it + * * @hidden */ private async _init(opts: GenesisOptions = {}): Promise { @@ -1353,7 +1355,7 @@ export class Blockchain implements BlockchainInterface { } /** - * Returns the genesis state root + * Returns the genesis state root if chain is well known or an empty state's root otherwise */ async function getGenesisStateRoot(chainId: Chain): Promise { const chainGenesis = ChainGenesis[chainId] diff --git a/packages/blockchain/src/types.ts b/packages/blockchain/src/types.ts index 84a0d0740e..d0a64a8441 100644 --- a/packages/blockchain/src/types.ts +++ b/packages/blockchain/src/types.ts @@ -117,6 +117,9 @@ export interface GenesisOptions { */ genesisState?: GenesisState + /** + * State root of the genesis state + */ genesisStateRoot?: Uint8Array } diff --git a/packages/client/src/execution/execution.ts b/packages/client/src/execution/execution.ts index 8d51514009..c0c43c1ddd 100644 --- a/packages/client/src/execution/execution.ts +++ b/packages/client/src/execution/execution.ts @@ -1,6 +1,5 @@ import type { Chain } from '../blockchain' import type { Config } from '../config' -import type { GenesisState } from '@ethereumjs/util' import type { AbstractLevel } from 'abstract-level' export interface ExecutionOptions { @@ -15,8 +14,6 @@ export interface ExecutionOptions { /** Chain */ chain: Chain - - genesisState?: GenesisState } export abstract class Execution { @@ -25,7 +22,6 @@ export abstract class Execution { protected stateDB?: AbstractLevel protected metaDB?: AbstractLevel protected chain: Chain - protected _customGenesisState?: GenesisState /** Custom genesis state */ public running: boolean = false public started: boolean = false @@ -39,7 +35,6 @@ export abstract class Execution { this.chain = options.chain this.stateDB = options.stateDB this.metaDB = options.metaDB - this._customGenesisState = options.genesisState } /** diff --git a/packages/client/src/execution/vmexecution.ts b/packages/client/src/execution/vmexecution.ts index 8a03dd2c24..198574f4ac 100644 --- a/packages/client/src/execution/vmexecution.ts +++ b/packages/client/src/execution/vmexecution.ts @@ -134,7 +134,7 @@ export class VMExecution extends Execution { this.config.logger.info(`Initializing VM execution hardfork=${this.hardfork}`) if (number === BigInt(0)) { const genesisState = - this._customGenesisState ?? getGenesis(Number(this.vm.common.chainId())) + this.chain['_customGenesisState'] ?? getGenesis(Number(this.vm.common.chainId())) if (!genesisState) { throw new Error('genesisState not available') } diff --git a/packages/client/src/service/fullethereumservice.ts b/packages/client/src/service/fullethereumservice.ts index 431ca3b7e4..b6fcf59b86 100644 --- a/packages/client/src/service/fullethereumservice.ts +++ b/packages/client/src/service/fullethereumservice.ts @@ -49,7 +49,6 @@ export class FullEthereumService extends EthereumService { config: options.config, stateDB: options.stateDB, metaDB: options.metaDB, - genesisState: options.genesisState, chain: this.chain, }) diff --git a/packages/client/test/rpc/helpers.ts b/packages/client/test/rpc/helpers.ts index b9f9d46b42..e5ef810d79 100644 --- a/packages/client/test/rpc/helpers.ts +++ b/packages/client/test/rpc/helpers.ts @@ -127,7 +127,7 @@ export function createClient(clientOpts: Partial = {}) { let execution if (!(clientOpts.includeVM === false)) { const metaDB: any = clientOpts.enableMetaDB === true ? new MemoryLevel() : undefined - execution = new VMExecution({ config, chain, metaDB, genesisState }) + execution = new VMExecution({ config, chain, metaDB }) } let peers = [1, 2, 3] From 5105d7d40ead2d2b165257b44feb4b9e9daf2a7b Mon Sep 17 00:00:00 2001 From: harkamal Date: Wed, 5 Jul 2023 14:37:54 +0530 Subject: [PATCH 07/10] further cleanup genesis state passing --- packages/client/src/client.ts | 3 ++- packages/client/src/service/ethereumservice.ts | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index c7db2fbe01..ea737252e3 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -50,6 +50,8 @@ export interface EthereumClientOptions { /* How often to discover new peers */ refreshInterval?: number + + /* custom genesisState if any for the chain */ genesisState?: GenesisState } @@ -91,7 +93,6 @@ export class EthereumClient { chainDB: options.chainDB, stateDB: options.stateDB, metaDB: options.metaDB, - genesisState: options.genesisState, chain, }), ] diff --git a/packages/client/src/service/ethereumservice.ts b/packages/client/src/service/ethereumservice.ts index e80ec90fe9..eb340c7774 100644 --- a/packages/client/src/service/ethereumservice.ts +++ b/packages/client/src/service/ethereumservice.ts @@ -7,7 +7,6 @@ import { Service } from './service' import type { Synchronizer } from '../sync' import type { V8Engine } from '../util' import type { ServiceOptions } from './service' -import type { GenesisState } from '@ethereumjs/util' import type { AbstractLevel } from 'abstract-level' export interface EthereumServiceOptions extends ServiceOptions { @@ -28,8 +27,6 @@ export interface EthereumServiceOptions extends ServiceOptions { /* Protocol timeout in ms (default: 6000) */ timeout?: number - - genesisState?: GenesisState } /** From 5b581c73f56ca8616014026e8dd253d8d9ecb5ba Mon Sep 17 00:00:00 2001 From: harkamal Date: Wed, 5 Jul 2023 14:47:28 +0530 Subject: [PATCH 08/10] improve jsdocs --- packages/common/src/enums.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/common/src/enums.ts b/packages/common/src/enums.ts index 5f066d63ef..a052f8de8b 100644 --- a/packages/common/src/enums.ts +++ b/packages/common/src/enums.ts @@ -6,8 +6,10 @@ export enum Chain { Sepolia = 11155111, } -// Genesis meta gives the genesis state info which is uncoupled with common's genesis params -type GenesiState = { +/** + * Genesis state meta info which is decoupled from common's genesis params + */ +type GenesisState = { /* blockNumber that can be used to update and track the regenesis marker */ blockNumber: bigint /* stateRoot of the chain at the blockNumber */ @@ -15,7 +17,10 @@ type GenesiState = { } // Having this info as record will force typescript to make sure no chain is missed -export const ChainGenesis: Record = { +/** + * GenesisState info about well known ethereum chains + */ +export const ChainGenesis: Record = { [Chain.Mainnet]: { blockNumber: BigInt(0), stateRoot: hexToBytes('0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544'), From fadc0102f2205b226fd3fd024089efedfa4e3d1f Mon Sep 17 00:00:00 2001 From: harkamal Date: Wed, 5 Jul 2023 15:02:00 +0530 Subject: [PATCH 09/10] fix jsdocs --- packages/vm/src/types.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/vm/src/types.ts b/packages/vm/src/types.ts index 184166cf2c..9c6a8f2b00 100644 --- a/packages/vm/src/types.ts +++ b/packages/vm/src/types.ts @@ -120,11 +120,8 @@ export interface VMOpts { */ activatePrecompiles?: boolean /** - * If true, the state of the VM will add the genesis state given by {@link Blockchain.genesisState} to a newly - * created state manager instance. Note that if stateManager option is also passed as argument - * this flag won't have any effect. - * - * Default: `false` + * A genesisState to generate canonical genesis for the "in-house" created stateManager if external + * stateManager not provided for the VM, defaults to an empty state */ genesisState?: GenesisState From 56b9afbb4af573a4334278d7b5fa7712882a5fb2 Mon Sep 17 00:00:00 2001 From: harkamal Date: Wed, 5 Jul 2023 16:24:23 +0530 Subject: [PATCH 10/10] fix client sim runner --- packages/client/test/sim/simutils.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/client/test/sim/simutils.ts b/packages/client/test/sim/simutils.ts index 4adb6d0ca7..9fce1c0b73 100644 --- a/packages/client/test/sim/simutils.ts +++ b/packages/client/test/sim/simutils.ts @@ -428,7 +428,14 @@ export async function createInlineClient(config: any, common: any, customGenesis validateConsensus: false, }) config.chainCommon.setForkHashes(blockchain.genesisBlock.hash()) - const inlineClient = await EthereumClient.create({ config, blockchain, chainDB, stateDB, metaDB }) + const inlineClient = await EthereumClient.create({ + config, + blockchain, + chainDB, + stateDB, + metaDB, + genesisState: customGenesisState, + }) await inlineClient.open() await inlineClient.start() return inlineClient