From 86e23b474e2d311a114e34150b2fcdcf33521558 Mon Sep 17 00:00:00 2001 From: Daisuke Kanda Date: Fri, 22 Aug 2025 15:19:10 +0000 Subject: [PATCH 1/3] add debug prover and debug chain module for testing fake lost of chain state Signed-off-by: Daisuke Kanda --- chains/debug/chain.go | 77 +++++ chains/debug/codec.go | 15 + chains/debug/config.go | 45 +++ chains/debug/config.pb.go | 325 ++++++++++++++++++ chains/debug/module/module.go | 27 ++ chains/debug/query.go | 121 +++++++ coreutil/unwrap.go | 6 + main.go | 4 + .../relayer/chains/debug/config/config.proto | 13 + .../relayer/provers/debug/config/config.proto | 12 + provers/debug/codec.go | 14 + provers/debug/config.go | 45 +++ provers/debug/config.pb.go | 325 ++++++++++++++++++ provers/debug/module/module.go | 27 ++ provers/debug/prover.go | 130 +++++++ tests/cases/tm2tm/configs/demo/ibc-0.json | 34 +- tests/cases/tm2tm/configs/demo/ibc-1.json | 34 +- 17 files changed, 1226 insertions(+), 28 deletions(-) create mode 100644 chains/debug/chain.go create mode 100644 chains/debug/codec.go create mode 100644 chains/debug/config.go create mode 100644 chains/debug/config.pb.go create mode 100644 chains/debug/module/module.go create mode 100644 chains/debug/query.go create mode 100644 proto/relayer/chains/debug/config/config.proto create mode 100644 proto/relayer/provers/debug/config/config.proto create mode 100644 provers/debug/codec.go create mode 100644 provers/debug/config.go create mode 100644 provers/debug/config.pb.go create mode 100644 provers/debug/module/module.go create mode 100644 provers/debug/prover.go diff --git a/chains/debug/chain.go b/chains/debug/chain.go new file mode 100644 index 00000000..90385edf --- /dev/null +++ b/chains/debug/chain.go @@ -0,0 +1,77 @@ +package debug + +import ( + "context" + "time" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" + + "github.com/hyperledger-labs/yui-relayer/core" +) + +type Chain struct { + config ChainConfig + OriginChain core.Chain +} + +var _ core.Chain = (*Chain)(nil) + +func (c *Chain) ChainID() string { + return c.OriginChain.ChainID() +} + +func (c *Chain) Config() ChainConfig { + return c.config +} + +func (c *Chain) Codec() codec.ProtoCodecMarshaler { + return c.OriginChain.Codec() +} + +func (c *Chain) GetAddress() (sdk.AccAddress, error) { + return c.OriginChain.GetAddress() +} + +// SetRelayInfo sets source's path and counterparty's info to the chain +func (c *Chain) SetRelayInfo(path *core.PathEnd, counterparty *core.ProvableChain, counterpartyPath *core.PathEnd) error { + return c.OriginChain.SetRelayInfo(path, counterparty, counterpartyPath) +} + +func (c *Chain) Path() *core.PathEnd { + return c.OriginChain.Path() +} + +func (c *Chain) Init(homePath string, timeout time.Duration, codec codec.ProtoCodecMarshaler, debug bool) error { + return c.OriginChain.Init(homePath, timeout, codec, debug) +} + +func (c *Chain) SetupForRelay(ctx context.Context) error { + return c.OriginChain.SetupForRelay(ctx) +} + +// LatestHeight queries the chain for the latest height and returns it +func (c *Chain) LatestHeight(ctx context.Context) (ibcexported.Height, error) { + return c.OriginChain.LatestHeight(ctx) +} + +func (c *Chain) Timestamp(ctx context.Context, height ibcexported.Height) (time.Time, error) { + return c.OriginChain.Timestamp(ctx, height) +} + +func (c *Chain) AverageBlockTime() time.Duration { + return c.OriginChain.AverageBlockTime() +} + +func (c *Chain) RegisterMsgEventListener(listener core.MsgEventListener) { + c.OriginChain.RegisterMsgEventListener(listener) +} + +func (c *Chain) SendMsgs(ctx context.Context, msgs []sdk.Msg) ([]core.MsgID, error) { + return c.OriginChain.SendMsgs(ctx, msgs) +} + +func (c *Chain) GetMsgResult(ctx context.Context, id core.MsgID) (core.MsgResult, error) { + return c.OriginChain.GetMsgResult(ctx, id) +} diff --git a/chains/debug/codec.go b/chains/debug/codec.go new file mode 100644 index 00000000..c739613a --- /dev/null +++ b/chains/debug/codec.go @@ -0,0 +1,15 @@ +package debug + +import ( + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/hyperledger-labs/yui-relayer/core" +) + +// RegisterInterfaces register the module interfaces to protobuf +// Any. +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*core.ChainConfig)(nil), + &ChainConfig{}, + ) +} diff --git a/chains/debug/config.go b/chains/debug/config.go new file mode 100644 index 00000000..e605560c --- /dev/null +++ b/chains/debug/config.go @@ -0,0 +1,45 @@ +package debug + +import ( + "fmt" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/hyperledger-labs/yui-relayer/core" +) + +var _ core.ChainConfig = (*ChainConfig)(nil) + +var _ codectypes.UnpackInterfacesMessage = (*ChainConfig)(nil) + +func (cfg *ChainConfig) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + if cfg == nil { + return nil + } + if err := unpacker.UnpackAny(cfg.OriginChain, new(core.ChainConfig)); err != nil { + return err + } + return nil +} + +func (c ChainConfig) Build() (core.Chain, error) { + if c.OriginChain == nil { + return nil, fmt.Errorf("OriginChain must be set") + } + if c.OriginChain.GetCachedValue() == nil { + return nil, fmt.Errorf("OriginChain.GetCachedValue() must be set") + } + + originChain, err := c.OriginChain.GetCachedValue().(core.ChainConfig).Build() + if err != nil { + return nil, err + } + + return &Chain{ + config: c, + OriginChain: originChain, + }, nil +} + +func (c ChainConfig) Validate() error { + return nil +} diff --git a/chains/debug/config.pb.go b/chains/debug/config.pb.go new file mode 100644 index 00000000..cd2f93ba --- /dev/null +++ b/chains/debug/config.pb.go @@ -0,0 +1,325 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: relayer/chains/debug/config/config.proto + +package debug + +import ( + fmt "fmt" + types "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + 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 ChainConfig struct { + OriginChain *types.Any `protobuf:"bytes,1,opt,name=origin_chain,json=originChain,proto3" json:"origin_chain,omitempty"` +} + +func (m *ChainConfig) Reset() { *m = ChainConfig{} } +func (m *ChainConfig) String() string { return proto.CompactTextString(m) } +func (*ChainConfig) ProtoMessage() {} +func (*ChainConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_dc678f0806ea870f, []int{0} +} +func (m *ChainConfig) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ChainConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ChainConfig.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 *ChainConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChainConfig.Merge(m, src) +} +func (m *ChainConfig) XXX_Size() int { + return m.Size() +} +func (m *ChainConfig) XXX_DiscardUnknown() { + xxx_messageInfo_ChainConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_ChainConfig proto.InternalMessageInfo + +func init() { + proto.RegisterType((*ChainConfig)(nil), "relayer.chains.debug.config.ChainConfig") +} + +func init() { + proto.RegisterFile("relayer/chains/debug/config/config.proto", fileDescriptor_dc678f0806ea870f) +} + +var fileDescriptor_dc678f0806ea870f = []byte{ + // 226 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x28, 0x4a, 0xcd, 0x49, + 0xac, 0x4c, 0x2d, 0xd2, 0x4f, 0xce, 0x48, 0xcc, 0xcc, 0x2b, 0xd6, 0x4f, 0x49, 0x4d, 0x2a, 0x4d, + 0xd7, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x84, 0x51, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0xd2, + 0x50, 0x95, 0x7a, 0x10, 0x95, 0x7a, 0x60, 0x95, 0x7a, 0x10, 0x25, 0x52, 0x22, 0xe9, 0xf9, 0xe9, + 0xf9, 0x60, 0x75, 0xfa, 0x20, 0x16, 0x44, 0x8b, 0x94, 0x64, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, + 0x3e, 0x98, 0x97, 0x54, 0x9a, 0xa6, 0x9f, 0x98, 0x57, 0x09, 0x91, 0x52, 0x72, 0xe3, 0xe2, 0x76, + 0x06, 0x99, 0xe3, 0x0c, 0xd6, 0x2f, 0x64, 0xce, 0xc5, 0x93, 0x5f, 0x94, 0x99, 0x9e, 0x99, 0x17, + 0x0f, 0x36, 0x5d, 0x82, 0x51, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x44, 0x0f, 0x62, 0x80, 0x1e, 0xcc, + 0x00, 0x3d, 0xc7, 0xbc, 0xca, 0x20, 0x6e, 0x88, 0x4a, 0xb0, 0x76, 0xa7, 0xa0, 0x13, 0x0f, 0xe5, + 0x18, 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, 0x24, 0x3d, 0xb3, 0x24, + 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x3f, 0xa3, 0xb2, 0x20, 0xb5, 0x28, 0x27, 0x35, 0x25, + 0x3d, 0xb5, 0x48, 0x37, 0x27, 0x31, 0xa9, 0x58, 0xbf, 0xb2, 0x34, 0x53, 0x17, 0x9b, 0xef, 0x93, + 0xd8, 0xc0, 0xd6, 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc5, 0xcc, 0x8c, 0x24, 0x1c, 0x01, + 0x00, 0x00, +} + +func (m *ChainConfig) 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 *ChainConfig) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ChainConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.OriginChain != nil { + { + size, err := m.OriginChain.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConfig(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintConfig(dAtA []byte, offset int, v uint64) int { + offset -= sovConfig(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ChainConfig) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.OriginChain != nil { + l = m.OriginChain.Size() + n += 1 + l + sovConfig(uint64(l)) + } + return n +} + +func sovConfig(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozConfig(x uint64) (n int) { + return sovConfig(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ChainConfig) 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 ErrIntOverflowConfig + } + 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: ChainConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ChainConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OriginChain", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthConfig + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthConfig + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.OriginChain == nil { + m.OriginChain = &types.Any{} + } + if err := m.OriginChain.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipConfig(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConfig + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipConfig(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, ErrIntOverflowConfig + } + 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, ErrIntOverflowConfig + } + 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, ErrIntOverflowConfig + } + 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, ErrInvalidLengthConfig + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupConfig + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthConfig + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthConfig = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowConfig = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupConfig = fmt.Errorf("proto: unexpected end of group") +) diff --git a/chains/debug/module/module.go b/chains/debug/module/module.go new file mode 100644 index 00000000..8609c107 --- /dev/null +++ b/chains/debug/module/module.go @@ -0,0 +1,27 @@ +package module + +import ( + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/hyperledger-labs/yui-relayer/chains/debug" + "github.com/hyperledger-labs/yui-relayer/config" + "github.com/spf13/cobra" +) + +type Module struct{} + +var _ config.ModuleI = (*Module)(nil) + +// Name returns the name of the module +func (Module) Name() string { + return "debug" +} + +// RegisterInterfaces register the module interfaces to protobuf Any. +func (Module) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + debug.RegisterInterfaces(registry) +} + +// GetCmd returns the command +func (Module) GetCmd(ctx *config.Context) *cobra.Command { + return nil +} diff --git a/chains/debug/query.go b/chains/debug/query.go new file mode 100644 index 00000000..38b7b250 --- /dev/null +++ b/chains/debug/query.go @@ -0,0 +1,121 @@ +package debug + +import ( + "context" + "fmt" + "os" + "strconv" + + sdk "github.com/cosmos/cosmos-sdk/types" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + chantypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" + "github.com/hyperledger-labs/yui-relayer/core" + "github.com/hyperledger-labs/yui-relayer/log" +) + +func debugFakeLost(ctx context.Context, chain *Chain, queryHeight ibcexported.Height) error { + logger := log.GetLogger() + env := fmt.Sprintf("DEBUG_RELAYER_PRUNE_AFTER_BLOCKS_CHAIN_%s", chain.ChainID()) + if val, ok := os.LookupEnv(env); ok { + logger.Debug(env, "chain", chain.ChainID(), "value", val) + + threshold, err := strconv.Atoi(val) + if err != nil { + logger.ErrorContext(ctx, "malformed value", err, "value", val) + return err + } + + qh := int64(queryHeight.GetRevisionHeight()) + + latestHeight, err := chain.LatestHeight(ctx) + if err != nil { + return err + } + lh := int64(latestHeight.GetRevisionHeight()) + + if qh+int64(threshold) < lh { + return fmt.Errorf("fake missing trie node: %v + %v < %v", qh, threshold, lh) + } + } + return nil +} + +func (c *Chain) QueryClientState(ctx core.QueryContext) (*clienttypes.QueryClientStateResponse, error) { + if err := debugFakeLost(ctx.Context(), c, ctx.Height()); err != nil { + return nil, err + } + return c.OriginChain.QueryClientState(ctx) +} + +func (c *Chain) QueryConnection(ctx core.QueryContext, connectionID string) (*conntypes.QueryConnectionResponse, error) { + if err := debugFakeLost(ctx.Context(), c, ctx.Height()); err != nil { + return nil, err + } + return c.OriginChain.QueryConnection(ctx, connectionID) +} + +func (c *Chain) QueryChannel(ctx core.QueryContext) (chanRes *chantypes.QueryChannelResponse, err error) { + if err := debugFakeLost(ctx.Context(), c, ctx.Height()); err != nil { + return nil, err + } + return c.OriginChain.QueryChannel(ctx) +} + +func (c *Chain) QueryClientConsensusState( + ctx core.QueryContext, dstClientConsHeight ibcexported.Height) (*clienttypes.QueryConsensusStateResponse, error) { + if err := debugFakeLost(ctx.Context(), c, ctx.Height()); err != nil { + return nil, err + } + return c.OriginChain.QueryClientConsensusState(ctx, dstClientConsHeight) +} + +func (c *Chain) QueryBalance(ctx core.QueryContext, addr sdk.AccAddress) (sdk.Coins, error) { + return c.OriginChain.QueryBalance(ctx, addr) +} + +func (c *Chain) QueryDenomTraces(ctx core.QueryContext, offset, limit uint64) (*transfertypes.QueryDenomTracesResponse, error) { + return c.OriginChain.QueryDenomTraces(ctx, offset, limit) +} + +func (c *Chain) QueryUnreceivedPackets(ctx core.QueryContext, seqs []uint64) ([]uint64, error) { + if err := debugFakeLost(ctx.Context(), c, ctx.Height()); err != nil { + return nil, err + } + return c.OriginChain.QueryUnreceivedPackets(ctx, seqs) +} + +func (c *Chain) QueryUnfinalizedRelayPackets(ctx core.QueryContext, counterparty core.LightClientICS04Querier) (core.PacketInfoList, error) { + return c.OriginChain.QueryUnfinalizedRelayPackets(ctx, counterparty) +} + +func (c *Chain) QueryUnreceivedAcknowledgements(ctx core.QueryContext, seqs []uint64) ([]uint64, error) { + if err := debugFakeLost(ctx.Context(), c, ctx.Height()); err != nil { + return nil, err + } + return c.OriginChain.QueryUnreceivedAcknowledgements(ctx, seqs) +} + +func (c *Chain) QueryUnfinalizedRelayAcknowledgements(ctx core.QueryContext, counterparty core.LightClientICS04Querier) (core.PacketInfoList, error) { + return c.OriginChain.QueryUnfinalizedRelayAcknowledgements(ctx, counterparty) +} + +func (c *Chain) QueryChannelUpgrade(ctx core.QueryContext) (*chantypes.QueryUpgradeResponse, error) { + if err := debugFakeLost(ctx.Context(), c, ctx.Height()); err != nil { + return nil, err + } + return c.OriginChain.QueryChannelUpgrade(ctx) +} + +func (c *Chain) QueryChannelUpgradeError(ctx core.QueryContext) (*chantypes.QueryUpgradeErrorResponse, error) { + return c.OriginChain.QueryChannelUpgradeError(ctx) +} + +func (c *Chain) QueryCanTransitionToFlushComplete(ctx core.QueryContext) (bool, error) { + if err := debugFakeLost(ctx.Context(), c, ctx.Height()); err != nil { + return false, err + } + return c.OriginChain.QueryCanTransitionToFlushComplete(ctx) +} diff --git a/coreutil/unwrap.go b/coreutil/unwrap.go index bb5c45b9..99e36089 100644 --- a/coreutil/unwrap.go +++ b/coreutil/unwrap.go @@ -3,8 +3,10 @@ package coreutil import ( "fmt" + debugchain "github.com/hyperledger-labs/yui-relayer/chains/debug" "github.com/hyperledger-labs/yui-relayer/core" "github.com/hyperledger-labs/yui-relayer/otelcore" + debugprover "github.com/hyperledger-labs/yui-relayer/provers/debug" ) // UnwrapChain finds the first struct value in the Chain field that matches the specified @@ -17,6 +19,8 @@ func UnwrapChain[C core.Chain](c core.Chain) (C, error) { chain := c for { switch unwrapped := chain.(type) { + case *debugchain.Chain: + return UnwrapChain[C](unwrapped.OriginChain) case *core.ProvableChain: chain = unwrapped.Chain case *otelcore.Chain: @@ -40,6 +44,8 @@ func UnwrapProver[P core.Prover](p core.Prover) (P, error) { prover := p for { switch unwrapped := prover.(type) { + case *debugprover.Prover: + return UnwrapProver[P](unwrapped.OriginProver) case *core.ProvableChain: prover = unwrapped.Prover case *otelcore.Prover: diff --git a/main.go b/main.go index af7c0e66..3eb5e566 100644 --- a/main.go +++ b/main.go @@ -3,8 +3,10 @@ package main import ( "log" + debug_chain "github.com/hyperledger-labs/yui-relayer/chains/debug/module" tendermint "github.com/hyperledger-labs/yui-relayer/chains/tendermint/module" "github.com/hyperledger-labs/yui-relayer/cmd" + debug_prover "github.com/hyperledger-labs/yui-relayer/provers/debug/module" mock "github.com/hyperledger-labs/yui-relayer/provers/mock/module" ) @@ -12,6 +14,8 @@ func main() { if err := cmd.Execute( tendermint.Module{}, mock.Module{}, + debug_chain.Module{}, + debug_prover.Module{}, ); err != nil { log.Fatal(err) } diff --git a/proto/relayer/chains/debug/config/config.proto b/proto/relayer/chains/debug/config/config.proto new file mode 100644 index 00000000..b51978a6 --- /dev/null +++ b/proto/relayer/chains/debug/config/config.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +package relayer.chains.debug.config; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/hyperledger-labs/yui-relayer/chains/debug"; +option (gogoproto.goproto_getters_all) = false; + +message ChainConfig { + google.protobuf.Any origin_chain = 1; +} + diff --git a/proto/relayer/provers/debug/config/config.proto b/proto/relayer/provers/debug/config/config.proto new file mode 100644 index 00000000..fcce9836 --- /dev/null +++ b/proto/relayer/provers/debug/config/config.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package relayer.provers.debug.config; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/hyperledger-labs/yui-relayer/provers/debug"; +option (gogoproto.goproto_getters_all) = false; + +message ProverConfig { + google.protobuf.Any origin_prover = 1; +} diff --git a/provers/debug/codec.go b/provers/debug/codec.go new file mode 100644 index 00000000..73d8eb4b --- /dev/null +++ b/provers/debug/codec.go @@ -0,0 +1,14 @@ +package debug + +import ( + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/hyperledger-labs/yui-relayer/core" +) + +// RegisterInterfaces register the module interfaces to protobuf Any. +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*core.ProverConfig)(nil), + &ProverConfig{}, + ) +} diff --git a/provers/debug/config.go b/provers/debug/config.go new file mode 100644 index 00000000..4efc5c75 --- /dev/null +++ b/provers/debug/config.go @@ -0,0 +1,45 @@ +package debug + +import ( + "fmt" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/hyperledger-labs/yui-relayer/core" +) + +var _ core.ProverConfig = (*ProverConfig)(nil) + +var _ codectypes.UnpackInterfacesMessage = (*ProverConfig)(nil) + +func (cfg *ProverConfig) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + if cfg == nil { + return nil + } + if err := unpacker.UnpackAny(cfg.OriginProver, new(core.ProverConfig)); err != nil { + return err + } + return nil +} + +func (pc ProverConfig) Build(chain core.Chain) (core.Prover, error) { + if err := pc.Validate(); err != nil { + return nil, err + } + + if pc.OriginProver == nil { + return nil, fmt.Errorf("OriginProver must be set") + } + if pc.OriginProver.GetCachedValue() == nil { + return nil, fmt.Errorf("OriginProver.GetCachedValue() must be set") + } + originProver, err := pc.OriginProver.GetCachedValue().(core.ProverConfig).Build(chain) + if err != nil { + return nil, err + } + prover := NewProver(chain, originProver) + return prover, nil +} + +func (c ProverConfig) Validate() error { + return nil +} diff --git a/provers/debug/config.pb.go b/provers/debug/config.pb.go new file mode 100644 index 00000000..04bfb314 --- /dev/null +++ b/provers/debug/config.pb.go @@ -0,0 +1,325 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: relayer/provers/debug/config/config.proto + +package debug + +import ( + fmt "fmt" + types "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + 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 ProverConfig struct { + OriginProver *types.Any `protobuf:"bytes,1,opt,name=origin_prover,json=originProver,proto3" json:"origin_prover,omitempty"` +} + +func (m *ProverConfig) Reset() { *m = ProverConfig{} } +func (m *ProverConfig) String() string { return proto.CompactTextString(m) } +func (*ProverConfig) ProtoMessage() {} +func (*ProverConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_36e45da015571dc5, []int{0} +} +func (m *ProverConfig) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ProverConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ProverConfig.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 *ProverConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProverConfig.Merge(m, src) +} +func (m *ProverConfig) XXX_Size() int { + return m.Size() +} +func (m *ProverConfig) XXX_DiscardUnknown() { + xxx_messageInfo_ProverConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_ProverConfig proto.InternalMessageInfo + +func init() { + proto.RegisterType((*ProverConfig)(nil), "relayer.provers.debug.config.ProverConfig") +} + +func init() { + proto.RegisterFile("relayer/provers/debug/config/config.proto", fileDescriptor_36e45da015571dc5) +} + +var fileDescriptor_36e45da015571dc5 = []byte{ + // 227 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2c, 0x4a, 0xcd, 0x49, + 0xac, 0x4c, 0x2d, 0xd2, 0x2f, 0x28, 0xca, 0x2f, 0x4b, 0x2d, 0x2a, 0xd6, 0x4f, 0x49, 0x4d, 0x2a, + 0x4d, 0xd7, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x84, 0x51, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, + 0x32, 0x50, 0xa5, 0x7a, 0x50, 0xa5, 0x7a, 0x60, 0xa5, 0x7a, 0x10, 0x35, 0x52, 0x22, 0xe9, 0xf9, + 0xe9, 0xf9, 0x60, 0x85, 0xfa, 0x20, 0x16, 0x44, 0x8f, 0x94, 0x64, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, + 0xaa, 0x3e, 0x98, 0x97, 0x54, 0x9a, 0xa6, 0x9f, 0x98, 0x57, 0x09, 0x91, 0x52, 0xf2, 0xe4, 0xe2, + 0x09, 0x00, 0x1b, 0xe4, 0x0c, 0x36, 0x40, 0xc8, 0x92, 0x8b, 0x37, 0xbf, 0x28, 0x33, 0x3d, 0x33, + 0x2f, 0x1e, 0x62, 0xbe, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0x88, 0x1e, 0xc4, 0x08, 0x3d, + 0x98, 0x11, 0x7a, 0x8e, 0x79, 0x95, 0x41, 0x3c, 0x10, 0xa5, 0x10, 0x03, 0x9c, 0x82, 0x4f, 0x3c, + 0x94, 0x63, 0x38, 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, 0xd3, 0xf4, 0xcc, + 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0xfd, 0x8c, 0xca, 0x82, 0xd4, 0xa2, 0x9c, 0xd4, + 0x94, 0xf4, 0xd4, 0x22, 0xdd, 0x9c, 0xc4, 0xa4, 0x62, 0xfd, 0xca, 0xd2, 0x4c, 0x5d, 0xac, 0x41, + 0x90, 0xc4, 0x06, 0xb6, 0xd0, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xb4, 0x21, 0x30, 0x54, 0x22, + 0x01, 0x00, 0x00, +} + +func (m *ProverConfig) 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 *ProverConfig) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ProverConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.OriginProver != nil { + { + size, err := m.OriginProver.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConfig(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintConfig(dAtA []byte, offset int, v uint64) int { + offset -= sovConfig(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ProverConfig) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.OriginProver != nil { + l = m.OriginProver.Size() + n += 1 + l + sovConfig(uint64(l)) + } + return n +} + +func sovConfig(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozConfig(x uint64) (n int) { + return sovConfig(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ProverConfig) 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 ErrIntOverflowConfig + } + 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: ProverConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ProverConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OriginProver", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConfig + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthConfig + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthConfig + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.OriginProver == nil { + m.OriginProver = &types.Any{} + } + if err := m.OriginProver.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipConfig(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthConfig + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipConfig(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, ErrIntOverflowConfig + } + 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, ErrIntOverflowConfig + } + 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, ErrIntOverflowConfig + } + 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, ErrInvalidLengthConfig + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupConfig + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthConfig + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthConfig = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowConfig = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupConfig = fmt.Errorf("proto: unexpected end of group") +) diff --git a/provers/debug/module/module.go b/provers/debug/module/module.go new file mode 100644 index 00000000..826dfc94 --- /dev/null +++ b/provers/debug/module/module.go @@ -0,0 +1,27 @@ +package module + +import ( + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/hyperledger-labs/yui-relayer/config" + debugprover "github.com/hyperledger-labs/yui-relayer/provers/debug" + "github.com/spf13/cobra" +) + +type Module struct{} + +var _ config.ModuleI = (*Module)(nil) + +// Name returns the name of the module +func (Module) Name() string { + return "debug-client" +} + +// RegisterInterfaces register the module interfaces to protobuf Any. +func (Module) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + debugprover.RegisterInterfaces(registry) +} + +// GetCmd returns the command +func (Module) GetCmd(ctx *config.Context) *cobra.Command { + return nil +} diff --git a/provers/debug/prover.go b/provers/debug/prover.go new file mode 100644 index 00000000..ff2cb0dc --- /dev/null +++ b/provers/debug/prover.go @@ -0,0 +1,130 @@ +package debug + +import ( + "context" + fmt "fmt" + "os" + "strconv" + "time" + + "github.com/cosmos/cosmos-sdk/codec" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v8/modules/core/exported" + + "github.com/hyperledger-labs/yui-relayer/core" + "github.com/hyperledger-labs/yui-relayer/log" +) + +func debugFakeLost(ctx context.Context, chain core.Chain, queryHeight exported.Height) error { + logger := log.GetLogger() + env := fmt.Sprintf("DEBUG_RELAYER_PRUNE_AFTER_BLOCKS_PROVER_%s", chain.ChainID()) + if val, ok := os.LookupEnv(env); ok { + logger.Info(fmt.Sprintf(">%s: chain=%s: '%v'", env, chain.ChainID(), val)) + + threshold, err := strconv.Atoi(val) + if err != nil { + logger.ErrorContext(ctx, "malformed value", err, "value", val) + return err + } + + qh := int64(queryHeight.GetRevisionHeight()) + + latestHeight, err := chain.LatestHeight(ctx) + if err != nil { + return err + } + lh := int64(latestHeight.GetRevisionHeight()) + + if qh+int64(threshold) < lh { + return fmt.Errorf("fake missing trie node: %v + %v < %v", qh, threshold, lh) + } + } + return nil +} + +type Prover struct { + chain core.Chain + OriginProver core.Prover +} + +var _ core.Prover = (*Prover)(nil) + +func NewProver(chain core.Chain, originProver core.Prover) *Prover { + return &Prover{OriginProver: originProver, chain: chain} +} + +func (pr *Prover) Init(homePath string, timeout time.Duration, codec codec.ProtoCodecMarshaler, debug bool) error { + logger := log.GetLogger() + logger.Info("debug prover is initialized.") + return pr.OriginProver.Init(homePath, timeout, codec, debug) +} + +// SetRelayInfo sets source's path and counterparty's info to the chain +func (pr *Prover) SetRelayInfo(path *core.PathEnd, counterparty *core.ProvableChain, counterpartyPath *core.PathEnd) error { + return pr.OriginProver.SetRelayInfo(path, counterparty, counterpartyPath) +} + +func (pr *Prover) SetupForRelay(ctx context.Context) error { + return pr.OriginProver.SetupForRelay(ctx) +} + +/* LightClient implementation */ + +// CreateInitialLightClientState creates a pair of ClientState and ConsensusState for building MsgCreateClient submitted to the counterparty chain +func (pr *Prover) CreateInitialLightClientState(ctx context.Context, height exported.Height) (exported.ClientState, exported.ConsensusState, error) { + return pr.OriginProver.CreateInitialLightClientState(ctx, height) +} + +// SetupHeadersForUpdate returns the finalized header and any intermediate headers needed to apply it to the client on the counterparty chain +func (pr *Prover) SetupHeadersForUpdate(ctx context.Context, counterparty core.FinalityAwareChain, latestFinalizedHeader core.Header) (<-chan *core.HeaderOrError, error) { + logger := log.GetLogger() + headerStream, err := pr.OriginProver.SetupHeadersForUpdate(ctx, counterparty, latestFinalizedHeader) + if err != nil { + return headerStream, err + } + + env := fmt.Sprintf("DEBUG_RELAYER_SHFU_WAIT_%s", pr.chain.ChainID()) + + if val, ok := os.LookupEnv(env); ok { + logger.Debug(env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "value", val) + t, err := strconv.Atoi(val) + if err != nil { + logger.ErrorContext(ctx, "malformed value", err, "value", val) + return nil, err + } + + lap := 60 + n := t / lap + for i := 0; i < n; i++ { + logger.Debug(env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "lap", fmt.Sprintf("%v/%v", (i+1)*lap, t)) + time.Sleep(time.Duration(lap) * time.Second) + } + logger.Debug(env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "lap", fmt.Sprintf("%v/%v", t-n*lap, t)) + time.Sleep(time.Duration(t-n*lap) * time.Second) + logger.Debug(env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "done", t) + } + return headerStream, nil +} + +// GetLatestFinalizedHeader returns the latest finalized header +func (pr *Prover) GetLatestFinalizedHeader(ctx context.Context) (core.Header, error) { + return pr.OriginProver.GetLatestFinalizedHeader(ctx) +} + +// CheckRefreshRequired returns if the on-chain light client needs to be updated. +func (pr *Prover) CheckRefreshRequired(ctx context.Context, dst core.ChainInfoICS02Querier) (bool, error) { + return pr.OriginProver.CheckRefreshRequired(ctx, dst) +} + +// ProveState returns the proof of an IBC state specified by `path` and `value` +func (pr *Prover) ProveState(ctx core.QueryContext, path string, value []byte) ([]byte, clienttypes.Height, error) { + if err := debugFakeLost(ctx.Context(), pr.chain, ctx.Height()); err != nil { + return nil, clienttypes.Height{}, err + } + return pr.OriginProver.ProveState(ctx, path, value) +} + +// ProveHostConsensusState returns the proof of the consensus state at `height` +func (pr *Prover) ProveHostConsensusState(ctx core.QueryContext, height exported.Height, consensusState exported.ConsensusState) ([]byte, error) { + return pr.OriginProver.ProveHostConsensusState(ctx, height, consensusState) +} diff --git a/tests/cases/tm2tm/configs/demo/ibc-0.json b/tests/cases/tm2tm/configs/demo/ibc-0.json index 9f2b22e1..048fb20d 100644 --- a/tests/cases/tm2tm/configs/demo/ibc-0.json +++ b/tests/cases/tm2tm/configs/demo/ibc-0.json @@ -1,21 +1,27 @@ { "chain": { - "@type": "/relayer.chains.tendermint.config.ChainConfig", - "key": "testkey", - "chain_id": "ibc0", - "rpc_addr": "http://localhost:26657", - "account_prefix": "cosmos", - "gas_adjustment": 1.5, - "gas_prices": "0.025stake", - "average_block_time_msec": 1000, - "max_retry_for_commit": 5 + "@type": "/relayer.chains.debug.config.ChainConfig", + "origin_chain": { + "@type": "/relayer.chains.tendermint.config.ChainConfig", + "key": "testkey", + "chain_id": "ibc0", + "rpc_addr": "http://localhost:26657", + "account_prefix": "cosmos", + "gas_adjustment": 1.5, + "gas_prices": "0.025stake", + "average_block_time_msec": 1000, + "max_retry_for_commit": 5 + } }, "prover": { - "@type": "/relayer.chains.tendermint.config.ProverConfig", - "trusting_period": "336h", - "refresh_threshold_rate": { - "numerator": 2, - "denominator": 3 + "@type": "/relayer.provers.debug.config.ProverConfig", + "origin_prover": { + "@type": "/relayer.chains.tendermint.config.ProverConfig", + "trusting_period": "336h", + "refresh_threshold_rate": { + "numerator": 2, + "denominator": 3 + } } } } diff --git a/tests/cases/tm2tm/configs/demo/ibc-1.json b/tests/cases/tm2tm/configs/demo/ibc-1.json index eda642d4..dbc07432 100644 --- a/tests/cases/tm2tm/configs/demo/ibc-1.json +++ b/tests/cases/tm2tm/configs/demo/ibc-1.json @@ -1,21 +1,27 @@ { "chain": { - "@type": "/relayer.chains.tendermint.config.ChainConfig", - "key": "testkey", - "chain_id": "ibc1", - "rpc_addr": "http://localhost:26557", - "account_prefix": "cosmos", - "gas_adjustment": 1.5, - "gas_prices": "0.025stake", - "average_block_time_msec": 1000, - "max_retry_for_commit": 5 + "@type": "/relayer.chains.debug.config.ChainConfig", + "origin_chain": { + "@type": "/relayer.chains.tendermint.config.ChainConfig", + "key": "testkey", + "chain_id": "ibc1", + "rpc_addr": "http://localhost:26557", + "account_prefix": "cosmos", + "gas_adjustment": 1.5, + "gas_prices": "0.025stake", + "average_block_time_msec": 1000, + "max_retry_for_commit": 5 + } }, "prover": { - "@type": "/relayer.chains.tendermint.config.ProverConfig", - "trusting_period": "336h", - "refresh_threshold_rate": { - "numerator": 2, - "denominator": 3 + "@type": "/relayer.provers.debug.config.ProverConfig", + "origin_prover": { + "@type": "/relayer.chains.tendermint.config.ProverConfig", + "trusting_period": "336h", + "refresh_threshold_rate": { + "numerator": 2, + "denominator": 3 + } } } } From ab00d8e418834182e71e0d74efc0dd8d457141e1 Mon Sep 17 00:00:00 2001 From: Daisuke Kanda Date: Sat, 23 Aug 2025 01:40:10 +0000 Subject: [PATCH 2/3] fix review Signed-off-by: Daisuke Kanda --- chains/debug/chain.go | 4 ---- chains/debug/module/module.go | 2 +- chains/debug/query.go | 2 +- provers/debug/module/module.go | 2 +- provers/debug/prover.go | 10 +++++----- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/chains/debug/chain.go b/chains/debug/chain.go index 90385edf..ab03c8ed 100644 --- a/chains/debug/chain.go +++ b/chains/debug/chain.go @@ -22,10 +22,6 @@ func (c *Chain) ChainID() string { return c.OriginChain.ChainID() } -func (c *Chain) Config() ChainConfig { - return c.config -} - func (c *Chain) Codec() codec.ProtoCodecMarshaler { return c.OriginChain.Codec() } diff --git a/chains/debug/module/module.go b/chains/debug/module/module.go index 8609c107..cede5d5b 100644 --- a/chains/debug/module/module.go +++ b/chains/debug/module/module.go @@ -13,7 +13,7 @@ var _ config.ModuleI = (*Module)(nil) // Name returns the name of the module func (Module) Name() string { - return "debug" + return "debug.chain" } // RegisterInterfaces register the module interfaces to protobuf Any. diff --git a/chains/debug/query.go b/chains/debug/query.go index 38b7b250..86901cbe 100644 --- a/chains/debug/query.go +++ b/chains/debug/query.go @@ -20,7 +20,7 @@ func debugFakeLost(ctx context.Context, chain *Chain, queryHeight ibcexported.He logger := log.GetLogger() env := fmt.Sprintf("DEBUG_RELAYER_PRUNE_AFTER_BLOCKS_CHAIN_%s", chain.ChainID()) if val, ok := os.LookupEnv(env); ok { - logger.Debug(env, "chain", chain.ChainID(), "value", val) + logger.DebugContext(ctx, env, "chain", chain.ChainID(), "value", val) threshold, err := strconv.Atoi(val) if err != nil { diff --git a/provers/debug/module/module.go b/provers/debug/module/module.go index 826dfc94..fda02bad 100644 --- a/provers/debug/module/module.go +++ b/provers/debug/module/module.go @@ -13,7 +13,7 @@ var _ config.ModuleI = (*Module)(nil) // Name returns the name of the module func (Module) Name() string { - return "debug-client" + return "debug.prover" } // RegisterInterfaces register the module interfaces to protobuf Any. diff --git a/provers/debug/prover.go b/provers/debug/prover.go index ff2cb0dc..dfc6fcd8 100644 --- a/provers/debug/prover.go +++ b/provers/debug/prover.go @@ -19,7 +19,7 @@ func debugFakeLost(ctx context.Context, chain core.Chain, queryHeight exported.H logger := log.GetLogger() env := fmt.Sprintf("DEBUG_RELAYER_PRUNE_AFTER_BLOCKS_PROVER_%s", chain.ChainID()) if val, ok := os.LookupEnv(env); ok { - logger.Info(fmt.Sprintf(">%s: chain=%s: '%v'", env, chain.ChainID(), val)) + logger.DebugContext(ctx, fmt.Sprintf(">%s: chain=%s: '%v'", env, chain.ChainID(), val)) threshold, err := strconv.Atoi(val) if err != nil { @@ -86,7 +86,7 @@ func (pr *Prover) SetupHeadersForUpdate(ctx context.Context, counterparty core.F env := fmt.Sprintf("DEBUG_RELAYER_SHFU_WAIT_%s", pr.chain.ChainID()) if val, ok := os.LookupEnv(env); ok { - logger.Debug(env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "value", val) + logger.DebugContext(ctx, env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "value", val) t, err := strconv.Atoi(val) if err != nil { logger.ErrorContext(ctx, "malformed value", err, "value", val) @@ -96,12 +96,12 @@ func (pr *Prover) SetupHeadersForUpdate(ctx context.Context, counterparty core.F lap := 60 n := t / lap for i := 0; i < n; i++ { - logger.Debug(env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "lap", fmt.Sprintf("%v/%v", (i+1)*lap, t)) + logger.DebugContext(ctx, env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "lap", fmt.Sprintf("%v/%v", (i+1)*lap, t)) time.Sleep(time.Duration(lap) * time.Second) } - logger.Debug(env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "lap", fmt.Sprintf("%v/%v", t-n*lap, t)) + logger.DebugContext(ctx, env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "lap", fmt.Sprintf("%v/%v", t-n*lap, t)) time.Sleep(time.Duration(t-n*lap) * time.Second) - logger.Debug(env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "done", t) + logger.DebugContext(ctx, env, "chain", pr.chain.ChainID(), "cp", counterparty.ChainID(), "done", t) } return headerStream, nil } From 106b0db872c185449ddb20b3bc3b4701b51df092 Mon Sep 17 00:00:00 2001 From: Daisuke Kanda Date: Wed, 27 Aug 2025 05:07:27 +0000 Subject: [PATCH 3/3] fix review Signed-off-by: Daisuke Kanda --- provers/debug/prover.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provers/debug/prover.go b/provers/debug/prover.go index dfc6fcd8..379b0572 100644 --- a/provers/debug/prover.go +++ b/provers/debug/prover.go @@ -55,7 +55,7 @@ func NewProver(chain core.Chain, originProver core.Prover) *Prover { func (pr *Prover) Init(homePath string, timeout time.Duration, codec codec.ProtoCodecMarshaler, debug bool) error { logger := log.GetLogger() - logger.Info("debug prover is initialized.") + logger.Debug("debug prover is initialized.") return pr.OriginProver.Init(homePath, timeout, codec, debug) }