From 2e8a49e2e4a618065480547321a1d3058319aa4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= <95722332+sirarthurmoney@users.noreply.github.com> Date: Tue, 23 Jan 2024 17:46:22 -0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=B7=E2=80=8D=E2=99=82=EF=B8=8F?= =?UTF-8?q?=F0=9F=AA=9BRefactor=20OApp=20SetConfig=20(#226)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/smooth-chairs-warn.md | 6 + packages/ua-devtools/src/oapp/config.ts | 176 +- .../test/oapp/config.test.ts | 1566 +++++++++-------- 3 files changed, 959 insertions(+), 789 deletions(-) create mode 100644 .changeset/smooth-chairs-warn.md diff --git a/.changeset/smooth-chairs-warn.md b/.changeset/smooth-chairs-warn.md new file mode 100644 index 000000000..71d4e7f03 --- /dev/null +++ b/.changeset/smooth-chairs-warn.md @@ -0,0 +1,6 @@ +--- +"@layerzerolabs/ua-devtools-evm-hardhat-test": patch +"@layerzerolabs/ua-devtools": patch +--- + +Updated OApp config to combine setConfig transactions diff --git a/packages/ua-devtools/src/oapp/config.ts b/packages/ua-devtools/src/oapp/config.ts index 5fccee9c0..c9340e49d 100644 --- a/packages/ua-devtools/src/oapp/config.ts +++ b/packages/ua-devtools/src/oapp/config.ts @@ -1,10 +1,9 @@ -import { flattenTransactions, type OmniTransaction } from '@layerzerolabs/devtools' +import { Address, flattenTransactions, OmniPointMap, type OmniTransaction } from '@layerzerolabs/devtools' import { EnforcedOptions, OAppEnforcedOptionConfig, OAppFactory, OAppOmniGraph } from './types' import { createModuleLogger, printBoolean } from '@layerzerolabs/io-devtools' import { formatOmniVector, isDeepEqual } from '@layerzerolabs/devtools' -import { type SetConfigParam, Uln302ExecutorConfig, Uln302UlnConfig } from '@layerzerolabs/protocol-devtools' +import { SetConfigParam, Uln302ExecutorConfig } from '@layerzerolabs/protocol-devtools' import assert from 'assert' - export type OAppConfigurator = (graph: OAppOmniGraph, createSdk: OAppFactory) => Promise export const configureOApp: OAppConfigurator = async (graph: OAppOmniGraph, createSdk: OAppFactory) => @@ -102,81 +101,104 @@ export const configureReceiveLibraryTimeouts: OAppConfigurator = async (graph, c ) ) -export const configureSendConfig: OAppConfigurator = async (graph, createSdk) => - flattenTransactions( - await Promise.all( - graph.connections.map(async ({ vector: { from, to }, config }): Promise => { - if (config?.sendConfig == null) return [] - const setConfigParam: SetConfigParam[] = [] - const oappSdk = await createSdk(from) - const endpointSdk = await oappSdk.getEndpointSDK() - const currentSendLibrary = - config.sendLibrary ?? (await endpointSdk.getSendLibrary(from.address, to.eid)) - assert( - currentSendLibrary !== undefined, - 'sendLibrary has not been set in your config and no default value exists' - ) - const sendExecutorConfig: Uln302ExecutorConfig = await endpointSdk.getExecutorConfig( - from.address, - currentSendLibrary, - to.eid - ) - if (!isDeepEqual(sendExecutorConfig, config.sendConfig.executorConfig)) { - setConfigParam.push( - ...(await endpointSdk.getExecutorConfigParams(currentSendLibrary, [ - { eid: to.eid, executorConfig: config.sendConfig.executorConfig }, - ])) - ) - } - const sendUlnConfig = await endpointSdk.getUlnConfig(from.address, currentSendLibrary, to.eid) - if (!isDeepEqual(sendUlnConfig, config.sendConfig.ulnConfig)) { - setConfigParam.push( - ...(await endpointSdk.getUlnConfigParams(currentSendLibrary, [ - { eid: to.eid, ulnConfig: config.sendConfig.ulnConfig }, - ])) - ) - } - - if (setConfigParam.length === 0) return [] - return [await endpointSdk.setConfig(from.address, currentSendLibrary, setConfigParam)] - }) +export const configureSendConfig: OAppConfigurator = async (graph, createSdk) => { + // This function builds a map to find all SetConfigParam[] to execute for a given OApp and SendLibrary + const setConfigsByEndpointAndLibrary: OmniPointMap> = new OmniPointMap() + for (const { + vector: { from, to }, + config, + } of graph.connections) { + if (!config?.sendConfig) continue + const oappSdk = await createSdk(from) + const endpointSdk = await oappSdk.getEndpointSDK() + const currentSendLibrary = config?.sendLibrary ?? (await endpointSdk.getSendLibrary(from.address, to.eid)) + assert( + currentSendLibrary !== undefined, + 'sendLibrary has not been set in your config and no default value exists' ) - ) - -export const configureReceiveConfig: OAppConfigurator = async (graph, createSdk) => - flattenTransactions( - await Promise.all( - graph.connections.map(async ({ vector: { from, to }, config }): Promise => { - if (config?.receiveConfig == null) return [] + const sendExecutorConfig: Uln302ExecutorConfig = await endpointSdk.getExecutorConfig( + from.address, + currentSendLibrary, + to.eid + ) + const sendUlnConfig = await endpointSdk.getUlnConfig(from.address, currentSendLibrary, to.eid) + + if (!isDeepEqual(sendExecutorConfig, config.sendConfig.executorConfig)) { + const newSetConfigs: SetConfigParam[] = await endpointSdk.getExecutorConfigParams(currentSendLibrary, [ + { eid: to.eid, executorConfig: config.sendConfig.executorConfig }, + ]) + + // Updates map with new configs for that OApp and Send Library + const setConfigsByLibrary = setConfigsByEndpointAndLibrary.getOrElse(from, () => new Map()) + const existingSetConfigs = setConfigsByLibrary.get(currentSendLibrary) ?? [] + setConfigsByEndpointAndLibrary.set( + from, + setConfigsByLibrary.set(currentSendLibrary, [...existingSetConfigs, ...newSetConfigs]) + ) + } + + if (!isDeepEqual(sendUlnConfig, config.sendConfig.ulnConfig)) { + const newSetConfigs: SetConfigParam[] = await endpointSdk.getUlnConfigParams(currentSendLibrary, [ + { eid: to.eid, ulnConfig: config.sendConfig.ulnConfig }, + ]) + + // Updates map with new configs for that OApp and Send Library + const setConfigsByLibrary = setConfigsByEndpointAndLibrary.getOrElse(from, () => new Map()) + const existingSetConfigs = setConfigsByLibrary.get(currentSendLibrary) ?? [] + setConfigsByEndpointAndLibrary.set( + from, + setConfigsByLibrary.set(currentSendLibrary, [...existingSetConfigs, ...newSetConfigs]) + ) + } + } + + // This function iterates over the map (OApp -> SendLibrary -> SetConfigParam[]) to execute setConfig + return buildOmniTransactions(setConfigsByEndpointAndLibrary, createSdk) +} - const oappSdk = await createSdk(from) - const endpointSdk = await oappSdk.getEndpointSDK() - const [currentReceiveLibrary] = config.receiveLibraryConfig?.receiveLibrary - ? [config.receiveLibraryConfig?.receiveLibrary, false] - : await endpointSdk.getReceiveLibrary(from.address, to.eid) - assert( - currentReceiveLibrary !== undefined, - 'receiveLibrary has not been set in your config and no default value exists' - ) - const receiveUlnConfig: Uln302UlnConfig = ( - await endpointSdk.getUlnConfig(from.address, currentReceiveLibrary, to.eid) - ) - if (isDeepEqual(receiveUlnConfig, config.receiveConfig.ulnConfig)) return [] - return [ - await endpointSdk.setUlnConfig(from.address, currentReceiveLibrary, [ - { eid: to.eid, ulnConfig: config.receiveConfig.ulnConfig }, - ]), - ] - }) +export const configureReceiveConfig: OAppConfigurator = async (graph, createSdk) => { + // This function builds a map to find all SetConfigParam[] to execute for a given OApp and ReceiveLibrary + const setConfigsByEndpointAndLibrary: OmniPointMap> = new OmniPointMap() + for (const { + vector: { from, to }, + config, + } of graph.connections) { + if (!config?.receiveConfig) continue + const oappSdk = await createSdk(from) + const endpointSdk = await oappSdk.getEndpointSDK() + const [currentReceiveLibrary] = config?.receiveLibraryConfig?.receiveLibrary + ? [config.receiveLibraryConfig?.receiveLibrary, false] + : await endpointSdk.getReceiveLibrary(from.address, to.eid) + assert( + currentReceiveLibrary !== undefined, + 'receiveLibrary has not been set in your config and no default value exists' ) - ) + const receiveUlnConfig = await endpointSdk.getUlnConfig(from.address, currentReceiveLibrary, to.eid) + + if (!isDeepEqual(receiveUlnConfig, config.receiveConfig.ulnConfig)) { + const newSetConfigs: SetConfigParam[] = await endpointSdk.getUlnConfigParams(currentReceiveLibrary, [ + { eid: to.eid, ulnConfig: config.receiveConfig.ulnConfig }, + ]) + + // Updates map with new configs for that OApp and Receive Library + const setConfigsByLibrary = setConfigsByEndpointAndLibrary.getOrElse(from, () => new Map()) + const existingSetConfigs = setConfigsByLibrary.get(currentReceiveLibrary) ?? [] + setConfigsByEndpointAndLibrary.set( + from, + setConfigsByLibrary.set(currentReceiveLibrary, [...existingSetConfigs, ...newSetConfigs]) + ) + } + } + + // This function iterates over the map (OApp -> ReceiveLibrary -> SetConfigParam[]) to execute setConfig + return buildOmniTransactions(setConfigsByEndpointAndLibrary, createSdk) +} export const configureEnforcedOptions: OAppConfigurator = async (graph, createSdk) => flattenTransactions( await Promise.all( graph.connections.map(async ({ vector: { from, to }, config }): Promise => { if (config?.enforcedOptions == null) return [] - const enforcedOptions: EnforcedOptions[] = [] const enforcedOptionsConfig: OAppEnforcedOptionConfig[] = config.enforcedOptions const oappSdk = await createSdk(from) @@ -191,9 +213,23 @@ export const configureEnforcedOptions: OAppConfigurator = async (graph, createSd }) } } - if (enforcedOptions.length === 0) return [] return [await oappSdk.setEnforcedOptions(enforcedOptions)] }) ) ) + +const buildOmniTransactions = async ( + setConfigsByEndpointAndLibrary: OmniPointMap>, + createSdk: OAppFactory +): Promise => { + const omniTransaction: OmniTransaction[] = [] + for (const [from, configsByLibrary] of setConfigsByEndpointAndLibrary) { + const oapp = await createSdk(from) + const endpoint = await oapp.getEndpointSDK() + for (const [library, setConfigParams] of configsByLibrary) { + omniTransaction.push(await endpoint.setConfig(from.address, library, setConfigParams)) + } + } + return omniTransaction +} diff --git a/tests/ua-devtools-evm-hardhat-test/test/oapp/config.test.ts b/tests/ua-devtools-evm-hardhat-test/test/oapp/config.test.ts index 5feda0fbe..875a545e9 100644 --- a/tests/ua-devtools-evm-hardhat-test/test/oapp/config.test.ts +++ b/tests/ua-devtools-evm-hardhat-test/test/oapp/config.test.ts @@ -5,33 +5,50 @@ import { OmniContractFactoryHardhat, createConnectedContractFactory, createSignerFactory, + createProviderFactory, } from '@layerzerolabs/devtools-evm-hardhat' import { createOAppFactory } from '@layerzerolabs/ua-devtools-evm' -import { configureOApp, OAppFactory, OAppOmniGraph } from '@layerzerolabs/ua-devtools' -import { omniContractToPoint } from '@layerzerolabs/devtools-evm' +import { configureOApp, IOApp, OAppFactory, OAppOmniGraph } from '@layerzerolabs/ua-devtools' +import { OmniContract, omniContractToPoint } from '@layerzerolabs/devtools-evm' import { getLibraryAddress } from '../__utils__/oapp' import { - avaxReceiveUln, - ethReceiveUln, setupDefaultEndpoint, - ethSendUln2_Opt2, - ethReceiveUln2_Opt2, - avaxSendUln2_Opt2, - avaxReceiveUln2_Opt2, avaxExecutor, - ethDvn, avaxDvn, ethSendUln, deployEndpoint, + bscExecutor, + bscDvn, + ethSendUln2_Opt2, + avaxSendUln2_Opt2, + ethReceiveUln2_Opt2, + avaxReceiveUln2_Opt2, + ethReceiveUln, + avaxReceiveUln, + ethDvn, } from '../__utils__/endpoint' +import { createSignAndSend, OmniPoint } from '@layerzerolabs/devtools' +import { IEndpoint } from '@layerzerolabs/protocol-devtools' describe('oapp/config', () => { const ethPointHardhat = { eid: EndpointId.ETHEREUM_V2_MAINNET, contractName: 'DefaultOApp' } const avaxPointHardhat = { eid: EndpointId.AVALANCHE_V2_MAINNET, contractName: 'DefaultOApp' } + const bscPointHardhat = { eid: EndpointId.BSC_V2_MAINNET, contractName: 'DefaultOApp' } let contractFactory: OmniContractFactoryHardhat + let signAndSend let oappSdkFactory: OAppFactory + let ethContract: OmniContract + let ethPoint: OmniPoint + let ethOAppSdk: IOApp + let ethEndpointSdk: IEndpoint + + let avaxContract: OmniContract + let avaxPoint: OmniPoint + let avaxOAppSdk: IOApp + let avaxEndpointSdk: IEndpoint + // This is the OApp config that we want to use against our contracts beforeEach(async () => { await deployEndpoint() @@ -39,36 +56,26 @@ describe('oapp/config', () => { await deployOApp() contractFactory = createConnectedContractFactory() + signAndSend = createSignAndSend(createSignerFactory()) oappSdkFactory = createOAppFactory(contractFactory) - }) - describe('configureOApp', () => { - it('should return an empty array with an empty config', async () => { - const graph: OAppOmniGraph = { - contracts: [], - connections: [], - } + ethContract = await contractFactory(ethPointHardhat) + avaxContract = await contractFactory(avaxPointHardhat) - // Now we configure the OApp - const transactions = await configureOApp(graph, oappSdkFactory) + ethPoint = omniContractToPoint(ethContract) + ethOAppSdk = await oappSdkFactory(ethPoint) - expect(transactions).toEqual([]) - }) + avaxPoint = omniContractToPoint(avaxContract) + avaxOAppSdk = await oappSdkFactory(avaxPoint) + + ethEndpointSdk = await ethOAppSdk.getEndpointSDK() + avaxEndpointSdk = await avaxOAppSdk.getEndpointSDK() }) describe('configureOAppPeers', () => { - it('should return all setPeer transactions', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) - - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) - - // This is the OApp config that we want to use against our contracts - const graph: OAppOmniGraph = { + let graph: OAppOmniGraph + beforeEach(async () => { + graph = { contracts: [ { point: ethPoint, @@ -88,47 +95,19 @@ describe('oapp/config', () => { }, ], } + }) - // Now we configure the OApp - const transactions = await configureOApp(graph, oappSdkFactory) + it('should return all setPeer transactions', async () => { + // This is the OApp config that we want to use against our contracts - expect(transactions).toEqual([ + const transactions = await configureOApp(graph, oappSdkFactory) + const expectedTransactions = [ await ethOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address), - ]) + ] + expect(transactions).toEqual(expectedTransactions) }) it('should exclude setPeer transactions for peers that have been set', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) - - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) - - // This is the OApp config that we want to use against our contracts - const graph: OAppOmniGraph = { - contracts: [ - { - point: ethPoint, - }, - { - point: avaxPoint, - }, - ], - connections: [ - { - vector: { from: ethPoint, to: avaxPoint }, - config: undefined, - }, - { - vector: { from: avaxPoint, to: ethPoint }, - config: undefined, - }, - ], - } - // Before we configure the OApp, we'll set some peers { const signerFactory = createSignerFactory() @@ -141,734 +120,883 @@ describe('oapp/config', () => { // Now we configure the OApp const transactions = await configureOApp(graph, oappSdkFactory) - // And expect the setPeer on the eth contact not to be there expect(transactions).toEqual([await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address)]) }) }) - describe('configureSendLibraries', () => { - it('should return all setPeer transactions and configureSendLibraries transactions', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) - - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - const ethEndpointSdk = await ethOAppSdk.getEndpointSDK() - - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) - const avaxEndpointSdk = await avaxOAppSdk.getEndpointSDK() - - const ethSendLibrary = await getLibraryAddress(ethSendUln2_Opt2) - const avaxSendLibrary = await getLibraryAddress(avaxSendUln2_Opt2) - - // This is the OApp config that we want to use against our contracts + describe('configureOApp', () => { + it('should return an empty array with an empty config', async () => { const graph: OAppOmniGraph = { - contracts: [ - { - point: ethPoint, - }, - { - point: avaxPoint, - }, - ], - connections: [ - { - vector: { from: ethPoint, to: avaxPoint }, - config: { - sendLibrary: ethSendLibrary, - }, - }, - { - vector: { from: avaxPoint, to: ethPoint }, - config: { - sendLibrary: avaxSendLibrary, - }, - }, - ], + contracts: [], + connections: [], } // Now we configure the OApp const transactions = await configureOApp(graph, oappSdkFactory) - expect(transactions).toEqual([ - await ethOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), - await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address), - await ethEndpointSdk.setSendLibrary(ethPoint.address, avaxPoint.eid, ethSendLibrary), - await avaxEndpointSdk.setSendLibrary(avaxPoint.address, ethPoint.eid, avaxSendLibrary), - ]) + expect(transactions).toEqual([]) }) - it('should return all setPeer transactions and one configureSendLibraries transaction', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) - - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - const ethEndpointSdk = await ethOAppSdk.getEndpointSDK() - - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) - const avaxEndpointSdk = await avaxOAppSdk.getEndpointSDK() - - const ethSendLibrary = await getLibraryAddress(ethSendUln2_Opt2) - const avaxSendLibrary = await getLibraryAddress(avaxSendUln2_Opt2) - - // This is the OApp config that we want to use against our contracts - const graph: OAppOmniGraph = { - contracts: [ - { - point: ethPoint, - }, - { - point: avaxPoint, - }, - ], - connections: [ - { - vector: { from: ethPoint, to: avaxPoint }, - config: { - sendLibrary: ethSendLibrary, - }, - }, - { - vector: { from: avaxPoint, to: ethPoint }, - config: { - sendLibrary: avaxSendLibrary, - }, - }, - ], - } - - { - const signerFactory = createSignerFactory() - // register new Send ULNs on ETH - const ethSigner = await signerFactory(ethContract.eid) - await ethSigner.signAndSend(await ethEndpointSdk.registerLibrary(ethSendLibrary)) - await ethSigner.signAndSend( - await ethEndpointSdk.setSendLibrary(ethPoint.address, avaxPoint.eid, ethSendLibrary) - ) - } - // Now we configure the OApp - const transactions = await configureOApp(graph, oappSdkFactory) - expect(transactions).toEqual([ + beforeEach(async () => { + await signAndSend([ await ethOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address), - await avaxEndpointSdk.setSendLibrary(avaxPoint.address, ethPoint.eid, avaxSendLibrary), ]) }) - }) - - describe('configureReceiveLibraries', () => { - it('should return all setPeer transactions and configureReceiveLibraries transactions', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - const ethEndpointSdk = await ethOAppSdk.getEndpointSDK() - - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) - const avaxEndpointSdk = await avaxOAppSdk.getEndpointSDK() - - const ethReceiveLibrary = await getLibraryAddress(ethReceiveUln2_Opt2) - const avaxReceiveLibrary = await getLibraryAddress(avaxReceiveUln2_Opt2) - - // This is the OApp config that we want to use against our contracts - const graph: OAppOmniGraph = { - contracts: [ - { - point: ethPoint, - }, - { - point: avaxPoint, - }, - ], - connections: [ - { - vector: { from: ethPoint, to: avaxPoint }, - config: { - receiveLibraryConfig: { - receiveLibrary: ethReceiveLibrary, - gracePeriod: 0, + describe('configureSendLibraries', () => { + let ethSendLibrary: string, avaxSendLibrary: string, graph: OAppOmniGraph + beforeEach(async () => { + ethSendLibrary = await getLibraryAddress(ethSendUln2_Opt2) + avaxSendLibrary = await getLibraryAddress(avaxSendUln2_Opt2) + graph = { + contracts: [ + { + point: ethPoint, + }, + { + point: avaxPoint, + }, + ], + connections: [ + { + vector: { from: ethPoint, to: avaxPoint }, + config: { + sendLibrary: ethSendLibrary, }, }, - }, - { - vector: { from: avaxPoint, to: ethPoint }, - config: { - receiveLibraryConfig: { - receiveLibrary: avaxReceiveLibrary, - gracePeriod: 0, + { + vector: { from: avaxPoint, to: ethPoint }, + config: { + sendLibrary: avaxSendLibrary, }, }, - }, - ], - } - - // Now we configure the OApp - const transactions = await configureOApp(graph, oappSdkFactory) - expect(transactions).toEqual([ - await ethOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), - await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address), - await ethEndpointSdk.setReceiveLibrary(ethPoint.address, avaxPoint.eid, ethReceiveLibrary, 0), - await avaxEndpointSdk.setReceiveLibrary(avaxPoint.address, ethPoint.eid, avaxReceiveLibrary, 0), - ]) + ], + } + }) + + it('should configureSendLibraries transactions', async () => { + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + expect(transactions).toEqual([ + await ethEndpointSdk.setSendLibrary(ethPoint.address, avaxPoint.eid, ethSendLibrary), + await avaxEndpointSdk.setSendLibrary(avaxPoint.address, ethPoint.eid, avaxSendLibrary), + ]) + }) + it('should return one configureSendLibraries transaction', async () => { + // Before we configure the OApp, we'll register and set one of the send libraries + { + await signAndSend([ + await ethEndpointSdk.registerLibrary(ethSendLibrary), + await ethEndpointSdk.setSendLibrary(ethPoint.address, avaxPoint.eid, ethSendLibrary), + ]) + } + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + expect(transactions).toEqual([ + await avaxEndpointSdk.setSendLibrary(avaxPoint.address, ethPoint.eid, avaxSendLibrary), + ]) + }) }) - it('should return all setPeer transactions and one configureReceiveLibraries transaction', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) - - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - const ethEndpointSdk = await ethOAppSdk.getEndpointSDK() - - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) - const avaxEndpointSdk = await avaxOAppSdk.getEndpointSDK() - const ethReceiveLibrary = await getLibraryAddress(ethReceiveUln2_Opt2) - const avaxReceiveLibrary = await getLibraryAddress(avaxReceiveUln2_Opt2) - - // This is the OApp config that we want to use against our contracts - const graph: OAppOmniGraph = { - contracts: [ - { - point: ethPoint, - }, - { - point: avaxPoint, - }, - ], - connections: [ - { - vector: { from: ethPoint, to: avaxPoint }, - config: { - receiveLibraryConfig: { - receiveLibrary: ethReceiveLibrary, - gracePeriod: 0, + describe('configureReceiveLibraries', () => { + let ethReceiveLibrary: string, avaxReceiveLibrary: string, graph: OAppOmniGraph + beforeEach(async () => { + ethReceiveLibrary = await getLibraryAddress(ethReceiveUln2_Opt2) + avaxReceiveLibrary = await getLibraryAddress(avaxReceiveUln2_Opt2) + graph = { + contracts: [ + { + point: ethPoint, + }, + { + point: avaxPoint, + }, + ], + connections: [ + { + vector: { from: ethPoint, to: avaxPoint }, + config: { + receiveLibraryConfig: { + receiveLibrary: ethReceiveLibrary, + gracePeriod: 0, + }, }, }, - }, - { - vector: { from: avaxPoint, to: ethPoint }, - config: { - receiveLibraryConfig: { - receiveLibrary: avaxReceiveLibrary, - gracePeriod: 0, + { + vector: { from: avaxPoint, to: ethPoint }, + config: { + receiveLibraryConfig: { + receiveLibrary: avaxReceiveLibrary, + gracePeriod: 0, + }, }, }, - }, - ], - } - - { - const signerFactory = createSignerFactory() - // register new Send ULNs on ETH - const ethSigner = await signerFactory(ethContract.eid) - await ethSigner.signAndSend(await ethEndpointSdk.registerLibrary(ethReceiveLibrary)) - await ethSigner.signAndSend( - await ethEndpointSdk.setReceiveLibrary(ethPoint.address, avaxPoint.eid, ethReceiveLibrary, 0) - ) - } - - // Now we configure the OApp - const transactions = await configureOApp(graph, oappSdkFactory) - expect(transactions).toEqual([ - await ethOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), - await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address), - await avaxEndpointSdk.setReceiveLibrary(avaxPoint.address, ethPoint.eid, avaxReceiveLibrary, 0), - ]) + ], + } + }) + + it('should return all configureReceiveLibraries transactions', async () => { + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + expect(transactions).toEqual([ + await ethEndpointSdk.setReceiveLibrary(ethPoint.address, avaxPoint.eid, ethReceiveLibrary, 0), + await avaxEndpointSdk.setReceiveLibrary(avaxPoint.address, ethPoint.eid, avaxReceiveLibrary, 0), + ]) + }) + it('should return one configureReceiveLibraries transaction', async () => { + // Before we configure the OApp, we'll register and set one of the receiving libraries + { + await signAndSend([ + await ethEndpointSdk.registerLibrary(ethReceiveLibrary), + await ethEndpointSdk.setReceiveLibrary(ethPoint.address, avaxPoint.eid, ethReceiveLibrary, 0), + ]) + } + const transactions = await configureOApp(graph, oappSdkFactory) + expect(transactions).toEqual([ + await avaxEndpointSdk.setReceiveLibrary(avaxPoint.address, ethPoint.eid, avaxReceiveLibrary, 0), + ]) + }) }) - }) - describe('configureReceiveLibraryTimeouts', () => { - it('should return all setPeer transactions and configureReceiveLibraryTimeouts transactions', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) - - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - const ethEndpointSdk = await ethOAppSdk.getEndpointSDK() - - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) - const avaxEndpointSdk = await avaxOAppSdk.getEndpointSDK() - - const ethDefaultReceiveLibrary = await getLibraryAddress(ethReceiveUln) - const ethReceiveLibrary = await getLibraryAddress(ethReceiveUln2_Opt2) - - const avaxDefaultReceiveLibrary = await getLibraryAddress(avaxReceiveUln) - const avaxReceiveLibrary = await getLibraryAddress(avaxReceiveUln2_Opt2) - - // This is the OApp config that we want to use against our contracts - const graph: OAppOmniGraph = { - contracts: [ - { - point: ethPoint, - }, - { - point: avaxPoint, - }, - ], - connections: [ - { - vector: { from: ethPoint, to: avaxPoint }, - config: { - receiveLibraryConfig: { - receiveLibrary: ethReceiveLibrary, - gracePeriod: 0, - }, - receiveLibraryTimeoutConfig: { - lib: ethDefaultReceiveLibrary, - expiry: 42, - }, + describe('configureReceiveLibraryTimeouts', () => { + let ethDefaultReceiveLibrary: string, + ethReceiveLibrary_Opt2: string, + avaxDefaultReceiveLibrary: string, + avaxReceiveLibrary_Opt2: string, + graph: OAppOmniGraph, + expiryEthBlock: number, + expiryAvaxBlock: number + beforeEach(async () => { + ethDefaultReceiveLibrary = await getLibraryAddress(ethReceiveUln) + ethReceiveLibrary_Opt2 = await getLibraryAddress(ethReceiveUln2_Opt2) + + avaxDefaultReceiveLibrary = await getLibraryAddress(avaxReceiveUln) + avaxReceiveLibrary_Opt2 = await getLibraryAddress(avaxReceiveUln2_Opt2) + + const createProvider = createProviderFactory() + const ethProvider = await createProvider(EndpointId.ETHEREUM_V2_MAINNET) + const latestEthBlock = (await ethProvider.getBlock('latest')).number + expiryEthBlock = latestEthBlock + 1000 + + const avaxProvider = await createProvider(EndpointId.AVALANCHE_V2_MAINNET) + const latestAvaxBlock = (await avaxProvider.getBlock('latest')).number + expiryAvaxBlock = latestAvaxBlock + 1000 + + graph = { + contracts: [ + { + point: ethPoint, }, - }, - { - vector: { from: avaxPoint, to: ethPoint }, - config: { - receiveLibraryConfig: { - receiveLibrary: avaxReceiveLibrary, - gracePeriod: 0, + { + point: avaxPoint, + }, + ], + connections: [ + { + vector: { from: ethPoint, to: avaxPoint }, + config: { + receiveLibraryConfig: { + receiveLibrary: ethReceiveLibrary_Opt2, + gracePeriod: 0, + }, + receiveLibraryTimeoutConfig: { + lib: ethDefaultReceiveLibrary, + expiry: expiryEthBlock, + }, }, - receiveLibraryTimeoutConfig: { - lib: avaxDefaultReceiveLibrary, - expiry: 42, + }, + { + vector: { from: avaxPoint, to: ethPoint }, + config: { + receiveLibraryConfig: { + receiveLibrary: avaxReceiveLibrary_Opt2, + gracePeriod: 0, + }, + receiveLibraryTimeoutConfig: { + lib: avaxDefaultReceiveLibrary, + expiry: expiryAvaxBlock, + }, }, }, - }, - ], - } - - { - const signerFactory = createSignerFactory() - // register new Send ULNs on ETH - const ethSigner = await signerFactory(ethContract.eid) - await ethSigner.signAndSend(await ethEndpointSdk.registerLibrary(ethReceiveLibrary)) - await ethSigner.signAndSend( - await ethEndpointSdk.setReceiveLibrary(ethPoint.address, avaxPoint.eid, ethReceiveLibrary, 0) - ) - - // register new Send ULNs on AVAX - const avaxSigner = await signerFactory(avaxContract.eid) - await avaxSigner.signAndSend(await avaxEndpointSdk.registerLibrary(avaxReceiveLibrary)) - await avaxSigner.signAndSend( - await avaxEndpointSdk.setReceiveLibrary(avaxPoint.address, ethPoint.eid, avaxReceiveLibrary, 0) - ) - } - - // Now we configure the OApp - const transactions = await configureOApp(graph, oappSdkFactory) - expect(transactions).toEqual([ - await ethOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), - await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address), - await ethEndpointSdk.setReceiveLibraryTimeout( - ethPoint.address, - avaxPoint.eid, - ethDefaultReceiveLibrary, - 42 - ), - await avaxEndpointSdk.setReceiveLibraryTimeout( - avaxPoint.address, - ethPoint.eid, - avaxDefaultReceiveLibrary, - 42 - ), - ]) + ], + } + }) + it('should return all configureReceiveLibraryTimeouts transactions', async () => { + { + await signAndSend([ + await ethEndpointSdk.registerLibrary(ethReceiveLibrary_Opt2), + await ethEndpointSdk.setReceiveLibrary( + ethPoint.address, + avaxPoint.eid, + ethReceiveLibrary_Opt2, + 0 + ), + await avaxEndpointSdk.registerLibrary(avaxReceiveLibrary_Opt2), + await avaxEndpointSdk.setReceiveLibrary( + avaxPoint.address, + ethPoint.eid, + avaxReceiveLibrary_Opt2, + 0 + ), + ]) + } + + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + expect(transactions).toEqual([ + await ethEndpointSdk.setReceiveLibraryTimeout( + ethPoint.address, + avaxPoint.eid, + ethDefaultReceiveLibrary, + expiryEthBlock + ), + await avaxEndpointSdk.setReceiveLibraryTimeout( + avaxPoint.address, + ethPoint.eid, + avaxDefaultReceiveLibrary, + expiryAvaxBlock + ), + ]) + }) + + it('should return one configureReceiveLibraryTimeouts transactions', async () => { + { + await signAndSend([ + await ethEndpointSdk.registerLibrary(ethReceiveLibrary_Opt2), + await ethEndpointSdk.setReceiveLibrary( + ethPoint.address, + avaxPoint.eid, + ethReceiveLibrary_Opt2, + 0 + ), + await avaxEndpointSdk.registerLibrary(avaxReceiveLibrary_Opt2), + await avaxEndpointSdk.setReceiveLibrary( + avaxPoint.address, + ethPoint.eid, + avaxReceiveLibrary_Opt2, + 0 + ), + await ethEndpointSdk.setReceiveLibraryTimeout( + ethPoint.address, + avaxPoint.eid, + ethDefaultReceiveLibrary, + expiryEthBlock + ), + ]) + } + + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + const expectedTransactions = [ + await avaxEndpointSdk.setReceiveLibraryTimeout( + avaxPoint.address, + ethPoint.eid, + avaxDefaultReceiveLibrary, + expiryAvaxBlock + ), + ] + expect(transactions).toEqual(expectedTransactions) + }) }) - }) - describe('configureSendConfig', () => { - it('should return all setPeer transactions and configureSendConfig transactions', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) - - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - const ethEndpointSdk = await ethOAppSdk.getEndpointSDK() - - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) - - const avaxExecutorAddress = await getLibraryAddress(avaxExecutor) - const avaxDvnAddress = await getLibraryAddress(avaxDvn) - const ethSendUlnDVNs: string[] = [avaxDvnAddress] - - const ethSendLibrary = await getLibraryAddress(ethSendUln) - - // This is the OApp config that we want to use against our contracts - const graph: OAppOmniGraph = { - contracts: [ - { - point: ethPoint, - }, - { - point: avaxPoint, - }, - ], - connections: [ - { - vector: { from: ethPoint, to: avaxPoint }, - config: { - sendConfig: { - executorConfig: { - maxMessageSize: 99, - executor: avaxExecutorAddress, + describe('configureConfig', () => { + let bscContract, bscPoint, bscOAppSdk + beforeEach(async () => { + bscContract = await contractFactory(bscPointHardhat) + bscPoint = omniContractToPoint(bscContract) + bscOAppSdk = await oappSdkFactory(bscPoint) + // Before we configure the OApp, we'll set some peers + { + await signAndSend([ + await ethOAppSdk.setPeer(bscPoint.eid, bscPoint.address), + await avaxOAppSdk.setPeer(bscPoint.eid, bscPoint.address), + await bscOAppSdk.setPeer(ethPoint.eid, ethPoint.address), + await bscOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), + ]) + } + }) + describe('configureSendConfig', () => { + let graph: OAppOmniGraph, + bscExecutorAddress: string, + bscDvnAddress: string, + avaxExecutorAddress: string, + avaxDvnAddress: string, + ethToAvaxSendUlnDVNs: string[], + ethToBscSendUlnDVNs: string[], + ethSendLibrary: string + beforeEach(async () => { + bscExecutorAddress = await getLibraryAddress(bscExecutor) + bscDvnAddress = await getLibraryAddress(bscDvn) + + avaxExecutorAddress = await getLibraryAddress(avaxExecutor) + avaxDvnAddress = await getLibraryAddress(avaxDvn) + + ethToAvaxSendUlnDVNs = [avaxDvnAddress] + ethToBscSendUlnDVNs = [bscDvnAddress] + ethSendLibrary = await getLibraryAddress(ethSendUln) + + graph = { + contracts: [ + { + point: ethPoint, + }, + { + point: avaxPoint, + }, + { + point: bscPoint, + }, + ], + connections: [ + { + vector: { from: ethPoint, to: avaxPoint }, + config: { + sendConfig: { + executorConfig: { + maxMessageSize: 99, + executor: avaxExecutorAddress, + }, + ulnConfig: { + confirmations: BigInt(42), + requiredDVNs: ethToAvaxSendUlnDVNs, + optionalDVNs: ethToAvaxSendUlnDVNs, + optionalDVNThreshold: 1, + }, + }, }, - ulnConfig: { - confirmations: 42, - requiredDVNs: ethSendUlnDVNs, - optionalDVNs: ethSendUlnDVNs, - optionalDVNThreshold: 0, - requiredDVNCount: ethSendUlnDVNs.length, - optionalDVNCount: ethSendUlnDVNs.length, + }, + { + vector: { from: ethPoint, to: bscPoint }, + config: { + sendConfig: { + executorConfig: { + maxMessageSize: 99, + executor: bscExecutorAddress, + }, + ulnConfig: { + confirmations: BigInt(42), + requiredDVNs: ethToBscSendUlnDVNs, + optionalDVNs: ethToBscSendUlnDVNs, + optionalDVNThreshold: 1, + }, + }, }, }, - }, - }, - { - vector: { from: avaxPoint, to: ethPoint }, - config: undefined, - }, - ], - } - - // Now we configure the OApp - const transactions = await configureOApp(graph, oappSdkFactory) - - expect(transactions).toEqual([ - await ethOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), - await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address), - await ethEndpointSdk.setConfig(ethPoint.address, ethSendLibrary, [ - ...(await ethEndpointSdk.getExecutorConfigParams(ethSendLibrary, [ - { - eid: avaxPoint.eid, - executorConfig: { - maxMessageSize: 99, - executor: avaxExecutorAddress, + { + vector: { from: avaxPoint, to: ethPoint }, + config: undefined, }, - }, - ])), - ...(await ethEndpointSdk.getUlnConfigParams(ethSendLibrary, [ - { - eid: avaxPoint.eid, - ulnConfig: { - confirmations: 42, - requiredDVNs: ethSendUlnDVNs, - optionalDVNs: ethSendUlnDVNs, - optionalDVNThreshold: 0, - requiredDVNCount: ethSendUlnDVNs.length, - optionalDVNCount: ethSendUlnDVNs.length, + { + vector: { from: avaxPoint, to: bscPoint }, + config: undefined, }, - }, - ])), - ]), - ]) + { + vector: { from: bscPoint, to: ethPoint }, + config: undefined, + }, + { + vector: { from: bscPoint, to: avaxPoint }, + config: undefined, + }, + ], + } + }) + + it('should return all configureSendConfig transactions', async () => { + const transactions = await configureOApp(graph, oappSdkFactory) + const expectedTransactions = [ + await ethEndpointSdk.setConfig(ethPoint.address, ethSendLibrary, [ + ...(await ethEndpointSdk.getExecutorConfigParams(ethSendLibrary, [ + { + eid: avaxPoint.eid, + executorConfig: { + maxMessageSize: 99, + executor: avaxExecutorAddress, + }, + }, + ])), + ...(await ethEndpointSdk.getUlnConfigParams(ethSendLibrary, [ + { + eid: avaxPoint.eid, + ulnConfig: { + confirmations: BigInt(42), + requiredDVNs: ethToAvaxSendUlnDVNs, + optionalDVNs: ethToAvaxSendUlnDVNs, + optionalDVNThreshold: 1, + }, + }, + ])), + ...(await ethEndpointSdk.getExecutorConfigParams(ethSendLibrary, [ + { + eid: bscPoint.eid, + executorConfig: { + maxMessageSize: 99, + executor: bscExecutorAddress, + }, + }, + ])), + ...(await ethEndpointSdk.getUlnConfigParams(ethSendLibrary, [ + { + eid: bscPoint.eid, + ulnConfig: { + confirmations: BigInt(42), + requiredDVNs: ethToBscSendUlnDVNs, + optionalDVNs: ethToBscSendUlnDVNs, + optionalDVNThreshold: 1, + }, + }, + ])), + ]), + ] + expect(transactions).toEqual(expectedTransactions) + }) + + it('should return one configureSendConfig transactions', async () => { + { + await signAndSend([ + await ethEndpointSdk.setConfig(ethPoint.address, ethSendLibrary, [ + ...(await ethEndpointSdk.getExecutorConfigParams(ethSendLibrary, [ + { + eid: bscPoint.eid, + executorConfig: { + maxMessageSize: 99, + executor: bscExecutorAddress, + }, + }, + ])), + ...(await ethEndpointSdk.getUlnConfigParams(ethSendLibrary, [ + { + eid: bscPoint.eid, + ulnConfig: { + confirmations: BigInt(42), + requiredDVNs: ethToBscSendUlnDVNs, + optionalDVNs: ethToBscSendUlnDVNs, + optionalDVNThreshold: 1, + }, + }, + ])), + ]), + ]) + } + + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + const expectedTransactions = [ + await ethEndpointSdk.setConfig(ethPoint.address, ethSendLibrary, [ + ...(await ethEndpointSdk.getExecutorConfigParams(ethSendLibrary, [ + { + eid: avaxPoint.eid, + executorConfig: { + maxMessageSize: 99, + executor: avaxExecutorAddress, + }, + }, + ])), + ...(await ethEndpointSdk.getUlnConfigParams(ethSendLibrary, [ + { + eid: avaxPoint.eid, + ulnConfig: { + confirmations: BigInt(42), + requiredDVNs: ethToAvaxSendUlnDVNs, + optionalDVNs: ethToAvaxSendUlnDVNs, + optionalDVNThreshold: 1, + }, + }, + ])), + ]), + ] + expect(transactions).toEqual(expectedTransactions) + }) + }) + + describe('configureReceiveConfig', () => { + let graph: OAppOmniGraph, ethDvnAddress: string, ethReceiveUlnDVNs: string[], ethReceiveLibrary: string + beforeEach(async () => { + ethDvnAddress = await getLibraryAddress(ethDvn) + ethReceiveUlnDVNs = [ethDvnAddress] + ethReceiveLibrary = await getLibraryAddress(ethReceiveUln) + graph = { + contracts: [ + { + point: ethPoint, + }, + { + point: avaxPoint, + }, + { + point: bscPoint, + }, + ], + connections: [ + { + vector: { from: ethPoint, to: avaxPoint }, + config: { + receiveConfig: { + ulnConfig: { + confirmations: BigInt(42), + requiredDVNs: ethReceiveUlnDVNs, + optionalDVNs: ethReceiveUlnDVNs, + optionalDVNThreshold: 1, + }, + }, + }, + }, + { + vector: { from: ethPoint, to: bscPoint }, + config: { + receiveConfig: { + ulnConfig: { + confirmations: BigInt(24), + requiredDVNs: ethReceiveUlnDVNs, + optionalDVNs: ethReceiveUlnDVNs, + optionalDVNThreshold: 1, + }, + }, + }, + }, + { + vector: { from: avaxPoint, to: ethPoint }, + config: undefined, + }, + { + vector: { from: avaxPoint, to: bscPoint }, + config: undefined, + }, + { + vector: { from: bscPoint, to: ethPoint }, + config: undefined, + }, + { + vector: { from: bscPoint, to: avaxPoint }, + config: undefined, + }, + ], + } + }) + + it('should return all configureReceiveConfig transactions', async () => { + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + const expectedTransactions = [ + await ethEndpointSdk.setConfig(ethPoint.address, ethReceiveLibrary, [ + ...(await ethEndpointSdk.getUlnConfigParams(ethReceiveLibrary, [ + { + eid: avaxPoint.eid, + ulnConfig: { + confirmations: BigInt(42), + requiredDVNs: ethReceiveUlnDVNs, + optionalDVNs: ethReceiveUlnDVNs, + optionalDVNThreshold: 1, + }, + }, + ])), + ...(await ethEndpointSdk.getUlnConfigParams(ethReceiveLibrary, [ + { + eid: bscPoint.eid, + ulnConfig: { + confirmations: BigInt(24), + requiredDVNs: ethReceiveUlnDVNs, + optionalDVNs: ethReceiveUlnDVNs, + optionalDVNThreshold: 1, + }, + }, + ])), + ]), + ] + expect(transactions).toEqual(expectedTransactions) + }) + + it('should return one configureReceiveConfig transactions', async () => { + { + await signAndSend([ + await ethEndpointSdk.setConfig(ethPoint.address, ethReceiveLibrary, [ + ...(await ethEndpointSdk.getUlnConfigParams(ethReceiveLibrary, [ + { + eid: avaxPoint.eid, + ulnConfig: { + confirmations: BigInt(42), + requiredDVNs: ethReceiveUlnDVNs, + optionalDVNs: ethReceiveUlnDVNs, + optionalDVNThreshold: 1, + }, + }, + ])), + ]), + ]) + } + + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + const expectedTransactions = [ + await ethEndpointSdk.setConfig(ethPoint.address, ethReceiveLibrary, [ + ...(await ethEndpointSdk.getUlnConfigParams(ethReceiveLibrary, [ + { + eid: bscPoint.eid, + ulnConfig: { + confirmations: BigInt(24), + requiredDVNs: ethReceiveUlnDVNs, + optionalDVNs: ethReceiveUlnDVNs, + optionalDVNThreshold: 1, + }, + }, + ])), + ]), + ] + expect(transactions).toEqual(expectedTransactions) + }) + }) }) - }) - describe('configureReceiveConfig', () => { - it('should return all setPeer transactions and configureReceiveConfig transactions', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) + describe('configureSendConfig and configureReceiveConfig', () => { + it('should return all setConfig transactions', async () => { + const avaxExecutorAddress = await getLibraryAddress(avaxExecutor) + const avaxDvnAddress = await getLibraryAddress(avaxDvn) + const ethSendUlnDVNs: string[] = [avaxDvnAddress] - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - const ethEndpointSdk = await ethOAppSdk.getEndpointSDK() + const ethDvnAddress = await getLibraryAddress(ethDvn) + const ethReceiveUlnDVNs: string[] = [ethDvnAddress] - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) + const ethSendLibrary = await getLibraryAddress(ethSendUln) + const ethReceiveLibrary = await getLibraryAddress(ethReceiveUln) - const ethDvnAddress = await getLibraryAddress(ethDvn) - const ethReceiveUlnDVNs: string[] = [ethDvnAddress] - - const ethReceiveLibrary = await getLibraryAddress(ethReceiveUln) - - // This is the OApp config that we want to use against our contracts - const graph: OAppOmniGraph = { - contracts: [ - { - point: ethPoint, - }, - { - point: avaxPoint, - }, - ], - connections: [ - { - vector: { from: ethPoint, to: avaxPoint }, - config: { - receiveConfig: { - ulnConfig: { - confirmations: 42, - requiredDVNs: ethReceiveUlnDVNs, - optionalDVNs: ethReceiveUlnDVNs, - optionalDVNThreshold: 0, - requiredDVNCount: ethReceiveUlnDVNs.length, - optionalDVNCount: ethReceiveUlnDVNs.length, + // This is the OApp config that we want to use against our contracts + const graph: OAppOmniGraph = { + contracts: [ + { + point: ethPoint, + }, + { + point: avaxPoint, + }, + ], + connections: [ + { + vector: { from: ethPoint, to: avaxPoint }, + config: { + sendConfig: { + executorConfig: { + maxMessageSize: 99, + executor: avaxExecutorAddress, + }, + ulnConfig: { + confirmations: BigInt(42), + requiredDVNs: ethSendUlnDVNs, + optionalDVNs: ethSendUlnDVNs, + optionalDVNThreshold: 1, + }, + }, + receiveConfig: { + ulnConfig: { + confirmations: BigInt(42), + requiredDVNs: ethReceiveUlnDVNs, + optionalDVNs: ethReceiveUlnDVNs, + optionalDVNThreshold: 1, + }, }, }, }, - }, - { - vector: { from: avaxPoint, to: ethPoint }, - config: undefined, - }, - ], - } - - // Now we configure the OApp - const transactions = await configureOApp(graph, oappSdkFactory) - - expect(transactions).toEqual([ - await ethOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), - await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address), - await ethEndpointSdk.setUlnConfig(ethPoint.address, ethReceiveLibrary, [ - { - eid: avaxPoint.eid, - ulnConfig: { - confirmations: 42, - requiredDVNs: ethReceiveUlnDVNs, - optionalDVNs: ethReceiveUlnDVNs, - optionalDVNThreshold: 0, - requiredDVNCount: ethReceiveUlnDVNs.length, - optionalDVNCount: ethReceiveUlnDVNs.length, + { + vector: { from: avaxPoint, to: ethPoint }, + config: undefined, }, - }, - ]), - ]) - }) - }) - - describe('configureSendConfig and configureReceiveConfig', () => { - it('should return all setPeer transactions and setConfig', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) - - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - const ethEndpointSdk = await ethOAppSdk.getEndpointSDK() - - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) - - const avaxExecutorAddress = await getLibraryAddress(avaxExecutor) - const avaxDvnAddress = await getLibraryAddress(avaxDvn) - const ethSendUlnDVNs: string[] = [avaxDvnAddress] - - const ethDvnAddress = await getLibraryAddress(ethDvn) - const ethReceiveUlnDVNs: string[] = [ethDvnAddress] - - const ethSendLibrary = await getLibraryAddress(ethSendUln) - const ethReceiveLibrary = await getLibraryAddress(ethReceiveUln) - - // This is the OApp config that we want to use against our contracts - const graph: OAppOmniGraph = { - contracts: [ - { - point: ethPoint, - }, - { - point: avaxPoint, - }, - ], - connections: [ - { - vector: { from: ethPoint, to: avaxPoint }, - config: { - sendConfig: { + ], + } + + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + expect(transactions).toEqual([ + await ethEndpointSdk.setConfig(ethPoint.address, ethSendLibrary, [ + ...(await ethEndpointSdk.getExecutorConfigParams(ethSendLibrary, [ + { + eid: avaxPoint.eid, executorConfig: { maxMessageSize: 99, executor: avaxExecutorAddress, }, + }, + ])), + ...(await ethEndpointSdk.getUlnConfigParams(ethSendLibrary, [ + { + eid: avaxPoint.eid, ulnConfig: { - confirmations: 42, + confirmations: BigInt(42), requiredDVNs: ethSendUlnDVNs, optionalDVNs: ethSendUlnDVNs, - optionalDVNThreshold: 0, - requiredDVNCount: ethSendUlnDVNs.length, - optionalDVNCount: ethSendUlnDVNs.length, + optionalDVNThreshold: 1, }, }, - receiveConfig: { + ])), + ]), + await ethEndpointSdk.setConfig(ethPoint.address, ethReceiveLibrary, [ + ...(await ethEndpointSdk.getUlnConfigParams(ethReceiveLibrary, [ + { + eid: avaxPoint.eid, ulnConfig: { - confirmations: 42, + confirmations: BigInt(42), requiredDVNs: ethReceiveUlnDVNs, optionalDVNs: ethReceiveUlnDVNs, - optionalDVNThreshold: 0, - requiredDVNCount: ethReceiveUlnDVNs.length, - optionalDVNCount: ethReceiveUlnDVNs.length, + optionalDVNThreshold: 1, }, }, - }, - }, - { - vector: { from: avaxPoint, to: ethPoint }, - config: undefined, - }, - ], - } + ])), + ]), + ]) + }) + }) - // Now we configure the OApp - const transactions = await configureOApp(graph, oappSdkFactory) - expect(transactions).toEqual([ - await ethOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), - await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address), - await ethEndpointSdk.setConfig(ethPoint.address, ethSendLibrary, [ - ...(await ethEndpointSdk.getExecutorConfigParams(ethSendLibrary, [ + describe('configureEnforcedOptions', () => { + it('should return empty transactions when enforcedOptions is empty', async () => { + // This is the OApp config that we want to use against our contracts + const graph: OAppOmniGraph = { + contracts: [ { - eid: avaxPoint.eid, - executorConfig: { - maxMessageSize: 99, - executor: avaxExecutorAddress, + point: ethPoint, + }, + { + point: avaxPoint, + }, + ], + connections: [ + { + vector: { from: ethPoint, to: avaxPoint }, + config: { + enforcedOptions: [], }, }, - ])), - ...(await ethEndpointSdk.getUlnConfigParams(ethSendLibrary, [ { - eid: avaxPoint.eid, - ulnConfig: { - confirmations: 42, - requiredDVNs: ethSendUlnDVNs, - optionalDVNs: ethSendUlnDVNs, - optionalDVNThreshold: 0, - requiredDVNCount: ethSendUlnDVNs.length, - optionalDVNCount: ethSendUlnDVNs.length, + vector: { from: avaxPoint, to: ethPoint }, + config: { + enforcedOptions: [], }, }, - ])), - ]), - await ethEndpointSdk.setUlnConfig(ethPoint.address, ethReceiveLibrary, [ - { - eid: avaxPoint.eid, - ulnConfig: { - confirmations: 42, - requiredDVNs: ethReceiveUlnDVNs, - optionalDVNs: ethReceiveUlnDVNs, - optionalDVNThreshold: 0, - requiredDVNCount: ethReceiveUlnDVNs.length, - optionalDVNCount: ethReceiveUlnDVNs.length, + ], + } + + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + + expect(transactions).toEqual([]) + }) + it('should return all setEnforcedOption transactions', async () => { + // This is the OApp config that we want to use against our contracts + const graph: OAppOmniGraph = { + contracts: [ + { + point: ethPoint, }, - }, - ]), - ]) - }) - }) - - describe('configureEnforcedOptions', () => { - it('should return only setPeer transaction when enforcedOptions is empty', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) - - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) - - // This is the OApp config that we want to use against our contracts - const graph: OAppOmniGraph = { - contracts: [ - { - point: ethPoint, - }, - { - point: avaxPoint, - }, - ], - connections: [ - { - vector: { from: ethPoint, to: avaxPoint }, - config: { - enforcedOptions: [], + { + point: avaxPoint, }, - }, - { - vector: { from: avaxPoint, to: ethPoint }, - config: { - enforcedOptions: [], + ], + connections: [ + { + vector: { from: ethPoint, to: avaxPoint }, + config: { + enforcedOptions: [ + { + msgType: 1, + options: '0x00030100110100000000000000000000000000030d40', + }, + ], + }, }, - }, - ], - } - - // Now we configure the OApp - const transactions = await configureOApp(graph, oappSdkFactory) - - expect(transactions).toEqual([ - await ethOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), - await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address), - ]) - }) - it('should return setPeer and setEnforcedOptions transaction when enforcedOptions are set', async () => { - const ethContract = await contractFactory(ethPointHardhat) - const avaxContract = await contractFactory(avaxPointHardhat) - - const ethPoint = omniContractToPoint(ethContract) - const ethOAppSdk = await oappSdkFactory(ethPoint) - - const avaxPoint = omniContractToPoint(avaxContract) - const avaxOAppSdk = await oappSdkFactory(avaxPoint) - - // This is the OApp config that we want to use against our contracts - const graph: OAppOmniGraph = { - contracts: [ - { - point: ethPoint, - }, - { - point: avaxPoint, - }, - ], - connections: [ - { - vector: { from: ethPoint, to: avaxPoint }, - config: { - enforcedOptions: [ - { - msgType: 1, - options: '0x00030100110100000000000000000000000000030d40', - }, - ], + { + vector: { from: avaxPoint, to: ethPoint }, + config: { + enforcedOptions: [ + { + msgType: 1, + gas: '200000', + value: '0', + }, + ], + }, }, - }, - { - vector: { from: avaxPoint, to: ethPoint }, - config: { - enforcedOptions: [ - { - msgType: 1, - gas: '200000', - value: '0', - }, - ], + ], + } + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + expect(transactions).toEqual([ + await ethOAppSdk.setEnforcedOptions([ + { + eid: avaxPoint.eid, + msgType: 1, + options: '0x00030100110100000000000000000000000000030d40', }, - }, - ], - } - // Now we configure the OApp - const transactions = await configureOApp(graph, oappSdkFactory) - expect(transactions).toEqual([ - await ethOAppSdk.setPeer(avaxPoint.eid, avaxPoint.address), - await avaxOAppSdk.setPeer(ethPoint.eid, ethPoint.address), - await ethOAppSdk.setEnforcedOptions([ - { - eid: avaxPoint.eid, - msgType: 1, - options: '0x00030100110100000000000000000000000000030d40', - }, - ]), - await avaxOAppSdk.setEnforcedOptions([ - { - eid: ethPoint.eid, - msgType: 1, - options: '0x00030100110100000000000000000000000000030d40', - }, - ]), - ]) + ]), + await avaxOAppSdk.setEnforcedOptions([ + { + eid: ethPoint.eid, + msgType: 1, + options: '0x00030100110100000000000000000000000000030d40', + }, + ]), + ]) + }) + it('should return one transactions when enforcedOptions', async () => { + // This is the OApp config that we want to use against our contracts + const graph: OAppOmniGraph = { + contracts: [ + { + point: ethPoint, + }, + { + point: avaxPoint, + }, + ], + connections: [ + { + vector: { from: ethPoint, to: avaxPoint }, + config: { + enforcedOptions: [ + { + msgType: 1, + options: '0x00030100110100000000000000000000000000030d40', + }, + ], + }, + }, + { + vector: { from: avaxPoint, to: ethPoint }, + config: { + enforcedOptions: [ + { + msgType: 1, + gas: '200000', + value: '0', + }, + ], + }, + }, + ], + } + + { + await signAndSend([ + await ethOAppSdk.setEnforcedOptions([ + { + eid: avaxPoint.eid, + msgType: 1, + options: '0x00030100110100000000000000000000000000030d40', + }, + ]), + ]) + } + + // Now we configure the OApp + const transactions = await configureOApp(graph, oappSdkFactory) + expect(transactions).toEqual([ + await avaxOAppSdk.setEnforcedOptions([ + { + eid: ethPoint.eid, + msgType: 1, + options: '0x00030100110100000000000000000000000000030d40', + }, + ]), + ]) + }) }) }) })