Relayer: Generic Relayer Guardian Changes for Merging into Main (#3041)

* gRelayer: surrounding files

* modification to get compilation

* restore devnet

* remove generic relayer docker

* remove wait for relayer engine

* keep build time 20

* sh -> bash

* sh -> bash

* Remove comment

* bash -> sh

* Revert "bash -> sh"

This reverts commit 5c37e92fa1.

* bash->sh

* gRelayer: ethereum folder changes for generic-relayer-merge

* add eth-devnet

* Adds .github because workflow needs to install forge

* sdk-ci-tests need to install forge

* don't wait for nonexistent relayer engine

* update package.json and package-lock.json

* Remove unnecessary types from package.json

* ts-node

* gRelayer: ethereum folder changes for generic-relayer-merge

* sdk-ci-tests need to install forge

* don't wait for nonexistent relayer engine

* update package.json and package-lock.json

* remove these changes

* Relayer: Natspec documentation in IWormholeRelayer (#3032)

* WIP

* Fixes

* Updated interfaces

* remove bash

* Forward uses same refund chain id and refund address (#3034)

* WIP

* Fixes

* Forward uses same refund chain id and refund address

* Updated interfaces

* Adds .github because workflow needs to install forge

* sdk-ci-tests need to install forge

* don't wait for nonexistent relayer engine

* SDK minus payload tests

* Rename sdk relayer folder and file

* modify index.ts

* modify path

* sdk-ci-tests need to install forge

* don't wait for nonexistent relayer engine

* Add three governance VAA actions for generic relayers

* demandOption and const

* Remove forge build warnings

* Add note to interface for resend

* Verify additional VAAs in SDK

* via-ir on unless in Tilt

* Correct IWormholeReceiver interface

* Wormhole message fee now part of quoteDeliveryPrice (#3043)

* Fix to PR 3043

* Remove compiler warning

* Remove files

* remove generic relayer docker

* Fix typo

* Relayer/address drew review (#3060)

* Fix typo in Create2Factory

* Add event for contract upgrades

* Prevent registering contract if it is already registered

* Prevent allowing unset chainId for default delivery provider governance VAA

* memory to calldata for external functions in WormholeRelayerSend

* continue memory to calldata for external functions

* Fix pricing in delivery provider

* Sanity check new default delivery provider isn't 0 address

* Don't save vaaKey as local variable

* cache the length of array rather than iterate every time for vaaKeys

* Replacing memory with calldata in few locations

* Remove stale file DeliveryProviderMessages

* Remove batch VAA sender script

* Remove batch VAA from WormholeSimulator

* Wait for a confirmation in deploy scripts

* remove unnecessary comments

* Fix Delivery Provider Pricing and add a test

* remove console logs

* Revert "continue memory to calldata for external functions"

This reverts commit f322afb6c0.

* Revert "memory to calldata for external functions in WormholeRelayerSend"

This reverts commit 42fcaad884.

* Revert "Don't save vaaKey as local variable"

This reverts commit a9172379c5.

* Revert "cache the length of array rather than iterate every time for vaaKeys"

This reverts commit d61380a9b0.

* Revert "Replacing memory with calldata in few locations"

This reverts commit 94e47b6e72.

* Revert "Fix typo in Create2Factory"

This reverts commit a9f7bdf461.

* Update contract addresses for via-ir

* Update register chain test to only do one registration

* Slight improvements to delivery provider implementation

* typed errors for delivery provider

* Update SDK to have via-ir devnet address

* Fix test

* enable VIA-IR in CI and not in Tilt

* Fix chain id

* get register chain test to work

* correct contract address for via ir

* update sdk consts for via ir address

* base 32 address

* merge

* -f to -r

* relay provider -> delivery provider

* fix await

* Readme changes
This commit is contained in:
derpy-duck 2023-06-14 10:27:00 -04:00 committed by GitHub
parent b07278c331
commit 3c0fecc3fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 846 additions and 444 deletions

View File

@ -240,6 +240,8 @@ Commands:
worm generate upgrade Generate contract upgrade VAA
worm generate attestation Generate a token attestation VAA
worm generate recover-chain-id Generate a recover chain ID VAA
worm generate Sets the default delivery provider
set-default-delivery-provider for the Wormhole Relayer contract
Options:
--help Show help [boolean]
@ -309,6 +311,8 @@ Commands:
worm info upgrade Generate contract upgrade VAA
worm info attestation Generate a token attestation VAA
worm info recover-chain-id Generate a recover chain ID VAA
worm info set-default-delivery-provider Sets the default delivery provider
for the Wormhole Relayer contract
worm info chain-id <chain> Print the wormhole chain ID integer
associated with the specified chain
name
@ -395,6 +399,8 @@ Commands:
worm near upgrade Generate contract upgrade VAA
worm near attestation Generate a token attestation VAA
worm near recover-chain-id Generate a recover chain ID VAA
worm near set-default-delivery-provider Sets the default delivery provider
for the Wormhole Relayer contract
worm near chain-id <chain> Print the wormhole chain ID integer
associated with the specified chain
name
@ -495,6 +501,8 @@ Commands:
worm parse <vaa> upgrade Generate contract upgrade VAA
worm parse <vaa> attestation Generate a token attestation VAA
worm parse <vaa> recover-chain-id Generate a recover chain ID VAA
worm parse <vaa> Sets the default delivery provider
set-default-delivery-provider for the Wormhole Relayer contract
worm parse <vaa> chain-id <chain> Print the wormhole chain ID integer
associated with the specified chain
name
@ -607,6 +615,8 @@ Commands:
attestation
worm recover <digest> <signature> Generate a recover chain ID VAA
recover-chain-id
worm recover <digest> <signature> Sets the default delivery provider
set-default-delivery-provider for the Wormhole Relayer contract
worm recover <digest> <signature> Print the wormhole chain ID integer
chain-id <chain> associated with the specified chain
name
@ -712,6 +722,8 @@ Commands:
worm submit <vaa> upgrade Generate contract upgrade VAA
worm submit <vaa> attestation Generate a token attestation VAA
worm submit <vaa> recover-chain-id Generate a recover chain ID VAA
worm submit <vaa> Sets the default delivery provider
set-default-delivery-provider for the Wormhole Relayer contract
worm submit <vaa> chain-id <chain> Print the wormhole chain ID integer
associated with the specified chain
name
@ -825,6 +837,8 @@ Commands:
worm sui upgrade Generate contract upgrade VAA
worm sui attestation Generate a token attestation VAA
worm sui recover-chain-id Generate a recover chain ID VAA
worm sui set-default-delivery-provider Sets the default delivery provider
for the Wormhole Relayer contract
worm sui chain-id <chain> Print the wormhole chain ID integer
associated with the specified chain
name
@ -959,6 +973,8 @@ Commands:
worm verify-vaa upgrade Generate contract upgrade VAA
worm verify-vaa attestation Generate a token attestation VAA
worm verify-vaa recover-chain-id Generate a recover chain ID VAA
worm verify-vaa Sets the default delivery provider
set-default-delivery-provider for the Wormhole Relayer contract
worm verify-vaa chain-id <chain> Print the wormhole chain ID integer
associated with the specified chain
name

View File

@ -119,6 +119,8 @@ export async function execute_algorand(
break;
}
case "WormholeRelayer":
throw Error("Wormhole Relayer not supported on Algorand");
default:
target_contract = impossible(payload);
}

View File

@ -229,6 +229,8 @@ export async function execute_aptos(
break;
}
case "WormholeRelayer":
throw Error("Wormhole Relayer not supported on Aptos");
default:
impossible(payload);
}

View File

@ -119,6 +119,8 @@ export const submit = async (
break;
}
case "WormholeRelayer":
throw Error("Wormhole Relayer not supported on Sei");
default:
target_contract = impossible(payload);
execute_msg = impossible(payload);

View File

@ -198,6 +198,8 @@ export const submit = async (
break;
}
case "WormholeRelayer":
throw Error("Wormhole Relayer not supported on Sui");
default:
impossible(payload);
}

View File

@ -194,7 +194,7 @@ export const builder = function (y: typeof yargs) {
"Start a local EVM validator",
(yargs) => yargs.option("validator-args", VALIDATOR_OPTIONS),
(argv) => {
const cmd = `cd ${homedir()} && npx ganache-cli -e 10000 --deterministic --time="1970-01-01T00:00:00+00:00"`;
const cmd = `cd ${homedir()} && npx ganache-cli --wallet.defaultBalance 10000 --wallet.deterministic --chain.time="1970-01-01T00:00:00+00:00"`;
runCommand(cmd, argv["validator-args"]);
}
)

View File

@ -23,6 +23,7 @@ import {
sign,
TokenBridgeAttestMeta,
VAA,
WormholeRelayerSetDefaultDeliveryProvider,
} from "../vaa";
function makeVAA(
@ -78,10 +79,11 @@ export const builder = function (y: typeof yargs) {
})
.option("module", {
alias: "m",
describe: "Module to upgrade",
choices: ["NFTBridge", "TokenBridge"],
describe: "Module to register",
choices: ["NFTBridge", "TokenBridge", "WormholeRelayer"],
demandOption: true,
} as const),
} as const)
,
(argv) => {
const module = argv["module"];
assertChain(argv.chain);
@ -122,7 +124,7 @@ export const builder = function (y: typeof yargs) {
.option("module", {
alias: "m",
describe: "Module to upgrade",
choices: ["Core", "NFTBridge", "TokenBridge"],
choices: ["Core", "NFTBridge", "TokenBridge", "WormholeRelayer"],
demandOption: true,
} as const),
(argv) => {
@ -221,7 +223,7 @@ export const builder = function (y: typeof yargs) {
yargs
.option("module", {
alias: "m",
describe: "Module to upgrade",
describe: "Module to recover",
choices: ["Core", "NFTBridge", "TokenBridge"],
demandOption: true,
} as const)
@ -254,6 +256,41 @@ export const builder = function (y: typeof yargs) {
console.log(serialiseVAA(vaa));
}
)
.command(
"set-default-delivery-provider",
"Sets the default delivery provider for the Wormhole Relayer contract",
(yargs) => {
return yargs
.option("chain", {
alias: "c",
describe: "Chain of Wormhole Relayer contract",
choices: Object.keys(CHAINS),
demandOption: true,
} as const)
.option("delivery-provider-address", {
alias: "p",
describe: "Address of the delivery provider contract",
type: "string",
demandOption: true,
})
},
(argv) => {
assertChain(argv.chain);
const payload: WormholeRelayerSetDefaultDeliveryProvider = {
module: "WormholeRelayer",
type: "SetDefaultDeliveryProvider",
chain: toChainId(argv["chain"]),
relayProviderAddress: parseAddress(argv["chain"], argv["delivery-provider-address"])
};
let v = makeVAA(
GOVERNANCE_CHAIN,
GOVERNANCE_EMITTER,
argv["guardian-secret"].split(","),
payload
);
console.log(serialiseVAA(v));
}
)
);
};
export const handler = () => {};

View File

@ -429,6 +429,36 @@ export async function execute_evm(
break;
}
case "WormholeRelayer":
// TODO: Try to get contract address from SDK if it is undefined
// Needs SDK to be published with Wormhole Relayer contract addresses
if (contract_address === undefined) {
throw Error(`Unknown Wormhole Relayer contract on ${network} for ${chain}`)
}
// let rb = ethers_contracts.WormholeRelayer__factory.connect(contract_address, signer)
switch (payload.type) {
case "ContractUpgrade":
console.log("Upgrading contract")
console.log("Error: The published NPM SDK doesn't have the typechain binding for WormholeRelayer yet")
//console.log("Hash: " + (await rb.submitContractUpgrade(vaa, overrides)).hash)
console.log("Don't forget to verify the new implementation! See ethereum/VERIFY.md for instructions")
break
case "RegisterChain":
console.log("Registering chain")
console.log("Error: The published NPM SDK doesn't have the typechain binding for WormholeRelayer yet")
//console.log("Hash: " + (await rb.registerWormholeRelayerContract(vaa, overrides)).hash)
break
case "SetDefaultDeliveryProvider":
console.log("Setting default relay provider")
console.log("Error: The published NPM SDK doesn't have the typechain binding for WormholeRelayer yet")
//console.log("Hash: " + (await rb.setDefaultDeliveryProvider(vaa, overrides)).hash)
break
default:
impossible(payload)
break
}
break
default:
impossible(payload);
}

