diff --git a/changelog.md b/changelog.md index 1414740d47..a2fdd6c26c 100644 --- a/changelog.md +++ b/changelog.md @@ -16,6 +16,8 @@ * [2113](https://github.com/zeta-chain/node/pull/2113) - add zetaclientd-supervisor process * [2154](https://github.com/zeta-chain/node/pull/2154) - add `ibccrosschain` module * [2258](https://github.com/zeta-chain/node/pull/2258) - add Optimism and Base in static chain information +* [2279](https://github.com/zeta-chain/node/pull/2279) - add a CCTXGateway field to chain static data +* [2275](https://github.com/zeta-chain/node/pull/2275) - add ChainInfo singleton state variable in authority ### Refactor diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index ead84ee4d1..a297be595b 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -136,9 +136,9 @@ if [ "$OPTION" == "upgrade" ]; then # When the upgrade height is greater than 100 for upgrade test, the Bitcoin tests have been run once, therefore the Bitcoin wallet is already set up # Use light flag to skip advanced tests if [ "$UPGRADE_HEIGHT" -lt 100 ]; then - zetae2e "$ZETAE2E_CMD" --skip-setup --config deployed.yml --light --skip-header-proof + zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --light --skip-header-proof else - zetae2e "$ZETAE2E_CMD" --skip-setup --config deployed.yml --skip-bitcoin-setup --light --skip-header-proof + zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --skip-bitcoin-setup --light --skip-header-proof fi ZETAE2E_EXIT_CODE=$? @@ -156,7 +156,7 @@ else echo "running e2e setup..." if [[ ! -f deployed.yml ]]; then - zetae2e "$ZETAE2E_CMD" --setup-only --config-out deployed.yml + zetae2e $ZETAE2E_CMD --setup-only --config-out deployed.yml if [ $? -ne 0 ]; then echo "e2e setup failed" exit 1 @@ -167,7 +167,7 @@ else echo "running e2e tests..." - zetae2e "$ZETAE2E_CMD" --skip-setup --config deployed.yml + zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml ZETAE2E_EXIT_CODE=$? # if e2e passed, exit with 0, otherwise exit with 1 diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 9067eccc6d..9c0dbc1e10 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -56744,6 +56744,18 @@ definitions: description: |- QueryGetPoliciesResponse is the response type for the Query/Policies RPC method. + chainsCCTXGateway: + type: string + enum: + - zevm + - observers + default: zevm + description: |- + - zevm: zevm is the internal CCTX gateway to process outbound on the ZEVM and read + inbound events from the ZEVM only used for ZetaChain chains + - observers: observers is the CCTX gateway for chains relying on the observer set to + observe inbounds and TSS for outbounds + title: CCTXGateway describes for the chain the gateway used to handle CCTX outbounds chainsChain: type: object properties: @@ -56769,6 +56781,9 @@ definitions: is_external: type: boolean title: IsExternal describe if the chain is ZetaChain or external + cctx_gateway: + $ref: '#/definitions/chainsCCTXGateway' + title: CCTXGateway is the gateway used to handle CCTX outbounds title: |- Chain represents static data about a blockchain network it is identified by a unique chain ID diff --git a/pkg/chains/chain.go b/pkg/chains/chain.go index 0b1c9edcc8..681e13a5ae 100644 --- a/pkg/chains/chain.go +++ b/pkg/chains/chain.go @@ -14,14 +14,47 @@ type SigninAlgo string // Chains represent a slice of Chain type Chains []Chain +// Validate checks whether the chain is valid +// The function check the chain ID is positive and all enum fields have a defined value +func (chain Chain) Validate() error { + if chain.ChainId <= 0 { + return fmt.Errorf("chain ID must be positive") + } + + if _, ok := ChainName_name[int32(chain.ChainName)]; !ok { + return fmt.Errorf("invalid chain name %d", int32(chain.ChainName)) + } + + if _, ok := Network_name[int32(chain.Network)]; !ok { + return fmt.Errorf("invalid network %d", int32(chain.Network)) + } + + if _, ok := NetworkType_name[int32(chain.NetworkType)]; !ok { + return fmt.Errorf("invalid network type %d", int32(chain.NetworkType)) + } + + if _, ok := Vm_name[int32(chain.Vm)]; !ok { + return fmt.Errorf("invalid vm %d", int32(chain.Vm)) + } + + if _, ok := Consensus_name[int32(chain.Consensus)]; !ok { + return fmt.Errorf("invalid consensus %d", int32(chain.Consensus)) + } + + return nil +} + // IsEqual compare two chain to see whether they represent the same chain func (chain Chain) IsEqual(c Chain) bool { return chain.ChainId == c.ChainId } +// IsZetaChain returns true if the chain is a ZetaChain chain func (chain Chain) IsZetaChain() bool { return chain.Network == Network_zeta } + +// IsExternalChain returns true if the chain is an ExternalChain chain, not ZetaChain func (chain Chain) IsExternalChain() bool { return chain.IsExternal } diff --git a/pkg/chains/chain_test.go b/pkg/chains/chain_test.go index 7bbb9de679..d14fd39a37 100644 --- a/pkg/chains/chain_test.go +++ b/pkg/chains/chain_test.go @@ -11,6 +11,133 @@ import ( "github.com/stretchr/testify/require" ) +func TestChain_Validate(t *testing.T) { + tests := []struct { + name string + chain Chain + errStr string + }{ + { + name: "should pass if chain is valid", + chain: Chain{ + ChainId: 42, + ChainName: ChainName_empty, + Network: Network_optimism, + NetworkType: NetworkType_testnet, + Vm: Vm_evm, + Consensus: Consensus_op_stack, + IsExternal: true, + }, + }, + { + name: "should error if chain ID is zero", + chain: Chain{ + ChainId: 0, + ChainName: ChainName_empty, + Network: Network_optimism, + NetworkType: NetworkType_testnet, + Vm: Vm_evm, + Consensus: Consensus_op_stack, + IsExternal: true, + }, + errStr: "chain ID must be positive", + }, + { + name: "should error if chain ID is negative", + chain: Chain{ + ChainId: 0, + ChainName: ChainName_empty, + Network: Network_optimism, + NetworkType: NetworkType_testnet, + Vm: Vm_evm, + Consensus: Consensus_op_stack, + IsExternal: true, + }, + errStr: "chain ID must be positive", + }, + { + name: "should error if chain name invalid", + chain: Chain{ + ChainId: 42, + ChainName: ChainName_base_sepolia + 1, + Network: Network_optimism, + NetworkType: NetworkType_testnet, + Vm: Vm_evm, + Consensus: Consensus_op_stack, + IsExternal: true, + }, + errStr: "invalid chain name", + }, + { + name: "should error if network invalid", + chain: Chain{ + ChainId: 42, + ChainName: ChainName_empty, + Network: Network_base + 1, + NetworkType: NetworkType_testnet, + Vm: Vm_evm, + Consensus: Consensus_op_stack, + IsExternal: true, + }, + errStr: "invalid network", + }, + { + name: "should error if network type invalid", + chain: Chain{ + ChainId: 42, + ChainName: ChainName_empty, + Network: Network_base, + NetworkType: NetworkType_devnet + 1, + Vm: Vm_evm, + Consensus: Consensus_op_stack, + IsExternal: true, + }, + errStr: "invalid network type", + }, + { + name: "should error if vm invalid", + chain: Chain{ + ChainId: 42, + ChainName: ChainName_empty, + Network: Network_base, + NetworkType: NetworkType_devnet, + Vm: Vm_evm + 1, + Consensus: Consensus_op_stack, + IsExternal: true, + }, + errStr: "invalid vm", + }, + { + name: "should error if consensus invalid", + chain: Chain{ + ChainId: 42, + ChainName: ChainName_empty, + Network: Network_base, + NetworkType: NetworkType_devnet, + Vm: Vm_evm, + Consensus: Consensus_op_stack + 1, + IsExternal: true, + }, + errStr: "invalid consensus", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.errStr != "" { + require.ErrorContains(t, tt.chain.Validate(), tt.errStr) + } else { + require.NoError(t, tt.chain.Validate()) + } + }) + } + + t.Run("all default chains are valid", func(t *testing.T) { + for _, chain := range DefaultChainsList() { + require.NoError(t, chain.Validate()) + } + }) +} + func TestChain_EncodeAddress(t *testing.T) { tests := []struct { name string diff --git a/pkg/chains/chains.go b/pkg/chains/chains.go index 21718f874d..61fffece76 100644 --- a/pkg/chains/chains.go +++ b/pkg/chains/chains.go @@ -16,6 +16,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_tendermint, IsExternal: false, + CctxGateway: CCTXGateway_zevm, } // Ethereum is Ethereum mainnet @@ -27,6 +28,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_ethereum, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // BscMainnet is Binance Smart Chain mainnet @@ -38,6 +40,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_ethereum, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // BitcoinMainnet is Bitcoin mainnet @@ -49,6 +52,7 @@ var ( Vm: Vm_no_vm, Consensus: Consensus_bitcoin, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // Polygon is Polygon mainnet @@ -60,6 +64,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_ethereum, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // OptimismMainnet is Optimism mainnet @@ -71,6 +76,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_op_stack, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // BaseMainnet is Base mainnet @@ -82,6 +88,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_op_stack, IsExternal: true, + CctxGateway: CCTXGateway_observers, } /** @@ -97,6 +104,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_tendermint, IsExternal: false, + CctxGateway: CCTXGateway_zevm, } // Sepolia is Ethereum sepolia testnet @@ -108,6 +116,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_ethereum, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // BscTestnet is Binance Smart Chain testnet @@ -119,6 +128,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_ethereum, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // BitcoinTestnet is Bitcoin testnet3 @@ -130,6 +140,7 @@ var ( Vm: Vm_no_vm, Consensus: Consensus_bitcoin, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // Amoy is Polygon amoy testnet @@ -141,6 +152,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_ethereum, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // OptimismSepolia is Optimism sepolia testnet @@ -152,6 +164,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_op_stack, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // BaseSepolia is Base sepolia testnet @@ -163,6 +176,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_op_stack, IsExternal: true, + CctxGateway: CCTXGateway_observers, } /** @@ -179,6 +193,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_tendermint, IsExternal: false, + CctxGateway: CCTXGateway_zevm, } /** @@ -194,6 +209,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_tendermint, IsExternal: false, + CctxGateway: CCTXGateway_zevm, } // BitcoinRegtest is Bitcoin regtest (localnet) @@ -205,6 +221,7 @@ var ( Vm: Vm_no_vm, Consensus: Consensus_bitcoin, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // GoerliLocalnet is Ethereum local goerli (localnet) @@ -216,6 +233,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_ethereum, IsExternal: true, + CctxGateway: CCTXGateway_observers, } /** @@ -231,6 +249,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_ethereum, IsExternal: true, + CctxGateway: CCTXGateway_observers, } // Mumbai is Polygon mumbai testnet (deprecated for amoy) @@ -242,6 +261,7 @@ var ( Vm: Vm_evm, Consensus: Consensus_ethereum, IsExternal: true, + CctxGateway: CCTXGateway_observers, } ) diff --git a/pkg/chains/chains.pb.go b/pkg/chains/chains.pb.go index 1153208c6d..848a7e1bc0 100644 --- a/pkg/chains/chains.pb.go +++ b/pkg/chains/chains.pb.go @@ -269,6 +269,36 @@ func (Consensus) EnumDescriptor() ([]byte, []int) { return fileDescriptor_236b85e7bff6130d, []int{5} } +// CCTXGateway describes for the chain the gateway used to handle CCTX outbounds +type CCTXGateway int32 + +const ( + // zevm is the internal CCTX gateway to process outbound on the ZEVM and read + // inbound events from the ZEVM only used for ZetaChain chains + CCTXGateway_zevm CCTXGateway = 0 + // observers is the CCTX gateway for chains relying on the observer set to + // observe inbounds and TSS for outbounds + CCTXGateway_observers CCTXGateway = 1 +) + +var CCTXGateway_name = map[int32]string{ + 0: "zevm", + 1: "observers", +} + +var CCTXGateway_value = map[string]int32{ + "zevm": 0, + "observers": 1, +} + +func (x CCTXGateway) String() string { + return proto.EnumName(CCTXGateway_name, int32(x)) +} + +func (CCTXGateway) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_236b85e7bff6130d, []int{6} +} + // Chain represents static data about a blockchain network // it is identified by a unique chain ID type Chain struct { @@ -286,6 +316,8 @@ type Chain struct { Consensus Consensus `protobuf:"varint,6,opt,name=consensus,proto3,enum=zetachain.zetacore.pkg.chains.Consensus" json:"consensus,omitempty"` // IsExternal describe if the chain is ZetaChain or external IsExternal bool `protobuf:"varint,7,opt,name=is_external,json=isExternal,proto3" json:"is_external,omitempty"` + // CCTXGateway is the gateway used to handle CCTX outbounds + CctxGateway CCTXGateway `protobuf:"varint,8,opt,name=cctx_gateway,json=cctxGateway,proto3,enum=zetachain.zetacore.pkg.chains.CCTXGateway" json:"cctx_gateway,omitempty"` } func (m *Chain) Reset() { *m = Chain{} } @@ -370,6 +402,13 @@ func (m *Chain) GetIsExternal() bool { return false } +func (m *Chain) GetCctxGateway() CCTXGateway { + if m != nil { + return m.CctxGateway + } + return CCTXGateway_zevm +} + func init() { proto.RegisterEnum("zetachain.zetacore.pkg.chains.ReceiveStatus", ReceiveStatus_name, ReceiveStatus_value) proto.RegisterEnum("zetachain.zetacore.pkg.chains.ChainName", ChainName_name, ChainName_value) @@ -377,6 +416,7 @@ func init() { proto.RegisterEnum("zetachain.zetacore.pkg.chains.NetworkType", NetworkType_name, NetworkType_value) proto.RegisterEnum("zetachain.zetacore.pkg.chains.Vm", Vm_name, Vm_value) proto.RegisterEnum("zetachain.zetacore.pkg.chains.Consensus", Consensus_name, Consensus_value) + proto.RegisterEnum("zetachain.zetacore.pkg.chains.CCTXGateway", CCTXGateway_name, CCTXGateway_value) proto.RegisterType((*Chain)(nil), "zetachain.zetacore.pkg.chains.Chain") } @@ -385,49 +425,51 @@ func init() { } var fileDescriptor_236b85e7bff6130d = []byte{ - // 658 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0xcf, 0x6e, 0x13, 0x3b, - 0x14, 0xc6, 0x33, 0x93, 0xff, 0x27, 0x69, 0xea, 0xeb, 0x76, 0x91, 0x5b, 0xe9, 0xce, 0xed, 0xbd, - 0x0b, 0x14, 0x22, 0x91, 0x08, 0x58, 0xb2, 0x41, 0x54, 0x14, 0x81, 0x44, 0x17, 0x03, 0xaa, 0x04, - 0x9b, 0x68, 0xe2, 0x1c, 0x26, 0x56, 0x62, 0x7b, 0x34, 0x76, 0x02, 0xe1, 0x29, 0x58, 0xf2, 0x00, - 0x2c, 0x78, 0x14, 0x96, 0x5d, 0xb2, 0x44, 0xed, 0x03, 0xf0, 0x0a, 0xc8, 0xce, 0x78, 0x02, 0x0b, - 0x68, 0x57, 0x73, 0xfc, 0x9b, 0xef, 0x7c, 0xe7, 0xd8, 0x3e, 0x32, 0x0c, 0xdf, 0xa3, 0x49, 0xd8, - 0x3c, 0xe1, 0x72, 0xec, 0x22, 0x95, 0xe3, 0x38, 0x5b, 0xa4, 0x63, 0x87, 0x74, 0xf1, 0x19, 0x65, - 0xb9, 0x32, 0x8a, 0xfe, 0x53, 0x6a, 0x47, 0x5e, 0x3b, 0xca, 0x16, 0xe9, 0x68, 0x2b, 0x3a, 0x3a, - 0x4c, 0x55, 0xaa, 0x9c, 0x72, 0x6c, 0xa3, 0x6d, 0xd2, 0xff, 0x1f, 0xab, 0x50, 0x3f, 0xb1, 0x02, - 0xfa, 0x37, 0xb4, 0x9c, 0x72, 0xc2, 0x67, 0xfd, 0xf0, 0x38, 0x18, 0x54, 0xe3, 0xa6, 0x5b, 0x3f, - 0x9d, 0xd1, 0x27, 0x00, 0xdb, 0x5f, 0x32, 0x11, 0xd8, 0x0f, 0x8e, 0x83, 0x41, 0xef, 0xde, 0x60, - 0xf4, 0xc7, 0x72, 0x23, 0x67, 0x7a, 0x96, 0x08, 0x8c, 0xdb, 0xcc, 0x87, 0xf4, 0x21, 0x34, 0x25, - 0x9a, 0xb7, 0x2a, 0x5f, 0xf4, 0xab, 0xce, 0xe5, 0xd6, 0x35, 0x2e, 0x67, 0x5b, 0x75, 0xec, 0xd3, - 0xe8, 0x73, 0xe8, 0x16, 0xe1, 0xc4, 0x6c, 0x32, 0xec, 0xd7, 0x9c, 0xcd, 0xf0, 0x66, 0x36, 0x2f, - 0x37, 0x19, 0xc6, 0x1d, 0xb9, 0x5b, 0xd0, 0xbb, 0x10, 0xae, 0x45, 0xbf, 0xee, 0x4c, 0xfe, 0xbb, - 0xc6, 0xe4, 0x5c, 0xc4, 0xe1, 0x5a, 0xd0, 0x53, 0x68, 0x33, 0x25, 0x35, 0x4a, 0xbd, 0xd2, 0xfd, - 0xc6, 0xcd, 0xce, 0xc2, 0xeb, 0xe3, 0x5d, 0x2a, 0xfd, 0x17, 0x3a, 0x5c, 0x4f, 0xf0, 0x9d, 0xc1, - 0x5c, 0x26, 0xcb, 0x7e, 0xf3, 0x38, 0x18, 0xb4, 0x62, 0xe0, 0xfa, 0x71, 0x41, 0x86, 0x0f, 0x60, - 0x2f, 0x46, 0x86, 0x7c, 0x8d, 0x2f, 0x4c, 0x62, 0x56, 0x9a, 0x76, 0xa0, 0xc9, 0x72, 0x4c, 0x0c, - 0xce, 0x48, 0xc5, 0x2e, 0xf4, 0x8a, 0x31, 0xd4, 0x9a, 0x04, 0x14, 0xa0, 0xf1, 0x26, 0xe1, 0x4b, - 0x9c, 0x91, 0xf0, 0xa8, 0xf6, 0xf9, 0x53, 0x14, 0x0c, 0xbf, 0x87, 0xd0, 0x2e, 0xaf, 0x80, 0xb6, - 0xa1, 0x8e, 0x22, 0x33, 0x1b, 0x52, 0xa1, 0xfb, 0xd0, 0x41, 0x33, 0x9f, 0x88, 0x84, 0x4b, 0x89, - 0x86, 0x04, 0x94, 0x40, 0xd7, 0xf6, 0x5c, 0x92, 0xd0, 0x4a, 0xa6, 0x86, 0x95, 0xa0, 0x4a, 0x0f, - 0x60, 0x3f, 0x53, 0xcb, 0x4d, 0xaa, 0x64, 0x09, 0x6b, 0x4e, 0xa5, 0x77, 0xaa, 0x3a, 0xa5, 0xd0, - 0x4b, 0x15, 0xe6, 0x4b, 0x3e, 0x31, 0xa8, 0x8d, 0x65, 0x0d, 0xcb, 0xc4, 0x4a, 0x4c, 0x93, 0x1d, - 0x6b, 0xfa, 0x44, 0x0f, 0xa0, 0xec, 0xc0, 0x93, 0x8e, 0xef, 0xc0, 0x83, 0xae, 0xed, 0x40, 0x63, - 0xa6, 0x96, 0x7c, 0xa7, 0xda, 0xb3, 0xb0, 0x28, 0xb8, 0x54, 0x2c, 0x59, 0x5a, 0xd8, 0xf3, 0xa9, - 0x39, 0xa6, 0x56, 0x48, 0xf6, 0xad, 0x7b, 0x22, 0xd4, 0xa6, 0xcc, 0x23, 0xf4, 0x10, 0x88, 0xca, - 0x0c, 0x17, 0x5c, 0x8b, 0xb2, 0xfd, 0xbf, 0x7e, 0xa1, 0x45, 0x2d, 0x42, 0x6d, 0xf6, 0x34, 0xd1, - 0x58, 0xea, 0x0e, 0x4a, 0xe2, 0x35, 0x87, 0xc5, 0x89, 0xbf, 0x82, 0x66, 0x31, 0x66, 0xb4, 0x09, - 0x55, 0x34, 0x73, 0x52, 0xa1, 0x2d, 0xa8, 0xd9, 0x9d, 0x91, 0xc0, 0xa2, 0xa9, 0x61, 0x24, 0xb4, - 0xf7, 0x56, 0x9c, 0x25, 0xa9, 0x3a, 0xaa, 0x19, 0xa9, 0xd1, 0x2e, 0xb4, 0x7c, 0x71, 0x52, 0xb7, - 0x69, 0xb6, 0x04, 0x69, 0x14, 0xd6, 0xa7, 0xd0, 0xf9, 0x69, 0x82, 0xad, 0x85, 0x6f, 0xc7, 0xcd, - 0x81, 0xdf, 0x59, 0xe0, 0xcc, 0x73, 0xbe, 0xde, 0x5e, 0x23, 0x40, 0x63, 0x86, 0x2e, 0xae, 0x16, - 0x3e, 0x11, 0x84, 0xe7, 0xc2, 0x0e, 0x83, 0x54, 0x93, 0xb5, 0x20, 0x15, 0xd7, 0xe8, 0x5a, 0x90, - 0xa0, 0xf8, 0xff, 0x0c, 0xda, 0xe5, 0xa8, 0xda, 0x96, 0xd0, 0xcc, 0x31, 0xc7, 0x95, 0x55, 0xf6, - 0x00, 0x0c, 0xca, 0x19, 0xe6, 0x82, 0xcb, 0xa2, 0xd2, 0x94, 0x1b, 0xa6, 0xb8, 0x24, 0xe1, 0xb6, - 0xfb, 0x89, 0x36, 0x09, 0x5b, 0xf8, 0x5a, 0x8f, 0x4e, 0xbe, 0x5c, 0x46, 0xc1, 0xc5, 0x65, 0x14, - 0x7c, 0xbb, 0x8c, 0x82, 0x0f, 0x57, 0x51, 0xe5, 0xe2, 0x2a, 0xaa, 0x7c, 0xbd, 0x8a, 0x2a, 0xaf, - 0x6f, 0xa7, 0xdc, 0xcc, 0x57, 0xd3, 0x11, 0x53, 0xc2, 0x3d, 0x6a, 0x77, 0x7e, 0xfb, 0xbe, 0x4d, - 0x1b, 0xee, 0x91, 0xba, 0xff, 0x23, 0x00, 0x00, 0xff, 0xff, 0x15, 0x2a, 0x93, 0x8e, 0x07, 0x05, - 0x00, 0x00, + // 704 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x3d, 0x8f, 0x2b, 0x35, + 0x14, 0xcd, 0x4c, 0xbe, 0xef, 0x64, 0xb3, 0xc6, 0x6f, 0x8b, 0xe1, 0x49, 0x0c, 0x0b, 0x05, 0x0a, + 0x11, 0x24, 0x02, 0x4a, 0x1a, 0x44, 0xc4, 0x7b, 0x02, 0x89, 0x57, 0x0c, 0xab, 0x15, 0xd0, 0x8c, + 0x3c, 0xce, 0x65, 0x62, 0x25, 0x1e, 0x8f, 0xc6, 0x4e, 0x76, 0xc3, 0xaf, 0xe0, 0x47, 0x50, 0xf0, + 0x53, 0x28, 0xb7, 0xa4, 0x44, 0xbb, 0x05, 0x25, 0x7f, 0x01, 0xd9, 0xf3, 0x91, 0xa5, 0x80, 0xdd, + 0x2a, 0xd7, 0x67, 0xce, 0x39, 0xf7, 0xd8, 0xbe, 0x31, 0xcc, 0x7f, 0x46, 0xc3, 0xf8, 0x86, 0x89, + 0x7c, 0xe9, 0x2a, 0x55, 0xe2, 0xb2, 0xd8, 0x66, 0x4b, 0x07, 0xe9, 0xfa, 0x67, 0x51, 0x94, 0xca, + 0x28, 0xfa, 0x4e, 0xcb, 0x5d, 0x34, 0xdc, 0x45, 0xb1, 0xcd, 0x16, 0x15, 0xe9, 0xe5, 0x45, 0xa6, + 0x32, 0xe5, 0x98, 0x4b, 0x5b, 0x55, 0xa2, 0xf7, 0xff, 0xea, 0x42, 0x7f, 0x65, 0x09, 0xf4, 0x6d, + 0x18, 0x39, 0x66, 0x22, 0xd6, 0xa1, 0x7f, 0xe9, 0xcd, 0xba, 0xf1, 0xd0, 0xad, 0xbf, 0x5e, 0xd3, + 0xd7, 0x00, 0xd5, 0xa7, 0x9c, 0x49, 0x0c, 0xbd, 0x4b, 0x6f, 0x36, 0xfd, 0x74, 0xb6, 0xf8, 0xdf, + 0x76, 0x0b, 0x67, 0xfa, 0x86, 0x49, 0x8c, 0xc7, 0xbc, 0x29, 0xe9, 0x17, 0x30, 0xcc, 0xd1, 0xdc, + 0xa8, 0x72, 0x1b, 0x76, 0x9d, 0xcb, 0x07, 0x4f, 0xb8, 0xbc, 0xa9, 0xd8, 0x71, 0x23, 0xa3, 0xdf, + 0xc2, 0xa4, 0x2e, 0x13, 0x73, 0x2c, 0x30, 0xec, 0x39, 0x9b, 0xf9, 0xf3, 0x6c, 0xae, 0x8e, 0x05, + 0xc6, 0x41, 0x7e, 0x5a, 0xd0, 0x4f, 0xc0, 0x3f, 0xc8, 0xb0, 0xef, 0x4c, 0xde, 0x7b, 0xc2, 0xe4, + 0x5a, 0xc6, 0xfe, 0x41, 0xd2, 0x57, 0x30, 0xe6, 0x2a, 0xd7, 0x98, 0xeb, 0xbd, 0x0e, 0x07, 0xcf, + 0x3b, 0x8b, 0x86, 0x1f, 0x9f, 0xa4, 0xf4, 0x5d, 0x08, 0x84, 0x4e, 0xf0, 0xd6, 0x60, 0x99, 0xb3, + 0x5d, 0x38, 0xbc, 0xf4, 0x66, 0xa3, 0x18, 0x84, 0xfe, 0xaa, 0x46, 0xec, 0x56, 0x39, 0x37, 0xb7, + 0x49, 0xc6, 0x0c, 0xde, 0xb0, 0x63, 0x38, 0x7a, 0xd6, 0x56, 0x57, 0xab, 0xab, 0xef, 0x5f, 0x57, + 0x8a, 0x38, 0xb0, 0xfa, 0x7a, 0x31, 0xff, 0x1c, 0xce, 0x62, 0xe4, 0x28, 0x0e, 0xf8, 0x9d, 0x61, + 0x66, 0xaf, 0x69, 0x00, 0x43, 0x5e, 0x22, 0x33, 0xb8, 0x26, 0x1d, 0xbb, 0xd0, 0x7b, 0xce, 0x51, + 0x6b, 0xe2, 0x51, 0x80, 0xc1, 0x4f, 0x4c, 0xec, 0x70, 0x4d, 0xfc, 0x97, 0xbd, 0xdf, 0x7e, 0x8d, + 0xbc, 0xf9, 0xdf, 0x3e, 0x8c, 0xdb, 0x1b, 0xa5, 0x63, 0xe8, 0xa3, 0x2c, 0xcc, 0x91, 0x74, 0xe8, + 0x39, 0x04, 0x68, 0x36, 0x89, 0x64, 0x22, 0xcf, 0xd1, 0x10, 0x8f, 0x12, 0x98, 0xd8, 0x58, 0x2d, + 0xe2, 0x5b, 0x4a, 0x6a, 0x78, 0x0b, 0x74, 0xe9, 0x0b, 0x38, 0x2f, 0xd4, 0xee, 0x98, 0xa9, 0xbc, + 0x05, 0x7b, 0x8e, 0xa5, 0x4f, 0xac, 0x3e, 0xa5, 0x30, 0xcd, 0x14, 0x96, 0x3b, 0x91, 0x18, 0xd4, + 0xc6, 0x62, 0x03, 0x8b, 0xc9, 0xbd, 0x4c, 0xd9, 0x09, 0x1b, 0x36, 0xc2, 0x06, 0x80, 0x36, 0x41, + 0x83, 0x04, 0x4d, 0x82, 0x06, 0x98, 0xd8, 0x04, 0x1a, 0x0b, 0xb5, 0x13, 0x27, 0xd6, 0x99, 0x05, + 0xeb, 0x86, 0x3b, 0xc5, 0xd9, 0xce, 0x82, 0xd3, 0x46, 0x5a, 0x62, 0x66, 0x89, 0xe4, 0xdc, 0xba, + 0x33, 0xa9, 0x8e, 0xad, 0x8e, 0xd0, 0x0b, 0x20, 0xaa, 0x30, 0x42, 0x0a, 0x2d, 0xdb, 0xf8, 0x6f, + 0xfd, 0x0b, 0xad, 0x7b, 0x11, 0x6a, 0xd5, 0x29, 0xd3, 0xd8, 0xf2, 0x5e, 0xb4, 0x48, 0xc3, 0xb9, + 0xa8, 0x4f, 0xfc, 0x07, 0x18, 0xd6, 0x53, 0x4b, 0x87, 0xd0, 0x45, 0xb3, 0x21, 0x1d, 0x3a, 0x82, + 0x9e, 0xdd, 0x19, 0xf1, 0x2c, 0x94, 0x1a, 0x4e, 0x7c, 0x7b, 0x6f, 0xf5, 0x59, 0x92, 0xae, 0x43, + 0x35, 0x27, 0x3d, 0x3a, 0x81, 0x51, 0xd3, 0x9c, 0xf4, 0xad, 0xcc, 0xb6, 0x20, 0x83, 0xda, 0xfa, + 0x15, 0x04, 0x8f, 0xfe, 0x10, 0xd6, 0xa2, 0x89, 0xe3, 0xe6, 0xa0, 0xd9, 0x99, 0xe7, 0xcc, 0x4b, + 0x71, 0xa8, 0xae, 0x11, 0x60, 0xb0, 0x46, 0x57, 0x77, 0x6b, 0x9f, 0x08, 0xfc, 0x6b, 0x69, 0x87, + 0x21, 0x57, 0xc9, 0x41, 0x92, 0x8e, 0x0b, 0x7a, 0x90, 0xc4, 0xab, 0xbf, 0x7f, 0x03, 0xe3, 0x76, + 0xf2, 0x6d, 0x24, 0x34, 0x1b, 0x2c, 0x71, 0x6f, 0x99, 0x53, 0x00, 0x83, 0xf9, 0x1a, 0x4b, 0x29, + 0xf2, 0xba, 0x53, 0x2a, 0x0c, 0x57, 0x22, 0x27, 0x7e, 0x95, 0x3e, 0xd1, 0x86, 0xf1, 0x6d, 0xdb, + 0xeb, 0x23, 0x08, 0x1e, 0x4d, 0x76, 0x75, 0x12, 0xae, 0xe7, 0x19, 0x8c, 0x55, 0xaa, 0xb1, 0x3c, + 0x60, 0xa9, 0x9b, 0xce, 0x5f, 0xae, 0x7e, 0xbf, 0x8f, 0xbc, 0xbb, 0xfb, 0xc8, 0xfb, 0xf3, 0x3e, + 0xf2, 0x7e, 0x79, 0x88, 0x3a, 0x77, 0x0f, 0x51, 0xe7, 0x8f, 0x87, 0xa8, 0xf3, 0xe3, 0x87, 0x99, + 0x30, 0x9b, 0x7d, 0xba, 0xe0, 0x4a, 0xba, 0x17, 0xf5, 0xe3, 0xff, 0x7c, 0x5c, 0xd3, 0x81, 0x7b, + 0x21, 0x3f, 0xfb, 0x27, 0x00, 0x00, 0xff, 0xff, 0x05, 0xa7, 0x7f, 0x40, 0x84, 0x05, 0x00, 0x00, } func (m *Chain) Marshal() (dAtA []byte, err error) { @@ -450,6 +492,11 @@ func (m *Chain) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.CctxGateway != 0 { + i = encodeVarintChains(dAtA, i, uint64(m.CctxGateway)) + i-- + dAtA[i] = 0x40 + } if m.IsExternal { i-- if m.IsExternal { @@ -531,6 +578,9 @@ func (m *Chain) Size() (n int) { if m.IsExternal { n += 2 } + if m.CctxGateway != 0 { + n += 1 + sovChains(uint64(m.CctxGateway)) + } return n } @@ -703,6 +753,25 @@ func (m *Chain) Unmarshal(dAtA []byte) error { } } m.IsExternal = bool(v != 0) + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CctxGateway", wireType) + } + m.CctxGateway = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChains + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CctxGateway |= CCTXGateway(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipChains(dAtA[iNdEx:]) diff --git a/proto/zetachain/zetacore/authority/chain_info.proto b/proto/zetachain/zetacore/authority/chain_info.proto new file mode 100644 index 0000000000..f417184b06 --- /dev/null +++ b/proto/zetachain/zetacore/authority/chain_info.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +package zetachain.zetacore.authority; + +import "zetachain/zetacore/pkg/chains/chains.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/zeta-chain/zetacore/x/authority/types"; + +// ChainInfo contains static information about the chains +// This structure is used to dynamically update these info on a live network +// before hardcoding the values in a upgrade +message ChainInfo { + repeated pkg.chains.Chain chains = 1 [ (gogoproto.nullable) = false ]; +} \ No newline at end of file diff --git a/proto/zetachain/zetacore/authority/genesis.proto b/proto/zetachain/zetacore/authority/genesis.proto index e508fa5746..4f7b238aca 100644 --- a/proto/zetachain/zetacore/authority/genesis.proto +++ b/proto/zetachain/zetacore/authority/genesis.proto @@ -3,6 +3,7 @@ package zetachain.zetacore.authority; import "zetachain/zetacore/authority/policies.proto"; import "zetachain/zetacore/authority/authorization.proto"; +import "zetachain/zetacore/authority/chain_info.proto"; import "gogoproto/gogo.proto"; option go_package = "github.com/zeta-chain/zetacore/x/authority/types"; @@ -11,4 +12,5 @@ option go_package = "github.com/zeta-chain/zetacore/x/authority/types"; message GenesisState { Policies policies = 1 [ (gogoproto.nullable) = false ]; AuthorizationList authorization_list = 2 [ (gogoproto.nullable) = false ]; + ChainInfo chain_info = 3 [ (gogoproto.nullable) = false ]; } diff --git a/proto/zetachain/zetacore/pkg/chains/chains.proto b/proto/zetachain/zetacore/pkg/chains/chains.proto index 1f2279af35..8075822471 100644 --- a/proto/zetachain/zetacore/pkg/chains/chains.proto +++ b/proto/zetachain/zetacore/pkg/chains/chains.proto @@ -88,6 +88,19 @@ enum Consensus { op_stack = 3; } +// CCTXGateway describes for the chain the gateway used to handle CCTX outbounds +enum CCTXGateway { + option (gogoproto.goproto_enum_stringer) = true; + + // zevm is the internal CCTX gateway to process outbound on the ZEVM and read + // inbound events from the ZEVM only used for ZetaChain chains + zevm = 0; + + // observers is the CCTX gateway for chains relying on the observer set to + // observe inbounds and TSS for outbounds + observers = 1; +} + // Chain represents static data about a blockchain network // it is identified by a unique chain ID message Chain { @@ -111,4 +124,7 @@ message Chain { // IsExternal describe if the chain is ZetaChain or external bool is_external = 7; + + // CCTXGateway is the gateway used to handle CCTX outbounds + CCTXGateway cctx_gateway = 8; } diff --git a/testutil/sample/authority.go b/testutil/sample/authority.go index ef92db0f94..c7e3b7e6b8 100644 --- a/testutil/sample/authority.go +++ b/testutil/sample/authority.go @@ -3,6 +3,7 @@ package sample import ( "fmt" + "github.com/zeta-chain/zetacore/pkg/chains" authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" ) @@ -25,6 +26,20 @@ func Policies() authoritytypes.Policies { } } +func ChainInfo(startChainID int64) authoritytypes.ChainInfo { + chain1 := Chain(startChainID) + chain2 := Chain(startChainID + 1) + chain3 := Chain(startChainID + 2) + + return authoritytypes.ChainInfo{ + Chains: []chains.Chain{ + *chain1, + *chain2, + *chain3, + }, + } +} + func AuthorizationList(val string) authoritytypes.AuthorizationList { return authoritytypes.AuthorizationList{ Authorizations: []authoritytypes.Authorization{ diff --git a/testutil/sample/sample.go b/testutil/sample/sample.go index 411c6dd7c9..431d93337d 100644 --- a/testutil/sample/sample.go +++ b/testutil/sample/sample.go @@ -121,9 +121,20 @@ func GenDoc(t *testing.T) *types.GenesisDoc { func Chain(chainID int64) *chains.Chain { r := newRandFromSeed(chainID) + chainNameLen := len(chains.ChainName_name) + networkLen := len(chains.Network_name) + networkTypeLen := len(chains.NetworkType_name) + vmLen := len(chains.Vm_name) + consensusLen := len(chains.Consensus_name) + return &chains.Chain{ - ChainName: chains.ChainName(r.Intn(4)), - ChainId: chainID, + ChainId: chainID, + ChainName: chains.ChainName(r.Intn(chainNameLen)), + Network: chains.Network(r.Intn(networkLen)), + NetworkType: chains.NetworkType(r.Intn(networkTypeLen)), + Vm: chains.Vm(r.Intn(vmLen)), + Consensus: chains.Consensus(r.Intn(consensusLen)), + IsExternal: true, } } diff --git a/typescript/zetachain/zetacore/authority/chain_info_pb.d.ts b/typescript/zetachain/zetacore/authority/chain_info_pb.d.ts new file mode 100644 index 0000000000..49437eb7e2 --- /dev/null +++ b/typescript/zetachain/zetacore/authority/chain_info_pb.d.ts @@ -0,0 +1,37 @@ +// @generated by protoc-gen-es v1.3.0 with parameter "target=dts" +// @generated from file zetachain/zetacore/authority/chain_info.proto (package zetachain.zetacore.authority, syntax proto3) +/* eslint-disable */ +// @ts-nocheck + +import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; +import { Message, proto3 } from "@bufbuild/protobuf"; +import type { Chain } from "../pkg/chains/chains_pb.js"; + +/** + * ChainInfo contains static information about the chains + * This structure is used to dynamically update these info on a live network + * before hardcoding the values in a upgrade + * + * @generated from message zetachain.zetacore.authority.ChainInfo + */ +export declare class ChainInfo extends Message { + /** + * @generated from field: repeated zetachain.zetacore.pkg.chains.Chain chains = 1; + */ + chains: Chain[]; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.authority.ChainInfo"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): ChainInfo; + + static fromJson(jsonValue: JsonValue, options?: Partial): ChainInfo; + + static fromJsonString(jsonString: string, options?: Partial): ChainInfo; + + static equals(a: ChainInfo | PlainMessage | undefined, b: ChainInfo | PlainMessage | undefined): boolean; +} + diff --git a/typescript/zetachain/zetacore/authority/genesis_pb.d.ts b/typescript/zetachain/zetacore/authority/genesis_pb.d.ts index 69c965b7e1..1bd7878edb 100644 --- a/typescript/zetachain/zetacore/authority/genesis_pb.d.ts +++ b/typescript/zetachain/zetacore/authority/genesis_pb.d.ts @@ -7,6 +7,7 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialM import { Message, proto3 } from "@bufbuild/protobuf"; import type { Policies } from "./policies_pb.js"; import type { AuthorizationList } from "./authorization_pb.js"; +import type { ChainInfo } from "./chain_info_pb.js"; /** * GenesisState defines the authority module's genesis state. @@ -24,6 +25,11 @@ export declare class GenesisState extends Message { */ authorizationList?: AuthorizationList; + /** + * @generated from field: zetachain.zetacore.authority.ChainInfo chain_info = 3; + */ + chainInfo?: ChainInfo; + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; diff --git a/typescript/zetachain/zetacore/authority/index.d.ts b/typescript/zetachain/zetacore/authority/index.d.ts index b129207549..6978a3b26c 100644 --- a/typescript/zetachain/zetacore/authority/index.d.ts +++ b/typescript/zetachain/zetacore/authority/index.d.ts @@ -1,4 +1,5 @@ export * from "./authorization_pb"; +export * from "./chain_info_pb"; export * from "./genesis_pb"; export * from "./policies_pb"; export * from "./query_pb"; diff --git a/typescript/zetachain/zetacore/pkg/chains/chains_pb.d.ts b/typescript/zetachain/zetacore/pkg/chains/chains_pb.d.ts index 6abe26cd04..782e669d43 100644 --- a/typescript/zetachain/zetacore/pkg/chains/chains_pb.d.ts +++ b/typescript/zetachain/zetacore/pkg/chains/chains_pb.d.ts @@ -253,6 +253,29 @@ export declare enum Consensus { op_stack = 3, } +/** + * CCTXGateway describes for the chain the gateway used to handle CCTX outbounds + * + * @generated from enum zetachain.zetacore.pkg.chains.CCTXGateway + */ +export declare enum CCTXGateway { + /** + * zevm is the internal CCTX gateway to process outbound on the ZEVM and read + * inbound events from the ZEVM only used for ZetaChain chains + * + * @generated from enum value: zevm = 0; + */ + zevm = 0, + + /** + * observers is the CCTX gateway for chains relying on the observer set to + * observe inbounds and TSS for outbounds + * + * @generated from enum value: observers = 1; + */ + observers = 1, +} + /** * Chain represents static data about a blockchain network * it is identified by a unique chain ID @@ -309,6 +332,13 @@ export declare class Chain extends Message { */ isExternal: boolean; + /** + * CCTXGateway is the gateway used to handle CCTX outbounds + * + * @generated from field: zetachain.zetacore.pkg.chains.CCTXGateway cctx_gateway = 8; + */ + cctxGateway: CCTXGateway; + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; diff --git a/x/authority/genesis.go b/x/authority/genesis.go index adcaeaed29..a1bd59abb0 100644 --- a/x/authority/genesis.go +++ b/x/authority/genesis.go @@ -10,6 +10,7 @@ import ( // InitGenesis initializes the authority module's state from a provided genesis state func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { k.SetPolicies(ctx, genState.Policies) + k.SetChainInfo(ctx, genState.ChainInfo) err := k.SetAuthorizationList(ctx, genState.AuthorizationList) if err != nil { ctx.Logger().Error("Failed to set authorization list in InitGenesis", "error", err) @@ -29,5 +30,10 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { genesis.AuthorizationList = authorizationList } + chainInfo, found := k.GetChainInfo(ctx) + if found { + genesis.ChainInfo = chainInfo + } + return &genesis } diff --git a/x/authority/genesis_test.go b/x/authority/genesis_test.go index 5ab91da960..4bdf82d82c 100644 --- a/x/authority/genesis_test.go +++ b/x/authority/genesis_test.go @@ -16,6 +16,7 @@ func TestGenesis(t *testing.T) { genesisState := types.GenesisState{ Policies: sample.Policies(), AuthorizationList: sample.AuthorizationList("sample"), + ChainInfo: sample.ChainInfo(42), } // Init @@ -32,6 +33,11 @@ func TestGenesis(t *testing.T) { require.True(t, found) require.Equal(t, genesisState.AuthorizationList, authorizationList) + // Check chain info is set + chainInfo, found := k.GetChainInfo(ctx) + require.True(t, found) + require.Equal(t, genesisState.ChainInfo, chainInfo) + // Export got := authority.ExportGenesis(ctx, *k) require.NotNil(t, got) diff --git a/x/authority/keeper/chain_info.go b/x/authority/keeper/chain_info.go new file mode 100644 index 0000000000..5c9056fe0c --- /dev/null +++ b/x/authority/keeper/chain_info.go @@ -0,0 +1,26 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/zeta-chain/zetacore/x/authority/types" +) + +// SetChainInfo sets the chain info to the store +func (k Keeper) SetChainInfo(ctx sdk.Context, chainInfo types.ChainInfo) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ChainInfoKey)) + b := k.cdc.MustMarshal(&chainInfo) + store.Set([]byte{0}, b) +} + +// GetChainInfo returns the policies from the store +func (k Keeper) GetChainInfo(ctx sdk.Context) (val types.ChainInfo, found bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.ChainInfoKey)) + b := store.Get([]byte{0}) + if b == nil { + return val, false + } + k.cdc.MustUnmarshal(b, &val) + return val, true +} diff --git a/x/authority/keeper/chain_info_test.go b/x/authority/keeper/chain_info_test.go new file mode 100644 index 0000000000..87424cb4dd --- /dev/null +++ b/x/authority/keeper/chain_info_test.go @@ -0,0 +1,33 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" +) + +func TestKeeper_SetChainInfo(t *testing.T) { + k, ctx := keepertest.AuthorityKeeper(t) + chainInfo := sample.ChainInfo(42) + + _, found := k.GetChainInfo(ctx) + require.False(t, found) + + k.SetChainInfo(ctx, chainInfo) + + // Check policy is set + got, found := k.GetChainInfo(ctx) + require.True(t, found) + require.Equal(t, chainInfo, got) + + // Can set policies again + newChainInfo := sample.ChainInfo(84) + require.NotEqual(t, chainInfo, newChainInfo) + k.SetChainInfo(ctx, newChainInfo) + got, found = k.GetChainInfo(ctx) + require.True(t, found) + require.Equal(t, newChainInfo, got) +} diff --git a/x/authority/types/authorizations_test.go b/x/authority/types/authorizations_test.go index 3a95f5c224..116c7f2769 100644 --- a/x/authority/types/authorizations_test.go +++ b/x/authority/types/authorizations_test.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/testutil/sample" "github.com/zeta-chain/zetacore/x/authority/types" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" @@ -183,6 +184,10 @@ func TestDefaultAuthorizationsList(t *testing.T) { require.NoError(t, err) require.Equal(t, types.PolicyType_groupAdmin, policy) } - require.Len(t, defaultList.Authorizations, len(OperationalPolicyMessageList)+len(EmergencyPolicyMessageList)+len(AdminPolicyMessageList)) + require.Len( + t, + defaultList.Authorizations, + len(OperationalPolicyMessageList)+len(EmergencyPolicyMessageList)+len(AdminPolicyMessageList), + ) }) } diff --git a/x/authority/types/chain_info.go b/x/authority/types/chain_info.go new file mode 100644 index 0000000000..cff10235c4 --- /dev/null +++ b/x/authority/types/chain_info.go @@ -0,0 +1,30 @@ +package types + +import ( + "fmt" + + "github.com/zeta-chain/zetacore/pkg/chains" +) + +// DefaultChainInfo returns the structure with an empty list of chains +func DefaultChainInfo() ChainInfo { + return ChainInfo{ + Chains: []chains.Chain{}, + } +} + +// Validate performs basic validation of chain info +// It checks all chains are valid and they're all of external type +// The structure is used to store external chain information +func (ci ChainInfo) Validate() error { + for _, chain := range ci.Chains { + if err := chain.Validate(); err != nil { + return err + } + if !chain.IsExternal { + return fmt.Errorf("chain %d is not external", chain.ChainId) + } + } + + return nil +} diff --git a/x/authority/types/chain_info.pb.go b/x/authority/types/chain_info.pb.go new file mode 100644 index 0000000000..9dd945040e --- /dev/null +++ b/x/authority/types/chain_info.pb.go @@ -0,0 +1,335 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: zetachain/zetacore/authority/chain_info.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + chains "github.com/zeta-chain/zetacore/pkg/chains" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// ChainInfo contains static information about the chains +// This structure is used to dynamically update these info on a live network +// before hardcoding the values in a upgrade +type ChainInfo struct { + Chains []chains.Chain `protobuf:"bytes,1,rep,name=chains,proto3" json:"chains"` +} + +func (m *ChainInfo) Reset() { *m = ChainInfo{} } +func (m *ChainInfo) String() string { return proto.CompactTextString(m) } +func (*ChainInfo) ProtoMessage() {} +func (*ChainInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_88c7b2261e38c0a9, []int{0} +} +func (m *ChainInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ChainInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ChainInfo.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ChainInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChainInfo.Merge(m, src) +} +func (m *ChainInfo) XXX_Size() int { + return m.Size() +} +func (m *ChainInfo) XXX_DiscardUnknown() { + xxx_messageInfo_ChainInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_ChainInfo proto.InternalMessageInfo + +func (m *ChainInfo) GetChains() []chains.Chain { + if m != nil { + return m.Chains + } + return nil +} + +func init() { + proto.RegisterType((*ChainInfo)(nil), "zetachain.zetacore.authority.ChainInfo") +} + +func init() { + proto.RegisterFile("zetachain/zetacore/authority/chain_info.proto", fileDescriptor_88c7b2261e38c0a9) +} + +var fileDescriptor_88c7b2261e38c0a9 = []byte{ + // 206 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0xad, 0x4a, 0x2d, 0x49, + 0x4c, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x07, 0xb3, 0xf2, 0x8b, 0x52, 0xf5, 0x13, 0x4b, 0x4b, 0x32, + 0xf2, 0x8b, 0x32, 0x4b, 0x2a, 0xf5, 0xc1, 0x12, 0xf1, 0x99, 0x79, 0x69, 0xf9, 0x7a, 0x05, 0x45, + 0xf9, 0x25, 0xf9, 0x42, 0x32, 0x70, 0xe5, 0x7a, 0x30, 0xe5, 0x7a, 0x70, 0xe5, 0x52, 0x5a, 0x58, + 0x0c, 0x2b, 0xc8, 0x4e, 0x87, 0x18, 0x53, 0x0c, 0xa5, 0x20, 0x26, 0x49, 0x89, 0xa4, 0xe7, 0xa7, + 0xe7, 0x83, 0x99, 0xfa, 0x20, 0x16, 0x44, 0x54, 0xc9, 0x9f, 0x8b, 0xd3, 0x19, 0xa4, 0xca, 0x33, + 0x2f, 0x2d, 0x5f, 0xc8, 0x89, 0x8b, 0x0d, 0xa2, 0x45, 0x82, 0x51, 0x81, 0x59, 0x83, 0xdb, 0x48, + 0x45, 0x0f, 0x8b, 0xed, 0x05, 0xd9, 0xe9, 0x7a, 0x50, 0x83, 0xc1, 0x3a, 0x9d, 0x58, 0x4e, 0xdc, + 0x93, 0x67, 0x08, 0x82, 0xea, 0x74, 0xf2, 0x3a, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, + 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, + 0x86, 0x28, 0x83, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0xb0, 0x6b, 0x75, + 0xd1, 0x1c, 0x5e, 0x81, 0x14, 0x0e, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0x60, 0x37, 0x1a, + 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x16, 0x2c, 0xe3, 0x34, 0x01, 0x00, 0x00, +} + +func (m *ChainInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ChainInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ChainInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Chains) > 0 { + for iNdEx := len(m.Chains) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Chains[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintChainInfo(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintChainInfo(dAtA []byte, offset int, v uint64) int { + offset -= sovChainInfo(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ChainInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Chains) > 0 { + for _, e := range m.Chains { + l = e.Size() + n += 1 + l + sovChainInfo(uint64(l)) + } + } + return n +} + +func sovChainInfo(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozChainInfo(x uint64) (n int) { + return sovChainInfo(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ChainInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChainInfo + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ChainInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ChainInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Chains", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChainInfo + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthChainInfo + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthChainInfo + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Chains = append(m.Chains, chains.Chain{}) + if err := m.Chains[len(m.Chains)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipChainInfo(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthChainInfo + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipChainInfo(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowChainInfo + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowChainInfo + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowChainInfo + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthChainInfo + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupChainInfo + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthChainInfo + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthChainInfo = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowChainInfo = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupChainInfo = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/authority/types/chain_info_test.go b/x/authority/types/chain_info_test.go new file mode 100644 index 0000000000..dd43b4064f --- /dev/null +++ b/x/authority/types/chain_info_test.go @@ -0,0 +1,79 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/zeta-chain/zetacore/pkg/chains" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/authority/types" +) + +func TestDefaultChainInfo(t *testing.T) { + t.Run("default is empty", func(t *testing.T) { + chainInfo := types.DefaultChainInfo() + require.Empty(t, chainInfo.Chains) + }) +} + +func TestChainInfo_Validate(t *testing.T) { + tests := []struct { + name string + chainInfo types.ChainInfo + errContains string + }{ + { + name: "empty is valid", + chainInfo: types.ChainInfo{}, + }, + { + name: "valid chain info", + chainInfo: sample.ChainInfo(42), + }, + { + name: "invalid if chain is invalid", + chainInfo: types.ChainInfo{ + Chains: []chains.Chain{ + { + ChainId: 0, + ChainName: chains.ChainName_empty, + Network: chains.Network_optimism, + NetworkType: chains.NetworkType_testnet, + Vm: chains.Vm_evm, + Consensus: chains.Consensus_op_stack, + IsExternal: true, + }, + }, + }, + errContains: "chain ID must be positive", + }, + { + name: "invalid if chain is not external", + chainInfo: types.ChainInfo{ + Chains: []chains.Chain{ + { + ChainId: 42, + ChainName: chains.ChainName_empty, + Network: chains.Network_optimism, + NetworkType: chains.NetworkType_testnet, + Vm: chains.Vm_evm, + Consensus: chains.Consensus_op_stack, + IsExternal: false, + }, + }, + }, + errContains: "not external", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.chainInfo.Validate() + if tt.errContains != "" { + require.ErrorContains(t, err, tt.errContains) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/x/authority/types/genesis.go b/x/authority/types/genesis.go index bed0e04a41..13a01030bf 100644 --- a/x/authority/types/genesis.go +++ b/x/authority/types/genesis.go @@ -3,11 +3,16 @@ package types // DefaultGenesis returns the default authority genesis state func DefaultGenesis() *GenesisState { return &GenesisState{ - Policies: DefaultPolicies(), + Policies: DefaultPolicies(), + ChainInfo: DefaultChainInfo(), } } // Validate performs basic genesis state validation returning an error upon any failure func (gs GenesisState) Validate() error { - return gs.Policies.Validate() + if err := gs.Policies.Validate(); err != nil { + return err + } + + return gs.ChainInfo.Validate() } diff --git a/x/authority/types/genesis.pb.go b/x/authority/types/genesis.pb.go index 923ebb8308..c4a9f015bc 100644 --- a/x/authority/types/genesis.pb.go +++ b/x/authority/types/genesis.pb.go @@ -27,6 +27,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { Policies Policies `protobuf:"bytes,1,opt,name=policies,proto3" json:"policies"` AuthorizationList AuthorizationList `protobuf:"bytes,2,opt,name=authorization_list,json=authorizationList,proto3" json:"authorization_list"` + ChainInfo ChainInfo `protobuf:"bytes,3,opt,name=chain_info,json=chainInfo,proto3" json:"chain_info"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -76,6 +77,13 @@ func (m *GenesisState) GetAuthorizationList() AuthorizationList { return AuthorizationList{} } +func (m *GenesisState) GetChainInfo() ChainInfo { + if m != nil { + return m.ChainInfo + } + return ChainInfo{} +} + func init() { proto.RegisterType((*GenesisState)(nil), "zetachain.zetacore.authority.GenesisState") } @@ -85,23 +93,25 @@ func init() { } var fileDescriptor_633475075491b169 = []byte{ - // 248 bytes of a gzipped FileDescriptorProto + // 287 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0xaa, 0x4a, 0x2d, 0x49, 0x4c, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x07, 0xb3, 0xf2, 0x8b, 0x52, 0xf5, 0x13, 0x4b, 0x4b, 0x32, 0xf2, 0x8b, 0x32, 0x4b, 0x2a, 0xf5, 0xd3, 0x53, 0xf3, 0x52, 0x8b, 0x33, 0x8b, 0xf5, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x64, 0xe0, 0x6a, 0xf5, 0x60, 0x6a, 0xf5, 0xe0, 0x6a, 0xa5, 0xb4, 0xf1, 0x9a, 0x54, 0x90, 0x9f, 0x93, 0x99, 0x9c, 0x99, 0x0a, 0x35, 0x4a, 0xca, 0x00, 0xaf, 0x62, 0x28, - 0xab, 0x2a, 0xb1, 0x24, 0x33, 0x3f, 0x0f, 0xaa, 0x43, 0x24, 0x3d, 0x3f, 0x3d, 0x1f, 0xcc, 0xd4, - 0x07, 0xb1, 0x20, 0xa2, 0x4a, 0xfb, 0x18, 0xb9, 0x78, 0xdc, 0x21, 0x8e, 0x0c, 0x2e, 0x49, 0x2c, - 0x49, 0x15, 0xf2, 0xe0, 0xe2, 0x80, 0x59, 0x25, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0xa4, 0xa6, - 0x87, 0xcf, 0xd9, 0x7a, 0x01, 0x50, 0xd5, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0xc1, 0x75, - 0x0b, 0xa5, 0x70, 0x09, 0xa1, 0xb8, 0x23, 0x3e, 0x27, 0xb3, 0xb8, 0x44, 0x82, 0x09, 0x6c, 0xa6, - 0x3e, 0x7e, 0x33, 0x1d, 0x91, 0xf5, 0xf9, 0x64, 0x16, 0x97, 0x40, 0x0d, 0x17, 0x4c, 0xc4, 0x90, - 0xf0, 0x3a, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, - 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0x83, 0xf4, 0xcc, 0x92, - 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x70, 0x18, 0xe9, 0xa2, 0x05, 0x57, 0x05, 0x52, 0x80, - 0x95, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0xc3, 0xc4, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, - 0x65, 0xfd, 0x9b, 0x1b, 0xd4, 0x01, 0x00, 0x00, + 0xab, 0x2a, 0xb1, 0x24, 0x33, 0x3f, 0x0f, 0xaa, 0x43, 0x17, 0xaf, 0x0e, 0xb0, 0x44, 0x7c, 0x66, + 0x5e, 0x5a, 0x3e, 0x54, 0xb9, 0x48, 0x7a, 0x7e, 0x7a, 0x3e, 0x98, 0xa9, 0x0f, 0x62, 0x41, 0x44, + 0x95, 0x7a, 0x98, 0xb8, 0x78, 0xdc, 0x21, 0x7e, 0x0a, 0x2e, 0x49, 0x2c, 0x49, 0x15, 0xf2, 0xe0, + 0xe2, 0x80, 0xb9, 0x4c, 0x82, 0x51, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x4d, 0x0f, 0x9f, 0x2f, 0xf5, + 0x02, 0xa0, 0xaa, 0x9d, 0x58, 0x4e, 0xdc, 0x93, 0x67, 0x08, 0x82, 0xeb, 0x16, 0x4a, 0xe1, 0x12, + 0x42, 0x71, 0x76, 0x7c, 0x4e, 0x66, 0x71, 0x89, 0x04, 0x13, 0xd8, 0x4c, 0x7d, 0xfc, 0x66, 0x3a, + 0x22, 0xeb, 0xf3, 0xc9, 0x2c, 0x2e, 0x81, 0x1a, 0x2e, 0x98, 0x88, 0x2e, 0x21, 0xe4, 0xc3, 0xc5, + 0x85, 0xf0, 0xaa, 0x04, 0x33, 0xd8, 0x74, 0x75, 0xfc, 0xa6, 0x3b, 0x83, 0x24, 0x3c, 0xf3, 0xd2, + 0xf2, 0xa1, 0xa6, 0x72, 0x26, 0xc3, 0x05, 0xbc, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, + 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, + 0x8e, 0x21, 0xca, 0x20, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x17, 0x1c, 0xdc, + 0xba, 0x68, 0x21, 0x5f, 0x81, 0x14, 0xf6, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0xe0, 0x10, + 0x36, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x66, 0xd6, 0x94, 0x51, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -124,6 +134,16 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.ChainInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a { size, err := m.AuthorizationList.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -168,6 +188,8 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) l = m.AuthorizationList.Size() n += 1 + l + sovGenesis(uint64(l)) + l = m.ChainInfo.Size() + n += 1 + l + sovGenesis(uint64(l)) return n } @@ -272,6 +294,39 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ChainInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/authority/types/genesis_test.go b/x/authority/types/genesis_test.go index 46f4ad9bcb..90aee92509 100644 --- a/x/authority/types/genesis_test.go +++ b/x/authority/types/genesis_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/testutil/sample" "github.com/zeta-chain/zetacore/x/authority/types" ) @@ -25,7 +26,8 @@ func TestGenesisState_Validate(t *testing.T) { { name: "valid genesis", gs: &types.GenesisState{ - Policies: sample.Policies(), + Policies: sample.Policies(), + ChainInfo: sample.ChainInfo(42), }, errContains: "", }, @@ -40,9 +42,30 @@ func TestGenesisState_Validate(t *testing.T) { }, }, }, + ChainInfo: sample.ChainInfo(42), }, errContains: "invalid address", }, + { + name: "invalid if policies is invalid", + gs: &types.GenesisState{ + Policies: sample.Policies(), + ChainInfo: types.ChainInfo{ + Chains: []chains.Chain{ + { + ChainId: 0, + ChainName: chains.ChainName_empty, + Network: chains.Network_optimism, + NetworkType: chains.NetworkType_testnet, + Vm: chains.Vm_evm, + Consensus: chains.Consensus_op_stack, + IsExternal: true, + }, + }, + }, + }, + errContains: "chain ID must be positive", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/x/authority/types/keys.go b/x/authority/types/keys.go index 5b86ca9711..7593feed3a 100644 --- a/x/authority/types/keys.go +++ b/x/authority/types/keys.go @@ -25,4 +25,7 @@ func KeyPrefix(p string) []byte { const ( // PoliciesKey is the key for the policies store PoliciesKey = "Policies-value-" + + // ChainInfoKey is the key for the chain info store + ChainInfoKey = "ChainInfo-value-" ) diff --git a/zetaclient/zetacore/tx_test.go b/zetaclient/zetacore/tx_test.go index f12fcc8b6a..919f9cc058 100644 --- a/zetaclient/zetacore/tx_test.go +++ b/zetaclient/zetacore/tx_test.go @@ -247,7 +247,6 @@ func TestZetacore_UpdateZetacoreContext(t *testing.T) { WithPayload(observertypes.QuerySupportedChains{}). Return(observertypes.QuerySupportedChainsResponse{ Chains: []*chains.Chain{ - { chains.BitcoinMainnet.ChainId, chains.BitcoinMainnet.ChainName, @@ -256,6 +255,7 @@ func TestZetacore_UpdateZetacoreContext(t *testing.T) { chains.BscMainnet.Vm, chains.BscMainnet.Consensus, chains.BscMainnet.IsExternal, + chains.BscMainnet.CctxGateway, }, { chains.Ethereum.ChainId, @@ -265,6 +265,7 @@ func TestZetacore_UpdateZetacoreContext(t *testing.T) { chains.Ethereum.Vm, chains.Ethereum.Consensus, chains.Ethereum.IsExternal, + chains.Ethereum.CctxGateway, }, }, })