From 563e97b71ee0d03e232aa5bb279606b5125b106a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 23 Aug 2022 18:01:13 +0200 Subject: [PATCH 1/2] fix: ensure GRE handles multiple chains with same chainId gracefully MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- gre/config.ts | 67 +++++++++++++++++++++++++++++++++----------- gre/gre.ts | 3 ++ gre/test/gre.test.ts | 14 +++++++++ 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/gre/config.ts b/gre/config.ts index 68b624b82..8d07825e1 100644 --- a/gre/config.ts +++ b/gre/config.ts @@ -12,7 +12,8 @@ import GraphNetwork from './helpers/network' import { createProvider } from 'hardhat/internal/core/providers/construction' import { EthersProviderWrapper } from '@nomiclabs/hardhat-ethers/internal/ethers-provider-wrapper' -import { logDebug } from './logger' +import { logDebug, logWarn } from './logger' +import { HARDHAT_NETWORK_NAME } from 'hardhat/plugins' interface GREChains { l1ChainId: number @@ -99,19 +100,24 @@ export function getProviders( const getProvider = ( networks: NetworksConfig, chainId: number, + mainNetworkName: string, isMainProvider: boolean, chainLabel: string, ): EthersProviderWrapper | undefined => { - const network = getNetworkConfig(networks, chainId) as HttpNetworkConfig - const networkName = getNetworkName(networks, chainId) + const network = getNetworkConfig(networks, chainId, mainNetworkName) as HttpNetworkConfig + const networkName = getNetworkName(networks, chainId, mainNetworkName) + + logDebug(`Provider url for ${chainLabel}(${networkName}): ${network?.url}`) // Ensure at least main provider is configured - if (isMainProvider && network === undefined) { + if ( + isMainProvider && + (network === undefined || network.url === undefined) && + networkName !== HARDHAT_NETWORK_NAME + ) { throw new GREPluginError(`Must set a provider url for chain: ${chainId}!`) } - logDebug(`Provider url for ${chainLabel}: ${network?.url}`) - if (network === undefined || networkName === undefined) { return undefined } @@ -123,8 +129,8 @@ export function getProviders( return ethersProviderWrapper } - const l1Provider = getProvider(hre.config.networks, l1ChainId, isHHL1, 'L1') - const l2Provider = getProvider(hre.config.networks, l2ChainId, !isHHL1, 'L2') + const l1Provider = getProvider(hre.config.networks, l1ChainId, hre.network.name, isHHL1, 'L1') + const l2Provider = getProvider(hre.config.networks, l2ChainId, hre.network.name, !isHHL1, 'L2') return { l1Provider, @@ -142,8 +148,8 @@ export function getGraphConfigPaths( logDebug('== Getting graph config paths') logDebug(`Graph base dir: ${hre.config.paths.graph}`) - const l1Network = getNetworkConfig(hre.config.networks, l1ChainId) - const l2Network = getNetworkConfig(hre.config.networks, l2ChainId) + const l1Network = getNetworkConfig(hre.config.networks, l1ChainId, hre.network.name) + const l2Network = getNetworkConfig(hre.config.networks, l2ChainId, hre.network.name) // Priority is as follows: // - hre.graph() init parameter l1GraphConfigPath/l2GraphConfigPath @@ -205,14 +211,43 @@ export function getGraphConfigPaths( } } -function getNetworkConfig(networks: NetworksConfig, chainId: number): NetworkConfig | undefined { - return Object.keys(networks) - .map((n) => networks[n]) - .find((n) => n.chainId === chainId) +function getNetworkConfig( + networks: NetworksConfig, + chainId: number, + mainNetworkName: string, +): (NetworkConfig & { name: string }) | undefined { + let candidateNetworks = Object.keys(networks) + .map((n) => ({ ...networks[n], name: n })) + .filter((n) => n.chainId === chainId) + + if (candidateNetworks.length > 1) { + logWarn( + `Found multiple networks with chainId ${chainId}, trying to use main network name to desambiguate`, + ) + + candidateNetworks = candidateNetworks.filter((n) => n.name === mainNetworkName) + + if (candidateNetworks.length === 1) { + return candidateNetworks[0] + } else { + throw new GREPluginError( + `Found multiple networks with chainID ${chainId}. This is not supported!`, + ) + } + } else if (candidateNetworks.length === 1) { + return candidateNetworks[0] + } else { + return undefined + } } -function getNetworkName(networks: NetworksConfig, chainId: number): string | undefined { - return Object.keys(networks).find((n) => networks[n].chainId === chainId) +function getNetworkName( + networks: NetworksConfig, + chainId: number, + mainNetworkName: string, +): string | undefined { + const network = getNetworkConfig(networks, chainId, mainNetworkName) + return network?.name } function normalizePath(_path: string, graphPath: string) { diff --git a/gre/gre.ts b/gre/gre.ts index 221557ba4..97520a16a 100644 --- a/gre/gre.ts +++ b/gre/gre.ts @@ -39,6 +39,9 @@ extendConfig((config: HardhatConfig, userConfig: Readonly) => extendEnvironment((hre: HardhatRuntimeEnvironment) => { hre.graph = (opts: GraphRuntimeEnvironmentOptions = {}) => { + logDebug('*** Initializing Graph Runtime Environment (GRE) ***') + logDebug(`Main network: ${hre.network.name}`) + const { l1ChainId, l2ChainId, isHHL1 } = getChains(hre.network.config.chainId) const { l1Provider, l2Provider } = getProviders(hre, l1ChainId, l2ChainId, isHHL1) const addressBookPath = getAddressBookPath(hre, opts) diff --git a/gre/test/gre.test.ts b/gre/test/gre.test.ts index 486e01d79..e73fe312e 100644 --- a/gre/test/gre.test.ts +++ b/gre/test/gre.test.ts @@ -32,6 +32,20 @@ describe('GRE usage', function () { }) }) + describe('graph-config project setting --network to hardhat network', function () { + useEnvironment('graph-config', 'hardhat') + + it('should return L1 and L2 configured objects ', function () { + const g = this.hre.graph() + + expect(g).to.be.an('object') + expect(g.l1).to.be.an('object') + expect(g.l2).to.be.null + expect(g.l1.chainId).to.equal(1337) + expect(g.chainId).to.equal(1337) + }) + }) + describe('graph-config project setting --network to an L1 with no configured counterpart', function () { useEnvironment('graph-config', 'localhost') From 4cedbc81705df97f68128a75a11cbdc409da2fba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Tue, 23 Aug 2022 18:28:20 +0200 Subject: [PATCH 2/2] chore: fix test text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- gre/config.ts | 1 + gre/test/gre.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gre/config.ts b/gre/config.ts index 8d07825e1..14e4008ac 100644 --- a/gre/config.ts +++ b/gre/config.ts @@ -110,6 +110,7 @@ export function getProviders( logDebug(`Provider url for ${chainLabel}(${networkName}): ${network?.url}`) // Ensure at least main provider is configured + // For Hardhat network we don't need url to create a provider if ( isMainProvider && (network === undefined || network.url === undefined) && diff --git a/gre/test/gre.test.ts b/gre/test/gre.test.ts index e73fe312e..a13274f94 100644 --- a/gre/test/gre.test.ts +++ b/gre/test/gre.test.ts @@ -20,7 +20,7 @@ describe('GRE usage', function () { describe('graph-config project setting --network to an L2', function () { useEnvironment('graph-config', 'arbitrum-goerli') - it('should return L1 and L2 configured objects ', function () { + it('should return L1 and L2 configured objects', function () { const g = this.hre.graph() expect(g).to.be.an('object') @@ -35,7 +35,7 @@ describe('GRE usage', function () { describe('graph-config project setting --network to hardhat network', function () { useEnvironment('graph-config', 'hardhat') - it('should return L1 and L2 configured objects ', function () { + it('should return L1 configured object and L2 unconfigured', function () { const g = this.hre.graph() expect(g).to.be.an('object')