View File

@ -136,6 +136,8 @@ export async function execute_injective(
break;
}
case "WormholeRelayer":
throw Error("Wormhole Relayer not supported on Injective");
default:
action = impossible(payload);
target_contract = impossible(payload);

View File

@ -99,6 +99,8 @@ export const execute_near = async (
break;
}
case "WormholeRelayer":
throw Error("Wormhole Relayer not supported on Near");
default:
impossible(payload);
}

View File

@ -185,6 +185,8 @@ export async function execute_solana(
break;
}
break;
case "WormholeRelayer":
throw Error("Wormhole Relayer not supported on Solana");
default:
ix = impossible(v.payload);
}

View File

@ -138,6 +138,8 @@ export async function execute_terra(
break;
}
case "WormholeRelayer":
throw Error("Wormhole Relayer not supported on Terra");
default:
target_contract = impossible(payload);
execute_msg = impossible(payload);

View File

@ -64,8 +64,10 @@ export type Payload =
| CoreContractUpgrade
| PortalContractUpgrade<"TokenBridge">
| PortalContractUpgrade<"NFTBridge">
| PortalContractUpgrade<"WormholeRelayer">
| PortalRegisterChain<"TokenBridge">
| PortalRegisterChain<"NFTBridge">
| PortalRegisterChain<"WormholeRelayer">
| TokenBridgeTransfer
| TokenBridgeTransferWithPayload
| TokenBridgeAttestMeta
@ -73,11 +75,13 @@ export type Payload =
| CoreContractRecoverChainId
| PortalContractRecoverChainId<"TokenBridge">
| PortalContractRecoverChainId<"NFTBridge">
| WormholeRelayerSetDefaultDeliveryProvider
export type ContractUpgrade =
CoreContractUpgrade
| PortalContractUpgrade<"TokenBridge">
| PortalContractUpgrade<"NFTBridge">
| PortalContractUpgrade<"WormholeRelayer">
export type RecoverChainId =
CoreContractRecoverChainId
@ -90,8 +94,10 @@ export function parse(buffer: Buffer): VAA<Payload | Other> {
.or(coreContractUpgradeParser)
.or(portalContractUpgradeParser("TokenBridge"))
.or(portalContractUpgradeParser("NFTBridge"))
.or(portalContractUpgradeParser("WormholeRelayer"))
.or(portalRegisterChainParser("TokenBridge"))
.or(portalRegisterChainParser("NFTBridge"))
.or(portalRegisterChainParser("WormholeRelayer"))
.or(tokenBridgeTransferParser())
.or(tokenBridgeTransferWithPayloadParser())
.or(tokenBridgeAttestMetaParser())
@ -99,6 +105,7 @@ export function parse(buffer: Buffer): VAA<Payload | Other> {
.or(coreContractRecoverChainId())
.or(portalContractRecoverChainId("TokenBridge"))
.or(portalContractRecoverChainId("NFTBridge"))
.or(wormholeRelayerSetDefaultDeliveryProvider())
let payload : Payload | Other | null = parser.parse(vaa.payload)
if (payload === null) {
payload = {type: "Other", hex: Buffer.from(vaa.payload).toString("hex"), ascii: Buffer.from(vaa.payload).toString('utf8')}
@ -255,6 +262,22 @@ function vaaBody(vaa: VAA<Payload | Other>) {
break
}
break
case "WormholeRelayer":
switch (payload.type) {
case "ContractUpgrade":
payload_str = serialisePortalContractUpgrade(payload)
break
case "RegisterChain":
payload_str = serialisePortalRegisterChain(payload)
break
case "SetDefaultDeliveryProvider":
payload_str = serialiseWormholeRelayerSetDefaultDeliveryProvider(payload)
break
default:
impossible(payload)
break
}
break
default:
impossible(payload)
break
@ -395,7 +418,7 @@ function serialiseCoreContractUpgrade(payload: CoreContractUpgrade): string {
return body.join("")
}
export interface PortalContractUpgrade<Module extends "NFTBridge" | "TokenBridge"> {
export interface PortalContractUpgrade<Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer"> {
module: Module
type: "ContractUpgrade"
chain: number
@ -403,7 +426,7 @@ export interface PortalContractUpgrade<Module extends "NFTBridge" | "TokenBridge
}
// Parse a portal contract upgrade payload
function portalContractUpgradeParser<Module extends "NFTBridge" | "TokenBridge">(module: Module): P<PortalContractUpgrade<Module>> {
function portalContractUpgradeParser<Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer">(module: Module): P<PortalContractUpgrade<Module>> {
return new P(new Parser()
.endianess("big")
.string("module", {
@ -428,7 +451,7 @@ function portalContractUpgradeParser<Module extends "NFTBridge" | "TokenBridge">
}))
}
function serialisePortalContractUpgrade<Module extends "NFTBridge" | "TokenBridge">(payload: PortalContractUpgrade<Module>): string {
function serialisePortalContractUpgrade<Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer">(payload: PortalContractUpgrade<Module>): string {
const body = [
encode("bytes32", encodeString(payload.module)),
encode("uint8", 2),
@ -441,7 +464,7 @@ function serialisePortalContractUpgrade<Module extends "NFTBridge" | "TokenBridg
////////////////////////////////////////////////////////////////////////////////
// Registrations
export interface PortalRegisterChain<Module extends "NFTBridge" | "TokenBridge"> {
export interface PortalRegisterChain<Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer"> {
module: Module
type: "RegisterChain"
chain: number
@ -450,7 +473,7 @@ export interface PortalRegisterChain<Module extends "NFTBridge" | "TokenBridge">
}
// Parse a portal chain registration payload
function portalRegisterChainParser<Module extends "NFTBridge" | "TokenBridge">(module: Module): P<PortalRegisterChain<Module>> {
function portalRegisterChainParser<Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer">(module: Module): P<PortalRegisterChain<Module>> {
return new P(new Parser()
.endianess("big")
.string("module", {
@ -477,7 +500,7 @@ function portalRegisterChainParser<Module extends "NFTBridge" | "TokenBridge">(m
)
}
function serialisePortalRegisterChain<Module extends "NFTBridge" | "TokenBridge">(payload: PortalRegisterChain<Module>): string {
function serialisePortalRegisterChain<Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer">(payload: PortalRegisterChain<Module>): string {
const body = [
encode("bytes32", encodeString(payload.module)),
encode("uint8", 1),
@ -534,7 +557,7 @@ function serialiseCoreContractRecoverChainId(payload: CoreContractRecoverChainId
return body.join("")
}
export interface PortalContractRecoverChainId<Module extends "NFTBridge" | "TokenBridge"> {
export interface PortalContractRecoverChainId<Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer"> {
module: Module
type: "RecoverChainId"
evmChainId: bigint
@ -542,7 +565,7 @@ export interface PortalContractRecoverChainId<Module extends "NFTBridge" | "Toke
}
// Parse a portal contract recoverChainId payload
function portalContractRecoverChainId<Module extends "NFTBridge" | "TokenBridge">(module: Module): P<PortalContractRecoverChainId<Module>> {
function portalContractRecoverChainId<Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer">(module: Module): P<PortalContractRecoverChainId<Module>> {
return new P(new Parser()
.endianess("big")
.string("module", {
@ -567,7 +590,7 @@ function portalContractRecoverChainId<Module extends "NFTBridge" | "TokenBridge"
}))
}
function serialisePortalContractRecoverChainId<Module extends "NFTBridge" | "TokenBridge">(payload: PortalContractRecoverChainId<Module>): string {
function serialisePortalContractRecoverChainId<Module extends "NFTBridge" | "TokenBridge" | "WormholeRelayer">(payload: PortalContractRecoverChainId<Module>): string {
const body = [
encode("bytes32", encodeString(payload.module)),
encode("uint8", 3),
@ -862,6 +885,51 @@ function serialiseNFTBridgeTransfer(payload: NFTBridgeTransfer): string {
return body.join("")
}
////////////////////////////////////////////////////////////////////////////////
// WormholeRelayer
export interface WormholeRelayerSetDefaultDeliveryProvider {
module: "WormholeRelayer"
type: "SetDefaultDeliveryProvider"
relayProviderAddress: string
chain: number
}
function wormholeRelayerSetDefaultDeliveryProvider(): P<WormholeRelayerSetDefaultDeliveryProvider> {
return new P(new Parser()
.endianess("big")
.string("module", {
length: 32,
encoding: "hex",
assert: Buffer.from("WormholeRelayer").toString("hex").padStart(64, "0"),
formatter: (_str: string) => "WormholeRelayer"
})
.uint8("type", {
assert: 3,
formatter: (_action) => "SetDefaultDeliveryProvider"
})
.uint16("chain")
.array("relayProviderAddress", {
type: "uint8",
lengthInBytes: 32,
formatter: (arr) => "0x" + Buffer.from(arr).toString("hex")
})
.string("end", {
greedy: true,
assert: str => str === ""
})
)
}
function serialiseWormholeRelayerSetDefaultDeliveryProvider(payload: WormholeRelayerSetDefaultDeliveryProvider): string {
const body = [
encode("bytes32", encodeString(payload.module)),
encode("uint8", 3),
encode("uint16", payload.chain),
encode("bytes32", hex(payload.relayProviderAddress)),
]
return body.join("")
}
// This function should be called after pattern matching on all possible options
// of an enum (union) type, so that typescript can derive that no other options
// are possible. If (from JavaScript land) an unsupported argument is passed

View File

@ -132,6 +132,8 @@ export async function execute_xpla(
break;
}
case "WormholeRelayer":
throw Error("Wormhole Relayer not supported on Xpla");
default:
target_contract = impossible(payload);
execute_msg = impossible(payload);

View File

@ -73,6 +73,9 @@ func init() {
AdminClientTokenBridgeUpgradeContractCmd.Flags().AddFlagSet(moduleFlagSet)
TemplateCmd.AddCommand(AdminClientTokenBridgeUpgradeContractCmd)
AdminClientWormholeRelayerSetDefaultDeliveryProviderCmd.Flags().AddFlagSet(governanceFlagSet)
TemplateCmd.AddCommand(AdminClientWormholeRelayerSetDefaultDeliveryProviderCmd)
circleIntegrationChainIDFlagSet := pflag.NewFlagSet("circle-integ", pflag.ExitOnError)
circleIntegrationChainID = circleIntegrationChainIDFlagSet.String("chain-id", "", "Target chain ID")
@ -195,6 +198,12 @@ var AdminClientIbcReceiverUpdateChannelChainCmd = &cobra.Command{
Run: runIbcReceiverUpdateChannelChainTemplate,
}
var AdminClientWormholeRelayerSetDefaultDeliveryProviderCmd = &cobra.Command{
Use: "wormhole-relayer-set-default-relay-provider",
Short: "Generate a 'set default relay provider' template for specified chain and address",
Run: runWormholeRelayerSetDefaultDeliveryProviderTemplate,
}
func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
// Use deterministic devnet addresses as examples in the template, such that this doubles as a test fixture.
guardians := make([]*nodev1.GuardianSetUpdate_Guardian, *setUpdateNumGuardians)
@ -616,6 +625,40 @@ func runIbcReceiverUpdateChannelChainTemplate(cmd *cobra.Command, args []string)
},
}
b, err := prototext.MarshalOptions{Multiline: true}.Marshal(m)
if err != nil {
panic(err)
}
fmt.Print(string(b))
}
func runWormholeRelayerSetDefaultDeliveryProviderTemplate(cmd *cobra.Command, args []string) {
address, err := parseAddress(*address)
if err != nil {
log.Fatal(err)
}
chainID, err := parseChainID(*chainID)
if err != nil {
log.Fatal(err)
}
m := &nodev1.InjectGovernanceVAARequest{
CurrentSetIndex: uint32(*templateGuardianIndex),
Messages: []*nodev1.GovernanceMessage{
{
Sequence: rand.Uint64(),
Nonce: rand.Uint32(),
Payload: &nodev1.GovernanceMessage_WormholeRelayerSetDefaultDeliveryProvider{
WormholeRelayerSetDefaultDeliveryProvider: &nodev1.WormholeRelayerSetDefaultDeliveryProvider{
ChainId: uint32(chainID),
NewDefaultDeliveryProviderAddress: address,
},
},
},
},
}
b, err := prototext.MarshalOptions{Multiline: true}.Marshal(m)
if err != nil {
panic(err)

View File

@ -413,6 +413,34 @@ func ibcReceiverUpdateChannelChain(
return v, nil
}
// wormholeRelayerSetDefaultDeliveryProvider converts a nodev1.WormholeRelayerSetDefaultDeliveryProvider message to its canonical VAA representation.
// Returns an error if the data is invalid.
func wormholeRelayerSetDefaultDeliveryProvider(req *nodev1.WormholeRelayerSetDefaultDeliveryProvider, timestamp time.Time, guardianSetIndex uint32, nonce uint32, sequence uint64) (*vaa.VAA, error) {
if req.ChainId > math.MaxUint16 {
return nil, errors.New("invalid target_chain_id")
}
b, err := hex.DecodeString(req.NewDefaultDeliveryProviderAddress)
if err != nil {
return nil, errors.New("invalid new default relay provider address (expected hex)")
}
if len(b) != 32 {
return nil, errors.New("invalid new default relay provider address (expected 32 bytes)")
}
NewDefaultDeliveryProviderAddress := vaa.Address{}
copy(NewDefaultDeliveryProviderAddress[:], b)
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyWormholeRelayerSetDefaultDeliveryProvider{
ChainID: vaa.ChainID(req.ChainId),
NewDefaultDeliveryProviderAddress: NewDefaultDeliveryProviderAddress,
}.Serialize())
return v, nil
}
func GovMsgToVaa(message *nodev1.GovernanceMessage, currentSetIndex uint32, timestamp time.Time) (*vaa.VAA, error) {
var (
v *vaa.VAA
@ -444,6 +472,8 @@ func GovMsgToVaa(message *nodev1.GovernanceMessage, currentSetIndex uint32, time
v, err = circleIntegrationUpgradeContractImplementation(payload.CircleIntegrationUpgradeContractImplementation, timestamp, currentSetIndex, message.Nonce, message.Sequence)
case *nodev1.GovernanceMessage_IbcReceiverUpdateChannelChain:
v, err = ibcReceiverUpdateChannelChain(payload.IbcReceiverUpdateChannelChain, timestamp, currentSetIndex, message.Nonce, message.Sequence)
case *nodev1.GovernanceMessage_WormholeRelayerSetDefaultDeliveryProvider:
v, err = wormholeRelayerSetDefaultDeliveryProvider(payload.WormholeRelayerSetDefaultDeliveryProvider, timestamp, currentSetIndex, message.Nonce, message.Sequence)
default:
panic(fmt.Sprintf("unsupported VAA type: %T", payload))
}

File diff suppressed because it is too large Load Diff

View File

@ -82,7 +82,7 @@ message GovernanceMessage {
GuardianSetUpdate guardian_set = 10;
ContractUpgrade contract_upgrade = 11;
// Token bridge and NFT module
// Token bridge, NFT module, and Wormhole Relayer module (for the first two)
BridgeRegisterChain bridge_register_chain = 12;
BridgeUpgradeContract bridge_contract_upgrade = 13;
@ -103,6 +103,8 @@ message GovernanceMessage {
// IBC Receiver Integration
IbcReceiverUpdateChannelChain ibc_receiver_update_channel_chain = 21;
// Wormhole Relayer module
WormholeRelayerSetDefaultDeliveryProvider wormhole_relayer_set_default_delivery_provider = 22;
}
}
@ -248,6 +250,14 @@ message IbcReceiverUpdateChannelChain {
uint32 chain_id = 3;
}
message WormholeRelayerSetDefaultDeliveryProvider {
// ID of the chain of the Wormhole Relayer contract where the default delivery provider should be updated (uint16).
uint32 chain_id = 1;
// Hex-encoded address (without leading 0x) of the new default delivery provider contract address.
string new_default_delivery_provider_address = 2;
}
message FindMissingMessagesRequest {
// Emitter chain ID to iterate.
uint32 emitter_chain = 1;

View File

@ -232,6 +232,12 @@ guardiand template token-bridge-upgrade-contract \\
echo "\
guardiand template token-bridge-upgrade-contract \\
--chain-id $chain --module \"NFTBridge\" \\
--new-address $address"
;;
wormhole_relayer)
echo "\
guardiand template token-bridge-upgrade-contract \\
--chain-id $chain --module \"WormholeRelayer\" \\
--new-address $address"
;;
*) echo "unknown module $module" >&2

View File

@ -36,7 +36,7 @@ Usage:
where:
-h show this help text
-m module (TokenBridge, NFTBridge)
-m module (TokenBridge, NFTBridge, WormholeRelayer)
-c chain name
-a emitter address (optional, derived by worm CLI by default)
-o multi-mode output directory
@ -122,6 +122,12 @@ guardiand template token-bridge-register-chain \\
echo "\
guardiand template token-bridge-register-chain \\
--chain-id $chain --module \"NFTBridge\" \\
--new-address $address"
;;
WormholeRelayer)
echo "\
guardiand template token-bridge-register-chain \\
--chain-id $chain --module \"WormholeRelayer\" \\
--new-address $address"
;;
*) echo "unknown module $module" >&2

View File

@ -32,6 +32,14 @@ var IbcReceiverModule = [32]byte{
}
var IbcReceiverModuleStr = string(IbcReceiverModule[:])
// WormholeRelayerModule is the identifier of the Wormhole Relayer module (which is used for governance messages).
// It is the hex representation of "WormholeRelayer" left padded with zeroes.
var WormholeRelayerModule = [32]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x57, 0x6f, 0x72, 0x6d, 0x68, 0x6f, 0x6c, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x72,
}
var WormholeRelayerModuleStr = string(WormholeRelayerModule[:])
type GovernanceAction uint8
var (
@ -63,6 +71,9 @@ var (
// Ibc Receiver governance actions
IbcReceiverActionUpdateChannelChain GovernanceAction = 1
// Wormhole relayer governance actions
WormholeRelayerSetDefaultDeliveryProvider GovernanceAction = 3
)
type (
@ -150,6 +161,12 @@ type (
ChannelId [64]byte
ChainId ChainID
}
// BodyWormholeRelayerSetDefaultDeliveryProvider is a governance message to set the default relay provider for the Wormhole Relayer.
BodyWormholeRelayerSetDefaultDeliveryProvider struct {
ChainID ChainID
NewDefaultDeliveryProviderAddress Address
}
)
func (b BodyContractUpgrade) Serialize() []byte {
@ -258,6 +275,12 @@ func (r BodyIbcReceiverUpdateChannelChain) Serialize() []byte {
return serializeBridgeGovernanceVaa(IbcReceiverModuleStr, IbcReceiverActionUpdateChannelChain, r.TargetChainId, payload.Bytes())
}
func (r BodyWormholeRelayerSetDefaultDeliveryProvider) Serialize() []byte {
payload := &bytes.Buffer{}
payload.Write(r.NewDefaultDeliveryProviderAddress[:])
return serializeBridgeGovernanceVaa(WormholeRelayerModuleStr, WormholeRelayerSetDefaultDeliveryProvider, r.ChainID, payload.Bytes())
}
func serializeBridgeGovernanceVaa(module string, actionId GovernanceAction, chainId ChainID, payload []byte) []byte {
buf := LeftPadBytes(module, 32)
// Write action ID

View File

@ -200,3 +200,12 @@ func FuzzLeftPadBytes(f *testing.F) {
assert.Equal(t, paddedPayload.Len(), length)
})
}
func TestBodyWormholeRelayerSetDefaultDeliveryProviderSerialize(t *testing.T) {
expected := "0000000000000000000000000000000000576f726d686f6c6552656c617965720300040000000000000000000000000000000000000000000000000000000000000004"
bodyWormholeRelayerSetDefaultDeliveryProvider := BodyWormholeRelayerSetDefaultDeliveryProvider{
ChainID: 4,
NewDefaultDeliveryProviderAddress: addr,
}
assert.Equal(t, expected, hex.EncodeToString(bodyWormholeRelayerSetDefaultDeliveryProvider.Serialize()))
}