Skip to content

Commit

Permalink
common: add support for new Sepolia chain (#1581)
Browse files Browse the repository at this point in the history
* common: add support for new Sepolia chain
* common: updates in sepolia.json chain config
* common: sepolia configuration fixes
* add initialBaseFee logic to block header constructor
* block: improve londonHfBlock var name for clarity
* common: add require for sepolia genesisStates
* block: fix tests with initialBaseFeePerGas
* use Hardfork enum
* organize test util code
Co-authored-by: holgerd77 <Holger.Drewes@gmail.com>
Co-authored-by: Ryan Ghods <ryan@ryanio.com>
  • Loading branch information
emersonmacro authored Jan 3, 2022
1 parent 3751bbd commit 23a7f35
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 28 deletions.
22 changes: 15 additions & 7 deletions packages/block/src/header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,15 @@ export class BlockHeader {

if (this._common.isActivatedEIP(1559)) {
if (baseFeePerGas === undefined) {
baseFeePerGas = new BN(7)
const londonHfBlock = this._common.hardforkBlockBN(Hardfork.London)
const isInitialEIP1559Block = londonHfBlock && number.eq(londonHfBlock)
if (isInitialEIP1559Block) {
baseFeePerGas = new BN(this._common.param('gasConfig', 'initialBaseFee'))
} else {
// Minimum possible value for baseFeePerGas is 7,
// so we use it as the default if the field is missing.
baseFeePerGas = new BN(7)
}
}
} else {
if (baseFeePerGas) {
Expand Down Expand Up @@ -455,7 +463,7 @@ export class BlockHeader {
// We use a ! here as TS cannot follow this hardfork-dependent logic, but it always gets assigned
let dif!: BN

if (this._common.hardforkGteHardfork(hardfork, 'byzantium')) {
if (this._common.hardforkGteHardfork(hardfork, Hardfork.Byzantium)) {
// max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99) (EIP100)
const uncleAddend = parentBlockHeader.uncleHash.equals(KECCAK256_RLP_ARRAY) ? 1 : 2
let a = blockTs.sub(parentTs).idivn(9).ineg().iaddn(uncleAddend)
Expand All @@ -467,13 +475,13 @@ export class BlockHeader {
dif = parentDif.add(offset.mul(a))
}

if (this._common.hardforkGteHardfork(hardfork, 'byzantium')) {
if (this._common.hardforkGteHardfork(hardfork, Hardfork.Byzantium)) {
// Get delay as parameter from common
num.isubn(this._common.param('pow', 'difficultyBombDelay'))
if (num.ltn(0)) {
num = new BN(0)
}
} else if (this._common.hardforkGteHardfork(hardfork, 'homestead')) {
} else if (this._common.hardforkGteHardfork(hardfork, Hardfork.Homestead)) {
// 1 - (block_timestamp - parent_timestamp) // 10
let a = blockTs.sub(parentTs).idivn(10).ineg().iaddn(1)
const cutoff = new BN(-99)
Expand Down Expand Up @@ -558,7 +566,7 @@ export class BlockHeader {
let parentGasLimit = parentBlockHeader.gasLimit
// EIP-1559: assume double the parent gas limit on fork block
// to adopt to the new gas target centered logic
const londonHardforkBlock = this._common.hardforkBlockBN('london')
const londonHardforkBlock = this._common.hardforkBlockBN(Hardfork.London)
if (londonHardforkBlock && this.number.eq(londonHardforkBlock)) {
const elasticity = new BN(this._common.param('gasConfig', 'elasticityMultiplier'))
parentGasLimit = parentGasLimit.mul(elasticity)
Expand Down Expand Up @@ -708,8 +716,8 @@ export class BlockHeader {
const msg = this._errorMsg('EIP1559 block has no base fee field')
throw new Error(msg)
}
const block = this._common.hardforkBlockBN('london')
const isInitialEIP1559Block = block && this.number.eq(block)
const londonHfBlock = this._common.hardforkBlockBN(Hardfork.London)
const isInitialEIP1559Block = londonHfBlock && this.number.eq(londonHfBlock)
if (isInitialEIP1559Block) {
const initialBaseFee = new BN(this._common.param('gasConfig', 'initialBaseFee'))
if (!this.baseFeePerGas!.eq(initialBaseFee)) {
Expand Down
22 changes: 13 additions & 9 deletions packages/block/test/block.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ tape('[Block]: block functions', function (t) {
},
{ common, hardforkByBlockNumber: true }
)
st.equal(block._common.hardfork(), 'berlin', 'should use hardforkByBlockNumber option')
st.equal(block._common.hardfork(), Hardfork.Berlin, 'should use hardforkByBlockNumber option')

block = Block.fromBlockData(
{
Expand All @@ -88,7 +88,11 @@ tape('[Block]: block functions', function (t) {
},
{ common, hardforkByTD: 5001 }
)
st.equal(block._common.hardfork(), 'merge', 'should use hardforkByTD option (td > threshold)')
st.equal(
block._common.hardfork(),
Hardfork.Merge,
'should use hardforkByTD option (td > threshold)'
)

block = Block.fromBlockData(
{
Expand All @@ -100,7 +104,7 @@ tape('[Block]: block functions', function (t) {
)
st.equal(
block._common.hardfork(),
'berlin',
Hardfork.Berlin,
'should work with hardforkByTD option (td < threshold)'
)

Expand Down Expand Up @@ -522,7 +526,7 @@ tape('[Block]: block functions', function (t) {
const common = new Common({ chain: Chain.Mainnet })
common.setHardfork(Hardfork.Berlin)

const mainnetForkBlock = common.hardforkBlockBN('london')
const mainnetForkBlock = common.hardforkBlockBN(Hardfork.London)
const rootBlock = Block.fromBlockData({
header: {
number: mainnetForkBlock!.subn(3),
Expand Down Expand Up @@ -552,10 +556,10 @@ tape('[Block]: block functions', function (t) {
await blockchain.putBlock(forkBlock)
await preForkBlock.validate(blockchain)

st.ok(common.hardfork() === 'london', 'validation did not change common hardfork')
st.ok(common.hardfork() === Hardfork.London, 'validation did not change common hardfork')
await forkBlock2.validate(blockchain)

st.ok(common.hardfork() === 'london', 'validation did not change common hardfork')
st.ok(common.hardfork() === Hardfork.London, 'validation did not change common hardfork')

const forkBlock2HeaderData = forkBlock2.header.toJSON()
const uncleHeaderData = unclePreFork.header.toJSON()
Expand All @@ -578,8 +582,8 @@ tape('[Block]: block functions', function (t) {

await forkBlock_ValidCommon.validate(blockchain)

st.pass('succesfully validated a pre-london uncle on a london block')
st.ok(common.hardfork() === 'london', 'validation did not change common hardfork')
st.pass('successfully validated a pre-london uncle on a london block')
st.ok(common.hardfork() === Hardfork.London, 'validation did not change common hardfork')

const forkBlock_InvalidCommon = Block.fromBlockData(
{
Expand All @@ -602,7 +606,7 @@ tape('[Block]: block functions', function (t) {
)
}

st.ok(common.hardfork() === 'london', 'validation did not change common hardfork')
st.ok(common.hardfork() === Hardfork.London, 'validation did not change common hardfork')
}
)

Expand Down
17 changes: 8 additions & 9 deletions packages/block/test/eip1559block.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ tape('EIP1559 tests', function (t) {
st.end()
})

t.test('Header -> Initialization', async function (st) {
try {
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul })
t.test('Header -> Initialization', function (st) {
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul })
st.throws(() => {
BlockHeader.fromHeaderData(
{
number: new BN(1),
Expand All @@ -54,11 +54,9 @@ tape('EIP1559 tests', function (t) {
{
common,
}
)
} catch (e: any) {
const expectedError = 'A base fee for a block can only be set with EIP1559 being activated'
st.ok(e.message.includes(expectedError), 'should throw with EIP1559 not being activated')
}
),
'should throw when setting baseFeePerGas with EIP1559 not being activated'
})
st.end()
})

Expand All @@ -69,6 +67,7 @@ tape('EIP1559 tests', function (t) {
parentHash: genesis.hash(),
gasLimit: genesis.header.gasLimit.muln(2), // Special case on EIP-1559 transition block
timestamp: new BN(1),
baseFeePerGas: 100,
},
{
calcDifficultyFromHeader: genesis.header,
Expand All @@ -79,7 +78,7 @@ tape('EIP1559 tests', function (t) {

try {
await header.validate(blockchain1)
st.fail('should throw')
st.fail('should throw when baseFeePerGas is not set to initial base fee')
} catch (e: any) {
const expectedError = 'Initial EIP1559 block does not have initial base fee'
st.ok(
Expand Down
14 changes: 11 additions & 3 deletions packages/block/test/util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Common, { Chain } from '@ethereumjs/common'
import Common, { Chain, Hardfork } from '@ethereumjs/common'
import { BN, rlp, keccak256 } from 'ethereumjs-util'
import { Block, BlockHeader } from '../src'

Expand All @@ -21,15 +21,23 @@ function createBlock(
throw new Error('extra data graffiti must be 32 bytes or less')
}

const number = parentBlock.header.number.addn(1)
const timestamp = parentBlock.header.timestamp.addn(1)

const londonHfBlock = common.hardforkBlockBN(Hardfork.London)
const baseFeePerGas =
londonHfBlock && number.gt(londonHfBlock) ? parentBlock.header.calcNextBaseFee() : undefined

return Block.fromBlockData(
{
header: {
number: parentBlock.header.number.addn(1),
number,
parentHash: parentBlock.hash(),
timestamp: parentBlock.header.timestamp.addn(1),
timestamp,
gasLimit: new BN(5000),
extraData: Buffer.from(extraData),
uncleHash: keccak256(rlp.encode(uncles.map((uh) => uh.raw()))),
baseFeePerGas,
},
uncleHeaders: uncles,
},
Expand Down
1 change: 1 addition & 0 deletions packages/common/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ Supported chains:
- `rinkeby` (`Chain.Rinkeby`)
- `kovan` (`Chain.Kovan`)
- `goerli` (`Chain.Goerli`)
- `sepolia` (`Chain.Sepolia`)
- Private/custom chain parameters

The following chain-specific parameters are provided:
Expand Down
3 changes: 3 additions & 0 deletions packages/common/src/chains/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ropsten from './ropsten.json'
import rinkeby from './rinkeby.json'
import kovan from './kovan.json'
import goerli from './goerli.json'
import sepolia from './sepolia.json'

/**
* @hidden
Expand All @@ -15,13 +16,15 @@ export function _getInitializedChains(customChains?: Chain[]) {
'4': 'rinkeby',
'42': 'kovan',
'5': 'goerli',
'11155111': 'sepolia',
}
const chains: any = {
mainnet,
ropsten,
rinkeby,
kovan,
goerli,
sepolia,
}
if (customChains) {
for (const chain of customChains) {
Expand Down
106 changes: 106 additions & 0 deletions packages/common/src/chains/sepolia.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
{
"name": "sepolia",
"chainId": 11155111,
"networkId": 11155111,
"defaultHardfork": "istanbul",
"consensus": {
"type": "pow",
"algorithm": "ethash",
"ethash": {}
},
"comment": "PoW test network to replace Ropsten",
"url": "https://github.com/ethereum/go-ethereum/pull/23730",
"genesis": {
"hash": "0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9",
"timestamp": "0x6159af19",
"gasLimit": 30000000,
"difficulty": 131072,
"nonce": "0x0000000000000000",
"extraData": "0x5365706f6c69612c20417468656e732c204174746963612c2047726565636521",
"stateRoot": "0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494"
},
"hardforks": [
{
"name": "chainstart",
"block": 0,
"forkHash": "0xfe3366e7"
},
{
"name": "homestead",
"block": 0,
"forkHash": "0xfe3366e7"
},
{
"name": "tangerineWhistle",
"block": 0,
"forkHash": "0xfe3366e7"
},
{
"name": "spuriousDragon",
"block": 0,
"forkHash": "0xfe3366e7"
},
{
"name": "byzantium",
"block": 0,
"forkHash": "0xfe3366e7"
},
{
"name": "constantinople",
"block": 0,
"forkHash": "0xfe3366e7"
},
{
"name": "petersburg",
"block": 0,
"forkHash": "0xfe3366e7"
},
{
"name": "istanbul",
"block": 0,
"forkHash": "0xfe3366e7"
},
{
"name": "muirGlacier",
"block": 0,
"forkHash": "0xfe3366e7"
},
{
"name": "berlin",
"block": 0,
"forkHash": "0xfe3366e7"
},
{
"name": "london",
"block": 0,
"forkHash": "0xfe3366e7"
},
{
"name": "merge",
"block": null,
"forkHash": null
},
{
"name": "shanghai",
"block": null,
"forkHash": null
}
],
"bootstrapNodes": [
{
"ip": "18.168.182.86",
"port": 30303,
"id": "9246d00bc8fd1742e5ad2428b80fc4dc45d786283e05ef6edbd9002cbc335d40998444732fbe921cb88e1d2c73d1b1de53bae6a2237996e9bfe14f871baf7066",
"location": "",
"comment": "geth"
},
{
"ip": "52.14.151.177",
"port": 30303,
"id": "ec66ddcf1a974950bd4c782789a7e04f8aa7110a72569b6e65fcd51e937e74eed303b1ea734e4d19cfaec9fbff9b6ee65bf31dcb50ba79acce9dd63a6aca61c7",
"location": "",
"comment": "besu"
}
],
"dnsNetworks": []
}
2 changes: 2 additions & 0 deletions packages/common/src/genesisStates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ const genesisStates: genesisStatesType = {
'4': 'rinkeby',
'42': 'kovan',
'5': 'goerli',
'11155111': 'sepolia',
},
mainnet: require('./mainnet.json'),
ropsten: require('./ropsten.json'),
rinkeby: require('./rinkeby.json'),
kovan: require('./kovan.json'),
goerli: require('./goerli.json'),
sepolia: require('./sepolia.json'),
}

/**
Expand Down
17 changes: 17 additions & 0 deletions packages/common/src/genesisStates/sepolia.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"0xa2A6d93439144FFE4D27c9E088dCD8b783946263": "0xD3C21BCECCEDA1000000",
"0xBc11295936Aa79d594139de1B2e12629414F3BDB": "0xD3C21BCECCEDA1000000",
"0x7cF5b79bfe291A67AB02b393E456cCc4c266F753": "0xD3C21BCECCEDA1000000",
"0xaaec86394441f915bce3e6ab399977e9906f3b69": "0xD3C21BCECCEDA1000000",
"0xF47CaE1CF79ca6758Bfc787dbD21E6bdBe7112B8": "0xD3C21BCECCEDA1000000",
"0xd7eDDB78ED295B3C9629240E8924fb8D8874ddD8": "0xD3C21BCECCEDA1000000",
"0x8b7F0977Bb4f0fBE7076FA22bC24acA043583F5e": "0xD3C21BCECCEDA1000000",
"0xe2e2659028143784d557bcec6ff3a0721048880a": "0xD3C21BCECCEDA1000000",
"0xd9a5179f091d85051d3c982785efd1455cec8699": "0xD3C21BCECCEDA1000000",
"0xbeef32ca5b9a198d27B4e02F4c70439fE60356Cf": "0xD3C21BCECCEDA1000000",
"0x0000006916a87b82333f4245046623b23794c65c": "0x84595161401484A000000",
"0xb21c33de1fab3fa15499c62b59fe0cc3250020d1": "0x52B7D2DCC80CD2E4000000",
"0x10F5d45854e038071485AC9e402308cF80D2d2fE": "0x52B7D2DCC80CD2E4000000",
"0xd7d76c58b3a519e9fA6Cc4D22dC017259BC49F1E": "0x52B7D2DCC80CD2E4000000",
"0x799D329e5f583419167cD722962485926E338F4a": "0xDE0B6B3A7640000"
}
Loading

0 comments on commit 23a7f35

Please sign in to comment.