Skip to content

Commit

Permalink
common: Relocate geth genesis, state parsers to common, blockchain re…
Browse files Browse the repository at this point in the history
…spectively (#2300)

* common: Relocate geth genesis, state parsers to common, blockchain respectively

* lint utils

* relocate setForkHashes

* update readme

* use Common.fromGethGenesis wherever possible

* relocate parseGethGenesis tests

* remove unnecessary await

* fix tests access across common and client

* provide abs path

* add test for parseGethGenesisState

* add test cases for setcommon hashes and correct kiln genesis root

* add stateroot match test

* fix the storage trie to also use key hashing
  • Loading branch information
g11tech committed Sep 22, 2022
1 parent 5ca079f commit 3712a1b
Show file tree
Hide file tree
Showing 20 changed files with 1,252 additions and 292 deletions.
19 changes: 18 additions & 1 deletion packages/blockchain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,24 @@ Starting with v6 responsibility for setting up a custom genesis state moved from

A genesis state can be set along `Blockchain` creation by passing in a custom `genesisBlock` and `genesisState`. For `mainnet` and the official test networks like `sepolia` or `goerli` genesis is already provided with the block data coming from `@ethereumjs/common`. The genesis state is being integrated in the `Blockchain` library (see `genesisStates` folder).

TODO: add code example here!
### Custom genesis from a Geth genesis config

For many custom chains we might come across a genesis configuration, which can be used to build both chain config as well the genesis state (and hence the genesis block as well to start off with)

```typescript
import { Blockchain, parseGethGenesisState } from '@ethereumjs/blockchain'
import { Common, parseGethGenesis } from '@ethereumjs/common'

// Load geth genesis json file into lets say `gethGenesisJson`
const common = Common.fromGethGenesis(gethGenesisJson, { chain: 'customChain' })
const genesisState = parseGethGenesisState(gethGenesisJson)
const blockchain = await Blockchain.create({
genesisState,
common,
})
const genesisBlockHash = blockchain.genesisBlock.hash()
common.setForkHashes(genesisBlockHash)
```

The genesis block from the initialized `Blockchain` can be retrieved via the `Blockchain.genesisBlock` getter. For creating a genesis block from the params in `@ethereumjs/common`, the `createGenesisBlock(stateRoot: Buffer): Block` method can be used.

Expand Down
2 changes: 1 addition & 1 deletion packages/blockchain/src/genesisStates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export async function genesisStateRoot(genesisState: GenesisState) {
account.codeHash = Buffer.from(keccak256(toBuffer(code)))
}
if (storage !== undefined) {
const storageTrie = new Trie()
const storageTrie = new Trie({ useKeyHashing: true })
for (const [k, val] of storage) {
const storageKey = isHexPrefixed(k) ? toBuffer(k) : Buffer.from(k, 'hex')
const storageVal = Buffer.from(
Expand Down
1 change: 1 addition & 0 deletions packages/blockchain/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { Blockchain } from './blockchain'
export { CasperConsensus, CliqueConsensus, Consensus, EthashConsensus } from './consensus'
export { BlockchainInterface, BlockchainOptions } from './types'
export * from './utils'
19 changes: 19 additions & 0 deletions packages/blockchain/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { addHexPrefix, bigIntToHex, isHexPrefixed } from '@ethereumjs/util'

import type { GenesisState } from './genesisStates'
/**
* Parses the geth genesis state into Blockchain {@link GenesisState}
* @param json representing the `alloc` key in a Geth genesis file
*/
export function parseGethGenesisState(json: any) {
const state: GenesisState = {}
for (let address of Object.keys(json.alloc)) {
let { balance, code, storage } = json.alloc[address]
address = addHexPrefix(address)
balance = isHexPrefixed(balance) ? balance : bigIntToHex(BigInt(balance))
code = code !== undefined ? addHexPrefix(code) : undefined
storage = storage !== undefined ? Object.entries(storage) : undefined
state[address] = [balance, code, storage] as any
}
return state
}

0 comments on commit 3712a1b

Please sign in to comment.