Skip to content

Commit f9deb7b

Browse files
authored
fix: ensure GRE handles multiple chains with same chainId gracefully (#695)
* fix: ensure GRE handles multiple chains with same chainId gracefully Signed-off-by: Tomás Migone <[email protected]>
1 parent 707b856 commit f9deb7b

File tree

3 files changed

+70
-17
lines changed

3 files changed

+70
-17
lines changed

gre/config.ts

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import GraphNetwork from './helpers/network'
1212
import { createProvider } from 'hardhat/internal/core/providers/construction'
1313
import { EthersProviderWrapper } from '@nomiclabs/hardhat-ethers/internal/ethers-provider-wrapper'
1414

15-
import { logDebug } from './logger'
15+
import { logDebug, logWarn } from './logger'
16+
import { HARDHAT_NETWORK_NAME } from 'hardhat/plugins'
1617

1718
interface GREChains {
1819
l1ChainId: number
@@ -99,19 +100,25 @@ export function getProviders(
99100
const getProvider = (
100101
networks: NetworksConfig,
101102
chainId: number,
103+
mainNetworkName: string,
102104
isMainProvider: boolean,
103105
chainLabel: string,
104106
): EthersProviderWrapper | undefined => {
105-
const network = getNetworkConfig(networks, chainId) as HttpNetworkConfig
106-
const networkName = getNetworkName(networks, chainId)
107+
const network = getNetworkConfig(networks, chainId, mainNetworkName) as HttpNetworkConfig
108+
const networkName = getNetworkName(networks, chainId, mainNetworkName)
109+
110+
logDebug(`Provider url for ${chainLabel}(${networkName}): ${network?.url}`)
107111

108112
// Ensure at least main provider is configured
109-
if (isMainProvider && network === undefined) {
113+
// For Hardhat network we don't need url to create a provider
114+
if (
115+
isMainProvider &&
116+
(network === undefined || network.url === undefined) &&
117+
networkName !== HARDHAT_NETWORK_NAME
118+
) {
110119
throw new GREPluginError(`Must set a provider url for chain: ${chainId}!`)
111120
}
112121

113-
logDebug(`Provider url for ${chainLabel}: ${network?.url}`)
114-
115122
if (network === undefined || networkName === undefined) {
116123
return undefined
117124
}
@@ -123,8 +130,8 @@ export function getProviders(
123130
return ethersProviderWrapper
124131
}
125132

126-
const l1Provider = getProvider(hre.config.networks, l1ChainId, isHHL1, 'L1')
127-
const l2Provider = getProvider(hre.config.networks, l2ChainId, !isHHL1, 'L2')
133+
const l1Provider = getProvider(hre.config.networks, l1ChainId, hre.network.name, isHHL1, 'L1')
134+
const l2Provider = getProvider(hre.config.networks, l2ChainId, hre.network.name, !isHHL1, 'L2')
128135

129136
return {
130137
l1Provider,
@@ -142,8 +149,8 @@ export function getGraphConfigPaths(
142149
logDebug('== Getting graph config paths')
143150
logDebug(`Graph base dir: ${hre.config.paths.graph}`)
144151

145-
const l1Network = getNetworkConfig(hre.config.networks, l1ChainId)
146-
const l2Network = getNetworkConfig(hre.config.networks, l2ChainId)
152+
const l1Network = getNetworkConfig(hre.config.networks, l1ChainId, hre.network.name)
153+
const l2Network = getNetworkConfig(hre.config.networks, l2ChainId, hre.network.name)
147154

148155
// Priority is as follows:
149156
// - hre.graph() init parameter l1GraphConfigPath/l2GraphConfigPath
@@ -205,14 +212,43 @@ export function getGraphConfigPaths(
205212
}
206213
}
207214

208-
function getNetworkConfig(networks: NetworksConfig, chainId: number): NetworkConfig | undefined {
209-
return Object.keys(networks)
210-
.map((n) => networks[n])
211-
.find((n) => n.chainId === chainId)
215+
function getNetworkConfig(
216+
networks: NetworksConfig,
217+
chainId: number,
218+
mainNetworkName: string,
219+
): (NetworkConfig & { name: string }) | undefined {
220+
let candidateNetworks = Object.keys(networks)
221+
.map((n) => ({ ...networks[n], name: n }))
222+
.filter((n) => n.chainId === chainId)
223+
224+
if (candidateNetworks.length > 1) {
225+
logWarn(
226+
`Found multiple networks with chainId ${chainId}, trying to use main network name to desambiguate`,
227+
)
228+
229+
candidateNetworks = candidateNetworks.filter((n) => n.name === mainNetworkName)
230+
231+
if (candidateNetworks.length === 1) {
232+
return candidateNetworks[0]
233+
} else {
234+
throw new GREPluginError(
235+
`Found multiple networks with chainID ${chainId}. This is not supported!`,
236+
)
237+
}
238+
} else if (candidateNetworks.length === 1) {
239+
return candidateNetworks[0]
240+
} else {
241+
return undefined
242+
}
212243
}
213244

214-
function getNetworkName(networks: NetworksConfig, chainId: number): string | undefined {
215-
return Object.keys(networks).find((n) => networks[n].chainId === chainId)
245+
function getNetworkName(
246+
networks: NetworksConfig,
247+
chainId: number,
248+
mainNetworkName: string,
249+
): string | undefined {
250+
const network = getNetworkConfig(networks, chainId, mainNetworkName)
251+
return network?.name
216252
}
217253

218254
function normalizePath(_path: string, graphPath: string) {

gre/gre.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ extendConfig((config: HardhatConfig, userConfig: Readonly<HardhatUserConfig>) =>
3939

4040
extendEnvironment((hre: HardhatRuntimeEnvironment) => {
4141
hre.graph = (opts: GraphRuntimeEnvironmentOptions = {}) => {
42+
logDebug('*** Initializing Graph Runtime Environment (GRE) ***')
43+
logDebug(`Main network: ${hre.network.name}`)
44+
4245
const { l1ChainId, l2ChainId, isHHL1 } = getChains(hre.network.config.chainId)
4346
const { l1Provider, l2Provider } = getProviders(hre, l1ChainId, l2ChainId, isHHL1)
4447
const addressBookPath = getAddressBookPath(hre, opts)

gre/test/gre.test.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ describe('GRE usage', function () {
2020
describe('graph-config project setting --network to an L2', function () {
2121
useEnvironment('graph-config', 'arbitrum-goerli')
2222

23-
it('should return L1 and L2 configured objects ', function () {
23+
it('should return L1 and L2 configured objects', function () {
2424
const g = this.hre.graph()
2525

2626
expect(g).to.be.an('object')
@@ -32,6 +32,20 @@ describe('GRE usage', function () {
3232
})
3333
})
3434

35+
describe('graph-config project setting --network to hardhat network', function () {
36+
useEnvironment('graph-config', 'hardhat')
37+
38+
it('should return L1 configured object and L2 unconfigured', function () {
39+
const g = this.hre.graph()
40+
41+
expect(g).to.be.an('object')
42+
expect(g.l1).to.be.an('object')
43+
expect(g.l2).to.be.null
44+
expect(g.l1.chainId).to.equal(1337)
45+
expect(g.chainId).to.equal(1337)
46+
})
47+
})
48+
3549
describe('graph-config project setting --network to an L1 with no configured counterpart', function () {
3650
useEnvironment('graph-config', 'localhost')
3751

0 commit comments

Comments
 (0)