Commit 855de9e7 authored by Mark Tyneway's avatar Mark Tyneway Committed by Kelvin Fichter

state-surgery: validate configs using chainid

Move the instantiation of the providers to earlier
in the script so that they can be used to check the
chain id before doing any slow disk reads of giant json
files.
parent 838bd1ac
...@@ -3,9 +3,8 @@ REGEN__ETHERSCAN_FILE= ...@@ -3,9 +3,8 @@ REGEN__ETHERSCAN_FILE=
REGEN__GENESIS_FILE= REGEN__GENESIS_FILE=
REGEN__OUTPUT_FILE= REGEN__OUTPUT_FILE=
REGEN__L2_PROVIDER_URL= REGEN__L2_PROVIDER_URL=
REGEN__L2_NETWORK_NAME= REGEN__ETH_PROVIDER_URL=
REGEN__L1_PROVIDER_URL=
REGEN__L1_TESTNET_PROVIDER_URL= REGEN__L1_TESTNET_PROVIDER_URL=
REGEN__L1_TESTNET_PRIVATE_KEY= REGEN__L1_TESTNET_PRIVATE_KEY=
START_INDEX= REGEN__START_INDEX=
END_INDEX= REGEN__END_INDEX=
...@@ -19,16 +19,16 @@ yarn build ...@@ -19,16 +19,16 @@ yarn build
## Environment Variables ## Environment Variables
| Variable | Description | | Variable | Description |
| ----------------------------- | ---------------------------------------------------------- | | ----------------------------- | --------------------------------------------------------------|
| `REGEN__STATE_DUMP_FILE` | Path to the state dump file | | `REGEN__STATE_DUMP_FILE` | Path to the state dump file |
| `REGEN__ETHERSCAN_FILE` | Path to the etherscan dump file | | `REGEN__ETHERSCAN_FILE` | Path to the etherscan dump file |
| `REGEN__GENESIS_FILE` | Path to the initial genesis file | | `REGEN__GENESIS_FILE` | Path to the initial genesis file |
| `REGEN__OUTPUT_FILE` | Path where the output genesis will be saved | | `REGEN__OUTPUT_FILE` | Path where the output genesis will be saved |
| `REGEN__L2_NETWORK_NAME` | Name of the L2 network being upgraded (kovan or mainnet) | | `REGEN__L2_PROVIDER_URL` | RPC provider for the L2 network being upgraded |
| `REGEN__L2_PROVIDER_URL` | RPC provider for the L2 network being upgraded | | `REGEN__ETH_PROVIDER_URL` | RPC provider for Ethereum mainnet |
| `REGEN__L1_PROVIDER_URL` | RPC provider for the L1 network that corresponds to the L2 | | `REGEN__ROPSTEN_PROVIDER_URL` | RPC provider for the Ropsten testnet |
| `REGEN__ETH_PROVIDER_URL` | RPC provider for Ethereum mainnet | | `REGEN__ROPSTEN_PRIVATE_KEY` | Private key of an account that has Ropsten ETH |
| `REGEN__ROPSTEN_PROVIDER_URL` | RPC provider for the Ropsten testnet | | `REGEN__STATE_DUMP_HEIGHT` | Height at which the state dump was taken |
| `REGEN__ROPSTEN_PRIVATE_KEY` | Private key of an account that has Ropsten ETH | | `REGEN__START_INDEX` | Start index to begin processing the regenesis at (do not set) |
| `REGEN__STATE_DUMP_HEIGHT` | Height at which the state dump was taken | | `REGEN__END_INDEX` | End index to finish processing the regenesis at (do not set) |
...@@ -31,6 +31,9 @@ export const getUniswapPoolData = async ( ...@@ -31,6 +31,9 @@ export const getUniswapPoolData = async (
l2Provider: ethers.providers.BaseProvider, l2Provider: ethers.providers.BaseProvider,
network: 'mainnet' | 'kovan' network: 'mainnet' | 'kovan'
): Promise<UniswapPoolData[]> => { ): Promise<UniswapPoolData[]> => {
if (!network) {
throw new Error('Must provide network "mainnet" or "kovan"')
}
const UniswapV3Factory = getUniswapV3Factory(l2Provider) const UniswapV3Factory = getUniswapV3Factory(l2Provider)
const pools: UniswapPoolData[] = [] const pools: UniswapPoolData[] = []
...@@ -82,6 +85,13 @@ export const makePoolHashCache = (pools: UniswapPoolData[]): PoolHashCache => { ...@@ -82,6 +85,13 @@ export const makePoolHashCache = (pools: UniswapPoolData[]): PoolHashCache => {
return cache return cache
} }
const getChainId = async (
provider: ethers.providers.JsonRpcProvider
): Promise<number> => {
const response = await provider.send('eth_chainId', [])
return ethers.BigNumber.from(response.result).toNumber()
}
export const loadSurgeryData = async ( export const loadSurgeryData = async (
configs?: SurgeryConfigs configs?: SurgeryConfigs
): Promise<SurgeryDataSources> => { ): Promise<SurgeryDataSources> => {
...@@ -95,6 +105,33 @@ export const loadSurgeryData = async ( ...@@ -95,6 +105,33 @@ export const loadSurgeryData = async (
configs = loadConfigs() configs = loadConfigs()
} }
// Get a reference to an ETH (mainnet) provider.
console.log('Connecting to ETH provider...')
const ethProvider = new ethers.providers.JsonRpcProvider(
configs.ethProviderUrl
)
const mainnetChainId = await getChainId(ethProvider)
if (mainnetChainId !== 1) {
throw new Error(
`Mainnet chain id incorrect, got ${mainnetChainId} and expected 1`
)
}
// Get a reference to the L2 provider so we can load pool data.
// Do validation on the chain id before reading data from disk
// because that is slow
console.log('Connecting to L2 provider...')
const l2Provider = new ethers.providers.JsonRpcProvider(configs.l2ProviderUrl)
const l2ChainId = await getChainId(l2Provider)
if (l2ChainId === 10) {
configs.l2NetworkName = 'mainnet'
} else if (l2ChainId === 69) {
configs.l2NetworkName = 'kovan'
} else {
throw new Error(`Unknown l2 chain id: ${l2ChainId}`)
}
console.log(`Using network ${configs.l2NetworkName}`)
// Load and validate the state dump. // Load and validate the state dump.
console.log('Loading and validating state dump file...') console.log('Loading and validating state dump file...')
const dump: StateDump = await readDumpFile(configs.stateDumpFilePath) const dump: StateDump = await readDumpFile(configs.stateDumpFilePath)
...@@ -104,6 +141,12 @@ export const loadSurgeryData = async ( ...@@ -104,6 +141,12 @@ export const loadSurgeryData = async (
// Load the genesis file. // Load the genesis file.
console.log('Loading genesis file...') console.log('Loading genesis file...')
const genesis: GenesisFile = await readGenesisFile(configs.genesisFilePath) const genesis: GenesisFile = await readGenesisFile(configs.genesisFilePath)
if (genesis.config.chainId !== l2ChainId) {
throw new Error(
`Genesis File at ${configs.genesisFilePath} has chain id mismatch with remote L2 node` +
` got ${genesis.config.chainId} locally and ${l2ChainId} remote`
)
}
const genesisDump: StateDump = [] const genesisDump: StateDump = []
for (const [address, account] of Object.entries(genesis.alloc)) { for (const [address, account] of Object.entries(genesis.alloc)) {
genesisDump.push({ genesisDump.push({
...@@ -120,10 +163,6 @@ export const loadSurgeryData = async ( ...@@ -120,10 +163,6 @@ export const loadSurgeryData = async (
) )
console.log(`${etherscanDump.length} entries in etherscan dump`) console.log(`${etherscanDump.length} entries in etherscan dump`)
// Get a reference to the L2 provider so we can load pool data.
console.log('Connecting to L2 provider...')
const l2Provider = new ethers.providers.JsonRpcProvider(configs.l2ProviderUrl)
// Load the pool data. // Load the pool data.
console.log('Loading Uniswap pool data...') console.log('Loading Uniswap pool data...')
const pools: UniswapPoolData[] = await getUniswapPoolData( const pools: UniswapPoolData[] = await getUniswapPoolData(
...@@ -140,16 +179,17 @@ export const loadSurgeryData = async ( ...@@ -140,16 +179,17 @@ export const loadSurgeryData = async (
const ropstenProvider = new ethers.providers.JsonRpcProvider( const ropstenProvider = new ethers.providers.JsonRpcProvider(
configs.ropstenProviderUrl configs.ropstenProviderUrl
) )
const ropstenWallet = new ethers.Wallet( const ropstenWallet = new ethers.Wallet(
configs.ropstenPrivateKey, configs.ropstenPrivateKey,
ropstenProvider ropstenProvider
) )
const ropstenChainId = await ropstenWallet.getChainId()
// Get a reference to an ETH (mainnet) provider. if (ropstenChainId !== 3) {
console.log('Connecting to ETH provider...') throw new Error(
const ethProvider = new ethers.providers.JsonRpcProvider( `Ropsten chain id incorrect, got ${ropstenChainId} and expected 3`
configs.ethProviderUrl )
) }
return { return {
configs, configs,
......
...@@ -5,7 +5,7 @@ export interface SurgeryConfigs { ...@@ -5,7 +5,7 @@ export interface SurgeryConfigs {
etherscanFilePath: string etherscanFilePath: string
genesisFilePath: string genesisFilePath: string
outputFilePath: string outputFilePath: string
l2NetworkName: SupportedNetworks l2NetworkName?: SupportedNetworks
l2ProviderUrl: string l2ProviderUrl: string
ropstenProviderUrl: string ropstenProviderUrl: string
ropstenPrivateKey: string ropstenPrivateKey: string
......
...@@ -129,7 +129,6 @@ export const loadConfigs = (): SurgeryConfigs => { ...@@ -129,7 +129,6 @@ export const loadConfigs = (): SurgeryConfigs => {
const etherscanFilePath = reqenv('REGEN__ETHERSCAN_FILE') const etherscanFilePath = reqenv('REGEN__ETHERSCAN_FILE')
const genesisFilePath = reqenv('REGEN__GENESIS_FILE') const genesisFilePath = reqenv('REGEN__GENESIS_FILE')
const outputFilePath = reqenv('REGEN__OUTPUT_FILE') const outputFilePath = reqenv('REGEN__OUTPUT_FILE')
const l2NetworkName = reqenv('REGEN__L2_NETWORK_NAME')
const l2ProviderUrl = reqenv('REGEN__L2_PROVIDER_URL') const l2ProviderUrl = reqenv('REGEN__L2_PROVIDER_URL')
const ropstenProviderUrl = reqenv('REGEN__ROPSTEN_PROVIDER_URL') const ropstenProviderUrl = reqenv('REGEN__ROPSTEN_PROVIDER_URL')
const ropstenPrivateKey = reqenv('REGEN__ROPSTEN_PRIVATE_KEY') const ropstenPrivateKey = reqenv('REGEN__ROPSTEN_PRIVATE_KEY')
...@@ -138,18 +137,11 @@ export const loadConfigs = (): SurgeryConfigs => { ...@@ -138,18 +137,11 @@ export const loadConfigs = (): SurgeryConfigs => {
const startIndex = parseInt(getenv('REGEN__START_INDEX', '0'), 10) const startIndex = parseInt(getenv('REGEN__START_INDEX', '0'), 10)
const endIndex = parseInt(getenv('REGEN__END_INDEX', '0'), 10) || Infinity const endIndex = parseInt(getenv('REGEN__END_INDEX', '0'), 10) || Infinity
// Input assertions
assert.ok(
['mainnet', 'kovan'].includes(l2NetworkName),
`L2_NETWORK_NAME must be one of "mainnet" or "kovan"`
)
return { return {
stateDumpFilePath, stateDumpFilePath,
etherscanFilePath, etherscanFilePath,
genesisFilePath, genesisFilePath,
outputFilePath, outputFilePath,
l2NetworkName: l2NetworkName as SupportedNetworks,
l2ProviderUrl, l2ProviderUrl,
ropstenProviderUrl, ropstenProviderUrl,
ropstenPrivateKey, ropstenPrivateKey,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment