Skip to content

Commit

Permalink
👷‍♂️🪛Adding Enforced Options Config (#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
sirarthurmoney authored Jan 10, 2024
1 parent 95cbdaa commit 12f1d2a
Show file tree
Hide file tree
Showing 10 changed files with 556 additions and 266 deletions.
2 changes: 2 additions & 0 deletions packages/ua-devtools-evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@layerzerolabs/devtools": "~0.0.2",
"@layerzerolabs/devtools-evm": "~0.0.2",
"@layerzerolabs/lz-definitions": "~2.0.7",
"@layerzerolabs/lz-utility-v2": "~2.0.7",
"@layerzerolabs/protocol-devtools": "~0.0.2",
"@layerzerolabs/protocol-devtools-evm": "~0.0.2",
"@layerzerolabs/test-devtools": "~0.0.2",
Expand All @@ -55,6 +56,7 @@
"peerDependencies": {
"@layerzerolabs/devtools-evm": "~0.0.2",
"@layerzerolabs/lz-definitions": "~2.0.7",
"@layerzerolabs/lz-utility-v2": "~2.0.7",
"@layerzerolabs/protocol-devtools": "~0.0.2",
"@layerzerolabs/protocol-devtools-evm": "~0.0.2",
"@layerzerolabs/ua-devtools": "~0.0.2",
Expand Down
35 changes: 34 additions & 1 deletion packages/ua-devtools-evm/src/oapp/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IOApp } from '@layerzerolabs/ua-devtools'
import type { IOApp, EnforcedOptions, OAppEnforcedOptionConfig } from '@layerzerolabs/ua-devtools'
import type { Bytes32, Address, OmniTransaction } from '@layerzerolabs/devtools'
import {
type OmniContract,
Expand All @@ -11,6 +11,7 @@ import {
import type { EndpointId } from '@layerzerolabs/lz-definitions'
import type { EndpointFactory, IEndpoint } from '@layerzerolabs/protocol-devtools'
import { OmniSDK } from '@layerzerolabs/devtools-evm'
import { ExecutorOptionType, Options } from '@layerzerolabs/lz-utility-v2'

export class OApp extends OmniSDK implements IOApp {
constructor(
Expand Down Expand Up @@ -55,4 +56,36 @@ export class OApp extends OmniSDK implements IOApp {
const data = this.contract.contract.interface.encodeFunctionData('setPeer', [eid, makeBytes32(address)])
return this.createTransaction(data)
}

async getEnforcedOptions(eid: EndpointId, msgType: number): Promise<string> {
return await this.contract.contract.enforcedOptions(eid, msgType)
}

async setEnforcedOptions(enforcedOptions: EnforcedOptions[]): Promise<OmniTransaction> {
const data = this.contract.contract.interface.encodeFunctionData('setEnforcedOptions', [enforcedOptions])
return this.createTransaction(data)
}

encodeEnforcedOptions(enforcedOptionConfig: OAppEnforcedOptionConfig): Options {
if ('options' in enforcedOptionConfig) return Options.fromOptions(enforcedOptionConfig.options)

if (enforcedOptionConfig.msgType == ExecutorOptionType.LZ_RECEIVE) {
return Options.newOptions().addExecutorLzReceiveOption(enforcedOptionConfig.gas, enforcedOptionConfig.value)
} else if (enforcedOptionConfig.msgType == ExecutorOptionType.NATIVE_DROP) {
return Options.newOptions().addExecutorNativeDropOption(
enforcedOptionConfig.amount,
enforcedOptionConfig.receiver
)
} else if (enforcedOptionConfig.msgType == ExecutorOptionType.COMPOSE) {
return Options.newOptions().addExecutorComposeOption(
enforcedOptionConfig.index,
enforcedOptionConfig.gas,
enforcedOptionConfig.value
)
} else if (enforcedOptionConfig.msgType == ExecutorOptionType.ORDERED) {
return Options.newOptions().addExecutorOrderedExecutionOption()
} else {
throw new Error(`Invalid ExecutorOptionType`)
}
}
}
2 changes: 2 additions & 0 deletions packages/ua-devtools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@layerzerolabs/devtools": "~0.0.2",
"@layerzerolabs/io-devtools": "~0.0.2",
"@layerzerolabs/lz-definitions": "~2.0.7",
"@layerzerolabs/lz-utility-v2": "~2.0.7",
"@layerzerolabs/protocol-devtools": "~0.0.2",
"@layerzerolabs/test-devtools": "~0.0.2",
"@types/jest": "^29.5.11",
Expand All @@ -49,6 +50,7 @@
"@layerzerolabs/devtools": "~0.0.2",
"@layerzerolabs/io-devtools": "~0.0.2",
"@layerzerolabs/lz-definitions": "~2.0.7",
"@layerzerolabs/lz-utility-v2": "~2.0.7",
"@layerzerolabs/protocol-devtools": "~0.0.2",
"zod": "^3.22.4"
},
Expand Down
37 changes: 36 additions & 1 deletion packages/ua-devtools/src/oapp/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { flattenTransactions, type OmniTransaction } from '@layerzerolabs/devtools'
import { OAppFactory, OAppOmniGraph } from './types'
import { EnforcedOptions, OAppEnforcedOptionConfig, OAppFactory, OAppOmniGraph } from './types'
import { createModuleLogger, printBoolean } from '@layerzerolabs/io-devtools'
import { formatOmniVector, isDeepEqual } from '@layerzerolabs/devtools'
import { Uln302ExecutorConfig, Uln302UlnConfig } from '@layerzerolabs/protocol-devtools'
Expand All @@ -15,6 +15,7 @@ export const configureOApp: OAppConfigurator = async (graph: OAppOmniGraph, crea
await configureReceiveLibraryTimeouts(graph, createSdk),
await configureSendConfig(graph, createSdk),
await configureReceiveConfig(graph, createSdk),
await configureEnforcedOptions(graph, createSdk),
])

export const configureOAppPeers: OAppConfigurator = async (graph, createSdk) => {
Expand Down Expand Up @@ -186,3 +187,37 @@ export const configureReceiveConfig: OAppConfigurator = async (graph, createSdk)
})
)
)

