Node: Adminserver commands should not panic

This commit is contained in:
Bruce Riley 2024-04-23 17:13:12 -05:00
parent 9620fca895
commit 5a0296f34e
5 changed files with 385 additions and 148 deletions

View File

@ -174,13 +174,17 @@ func tokenBridgeRegisterChain(req *nodev1.BridgeRegisterChain, timestamp time.Ti
emitterAddress := vaa.Address{}
copy(emitterAddress[:], b)
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyTokenBridgeRegisterChain{
Module: req.Module,
ChainID: vaa.ChainID(req.ChainId),
EmitterAddress: emitterAddress,
}.Serialize())
body, err := vaa.BodyTokenBridgeRegisterChain{
Module: req.Module,
ChainID: vaa.ChainID(req.ChainId),
EmitterAddress: emitterAddress,
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -203,13 +207,17 @@ func recoverChainId(req *nodev1.RecoverChainId, timestamp time.Time, guardianSet
return nil, errors.New("invalid new_chain_id")
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyRecoverChainId{
Module: req.Module,
EvmChainID: evm_chain_id,
NewChainID: vaa.ChainID(req.NewChainId),
}.Serialize())
body, err := vaa.BodyRecoverChainId{
Module: req.Module,
EvmChainID: evm_chain_id,
NewChainID: vaa.ChainID(req.NewChainId),
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -254,20 +262,24 @@ func accountantModifyBalance(req *nodev1.AccountantModifyBalance, timestamp time
tokenAdress := vaa.Address{}
copy(tokenAdress[:], b)
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyAccountantModifyBalance{
Module: req.Module,
TargetChainID: vaa.ChainID(req.TargetChainId),
body, err := vaa.BodyAccountantModifyBalance{
Module: req.Module,
TargetChainID: vaa.ChainID(req.TargetChainId),
Sequence: req.Sequence,
ChainId: vaa.ChainID(req.ChainId),
TokenChain: vaa.ChainID(req.TokenChain),
TokenAddress: tokenAdress,
Kind: uint8(req.Kind),
Amount: amount,
Reason: req.Reason,
}.Serialize())
Sequence: req.Sequence,
ChainId: vaa.ChainID(req.ChainId),
TokenChain: vaa.ChainID(req.TokenChain),
TokenAddress: tokenAdress,
Kind: uint8(req.Kind),
Amount: amount,
Reason: req.Reason,
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -290,13 +302,17 @@ func tokenBridgeUpgradeContract(req *nodev1.BridgeUpgradeContract, timestamp tim
newContract := vaa.Address{}
copy(newContract[:], b)
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyTokenBridgeUpgradeContract{
Module: req.Module,
TargetChainID: vaa.ChainID(req.TargetChainId),
NewContract: newContract,
}.Serialize())
body, err := vaa.BodyTokenBridgeUpgradeContract{
Module: req.Module,
TargetChainID: vaa.ChainID(req.TargetChainId),
NewContract: newContract,
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -316,11 +332,15 @@ func wormchainStoreCode(req *nodev1.WormchainStoreCode, timestamp time.Time, gua
wasmHash := [32]byte{}
copy(wasmHash[:], b)
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyWormchainStoreCode{
WasmHash: wasmHash,
}.Serialize())
body, err := vaa.BodyWormchainStoreCode{
WasmHash: wasmHash,
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -329,11 +349,15 @@ func wormchainStoreCode(req *nodev1.WormchainStoreCode, timestamp time.Time, gua
func wormchainInstantiateContract(req *nodev1.WormchainInstantiateContract, timestamp time.Time, guardianSetIndex uint32, nonce uint32, sequence uint64) (*vaa.VAA, error) { //nolint:unparam // error is always nil but kept to mirror function signature of other functions
instantiationParams_hash := vaa.CreateInstatiateCosmwasmContractHash(req.CodeId, req.Label, []byte(req.InstantiationMsg))
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyWormchainInstantiateContract{
InstantiationParamsHash: instantiationParams_hash,
}.Serialize())
body, err := vaa.BodyWormchainInstantiateContract{
InstantiationParamsHash: instantiationParams_hash,
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -341,11 +365,15 @@ func wormchainInstantiateContract(req *nodev1.WormchainInstantiateContract, time
func wormchainMigrateContract(req *nodev1.WormchainMigrateContract, timestamp time.Time, guardianSetIndex uint32, nonce uint32, sequence uint64) (*vaa.VAA, error) { //nolint:unparam // error is always nil but kept to mirror function signature of other functions
instantiationParams_hash := vaa.CreateMigrateCosmwasmContractHash(req.CodeId, req.Contract, []byte(req.InstantiationMsg))
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyWormchainMigrateContract{
MigrationParamsHash: instantiationParams_hash,
}.Serialize())
body, err := vaa.BodyWormchainMigrateContract{
MigrationParamsHash: instantiationParams_hash,
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -373,11 +401,16 @@ func wormchainWasmInstantiateAllowlist(
var decodedAddr32 [32]byte
copy(decodedAddr32[:], decodedAddr)
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, vaa.BodyWormchainWasmAllowlistInstantiate{
body, err := vaa.BodyWormchainWasmAllowlistInstantiate{
ContractAddr: decodedAddr32,
CodeId: req.CodeId,
}.Serialize(action))
}.Serialize(action)
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -388,11 +421,17 @@ func gatewayScheduleUpgrade(
nonce uint32,
sequence uint64,
) (*vaa.VAA, error) { //nolint:unparam // error is always nil but kept to mirror function signature of other functions
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, vaa.BodyGatewayScheduleUpgrade{
body, err := vaa.BodyGatewayScheduleUpgrade{
Name: req.Name,
Height: req.Height,
}.Serialize())
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -402,10 +441,14 @@ func gatewayCancelUpgrade(
nonce uint32,
sequence uint64,
) (*vaa.VAA, error) { //nolint:unparam // error is always nil but kept to mirror function signature of other functions
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.EmptyPayloadVaa(vaa.GatewayModuleStr, vaa.ActionCancelUpgrade, vaa.ChainIDWormchain),
)
body, err := vaa.EmptyPayloadVaa(vaa.GatewayModuleStr, vaa.ActionCancelUpgrade, vaa.ChainIDWormchain)
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -424,10 +467,15 @@ func gatewayIbcComposabilityMwSetContract(
var decodedAddr32 [32]byte
copy(decodedAddr32[:], decodedAddr)
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, vaa.BodyGatewayIbcComposabilityMwContract{
body, err := vaa.BodyGatewayIbcComposabilityMwContract{
ContractAddr: decodedAddr32,
}.Serialize())
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -440,12 +488,17 @@ func circleIntegrationUpdateWormholeFinality(req *nodev1.CircleIntegrationUpdate
if req.Finality > math.MaxUint8 {
return nil, fmt.Errorf("invalid finality, must be <= %d", math.MaxUint8)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyCircleIntegrationUpdateWormholeFinality{
TargetChainID: vaa.ChainID(req.TargetChainId),
Finality: uint8(req.Finality),
}.Serialize())
body, err := vaa.BodyCircleIntegrationUpdateWormholeFinality{
TargetChainID: vaa.ChainID(req.TargetChainId),
Finality: uint8(req.Finality),
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -470,14 +523,18 @@ func circleIntegrationRegisterEmitterAndDomain(req *nodev1.CircleIntegrationRegi
foreignEmitterAddress := vaa.Address{}
copy(foreignEmitterAddress[:], b)
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyCircleIntegrationRegisterEmitterAndDomain{
TargetChainID: vaa.ChainID(req.TargetChainId),
ForeignEmitterChainId: vaa.ChainID(req.ForeignEmitterChainId),
ForeignEmitterAddress: foreignEmitterAddress,
CircleDomain: req.CircleDomain,
}.Serialize())
body, err := vaa.BodyCircleIntegrationRegisterEmitterAndDomain{
TargetChainID: vaa.ChainID(req.TargetChainId),
ForeignEmitterChainId: vaa.ChainID(req.ForeignEmitterChainId),
ForeignEmitterAddress: foreignEmitterAddress,
CircleDomain: req.CircleDomain,
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -499,12 +556,16 @@ func circleIntegrationUpgradeContractImplementation(req *nodev1.CircleIntegratio
newImplementationAddress := vaa.Address{}
copy(newImplementationAddress[:], b)
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyCircleIntegrationUpgradeContractImplementation{
TargetChainID: vaa.ChainID(req.TargetChainId),
NewImplementationAddress: newImplementationAddress,
}.Serialize())
body, err := vaa.BodyCircleIntegrationUpgradeContractImplementation{
TargetChainID: vaa.ChainID(req.TargetChainId),
NewImplementationAddress: newImplementationAddress,
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -527,7 +588,10 @@ func ibcUpdateChannelChain(
if len(req.ChannelId) > 64 {
return nil, fmt.Errorf("invalid channel ID length, must be <= 64")
}
channelId := vaa.LeftPadIbcChannelId(req.ChannelId)
channelId, err := vaa.LeftPadIbcChannelId(req.ChannelId)
if err != nil {
return nil, fmt.Errorf("failed to left pad channel id: %w", err)
}
var module string
if req.Module == nodev1.IbcUpdateChannelChainModule_IBC_UPDATE_CHANNEL_CHAIN_MODULE_RECEIVER {
@ -538,14 +602,17 @@ func ibcUpdateChannelChain(
return nil, fmt.Errorf("unrecognized ibc update channel chain module")
}
// create governance VAA
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyIbcUpdateChannelChain{
TargetChainId: vaa.ChainID(req.TargetChainId),
ChannelId: channelId,
ChainId: vaa.ChainID(req.ChainId),
}.Serialize(module))
body, err := vaa.BodyIbcUpdateChannelChain{
TargetChainId: vaa.ChainID(req.TargetChainId),
ChannelId: channelId,
ChainId: vaa.ChainID(req.ChainId),
}.Serialize(module)
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -568,12 +635,16 @@ func wormholeRelayerSetDefaultDeliveryProvider(req *nodev1.WormholeRelayerSetDef
NewDefaultDeliveryProviderAddress := vaa.Address{}
copy(NewDefaultDeliveryProviderAddress[:], b)
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyWormholeRelayerSetDefaultDeliveryProvider{
ChainID: vaa.ChainID(req.ChainId),
NewDefaultDeliveryProviderAddress: NewDefaultDeliveryProviderAddress,
}.Serialize())
body, err := vaa.BodyWormholeRelayerSetDefaultDeliveryProvider{
ChainID: vaa.ChainID(req.ChainId),
NewDefaultDeliveryProviderAddress: NewDefaultDeliveryProviderAddress,
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -598,7 +669,6 @@ func evmCallToVaa(evmCall *nodev1.EvmCall, timestamp time.Time, guardianSetIndex
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -619,13 +689,17 @@ func solanaCallToVaa(solanaCall *nodev1.SolanaCall, timestamp time.Time, guardia
return nil, fmt.Errorf("failed to decode instruction: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyGeneralPurposeGovernanceSolana{
ChainID: vaa.ChainID(solanaCall.ChainId),
GovernanceContract: governanceContract,
Instruction: instruction,
}.Serialize())
body, err := vaa.BodyGeneralPurposeGovernanceSolana{
ChainID: vaa.ChainID(solanaCall.ChainId),
GovernanceContract: governanceContract,
Instruction: instruction,
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
@ -677,7 +751,7 @@ func GovMsgToVaa(message *nodev1.GovernanceMessage, currentSetIndex uint32, time
case *nodev1.GovernanceMessage_SolanaCall:
v, err = solanaCallToVaa(payload.SolanaCall, timestamp, currentSetIndex, message.Nonce, message.Sequence)
default:
panic(fmt.Sprintf("unsupported VAA type: %T", payload))
err = fmt.Errorf("unsupported VAA type: %T", payload)
}
return v, err

View File

@ -3,6 +3,7 @@ package vaa
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"math"
@ -282,7 +283,7 @@ func (b BodyGuardianSetUpdate) Serialize() []byte {
return buf.Bytes()
}
func (r BodyTokenBridgeRegisterChain) Serialize() []byte {
func (r BodyTokenBridgeRegisterChain) Serialize() ([]byte, error) {
payload := &bytes.Buffer{}
MustWrite(payload, binary.BigEndian, r.ChainID)
payload.Write(r.EmitterAddress[:])
@ -290,13 +291,16 @@ func (r BodyTokenBridgeRegisterChain) Serialize() []byte {
return serializeBridgeGovernanceVaa(r.Module, ActionRegisterChain, 0, payload.Bytes())
}
func (r BodyTokenBridgeUpgradeContract) Serialize() []byte {
func (r BodyTokenBridgeUpgradeContract) Serialize() ([]byte, error) {
return serializeBridgeGovernanceVaa(r.Module, ActionUpgradeTokenBridge, r.TargetChainID, r.NewContract[:])
}
func (r BodyRecoverChainId) Serialize() []byte {
func (r BodyRecoverChainId) Serialize() ([]byte, error) {
// Module
buf := LeftPadBytes(r.Module, 32)
buf, err := LeftPadBytes(r.Module, 32)
if err != nil {
return nil, fmt.Errorf("failed to left pad module: %w", err)
}
// Action
var action GovernanceAction
if r.Module == "Core" {
@ -309,10 +313,10 @@ func (r BodyRecoverChainId) Serialize() []byte {
MustWrite(buf, binary.BigEndian, r.EvmChainID.Bytes32())
// NewChainID
MustWrite(buf, binary.BigEndian, r.NewChainID)
return buf.Bytes()
return buf.Bytes(), nil
}
func (r BodyAccountantModifyBalance) Serialize() []byte {
func (r BodyAccountantModifyBalance) Serialize() ([]byte, error) {
payload := &bytes.Buffer{}
MustWrite(payload, binary.BigEndian, r.Sequence)
MustWrite(payload, binary.BigEndian, r.ChainId)
@ -335,28 +339,28 @@ func (r BodyAccountantModifyBalance) Serialize() []byte {
return serializeBridgeGovernanceVaa(r.Module, ActionModifyBalance, r.TargetChainID, payload.Bytes())
}
func (r BodyWormchainStoreCode) Serialize() []byte {
func (r BodyWormchainStoreCode) Serialize() ([]byte, error) {
return serializeBridgeGovernanceVaa(WasmdModuleStr, ActionStoreCode, ChainIDWormchain, r.WasmHash[:])
}
func (r BodyWormchainInstantiateContract) Serialize() []byte {
func (r BodyWormchainInstantiateContract) Serialize() ([]byte, error) {
return serializeBridgeGovernanceVaa(WasmdModuleStr, ActionInstantiateContract, ChainIDWormchain, r.InstantiationParamsHash[:])
}
func (r BodyWormchainMigrateContract) Serialize() []byte {
func (r BodyWormchainMigrateContract) Serialize() ([]byte, error) {
return serializeBridgeGovernanceVaa(WasmdModuleStr, ActionMigrateContract, ChainIDWormchain, r.MigrationParamsHash[:])
}
func (r BodyWormchainWasmAllowlistInstantiate) Serialize(action GovernanceAction) []byte {
func (r BodyWormchainWasmAllowlistInstantiate) Serialize(action GovernanceAction) ([]byte, error) {
payload := &bytes.Buffer{}
payload.Write(r.ContractAddr[:])
MustWrite(payload, binary.BigEndian, r.CodeId)
return serializeBridgeGovernanceVaa(WasmdModuleStr, action, ChainIDWormchain, payload.Bytes())
}
func (r *BodyWormchainWasmAllowlistInstantiate) Deserialize(bz []byte) {
func (r *BodyWormchainWasmAllowlistInstantiate) Deserialize(bz []byte) error {
if len(bz) != 40 {
panic("incorrect payload length")
return fmt.Errorf("incorrect payload length, should be 40, is %d", len(bz))
}
var contractAddr [32]byte
@ -366,26 +370,28 @@ func (r *BodyWormchainWasmAllowlistInstantiate) Deserialize(bz []byte) {
r.ContractAddr = contractAddr
r.CodeId = codeId
return nil
}
func (r BodyGatewayIbcComposabilityMwContract) Serialize() []byte {
func (r BodyGatewayIbcComposabilityMwContract) Serialize() ([]byte, error) {
payload := &bytes.Buffer{}
payload.Write(r.ContractAddr[:])
return serializeBridgeGovernanceVaa(GatewayModuleStr, ActionSetIbcComposabilityMwContract, ChainIDWormchain, payload.Bytes())
}
func (r *BodyGatewayIbcComposabilityMwContract) Deserialize(bz []byte) {
func (r *BodyGatewayIbcComposabilityMwContract) Deserialize(bz []byte) error {
if len(bz) != 32 {
panic("incorrect payload length")
return fmt.Errorf("incorrect payload length, should be 32, is %d", len(bz))
}
var contractAddr [32]byte
copy(contractAddr[:], bz[0:32])
r.ContractAddr = contractAddr
return nil
}
func (r BodyGatewayScheduleUpgrade) Serialize() []byte {
func (r BodyGatewayScheduleUpgrade) Serialize() ([]byte, error) {
payload := &bytes.Buffer{}
payload.Write([]byte(r.Name))
MustWrite(payload, binary.BigEndian, r.Height)
@ -397,11 +403,11 @@ func (r *BodyGatewayScheduleUpgrade) Deserialize(bz []byte) {
r.Height = binary.BigEndian.Uint64(bz[len(bz)-8:])
}
func (r BodyCircleIntegrationUpdateWormholeFinality) Serialize() []byte {
func (r BodyCircleIntegrationUpdateWormholeFinality) Serialize() ([]byte, error) {
return serializeBridgeGovernanceVaa(CircleIntegrationModuleStr, CircleIntegrationActionUpdateWormholeFinality, r.TargetChainID, []byte{r.Finality})
}
func (r BodyCircleIntegrationRegisterEmitterAndDomain) Serialize() []byte {
func (r BodyCircleIntegrationRegisterEmitterAndDomain) Serialize() ([]byte, error) {
payload := &bytes.Buffer{}
MustWrite(payload, binary.BigEndian, r.ForeignEmitterChainId)
payload.Write(r.ForeignEmitterAddress[:])
@ -409,15 +415,15 @@ func (r BodyCircleIntegrationRegisterEmitterAndDomain) Serialize() []byte {
return serializeBridgeGovernanceVaa(CircleIntegrationModuleStr, CircleIntegrationActionRegisterEmitterAndDomain, r.TargetChainID, payload.Bytes())
}
func (r BodyCircleIntegrationUpgradeContractImplementation) Serialize() []byte {
func (r BodyCircleIntegrationUpgradeContractImplementation) Serialize() ([]byte, error) {
payload := &bytes.Buffer{}
payload.Write(r.NewImplementationAddress[:])
return serializeBridgeGovernanceVaa(CircleIntegrationModuleStr, CircleIntegrationActionUpgradeContractImplementation, r.TargetChainID, payload.Bytes())
}
func (r BodyIbcUpdateChannelChain) Serialize(module string) []byte {
func (r BodyIbcUpdateChannelChain) Serialize(module string) ([]byte, error) {
if module != IbcReceiverModuleStr && module != IbcTranslatorModuleStr {
panic("module for BodyIbcUpdateChannelChain must be either IbcReceiver or IbcTranslator")
return nil, errors.New("module for BodyIbcUpdateChannelChain must be either IbcReceiver or IbcTranslator")
}
payload := &bytes.Buffer{}
@ -426,7 +432,7 @@ func (r BodyIbcUpdateChannelChain) Serialize(module string) []byte {
return serializeBridgeGovernanceVaa(module, IbcReceiverActionUpdateChannelChain, r.TargetChainId, payload.Bytes())
}
func (r BodyWormholeRelayerSetDefaultDeliveryProvider) Serialize() []byte {
func (r BodyWormholeRelayerSetDefaultDeliveryProvider) Serialize() ([]byte, error) {
payload := &bytes.Buffer{}
payload.Write(r.NewDefaultDeliveryProviderAddress[:])
return serializeBridgeGovernanceVaa(WormholeRelayerModuleStr, WormholeRelayerSetDefaultDeliveryProvider, r.ChainID, payload.Bytes())
@ -443,10 +449,10 @@ func (r BodyGeneralPurposeGovernanceEvm) Serialize() ([]byte, error) {
}
MustWrite(payload, binary.BigEndian, uint16(len(r.Payload)))
payload.Write(r.Payload)
return serializeBridgeGovernanceVaa(GeneralPurposeGovernanceModuleStr, GeneralPurposeGovernanceEvmAction, r.ChainID, payload.Bytes()), nil
return serializeBridgeGovernanceVaa(GeneralPurposeGovernanceModuleStr, GeneralPurposeGovernanceEvmAction, r.ChainID, payload.Bytes())
}
func (r BodyGeneralPurposeGovernanceSolana) Serialize() []byte {
func (r BodyGeneralPurposeGovernanceSolana) Serialize() ([]byte, error) {
payload := &bytes.Buffer{}
payload.Write(r.GovernanceContract[:])
// NOTE: unlike in EVM, we don't write the payload length here, because we're using
@ -457,12 +463,15 @@ func (r BodyGeneralPurposeGovernanceSolana) Serialize() []byte {
return serializeBridgeGovernanceVaa(GeneralPurposeGovernanceModuleStr, GeneralPurposeGovernanceSolanaAction, r.ChainID, payload.Bytes())
}
func EmptyPayloadVaa(module string, actionId GovernanceAction, chainId ChainID) []byte {
func EmptyPayloadVaa(module string, actionId GovernanceAction, chainId ChainID) ([]byte, error) {
return serializeBridgeGovernanceVaa(module, actionId, chainId, []byte{})
}
func serializeBridgeGovernanceVaa(module string, actionId GovernanceAction, chainId ChainID, payload []byte) []byte {
buf := LeftPadBytes(module, 32)
func serializeBridgeGovernanceVaa(module string, actionId GovernanceAction, chainId ChainID, payload []byte) ([]byte, error) {
buf, err := LeftPadBytes(module, 32)
if err != nil {
return nil, fmt.Errorf("failed to left pad module: %w", err)
}
// Write action ID
MustWrite(buf, binary.BigEndian, actionId)
// Write target chain
@ -470,24 +479,27 @@ func serializeBridgeGovernanceVaa(module string, actionId GovernanceAction, chai
// Write emitter address of chain to be registered
buf.Write(payload[:])
return buf.Bytes()
return buf.Bytes(), nil
}
func LeftPadIbcChannelId(channelId string) [64]byte {
channelIdBuf := LeftPadBytes(channelId, 64)
func LeftPadIbcChannelId(channelId string) ([64]byte, error) {
channelIdBuf, err := LeftPadBytes(channelId, 64)
if err != nil {
return [64]byte{}, fmt.Errorf("failed to left pad module: %w", err)
}
var channelIdIdLeftPadded [64]byte
copy(channelIdIdLeftPadded[:], channelIdBuf.Bytes())
return channelIdIdLeftPadded
return channelIdIdLeftPadded, nil
}
// Prepends 0x00 bytes to the payload buffer, up to a size of `length`
func LeftPadBytes(payload string, length int) *bytes.Buffer {
func LeftPadBytes(payload string, length int) (*bytes.Buffer, error) {
if length < 0 {
panic("cannot prepend bytes to a negative length buffer")
return nil, errors.New("cannot prepend bytes to a negative length buffer")
}
if len(payload) > length {
panic(fmt.Sprintf("payload longer than %d bytes", length))
return nil, fmt.Errorf(fmt.Sprintf("payload longer than %d bytes", length))
}
buf := &bytes.Buffer{}
@ -500,5 +512,5 @@ func LeftPadBytes(payload string, length int) *bytes.Buffer {
// add the payload slice
buf.Write([]byte(payload))
return buf
return buf, nil
}

View File

@ -3,11 +3,14 @@ package vaa
import (
"bytes"
"encoding/hex"
"errors"
"reflect"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var addr = Address{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}
@ -74,27 +77,30 @@ func TestBodyTokenBridgeRegisterChainSerialize(t *testing.T) {
name string
expected string
object BodyTokenBridgeRegisterChain
panic bool
err error
}{
{
name: "working_as_expected",
panic: false,
err: nil,
object: BodyTokenBridgeRegisterChain{Module: module, ChainID: 1, EmitterAddress: addr},
expected: "000000000000000000000000000000000000000000000000000000007465737401000000010000000000000000000000000000000000000000000000000000000000000004",
},
{
name: "panic_at_the_disco!",
panic: true,
err: errors.New("payload longer than 32 bytes"),
object: BodyTokenBridgeRegisterChain{Module: "123456789012345678901234567890123", ChainID: 1, EmitterAddress: addr},
expected: "payload longer than 32 bytes",
},
}
for _, testCase := range tests {
t.Run(testCase.name, func(t *testing.T) {
if testCase.panic {
assert.PanicsWithValue(t, testCase.expected, func() { testCase.object.Serialize() })
buf, err := testCase.object.Serialize()
if testCase.err != nil {
require.ErrorContains(t, err, testCase.err.Error())
assert.Nil(t, buf)
} else {
assert.Equal(t, testCase.expected, hex.EncodeToString(testCase.object.Serialize()))
require.NoError(t, err)
assert.Equal(t, testCase.expected, hex.EncodeToString(buf))
}
})
}
@ -104,32 +110,80 @@ func TestBodyTokenBridgeUpgradeContractSerialize(t *testing.T) {
module := "test"
bodyTokenBridgeUpgradeContract := BodyTokenBridgeUpgradeContract{Module: module, TargetChainID: 1, NewContract: addr}
expected := "00000000000000000000000000000000000000000000000000000000746573740200010000000000000000000000000000000000000000000000000000000000000004"
serializedBodyTokenBridgeUpgradeContract := bodyTokenBridgeUpgradeContract.Serialize()
serializedBodyTokenBridgeUpgradeContract, err := bodyTokenBridgeUpgradeContract.Serialize()
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(serializedBodyTokenBridgeUpgradeContract))
}
func TestBodyWormchainStoreCodeSerialize(t *testing.T) {
expected := "0000000000000000000000000000000000000000005761736d644d6f64756c65010c200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"
bodyWormchainStoreCode := BodyWormchainStoreCode{WasmHash: dummyBytes}
assert.Equal(t, expected, hex.EncodeToString(bodyWormchainStoreCode.Serialize()))
buf, err := bodyWormchainStoreCode.Serialize()
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
func TestBodyWormchainInstantiateContractSerialize(t *testing.T) {
actual := BodyWormchainInstantiateContract{InstantiationParamsHash: dummyBytes}
expected := "0000000000000000000000000000000000000000005761736d644d6f64756c65020c200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"
assert.Equal(t, expected, hex.EncodeToString(actual.Serialize()))
buf, err := actual.Serialize()
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
func TestBodyWormchainMigrateContractSerialize(t *testing.T) {
actual := BodyWormchainMigrateContract{MigrationParamsHash: dummyBytes}
expected := "0000000000000000000000000000000000000000005761736d644d6f64756c65030c200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"
assert.Equal(t, expected, hex.EncodeToString(actual.Serialize()))
buf, err := actual.Serialize()
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
func TestBodyWormchainWasmAllowlistInstantiateSerialize(t *testing.T) {
actual := BodyWormchainWasmAllowlistInstantiate{ContractAddr: dummyBytes, CodeId: uint64(42)}
expected := "0000000000000000000000000000000000000000005761736d644d6f64756c65040c200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20000000000000002a"
buf, err := actual.Serialize(ActionAddWasmInstantiateAllowlist)
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
const BodyWormchainWasmAllowlistInstantiateBuf = "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20000000000000002a"
func TestBodyWormchainWasmAllowlistInstantiateDeserialize(t *testing.T) {
expected := BodyWormchainWasmAllowlistInstantiate{ContractAddr: dummyBytes, CodeId: uint64(42)}
buf, err := hex.DecodeString(BodyWormchainWasmAllowlistInstantiateBuf)
require.NoError(t, err)
var actual BodyWormchainWasmAllowlistInstantiate
err = actual.Deserialize(buf)
require.NoError(t, err)
assert.True(t, reflect.DeepEqual(expected, actual))
}
func TestBodyWormchainWasmAllowlistInstantiateDeserializeFailureTooShort(t *testing.T) {
buf, err := hex.DecodeString(BodyWormchainWasmAllowlistInstantiateBuf[0 : len(BodyWormchainWasmAllowlistInstantiateBuf)-2])
require.NoError(t, err)
var actual BodyWormchainWasmAllowlistInstantiate
err = actual.Deserialize(buf)
require.ErrorContains(t, err, "incorrect payload length, should be 40, is 39")
}
func TestBodyWormchainWasmAllowlistInstantiateDeserializeFailureTooLong(t *testing.T) {
buf, err := hex.DecodeString(BodyWormchainWasmAllowlistInstantiateBuf + "00")
require.NoError(t, err)
var actual BodyWormchainWasmAllowlistInstantiate
err = actual.Deserialize(buf)
require.ErrorContains(t, err, "incorrect payload length, should be 40, is 41")
}
func TestBodyCircleIntegrationUpdateWormholeFinalitySerialize(t *testing.T) {
expected := "000000000000000000000000000000436972636c65496e746567726174696f6e0100022a"
bodyCircleIntegrationUpdateWormholeFinality := BodyCircleIntegrationUpdateWormholeFinality{TargetChainID: ChainIDEthereum, Finality: 42}
assert.Equal(t, expected, hex.EncodeToString(bodyCircleIntegrationUpdateWormholeFinality.Serialize()))
buf, err := bodyCircleIntegrationUpdateWormholeFinality.Serialize()
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
func TestBodyCircleIntegrationRegisterEmitterAndDomainSerialize(t *testing.T) {
@ -140,7 +194,9 @@ func TestBodyCircleIntegrationRegisterEmitterAndDomainSerialize(t *testing.T) {
ForeignEmitterAddress: addr,
CircleDomain: 42,
}
assert.Equal(t, expected, hex.EncodeToString(bodyCircleIntegrationRegisterEmitterAndDomain.Serialize()))
buf, err := bodyCircleIntegrationRegisterEmitterAndDomain.Serialize()
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
func TestBodyCircleIntegrationUpgradeContractImplementationSerialize(t *testing.T) {
@ -149,25 +205,58 @@ func TestBodyCircleIntegrationUpgradeContractImplementationSerialize(t *testing.
TargetChainID: ChainIDEthereum,
NewImplementationAddress: addr,
}
assert.Equal(t, expected, hex.EncodeToString(bodyCircleIntegrationUpgradeContractImplementation.Serialize()))
buf, err := bodyCircleIntegrationUpgradeContractImplementation.Serialize()
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
func TestBodyIbcReceiverUpdateChannelChain(t *testing.T) {
expected := "0000000000000000000000000000000000000000004962635265636569766572010c20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006368616e6e656c2d300013"
channelId := LeftPadIbcChannelId("channel-0")
channelId, err := LeftPadIbcChannelId("channel-0")
require.NoError(t, err)
bodyIbcReceiverUpdateChannelChain := BodyIbcUpdateChannelChain{
TargetChainId: ChainIDWormchain,
ChannelId: channelId,
ChainId: ChainIDInjective,
}
assert.Equal(t, expected, hex.EncodeToString(bodyIbcReceiverUpdateChannelChain.Serialize(IbcReceiverModuleStr)))
buf, err := bodyIbcReceiverUpdateChannelChain.Serialize(IbcReceiverModuleStr)
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
func TestBodyIbcReceiverUpdateChannelChainBadModuleName(t *testing.T) {
channelId, err := LeftPadIbcChannelId("channel-0")
require.NoError(t, err)
bodyIbcReceiverUpdateChannelChain := BodyIbcUpdateChannelChain{
TargetChainId: ChainIDWormchain,
ChannelId: channelId,
ChainId: ChainIDInjective,
}
buf, err := bodyIbcReceiverUpdateChannelChain.Serialize(IbcReceiverModuleStr + "ExtraJunk")
require.ErrorContains(t, err, "module for BodyIbcUpdateChannelChain must be either IbcReceiver or IbcTranslator")
assert.Nil(t, buf)
}
func TestLeftPadIbcChannelId(t *testing.T) {
channelId, err := LeftPadIbcChannelId("channel-0")
require.NoError(t, err)
assert.Equal(t, "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006368616e6e656c2d30", hex.EncodeToString(channelId[:]))
}
func TestLeftPadIbcChannelIdFailureTooLong(t *testing.T) {
channelId, err := LeftPadIbcChannelId("channel-ThatIsTooLong!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
require.ErrorContains(t, err, "failed to left pad module: payload longer than 64 bytes")
expected := [64]byte{}
assert.True(t, bytes.Equal(expected[:], channelId[:]))
}
func TestLeftPadBytes(t *testing.T) {
payload := "AAAA"
paddedPayload := LeftPadBytes(payload, int(8))
paddedPayload, err := LeftPadBytes(payload, int(8))
require.NoError(t, err)
buf := &bytes.Buffer{}
buf.WriteByte(0x00)
@ -179,6 +268,24 @@ func TestLeftPadBytes(t *testing.T) {
assert.Equal(t, paddedPayload, buf)
}
func TestLeftPadBytesFailures(t *testing.T) {
payload := "AAAA"
paddedPayload, err := LeftPadBytes(payload, int(-2))
require.ErrorContains(t, err, "cannot prepend bytes to a negative length buffer")
assert.Nil(t, paddedPayload)
paddedPayload, err = LeftPadBytes(payload, int(2))
require.ErrorContains(t, err, "payload longer than 2 bytes")
assert.Nil(t, paddedPayload)
}
func TestSerializeBridgeGovernanceVaaModuleTooLong(t *testing.T) {
buf, err := serializeBridgeGovernanceVaa("ModuleNameIsMoreThanThirtyTwoCharacters", ActionRegisterChain, 1, []byte{0, 1, 2})
require.ErrorContains(t, err, "failed to left pad module: payload longer than 32 bytes")
assert.Nil(t, buf)
}
func FuzzLeftPadBytes(f *testing.F) {
// Add examples to our fuzz corpus
f.Add("FOO", 8)
@ -195,7 +302,8 @@ func FuzzLeftPadBytes(f *testing.F) {
t.Skip()
}
paddedPayload := LeftPadBytes(payload, length)
paddedPayload, err := LeftPadBytes(payload, length)
require.NoError(t, err)
// paddedPayload must always be equal to length
assert.Equal(t, paddedPayload.Len(), length)
@ -208,7 +316,9 @@ func TestBodyWormholeRelayerSetDefaultDeliveryProviderSerialize(t *testing.T) {
ChainID: 4,
NewDefaultDeliveryProviderAddress: addr,
}
assert.Equal(t, expected, hex.EncodeToString(bodyWormholeRelayerSetDefaultDeliveryProvider.Serialize()))
buf, err := bodyWormholeRelayerSetDefaultDeliveryProvider.Serialize()
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
func TestBodyGatewayIbcComposabilityMwContractSerialize(t *testing.T) {
@ -216,18 +326,41 @@ func TestBodyGatewayIbcComposabilityMwContractSerialize(t *testing.T) {
bodyGatewayIbcComposabilityMwContract := BodyGatewayIbcComposabilityMwContract{
ContractAddr: dummyBytes,
}
assert.Equal(t, expected, hex.EncodeToString(bodyGatewayIbcComposabilityMwContract.Serialize()))
buf, err := bodyGatewayIbcComposabilityMwContract.Serialize()
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
const BodyGatewayIbcComposabilityMwContractBuf = "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"
func TestBodyGatewayIbcComposabilityMwContractDeserialize(t *testing.T) {
expected := BodyGatewayIbcComposabilityMwContract{
ContractAddr: dummyBytes,
}
var payloadBody BodyGatewayIbcComposabilityMwContract
payloadBody.Deserialize(dummyBytes[:])
err := payloadBody.Deserialize(dummyBytes[:])
require.NoError(t, err)
assert.Equal(t, expected, payloadBody)
}
func TestBodyGatewayIbcComposabilityMwContractDeserializeFailureTooShort(t *testing.T) {
buf, err := hex.DecodeString(BodyGatewayIbcComposabilityMwContractBuf[0 : len(BodyGatewayIbcComposabilityMwContractBuf)-2])
require.NoError(t, err)
var actual BodyGatewayIbcComposabilityMwContract
err = actual.Deserialize(buf)
require.ErrorContains(t, err, "incorrect payload length, should be 32, is 31")
}
func TestBodyGatewayIbcComposabilityMwContractDeserializeFailureTooLong(t *testing.T) {
buf, err := hex.DecodeString(BodyGatewayIbcComposabilityMwContractBuf + "00")
require.NoError(t, err)
var actual BodyGatewayIbcComposabilityMwContract
err = actual.Deserialize(buf)
require.ErrorContains(t, err, "incorrect payload length, should be 32, is 33")
}
func TestBodyCoreRecoverChainIdSerialize(t *testing.T) {
expected := "00000000000000000000000000000000000000000000000000000000436f72650500000000000000000000000000000000000000000000000000000000000000010fa0"
BodyRecoverChainId := BodyRecoverChainId{
@ -235,7 +368,9 @@ func TestBodyCoreRecoverChainIdSerialize(t *testing.T) {
EvmChainID: uint256.NewInt(1),
NewChainID: 4000,
}
assert.Equal(t, expected, hex.EncodeToString(BodyRecoverChainId.Serialize()))
buf, err := BodyRecoverChainId.Serialize()
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
func TestBodyTokenBridgeRecoverChainIdSerialize(t *testing.T) {
@ -245,5 +380,18 @@ func TestBodyTokenBridgeRecoverChainIdSerialize(t *testing.T) {
EvmChainID: uint256.NewInt(1),
NewChainID: 4000,
}
assert.Equal(t, expected, hex.EncodeToString(BodyRecoverChainId.Serialize()))
buf, err := BodyRecoverChainId.Serialize()
require.NoError(t, err)
assert.Equal(t, expected, hex.EncodeToString(buf))
}
func TestBodyRecoverChainIdModuleTooLong(t *testing.T) {
BodyRecoverChainId := BodyRecoverChainId{
Module: "ModuleNameIsMoreThanThirtyTwoCharacters",
EvmChainID: uint256.NewInt(1),
NewChainID: 4000,
}
buf, err := BodyRecoverChainId.Serialize()
require.ErrorContains(t, err, "failed to left pad module: payload longer than 32 bytes")
assert.Nil(t, buf)
}

View File

@ -91,7 +91,8 @@ func TestBodyRegisterChain_Serialize(t *testing.T) {
EmitterAddress: Address{1, 2, 3, 4},
}
data := msg.Serialize()
data, err := msg.Serialize()
require.NoError(t, err)
require.Equal(t, "000000000000000000000000000000000000000000000000000000000000000001000000080102030400000000000000000000000000000000000000000000000000000000", hex.EncodeToString(data))
}

View File

@ -501,7 +501,9 @@ func TestWasmdAccountantContractModify(t *testing.T) {
Reason: "test modify",
}
ts := time.Date(2012, 12, 12, 12, 12, 12, 12, time.UTC)
modify_vaa := vaa.CreateGovernanceVAA(ts, 1, 1, tb.set.Index, modify_msg.Serialize())
modify_buf, err := modify_msg.Serialize()
require.NoError(t, err)
modify_vaa := vaa.CreateGovernanceVAA(ts, 1, 1, tb.set.Index, modify_buf)
*modify_vaa = signVaa(*modify_vaa, tb.privateKeys)
vBz, err := modify_vaa.Marshal()
require.NoError(t, err)