Skip to content

Commit

Permalink
🗞️ Adjust simulation config logic for anvil [7/N] (#495)
Browse files Browse the repository at this point in the history
  • Loading branch information
janjakubnanista authored Mar 18, 2024
1 parent f9987d3 commit eb4e4d0
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changeset/dull-bananas-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@layerzerolabs/devtools-evm-hardhat": patch
---

Adjust simulation config logic for anvil
37 changes: 21 additions & 16 deletions packages/devtools-evm-hardhat/src/simulation/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { HardhatConfig, HttpNetworkConfig, NetworkConfig, NetworkUserConfig } from 'hardhat/types'
import type { HardhatConfig, HttpNetworkConfig, NetworkConfig } from 'hardhat/types'
import type { SimulationConfig, SimulationUserConfig } from './types'
import { resolve } from 'path'
import { AnvilOptions } from '@layerzerolabs/devtools-evm'
Expand All @@ -22,6 +22,10 @@ export const resolveSimulationConfig = (
// For now we'll hardcode the mnemonic we'll use to seed the accounts on the simulation networks
mnemonic: 'test test test test test test test test test test test junk',
...userConfig.anvil,
// The host and port need to always point to 0.0.0.0:8545
// since anvil runs in the container that exposes this port on 0.0.0.0
host: '0.0.0.0',
port: 8545,
},
})

Expand Down Expand Up @@ -63,31 +67,23 @@ export const getAnvilOptionsFromHardhatNetworks = (
*
* @param {SimulationConfig} config
* @param {Record<string, NetworkConfig>} networksConfig
* @returns {Record<string, NetworkUserConfig>}
* @returns {Record<string, NetworkConfig>}
*/
export const getHardhatNetworkOverrides = (
config: SimulationConfig,
networksConfig: Record<string, NetworkConfig>
): Record<string, NetworkUserConfig> =>
): Record<string, NetworkConfig> =>
pipe(
networksConfig,
// We want to drop all the networks that don't have URLs
R.filter(isHttpNetworkConfig),
// We'll map the network configs into objects that define the minimum overrides
// needed to make the simulation work.
// We'll take the existing network configs and point them to our RPC proxy
//
// Having the complete network configs copied here would definitely
// simplify the step in which we'll be applying these overrides
// to hardhat config, but it comes with a bit of bad / unexpected UX.
//
// If users changed their hardhat configs without regenerating the simulation configs, they would
// not see their changes applied (since they would be hardcoded in these overrides).
//
// Another thing to consider is that these overrides will be turned into a JSON file.
// Any properties that cannot be serialized would disappear (and we cannot assume only serializable properties
// since people can use whatever hardhat plugins they want)
// It's important that these configs are not saved to filesystem as they might contain
// sensitive data (and forgetting to ignore these files in git could lead to security breaches)
R.mapWithIndex(
(networkName): NetworkUserConfig => ({
(networkName, networkConfig): NetworkConfig => ({
...networkConfig,
// We want to redirect this network to the local proxy
//
// This is the nginx server listening on the port we configured in the simulation configuration
Expand All @@ -102,6 +98,15 @@ export const getHardhatNetworkOverrides = (
// - We don't want to be throwing production mnemonics around and storing them in json files
accounts: {
mnemonic: config.anvil.mnemonic,
// These need to be defaulted to the anvil options
// (or the anvil defaults)
//
// See https://book.getfoundry.sh/reference/cli/anvil for anvil defaults
count: config.anvil.count ?? 10,
path: config.anvil.derivationPath ?? "m/44'/60'/0'/0/",
// These will be hardcoded for now as anvil does not support setting these
initialIndex: 0,
passphrase: '',
},
})
)
Expand Down
59 changes: 58 additions & 1 deletion packages/devtools-evm-hardhat/test/simulation/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import { resolve } from 'path'

describe('simulation/config', () => {
describe('resolveSimulationConfig()', () => {
it('should resolve with defaults without no properties', () => {
it('should resolve with defaults when called with no properties', () => {
expect(resolveSimulationConfig({}, hre.config)).toEqual({
port: 8545,
directory: resolve(hre.config.paths.root, '.layerzero'),
anvil: {
host: '0.0.0.0',
port: 8545,
mnemonic: 'test test test test test test test test test test test junk',
},
})
Expand All @@ -27,6 +29,8 @@ describe('simulation/config', () => {
port,
directory: resolve(hre.config.paths.root, directory),
anvil: {
host: '0.0.0.0',
port: 8545,
mnemonic,
},
})
Expand Down Expand Up @@ -69,14 +73,20 @@ describe('simulation/config', () => {
networkA: {
forkUrl: networkA.url,
mnemonic: simulationConfig.anvil.mnemonic,
host: '0.0.0.0',
port: 8545,
},
networkB: {
forkUrl: networkB.url,
mnemonic: simulationConfig.anvil.mnemonic,
host: '0.0.0.0',
port: 8545,
},
networkC: {
forkUrl: networkC.url,
mnemonic: simulationConfig.anvil.mnemonic,
host: '0.0.0.0',
port: 8545,
},
})
})
Expand Down Expand Up @@ -114,20 +124,67 @@ describe('simulation/config', () => {
})
).toStrictEqual({
networkA: {
...networkA,
url: `http://localhost:${simulationConfig.port}/networkA`,
accounts: {
count: 10,
initialIndex: 0,
passphrase: '',
path: "m/44'/60'/0'/0/",
mnemonic: simulationConfig.anvil.mnemonic,
},
},
networkB: {
...networkB,
url: `http://localhost:${simulationConfig.port}/networkB`,
accounts: {
count: 10,
initialIndex: 0,
passphrase: '',
path: "m/44'/60'/0'/0/",
mnemonic: simulationConfig.anvil.mnemonic,
},
},
networkC: {
...networkC,
url: `http://localhost:${simulationConfig.port}/networkC`,
accounts: {
count: 10,
initialIndex: 0,
passphrase: '',
path: "m/44'/60'/0'/0/",
mnemonic: simulationConfig.anvil.mnemonic,
},
},
})
})

it('should respect anvil accounts options', () => {
const localhost = hre.config.networks.localhost
const networkA = { ...localhost, url: 'http://network.a' }
const simulationConfig = resolveSimulationConfig(
{
anvil: {
count: 20,
derivationPath: "m/44'/60'/0'/16/",
},
},
hre.config
)

expect(
getHardhatNetworkOverrides(simulationConfig, {
networkA,
})
).toStrictEqual({
networkA: {
...networkA,
url: `http://localhost:${simulationConfig.port}/networkA`,
accounts: {
count: simulationConfig.anvil.count,
initialIndex: 0,
passphrase: '',
path: simulationConfig.anvil.derivationPath,
mnemonic: simulationConfig.anvil.mnemonic,
},
},
Expand Down

0 comments on commit eb4e4d0

Please sign in to comment.