export const configureEnforcedOptions: OAppConfigurator = async (graph, createSdk) =>
flattenTransactions(
await Promise.all(
graph.connections.map(async ({ vector: { from, to }, config }): Promise<OmniTransaction[]> => {
const transactions: OmniTransaction[] = []

if (config?.enforcedOptions) {
const enforcedOptions: EnforcedOptions[] = []
const enforcedOptionsConfig: OAppEnforcedOptionConfig[] = config.enforcedOptions
const oappSdk = await createSdk(from)
for (const enforcedOption of enforcedOptionsConfig) {
const currentEnforcedOption = await oappSdk.getEnforcedOptions(to.eid, enforcedOption.msgType)
const encodedEnforcedOption = oappSdk
.encodeEnforcedOptions(enforcedOption)
.toHex()
.toLowerCase()
if (currentEnforcedOption !== encodedEnforcedOption) {
enforcedOptions.push({
eid: to.eid,
msgType: enforcedOption.msgType,
options: encodedEnforcedOption,
})
}
}
if (enforcedOptions.length) {
transactions.push(await oappSdk.setEnforcedOptions(enforcedOptions))
}
}

return transactions
})
)
)
16 changes: 15 additions & 1 deletion packages/ua-devtools/src/oapp/schema.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { z } from 'zod'
import { AddressSchema, UIntSchema } from '@layerzerolabs/devtools'
import { Uln302ExecutorConfigSchema, Uln302UlnConfigSchema, TimeoutSchema } from '@layerzerolabs/protocol-devtools'
import type { OAppEdgeConfig, OAppReceiveConfig, OAppReceiveLibraryConfig, OAppSendConfig } from './types'
import {
OAppEdgeConfig,
OAppEnforcedOptionConfig,
OAppReceiveConfig,
OAppReceiveLibraryConfig,
OAppSendConfig,
} from './types'

