Compare commits
5 Commits
da7a77de7a
...
d67eeac254
Author | SHA1 | Date |
---|---|---|
bruce-riley | d67eeac254 | |
Bruce Riley | d38cda598a | |
Bruce Riley | e2458dcac4 | |
Bruce Riley | 39db1176af | |
Dirk Brink | a566c3d3bf |
|
@ -44,6 +44,7 @@ As these 3rd party audits are completed and issues are sufficiently addressed, w
|
|||
- **[Jan 2024 - OtterSec](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-01-ottersec-terra.pdf)**: _Terra Classic Contract Upgrades_
|
||||
- **[Feb 2024 - Cyfrin](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-04-09-cyfrin-wormhole-evm-cctp-v2-1.pdf)**: _CCTP EVM Contracts_
|
||||
- **[Mar 2024 - Cyfrin](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-04-11-cyfrin-wormhole-evm-ntt.pdf)**: _NTT EVM Contracts_
|
||||
- **[Mar 2024 - Cantina](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-04-cantina-wormhole-evm-ntt.pdf)**: _NTT EVM Contracts_
|
||||
- **[Mar 2024 - OtterSec](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-03-28-ottersec-solana-ntt.pdf)**: _NTT Solana Contracts_
|
||||
- **[Mar 2024 - Neodyme](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-04-12-neodyme-solana-ntt.pdf)**: _NTT Solana Contracts_
|
||||
|
||||
|
|
|
@ -717,7 +717,7 @@ func runWormchainMigrateContractTemplate(cmd *cobra.Command, args []string) {
|
|||
log.Fatal("--contract-address must be specified.")
|
||||
}
|
||||
if *wormchainMigrateContractInstantiationMsg == "" {
|
||||
log.Fatal("--instantiate-msg must be specified.")
|
||||
log.Fatal("--instantiation-msg must be specified.")
|
||||
}
|
||||
|
||||
m := &nodev1.InjectGovernanceVAARequest{
|
||||
|
|
|
@ -118,12 +118,16 @@ func adminGuardianSetUpdateToVAA(req *nodev1.GuardianSetUpdate, timestamp time.T
|
|||
addrs[i] = ethAddr
|
||||
}
|
||||
|
||||
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
|
||||
vaa.BodyGuardianSetUpdate{
|
||||
Keys: addrs,
|
||||
NewIndex: guardianSetIndex + 1,
|
||||
}.Serialize())
|
||||
body, err := vaa.BodyGuardianSetUpdate{
|
||||
Keys: addrs,
|
||||
NewIndex: guardianSetIndex + 1,
|
||||
}.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
|
||||
}
|
||||
|
||||
|
@ -146,12 +150,16 @@ func adminContractUpgradeToVAA(req *nodev1.ContractUpgrade, timestamp time.Time,
|
|||
newContractAddress := vaa.Address{}
|
||||
copy(newContractAddress[:], b)
|
||||
|
||||
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
|
||||
vaa.BodyContractUpgrade{
|
||||
ChainID: vaa.ChainID(req.ChainId),
|
||||
NewContract: newContractAddress,
|
||||
}.Serialize())
|
||||
body, err := vaa.BodyContractUpgrade{
|
||||
ChainID: vaa.ChainID(req.ChainId),
|
||||
NewContract: newContractAddress,
|
||||
}.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
|
||||
}
|
||||
|
||||
|
@ -174,13 +182,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 +215,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 +270,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 +310,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 +340,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 +357,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 +373,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 +409,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 +429,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 +449,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 +475,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 +496,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 +531,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 +564,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 +596,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 +610,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 +643,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 +677,6 @@ func evmCallToVaa(evmCall *nodev1.EvmCall, timestamp time.Time, guardianSetIndex
|
|||
}
|
||||
|
||||
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
|
@ -619,13 +697,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 +759,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
|
||||
|
|
|
@ -2,28 +2,33 @@
|
|||
package adminrpc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
math_rand "math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/certusone/wormhole/node/pkg/common"
|
||||
nodev1 "github.com/certusone/wormhole/node/pkg/proto/node/v1"
|
||||
"github.com/certusone/wormhole/node/pkg/watchers/evm/connectors"
|
||||
"github.com/certusone/wormhole/node/pkg/watchers/evm/connectors/ethabi"
|
||||
ethereum "github.com/ethereum/go-ethereum"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
ethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
ethRpc "github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/encoding/prototext"
|
||||
)
|
||||
|
||||
type mockEVMConnector struct {
|
||||
guardianAddrs []common.Address
|
||||
guardianAddrs []ethCommon.Address
|
||||
guardianSetIndex uint32
|
||||
}
|
||||
|
||||
|
@ -42,7 +47,7 @@ func (m mockEVMConnector) NetworkName() string {
|
|||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (m mockEVMConnector) ContractAddress() common.Address {
|
||||
func (m mockEVMConnector) ContractAddress() ethCommon.Address {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
|
@ -50,11 +55,11 @@ func (m mockEVMConnector) WatchLogMessagePublished(ctx context.Context, errC cha
|
|||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (m mockEVMConnector) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
|
||||
func (m mockEVMConnector) TransactionReceipt(ctx context.Context, txHash ethCommon.Hash) (*types.Receipt, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func (m mockEVMConnector) TimeOfBlockByHash(ctx context.Context, hash common.Hash) (uint64, error) {
|
||||
func (m mockEVMConnector) TimeOfBlockByHash(ctx context.Context, hash ethCommon.Hash) (uint64, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
|
@ -82,7 +87,7 @@ func (c mockEVMConnector) SubscribeNewHead(ctx context.Context, ch chan<- *types
|
|||
panic("unimplemented")
|
||||
}
|
||||
|
||||
func generateGS(num int) (keys []*ecdsa.PrivateKey, addrs []common.Address) {
|
||||
func generateGS(num int) (keys []*ecdsa.PrivateKey, addrs []ethCommon.Address) {
|
||||
for i := 0; i < num; i++ {
|
||||
key, err := ethcrypto.GenerateKey()
|
||||
if err != nil {
|
||||
|
@ -94,7 +99,7 @@ func generateGS(num int) (keys []*ecdsa.PrivateKey, addrs []common.Address) {
|
|||
return
|
||||
}
|
||||
|
||||
func addrsToHexStrings(addrs []common.Address) (out []string) {
|
||||
func addrsToHexStrings(addrs []ethCommon.Address) (out []string) {
|
||||
for _, addr := range addrs {
|
||||
out = append(out, addr.String())
|
||||
}
|
||||
|
@ -125,7 +130,7 @@ func generateMockVAA(gsIndex uint32, gsKeys []*ecdsa.PrivateKey) []byte {
|
|||
return vBytes
|
||||
}
|
||||
|
||||
func setupAdminServerForVAASigning(gsIndex uint32, gsAddrs []common.Address) *nodePrivilegedService {
|
||||
func setupAdminServerForVAASigning(gsIndex uint32, gsAddrs []ethCommon.Address) *nodePrivilegedService {
|
||||
gk, err := ethcrypto.GenerateKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -150,7 +155,7 @@ func setupAdminServerForVAASigning(gsIndex uint32, gsAddrs []common.Address) *no
|
|||
}
|
||||
|
||||
func TestSignExistingVAA_NoVAA(t *testing.T) {
|
||||
s := setupAdminServerForVAASigning(0, []common.Address{})
|
||||
s := setupAdminServerForVAASigning(0, []ethCommon.Address{})
|
||||
|
||||
_, err := s.SignExistingVAA(context.Background(), &nodev1.SignExistingVAARequest{
|
||||
Vaa: nil,
|
||||
|
@ -247,7 +252,7 @@ func TestSignExistingVAA_CantReachQuorum(t *testing.T) {
|
|||
gsAddrs = append(gsAddrs, s.guardianAddress)
|
||||
_, err := s.SignExistingVAA(context.Background(), &nodev1.SignExistingVAARequest{
|
||||
Vaa: v,
|
||||
NewGuardianAddrs: addrsToHexStrings(append(gsAddrs, common.Address{0, 1}, common.Address{3, 1}, common.Address{8, 1})),
|
||||
NewGuardianAddrs: addrsToHexStrings(append(gsAddrs, ethCommon.Address{0, 1}, ethCommon.Address{3, 1}, ethCommon.Address{8, 1})),
|
||||
NewGuardianSetIndex: 1,
|
||||
})
|
||||
require.ErrorContains(t, err, "cannot reach quorum on new guardian set with the local signature")
|
||||
|
@ -270,3 +275,131 @@ func TestSignExistingVAA_Valid(t *testing.T) {
|
|||
v2 := generateMockVAA(1, append(gsKeys, s.gk))
|
||||
require.Equal(t, v2, res.Vaa)
|
||||
}
|
||||
|
||||
const govGuardianSetIndex = uint32(4)
|
||||
|
||||
var govTimestamp = time.Now()
|
||||
|
||||
const govEmitterChain = vaa.ChainIDSolana
|
||||
|
||||
var govEmitterAddr vaa.Address = [32]byte{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}
|
||||
|
||||
// verifyGovernanceVAA verifies the VAA fields of a generated governance VAA. Note that it doesn't verify the payload because that is
|
||||
// already verified in `sdk/vaa/payload_test` and we don't want to duplicate all those arrays.
|
||||
func verifyGovernanceVAA(t *testing.T, v *vaa.VAA, expectedSeqNo uint64, expectedNonce uint32) {
|
||||
t.Helper()
|
||||
require.NotNil(t, v)
|
||||
assert.Equal(t, uint8(vaa.SupportedVAAVersion), v.Version)
|
||||
assert.Equal(t, govGuardianSetIndex, v.GuardianSetIndex)
|
||||
assert.Nil(t, v.Signatures)
|
||||
assert.Equal(t, govTimestamp, v.Timestamp)
|
||||
assert.Equal(t, expectedNonce, v.Nonce)
|
||||
assert.Equal(t, expectedSeqNo, v.Sequence)
|
||||
assert.Equal(t, uint8(32), v.ConsistencyLevel)
|
||||
assert.Equal(t, govEmitterChain, v.EmitterChain)
|
||||
assert.True(t, bytes.Equal(govEmitterAddr[:], v.EmitterAddress[:]))
|
||||
}
|
||||
|
||||
func Test_adminGuardianSetUpdateToVAA(t *testing.T) {
|
||||
// Success case.
|
||||
govMsg := &nodev1.GovernanceMessage{
|
||||
Sequence: math_rand.Uint64(), //nolint:gosec
|
||||
Nonce: math_rand.Uint32(), //nolint:gosec
|
||||
Payload: &nodev1.GovernanceMessage_GuardianSet{
|
||||
GuardianSet: &nodev1.GuardianSetUpdate{
|
||||
Guardians: []*nodev1.GuardianSetUpdate_Guardian{
|
||||
{
|
||||
Pubkey: "0x187727CdD17C8142FE9b29A066F577548423aF0e",
|
||||
Name: "P2P Validator",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
vaa, err := GovMsgToVaa(govMsg, govGuardianSetIndex, govTimestamp)
|
||||
require.NoError(t, err)
|
||||
verifyGovernanceVAA(t, vaa, govMsg.Sequence, govMsg.Nonce)
|
||||
|
||||
// No guardian keys should return an error.
|
||||
govMsg.Payload = &nodev1.GovernanceMessage_GuardianSet{
|
||||
GuardianSet: &nodev1.GuardianSetUpdate{
|
||||
// Leave Guardians nil.
|
||||
},
|
||||
}
|
||||
|
||||
vaa, err = GovMsgToVaa(govMsg, govGuardianSetIndex, govTimestamp)
|
||||
require.ErrorContains(t, err, "empty guardian set specified")
|
||||
assert.Nil(t, vaa)
|
||||
|
||||
// Too many guardian keys should return an error.
|
||||
guardians := make([]*nodev1.GuardianSetUpdate_Guardian, 0, common.MaxGuardianCount+1)
|
||||
for count := 0; count < common.MaxGuardianCount+1; count++ {
|
||||
guardians = append(guardians, &nodev1.GuardianSetUpdate_Guardian{Pubkey: "0x187727CdD17C8142FE9b29A066F577548423aF0e", Name: "P2P Validator"})
|
||||
}
|
||||
|
||||
govMsg.Payload = &nodev1.GovernanceMessage_GuardianSet{
|
||||
GuardianSet: &nodev1.GuardianSetUpdate{
|
||||
Guardians: guardians,
|
||||
},
|
||||
}
|
||||
|
||||
vaa, err = GovMsgToVaa(govMsg, govGuardianSetIndex, govTimestamp)
|
||||
require.ErrorContains(t, err, "too many guardians")
|
||||
assert.Nil(t, vaa)
|
||||
|
||||
// Invalid guardian key should return an error.
|
||||
govMsg.Payload = &nodev1.GovernanceMessage_GuardianSet{
|
||||
GuardianSet: &nodev1.GuardianSetUpdate{
|
||||
Guardians: []*nodev1.GuardianSetUpdate_Guardian{
|
||||
{
|
||||
Pubkey: "HelloWorld",
|
||||
Name: "P2P Validator",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
vaa, err = GovMsgToVaa(govMsg, govGuardianSetIndex, govTimestamp)
|
||||
require.ErrorContains(t, err, "invalid pubkey format")
|
||||
assert.Nil(t, vaa)
|
||||
|
||||
// Duplicate guardian key should return an error.
|
||||
govMsg.Payload = &nodev1.GovernanceMessage_GuardianSet{
|
||||
GuardianSet: &nodev1.GuardianSetUpdate{
|
||||
Guardians: []*nodev1.GuardianSetUpdate_Guardian{
|
||||
{
|
||||
Pubkey: "0x187727CdD17C8142FE9b29A066F577548423aF0e",
|
||||
Name: "P2P Validator",
|
||||
},
|
||||
{
|
||||
Pubkey: "0x187727CdD17C8142FE9b29A066F577548423aF0e",
|
||||
Name: "P2P Validator",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
vaa, err = GovMsgToVaa(govMsg, govGuardianSetIndex, govTimestamp)
|
||||
require.ErrorContains(t, err, "duplicate pubkey at index 1 (duplicate of 0)")
|
||||
assert.Nil(t, vaa)
|
||||
}
|
||||
|
||||
func Test_adminCommands(t *testing.T) {
|
||||
for _, tst := range adminCommandTest {
|
||||
t.Run(tst.label, func(t *testing.T) {
|
||||
var msg nodev1.InjectGovernanceVAARequest
|
||||
err := prototext.Unmarshal([]byte(tst.prototext), &msg)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(msg.Messages))
|
||||
govMsg := msg.Messages[0]
|
||||
vaa, err := GovMsgToVaa(govMsg, govGuardianSetIndex, govTimestamp)
|
||||
if tst.errText == "" {
|
||||
require.NoError(t, err)
|
||||
verifyGovernanceVAA(t, vaa, govMsg.Sequence, govMsg.Nonce)
|
||||
} else {
|
||||
require.ErrorContains(t, err, tst.errText)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,638 @@
|
|||
//nolint:unparam
|
||||
package adminrpc
|
||||
|
||||
type adminCommandTestEntry struct {
|
||||
label string
|
||||
errText string // empty string means success
|
||||
prototext string
|
||||
}
|
||||
|
||||
var adminCommandTest = []adminCommandTestEntry{
|
||||
// build/bin/guardiand template guardian-set-update --num=2 --idx=4
|
||||
{
|
||||
label: "GuardianSetUpdate success",
|
||||
errText: "",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 13675600082943268828
|
||||
nonce: 1875482155
|
||||
guardian_set: {
|
||||
guardians: {
|
||||
pubkey: "0xbeFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe"
|
||||
name: "Example validator 0"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "GuardianSetUpdate no guardian keys",
|
||||
errText: "empty guardian set specified",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 13675600082943268828
|
||||
nonce: 1875482155
|
||||
guardian_set: {
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "GuardianSetUpdate too many guardian keys",
|
||||
errText: "too many guardians",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 13675600082943268828
|
||||
nonce: 1875482155
|
||||
guardian_set: {
|
||||
guardians: {
|
||||
pubkey: "0xbeFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe"
|
||||
name: "Example validator 0"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0x88D7D8B32a9105d228100E72dFFe2Fae0705D31c"
|
||||
name: "Example validator 1"
|
||||
}
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "GuardianSetUpdate invalid guardian key",
|
||||
errText: "invalid pubkey format",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 13675600082943268828
|
||||
nonce: 1875482155
|
||||
guardian_set: {
|
||||
guardians: {
|
||||
pubkey: "Hello, World!"
|
||||
name: "Example validator 0"
|
||||
}
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "GuardianSetUpdate duplicate guardian key",
|
||||
errText: "duplicate pubkey at index 1",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 13675600082943268828
|
||||
nonce: 1875482155
|
||||
guardian_set: {
|
||||
guardians: {
|
||||
pubkey: "0xbeFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe"
|
||||
name: "Example validator 0"
|
||||
}
|
||||
guardians: {
|
||||
pubkey: "0xbeFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe"
|
||||
name: "Example validator 0"
|
||||
}
|
||||
}
|
||||
}`,
|
||||
},
|
||||
|
||||
// build/bin/guardiand template contract-upgrade --chain-id "ethereum" --new-address 0xC89Ce4735882C9F0f0FE26686c53074E09B0D550
|
||||
{
|
||||
label: "ContractUpgrade success",
|
||||
errText: "",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 12970493895929703138
|
||||
nonce: 700990237
|
||||
contract_upgrade: {
|
||||
chain_id: 2
|
||||
new_contract: "000000000000000000000000c89ce4735882c9f0f0fe26686c53074e09b0d550"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "ContractUpgrade invalid contract address",
|
||||
errText: "invalid new contract address encoding (expected hex)",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 12970493895929703138
|
||||
nonce: 700990237
|
||||
contract_upgrade: {
|
||||
chain_id: 2
|
||||
new_contract: "Hello, World!"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "ContractUpgrade contract address wrong length",
|
||||
errText: "invalid new_contract address",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 12970493895929703138
|
||||
nonce: 700990237
|
||||
contract_upgrade: {
|
||||
chain_id: 2
|
||||
new_contract: "c89ce4735882c9f0f0fe26686c53074e09b0d550"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "ContractUpgrade chain id too large",
|
||||
errText: "invalid chain_id",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 12970493895929703138
|
||||
nonce: 700990237
|
||||
contract_upgrade: {
|
||||
chain_id: 65536
|
||||
new_contract: "000000000000000000000000c89ce4735882c9f0f0fe26686c53074e09b0d550"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
|
||||
// build/bin/guardiand template token-bridge-register-chain --chain-id ethereum --module TokenBridge --new-address 0x0290FB167208Af455bB137780163b7B7a9a10C16
|
||||
{
|
||||
label: "BridgeRegisterChain success",
|
||||
errText: "",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 13048739474937843907
|
||||
nonce: 277897432
|
||||
bridge_register_chain: {
|
||||
module: "TokenBridge"
|
||||
chain_id: 2
|
||||
emitter_address: "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "BridgeRegisterChain invalid chain id",
|
||||
errText: "invalid chain_id",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 13048739474937843907
|
||||
nonce: 277897432
|
||||
bridge_register_chain: {
|
||||
module: "TokenBridge"
|
||||
chain_id: 65536
|
||||
emitter_address: "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "BridgeRegisterChain invalid emitter address",
|
||||
errText: "invalid emitter address encoding (expected hex)",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 13048739474937843907
|
||||
nonce: 277897432
|
||||
bridge_register_chain: {
|
||||
module: "TokenBridge"
|
||||
chain_id: 2
|
||||
emitter_address: "Hello, World!"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "BridgeRegisterChain invalid emitter address length",
|
||||
errText: "invalid emitter address (expected 32 bytes)",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 13048739474937843907
|
||||
nonce: 277897432
|
||||
bridge_register_chain: {
|
||||
module: "TokenBridge"
|
||||
chain_id: 2
|
||||
emitter_address: "0290fb167208af455bb137780163b7b7a9a10c16"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
|
||||
// build/bin/guardiand template recover-chain-id --module TokenBridge --evm-chain-id 42 --new-chain-id 43
|
||||
{
|
||||
label: "RecoverChainId success",
|
||||
errText: "",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 4474356899438211298
|
||||
nonce: 4040780926
|
||||
recover_chain_id: {
|
||||
module: "TokenBridge"
|
||||
evm_chain_id: "42"
|
||||
new_chain_id: 43
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "RecoverChainId invalid evm chain id",
|
||||
errText: "invalid evm_chain_id",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 4474356899438211298
|
||||
nonce: 4040780926
|
||||
recover_chain_id: {
|
||||
module: "TokenBridge"
|
||||
evm_chain_id: "Hello, World!"
|
||||
new_chain_id: 43
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "RecoverChainId evm chain id too large",
|
||||
errText: "evm_chain_id overflow",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 4474356899438211298
|
||||
nonce: 4040780926
|
||||
recover_chain_id: {
|
||||
module: "TokenBridge"
|
||||
evm_chain_id: "115792089237316195423570985008687907853269984665640564039457584007913129639936"
|
||||
new_chain_id: 43
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "RecoverChainId invalid new chain id",
|
||||
errText: "invalid new_chain_id",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 4474356899438211298
|
||||
nonce: 4040780926
|
||||
recover_chain_id: {
|
||||
module: "TokenBridge"
|
||||
evm_chain_id: "42"
|
||||
new_chain_id: 65536
|
||||
}
|
||||
}`,
|
||||
},
|
||||
|
||||
// TODO: Skipping AccountantModifyBalance because it doesn't have an admin command to generate the prototext.
|
||||
|
||||
// build/bin/guardiand template token-bridge-upgrade-contract --chain-id ethereum --module TokenBridge --new-address 0x0290FB167208Af455bB137780163b7B7a9a10C16
|
||||
{
|
||||
label: "BridgeUpgradeContract success",
|
||||
errText: "",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 2474806415844516465
|
||||
nonce: 1137535017
|
||||
bridge_contract_upgrade: {
|
||||
module: "TokenBridge"
|
||||
target_chain_id: 2
|
||||
new_contract: "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "BridgeUpgradeContract invalid target chain id",
|
||||
errText: "invalid target_chain_id",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 2474806415844516465
|
||||
nonce: 1137535017
|
||||
bridge_contract_upgrade: {
|
||||
module: "TokenBridge"
|
||||
target_chain_id: 65536
|
||||
new_contract: "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "BridgeUpgradeContract invalid new contract address",
|
||||
errText: "invalid new contract address (expected hex)",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 2474806415844516465
|
||||
nonce: 1137535017
|
||||
bridge_contract_upgrade: {
|
||||
module: "TokenBridge"
|
||||
target_chain_id: 2
|
||||
new_contract: "Hello, World!"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "BridgeUpgradeContract contract address too long",
|
||||
errText: "invalid new contract address (expected 32 bytes)",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 2474806415844516465
|
||||
nonce: 1137535017
|
||||
bridge_contract_upgrade: {
|
||||
module: "TokenBridge"
|
||||
target_chain_id: 2
|
||||
new_contract: "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c1600"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
|
||||
// build/bin/guardiand template wormchain-store-code --wasm-hash 0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16
|
||||
{
|
||||
label: "WormchainStoreCode success",
|
||||
errText: "",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 1985924966232230622
|
||||
nonce: 1162627577
|
||||
wormchain_store_code: {
|
||||
wasm_hash: "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "WormchainStoreCode invalid wasm hash",
|
||||
errText: "invalid cosmwasm bytecode hash (expected hex)",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 1985924966232230622
|
||||
nonce: 1162627577
|
||||
wormchain_store_code: {
|
||||
wasm_hash: "Hello, World!"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "WormchainStoreCode invalid wasm hash length",
|
||||
errText: "invalid cosmwasm bytecode hash (expected 32 bytes but received 33 bytes)",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 1985924966232230622
|
||||
nonce: 1162627577
|
||||
wormchain_store_code: {
|
||||
wasm_hash: "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c1600"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
|
||||
// build/bin/guardiand template wormchain-instantiate-contract --code-id 12345678 --label "Hi, Mom!" --instantiation-msg "Some random junk"
|
||||
{
|
||||
label: "WormchainInstantiateContract success",
|
||||
errText: "",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 3355941316502237895
|
||||
nonce: 749992725
|
||||
wormchain_instantiate_contract: {
|
||||
code_id: 12345678
|
||||
label: "Hi, Mom!"
|
||||
instantiation_msg: "Some random junk"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
|
||||
// build/bin/guardiand template wormchain-migrate-contract --code-id 12345678 --contract-address wormhole1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqtm7t3h --instantiation-msg "Some junk"
|
||||
{
|
||||
label: "WormchainMigrateContract success",
|
||||
errText: "",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 13069018493465262425
|
||||
nonce: 222803138
|
||||
wormchain_migrate_contract: {
|
||||
code_id: 12345678
|
||||
contract: "wormhole1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqtm7t3h"
|
||||
instantiation_msg: "Some junk"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
|
||||
// build/bin/guardiand template wormchain-add-wasm-instantiate-allowlist --code-id 12345678 --contract-address wormchain-add-wasm-instantiate-allowlist
|
||||
{
|
||||
label: "WormchainWasmInstantiateAllowlist success",
|
||||
errText: "",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 14341603504021037676
|
||||
nonce: 1682273406
|
||||
wormchain_wasm_instantiate_allowlist: {
|
||||
code_id: 12345678
|
||||
contract: "wormhole1466nf3zuxpya8q9emxukd7vftaf6h4psr0a07srl5zw74zh84yjq4lyjmh"
|
||||
action: WORMCHAIN_WASM_INSTANTIATE_ALLOWLIST_ACTION_ADD
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "WormchainWasmInstantiateAllowlist invalid bech32 contract address",
|
||||
errText: "decoding bech32 failed",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 14341603504021037676
|
||||
nonce: 1682273406
|
||||
wormchain_wasm_instantiate_allowlist: {
|
||||
code_id: 12345678
|
||||
contract: "Hi, Mom!"
|
||||
action: WORMCHAIN_WASM_INSTANTIATE_ALLOWLIST_ACTION_ADD
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "WormchainWasmInstantiateAllowlist unexpected action",
|
||||
errText: "unrecognized wasm instantiate allowlist action",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 14341603504021037676
|
||||
nonce: 1682273406
|
||||
wormchain_wasm_instantiate_allowlist: {
|
||||
code_id: 12345678
|
||||
contract: "wormhole1466nf3zuxpya8q9emxukd7vftaf6h4psr0a07srl5zw74zh84yjq4lyjmh"
|
||||
action: WORMCHAIN_WASM_INSTANTIATE_ALLOWLIST_ACTION_UNSPECIFIED
|
||||
}
|
||||
}`,
|
||||
},
|
||||
|
||||
// build/bin/guardiand template circle-integration-update-wormhole-finality --chain-id ethereum --finality 42
|
||||
{
|
||||
label: "CircleIntegrationUpdateWormholeFinality success",
|
||||
errText: "",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 6415677735604800159
|
||||
nonce: 1410643993
|
||||
circle_integration_update_wormhole_finality: {
|
||||
finality: 42
|
||||
target_chain_id: 2
|
||||
}
|
||||
}`,
|
||||
},
|
||||
|
||||
// build/bin/guardiand template circle-integration-register-emitter-and-domain --chain-id ethereum --circle-domain 42 --foreign-emitter-chain-id bsc --foreign-emitter-address 0x0290FB167208Af455bB137780163b7B7a9a10C16
|
||||
{
|
||||
label: "CircleIntegrationRegisterEmitterAndDomain success",
|
||||
errText: "",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 4922548351928530675
|
||||
nonce: 1868545932
|
||||
circle_integration_register_emitter_and_domain: {
|
||||
foreign_emitter_chain_id: 4
|
||||
foreign_emitter_address: "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16"
|
||||
circle_domain: 42
|
||||
target_chain_id: 2
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "CircleIntegrationRegisterEmitterAndDomain invalid target chain id",
|
||||
errText: "invalid target chain id",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 4922548351928530675
|
||||
nonce: 1868545932
|
||||
circle_integration_register_emitter_and_domain: {
|
||||
foreign_emitter_chain_id: 4
|
||||
foreign_emitter_address: "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16"
|
||||
circle_domain: 42
|
||||
target_chain_id: 65536
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "CircleIntegrationRegisterEmitterAndDomain invalid foreign chain id",
|
||||
errText: "invalid foreign emitter chain id",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 4922548351928530675
|
||||
nonce: 1868545932
|
||||
circle_integration_register_emitter_and_domain: {
|
||||
foreign_emitter_chain_id: 65536
|
||||
foreign_emitter_address: "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16"
|
||||
circle_domain: 42
|
||||
target_chain_id: 2
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "CircleIntegrationRegisterEmitterAndDomain invalid foreign emitter address",
|
||||
errText: "invalid foreign emitter address encoding",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 4922548351928530675
|
||||
nonce: 1868545932
|
||||
circle_integration_register_emitter_and_domain: {
|
||||
foreign_emitter_chain_id: 4
|
||||
foreign_emitter_address: "Hello, World!"
|
||||
circle_domain: 42
|
||||
target_chain_id: 2
|
||||
}
|
||||
}`,
|
||||
},
|
||||
{
|
||||
label: "CircleIntegrationRegisterEmitterAndDomain foreign emitter address too short",
|
||||
errText: "invalid foreign emitter address (expected 32 bytes)",
|
||||
prototext: `
|
||||
current_set_index: 4
|
||||
messages: {
|
||||
sequence: 4922548351928530675
|
||||
nonce: 1868545932
|
||||
circle_integration_register_emitter_and_domain: {
|
||||
foreign_emitter_chain_id: 4
|
||||
foreign_emitter_address: "00000000000000000000000290fb167208af455bb137780163b7b7a9a10c16"
|
||||
circle_domain: 42
|
||||
target_chain_id: 2
|
||||
}
|
||||
}`,
|
||||
},
|
||||
}
|
|
@ -3,6 +3,7 @@ package vaa
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
|
@ -248,7 +249,7 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
func (b BodyContractUpgrade) Serialize() []byte {
|
||||
func (b BodyContractUpgrade) Serialize() ([]byte, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
// Module
|
||||
|
@ -260,10 +261,10 @@ func (b BodyContractUpgrade) Serialize() []byte {
|
|||
|
||||
buf.Write(b.NewContract[:])
|
||||
|
||||
return buf.Bytes()
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (b BodyGuardianSetUpdate) Serialize() []byte {
|
||||
func (b BodyGuardianSetUpdate) Serialize() ([]byte, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
// Module
|
||||
|
@ -279,10 +280,10 @@ func (b BodyGuardianSetUpdate) Serialize() []byte {
|
|||
buf.Write(k[:])
|
||||
}
|
||||
|
||||
return buf.Bytes()
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
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,42 +370,45 @@ 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)
|
||||
return serializeBridgeGovernanceVaa(GatewayModuleStr, ActionScheduleUpgrade, ChainIDWormchain, payload.Bytes())
|
||||
}
|
||||
|
||||
func (r *BodyGatewayScheduleUpgrade) Deserialize(bz []byte) {
|
||||
func (r *BodyGatewayScheduleUpgrade) Deserialize(bz []byte) error {
|
||||
r.Name = string(bz[0 : len(bz)-8])
|
||||
r.Height = binary.BigEndian.Uint64(bz[len(bz)-8:])
|
||||
return nil
|
||||
}
|
||||
|
||||
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 +416,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 +433,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 +450,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 +464,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 +480,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 +513,5 @@ func LeftPadBytes(payload string, length int) *bytes.Buffer {
|
|||
// add the payload slice
|
||||
buf.Write([]byte(payload))
|
||||
|
||||
return buf
|
||||
return buf, nil
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
@ -53,7 +56,8 @@ func TestBodyTokenBridgeUpgradeContract(t *testing.T) {
|
|||
func TestBodyContractUpgradeSerialize(t *testing.T) {
|
||||
bodyContractUpgrade := BodyContractUpgrade{ChainID: 1, NewContract: addr}
|
||||
expected := "00000000000000000000000000000000000000000000000000000000436f72650100010000000000000000000000000000000000000000000000000000000000000004"
|
||||
serializedBodyContractUpgrade := bodyContractUpgrade.Serialize()
|
||||
serializedBodyContractUpgrade, err := bodyContractUpgrade.Serialize()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expected, hex.EncodeToString(serializedBodyContractUpgrade))
|
||||
}
|
||||
|
||||
|
@ -64,7 +68,8 @@ func TestBodyGuardianSetUpdateSerialize(t *testing.T) {
|
|||
}
|
||||
bodyGuardianSetUpdate := BodyGuardianSetUpdate{Keys: keys, NewIndex: uint32(1)}
|
||||
expected := "00000000000000000000000000000000000000000000000000000000436f726502000000000001025aaeb6053f3e94c9b9a09f33669435e7ef1beaed5aaeb6053f3e94c9b9a09f33669435e7ef1beaee"
|
||||
serializedBodyGuardianSetUpdate := bodyGuardianSetUpdate.Serialize()
|
||||
serializedBodyGuardianSetUpdate, err := bodyGuardianSetUpdate.Serialize()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expected, hex.EncodeToString(serializedBodyGuardianSetUpdate))
|
||||
}
|
||||
|
||||
|
@ -74,27 +79,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 +112,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 +196,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 +207,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 +270,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 +304,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 +318,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 +328,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 +370,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 +382,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)
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue