Skip to content

Commit

Permalink
WIP: unit testing Hardhat Task: getDefaultConfig
Browse files Browse the repository at this point in the history
  • Loading branch information
sirarthurmoney committed Nov 22, 2023
1 parent 8f8b4c6 commit 557bd21
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 121 deletions.
3 changes: 2 additions & 1 deletion packages/ua-utils-evm-hardhat-test/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "hardhat-deploy"
import "hardhat-deploy-ethers"
import { withLayerZeroArtifacts } from "../utils-evm-hardhat/dist"
import { withLayerZeroArtifacts } from "@layerzerolabs/utils-evm-hardhat"
import "@layerzerolabs/ua-utils-evm-hardhat/tasks"
import { EndpointId } from "@layerzerolabs/lz-definitions"
import { HardhatUserConfig } from "hardhat/types"

Expand Down
3 changes: 2 additions & 1 deletion packages/ua-utils-evm-hardhat-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"private": true,
"scripts": {
"lint": "npx eslint '**/*.{js,ts,json}'",
"test": "docker compose run --rm tests"
"test": "docker compose run --rm --build tests"
},
"repository": {
"type": "git",
Expand All @@ -23,6 +23,7 @@
"@gnosis.pm/safe-ethers-lib": "^1.0.0",
"@gnosis.pm/safe-service-client": "1.1.1",
"@layerzerolabs/utils-evm-hardhat": "~0.0.1",
"@layerzerolabs/ua-utils-evm-hardhat": "~0.0.1",
"@layerzerolabs/lz-definitions": "~1.5.58",
"@layerzerolabs/lz-evm-sdk-v1": "~1.5.58",
"@layerzerolabs/lz-evm-sdk-v2": "~1.5.58",
Expand Down
69 changes: 37 additions & 32 deletions packages/ua-utils-evm-hardhat-test/test/config.test.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
import { expect } from "chai"
import { describe } from "mocha"
import { getNetworkRuntimeEnvironment } from "../../utils-evm-hardhat/dist"
import { getNetworkRuntimeEnvironment } from "@layerzerolabs/utils-evm-hardhat"
import { HardhatRuntimeEnvironment } from "hardhat/types"
import { BigNumber, Contract } from "ethers"
import Config = Chai.Config
import { TransactionResponse } from "@ethersproject/providers"

const NETWORK_NAMES = ["vengaboys", "britney"]

describe("config", () => {
NETWORK_NAMES.forEach((networkName) => {
describe(`Network '${networkName}`, () => {
let environment: HardhatRuntimeEnvironment
let ultraLightNode302: Contract
let ulnConfig: Contract
let endpoint: Contract
let endpointId: number

before(async () => {
environment = await getNetworkRuntimeEnvironment(networkName)
const endpoint = await environment.ethers.getContract("EndpointV2")
endpoint = await environment.ethers.getContract("EndpointV2")
endpointId = await endpoint.eid()

ultraLightNode302 = await environment.ethers.getContract("UltraLightNode302")
const ulnConfigAddress = await ultraLightNode302.ulnConfig()
console.log({ ulnConfigAddress })

const defaultUnlConfig = {
inboundConfirmations: BigNumber.from(0),
Expand All @@ -48,23 +47,14 @@ describe("config", () => {
let outboundConfigStruct = await ulnConfig.defaultOutboundConfig(endpointId)

let decodedUlnConfig = decodeUlnConfigStruct(ulnConfigStruct)
console.log({ decodedUlnConfig, defaultUnlConfig })
expect(decodedUlnConfig).to.eql(defaultUnlConfig)

let decodeOutboundConfig = decodeOutboundConfigStruct(outboundConfigStruct)
console.log({ decodeOutboundConfig, defaultOutboundConfig })
expect(decodeOutboundConfig).to.eql(defaultOutboundConfig)
})

it("should have an endpoint deployed", async () => {
const endpoint = await environment.ethers.getContract("EndpointV2")
const endpointId = await endpoint.eid()

expect(environment.network.config.endpointId).to.be.a("number")
expect(endpointId).to.eql(environment.network.config.endpointId)
})

it("should setDefaultConfig ", async () => {
// TODO clean up test
const executerWallet = await environment.ethers.Wallet.createRandom()
const executerAddress = executerWallet.address

Expand All @@ -84,28 +74,43 @@ describe("config", () => {
optionalVerifierThreshold: 0,
}

const setUnlConfig = {
inboundConfirmations: setDefaultConfigParam.inboundConfirmations,
useCustomVerifiers: false,
useCustomOptionalVerifiers: false,
verifierCount: setDefaultConfigParam.verifiers.length,
optionalVerifierCount: setDefaultConfigParam.optionalVerifiers.length,
optionalVerifierThreshold: setDefaultConfigParam.optionalVerifierThreshold,
verifiers: setDefaultConfigParam.verifiers,
optionalVerifiers: setDefaultConfigParam.optionalVerifiers,
}
const setDefaultConfigResponse: TransactionResponse = await ultraLightNode302.setDefaultConfig([setDefaultConfigParam])
await setDefaultConfigResponse.wait()

await ultraLightNode302.setDefaultConfig([setDefaultConfigParam])
const registerLibraryResponse: TransactionResponse = await endpoint.registerLibrary(ultraLightNode302.address)
await registerLibraryResponse.wait()

const setDefaultSendLibraryResponse: TransactionResponse = await endpoint.setDefaultSendLibrary(
endpointId,
ultraLightNode302.address
)
await setDefaultSendLibraryResponse.wait()

const setDefaultReceiveLibraryResponse: TransactionResponse = await endpoint.setDefaultReceiveLibrary(
endpointId,
ultraLightNode302.address,
0
)
await setDefaultReceiveLibraryResponse.wait()

let getDefaultConfigTask = await environment.run("getDefaultConfig", { networks: networkName })

const defaultSendLibrary = await endpoint.defaultSendLibrary(endpointId)
expect(defaultSendLibrary).to.eql(ultraLightNode302.address)

const defaultReceiveLibrary = await endpoint.defaultReceiveLibrary(endpointId)
expect(defaultReceiveLibrary).to.eql(ultraLightNode302.address)

const ulnConfigStruct = await ulnConfig.getDefaultUlnConfig(endpointId)
let decodedUlnConfig = decodeUlnConfigStruct(ulnConfigStruct)
console.log({ decodedUlnConfig, setUnlConfig })
expect(decodedUlnConfig).to.eql(setUnlConfig)
expect(ulnConfigStruct.inboundConfirmations).to.eql(getDefaultConfigTask.inboundConfirmations)
expect(ulnConfigStruct.optionalVerifiers).to.eql(getDefaultConfigTask.optionalVerifiers)
expect(ulnConfigStruct.optionalVerifierThreshold).to.eql(getDefaultConfigTask.optionalVerifierThreshold)
expect(ulnConfigStruct.verifiers).to.eql(getDefaultConfigTask.verifiers)

const outboundConfigStruct = await ulnConfig.defaultOutboundConfig(endpointId)
let decodeOutboundConfig = decodeOutboundConfigStruct(outboundConfigStruct)
console.log({ decodeOutboundConfig, setDefaultConfigParam: setDefaultConfigParam.outboundConfig })
expect(decodeOutboundConfig).to.eql(setDefaultConfigParam.outboundConfig)
expect(outboundConfigStruct.maxMessageSize).to.eql(getDefaultConfigTask.maxMessageSize)
expect(outboundConfigStruct.outboundConfirmations).to.eql(getDefaultConfigTask.outboundConfirmations)
expect(outboundConfigStruct.executor).to.eql(getDefaultConfigTask.executor)
})
})
})
Expand Down
1 change: 1 addition & 0 deletions packages/ua-utils-evm-hardhat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@gnosis.pm/safe-ethers-lib": "^1.0.0",
"@gnosis.pm/safe-service-client": "1.1.1",
"@layerzerolabs/lz-definitions": "~1.5.58",
"@layerzerolabs/utils-evm-hardhat": "~0.0.1",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@types/mocha": "^10.0.1",
"cli-ux": "^6.0.9",
Expand Down
103 changes: 79 additions & 24 deletions packages/ua-utils-evm-hardhat/src/tasks/getDefaultConfig.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,89 @@
import { ActionType } from "hardhat/types"
import { task, types } from "hardhat/config"
import "hardhat-deploy-ethers/internal/type-extensions"
import { ethers } from "ethers"
import { getProvider, getLayerZeroChainId, getEndpointAddress } from "@/utils/crossChainHelper"
import { ENDPOINT_ABI, MESSAGING_LIBRARY_ABI } from "@/constants/abi"
import { getNetworkRuntimeEnvironment } from "@layerzerolabs/utils-evm-hardhat"

export default async (taskArgs: any, hre: any) => {
const networks = taskArgs.networks.split(",")
const CONFIG_TYPE_MAX_MESSAGE_SIZE = 1
const CONFIG_TYPE_OUTBOUND_CONFIRMATIONS = 2
const CONFIG_TYPE_EXECUTOR = 3
const CONFIG_TYPE_INBOUND_CONFIRMATIONS = 4
const CONFIG_TYPE_VERIFIERS = 5
const CONFIG_TYPE_OPTIONAL_VERIFIERS = 6
interface TaskArgs {
networks: string
}
export const getDefaultConfig: ActionType<TaskArgs> = async (taskArgs, hre) => {
// TODO add logging
// const logger = createLogger()

const networks = taskArgs.networks.split(",")
const configByNetwork = await Promise.all(
networks.map(async (network: string) => {
const provider = getProvider(hre, network)
console.log()
const endpoint = new ethers.Contract(getEndpointAddress(network), ENDPOINT_ABI, provider)
const sendVersion = await endpoint.defaultSendVersion()
const receiveVersion = await endpoint.defaultReceiveVersion()
const sendLibraryAddress = await endpoint.defaultSendLibrary()
const messagingLibrary = new ethers.Contract(sendLibraryAddress, MESSAGING_LIBRARY_ABI, provider)
const config = await messagingLibrary.defaultAppConfig(getLayerZeroChainId(network))

return {
const environment = await getNetworkRuntimeEnvironment(network)
const endpointV2 = await environment.ethers.getContract("EndpointV2")
const eid = await endpointV2.eid()

const defaultSendLibrary = await endpointV2.defaultSendLibrary(eid)
const defaultReceiveLibrary = await endpointV2.defaultReceiveLibrary(eid)

const maxMessageSizeEncodedData = await endpointV2.defaultConfig(defaultSendLibrary, eid, CONFIG_TYPE_MAX_MESSAGE_SIZE)
const maxMessageSize = ethers.utils.defaultAbiCoder.decode(["uint32"], maxMessageSizeEncodedData)

const outboundConfirmationsEncodedData = await endpointV2.defaultConfig(defaultSendLibrary, eid, CONFIG_TYPE_OUTBOUND_CONFIRMATIONS)
const outboundConfirmations = ethers.utils.defaultAbiCoder.decode(["uint64"], outboundConfirmationsEncodedData)

const executorEncodedData = await endpointV2.defaultConfig(defaultSendLibrary, eid, CONFIG_TYPE_EXECUTOR)
const executor = ethers.utils.defaultAbiCoder.decode(["address"], executorEncodedData)

const inboundBlockConfirmationsEncodedData = await endpointV2.defaultConfig(
defaultReceiveLibrary,
eid,
CONFIG_TYPE_INBOUND_CONFIRMATIONS
)
const inboundConfirmations = ethers.utils.defaultAbiCoder.decode(["uint64"], inboundBlockConfirmationsEncodedData)

const verifiersEncodedData = await endpointV2.defaultConfig(defaultReceiveLibrary, eid, CONFIG_TYPE_VERIFIERS)
const verifiers = ethers.utils.defaultAbiCoder.decode(["address[]"], verifiersEncodedData)

const optionalVerifierEncodedData = await endpointV2.defaultConfig(defaultReceiveLibrary, eid, CONFIG_TYPE_OPTIONAL_VERIFIERS)
const [optionalVerifiers, optionalVerifierThreshold] = ethers.utils.defaultAbiCoder.decode(
["address[]", "uint8"],
optionalVerifierEncodedData
)

const defaultConfig = {
network,
defaultSendLibrary,
defaultReceiveLibrary,
maxMessageSize: maxMessageSize[0],
outboundConfirmations: outboundConfirmations[0],
executor: executor.toString(),
inboundConfirmations: inboundConfirmations[0],
verifiers: verifiers[0],
optionalVerifiers,
optionalVerifierThreshold,
}

const consoleTableDefaultConfig = {
network,
sendVersion,
receiveVersion,
inboundProofLibraryVersion: config.inboundProofLibraryVersion,
inboundBlockConfirmations: config.inboundBlockConfirmations.toNumber(),
relayer: config.relayer,
outboundProofType: config.outboundProofType,
outboundBlockConfirmations: config.outboundBlockConfirmations.toNumber(),
oracle: config.oracle,
defaultSendLibrary,
defaultReceiveLibrary,
maxMessageSize: maxMessageSize[0],
outboundConfirmations: outboundConfirmations[0].toNumber(),
executor: executor.toString(),
inboundBlockConfirmations: inboundConfirmations[0].toNumber(),
verifiers: verifiers[0].toString(),
optionalVerifiers,
optionalVerifierThreshold,
}
return { defaultConfig, consoleTableDefaultConfig }
})
)

console.table(configByNetwork)
console.log(configByNetwork[0].consoleTableDefaultConfig)
return configByNetwork[0].defaultConfig
}

task("getDefaultConfig", "outputs the default Send and Receive Messaging Library versions and the default application config")
.addParam("networks", "comma separated list of networks")
.setAction(getDefaultConfig)
64 changes: 1 addition & 63 deletions packages/ua-utils-evm-hardhat/src/tasks/index.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1 @@
import { task, types } from "hardhat/config"
import wireAll from "./wireAll"
import setConfig from "./setConfig"
import getDefaultConfig from "./getDefaultConfig"
import getConfig from "./getConfig"
import checkWireAllConfig from "./checkWireAllConfig"

task(
"setConfig",
"sets Send and Receive Messaging Library versions and a custom application config for contracts implementing ILayerZeroUserApplicationConfig interface",
setConfig
)
.addParam("configPath", "the application config file path")
.addOptionalParam(
"name",
"name of the deployed contracts. Should be specified if the same contract deployed on different chains and the deployment information is located in the deployments folder"
)
.addOptionalParam("address", "address of the deployed contracts. Should be specified if the contract address is the same on all chains")
.addOptionalParam("gnosisConfigPath", "the path to a file with Gnosis config. If specified, the transactions will be sent to Gnosis")
.addOptionalParam("gasLimit", "override execution gasLimit")

task(
"getDefaultConfig",
"outputs the default Send and Receive Messaging Library versions and the default application config",
getDefaultConfig
).addParam("networks", "comma separated list of networks")

task("getConfig", "outputs the application's Send and Receive Messaging Library versions and the config for remote networks", getConfig)
.addParam("remoteNetworks", "comma separated list of remote networks")
.addOptionalParam(
"name",
"name of the deployed contract. Should be specified only if the deployment information is located in the deployments folder"
)
.addOptionalParam("address", "the contract address")

task("checkWireAllConfig", "", checkWireAllConfig)
.addParam("e", "the environment ie: mainnet, testnet or sandbox")
.addFlag("u", "show use custom adapter params")
.addFlag("t", "show trusted remote lookup")
.addFlag("m", "show min destination gas lookup")
.addParam("chains", "comma separated list of networks")
.addOptionalParam("contract", "name of contract")
.addOptionalParam("addresses", "addresses of contracts in same order as chains")
.addOptionalParam("proxyContract", "name of proxy contract")
.addOptionalParam("proxyChain", "name of proxy chain")

task("wireAll", "", wireAll)
.addParam("e", "the environment ie: mainnet, testnet or sandbox")
.addOptionalParam("noPrompt", "no prompt", false, types.boolean)
.addOptionalParam(
"configPath",
"Optional config path. Default: ./constants/wireUpConfig.json",
"./constants/wireUpConfig.json",
types.string
)
.addOptionalParam("n", "send to gnosis", false, types.boolean)
.addOptionalParam("gasLimit", "override execution gasLimit")
.addOptionalParam(
"gnosisConfigPath",
"Optional config path. Default: ./constants/gnosisConfig.json",
"./constants/gnosisConfig.json",
types.string
)
import "./getDefaultConfig"

0 comments on commit 557bd21

Please sign in to comment.