diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..a4e7111cc --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,18 @@ +Here are our instructions: + +We want you to play the role of an expert software developer, who has particular expertise in Golang and all its nuances, as well as the Cosmos SDK, IBC protocol, Tendermint/CometBFT algorithms and light clients, and also knowledge of the wider blockchain technology space. + +Please be terse, and follow all the coding guidelines. Pay particular attention to importing packages correctly, and the visibility of methods, functions, types and fields. Do not write lines longer than 80 characters wide, you should split them according to golang formatting rules. If writing code, try to reuse existing code, and suggest refactors for how to keep the code DRY. + +Also pay particular attention to security, and to make sure that the code is deterministic. Make sure to look at the context of the code to use the right library versions and import aliases, and to follow typical Cosmos SDK practices like using the SDK math, coin and error handling libraries. Remember that Cosmos SDK blockchains have a single logical thread of execution and execute transactions in sequence, there are no 'race' conditions, and failed transactions have no effect. Be wary of any paths that can lead to a panic from BeginBlocker or EndBlocker. Don't worry about what ifs or improbably scenarios based on future code changes. Just evaluate the code as it is, and find bugs that definitely exist. + +These additional resources are useful +- https://github.com/dymensionxyz/dymension/blob/main/Contributing.md (also at ../Contributing.md) +- https://github.com/cosmos/ibc/tree/main/spec/core +- https://github.com/cosmos/ibc-go/tree/v7.5.1/modules/core +- https://github.com/cosmos/ibc-go/tree/v7.5.1/modules/light-clients/07-tendermint +- https://github.com/cosmos/cosmos-sdk/tree/v0.47.13/docs +- https://github.com/dymensionxyz/dymint +- https://github.com/dymensionxyz/rollapp-evm +- https://github.com/dymensionxyz/rollapp-wasm +- https://github.com/dymensionxyz/go-relayer diff --git a/cmd/tx.go b/cmd/tx.go index 81fea6c7d..3692cb6b0 100644 --- a/cmd/tx.go +++ b/cmd/tx.go @@ -49,6 +49,7 @@ Most of these commands take a [path] argument. Make sure: upgradeClientsCmd(a), createConnectionCmd(a), createChannelCmd(a), + sendGenesisTransfer(a), closeChannelCmd(a), lineBreakCommand(), registerCounterpartyCmd(a), @@ -596,6 +597,47 @@ $ %s tx chan demo-path --timeout 5s --max-retries 10`, return cmd } +func sendGenesisTransfer(a *appState) *cobra.Command { + cmd := &cobra.Command{ + Use: "rollapp-send-genesis-transfer ", + Aliases: []string{}, + Short: "Send a genesis transfer from the rollapp to the hub.", + Long: "Send a genesis transfer from the rollapp to the hub - intended for recovery/retry. Relayer will try automatically the first time during channel creation.", + Args: withUsage(cobra.ExactArgs(1)), + RunE: func(cmd *cobra.Command, args []string) error { + pathName := args[0] + + c, src, dst, err := a.config.ChainsFromPath(pathName) + if err != nil { + return err + } + + // ensure that keys exist + if exists := c[src].ChainProvider.KeyExists(c[src].ChainProvider.Key()); !exists { + return fmt.Errorf("key %s not found on src chain %s", c[src].ChainProvider.Key(), c[src].ChainID()) + } + + if exists := c[dst].ChainProvider.KeyExists(c[dst].ChainProvider.Key()); !exists { + return fmt.Errorf("key %s not found on dst chain %s", c[dst].ChainProvider.Key(), c[dst].ChainID()) + } + + // create channel if it isn't already created + return processor.SendGenesisTransfer( + cmd.Context(), + c[src].ChainProvider, // must be hub + c[dst].ChainProvider, // must be rollapp + ) + }, + } + + cmd = timeoutFlag(a.viper, cmd) + cmd = retryFlag(a.viper, cmd) + cmd = overrideFlag(a.viper, cmd) + cmd = channelParameterFlags(a.viper, cmd) + cmd = memoFlag(a.viper, cmd) + return cmd +} + func isRollapp(src, dst *relayer.Chain) bool { srcP, ok := src.ChainProvider.ProviderConfig().(cosmos.CosmosProviderConfig) if !ok { diff --git a/proto/dymensionxyz/dymension/lightclient/query.proto b/proto/dymensionxyz/dymension/lightclient/query.proto new file mode 100644 index 000000000..d4fa63a3d --- /dev/null +++ b/proto/dymensionxyz/dymension/lightclient/query.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package dymensionxyz.dymension.lightclient; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/relayer/relayer/chains/cosmos/dym/lightclient/types"; + + + +// Query defines the gRPC querier service. +service Query { + rpc RollappCanonChannel(QueryRollappCanonChannelRequest) returns (QueryRollappCanonChannelResponse) { + option (google.api.http).get = "/dymensionxyz/dymension/lightclient/canon_channel/{rollappId}"; + } +} + +message QueryRollappCanonChannelRequest { + string rollappId = 1; +} + +message QueryRollappCanonChannelResponse { + // hub side + string hub_channel_id = 1; + // rollapp side ('counterparty') + string rollapp_channel_id = 2; +} \ No newline at end of file diff --git a/proto/rollapp/hub_genesis/tx.proto b/proto/rollapp/hub_genesis/tx.proto new file mode 100644 index 000000000..ca653ee46 --- /dev/null +++ b/proto/rollapp/hub_genesis/tx.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +package rollapp.hub_genesis; + +import "cosmos/msg/v1/msg.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/relayer/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types"; + + +service Msg { + rpc SendTransfer(MsgSendTransfer) returns (MsgSendTransferResponse); +} + +// Try to send the genesis transfer +// Must be whitelisted relayer, and channel must be open +// Must have tokens available to send +message MsgSendTransfer { + option (cosmos.msg.v1.signer) = "signer"; + string signer = 1; + // ID of the canonical channel, as queried from the hub + string channel_id = 2; +} + +message MsgSendTransferResponse {} \ No newline at end of file diff --git a/relayer/chains/cosmos/codec.go b/relayer/chains/cosmos/codec.go index 370f40d2c..9c9bea09a 100644 --- a/relayer/chains/cosmos/codec.go +++ b/relayer/chains/cosmos/codec.go @@ -31,6 +31,7 @@ import ( dymtypes "github.com/cosmos/relayer/v2/relayer/chains/cosmos/dym/lightclient/types" cosmosmodule "github.com/cosmos/relayer/v2/relayer/chains/cosmos/module" + rdktypes "github.com/cosmos/relayer/v2/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types" "github.com/cosmos/relayer/v2/relayer/chains/cosmos/stride" ethermintcodecs "github.com/cosmos/relayer/v2/relayer/codecs/ethermint" injectivecodecs "github.com/cosmos/relayer/v2/relayer/codecs/injective" @@ -91,8 +92,12 @@ func MakeCodec(moduleBasics []module.AppModuleBasic, extraCodecs []string, accBe } { // DYMENSION + // hub dymtypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) encodingConfig.Amino.RegisterConcrete(&dymtypes.MsgSetCanonicalClient{}, "/lightclient.SetCanonicalClient", nil) + // rollapp TODO: finish + rdktypes.RegisterInterfaces(encodingConfig.InterfaceRegistry) + // encodingConfig.Amino.RegisterConcrete(&rdktypes.MsgSendTransfer{}, "/lightclient.SetCanonicalClient", nil) } return encodingConfig diff --git a/relayer/chains/cosmos/dym/lightclient/types/query.pb.go b/relayer/chains/cosmos/dym/lightclient/types/query.pb.go new file mode 100644 index 000000000..e07d95b1c --- /dev/null +++ b/relayer/chains/cosmos/dym/lightclient/types/query.pb.go @@ -0,0 +1,640 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dymensionxyz/dymension/lightclient/query.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + 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 + +type QueryRollappCanonChannelRequest struct { + RollappId string `protobuf:"bytes,1,opt,name=rollappId,proto3" json:"rollappId,omitempty"` +} + +func (m *QueryRollappCanonChannelRequest) Reset() { *m = QueryRollappCanonChannelRequest{} } +func (m *QueryRollappCanonChannelRequest) String() string { return proto.CompactTextString(m) } +func (*QueryRollappCanonChannelRequest) ProtoMessage() {} +func (*QueryRollappCanonChannelRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a51f5810cc34625d, []int{0} +} +func (m *QueryRollappCanonChannelRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryRollappCanonChannelRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryRollappCanonChannelRequest.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 *QueryRollappCanonChannelRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRollappCanonChannelRequest.Merge(m, src) +} +func (m *QueryRollappCanonChannelRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryRollappCanonChannelRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRollappCanonChannelRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryRollappCanonChannelRequest proto.InternalMessageInfo + +func (m *QueryRollappCanonChannelRequest) GetRollappId() string { + if m != nil { + return m.RollappId + } + return "" +} + +type QueryRollappCanonChannelResponse struct { + // hub side + HubChannelId string `protobuf:"bytes,1,opt,name=hub_channel_id,json=hubChannelId,proto3" json:"hub_channel_id,omitempty"` + // rollapp side ('counterparty') + RollappChannelId string `protobuf:"bytes,2,opt,name=rollapp_channel_id,json=rollappChannelId,proto3" json:"rollapp_channel_id,omitempty"` +} + +func (m *QueryRollappCanonChannelResponse) Reset() { *m = QueryRollappCanonChannelResponse{} } +func (m *QueryRollappCanonChannelResponse) String() string { return proto.CompactTextString(m) } +func (*QueryRollappCanonChannelResponse) ProtoMessage() {} +func (*QueryRollappCanonChannelResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a51f5810cc34625d, []int{1} +} +func (m *QueryRollappCanonChannelResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryRollappCanonChannelResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryRollappCanonChannelResponse.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 *QueryRollappCanonChannelResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRollappCanonChannelResponse.Merge(m, src) +} +func (m *QueryRollappCanonChannelResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryRollappCanonChannelResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRollappCanonChannelResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryRollappCanonChannelResponse proto.InternalMessageInfo + +func (m *QueryRollappCanonChannelResponse) GetHubChannelId() string { + if m != nil { + return m.HubChannelId + } + return "" +} + +func (m *QueryRollappCanonChannelResponse) GetRollappChannelId() string { + if m != nil { + return m.RollappChannelId + } + return "" +} + +func init() { + proto.RegisterType((*QueryRollappCanonChannelRequest)(nil), "dymensionxyz.dymension.lightclient.QueryRollappCanonChannelRequest") + proto.RegisterType((*QueryRollappCanonChannelResponse)(nil), "dymensionxyz.dymension.lightclient.QueryRollappCanonChannelResponse") +} + +func init() { + proto.RegisterFile("dymensionxyz/dymension/lightclient/query.proto", fileDescriptor_a51f5810cc34625d) +} + +var fileDescriptor_a51f5810cc34625d = []byte{ + // 356 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x52, 0x41, 0x4b, 0xc3, 0x30, + 0x14, 0x5e, 0x06, 0x0a, 0x0b, 0x22, 0x12, 0x3d, 0xe8, 0x18, 0x75, 0x14, 0x0f, 0x1e, 0xa4, 0x01, + 0x3d, 0xcb, 0xc0, 0xb9, 0xc3, 0x8e, 0xee, 0xe8, 0x65, 0xa4, 0x6d, 0x6c, 0x03, 0x69, 0x5e, 0xd7, + 0xa4, 0x62, 0x15, 0x2f, 0xfe, 0x02, 0xc1, 0x3f, 0xe5, 0x71, 0xe0, 0xc5, 0xa3, 0x6c, 0x82, 0x67, + 0xff, 0x81, 0xac, 0xed, 0xba, 0x09, 0xca, 0x04, 0x4f, 0xc9, 0x7b, 0xdf, 0xf7, 0xbe, 0x2f, 0xf9, + 0x78, 0xd8, 0xf1, 0xb3, 0x88, 0x2b, 0x2d, 0x40, 0xdd, 0x64, 0xb7, 0xb4, 0x2a, 0xa8, 0x14, 0x41, + 0x68, 0x3c, 0x29, 0xb8, 0x32, 0x74, 0x94, 0xf2, 0x24, 0x73, 0xe2, 0x04, 0x0c, 0x10, 0x7b, 0x99, + 0xbf, 0x18, 0x76, 0x96, 0xf8, 0xcd, 0x9d, 0x00, 0x02, 0xc8, 0xe9, 0x74, 0x76, 0x2b, 0x26, 0x9b, + 0xad, 0x00, 0x20, 0x90, 0x9c, 0xb2, 0x58, 0x50, 0xa6, 0x14, 0x18, 0x66, 0x04, 0x28, 0x5d, 0xa2, + 0x7b, 0x25, 0x9a, 0x57, 0x6e, 0x7a, 0x45, 0x99, 0x2a, 0x2d, 0xed, 0x0e, 0xde, 0xbf, 0x98, 0xbd, + 0x60, 0x00, 0x52, 0xb2, 0x38, 0xee, 0x32, 0x05, 0xaa, 0x1b, 0x32, 0xa5, 0xb8, 0x1c, 0xf0, 0x51, + 0xca, 0xb5, 0x21, 0x2d, 0xdc, 0x48, 0x0a, 0xb4, 0xef, 0xef, 0xa2, 0x36, 0x3a, 0x6c, 0x0c, 0x16, + 0x0d, 0xfb, 0x1a, 0xb7, 0x7f, 0x17, 0xd0, 0x31, 0x28, 0xcd, 0xc9, 0x01, 0xde, 0x0c, 0x53, 0x77, + 0xe8, 0x15, 0xed, 0xa1, 0x98, 0xcb, 0x6c, 0x84, 0xa9, 0x5b, 0x72, 0xfb, 0x3e, 0x39, 0xc2, 0xa4, + 0x94, 0x5d, 0x66, 0xd6, 0x73, 0xe6, 0x56, 0x89, 0x54, 0xec, 0xe3, 0x4f, 0x84, 0xd7, 0x72, 0x63, + 0xf2, 0x81, 0xf0, 0xf6, 0x0f, 0xee, 0xa4, 0xeb, 0xac, 0x8e, 0xd3, 0x59, 0xf1, 0xf9, 0xe6, 0xf9, + 0xff, 0x44, 0x8a, 0x00, 0xec, 0xde, 0xc3, 0xcb, 0xfb, 0x53, 0xbd, 0x43, 0x4e, 0xe9, 0x1f, 0x36, + 0xc2, 0x9b, 0x29, 0xcc, 0x23, 0xa0, 0x77, 0x55, 0xd4, 0xf7, 0x67, 0xc3, 0xe7, 0x89, 0x85, 0xc6, + 0x13, 0x0b, 0xbd, 0x4d, 0x2c, 0xf4, 0x38, 0xb5, 0x6a, 0xe3, 0xa9, 0x55, 0x7b, 0x9d, 0x5a, 0xb5, + 0xcb, 0x5e, 0x20, 0x4c, 0x98, 0xba, 0x8e, 0x07, 0x11, 0xf5, 0x40, 0x47, 0xa0, 0x69, 0xc2, 0x25, + 0xcb, 0x78, 0x52, 0x9d, 0x5e, 0xc8, 0x84, 0xd2, 0x73, 0xd4, 0xcf, 0xa2, 0x6f, 0xa6, 0x26, 0x8b, + 0xb9, 0x76, 0xd7, 0xf3, 0xa5, 0x38, 0xf9, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x22, 0x4c, 0x78, 0xe2, + 0xb9, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + RollappCanonChannel(ctx context.Context, in *QueryRollappCanonChannelRequest, opts ...grpc.CallOption) (*QueryRollappCanonChannelResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) RollappCanonChannel(ctx context.Context, in *QueryRollappCanonChannelRequest, opts ...grpc.CallOption) (*QueryRollappCanonChannelResponse, error) { + out := new(QueryRollappCanonChannelResponse) + err := c.cc.Invoke(ctx, "/dymensionxyz.dymension.lightclient.Query/RollappCanonChannel", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + RollappCanonChannel(context.Context, *QueryRollappCanonChannelRequest) (*QueryRollappCanonChannelResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) RollappCanonChannel(ctx context.Context, req *QueryRollappCanonChannelRequest) (*QueryRollappCanonChannelResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RollappCanonChannel not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_RollappCanonChannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryRollappCanonChannelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).RollappCanonChannel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dymensionxyz.dymension.lightclient.Query/RollappCanonChannel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).RollappCanonChannel(ctx, req.(*QueryRollappCanonChannelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "dymensionxyz.dymension.lightclient.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "RollappCanonChannel", + Handler: _Query_RollappCanonChannel_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "dymensionxyz/dymension/lightclient/query.proto", +} + +func (m *QueryRollappCanonChannelRequest) 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 *QueryRollappCanonChannelRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryRollappCanonChannelRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.RollappId) > 0 { + i -= len(m.RollappId) + copy(dAtA[i:], m.RollappId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.RollappId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryRollappCanonChannelResponse) 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 *QueryRollappCanonChannelResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryRollappCanonChannelResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.RollappChannelId) > 0 { + i -= len(m.RollappChannelId) + copy(dAtA[i:], m.RollappChannelId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.RollappChannelId))) + i-- + dAtA[i] = 0x12 + } + if len(m.HubChannelId) > 0 { + i -= len(m.HubChannelId) + copy(dAtA[i:], m.HubChannelId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.HubChannelId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryRollappCanonChannelRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.RollappId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryRollappCanonChannelResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.HubChannelId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.RollappChannelId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryRollappCanonChannelRequest) 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 ErrIntOverflowQuery + } + 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: QueryRollappCanonChannelRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryRollappCanonChannelRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RollappId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RollappId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryRollappCanonChannelResponse) 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 ErrIntOverflowQuery + } + 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: QueryRollappCanonChannelResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryRollappCanonChannelResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HubChannelId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.HubChannelId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RollappChannelId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RollappChannelId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/relayer/chains/cosmos/dym/lightclient/types/query.pb.gw.go b/relayer/chains/cosmos/dym/lightclient/types/query.pb.gw.go new file mode 100644 index 000000000..c2babe6bb --- /dev/null +++ b/relayer/chains/cosmos/dym/lightclient/types/query.pb.gw.go @@ -0,0 +1,189 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: dymensionxyz/dymension/lightclient/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_RollappCanonChannel_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryRollappCanonChannelRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["rollappId"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "rollappId") + } + + protoReq.RollappId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "rollappId", err) + } + + msg, err := client.RollappCanonChannel(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_RollappCanonChannel_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryRollappCanonChannelRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["rollappId"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "rollappId") + } + + protoReq.RollappId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "rollappId", err) + } + + msg, err := server.RollappCanonChannel(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_RollappCanonChannel_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_RollappCanonChannel_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_RollappCanonChannel_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_RollappCanonChannel_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_RollappCanonChannel_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_RollappCanonChannel_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_RollappCanonChannel_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"dymensionxyz", "dymension", "lightclient", "canon_channel", "rollappId"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_RollappCanonChannel_0 = runtime.ForwardResponseMessage +) diff --git a/relayer/chains/cosmos/query.go b/relayer/chains/cosmos/query.go index b3f8d3bb3..44bd09559 100644 --- a/relayer/chains/cosmos/query.go +++ b/relayer/chains/cosmos/query.go @@ -33,6 +33,7 @@ import ( ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" tmclient "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/cosmos/relayer/v2/relayer/chains" + dymtypes "github.com/cosmos/relayer/v2/relayer/chains/cosmos/dym/lightclient/types" "github.com/cosmos/relayer/v2/relayer/provider" "github.com/danwt/gerr/gerr" "go.uber.org/zap" @@ -1301,3 +1302,12 @@ func (cc *CosmosProvider) QueryConsensusStateABCI(ctx context.Context, clientID ProofHeight: proofHeight, }, nil } + +func (cc *CosmosProvider) GetCanonicalChan(ctx context.Context, rollappID string) (string, error) { + c := dymtypes.NewQueryClient(cc) + res, err := c.RollappCanonChannel(ctx, &dymtypes.QueryRollappCanonChannelRequest{RollappId: rollappID}) + if err != nil { + return "", fmt.Errorf("query: %w", err) + } + return res.RollappChannelId, nil +} diff --git a/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types/codec.go b/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types/codec.go new file mode 100644 index 000000000..7763dba40 --- /dev/null +++ b/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types/codec.go @@ -0,0 +1,28 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func RegisterCodec(cdc *codec.LegacyAmino) { +} + +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgSendTransfer{}, + ) +} + +func init() { + cryptocodec.RegisterCrypto(amino) + amino.Seal() +} + +var ( + amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) +) diff --git a/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types/msgs.go b/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types/msgs.go new file mode 100644 index 000000000..210b20ef7 --- /dev/null +++ b/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types/msgs.go @@ -0,0 +1,28 @@ +package types + +import ( + "errors" + + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/dymensionxyz/gerr-cosmos/gerrc" +) + +var ( + _ sdk.Msg = (*MsgSendTransfer)(nil) +) + +func (m *MsgSendTransfer) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{sdk.MustAccAddressFromBech32(m.Signer)} +} + +func (m *MsgSendTransfer) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(m.Signer) + if err != nil { + return errorsmod.Wrap(errors.Join(gerrc.ErrInvalidArgument, err), "get relayer addr from bech32") + } + if m.ChannelId == "" { + return errorsmod.Wrap(gerrc.ErrInvalidArgument, "channel id is empty") + } + return nil +} diff --git a/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types/tx.pb.go b/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types/tx.pb.go new file mode 100644 index 000000000..a8794de3b --- /dev/null +++ b/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types/tx.pb.go @@ -0,0 +1,584 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: rollapp/hub_genesis/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + 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 + +// Try to send the genesis transfer +// Must be whitelisted relayer, and channel must be open +// Must have tokens available to send +type MsgSendTransfer struct { + Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` + // ID of the canonical channel, as queried from the hub + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` +} + +func (m *MsgSendTransfer) Reset() { *m = MsgSendTransfer{} } +func (m *MsgSendTransfer) String() string { return proto.CompactTextString(m) } +func (*MsgSendTransfer) ProtoMessage() {} +func (*MsgSendTransfer) Descriptor() ([]byte, []int) { + return fileDescriptor_9ac4bb6bb2f3fa72, []int{0} +} +func (m *MsgSendTransfer) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSendTransfer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSendTransfer.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 *MsgSendTransfer) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSendTransfer.Merge(m, src) +} +func (m *MsgSendTransfer) XXX_Size() int { + return m.Size() +} +func (m *MsgSendTransfer) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSendTransfer.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSendTransfer proto.InternalMessageInfo + +func (m *MsgSendTransfer) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +func (m *MsgSendTransfer) GetChannelId() string { + if m != nil { + return m.ChannelId + } + return "" +} + +type MsgSendTransferResponse struct { +} + +func (m *MsgSendTransferResponse) Reset() { *m = MsgSendTransferResponse{} } +func (m *MsgSendTransferResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSendTransferResponse) ProtoMessage() {} +func (*MsgSendTransferResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_9ac4bb6bb2f3fa72, []int{1} +} +func (m *MsgSendTransferResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSendTransferResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSendTransferResponse.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 *MsgSendTransferResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSendTransferResponse.Merge(m, src) +} +func (m *MsgSendTransferResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSendTransferResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSendTransferResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSendTransferResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgSendTransfer)(nil), "rollapp.hub_genesis.MsgSendTransfer") + proto.RegisterType((*MsgSendTransferResponse)(nil), "rollapp.hub_genesis.MsgSendTransferResponse") +} + +func init() { proto.RegisterFile("rollapp/hub_genesis/tx.proto", fileDescriptor_9ac4bb6bb2f3fa72) } + +var fileDescriptor_9ac4bb6bb2f3fa72 = []byte{ + // 290 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x29, 0xca, 0xcf, 0xc9, + 0x49, 0x2c, 0x28, 0xd0, 0xcf, 0x28, 0x4d, 0x8a, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, + 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, 0xca, 0xea, 0x21, 0xc9, 0x4a, + 0x89, 0x27, 0xe7, 0x17, 0xe7, 0xe6, 0x17, 0xeb, 0xe7, 0x16, 0xa7, 0xeb, 0x97, 0x19, 0x82, 0x28, + 0x88, 0x6a, 0x29, 0xc9, 0xf4, 0xfc, 0xfc, 0xf4, 0x9c, 0x54, 0x7d, 0x30, 0x2f, 0xa9, 0x34, 0x4d, + 0x3f, 0x31, 0xaf, 0x12, 0x22, 0xa5, 0x14, 0xca, 0xc5, 0xef, 0x5b, 0x9c, 0x1e, 0x9c, 0x9a, 0x97, + 0x12, 0x52, 0x94, 0x98, 0x57, 0x9c, 0x96, 0x5a, 0x24, 0x24, 0xc6, 0xc5, 0x56, 0x9c, 0x99, 0x9e, + 0x97, 0x5a, 0x24, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x19, 0x04, 0xe5, 0x09, 0xc9, 0x72, 0x71, 0x25, + 0x67, 0x24, 0xe6, 0xe5, 0xa5, 0xe6, 0xc4, 0x67, 0xa6, 0x48, 0x30, 0x81, 0xe5, 0x38, 0xa1, 0x22, + 0x9e, 0x29, 0x56, 0xdc, 0x4d, 0xcf, 0x37, 0x68, 0x41, 0xd5, 0x2a, 0x49, 0x72, 0x89, 0xa3, 0x19, + 0x1b, 0x94, 0x5a, 0x5c, 0x90, 0x9f, 0x57, 0x9c, 0x6a, 0x94, 0xc9, 0xc5, 0xec, 0x5b, 0x9c, 0x2e, + 0x94, 0xc4, 0xc5, 0x83, 0x62, 0xab, 0x8a, 0x1e, 0x16, 0x2f, 0xe9, 0xa1, 0x19, 0x22, 0xa5, 0x43, + 0x8c, 0x2a, 0x98, 0x55, 0x4e, 0xe9, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, + 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, + 0xe5, 0x9b, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x0f, 0x0d, 0xb5, 0xa2, + 0xd4, 0x9c, 0xc4, 0xca, 0xd4, 0x22, 0x38, 0x9d, 0x9c, 0x91, 0x98, 0x99, 0x57, 0x0c, 0x97, 0x85, + 0xc6, 0x46, 0x51, 0x4a, 0x36, 0x28, 0x46, 0x74, 0xe1, 0x31, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, + 0x06, 0x0e, 0x4c, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x38, 0x5d, 0x8e, 0xf6, 0xb5, 0x01, + 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + SendTransfer(ctx context.Context, in *MsgSendTransfer, opts ...grpc.CallOption) (*MsgSendTransferResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) SendTransfer(ctx context.Context, in *MsgSendTransfer, opts ...grpc.CallOption) (*MsgSendTransferResponse, error) { + out := new(MsgSendTransferResponse) + err := c.cc.Invoke(ctx, "/rollapp.hub_genesis.Msg/SendTransfer", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + SendTransfer(context.Context, *MsgSendTransfer) (*MsgSendTransferResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) SendTransfer(ctx context.Context, req *MsgSendTransfer) (*MsgSendTransferResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SendTransfer not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_SendTransfer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSendTransfer) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SendTransfer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rollapp.hub_genesis.Msg/SendTransfer", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SendTransfer(ctx, req.(*MsgSendTransfer)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "rollapp.hub_genesis.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SendTransfer", + Handler: _Msg_SendTransfer_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "rollapp/hub_genesis/tx.proto", +} + +func (m *MsgSendTransfer) 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 *MsgSendTransfer) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSendTransfer) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ChannelId) > 0 { + i -= len(m.ChannelId) + copy(dAtA[i:], m.ChannelId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChannelId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSendTransferResponse) 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 *MsgSendTransferResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSendTransferResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgSendTransfer) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgSendTransferResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgSendTransfer) 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 ErrIntOverflowTx + } + 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: MsgSendTransfer: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSendTransfer: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChannelId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSendTransferResponse) 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 ErrIntOverflowTx + } + 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: MsgSendTransferResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSendTransferResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/relayer/chains/cosmos/tx.go b/relayer/chains/cosmos/tx.go index 7efa1409b..db683aa85 100644 --- a/relayer/chains/cosmos/tx.go +++ b/relayer/chains/cosmos/tx.go @@ -45,6 +45,8 @@ import ( tmclient "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" localhost "github.com/cosmos/ibc-go/v8/modules/light-clients/09-localhost" dymtypes "github.com/cosmos/relayer/v2/relayer/chains/cosmos/dym/lightclient/types" + rdktypes "github.com/cosmos/relayer/v2/relayer/chains/cosmos/rollapp/rdk/hub-genesis/types" + strideicqtypes "github.com/cosmos/relayer/v2/relayer/chains/cosmos/stride" "github.com/cosmos/relayer/v2/relayer/ethermint" "github.com/cosmos/relayer/v2/relayer/provider" @@ -733,10 +735,28 @@ func (cc *CosmosProvider) TrySetCanonicalClient(ctx context.Context, clientID st Signer: signer, } - m := NewCosmosMessage(msg, func(signer string) { + return cc.simpleSend(ctx, msg, func(signer string) { msg.Signer = signer }) +} + +func (cc *CosmosProvider) TrySendGenesisTransfer(ctx context.Context, channelID string) error { + signer, err := cc.Address() + if err != nil { + return fmt.Errorf("relayer bech32 wallet address: %w", err) + } + msg := &rdktypes.MsgSendTransfer{ + ChannelId: channelID, + Signer: signer, + } + + return cc.simpleSend(ctx, msg, func(signer string) { + msg.Signer = signer + }) +} +func (cc *CosmosProvider) simpleSend(ctx context.Context, msg sdk.Msg, f func(string)) error { + m := NewCosmosMessage(msg, f) res, ok, err := cc.SendMessage(ctx, m, "") var code uint32 @@ -1343,7 +1363,8 @@ func (cc *CosmosProvider) MsgChannelCloseConfirm(msgCloseInit provider.ChannelIn // creates an update to trust latest header, using trusted header as a trust basis func (cc *CosmosProvider) MsgUpdateClientHeader(latestHeader provider.IBCHeader, - trustedHeight clienttypes.Height, trustedHeader provider.IBCHeader) (ibcexported.ClientMessage, error) { + trustedHeight clienttypes.Height, trustedHeader provider.IBCHeader, +) (ibcexported.ClientMessage, error) { trustedCosmosHeader, ok := trustedHeader.(provider.TendermintIBCHeader) if !ok { return nil, fmt.Errorf("unsupported IBC trusted header type, expected: TendermintIBCHeader, actual: %T", trustedHeader) diff --git a/relayer/chains/cosmos/tx_test.go b/relayer/chains/cosmos/tx_test.go index 34ee2eabe..4e9bdcb11 100644 --- a/relayer/chains/cosmos/tx_test.go +++ b/relayer/chains/cosmos/tx_test.go @@ -119,7 +119,6 @@ func TestSetWithExtensionOptions(t *testing.T) { require.Equal(t, expectedTypeURL, actualTypeURL) require.Equal(t, expectedValue, actualValue) } - } type mockTxConfig struct { diff --git a/relayer/channel.go b/relayer/channel.go index 6670ce78b..613bc7f3f 100644 --- a/relayer/channel.go +++ b/relayer/channel.go @@ -24,15 +24,21 @@ func (c *Chain) blockUntilClientIsCanonical(ctx context.Context) error { return retry.Do(func() error { err := TrySetCanonicalClient(ctx, c, expClient) // TODO: check if ctx has deadline if err != nil { - needle := "not at least one cons state matches the rollapp state" // hacky :( - if !strings.Contains(err.Error(), needle) { - // something really wrong - c.log.Info("BlockUntilClientIsCanonical try set canonical client.", zap.Error(err)) - return retry.Unrecoverable(err) + acceptable := []string{ + "latest rollapp height: not found", + "not at least one cons state matches the rollapp state", } - // just need to wait for sequencer to catch up + for _, needle := range acceptable { + if strings.Contains(err.Error(), needle) { + // just need to wait for sequencer to catch up + return err + } + } + // something really wrong + c.log.Info("BlockUntilClientIsCanonical try set canonical client.", zap.Error(err)) + return retry.Unrecoverable(err) } - return err + return nil }, retry.Attempts(0), // forever retry.Delay(20*time.Second), diff --git a/relayer/path.go b/relayer/path.go index cf949bcc9..34664c531 100644 --- a/relayer/path.go +++ b/relayer/path.go @@ -35,7 +35,7 @@ func (p Paths) Get(name string) (path *Path, err error) { if pth, ok := p[name]; ok { path = pth } else { - err = fmt.Errorf("path with name %s does not exist", name) + err = fmt.Errorf("path with name does not exist: name: %s", name) } return } diff --git a/relayer/processor/path_end_runtime.go b/relayer/processor/path_end_runtime.go index 23edc942e..e1005afe6 100644 --- a/relayer/processor/path_end_runtime.go +++ b/relayer/processor/path_end_runtime.go @@ -2,6 +2,7 @@ package processor import ( "context" + "errors" "fmt" "sync" "time" @@ -287,6 +288,44 @@ func (pathEnd *pathEndRuntime) handleCallbacks(c IBCMessagesCache) { } } +func SendGenesisTransfer( + ctx context.Context, + hubC provider.ChainProvider, + raC provider.ChainProvider, +) error { + + hub, ok := hubC.(provider.DymensionHubProvider) + if !ok { + return errors.New("not dymension hub provider") + } + + channelID, err := hub.GetCanonicalChan(ctx, raC.ChainId()) + if err != nil { + return fmt.Errorf("get canonical chan: %w", err) + } + + ra, ok := raC.(provider.RollappProvider) + if !ok { + return errors.New("not rollapp provider") + } + return ra.TrySendGenesisTransfer(ctx, channelID) +} + +// DYMENSION +func (pathEnd *pathEndRuntime) handleDymensionCallbacks(ctx context.Context, counterParty *pathEndRuntime, c IBCMessagesCache) { + if pathEnd.chainProvider.IsDymensionRollapp() { + _, ok := c.ChannelHandshake[chantypes.EventTypeChannelOpenConfirm] + if !ok { + return + } + pathEnd.log.Debug("Handling dymension callbacks: open confirm.") + err := SendGenesisTransfer(ctx, counterParty.chainProvider, pathEnd.chainProvider) + if err != nil { + pathEnd.log.Error("Send rollapp genesis transfer to hub. Operator should retry using CLI.", zap.Error(err)) + } + } +} + func (pathEnd *pathEndRuntime) shouldTerminate(ibcMessagesCache IBCMessagesCache, messageLifecycle MessageLifecycle) bool { if messageLifecycle == nil { return false @@ -476,6 +515,7 @@ func (pathEnd *pathEndRuntime) mergeCacheData( messageLifecycle MessageLifecycle, counterParty *pathEndRuntime, memoLimit, maxReceiverSize int, + counterparty *pathEndRuntime, ) { pathEnd.lastClientUpdateHeightMu.Lock() var zeroType provider.LatestBlock @@ -509,6 +549,8 @@ func (pathEnd *pathEndRuntime) mergeCacheData( pathEnd.handleCallbacks(d.IBCMessagesCache) + pathEnd.handleDymensionCallbacks(ctx, counterparty, d.IBCMessagesCache) + if pathEnd.shouldTerminate(d.IBCMessagesCache, messageLifecycle) || terminate { cancel() return diff --git a/relayer/processor/path_processor.go b/relayer/processor/path_processor.go index 986fc2c04..d9d586809 100644 --- a/relayer/processor/path_processor.go +++ b/relayer/processor/path_processor.go @@ -342,6 +342,7 @@ func (pp *PathProcessor) processAvailableSignals(ctx context.Context, cancel fun pp.pathEnd2, pp.memoLimit, pp.maxReceiverSize, + pp.pathEnd2, ) case d := <-pp.pathEnd2.incomingCacheData: @@ -356,6 +357,7 @@ func (pp *PathProcessor) processAvailableSignals(ctx context.Context, cancel fun pp.pathEnd1, pp.memoLimit, pp.maxReceiverSize, + pp.pathEnd1, ) case <-pp.retryProcess: @@ -374,6 +376,7 @@ func (pp *PathProcessor) processAvailableSignals(ctx context.Context, cancel fun pp.pathEnd2, pp.memoLimit, pp.maxReceiverSize, + pp.pathEnd2, ) } for len(pp.pathEnd2.incomingCacheData) > 0 { @@ -389,6 +392,7 @@ func (pp *PathProcessor) processAvailableSignals(ctx context.Context, cancel fun pp.pathEnd1, pp.memoLimit, pp.maxReceiverSize, + pp.pathEnd1, ) } // Periodic flush to clear out any old packets diff --git a/relayer/processor/rotation_solver.go b/relayer/processor/rotation_solver.go index 48ddc4623..7cff76405 100644 --- a/relayer/processor/rotation_solver.go +++ b/relayer/processor/rotation_solver.go @@ -17,8 +17,10 @@ type rotationSolver struct { log *zap.Logger } -var errFalsePositive = fmt.Errorf("false positive (there is a bug): hub has latest valset") -var errTargetNotFound = fmt.Errorf("target not found") +var ( + errFalsePositive = fmt.Errorf("false positive (there is a bug): hub has latest valset") + errTargetNotFound = fmt.Errorf("target not found") +) // must be sure to run on same thread as message processor func (s *rotationSolver) solve(ctx c.Context) error { @@ -51,7 +53,6 @@ func (s *rotationSolver) solve(ctx c.Context) error { } func (s *rotationSolver) hubClientValset(ctx c.Context) (uint64, []byte, error) { - h := s.hub.clientState.LatestHeight.GetRevisionHeight() header, err := s.ra.chainProvider.QueryIBCHeader(ctx, int64(h)) if err != nil { @@ -139,7 +140,6 @@ func search(sleep time.Duration, l, r uint64, direction func(uint64) (int, error // a = h, b = h+1 where valhash changes in between func (s *rotationSolver) sendUpdatesV2(ctx c.Context, a, b provider.IBCHeader) error { - trusted, err := s.ra.chainProvider.QueryIBCHeader(ctx, int64(s.hub.clientState.LatestHeight.GetRevisionHeight())+1) if err != nil { return fmt.Errorf("query ibc header: %w", err) @@ -150,7 +150,6 @@ func (s *rotationSolver) sendUpdatesV2(ctx c.Context, a, b provider.IBCHeader) e s.hub.clientState.LatestHeight, trusted, // latest+1 ) - if err != nil { return fmt.Errorf("create msg update client header: %w", err) } diff --git a/relayer/processor/rotation_solver_test.go b/relayer/processor/rotation_solver_test.go index 21b087213..92ac0047e 100644 --- a/relayer/processor/rotation_solver_test.go +++ b/relayer/processor/rotation_solver_test.go @@ -11,7 +11,6 @@ func TestRotationSolverSearch(t *testing.T) { // our search function is looking for the first index in the array where the value changes from needle t.Run("basic 1", func(t *testing.T) { - haystack := []int{0, 0, 0, 1, 1, 1} l := 1 r := len(haystack) - 1 @@ -21,7 +20,6 @@ func TestRotationSolverSearch(t *testing.T) { }) t.Run("basic 2", func(t *testing.T) { - haystack := []int{0, 0, 0, 1, 1, 1, 2, 2, 2} l := 4 r := len(haystack) - 1 @@ -29,7 +27,6 @@ func TestRotationSolverSearch(t *testing.T) { require.NoError(t, err) require.Equal(t, 6, int(ans)) }) - } func createCheckFun(lowerLimit int, haystack []int, needle int) func(uint64) (int, error) { diff --git a/relayer/provider/provider.go b/relayer/provider/provider.go index c672e89c3..a0972f4d7 100644 --- a/relayer/provider/provider.go +++ b/relayer/provider/provider.go @@ -419,6 +419,11 @@ type ChainProvider interface { type DymensionHubProvider interface { TrySetCanonicalClient(ctx context.Context, clientID string) error + GetCanonicalChan(ctx context.Context, rollappID string) (string, error) +} + +type RollappProvider interface { + TrySendGenesisTransfer(ctx context.Context, channelID string) error } // Do we need intermediate types? i.e. can we use the SDK types for both substrate and cosmos?