export const OAppReceiveLibraryConfigSchema = z.object({
gracePeriod: UIntSchema,
Expand All @@ -17,10 +23,18 @@ export const OAppReceiveConfigSchema = z.object({
ulnConfig: Uln302UlnConfigSchema,
}) satisfies z.ZodSchema<OAppReceiveConfig, z.ZodTypeDef, unknown>

export const OAppEnforcedOptionsSchema = z.array(
z.object({
msgType: z.number(),
options: z.string(),
})
) satisfies z.ZodSchema<OAppEnforcedOptionConfig[], z.ZodTypeDef, unknown>

export const OAppEdgeConfigSchema = z.object({
sendLibrary: AddressSchema.optional(),
receiveLibraryConfig: OAppReceiveLibraryConfigSchema.optional(),
receiveLibraryTimeoutConfig: TimeoutSchema.optional(),
sendConfig: OAppSendConfigSchema.optional(),
receiveConfig: OAppReceiveConfigSchema.optional(),
enforcedOptions: OAppEnforcedOptionsSchema.optional(),
}) satisfies z.ZodSchema<OAppEdgeConfig, z.ZodTypeDef, unknown>
52 changes: 50 additions & 2 deletions packages/ua-devtools/src/oapp/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { EndpointId } from '@layerzerolabs/lz-definitions'
import type { IEndpoint, Timeout } from '@layerzerolabs/protocol-devtools'
import type { IEndpoint, Timeout, Uln302ExecutorConfig, Uln302UlnConfig } from '@layerzerolabs/protocol-devtools'
import type {
Address,
Bytes32,
Expand All @@ -10,13 +10,22 @@ import type {
OmniTransaction,
OmniVector,
} from '@layerzerolabs/devtools'
import type { Uln302ExecutorConfig, Uln302UlnConfig } from '@layerzerolabs/protocol-devtools'
import { ExecutorOptionType, Options } from '@layerzerolabs/lz-utility-v2'

export interface IOApp extends IOmniSDK {
getEndpointSDK(): Promise<IEndpoint>
getPeer(eid: EndpointId): Promise<Bytes32 | undefined>
hasPeer(eid: EndpointId, address: Bytes32 | Address | null | undefined): Promise<boolean>
setPeer(eid: EndpointId, peer: Bytes32 | Address | null | undefined): Promise<OmniTransaction>
getEnforcedOptions(eid: EndpointId, msgType: number): Promise<string>
setEnforcedOptions(enforcedOptions: EnforcedOptions[]): Promise<OmniTransaction>
encodeEnforcedOptions(enforcedOptionConfig: OAppEnforcedOptionConfig): Options
}

export type EnforcedOptions = {
eid: EndpointId
msgType: number
options: string
}

export interface OAppReceiveLibraryConfig {
Expand All @@ -39,8 +48,47 @@ export interface OAppEdgeConfig {
receiveLibraryTimeoutConfig?: Timeout
sendConfig?: OAppSendConfig
receiveConfig?: OAppReceiveConfig
enforcedOptions?: OAppEnforcedOptionConfig[]
}

interface BaseExecutorOption {
msgType: ExecutorOptionType
}

interface EndcodedOption extends BaseExecutorOption {
options: string
}

interface ExecutorLzReceiveOption extends BaseExecutorOption {
msgType: ExecutorOptionType.LZ_RECEIVE
gas: string | number
value: string | number
}

interface ExecutorNativeDropOption extends BaseExecutorOption {
msgType: ExecutorOptionType.NATIVE_DROP
amount: string | number
receiver: string
}

interface ExecutorComposeOption extends BaseExecutorOption {
msgType: ExecutorOptionType.COMPOSE
index: number
gas: string | number
value: string | number
}

interface ExecutorOrderedExecutionOption extends BaseExecutorOption {
msgType: ExecutorOptionType.ORDERED
}

export type OAppEnforcedOptionConfig =
| ExecutorLzReceiveOption
| ExecutorNativeDropOption
| ExecutorComposeOption
| ExecutorOrderedExecutionOption
| EndcodedOption

export interface OAppPeers {
vector: OmniVector
hasPeer: boolean
Expand Down
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion tests/ua-devtools-evm-hardhat-test/contracts/DefaultOApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
pragma solidity ^0.8.22;

import { OApp, Origin } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/OApp.sol";
import { OAppOptionsType3 } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/libs/OAppOptionsType3.sol";

contract DefaultOApp is OApp {
contract DefaultOApp is OApp, OAppOptionsType3 {
constructor(address _endpoint, address _owner) OApp(_endpoint, _owner) {}

function _lzReceive(Origin calldata, bytes32, bytes calldata, address, bytes calldata) internal virtual override {}
Expand Down
2 changes: 1 addition & 1 deletion tests/ua-devtools-evm-hardhat-test/test/__utils__/oapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export const getDefaultAvaxConfig = async (): Promise<OAppTestConfig> => {
}
}

const getLibraryAddress = async (library: OmniPointHardhat): Promise<string> => {
export const getLibraryAddress = async (library: OmniPointHardhat): Promise<string> => {
const contractFactory = createConnectedContractFactory()
const { contract } = await contractFactory(library)
return contract.address
Expand Down
Loading

0 comments on commit 12f1d2a

Please sign in to comment.