Skip to content

Commit

Permalink
common: add customHardforks option
Browse files Browse the repository at this point in the history
  • Loading branch information
jochem-brouwer committed Feb 28, 2024
1 parent 4427858 commit afabbec
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 8 deletions.
9 changes: 7 additions & 2 deletions packages/common/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ export class Common {
// Assign hardfork changes in the sequence of the applied hardforks
this.HARDFORK_CHANGES = this.hardforks().map((hf) => [
hf.name as HardforkSpecKeys,
HARDFORK_SPECS[hf.name as HardforkSpecKeys],
HARDFORK_SPECS[hf.name] ??
(this._chainParams.customHardforks && this._chainParams.customHardforks[hf.name]),
])
this._hardfork = this.DEFAULT_HARDFORK
if (opts.hardfork !== undefined) {
Expand Down Expand Up @@ -966,7 +967,11 @@ export class Common {
* @returns {Array} Array with arrays of hardforks
*/
hardforks(): HardforkTransitionConfig[] {
return this._chainParams.hardforks
const hfs = this._chainParams.hardforks
if (this._chainParams.customHardforks !== undefined) {
this._chainParams.customHardforks
}
return hfs
}

/**
Expand Down
8 changes: 2 additions & 6 deletions packages/common/src/hardforks.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import type { HardforkConfig } from './types.js'
import type { HardforksDict } from './types.js'

type HardforksDict = {
[key: string]: HardforkConfig
}

enum Status {
export enum Status {
Draft = 'draft',
Review = 'review',
Final = 'final',
Expand Down
5 changes: 5 additions & 0 deletions packages/common/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface ChainConfig {
url?: string
genesis: GenesisBlockConfig
hardforks: HardforkTransitionConfig[]
customHardforks?: HardforksDict
bootstrapNodes: BootstrapNodeConfig[]
dnsNetworks?: string[]
consensus: ConsensusConfig
Expand Down Expand Up @@ -194,3 +195,7 @@ export type HardforkConfig = {
eips?: number[]
consensus?: ConsensusConfig
} & EIPOrHFConfig

export type HardforksDict = {
[key: string]: HardforkConfig
}
91 changes: 91 additions & 0 deletions packages/common/test/customChains.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,52 @@
import { assert, describe, it } from 'vitest'

import { Status } from '../src/hardforks.js'
import { Chain, Common, ConsensusType, CustomChain, Hardfork } from '../src/index.js'

import * as testnet from './data/testnet.json'
import * as testnet2 from './data/testnet2.json'
import * as testnet3 from './data/testnet3.json'

describe('Test common custom hardforks', () => {
it('Instantiate new hardfork with EIPs', () => {
const c = Common.custom({
customHardforks: {
testEIP2935Hardfork: {
name: 'testEIP2935Hardfork',
comment: 'Start of the Ethereum main chain',
url: '',
status: Status.Final,
eips: [2935],
},
},
hardforks: [
{
name: 'chainstart',
block: 0,
},
{
// Note: this custom hardfork name MUST be in customHardforks as field
// If this is not the case, Common will throw with a random error
// Should we throw early with a descriptive error? TODO
name: 'testEIP2935Hardfork',
block: null,
timestamp: 1000,
},
],
})
assert.equal(c.hardfork(), Hardfork.Shanghai)
c.setHardforkBy({
blockNumber: 0,
})
assert.equal(c.hardfork(), Hardfork.Chainstart)
c.setHardforkBy({
blockNumber: 5,
timestamp: 1000,
})
assert.equal(c.hardfork(), 'testEIP2935Hardfork')
})
})

describe('[Common]: Custom chains', () => {
it('chain -> object: should provide correct access to private network chain parameters', () => {
const c = new Common({ chain: testnet, hardfork: Hardfork.Byzantium })
Expand Down Expand Up @@ -151,6 +192,56 @@ describe('[Common]: Custom chains', () => {
'customChains, should allow to switch custom chain'
)
})

it('customHardforks parameter: initialization and transition tests', () => {
const c = Common.custom({
customHardforks: {
testEIP2935Hardfork: {
name: 'testEIP2935Hardfork',
comment: 'Start of the Ethereum main chain',
url: '',
status: Status.Final,
eips: [2935],
},
},
hardforks: [
{
name: 'chainstart',
block: 0,
},
{
name: 'berlin',
block: null,
timestamp: 999,
},
{
// Note: this custom hardfork name MUST be in customHardforks as field
// If this is not the case, Common will throw with a random error
// Should we throw early with a descriptive error? TODO
name: 'testEIP2935Hardfork',
block: null,
timestamp: 1000,
},
],
})
// Note: default HF of Common is currently Shanghai
// Did not pass any "hardfork" param
assert.equal(c.hardfork(), Hardfork.Shanghai)
c.setHardforkBy({
blockNumber: 0,
})
assert.equal(c.hardfork(), Hardfork.Chainstart)
c.setHardforkBy({
blockNumber: 1,
timestamp: 999,
})
assert.equal(c.hardfork(), Hardfork.Berlin)
c.setHardforkBy({
blockNumber: 1,
timestamp: 1000,
})
assert.equal(c.hardfork(), 'testEIP2935Hardfork')
})
})

describe('custom chain setup with hardforks with undefined/null block numbers', () => {
Expand Down

0 comments on commit afabbec

Please sign in to comment.