Skip to content

feat(gre): desambiguate chainIds using secondary network name #714

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions gre/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { HttpNetworkConfig } from 'hardhat/types/config'

import { GraphRuntimeEnvironmentOptions } from './type-extensions'
import { GREPluginError } from './helpers/error'
import GraphNetwork from './helpers/network'
import GraphNetwork, { counterpartName } from './helpers/network'

import { createProvider } from 'hardhat/internal/core/providers/construction'
import { EthersProviderWrapper } from '@nomiclabs/hardhat-ethers/internal/ethers-provider-wrapper'
Expand Down Expand Up @@ -217,7 +217,7 @@ function getNetworkConfig(
chainId: number,
mainNetworkName: string,
): (NetworkConfig & { name: string }) | undefined {
let candidateNetworks = Object.keys(networks)
const candidateNetworks = Object.keys(networks)
.map((n) => ({ ...networks[n], name: n }))
.filter((n) => n.chainId === chainId)

Expand All @@ -226,14 +226,26 @@ function getNetworkConfig(
`Found multiple networks with chainId ${chainId}, trying to use main network name to desambiguate`,
)

candidateNetworks = candidateNetworks.filter((n) => n.name === mainNetworkName)
const filteredByMainNetworkName = candidateNetworks.filter((n) => n.name === mainNetworkName)

if (candidateNetworks.length === 1) {
return candidateNetworks[0]
if (filteredByMainNetworkName.length === 1) {
logDebug(`Found network with chainId ${chainId} and name ${mainNetworkName}`)
return filteredByMainNetworkName[0]
} else {
throw new GREPluginError(
`Found multiple networks with chainID ${chainId}. This is not supported!`,
logWarn(`Could not desambiguate with main network name, trying secondary network name`)
const secondaryNetworkName = counterpartName(mainNetworkName)
const filteredBySecondaryNetworkName = candidateNetworks.filter(
(n) => n.name === secondaryNetworkName,
)

if (filteredBySecondaryNetworkName.length === 1) {
logDebug(`Found network with chainId ${chainId} and name ${mainNetworkName}`)
return filteredBySecondaryNetworkName[0]
} else {
throw new GREPluginError(
`Could not desambiguate network with chainID ${chainId}. Use case not supported!`,
)
}
}
} else if (candidateNetworks.length === 1) {
return candidateNetworks[0]
Expand All @@ -242,7 +254,7 @@ function getNetworkConfig(
}
}

function getNetworkName(
export function getNetworkName(
networks: NetworksConfig,
chainId: number,
mainNetworkName: string,
Expand Down
24 changes: 24 additions & 0 deletions gre/helpers/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,46 @@ const chainMap = new MapWithGetKey<number>([
[1337, 412346], // Localhost - Arbitrum Localhost
])

// Hardhat network names as per our convention
const nameMap = new MapWithGetKey<string>([
['mainnet', 'arbitrum-one'], // Ethereum Mainnet - Arbitrum One
['rinkeby', 'arbitrum-rinkeby'], // Ethereum Rinkeby - Arbitrum Rinkeby
['goerli', 'arbitrum-goerli'], // Ethereum Goerli - Arbitrum Goerli
['localnitrol1', 'localnitrol2'], // Arbitrum testnode L1 - Arbitrum testnode L2
])

export const l1Chains = Array.from(chainMap.keys())
export const l2Chains = Array.from(chainMap.values())
export const chains = [...l1Chains, ...l2Chains]

export const l1ChainNames = Array.from(nameMap.keys())
export const l2ChainNames = Array.from(nameMap.values())
export const chainNames = [...l1ChainNames, ...l2ChainNames]

export const isL1 = (chainId: number): boolean => l1Chains.includes(chainId)
export const isL2 = (chainId: number): boolean => l2Chains.includes(chainId)
export const isSupported = (chainId: number | undefined): boolean =>
chainId !== undefined && chains.includes(chainId)

export const isL1Name = (name: string): boolean => l1ChainNames.includes(name)
export const isL2Name = (name: string): boolean => l2ChainNames.includes(name)
export const isSupportedName = (name: string | undefined): boolean =>
name !== undefined && chainNames.includes(name)

export const l1ToL2 = (chainId: number): number | undefined => chainMap.get(chainId)
export const l2ToL1 = (chainId: number): number | undefined => chainMap.getKey(chainId)
export const counterpart = (chainId: number): number | undefined => {
if (!isSupported(chainId)) return
return isL1(chainId) ? l1ToL2(chainId) : l2ToL1(chainId)
}

export const l1ToL2Name = (name: string): string | undefined => nameMap.get(name)
export const l2ToL1Name = (name: string): string | undefined => nameMap.getKey(name)
export const counterpartName = (name: string): string | undefined => {
if (!isSupportedName(name)) return
return isL1Name(name) ? l1ToL2Name(name) : l2ToL1Name(name)
}

export default {
l1Chains,
l2Chains,
Expand Down
38 changes: 37 additions & 1 deletion gre/test/config.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { expect } from 'chai'
import { useEnvironment } from './helpers'

import { getAddressBookPath, getChains, getGraphConfigPaths, getProviders } from '../config'
import {
getAddressBookPath,
getChains,
getGraphConfigPaths,
getNetworkName,
getProviders,
} from '../config'
import path from 'path'

describe('GRE init functions', function () {
Expand Down Expand Up @@ -104,6 +110,36 @@ describe('GRE init functions', function () {
})
})

describe('getProviders with graph-config-desambiguate project', function () {
useEnvironment('graph-config-desambiguate', 'localnitrol1')

it('should use main network name to desambiguate if multiple chains are defined with same chainId', async function () {
const { l1Provider, l2Provider } = getProviders(this.hre, 1337, 412346, true)
expect(l1Provider).to.be.an('object')
expect(l2Provider).to.be.an('object')

const l1NetworkName = getNetworkName(this.hre.config.networks, 1337, 'localnitrol1')
const l2NetworkName = getNetworkName(this.hre.config.networks, 412346, 'localnitrol1')
expect(l1NetworkName).to.equal('localnitrol1')
expect(l2NetworkName).to.equal('localnitrol2')
})
})

describe('getProviders with graph-config-desambiguate project', function () {
useEnvironment('graph-config-desambiguate', 'localnitrol2')

it('should use secondary network name to desambiguate if multiple chains are defined with same chainId', async function () {
const { l1Provider, l2Provider } = getProviders(this.hre, 1337, 412346, true)
expect(l1Provider).to.be.an('object')
expect(l2Provider).to.be.an('object')

const l1NetworkName = getNetworkName(this.hre.config.networks, 1337, 'localnitrol2')
const l2NetworkName = getNetworkName(this.hre.config.networks, 412346, 'localnitrol2')
expect(l1NetworkName).to.equal('localnitrol1')
expect(l2NetworkName).to.equal('localnitrol2')
})
})

describe('getGraphConfigPaths with graph-config-full project', function () {
useEnvironment('graph-config-full')

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import '../../../gre'

module.exports = {
paths: {
graph: '../../files',
},
solidity: '0.8.9',
defaultNetwork: 'hardhat',
networks: {
hardhat: {
chainId: 1337,
},
localhost: {
chainId: 1337,
url: `http://localhost:8545`,
},
localnitrol1: {
chainId: 1337,
url: `http://localhost:8545`,
},
localnitrol2: {
chainId: 412346,
url: `http://localhost:8547`,
},
mainnet: {
chainId: 1,
graphConfig: 'config/graph.mainnet.yml',
url: `https://mainnet.infura.io/v3/123456`,
},
'arbitrum-one': {
chainId: 42161,
url: 'https://arb1.arbitrum.io/rpc',
graphConfig: 'config/graph.arbitrum-goerli.yml',
},
goerli: {
chainId: 5,
url: `https://goerli.infura.io/v3/123456`,
graphConfig: 'config/graph.goerli.yml',
},
'arbitrum-goerli': {
chainId: 421613,
url: 'https://goerli-rollup.arbitrum.io/rpc',
graphConfig: 'config/graph.arbitrum-goerli.yml',
},
rinkeby: {
chainId: 4,
url: `https://goerli.infura.io/v3/123456`,
},
'arbitrum-rinkeby': {
chainId: 421611,
url: `https://goerli.infura.io/v3/123456`,
},
},
graph: {
addressBook: 'addresses-hre.json',
l1GraphConfig: 'config/graph.hre.yml',
l2GraphConfig: 'config/graph.arbitrum-hre.yml',
},
}
1 change: 1 addition & 0 deletions gre/test/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ export function useEnvironment(fixtureProjectName: string, network?: string): vo

afterEach('Resetting hardhat', function () {
resetHardhatContext()
delete process.env.HARDHAT_NETWORK
})
}