Skip to content

Commit

Permalink
Merge pull request #1677 from ethereum-optimism/genesis-json-provider
Browse files Browse the repository at this point in the history
core-utils: add GenesisJsonProvider and fix tests
  • Loading branch information
tynes committed Nov 3, 2021
2 parents 9df4459 + 47b0628 commit 8f21774
Show file tree
Hide file tree
Showing 15 changed files with 670 additions and 26 deletions.
5 changes: 5 additions & 0 deletions .changeset/funny-kings-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@eth-optimism/core-utils': patch
---

Add bytes32ify
5 changes: 3 additions & 2 deletions packages/core-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"lint:check": "eslint .",
"lint:fix": "yarn lint:check --fix",
"pre-commit": "lint-staged",
"test": "ts-mocha test/**/*.spec.ts",
"test:coverage": "nyc ts-mocha test/**/*.spec.ts && nyc merge .nyc_output coverage.json"
"test": "ts-mocha test/*.spec.ts",
"test:coverage": "nyc ts-mocha test/*.spec.ts && nyc merge .nyc_output coverage.json"
},
"devDependencies": {
"@types/chai": "^4.2.18",
Expand Down Expand Up @@ -46,6 +46,7 @@
},
"dependencies": {
"@ethersproject/abstract-provider": "^5.4.1",
"@ethersproject/bytes": "^5.5.0",
"@ethersproject/providers": "^5.4.5",
"chai": "^4.3.4",
"ethers": "^5.4.5",
Expand Down
5 changes: 5 additions & 0 deletions packages/core-utils/src/common/hex-strings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* Imports: External */
import { BigNumber, ethers } from 'ethers'
import { hexZeroPad } from '@ethersproject/bytes'

/**
* Removes "0x" from start of a string if it exists.
Expand Down Expand Up @@ -92,3 +93,7 @@ export const hexStringEquals = (stringA: string, stringB: string): boolean => {

return stringA.toLowerCase() === stringB.toLowerCase()
}

export const bytes32ify = (value: number | BigNumber): string => {
return hexZeroPad(BigNumber.from(value).toHexString(), 32)
}
2 changes: 1 addition & 1 deletion packages/core-utils/src/common/test-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect } from 'chai'
import { BigNumber } from 'ethers'
import { sleep } from './misc'
import { sleep } from './misc'

interface deviationRanges {
percentUpperDeviation?: number
Expand Down
1 change: 1 addition & 0 deletions packages/core-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './bcfg'
export * from './fees'
export * from './provider'
export * from './alias'
export * from './types'
39 changes: 39 additions & 0 deletions packages/core-utils/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Optimism PBC 2021

// Represents the ethereum state
export interface State {
[address: string]: {
nonce: number
balance: string
codeHash: string
root: string
code?: string
storage?: {
[key: string]: string
}
}
}

// Represents a genesis file that geth can consume
export interface Genesis {
config: {
chainId: number
homesteadBlock: number
eip150Block: number
eip155Block: number
eip158Block: number
byzantiumBlock: number
constantinopleBlock: number
petersburgBlock: number
istanbulBlock: number
muirGlacierBlock: number
clique: {
period: number
epoch: number
}
}
difficulty: string
gasLimit: string
extraData: string
alloc: State
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import '../setup'
import './setup'

/* Internal Imports */
import {
encodeAppendSequencerBatch,
decodeAppendSequencerBatch,
sequencerBatch,
} from '../../src'
} from '../src'
import { expect } from 'chai'

describe('BatchEncoder', () => {
Expand Down Expand Up @@ -43,7 +43,7 @@ describe('BatchEncoder', () => {

it('should work with mainnet calldata', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const data = require('../fixtures/appendSequencerBatch.json')
const data = require('./fixtures/appendSequencerBatch.json')
for (const calldata of data.calldata) {
const decoded = sequencerBatch.decode(calldata)
const encoded = sequencerBatch.encode(decoded)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from '../setup'
import * as fees from '../../src/fees'
import { expect } from './setup'
import * as fees from '../src/fees'
import { BigNumber, utils } from 'ethers'

const hundredBillion = 10 ** 11
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expect } from '../setup'
import { expect } from './setup'
import { BigNumber } from 'ethers'

/* Imports: Internal */
Expand All @@ -9,7 +9,7 @@ import {
fromHexString,
toHexString,
padHexString,
} from '../../src'
} from '../src'

describe('remove0x', () => {
it('should return undefined', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect } from '../setup'
import { expect } from './setup'

/* Imports: Internal */
import { sleep } from '../../src'
import { sleep } from '../src'

describe('sleep', async () => {
it('should return wait input amount of ms', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect } from '../setup'
import { expect } from './setup'

/* Imports: Internal */
import { expectApprox, awaitCondition } from '../../src'
import { expectApprox, awaitCondition } from '../src'
import { assert } from 'chai'

describe('awaitCondition', () => {
Expand All @@ -12,7 +12,7 @@ describe('awaitCondition', () => {
return Promise.resolve(i === 2)
}

await awaitCondition(condFn, 50, 3);
await awaitCondition(condFn, 50, 3)
expect(i).to.equal(2)
})

Expand All @@ -24,12 +24,12 @@ describe('awaitCondition', () => {
}

try {
await awaitCondition(condFn, 50, 1);
await awaitCondition(condFn, 50, 1)
} catch (e) {
return;
return
}

assert.fail('Condition never failed, but it should have.');
assert.fail('Condition never failed, but it should have.')
})
})

Expand Down
10 changes: 7 additions & 3 deletions packages/regenesis-surgery/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
"devDependencies": {
"@discoveryjs/json-ext": "^0.5.3",
"@eth-optimism/core-utils": "^0.6.0",
"@ethersproject/abstract-provider": "^5.5.1",
"@ethersproject/bignumber": "^5.5.0",
"@ethersproject/properties": "^5.5.0",
"@ethersproject/providers": "^5.5.0",
"@types/node": "^15.12.2",
"@types/node-fetch": "^3.0.3",
"@uniswap/sdk-core": "^3.0.1",
Expand All @@ -24,13 +28,13 @@
"byline": "^5.0.0",
"chai-as-promised": "^7.1.1",
"dotenv": "^10.0.0",
"ethereumjs-util": "^7.1.2",
"ethereumjs-util": "^7.1.3",
"ethers": "^5.4.5",
"hardhat": "^2.6.5",
"lint-staged": "11.0.0",
"mocha": "^9.1.2",
"node-fetch": "2.6.5",
"solc": "0.8.7-fixed",
"ts-node": "^10.0.0",
"lint-staged": "11.0.0"
"ts-node": "^10.0.0"
}
}
121 changes: 121 additions & 0 deletions packages/regenesis-surgery/test/provider.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { expect } from '@eth-optimism/core-utils/test/setup'
import { ethers, BigNumber } from 'ethers'
import { GenesisJsonProvider } from './provider'
import { Genesis } from '@eth-optimism/core-utils/src/types'
import {
remove0x,
add0x,
} from '@eth-optimism/core-utils/src/common/hex-strings'
import { KECCAK256_RLP_S, KECCAK256_NULL_S } from 'ethereumjs-util'

const account = '0x66a84544bed4ca45b3c024776812abf87728fbaf'

const genesis: Genesis = {
config: {
chainId: 0,
homesteadBlock: 0,
eip150Block: 0,
eip155Block: 0,
eip158Block: 0,
byzantiumBlock: 0,
constantinopleBlock: 0,
petersburgBlock: 0,
istanbulBlock: 0,
muirGlacierBlock: 0,
clique: {
period: 0,
epoch: 0,
},
},
difficulty: '0x',
gasLimit: '0x',
extraData: '0x',
alloc: {
[remove0x(account)]: {
nonce: 101,
balance: '234',
codeHash: ethers.utils.keccak256('0x6080'),
root: '0x',
code: '6080',
storage: {
'0000000000000000000000000000000000000000000000000000000000000002':
'989680',
'0000000000000000000000000000000000000000000000000000000000000003':
'536f6d65205265616c6c7920436f6f6c20546f6b656e204e616d650000000036',
'7d55c28652d09dd36b33c69e81e67cbe8d95f51dc46ab5b17568d616d481854d':
'989680',
},
},
},
}

describe.only('GenesisJsonProvider', () => {
let provider
before(() => {
provider = new GenesisJsonProvider(genesis)
})

it('should get nonce', async () => {
const nonce = await provider.getTransactionCount(account)
expect(nonce).to.deep.eq(101)
})

it('should get nonce on missing account', async () => {
const nonce = await provider.getTransactionCount('0x')
expect(nonce).to.deep.eq(0)
})

it('should get code', async () => {
const code = await provider.getCode(account)
expect(code).to.deep.eq('0x6080')
})

it('should get code on missing account', async () => {
const code = await provider.getCode('0x')
expect(code).to.deep.eq('0x')
})

it('should get balance', async () => {
const balance = await provider.getBalance(account)
expect(balance.toString()).to.deep.eq(BigNumber.from(234).toString())
})

it('should get balance on missing account', async () => {
const balance = await provider.getBalance('0x')
expect(balance.toString()).to.deep.eq('0')
})

it('should get storage', async () => {
const storage = await provider.getStorageAt(account, 2)
expect(storage).to.deep.eq('0x989680')
})

it('should get storage of missing account', async () => {
const storage = await provider.getStorageAt('0x', 0)
expect(storage).to.deep.eq('0x')
})

it('should get storage of missing slot', async () => {
const storage = await provider.getStorageAt(account, 9999999999999)
expect(storage).to.deep.eq('0x')
})

it('should call eth_getProof', async () => {
const proof = await provider.send('eth_getProof', [account])
// There is code at the account, so it shouldn't be the null code hash
expect(proof.codeHash).to.not.eq(add0x(KECCAK256_NULL_S))
// There is storage so it should not be the null storage hash
expect(proof.storageHash).to.not.eq(add0x(KECCAK256_RLP_S))
})

it('should call eth_getProof on missing account', async () => {
const proof = await provider.send('eth_getProof', ['0x'])
expect(proof.codeHash).to.eq(add0x(KECCAK256_NULL_S))
expect(proof.storageHash).to.eq(add0x(KECCAK256_RLP_S))
})

it('should also initialize correctly with state dump', async () => {
provider = new GenesisJsonProvider(genesis.alloc)
expect(provider).to.be.instanceOf(GenesisJsonProvider)
})
})

0 comments on commit 8f21774

Please sign in to comment.