From ef5b76f148ea0aed47d6e53deb96f598979479ef Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Wed, 21 Sep 2022 12:36:10 +0900 Subject: [PATCH 1/3] elc: add `include_state` option to UpdateClient Signed-off-by: Jun Kimura --- go/light-clients/lcp/types/update.go | 8 +- go/relay/elc/tx.pb.go | 122 ++++++++++++------ go/relay/lcp.go | 9 +- go/relay/prover.go | 4 +- modules/enclave-commands/src/light_client.rs | 2 + .../handler/src/light_client/update_client.rs | 5 +- modules/ibc-client/src/client_def.rs | 7 +- modules/ibc-client/src/tests/client.rs | 34 ++--- modules/ibc-client/src/tests/mod.rs | 60 ++++----- proto/definitions/lcp/service/elc/v1/tx.proto | 2 + proto/src/descriptor.bin | Bin 133931 -> 134083 bytes proto/src/prost/lcp.service.elc.v1.rs | 3 + 12 files changed, 157 insertions(+), 99 deletions(-) diff --git a/go/light-clients/lcp/types/update.go b/go/light-clients/lcp/types/update.go index 0791961d..907be76a 100644 --- a/go/light-clients/lcp/types/update.go +++ b/go/light-clients/lcp/types/update.go @@ -31,9 +31,13 @@ func (cs ClientState) CheckHeaderAndUpdateForUpdateClient(ctx sdk.Context, cdc c return nil, nil, err } - if !cs.LatestHeight.IsZero() { + if cs.LatestHeight.IsZero() { + if len(commitment.NewState) == 0 { + return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidHeader, "invalid header %v: the commitment's `NewState` must be non-nil", header) + } + } else { if commitment.PrevHeight == nil || commitment.PrevStateID == nil { - return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidHeader, "invalid header %v", header) + return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidHeader, "invalid header %v: the commitment's `PrevHeight` and `PrevStateID` must be non-nil", header) } prevConsensusState, err := GetConsensusState(store, cdc, commitment.PrevHeight) if err != nil { diff --git a/go/relay/elc/tx.pb.go b/go/relay/elc/tx.pb.go index b9f25774..f697d41d 100644 --- a/go/relay/elc/tx.pb.go +++ b/go/relay/elc/tx.pb.go @@ -121,6 +121,8 @@ type MsgUpdateClient struct { ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` // header to update the light client Header *types.Any `protobuf:"bytes,2,opt,name=header,proto3" json:"header,omitempty"` + // request to include state in a commitment + IncludeState bool `protobuf:"varint,3,opt,name=include_state,json=includeState,proto3" json:"include_state,omitempty"` } func (m *MsgUpdateClient) Reset() { *m = MsgUpdateClient{} } @@ -371,50 +373,51 @@ func init() { func init() { proto.RegisterFile("lcp/service/elc/v1/tx.proto", fileDescriptor_28db3542707b11e8) } var fileDescriptor_28db3542707b11e8 = []byte{ - // 682 bytes of a gzipped FileDescriptorProto + // 702 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xb1, 0x6f, 0xd3, 0x4e, - 0x14, 0xb6, 0x9b, 0x34, 0x6a, 0xae, 0xd1, 0xaf, 0x95, 0x1b, 0xa5, 0xf9, 0xb9, 0xc8, 0xae, 0xc2, - 0x40, 0x05, 0xe8, 0x4e, 0x29, 0x5b, 0x37, 0x52, 0x09, 0xc1, 0x10, 0x84, 0x8c, 0x40, 0x82, 0xa5, - 0x3d, 0x5f, 0x2e, 0xf6, 0x49, 0x8e, 0xcf, 0xb2, 0x2f, 0x51, 0x23, 0x81, 0xc4, 0xc8, 0xc8, 0xc4, - 0xdc, 0xbf, 0x80, 0x3f, 0x03, 0x75, 0xec, 0x08, 0x4b, 0x54, 0xda, 0x85, 0xb9, 0x7f, 0x01, 0xf2, - 0xd9, 0x49, 0xed, 0x34, 0x89, 0x22, 0x21, 0xba, 0xdd, 0x7b, 0xef, 0xbb, 0xf7, 0xbd, 0xef, 0x4b, - 0xee, 0x19, 0xec, 0x78, 0x24, 0x40, 0x11, 0x0d, 0x07, 0x8c, 0x50, 0x44, 0x3d, 0x82, 0x06, 0x4d, - 0x24, 0x4e, 0x60, 0x10, 0x72, 0xc1, 0x35, 0xcd, 0x23, 0x01, 0x4c, 0x8b, 0x90, 0x7a, 0x04, 0x0e, - 0x9a, 0x7a, 0xd5, 0xe1, 0x0e, 0x97, 0x65, 0x14, 0x9f, 0x12, 0xa4, 0xfe, 0xbf, 0xc3, 0xb9, 0xe3, - 0x51, 0x24, 0x23, 0xbb, 0xdf, 0x45, 0xd8, 0x1f, 0xa6, 0x25, 0x93, 0xd9, 0x04, 0x11, 0x1e, 0x52, - 0x44, 0x3c, 0x46, 0x7d, 0x11, 0x33, 0x24, 0xa7, 0x04, 0xd0, 0xb8, 0x50, 0xc1, 0x46, 0x3b, 0x72, - 0x0e, 0x43, 0x8a, 0x05, 0x3d, 0x94, 0x15, 0xed, 0x15, 0xa8, 0x24, 0x98, 0xa3, 0x48, 0x60, 0x41, - 0xeb, 0xea, 0xae, 0xba, 0xb7, 0xbe, 0x5f, 0x85, 0x09, 0x0d, 0x1c, 0xd3, 0xc0, 0xa7, 0xfe, 0xb0, - 0xb5, 0x7d, 0x3d, 0x32, 0xb7, 0x86, 0xb8, 0xe7, 0x1d, 0x34, 0xb2, 0x77, 0x1a, 0xd6, 0x7a, 0x12, - 0xbe, 0x8e, 0x23, 0xed, 0x1d, 0xd8, 0x20, 0xdc, 0x8f, 0xa8, 0x1f, 0xf5, 0xa3, 0xb4, 0xe9, 0xca, - 0x82, 0xa6, 0xfa, 0xf5, 0xc8, 0xac, 0xa5, 0x4d, 0xf3, 0xd7, 0x1a, 0xd6, 0x7f, 0x93, 0x4c, 0xd2, - 0xba, 0x06, 0x4a, 0x11, 0x73, 0x7c, 0x1a, 0xd6, 0x0b, 0xbb, 0xea, 0x5e, 0xd9, 0x4a, 0xa3, 0x83, - 0xb5, 0xcf, 0xa7, 0xa6, 0xf2, 0xfb, 0xd4, 0x54, 0x1a, 0x5f, 0x55, 0xb0, 0x3d, 0x25, 0xd1, 0xa2, - 0x51, 0x10, 0xb7, 0xd1, 0x76, 0x40, 0x39, 0x1d, 0x9b, 0x75, 0xa4, 0xce, 0xb2, 0xb5, 0x96, 0x24, - 0x5e, 0x74, 0x34, 0x03, 0x00, 0xc2, 0x7b, 0x3d, 0x26, 0x7a, 0xd4, 0x17, 0x72, 0xe0, 0x8a, 0x95, - 0xc9, 0x4c, 0x51, 0x57, 0xc6, 0xd4, 0xda, 0x3d, 0x50, 0x8e, 0x4f, 0x58, 0xf4, 0x43, 0x5a, 0x2f, - 0xca, 0xd2, 0x4d, 0x22, 0x33, 0xd8, 0x07, 0x69, 0xfd, 0x9b, 0xa0, 0x73, 0x63, 0x7d, 0xf3, 0xd6, - 0x3c, 0xad, 0xea, 0xf5, 0xc8, 0xdc, 0xcc, 0x39, 0xcc, 0x3a, 0x8d, 0xcc, 0x94, 0x8f, 0x41, 0xc9, - 0xa5, 0xb8, 0x43, 0xc3, 0x45, 0x96, 0x5a, 0x29, 0x26, 0xc3, 0x3e, 0x94, 0xae, 0x64, 0xd9, 0x27, - 0xae, 0xe4, 0x85, 0xab, 0x0b, 0x84, 0xaf, 0xcc, 0x17, 0x5e, 0x98, 0x2f, 0xfc, 0xa7, 0x0a, 0xb6, - 0xda, 0x91, 0xf3, 0x96, 0x86, 0xac, 0x3b, 0x6c, 0xd3, 0x9e, 0x4d, 0xc3, 0xc8, 0x65, 0xc1, 0xe2, - 0x5f, 0xa3, 0x06, 0x4a, 0x41, 0x48, 0xbb, 0xec, 0x64, 0x4c, 0x9a, 0x44, 0x9a, 0x06, 0x8a, 0x01, - 0x16, 0x6e, 0xfa, 0xf3, 0xcb, 0xb3, 0x56, 0x05, 0xab, 0x03, 0xec, 0xf5, 0xc7, 0xee, 0x27, 0x81, - 0x76, 0x08, 0x2a, 0x41, 0xc8, 0x79, 0xf7, 0xc8, 0xa5, 0xcc, 0x71, 0x45, 0x7d, 0x55, 0xfa, 0xa5, - 0x43, 0x66, 0x13, 0x18, 0xbf, 0x11, 0x98, 0xbe, 0x8c, 0x41, 0x13, 0x3e, 0x97, 0x88, 0x56, 0xf1, - 0x6c, 0x64, 0x2a, 0xd6, 0xba, 0xbc, 0x95, 0xa4, 0xe2, 0xd6, 0x32, 0xac, 0x97, 0x92, 0xd6, 0x32, - 0xc8, 0x68, 0xfb, 0x08, 0x76, 0x66, 0x48, 0xbb, 0x33, 0x6b, 0xbf, 0xab, 0xa0, 0x36, 0xe1, 0x7f, - 0xc9, 0xfd, 0x7f, 0xe1, 0xee, 0xb4, 0x8f, 0xc5, 0xbf, 0xf2, 0x71, 0x75, 0xb6, 0x8f, 0x9f, 0x54, - 0x60, 0xcc, 0x16, 0x72, 0x57, 0x5e, 0xee, 0x7f, 0x2b, 0x80, 0x42, 0x3b, 0x72, 0xb4, 0x63, 0x50, - 0xc9, 0xed, 0xc7, 0xfb, 0xf0, 0xf6, 0x6a, 0x86, 0x53, 0x1b, 0x46, 0x7f, 0xb4, 0x04, 0x68, 0xa2, - 0xe4, 0x18, 0x54, 0x72, 0x6b, 0x60, 0x1e, 0x43, 0x16, 0x34, 0x97, 0x61, 0xe6, 0x93, 0xf6, 0xc0, - 0xe6, 0xad, 0xe7, 0xf6, 0x60, 0x4e, 0x83, 0x69, 0xa0, 0x8e, 0x96, 0x04, 0x4e, 0xd8, 0xfa, 0x60, - 0x6b, 0xd6, 0x3f, 0xf0, 0xe1, 0xc2, 0x3e, 0x39, 0xac, 0xbe, 0xbf, 0x3c, 0x76, 0x4c, 0xdb, 0x7a, - 0x76, 0xf6, 0xcb, 0x50, 0xce, 0x2e, 0x0d, 0xf5, 0xfc, 0xd2, 0x50, 0x2f, 0x2e, 0x0d, 0xf5, 0xcb, - 0x95, 0xa1, 0x9c, 0x5f, 0x19, 0xca, 0x8f, 0x2b, 0x43, 0x79, 0xbf, 0xe7, 0x30, 0xe1, 0xf6, 0x6d, - 0x48, 0x78, 0x0f, 0x75, 0xb0, 0xc0, 0xc4, 0xc5, 0xcc, 0xf7, 0xb0, 0x8d, 0xe2, 0xaf, 0xb0, 0xc3, - 0x51, 0x48, 0x3d, 0x3c, 0x8c, 0x3f, 0xc3, 0x76, 0x49, 0xae, 0xce, 0x27, 0x7f, 0x02, 0x00, 0x00, - 0xff, 0xff, 0x1c, 0x26, 0xfa, 0x70, 0xa0, 0x07, 0x00, 0x00, + 0x14, 0xb6, 0x9b, 0x34, 0x6a, 0xae, 0xfe, 0xfd, 0x5a, 0xb9, 0x51, 0x1a, 0x5c, 0x64, 0x57, 0xe9, + 0x40, 0x05, 0xe8, 0xac, 0x94, 0xad, 0x1b, 0xa9, 0x84, 0x60, 0x08, 0x42, 0x46, 0x20, 0xc1, 0xd2, + 0xda, 0xe7, 0x8b, 0x7d, 0x92, 0xe3, 0xb3, 0xec, 0x73, 0xd4, 0x0c, 0x48, 0x8c, 0x8c, 0x4c, 0xcc, + 0xe5, 0x1f, 0xe0, 0xcf, 0x40, 0x1d, 0x3b, 0xc2, 0x12, 0x95, 0x76, 0x61, 0xee, 0x5f, 0x80, 0x7c, + 0xe7, 0xa4, 0x4e, 0x9a, 0x44, 0x95, 0x10, 0xdd, 0xee, 0xbd, 0xfb, 0xee, 0xfb, 0xde, 0xfb, 0xce, + 0xf7, 0x0c, 0xb6, 0x02, 0x14, 0x99, 0x09, 0x8e, 0xfb, 0x04, 0x61, 0x13, 0x07, 0xc8, 0xec, 0xb7, + 0x4c, 0x76, 0x0c, 0xa3, 0x98, 0x32, 0xaa, 0xaa, 0x01, 0x8a, 0x60, 0xbe, 0x09, 0x71, 0x80, 0x60, + 0xbf, 0xa5, 0xd5, 0x3c, 0xea, 0x51, 0xbe, 0x6d, 0x66, 0x2b, 0x81, 0xd4, 0xee, 0x79, 0x94, 0x7a, + 0x01, 0x36, 0x79, 0xe4, 0xa4, 0x5d, 0xd3, 0x0e, 0x07, 0xf9, 0x96, 0x41, 0x1c, 0x64, 0x22, 0x1a, + 0x63, 0x13, 0x05, 0x04, 0x87, 0x2c, 0x53, 0x10, 0x2b, 0x01, 0x68, 0x9e, 0xcb, 0x60, 0xad, 0x93, + 0x78, 0x07, 0x31, 0xb6, 0x19, 0x3e, 0xe0, 0x3b, 0xea, 0x2b, 0xa0, 0x08, 0xcc, 0x61, 0xc2, 0x6c, + 0x86, 0x1b, 0xf2, 0xb6, 0xbc, 0xbb, 0xba, 0x57, 0x83, 0x42, 0x06, 0x8e, 0x64, 0xe0, 0xd3, 0x70, + 0xd0, 0xde, 0xbc, 0x1a, 0x1a, 0x1b, 0x03, 0xbb, 0x17, 0xec, 0x37, 0x8b, 0x67, 0x9a, 0xd6, 0xaa, + 0x08, 0x5f, 0x67, 0x91, 0xfa, 0x0e, 0xac, 0x21, 0x1a, 0x26, 0x38, 0x4c, 0xd2, 0x24, 0x27, 0x5d, + 0x5a, 0x40, 0xaa, 0x5d, 0x0d, 0x8d, 0x7a, 0x4e, 0x3a, 0x79, 0xac, 0x69, 0xfd, 0x3f, 0xce, 0x08, + 0xea, 0x3a, 0xa8, 0x24, 0xc4, 0x0b, 0x71, 0xdc, 0x28, 0x6d, 0xcb, 0xbb, 0x55, 0x2b, 0x8f, 0xf6, + 0x57, 0x3e, 0x9d, 0x18, 0xd2, 0xef, 0x13, 0x43, 0x6a, 0x7e, 0x91, 0xc1, 0xe6, 0x54, 0x8b, 0x16, + 0x4e, 0xa2, 0x8c, 0x46, 0xdd, 0x02, 0xd5, 0xbc, 0x6c, 0xe2, 0xf2, 0x3e, 0xab, 0xd6, 0x8a, 0x48, + 0xbc, 0x70, 0x55, 0x1d, 0x00, 0x44, 0x7b, 0x3d, 0xc2, 0x7a, 0x38, 0x64, 0xbc, 0x60, 0xc5, 0x2a, + 0x64, 0xa6, 0xa4, 0x95, 0x91, 0xb4, 0x7a, 0x1f, 0x54, 0xb3, 0x95, 0xcd, 0xd2, 0x18, 0x37, 0xca, + 0x7c, 0xeb, 0x3a, 0x51, 0x28, 0xec, 0xab, 0xf0, 0xfe, 0x4d, 0xe4, 0x5e, 0x7b, 0xdf, 0xba, 0x51, + 0x50, 0xbb, 0x76, 0x35, 0x34, 0xd6, 0x27, 0x2c, 0x26, 0x6e, 0xb3, 0x50, 0xe6, 0x63, 0x50, 0xf1, + 0xb1, 0xed, 0xe2, 0x78, 0x91, 0xa7, 0x56, 0x8e, 0x51, 0x77, 0xc0, 0x7f, 0x24, 0x44, 0x41, 0xea, + 0xe2, 0xfc, 0x22, 0xb2, 0xda, 0x57, 0x2c, 0x25, 0x4f, 0x72, 0x53, 0x0b, 0x35, 0x0e, 0xb8, 0x77, + 0xc5, 0x12, 0xc7, 0xde, 0x4d, 0xda, 0x23, 0x2f, 0xb0, 0x67, 0x69, 0xbe, 0x3d, 0xa5, 0xf9, 0xf6, + 0xfc, 0x94, 0xc1, 0x46, 0x27, 0xf1, 0xde, 0xe2, 0x98, 0x74, 0x07, 0x1d, 0xdc, 0x73, 0x70, 0x9c, + 0xf8, 0x24, 0x5a, 0x7c, 0x67, 0x75, 0x50, 0x89, 0x62, 0xdc, 0x25, 0xc7, 0x23, 0x51, 0x11, 0xa9, + 0x2a, 0x28, 0x47, 0x36, 0xf3, 0xf3, 0x8f, 0x84, 0xaf, 0xd5, 0x1a, 0x58, 0xee, 0xdb, 0x41, 0x3a, + 0xba, 0x23, 0x11, 0xa8, 0x07, 0x40, 0x89, 0x62, 0x4a, 0xbb, 0x87, 0x3e, 0x26, 0x9e, 0xcf, 0x1a, + 0xcb, 0xdc, 0x54, 0x0d, 0x12, 0x07, 0xc1, 0xec, 0x25, 0xc1, 0xfc, 0xfd, 0xf4, 0x5b, 0xf0, 0x39, + 0x47, 0xb4, 0xcb, 0xa7, 0x43, 0x43, 0xb2, 0x56, 0xf9, 0x29, 0x91, 0xca, 0xa8, 0x79, 0xd8, 0xa8, + 0x08, 0x6a, 0x1e, 0x14, 0x7a, 0xfb, 0x00, 0xb6, 0x66, 0xb4, 0x76, 0x67, 0xd6, 0x7e, 0x97, 0x41, + 0x7d, 0xac, 0xff, 0x92, 0x86, 0xff, 0xc2, 0xdd, 0x69, 0x1f, 0xcb, 0x7f, 0xe5, 0xe3, 0xf2, 0x6c, + 0x1f, 0x3f, 0xca, 0x40, 0x9f, 0xdd, 0xc8, 0x5d, 0x79, 0xb9, 0xf7, 0xad, 0x04, 0x4a, 0x9d, 0xc4, + 0x53, 0x8f, 0x80, 0x32, 0x31, 0x45, 0x77, 0xe0, 0xcd, 0x01, 0x0e, 0xa7, 0xe6, 0x90, 0xf6, 0xe8, + 0x16, 0xa0, 0x71, 0x27, 0x47, 0x40, 0x99, 0x98, 0x15, 0xf3, 0x14, 0x8a, 0xa0, 0xb9, 0x0a, 0x33, + 0x9f, 0x74, 0x00, 0xd6, 0x6f, 0x3c, 0xb7, 0x07, 0x73, 0x08, 0xa6, 0x81, 0x9a, 0x79, 0x4b, 0xe0, + 0x58, 0x2d, 0x05, 0x1b, 0xb3, 0xbe, 0xc0, 0x87, 0x0b, 0x79, 0x26, 0xb0, 0xda, 0xde, 0xed, 0xb1, + 0x23, 0xd9, 0xf6, 0xb3, 0xd3, 0x5f, 0xba, 0x74, 0x7a, 0xa1, 0xcb, 0x67, 0x17, 0xba, 0x7c, 0x7e, + 0xa1, 0xcb, 0x9f, 0x2f, 0x75, 0xe9, 0xec, 0x52, 0x97, 0x7e, 0x5c, 0xea, 0xd2, 0xfb, 0x5d, 0x8f, + 0x30, 0x3f, 0x75, 0x20, 0xa2, 0x3d, 0xd3, 0xb5, 0x99, 0x8d, 0x7c, 0x9b, 0x84, 0x81, 0xed, 0x98, + 0xd9, 0xbf, 0xda, 0xa3, 0x66, 0x8c, 0x03, 0x7b, 0x90, 0xfd, 0xac, 0x9d, 0x0a, 0x9f, 0xaf, 0x4f, + 0xfe, 0x04, 0x00, 0x00, 0xff, 0xff, 0x42, 0x44, 0x74, 0xb1, 0xc6, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -738,6 +741,16 @@ func (m *MsgUpdateClient) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.IncludeState { + i-- + if m.IncludeState { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } if m.Header != nil { { size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) @@ -1092,6 +1105,9 @@ func (m *MsgUpdateClient) Size() (n int) { l = m.Header.Size() n += 1 + l + sovTx(uint64(l)) } + if m.IncludeState { + n += 2 + } return n } @@ -1657,6 +1673,26 @@ func (m *MsgUpdateClient) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IncludeState", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IncludeState = bool(v != 0) default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/go/relay/lcp.go b/go/relay/lcp.go index 99b50d38..993c41fb 100644 --- a/go/relay/lcp.go +++ b/go/relay/lcp.go @@ -15,7 +15,7 @@ import ( "github.com/hyperledger-labs/yui-relayer/core" ) -func (pr *Prover) syncUpstreamHeader(height int64) (*elc.MsgUpdateClientResponse, error) { +func (pr *Prover) syncUpstreamHeader(height int64, includeState bool) (*elc.MsgUpdateClientResponse, error) { // 1. check if the latest height of the client is less than the given height @@ -52,8 +52,9 @@ func (pr *Prover) syncUpstreamHeader(height int64) (*elc.MsgUpdateClientResponse // 3. send a request that contains a header from 2 to update the client in ELC return pr.lcpServiceClient.UpdateClient(context.TODO(), &elc.MsgUpdateClient{ - ClientId: pr.config.ElcClientId, - Header: anyHeader, + ClientId: pr.config.ElcClientId, + Header: anyHeader, + IncludeState: includeState, }) } @@ -103,7 +104,7 @@ func activateClient(pathEnd *core.PathEnd, src, dst *core.ProvableChain) error { // LCP synchronizes with the latest header of the upstream chain - res, err := srcProver.syncUpstreamHeader(latestHeight) + res, err := srcProver.syncUpstreamHeader(latestHeight, true) if err != nil { return err } diff --git a/go/relay/prover.go b/go/relay/prover.go index 82de2ae1..ad7f3ce7 100644 --- a/go/relay/prover.go +++ b/go/relay/prover.go @@ -322,7 +322,7 @@ func (pr *Prover) QueryPacketCommitmentWithProof(height int64, seq uint64) (comR if err := pr.initServiceClient(); err != nil { return nil, err } - if _, err := pr.syncUpstreamHeader(height); err != nil { + if _, err := pr.syncUpstreamHeader(height, false); err != nil { return nil, err } @@ -360,7 +360,7 @@ func (pr *Prover) QueryPacketAcknowledgementCommitmentWithProof(height int64, se if err := pr.initServiceClient(); err != nil { return nil, err } - if _, err := pr.syncUpstreamHeader(height); err != nil { + if _, err := pr.syncUpstreamHeader(height, false); err != nil { return nil, err } diff --git a/modules/enclave-commands/src/light_client.rs b/modules/enclave-commands/src/light_client.rs index 94873b2d..83d37884 100644 --- a/modules/enclave-commands/src/light_client.rs +++ b/modules/enclave-commands/src/light_client.rs @@ -56,6 +56,7 @@ impl TryFrom for InitClientInput { pub struct UpdateClientInput { pub client_id: ClientId, pub any_header: Any, + pub include_state: bool, pub current_timestamp: Time, } @@ -70,6 +71,7 @@ impl TryFrom for UpdateClientInput { Ok(Self { client_id, any_header, + include_state: msg.include_state, current_timestamp: Time::now(), }) } diff --git a/modules/handler/src/light_client/update_client.rs b/modules/handler/src/light_client/update_client.rs index 135c96ea..f1dc36ec 100644 --- a/modules/handler/src/light_client/update_client.rs +++ b/modules/handler/src/light_client/update_client.rs @@ -15,7 +15,10 @@ pub fn update_client<'l, S: KVStore, L: LightClientSource<'l>>( let lc = get_light_client_by_client_id::<_, L>(ctx, &input.client_id)?; let ek = ctx.get_enclave_key(); - let res = lc.update_client(ctx, input.client_id.clone(), input.any_header.into())?; + let mut res = lc.update_client(ctx, input.client_id.clone(), input.any_header.into())?; + if input.include_state && res.commitment.new_state.is_none() { + res.commitment.new_state = Some(res.new_any_client_state.clone()); + } ctx.store_any_client_state(input.client_id.clone(), res.new_any_client_state) .map_err(Error::ICS02Error)?; diff --git a/modules/ibc-client/src/client_def.rs b/modules/ibc-client/src/client_def.rs index 1e4f110c..44213b04 100644 --- a/modules/ibc-client/src/client_def.rs +++ b/modules/ibc-client/src/client_def.rs @@ -62,8 +62,11 @@ impl LCPClient { ) -> Result<(ClientState, ConsensusState), Ics02Error> { // TODO return an error instead of assertion - if !client_state.latest_height.is_zero() { - // if the client state's latest height is zero, the header's prev_* must be non-nil + if client_state.latest_height.is_zero() { + // if the client state's latest height is zero, the commitment's new_state must be non-nil + assert!(header.commitment.new_state.is_some()); + } else { + // if the client state's latest height is non-zero, the commitment's prev_* must be non-nil assert!(header.prev_height().is_some() && header.prev_state_id().is_some()); // check if the previous consensus state exists in the store let prev_consensus_state: ConsensusState = ctx diff --git a/modules/ibc-client/src/tests/client.rs b/modules/ibc-client/src/tests/client.rs index d10b3b02..8d605366 100644 --- a/modules/ibc-client/src/tests/client.rs +++ b/modules/ibc-client/src/tests/client.rs @@ -9,9 +9,7 @@ use alloc::borrow::ToOwned; use commitments::{gen_state_id_from_any, UpdateClientCommitment}; use ibc::core::ics02_client::client_state::ClientState as ICS02ClientState; use ibc::core::ics02_client::error::Error as ICS02Error; -use ibc::core::ics03_connection::connection::ConnectionEnd; -use ibc::core::ics04_channel::channel::ChannelEnd; -use ibc::core::ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId}; +use ibc::core::ics24_host::identifier::ClientId; use lcp_types::{Any, Height}; use light_client::{ClientReader, LightClientError}; use light_client::{CreateClientResult, StateVerificationResult, UpdateClientResult}; @@ -44,6 +42,10 @@ impl LightClient for LCPLightClient { let height = client_state.latest_height().into(); let timestamp = consensus_state.timestamp; + LCPClient {} + .initialise(&client_state, &consensus_state) + .map_err(LightClientError::ICS02Error)?; + Ok(CreateClientResult { any_client_state: client_state.clone().into(), any_consensus_state: consensus_state.into(), @@ -127,25 +129,25 @@ impl LightClient for LCPLightClient { fn verify_membership( &self, - ctx: &dyn ClientReader, - client_id: ClientId, - prefix: Vec, - path: String, - value: Vec, - proof_height: Height, - proof: Vec, + _ctx: &dyn ClientReader, + _client_id: ClientId, + _prefix: Vec, + _path: String, + _value: Vec, + _proof_height: Height, + _proof: Vec, ) -> Result { todo!() } fn verify_non_membership( &self, - ctx: &dyn ClientReader, - client_id: ClientId, - prefix: Vec, - path: String, - proof_height: Height, - proof: Vec, + _ctx: &dyn ClientReader, + _client_id: ClientId, + _prefix: Vec, + _path: String, + _proof_height: Height, + _proof: Vec, ) -> Result { todo!() } diff --git a/modules/ibc-client/src/tests/mod.rs b/modules/ibc-client/src/tests/mod.rs index 9fe9988b..1ca0be3b 100644 --- a/modules/ibc-client/src/tests/mod.rs +++ b/modules/ibc-client/src/tests/mod.rs @@ -60,73 +60,73 @@ mod tests { let tmp_dir = TempDir::new("lcp").unwrap(); let home = tmp_dir.path().to_str().unwrap().to_string(); - // 1. initializes Light Client(Mock) corresponding to the upstream chain on the LCP side - let (upstream_client_id, proof0) = { - let header = MockHeader::new(ICS02Height::new(0, 1).unwrap()); - let client_state = AnyClientState::Mock(MockClientState::new(header)); - let consensus_state = AnyConsensusState::Mock(MockConsensusState::new(header)); + // 1. initializes Light Client for LCP on the downstream side + let lcp_client_id = { + let expired_at = (Time::now() + Duration::from_secs(60)).unwrap(); + let initial_client_state = ClientState { + latest_height: Height::zero(), + mr_enclave: Default::default(), + key_expiration: Duration::from_secs(60), + keys: vec![(Address::from(&ek.get_pubkey()), expired_at)], + }; + let initial_consensus_state = ConsensusState { + state_id: Default::default(), + timestamp: Time::unix_epoch(), + }; let input = InitClientInput { - any_client_state: Any::from(client_state).into(), - any_consensus_state: Any::from(consensus_state).into(), + any_client_state: initial_client_state.into(), + any_consensus_state: initial_consensus_state.into(), current_timestamp: Time::now(), }; - assert_eq!(lcp_store.revision, 1); let res = router::dispatch::<_, LocalLightClientRegistry>( Some(&ek), - &mut lcp_store, + &mut ibc_store, EnclaveCommand::new( CommandParams::new(home.clone()), Command::LightClient(LightClientCommand::InitClient(input)), ), ); assert!(res.is_ok(), "res={:?}", res); - assert_eq!(lcp_store.revision, 2); if let CommandResult::LightClient(LightClientResult::InitClient(InitClientResult { client_id, - proof, + proof: _, })) = res.unwrap() { - assert!(ClientId::new(ClientType::Mock, 0).unwrap() == client_id); - (client_id, proof) + client_id } else { unreachable!() } }; - // 2. initializes Light Client for LCP on the downstream side - let lcp_client_id = { - let expired_at = (Time::now() + Duration::from_secs(60)).unwrap(); - let initial_client_state = ClientState { - latest_height: Height::new(0, 1), - mr_enclave: Default::default(), - key_expiration: Duration::from_secs(60), - keys: vec![(Address::from(&ek.get_pubkey()), expired_at)], - }; - let initial_consensus_state = ConsensusState { - state_id: proof0.commitment().new_state_id, - timestamp: proof0.commitment().timestamp, - }; + // 2. initializes Light Client(Mock) corresponding to the upstream chain on the LCP side + let upstream_client_id = { + let header = MockHeader::new(ICS02Height::new(0, 1).unwrap()); + let client_state = AnyClientState::Mock(MockClientState::new(header)); + let consensus_state = AnyConsensusState::Mock(MockConsensusState::new(header)); let input = InitClientInput { - any_client_state: initial_client_state.into(), - any_consensus_state: initial_consensus_state.into(), + any_client_state: Any::from(client_state).into(), + any_consensus_state: Any::from(consensus_state).into(), current_timestamp: Time::now(), }; + assert_eq!(lcp_store.revision, 1); let res = router::dispatch::<_, LocalLightClientRegistry>( Some(&ek), - &mut ibc_store, + &mut lcp_store, EnclaveCommand::new( CommandParams::new(home.clone()), Command::LightClient(LightClientCommand::InitClient(input)), ), ); assert!(res.is_ok(), "res={:?}", res); + assert_eq!(lcp_store.revision, 2); if let CommandResult::LightClient(LightClientResult::InitClient(InitClientResult { client_id, proof: _, })) = res.unwrap() { + assert!(ClientId::new(ClientType::Mock, 0).unwrap() == client_id); client_id } else { unreachable!() @@ -140,6 +140,7 @@ mod tests { client_id: upstream_client_id, any_header: Any::from(AnyHeader::Mock(header)).into(), current_timestamp: Time::now(), + include_state: true, }; let res = router::dispatch::<_, LocalLightClientRegistry>( @@ -174,6 +175,7 @@ mod tests { client_id: lcp_client_id.clone(), any_header: header.into(), current_timestamp: (Time::now() + Duration::from_secs(60)).unwrap(), + include_state: false, }; let res = router::dispatch::<_, LocalLightClientRegistry>( Some(&ek), diff --git a/proto/definitions/lcp/service/elc/v1/tx.proto b/proto/definitions/lcp/service/elc/v1/tx.proto index f7b7f65f..a4195d11 100644 --- a/proto/definitions/lcp/service/elc/v1/tx.proto +++ b/proto/definitions/lcp/service/elc/v1/tx.proto @@ -58,6 +58,8 @@ message MsgUpdateClient { string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; // header to update the light client google.protobuf.Any header = 2; + // request to include state in a commitment + bool include_state = 3; } // MsgUpdateClientResponse defines the Msg/UpdateClient response type. diff --git a/proto/src/descriptor.bin b/proto/src/descriptor.bin index 24152783018e6325f29a0538429726456cc13af2..02583f5bb74cdf7ddb4c5f802113687563f8a3b9 100644 GIT binary patch delta 2085 zcmX|>OK%fN6op;4svl_xkR}ga8jKJK%@Af0X=X8EBtW)DA@UOevW-I2Zih!=J7Crg zyIH`NY+%8P1zV*20DcV`gg`ib7}@$2g! z9~IFnwfo;E_25i=I-0#ZO12&i()EYajcIyBm({tjy;s5RJd{zg%nSV}3er!sm zoxQ)ms>D}+?tS>Ko~rEk$QUAu^+h^*?C0`>bmvj}a9W;@%OXpjXZwQ#O5OXaVpwx(PJUMAO#BM3(}yaBT*|NqhoWa^p`qTQRUt2vs&7H`9uAd zT?$V|QKXFyVttvGafFY*pMAlLjK%1R8$IC><34r1qNs38HL4z# zCkZMwr$SJvg>zBH8EPWP)aDoPxn%I#YU!HFKi%N5)$q9e8wp*N7>rGbkrOf)t+`R2 z5F;mKIH9^E1b}*-)@(w+46f=F<{p7Ku0CTU0>M;$VNql-YDhwcIH3mBZ9+h(H00Yr z{HP=Zf=WXYLV04{q&QCqVB*X)sbM1mL#FA>a74|SS+T|mH4n{+89>X)XqahHv#_n9 z(sE`rR9a!7qWMLqVq%@OX-(X4@NH@pGRBW}n~uxzyomORa|J=B{mc1+LeTQn=wK8g zZWF%$m&X@Y#VhP|oL3Krbf~>1uX>z+$C>qTO2?V?Ak%?aE`=AH>!n+^6#Ufn@N~X; z51YRsoA+!f7`YTYy6HxFDHypF9+#rarN~e}5L|WXrfmffrn+JZgyXt$Z$L2Bl~Q=T zqMnoj0F@qfZ7G0I={XfHMNdkB8B}^)iY#}7R`liGc=^vupL(_wK*;o+44>G?z2R$v z8D#o$ZSYICUbkrTow(;IGDR0U(po zz$OHQnbeu#6H~c1m_a3#!ut$E={o=_!;Df}crXe-l){4`GnB%E_)RH12!$U?;hFNn z52f%v-04l{m2cH14Q=5ugV#;>#YSa7DLjTaWm5_t#O7XU$F4JgmwVyad}jgHd0$o* z*mW}UI(f9^M)@`wd7A-mb0pgYz|@Gguubki7_LU*3WVcEQg{$djbxnxhdY*a0w6P{ zkzFScDr2X@+Z@X_F@wrjwi)m?C${e^IGxuyp|M>j5Hb@d!zWIp@R&hnviHrS74Lub CaK*F$ delta 1921 zcmX|>ON&%j6ou>Vd+wueeDyWmLKHIy1VP)0Q^81AiRsi+RH`bd)T2eEs)URKH-f_i zGO~Yy1Hni`p={M&8z&EKcfHN$;+#+Kfa43 z`uWxS=%?eO_tB|j>)(q-TDn&2`SII-qD2~AKQ2E+zedHV5Eqy3M(ftmSD&I$btC_} zD2mv{Ss8yPd&S8j3vslA&-Tj8cM@udKfnFblXamu^VXTuDcsXZJ1+dODJ z_6en&dXQhNV@QeNp~aB;gcLO)MpgVM%<6~~HKJ4_n%TPnFg24$J|PfOGixfubu)W5 z5T<69P^y0CmJoo-TxLEYFya2W{Weg~T0{^sb9*sODjC2Us~ZI3cs|%E7gTxTH#aN#fQPGzN$l6 z`oc5A>tXoCE~-E)JVS0dw8Celd(wLD*O}qvN&aoUvy62wK7)_*R8DZ5T;hP&P>By+d2Vc*0S>J1W{QB72W3Aw#f{Y nwQV!gZEk$uuW`Gsb0cfNP7s+*kkK1AR(NK}Y>t0V, + /// request to include state in a commitment + #[prost(bool, tag="3")] + pub include_state: bool, } /// MsgUpdateClientResponse defines the Msg/UpdateClient response type. #[derive(::serde::Serialize, ::serde::Deserialize)] From afdddb13c2ded8adc918a33ee6df16a2c6e36d0e Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Wed, 21 Sep 2022 17:39:27 +0900 Subject: [PATCH 2/3] elc: add `prove` option to {Create,Update}ClientResult Signed-off-by: Jun Kimura --- modules/commitments/src/proof.rs | 19 +++++++++++++++++++ modules/commitments/src/prover.rs | 6 +++--- .../handler/src/light_client/init_client.rs | 7 ++++++- .../handler/src/light_client/update_client.rs | 8 ++++++-- modules/ibc-client/src/tests/client.rs | 2 ++ modules/light-client/src/client.rs | 4 ++++ modules/mock-lc/src/client.rs | 2 ++ modules/tendermint-lc/src/client.rs | 2 ++ tests/integration/src/lib.rs | 13 +++++-------- 9 files changed, 49 insertions(+), 14 deletions(-) diff --git a/modules/commitments/src/proof.rs b/modules/commitments/src/proof.rs index ea21005a..6ff34a0a 100644 --- a/modules/commitments/src/proof.rs +++ b/modules/commitments/src/proof.rs @@ -15,9 +15,28 @@ pub struct UpdateClientCommitmentProof { } impl UpdateClientCommitmentProof { + pub fn new(commitment_bytes: Vec, signer: Vec, signature: Vec) -> Self { + Self { + commitment_bytes, + signer, + signature, + } + } + + pub fn new_with_no_signature(commitment_bytes: Vec) -> Self { + Self { + commitment_bytes, + ..Default::default() + } + } + pub fn commitment(&self) -> UpdateClientCommitment { UpdateClientCommitment::from_bytes(&self.commitment_bytes).unwrap() } + + pub fn is_proven(&self) -> bool { + !self.signature.is_empty() + } } #[derive(Serialize, Deserialize, Debug, Default)] diff --git a/modules/commitments/src/prover.rs b/modules/commitments/src/prover.rs index 62323f13..bc51e14b 100644 --- a/modules/commitments/src/prover.rs +++ b/modules/commitments/src/prover.rs @@ -16,11 +16,11 @@ pub fn prove_update_client_commitment( signer.use_verifier(&mut |verifier: &dyn Verifier| { signer_address = verifier.get_address(); }); - Ok(UpdateClientCommitmentProof { + Ok(UpdateClientCommitmentProof::new( commitment_bytes, - signer: signer_address, + signer_address, signature, - }) + )) } pub fn prove_state_commitment( diff --git a/modules/handler/src/light_client/init_client.rs b/modules/handler/src/light_client/init_client.rs index f4d929dd..cc76fd3e 100644 --- a/modules/handler/src/light_client/init_client.rs +++ b/modules/handler/src/light_client/init_client.rs @@ -1,5 +1,6 @@ use crate::light_client::LightClientHandlerError as Error; use commitments::prover::prove_update_client_commitment; +use commitments::UpdateClientCommitmentProof; use context::Context; use core::str::FromStr; use enclave_commands::{InitClientInput, InitClientResult, LightClientResult}; @@ -38,7 +39,11 @@ pub fn init_client<'l, S: KVStore, L: LightClientSource<'l>>( ctx.store_update_height(client_id.clone(), res.height, ctx.host_height()) .map_err(Error::ICS02Error)?; - let proof = prove_update_client_commitment(ek, res.commitment)?; + let proof = if res.prove { + prove_update_client_commitment(ek, res.commitment)? + } else { + UpdateClientCommitmentProof::new_with_no_signature(res.commitment.to_vec()) + }; Ok(LightClientResult::InitClient(InitClientResult { client_id, proof, diff --git a/modules/handler/src/light_client/update_client.rs b/modules/handler/src/light_client/update_client.rs index f1dc36ec..7245f93d 100644 --- a/modules/handler/src/light_client/update_client.rs +++ b/modules/handler/src/light_client/update_client.rs @@ -1,6 +1,6 @@ use super::registry::get_light_client_by_client_id; use crate::light_client::LightClientHandlerError as Error; -use commitments::prover::prove_update_client_commitment; +use commitments::{prover::prove_update_client_commitment, UpdateClientCommitmentProof}; use context::Context; use enclave_commands::{LightClientResult, UpdateClientInput, UpdateClientResult}; use light_client::{ClientKeeper, ClientReader, LightClientSource}; @@ -33,6 +33,10 @@ pub fn update_client<'l, S: KVStore, L: LightClientSource<'l>>( ctx.store_update_height(input.client_id, res.height, ctx.host_height()) .map_err(Error::ICS02Error)?; - let proof = prove_update_client_commitment(ek, res.commitment)?; + let proof = if res.prove { + prove_update_client_commitment(ek, res.commitment)? + } else { + UpdateClientCommitmentProof::new_with_no_signature(res.commitment.to_vec()) + }; Ok(LightClientResult::UpdateClient(UpdateClientResult(proof))) } diff --git a/modules/ibc-client/src/tests/client.rs b/modules/ibc-client/src/tests/client.rs index 8d605366..e646ee79 100644 --- a/modules/ibc-client/src/tests/client.rs +++ b/modules/ibc-client/src/tests/client.rs @@ -60,6 +60,7 @@ impl LightClient for LCPLightClient { timestamp, validation_params: ValidationParams::Empty, }, + prove: false, }) } @@ -107,6 +108,7 @@ impl LightClient for LCPLightClient { height, timestamp: header_timestamp, commitment: UpdateClientCommitment::default(), + prove: true, }) } diff --git a/modules/light-client/src/client.rs b/modules/light-client/src/client.rs index 8c0cb3b5..fd24168f 100644 --- a/modules/light-client/src/client.rs +++ b/modules/light-client/src/client.rs @@ -59,6 +59,8 @@ pub struct CreateClientResult { pub height: Height, pub timestamp: Time, pub commitment: UpdateClientCommitment, + /// if true, sign the commitment with Enclave Key + pub prove: bool, } #[derive(Clone, Debug, PartialEq)] @@ -68,6 +70,8 @@ pub struct UpdateClientResult { pub height: Height, pub timestamp: Time, pub commitment: UpdateClientCommitment, + /// if true, sign the commitment with Enclave Key + pub prove: bool, } #[derive(Clone, Debug, PartialEq)] diff --git a/modules/mock-lc/src/client.rs b/modules/mock-lc/src/client.rs index fa321e3e..9d9d6aa0 100644 --- a/modules/mock-lc/src/client.rs +++ b/modules/mock-lc/src/client.rs @@ -69,6 +69,7 @@ impl LightClient for MockLightClient { timestamp, validation_params: ValidationParams::Empty, }, + prove: false, }) } @@ -144,6 +145,7 @@ impl LightClient for MockLightClient { timestamp: header_timestamp, validation_params: ValidationParams::Empty, }, + prove: true, }) } diff --git a/modules/tendermint-lc/src/client.rs b/modules/tendermint-lc/src/client.rs index b0a420c5..76776bd2 100644 --- a/modules/tendermint-lc/src/client.rs +++ b/modules/tendermint-lc/src/client.rs @@ -92,6 +92,7 @@ impl LightClient for TendermintLightClient { timestamp, validation_params: ValidationParams::Empty, }, + prove: false, }) } @@ -220,6 +221,7 @@ impl LightClient for TendermintLightClient { trusted_consensus_state_timestamp, }), }, + prove: true, }) } diff --git a/tests/integration/src/lib.rs b/tests/integration/src/lib.rs index c073d357..fd2157ea 100644 --- a/tests/integration/src/lib.rs +++ b/tests/integration/src/lib.rs @@ -121,18 +121,14 @@ mod tests { current_timestamp: Time::now(), }) .unwrap(); - let commitment = res.proof.commitment(); + assert!(!res.proof.is_proven()); let client_id = res.client_id; info!("generated client id is {}", client_id.as_str().to_string()); let target_header = rly.create_header( - commitment - .new_height - .try_into() - .map_err(|e| anyhow!("{:?}", e))?, - commitment - .new_height + initial_height.try_into().map_err(|e| anyhow!("{:?}", e))?, + initial_height .increment() .try_into() .map_err(|e| anyhow!("{:?}", e))?, @@ -141,9 +137,10 @@ mod tests { client_id: client_id.clone(), any_header: target_header.into(), current_timestamp: Time::now(), + include_state: true, })?; - info!("update_client's result is {:?}", res); + assert!(res.0.is_proven()); let height = res.0.commitment().new_height; From ddba97cf3359c08beebc58a7f6a106e9d5ba5419 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Wed, 21 Sep 2022 18:23:31 +0900 Subject: [PATCH 3/3] elc: remove unused fields from {Create,Update}ClientResult Signed-off-by: Jun Kimura --- .../handler/src/light_client/init_client.rs | 7 ++++--- modules/ibc-client/src/tests/client.rs | 4 ---- modules/light-client/src/client.rs | 19 ++++++++++++++----- modules/mock-lc/src/client.rs | 6 +----- modules/tendermint-lc/src/client.rs | 12 ++++-------- 5 files changed, 23 insertions(+), 25 deletions(-) diff --git a/modules/handler/src/light_client/init_client.rs b/modules/handler/src/light_client/init_client.rs index cc76fd3e..cfc4075f 100644 --- a/modules/handler/src/light_client/init_client.rs +++ b/modules/handler/src/light_client/init_client.rs @@ -18,9 +18,10 @@ pub fn init_client<'l, S: KVStore, L: LightClientSource<'l>>( ctx.set_timestamp(input.current_timestamp); let any_client_state: Any = input.any_client_state.into(); + let any_consensus_state: Any = input.any_consensus_state.into(); let lc = L::get_light_client(&any_client_state.type_url).unwrap(); let ek = ctx.get_enclave_key(); - let res = lc.create_client(ctx, any_client_state, input.any_consensus_state.into())?; + let res = lc.create_client(ctx, any_client_state.clone(), any_consensus_state.clone())?; let client_id = gen_client_id( lc.client_type(), ctx.client_counter().map_err(Error::ICS02Error)?, @@ -29,9 +30,9 @@ pub fn init_client<'l, S: KVStore, L: LightClientSource<'l>>( ctx.store_client_type(client_id.clone(), lc.client_type()) .map_err(Error::ICS02Error)?; - ctx.store_any_client_state(client_id.clone(), res.any_client_state) + ctx.store_any_client_state(client_id.clone(), any_client_state) .map_err(Error::ICS02Error)?; - ctx.store_any_consensus_state(client_id.clone(), res.height, res.any_consensus_state) + ctx.store_any_consensus_state(client_id.clone(), res.height, any_consensus_state) .map_err(Error::ICS02Error)?; ctx.increase_client_counter(); ctx.store_update_time(client_id.clone(), res.height, ctx.host_timestamp()) diff --git a/modules/ibc-client/src/tests/client.rs b/modules/ibc-client/src/tests/client.rs index e646ee79..b10bacfc 100644 --- a/modules/ibc-client/src/tests/client.rs +++ b/modules/ibc-client/src/tests/client.rs @@ -47,10 +47,7 @@ impl LightClient for LCPLightClient { .map_err(LightClientError::ICS02Error)?; Ok(CreateClientResult { - any_client_state: client_state.clone().into(), - any_consensus_state: consensus_state.into(), height, - timestamp, commitment: UpdateClientCommitment { prev_state_id: None, new_state_id: state_id, @@ -106,7 +103,6 @@ impl LightClient for LCPLightClient { new_any_client_state: Any::new(new_client_state), new_any_consensus_state: Any::new(new_consensus_state), height, - timestamp: header_timestamp, commitment: UpdateClientCommitment::default(), prove: true, }) diff --git a/modules/light-client/src/client.rs b/modules/light-client/src/client.rs index fd24168f..bc7c4f25 100644 --- a/modules/light-client/src/client.rs +++ b/modules/light-client/src/client.rs @@ -3,19 +3,22 @@ use crate::sgx_reexport_prelude::*; use crate::{context::ClientReader, LightClientError}; use commitments::{StateCommitment, UpdateClientCommitment}; use ibc::core::ics24_host::identifier::ClientId; -use lcp_types::{Any, Height, Time}; +use lcp_types::{Any, Height}; use std::string::String; use std::vec::Vec; pub trait LightClient { + /// client_type returns a client type of the light client fn client_type(&self) -> String; + /// latest_height returns the latest height that the light client tracks fn latest_height( &self, ctx: &dyn ClientReader, client_id: &ClientId, ) -> Result; + /// create_client creates a new light client fn create_client( &self, ctx: &dyn ClientReader, @@ -23,6 +26,7 @@ pub trait LightClient { any_consensus_state: Any, ) -> Result; + /// update_client updates the light client with a header fn update_client( &self, ctx: &dyn ClientReader, @@ -30,6 +34,7 @@ pub trait LightClient { any_header: Any, ) -> Result; + /// verify_membership is a generic proof verification method which verifies a proof of the existence of a value at a given path at the specified height. fn verify_membership( &self, ctx: &dyn ClientReader, @@ -41,6 +46,7 @@ pub trait LightClient { proof: Vec, ) -> Result; + /// verify_non_membership is a generic proof verification method which verifies the absence of a given path at a specified height. fn verify_non_membership( &self, ctx: &dyn ClientReader, @@ -54,10 +60,9 @@ pub trait LightClient { #[derive(Clone, Debug, PartialEq)] pub struct CreateClientResult { - pub any_client_state: Any, - pub any_consensus_state: Any, + /// height corresponding to the updated state pub height: Height, - pub timestamp: Time, + /// commitment represents a state transition of the client pub commitment: UpdateClientCommitment, /// if true, sign the commitment with Enclave Key pub prove: bool, @@ -65,10 +70,13 @@ pub struct CreateClientResult { #[derive(Clone, Debug, PartialEq)] pub struct UpdateClientResult { + /// updated client state pub new_any_client_state: Any, + /// updated consensus state pub new_any_consensus_state: Any, + /// height corresponding to the updated state pub height: Height, - pub timestamp: Time, + /// commitment represents a state transition of the client pub commitment: UpdateClientCommitment, /// if true, sign the commitment with Enclave Key pub prove: bool, @@ -76,5 +84,6 @@ pub struct UpdateClientResult { #[derive(Clone, Debug, PartialEq)] pub struct StateVerificationResult { + /// state commitment represents a result of the state verification pub state_commitment: StateCommitment, } diff --git a/modules/mock-lc/src/client.rs b/modules/mock-lc/src/client.rs index 9d9d6aa0..e15b19dc 100644 --- a/modules/mock-lc/src/client.rs +++ b/modules/mock-lc/src/client.rs @@ -42,7 +42,7 @@ impl LightClient for MockLightClient { } Err(e) => return Err(Error::ICS02Error(e).into()), }; - let consensus_state = match AnyConsensusState::try_from(any_consensus_state.clone()) { + let consensus_state = match AnyConsensusState::try_from(any_consensus_state) { Ok(AnyConsensusState::Mock(consensus_state)) => { AnyConsensusState::Mock(consensus_state) } @@ -56,10 +56,7 @@ impl LightClient for MockLightClient { let height = client_state.latest_height().into(); let timestamp: Time = consensus_state.timestamp().into(); Ok(CreateClientResult { - any_client_state: any_client_state.clone(), - any_consensus_state, height, - timestamp, commitment: UpdateClientCommitment { prev_state_id: None, new_state_id: state_id, @@ -135,7 +132,6 @@ impl LightClient for MockLightClient { new_any_client_state: new_any_client_state.clone(), new_any_consensus_state: Any::try_from(new_consensus_state).unwrap(), height, - timestamp: header_timestamp, commitment: UpdateClientCommitment { prev_state_id: Some(prev_state_id), new_state_id, diff --git a/modules/tendermint-lc/src/client.rs b/modules/tendermint-lc/src/client.rs index 76776bd2..1935c4a2 100644 --- a/modules/tendermint-lc/src/client.rs +++ b/modules/tendermint-lc/src/client.rs @@ -62,7 +62,10 @@ impl LightClient for TendermintLightClient { } Err(e) => return Err(Error::ICS02Error(e).into()), }; - let consensus_state = match AnyConsensusState::try_from(any_consensus_state.clone()) { + + let state_id = gen_state_id_from_any(&canonical_client_state, &any_consensus_state) + .map_err(Error::OtherError)?; + let consensus_state = match AnyConsensusState::try_from(any_consensus_state) { Ok(AnyConsensusState::Tendermint(consensus_state)) => { AnyConsensusState::Tendermint(consensus_state) } @@ -73,16 +76,10 @@ impl LightClient for TendermintLightClient { Err(e) => return Err(Error::ICS02Error(e).into()), }; - let state_id = gen_state_id_from_any(&canonical_client_state, &any_consensus_state) - .map_err(Error::OtherError)?; - let height = client_state.latest_height().into(); let timestamp: Time = consensus_state.timestamp().into(); Ok(CreateClientResult { - any_client_state: any_client_state.clone(), - any_consensus_state, height, - timestamp, commitment: UpdateClientCommitment { prev_state_id: None, new_state_id: state_id, @@ -204,7 +201,6 @@ impl LightClient for TendermintLightClient { new_any_client_state: new_client_state.into(), new_any_consensus_state: new_consensus_state.into(), height, - timestamp: header_timestamp, commitment: UpdateClientCommitment { prev_state_id: Some(prev_state_id), new_state_id,