From 4ba9b53b9debaae68666f8f01a6d5cb5b496a988 Mon Sep 17 00:00:00 2001 From: Naohiro Yoshida Date: Thu, 19 Oct 2023 09:26:39 +0900 Subject: [PATCH] Add previous validators hash to ConsensusState (#17) Add previous validators hash to ConsensusState Signed-off-by: Naohiro Yoshida --- .../ibc/lightclients/parlia/v1/parlia.sol | 54 +++++- module/parlia.pb.go | 159 ++++++++++++------ module/proof.go | 8 +- module/prover.go | 46 ++--- module/prover_test.go | 24 +-- proto/ibc/lightclients/parlia/v1/parlia.proto | 3 +- tool/testdata/internal/create_client.go | 52 +++--- tool/testdata/internal/header.go | 12 +- tool/testdata/internal/histroy.go | 13 +- .../internal/membership/verify_membership.go | 112 ++++++++++++ tool/testdata/internal/misbehavior.go | 9 +- tool/testdata/internal/update_client.go | 44 +++-- tool/testdata/main.go | 2 + 13 files changed, 378 insertions(+), 160 deletions(-) create mode 100644 tool/testdata/internal/membership/verify_membership.go diff --git a/e2e/contracts/contracts/ibc/lightclients/parlia/v1/parlia.sol b/e2e/contracts/contracts/ibc/lightclients/parlia/v1/parlia.sol index 6218c81..5b5821e 100644 --- a/e2e/contracts/contracts/ibc/lightclients/parlia/v1/parlia.sol +++ b/e2e/contracts/contracts/ibc/lightclients/parlia/v1/parlia.sol @@ -1231,7 +1231,8 @@ library IbcLightclientsParliaV1ConsensusState { struct Data { bytes state_root; uint64 timestamp; - bytes validators_hash; + bytes current_validators_hash; + bytes previous_validators_hash; } // Decoder section @@ -1286,7 +1287,10 @@ library IbcLightclientsParliaV1ConsensusState { pointer += _read_timestamp(pointer, bs, r); } else if (fieldId == 3) { - pointer += _read_validators_hash(pointer, bs, r); + pointer += _read_current_validators_hash(pointer, bs, r); + } else + if (fieldId == 4) { + pointer += _read_previous_validators_hash(pointer, bs, r); } else { pointer += ProtoBufRuntime._skip_field_decode(wireType, pointer, bs); @@ -1339,13 +1343,30 @@ library IbcLightclientsParliaV1ConsensusState { * @param r The in-memory struct * @return The number of bytes decoded */ - function _read_validators_hash( + function _read_current_validators_hash( uint256 p, bytes memory bs, Data memory r ) internal pure returns (uint) { (bytes memory x, uint256 sz) = ProtoBufRuntime._decode_bytes(p, bs); - r.validators_hash = x; + r.current_validators_hash = x; + return sz; + } + + /** + * @dev The decoder for reading a field + * @param p The offset of bytes array to start decode + * @param bs The bytes array to be decoded + * @param r The in-memory struct + * @return The number of bytes decoded + */ + function _read_previous_validators_hash( + uint256 p, + bytes memory bs, + Data memory r + ) internal pure returns (uint) { + (bytes memory x, uint256 sz) = ProtoBufRuntime._decode_bytes(p, bs); + r.previous_validators_hash = x; return sz; } @@ -1400,14 +1421,23 @@ library IbcLightclientsParliaV1ConsensusState { ); pointer += ProtoBufRuntime._encode_uint64(r.timestamp, pointer, bs); } - if (r.validators_hash.length != 0) { + if (r.current_validators_hash.length != 0) { pointer += ProtoBufRuntime._encode_key( 3, ProtoBufRuntime.WireType.LengthDelim, pointer, bs ); - pointer += ProtoBufRuntime._encode_bytes(r.validators_hash, pointer, bs); + pointer += ProtoBufRuntime._encode_bytes(r.current_validators_hash, pointer, bs); + } + if (r.previous_validators_hash.length != 0) { + pointer += ProtoBufRuntime._encode_key( + 4, + ProtoBufRuntime.WireType.LengthDelim, + pointer, + bs + ); + pointer += ProtoBufRuntime._encode_bytes(r.previous_validators_hash, pointer, bs); } return pointer - offset; } @@ -1454,7 +1484,8 @@ library IbcLightclientsParliaV1ConsensusState { uint256 e; e += 1 + ProtoBufRuntime._sz_lendelim(r.state_root.length); e += 1 + ProtoBufRuntime._sz_uint64(r.timestamp); - e += 1 + ProtoBufRuntime._sz_lendelim(r.validators_hash.length); + e += 1 + ProtoBufRuntime._sz_lendelim(r.current_validators_hash.length); + e += 1 + ProtoBufRuntime._sz_lendelim(r.previous_validators_hash.length); return e; } // empty checker @@ -1471,7 +1502,11 @@ library IbcLightclientsParliaV1ConsensusState { return false; } - if (r.validators_hash.length != 0) { + if (r.current_validators_hash.length != 0) { + return false; + } + + if (r.previous_validators_hash.length != 0) { return false; } @@ -1488,7 +1523,8 @@ library IbcLightclientsParliaV1ConsensusState { function store(Data memory input, Data storage output) internal { output.state_root = input.state_root; output.timestamp = input.timestamp; - output.validators_hash = input.validators_hash; + output.current_validators_hash = input.current_validators_hash; + output.previous_validators_hash = input.previous_validators_hash; } diff --git a/module/parlia.pb.go b/module/parlia.pb.go index 4ecdaed..7358d2d 100644 --- a/module/parlia.pb.go +++ b/module/parlia.pb.go @@ -150,9 +150,10 @@ func (m *Header) XXX_DiscardUnknown() { var xxx_messageInfo_Header proto.InternalMessageInfo type ConsensusState struct { - StateRoot []byte `protobuf:"bytes,1,opt,name=state_root,json=stateRoot,proto3" json:"state_root,omitempty"` - Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - ValidatorsHash []byte `protobuf:"bytes,3,opt,name=validators_hash,json=validatorsHash,proto3" json:"validators_hash,omitempty"` + StateRoot []byte `protobuf:"bytes,1,opt,name=state_root,json=stateRoot,proto3" json:"state_root,omitempty"` + Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + CurrentValidatorsHash []byte `protobuf:"bytes,3,opt,name=current_validators_hash,json=currentValidatorsHash,proto3" json:"current_validators_hash,omitempty"` + PreviousValidatorsHash []byte `protobuf:"bytes,4,opt,name=previous_validators_hash,json=previousValidatorsHash,proto3" json:"previous_validators_hash,omitempty"` } func (m *ConsensusState) Reset() { *m = ConsensusState{} } @@ -240,50 +241,51 @@ func init() { } var fileDescriptor_dc631224085c6c85 = []byte{ - // 679 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xcb, 0x6e, 0xdb, 0x38, - 0x14, 0xb5, 0x1c, 0xc7, 0xb1, 0x19, 0x3b, 0x46, 0x38, 0xc1, 0x40, 0xf1, 0xcc, 0x28, 0x86, 0x83, - 0x41, 0x8c, 0x01, 0x22, 0x8d, 0x3d, 0xeb, 0x41, 0x90, 0x38, 0x03, 0x38, 0x98, 0x06, 0x08, 0x94, - 0xa2, 0x8b, 0x6e, 0x04, 0x8a, 0xa2, 0x2d, 0xa2, 0x92, 0x68, 0x90, 0x94, 0x91, 0xf6, 0x2b, 0xda, - 0x5d, 0x7f, 0xa1, 0x7f, 0x92, 0x65, 0x96, 0x5d, 0xf5, 0x91, 0xfc, 0x45, 0x57, 0x05, 0x1f, 0x8e, - 0xd3, 0x45, 0x5f, 0xbb, 0x7b, 0xcf, 0x3d, 0xe7, 0x4a, 0xe7, 0x90, 0x04, 0x07, 0x34, 0xc6, 0x41, - 0x46, 0x67, 0xa9, 0xc4, 0x19, 0x25, 0x85, 0x14, 0xc1, 0x1c, 0xf1, 0x8c, 0xa2, 0x60, 0x31, 0xb4, - 0x95, 0x3f, 0xe7, 0x4c, 0x32, 0xd8, 0xa5, 0x31, 0xf6, 0x1f, 0x12, 0x7d, 0x3b, 0x5e, 0x0c, 0xbb, - 0x3b, 0x33, 0x36, 0x63, 0x9a, 0x16, 0xa8, 0xca, 0x28, 0xba, 0x7b, 0x6a, 0x35, 0x66, 0x9c, 0x04, - 0x46, 0xa1, 0x56, 0x9a, 0xca, 0x12, 0xbc, 0x19, 0x63, 0xb3, 0x8c, 0x04, 0xba, 0x8b, 0xcb, 0x69, - 0x90, 0x94, 0x1c, 0x49, 0xca, 0x0a, 0x33, 0xef, 0x7f, 0xaa, 0x82, 0xcd, 0xb1, 0x16, 0x5c, 0x4a, - 0x24, 0x09, 0xdc, 0x05, 0x0d, 0x9c, 0x22, 0x5a, 0x44, 0x34, 0x71, 0x9d, 0x9e, 0x33, 0xa8, 0x85, - 0x1b, 0xba, 0x3f, 0x4b, 0xe0, 0x5f, 0x60, 0x9b, 0xc6, 0x38, 0x12, 0x92, 0x71, 0x12, 0xa1, 0x24, - 0xe1, 0x44, 0x08, 0xb7, 0xda, 0x73, 0x06, 0xad, 0xb0, 0x43, 0x63, 0x7c, 0xa9, 0xf0, 0x63, 0x03, - 0xc3, 0xbf, 0xc1, 0x8e, 0xe2, 0x62, 0x96, 0xe7, 0x54, 0xe6, 0xca, 0x4a, 0x24, 0x32, 0x26, 0xdd, - 0x35, 0x4d, 0x87, 0x34, 0xc6, 0xe3, 0xd5, 0xe8, 0x32, 0x63, 0x12, 0x1e, 0x81, 0x76, 0x86, 0x24, - 0x11, 0x32, 0x4a, 0x89, 0x4a, 0xc0, 0xad, 0xf5, 0x9c, 0xc1, 0xe6, 0xa8, 0xeb, 0xab, 0x4c, 0x94, - 0x43, 0xdf, 0xfa, 0x5a, 0x0c, 0xfd, 0x89, 0x66, 0x84, 0x2d, 0x23, 0x30, 0x1d, 0x7c, 0x04, 0x3a, - 0x92, 0x97, 0x42, 0xd2, 0x62, 0x16, 0xcd, 0x09, 0xa7, 0x2c, 0x71, 0xd7, 0xf5, 0x8a, 0x5d, 0xdf, - 0x64, 0xe0, 0x2f, 0x33, 0xf0, 0x4f, 0x6d, 0x06, 0x27, 0x8d, 0xeb, 0x77, 0x7b, 0x95, 0xd7, 0xef, - 0xf7, 0x9c, 0x70, 0x6b, 0xa9, 0xbd, 0xd0, 0x52, 0xf8, 0x3f, 0xe8, 0xe4, 0xe8, 0x2a, 0xc2, 0x19, - 0xc3, 0xcf, 0xa2, 0x84, 0xd3, 0xa9, 0x74, 0xeb, 0x3f, 0xbe, 0xad, 0x9d, 0xa3, 0xab, 0xb1, 0x92, - 0x9e, 0x2a, 0x25, 0xfc, 0x15, 0xd4, 0xa7, 0x9c, 0xbd, 0x20, 0x85, 0xbb, 0xd1, 0x73, 0x06, 0x8d, - 0xd0, 0x76, 0xfd, 0x7d, 0xd0, 0xfc, 0xef, 0xf1, 0x64, 0x42, 0x50, 0x42, 0xb8, 0x22, 0xa5, 0xba, - 0xd2, 0xb9, 0xb7, 0x42, 0xdb, 0xf5, 0x5f, 0x55, 0x41, 0xdd, 0x52, 0x8e, 0xc0, 0x86, 0x01, 0x85, - 0xeb, 0xf4, 0xd6, 0x06, 0x9b, 0xa3, 0x3f, 0xfd, 0xaf, 0xdf, 0x18, 0xff, 0x7e, 0x75, 0xb8, 0x54, - 0xc1, 0x63, 0x60, 0x7c, 0x92, 0x64, 0x99, 0x72, 0xf5, 0xbb, 0x29, 0xb7, 0xad, 0xc2, 0xc6, 0xbc, - 0x0f, 0xda, 0x08, 0x63, 0x56, 0x16, 0x32, 0x9a, 0x73, 0xc6, 0xa6, 0xf6, 0x48, 0x5b, 0x16, 0xbc, - 0x50, 0x18, 0x3c, 0x04, 0x10, 0x97, 0x9c, 0x93, 0x42, 0x46, 0x0b, 0x94, 0xd1, 0x04, 0x49, 0xc6, - 0x85, 0x5b, 0xeb, 0xad, 0x0d, 0x5a, 0xe1, 0xb6, 0x9d, 0x3c, 0xb9, 0x1f, 0xc0, 0x00, 0xfc, 0x32, - 0xe7, 0x64, 0x41, 0x59, 0x29, 0x1e, 0xf2, 0xd7, 0x35, 0x1f, 0x2e, 0x47, 0x2b, 0x41, 0x7f, 0x01, - 0xb6, 0xc6, 0xac, 0x10, 0xa4, 0x10, 0xa5, 0x30, 0xf7, 0xf6, 0x0f, 0x00, 0x84, 0x2a, 0x22, 0xce, - 0x98, 0xb4, 0x09, 0x36, 0x35, 0x12, 0x32, 0x26, 0xe1, 0xef, 0xa0, 0x29, 0x69, 0x4e, 0x84, 0x44, - 0xf9, 0x5c, 0x7b, 0xae, 0x85, 0x2b, 0x00, 0x1e, 0x80, 0xce, 0xea, 0xb3, 0x51, 0x8a, 0x44, 0x6a, - 0x5d, 0x6d, 0xad, 0xe0, 0x09, 0x12, 0x69, 0xff, 0x8d, 0x03, 0x5a, 0xe7, 0x54, 0xc4, 0x24, 0x45, - 0xea, 0x97, 0x38, 0xfc, 0x0d, 0x34, 0x4d, 0x60, 0xcb, 0xf7, 0xd2, 0x0c, 0x1b, 0x06, 0x38, 0x4b, - 0xe0, 0xbf, 0xa0, 0x61, 0x82, 0x8f, 0x86, 0x36, 0xe7, 0xfe, 0xb7, 0xce, 0xeb, 0xcb, 0xc3, 0x1a, - 0x3e, 0x90, 0x8f, 0xf4, 0xef, 0xfc, 0x94, 0x7c, 0x74, 0x72, 0x7e, 0xfd, 0xd1, 0xab, 0x5c, 0xdf, - 0x7a, 0xce, 0xcd, 0xad, 0xe7, 0x7c, 0xb8, 0xf5, 0x9c, 0x97, 0x77, 0x5e, 0xe5, 0xe6, 0xce, 0xab, - 0xbc, 0xbd, 0xf3, 0x2a, 0x4f, 0x83, 0x19, 0x95, 0x69, 0x19, 0xfb, 0x98, 0xe5, 0x41, 0x82, 0x24, - 0xd2, 0x8f, 0x3c, 0x43, 0x71, 0x40, 0x63, 0x7c, 0x68, 0x96, 0x1e, 0x72, 0x92, 0xa1, 0xe7, 0x41, - 0xce, 0x92, 0x32, 0x23, 0x71, 0x5d, 0xdf, 0xf7, 0x7f, 0x3e, 0x07, 0x00, 0x00, 0xff, 0xff, 0x8f, - 0xf6, 0x83, 0x08, 0xcd, 0x04, 0x00, 0x00, + // 702 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x4e, 0x23, 0x47, + 0x10, 0xf6, 0x18, 0x63, 0xec, 0xc6, 0x06, 0xd1, 0x21, 0x64, 0x70, 0x92, 0xc1, 0x32, 0x8a, 0x62, + 0x45, 0x62, 0x26, 0x76, 0xa4, 0x28, 0x97, 0x08, 0x81, 0x89, 0x64, 0x94, 0x20, 0xa1, 0x21, 0xca, + 0x21, 0x97, 0x51, 0x4f, 0x4f, 0xdb, 0xd3, 0xda, 0x99, 0x69, 0xab, 0xbb, 0xc7, 0x62, 0xf7, 0x29, + 0x76, 0x6f, 0xfb, 0x0a, 0xfb, 0x14, 0x7b, 0xe5, 0xc8, 0x71, 0x4f, 0xfb, 0x03, 0x6f, 0xb1, 0xa7, + 0x55, 0xff, 0x18, 0x58, 0xb1, 0xbf, 0xb7, 0xaa, 0xaf, 0xbe, 0xaf, 0x54, 0xf5, 0xd5, 0xf4, 0x80, + 0x9f, 0x69, 0x8c, 0x83, 0x8c, 0x4e, 0x53, 0x89, 0x33, 0x4a, 0x0a, 0x29, 0x82, 0x19, 0xe2, 0x19, + 0x45, 0xc1, 0x7c, 0x60, 0x23, 0x7f, 0xc6, 0x99, 0x64, 0xb0, 0x43, 0x63, 0xec, 0xdf, 0x25, 0xfa, + 0xb6, 0x3c, 0x1f, 0x74, 0x36, 0xa7, 0x6c, 0xca, 0x34, 0x2d, 0x50, 0x91, 0x51, 0x74, 0x76, 0x54, + 0x6b, 0xcc, 0x38, 0x09, 0x8c, 0x42, 0xb5, 0x34, 0x91, 0x25, 0x78, 0x53, 0xc6, 0xa6, 0x19, 0x09, + 0x74, 0x16, 0x97, 0x93, 0x20, 0x29, 0x39, 0x92, 0x94, 0x15, 0xa6, 0xde, 0x7b, 0x5b, 0x05, 0xab, + 0x23, 0x2d, 0x38, 0x93, 0x48, 0x12, 0xb8, 0x0d, 0x1a, 0x38, 0x45, 0xb4, 0x88, 0x68, 0xe2, 0x3a, + 0x5d, 0xa7, 0x5f, 0x0b, 0x57, 0x74, 0x7e, 0x9c, 0xc0, 0x5f, 0xc0, 0x06, 0x8d, 0x71, 0x24, 0x24, + 0xe3, 0x24, 0x42, 0x49, 0xc2, 0x89, 0x10, 0x6e, 0xb5, 0xeb, 0xf4, 0x5b, 0xe1, 0x3a, 0x8d, 0xf1, + 0x99, 0xc2, 0x0f, 0x0c, 0x0c, 0x7f, 0x05, 0x9b, 0x8a, 0x8b, 0x59, 0x9e, 0x53, 0x99, 0xab, 0x55, + 0x22, 0x91, 0x31, 0xe9, 0x2e, 0x69, 0x3a, 0xa4, 0x31, 0x1e, 0xdd, 0x96, 0xce, 0x32, 0x26, 0xe1, + 0x3e, 0x68, 0x67, 0x48, 0x12, 0x21, 0xa3, 0x94, 0x28, 0x07, 0xdc, 0x5a, 0xd7, 0xe9, 0xaf, 0x0e, + 0x3b, 0xbe, 0xf2, 0x44, 0x6d, 0xe8, 0xdb, 0xbd, 0xe6, 0x03, 0x7f, 0xac, 0x19, 0x61, 0xcb, 0x08, + 0x4c, 0x06, 0xff, 0x01, 0xeb, 0x92, 0x97, 0x42, 0xd2, 0x62, 0x1a, 0xcd, 0x08, 0xa7, 0x2c, 0x71, + 0x97, 0x75, 0x8b, 0x6d, 0xdf, 0x78, 0xe0, 0x2f, 0x3c, 0xf0, 0x8f, 0xac, 0x07, 0x87, 0x8d, 0x8b, + 0x97, 0x3b, 0x95, 0xa7, 0xaf, 0x76, 0x9c, 0x70, 0x6d, 0xa1, 0x3d, 0xd5, 0x52, 0xf8, 0x37, 0x58, + 0xcf, 0xd1, 0x79, 0x84, 0x33, 0x86, 0x1f, 0x44, 0x09, 0xa7, 0x13, 0xe9, 0xd6, 0xbf, 0xbc, 0x5b, + 0x3b, 0x47, 0xe7, 0x23, 0x25, 0x3d, 0x52, 0x4a, 0xb8, 0x05, 0xea, 0x13, 0xce, 0x1e, 0x91, 0xc2, + 0x5d, 0xe9, 0x3a, 0xfd, 0x46, 0x68, 0xb3, 0xde, 0x2e, 0x68, 0xfe, 0xf5, 0xef, 0x78, 0x4c, 0x50, + 0x42, 0xb8, 0x22, 0xa5, 0x3a, 0xd2, 0xbe, 0xb7, 0x42, 0x9b, 0xf5, 0x9e, 0x54, 0x41, 0xdd, 0x52, + 0xf6, 0xc1, 0x8a, 0x01, 0x85, 0xeb, 0x74, 0x97, 0xfa, 0xab, 0xc3, 0x9f, 0xfc, 0x8f, 0x7f, 0x31, + 0xfe, 0x4d, 0xeb, 0x70, 0xa1, 0x82, 0x07, 0xc0, 0xec, 0x49, 0x92, 0x85, 0xcb, 0xd5, 0xcf, 0xba, + 0xdc, 0xb6, 0x0a, 0x6b, 0xf3, 0x2e, 0x68, 0x23, 0x8c, 0x59, 0x59, 0xc8, 0x68, 0xc6, 0x19, 0x9b, + 0xd8, 0x93, 0xb6, 0x2c, 0x78, 0xaa, 0x30, 0xb8, 0x07, 0x20, 0x2e, 0x39, 0x27, 0x85, 0x8c, 0xe6, + 0x28, 0xa3, 0x09, 0x92, 0x8c, 0x0b, 0xb7, 0xd6, 0x5d, 0xea, 0xb7, 0xc2, 0x0d, 0x5b, 0xf9, 0xef, + 0xa6, 0x00, 0x03, 0xf0, 0xcd, 0x8c, 0x93, 0x39, 0x65, 0xa5, 0xb8, 0xcb, 0x5f, 0xd6, 0x7c, 0xb8, + 0x28, 0xdd, 0x0a, 0x7a, 0xcf, 0x1d, 0xb0, 0x36, 0x62, 0x85, 0x20, 0x85, 0x28, 0x85, 0xf9, 0x70, + 0x7f, 0x04, 0x40, 0xa8, 0x20, 0xe2, 0x8c, 0x49, 0x6b, 0x61, 0x53, 0x23, 0x21, 0x63, 0x12, 0xfe, + 0x00, 0x9a, 0x92, 0xe6, 0x44, 0x48, 0x94, 0xcf, 0xf4, 0xd2, 0xb5, 0xf0, 0x16, 0x80, 0xbf, 0x83, + 0xef, 0xee, 0xcf, 0x1b, 0xa5, 0x48, 0xa4, 0x76, 0xbd, 0x6f, 0xef, 0x0d, 0x3d, 0x46, 0x22, 0x85, + 0x7f, 0x00, 0xf7, 0x03, 0x83, 0x1b, 0x61, 0x4d, 0x0b, 0xb7, 0xee, 0x4f, 0xaf, 0x94, 0xbd, 0x67, + 0x0e, 0x68, 0x9d, 0x50, 0x11, 0x93, 0x14, 0xa9, 0x32, 0x87, 0xdf, 0x83, 0xa6, 0xb1, 0x7e, 0xf1, + 0xf2, 0x9a, 0x61, 0xc3, 0x00, 0xc7, 0x09, 0xfc, 0x13, 0x34, 0xcc, 0x09, 0xa3, 0x81, 0xbd, 0x58, + 0xef, 0x53, 0x97, 0x7f, 0xff, 0xec, 0x83, 0x3b, 0xf2, 0xa1, 0xde, 0xe7, 0xab, 0xe4, 0xc3, 0xc3, + 0x93, 0x8b, 0x37, 0x5e, 0xe5, 0xe2, 0xca, 0x73, 0x2e, 0xaf, 0x3c, 0xe7, 0xf5, 0x95, 0xe7, 0x3c, + 0xbe, 0xf6, 0x2a, 0x97, 0xd7, 0x5e, 0xe5, 0xc5, 0xb5, 0x57, 0xf9, 0x3f, 0x98, 0x52, 0x99, 0x96, + 0xb1, 0x8f, 0x59, 0x1e, 0x24, 0x48, 0x22, 0xfd, 0xbb, 0xc8, 0x50, 0x1c, 0xd0, 0x18, 0xef, 0x99, + 0xa6, 0x7b, 0x9c, 0x64, 0xe8, 0x61, 0x90, 0xb3, 0xa4, 0xcc, 0x48, 0x5c, 0xd7, 0x2f, 0xe7, 0xb7, + 0x77, 0x01, 0x00, 0x00, 0xff, 0xff, 0x07, 0x09, 0x35, 0x20, 0x17, 0x05, 0x00, 0x00, } func (m *ClientState) Marshal() (dAtA []byte, err error) { @@ -490,10 +492,17 @@ func (m *ConsensusState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.ValidatorsHash) > 0 { - i -= len(m.ValidatorsHash) - copy(dAtA[i:], m.ValidatorsHash) - i = encodeVarintParlia(dAtA, i, uint64(len(m.ValidatorsHash))) + if len(m.PreviousValidatorsHash) > 0 { + i -= len(m.PreviousValidatorsHash) + copy(dAtA[i:], m.PreviousValidatorsHash) + i = encodeVarintParlia(dAtA, i, uint64(len(m.PreviousValidatorsHash))) + i-- + dAtA[i] = 0x22 + } + if len(m.CurrentValidatorsHash) > 0 { + i -= len(m.CurrentValidatorsHash) + copy(dAtA[i:], m.CurrentValidatorsHash) + i = encodeVarintParlia(dAtA, i, uint64(len(m.CurrentValidatorsHash))) i-- dAtA[i] = 0x1a } @@ -669,7 +678,11 @@ func (m *ConsensusState) Size() (n int) { if m.Timestamp != 0 { n += 1 + sovParlia(uint64(m.Timestamp)) } - l = len(m.ValidatorsHash) + l = len(m.CurrentValidatorsHash) + if l > 0 { + n += 1 + l + sovParlia(uint64(l)) + } + l = len(m.PreviousValidatorsHash) if l > 0 { n += 1 + l + sovParlia(uint64(l)) } @@ -1348,7 +1361,41 @@ func (m *ConsensusState) Unmarshal(dAtA []byte) error { } case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsHash", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CurrentValidatorsHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParlia + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthParlia + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthParlia + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CurrentValidatorsHash = append(m.CurrentValidatorsHash[:0], dAtA[iNdEx:postIndex]...) + if m.CurrentValidatorsHash == nil { + m.CurrentValidatorsHash = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PreviousValidatorsHash", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -1375,9 +1422,9 @@ func (m *ConsensusState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ValidatorsHash = append(m.ValidatorsHash[:0], dAtA[iNdEx:postIndex]...) - if m.ValidatorsHash == nil { - m.ValidatorsHash = []byte{} + m.PreviousValidatorsHash = append(m.PreviousValidatorsHash[:0], dAtA[iNdEx:postIndex]...) + if m.PreviousValidatorsHash == nil { + m.PreviousValidatorsHash = []byte{} } iNdEx = postIndex default: diff --git a/module/proof.go b/module/proof.go index 89720d1..0d1f8f7 100644 --- a/module/proof.go +++ b/module/proof.go @@ -50,16 +50,16 @@ func (pr *Prover) getStateCommitmentProof(path []byte, height exported.Height) ( return stateProof.StorageProofRLP[0], nil } -func (pr *Prover) getStateRootOrEmpty(header *types.Header) common.Hash { +func (pr *Prover) GetStorageRoot(header *types.Header) (common.Hash, error) { rlpAccountProof, _, err := pr.getAccountProof(header.Number.Int64()) if err != nil { - return common.Hash{} + return common.Hash{}, err } stateAccount, err := verifyAccount(header, rlpAccountProof, pr.chain.IBCAddress()) if err != nil { - return common.Hash{} + return common.Hash{}, err } - return stateAccount.Root + return stateAccount.Root, nil } type proofList struct { diff --git a/module/prover.go b/module/prover.go index fc50bc2..c9e9e00 100644 --- a/module/prover.go +++ b/module/prover.go @@ -104,26 +104,34 @@ func (pr *Prover) GetLatestFinalizedHeaderByLatestHeight(latestBlockNumber uint6 // CreateMsgCreateClient creates a CreateClientMsg to this chain func (pr *Prover) CreateMsgCreateClient(_ string, dstHeader core.Header, _ sdk.AccAddress) (*clienttypes.MsgCreateClient, error) { - // Initial client_state must be previous epoch header because lcp-parlia requires validator set when update_client - previousEpoch := getPreviousEpoch(dstHeader.GetHeight().GetRevisionHeight()) - previousEpochHeader, err := pr.chain.Header(context.TODO(), previousEpoch) + currentEpoch := GetCurrentEpoch(dstHeader.GetHeight().GetRevisionHeight()) + currentValidators, err := pr.QueryValidatorSet(currentEpoch) if err != nil { return nil, err } - previousValidators, err := ExtractValidatorSet(previousEpochHeader) + + previousEpoch := GetPreviousEpoch(dstHeader.GetHeight().GetRevisionHeight()) + previousValidators, err := pr.QueryValidatorSet(previousEpoch) + if err != nil { + return nil, err + } + header, err := dstHeader.(*Header).Target() + if err != nil { + return nil, err + } + + stateRoot, err := pr.GetStorageRoot(header) if err != nil { return nil, err } - // get chain id chainID, err := pr.chain.CanonicalChainID(context.TODO()) if err != nil { return nil, err } var commitmentsSlot [32]byte - // create initial client state - latestHeight := clienttypes.NewHeight(dstHeader.GetHeight().GetRevisionNumber(), previousEpoch) + latestHeight := toHeight(dstHeader.GetHeight()) clientState := ClientState{ TrustingPeriod: pr.config.TrustingPeriod, MaxClockDrift: pr.config.MaxClockDrift, @@ -138,10 +146,10 @@ func (pr *Prover) CreateMsgCreateClient(_ string, dstHeader core.Header, _ sdk.A return nil, err } consensusState := ConsensusState{ - Timestamp: previousEpochHeader.Time, - ValidatorsHash: crypto.Keccak256(previousValidators...), - // Since ibc handler may not be deployed at the target epoch when create_client is used, state_root is not obtained. - StateRoot: pr.getStateRootOrEmpty(previousEpochHeader).Bytes(), + Timestamp: header.Time, + PreviousValidatorsHash: crypto.Keccak256(previousValidators...), + CurrentValidatorsHash: crypto.Keccak256(currentValidators...), + StateRoot: stateRoot.Bytes(), } anyConsensusState, err := codectypes.NewAnyWithValue(&consensusState) if err != nil { @@ -244,15 +252,15 @@ func (pr *Prover) withProofAndValidators(height uint64, ethHeaders []*ETHHeader) } // Get validator set for verify headers - previousEpoch := getPreviousEpoch(height) - header.PreviousValidators, err = pr.queryValidatorSet(previousEpoch) + previousEpoch := GetPreviousEpoch(height) + header.PreviousValidators, err = pr.QueryValidatorSet(previousEpoch) if err != nil { return nil, fmt.Errorf("ValidatorSet was not found in previous epoch : number = %d : %+v", previousEpoch, err) } // Epoch doesn't need to get validator set because it contains validator set. if !isEpoch(height) { - currentEpoch := getCurrentEpoch(height) - header.CurrentValidators, err = pr.queryValidatorSet(currentEpoch) + currentEpoch := GetCurrentEpoch(height) + header.CurrentValidators, err = pr.QueryValidatorSet(currentEpoch) if err != nil { return nil, fmt.Errorf("ValidatorSet was not found in current epoch : number= %d : %+v", currentEpoch, err) } @@ -308,8 +316,8 @@ func (pr *Prover) queryETHHeader(height uint64) (*types.Header, *ETHHeader, *Vot return block, ethHeader, vote, err } -// queryValidatorSet returns the validator set -func (pr *Prover) queryValidatorSet(epochBlockNumber uint64) ([][]byte, error) { +// QueryValidatorSet returns the validator set +func (pr *Prover) QueryValidatorSet(epochBlockNumber uint64) ([][]byte, error) { header, err := pr.chain.Header(context.TODO(), epochBlockNumber) if err != nil { return nil, err @@ -326,7 +334,7 @@ func newETHHeader(header *types.Header) (*ETHHeader, error) { return ÐHeader{Header: rlpHeader}, nil } -func getPreviousEpoch(v uint64) uint64 { +func GetPreviousEpoch(v uint64) uint64 { epochCount := v / constant.BlocksPerEpoch return uint64(math.MaxInt64(0, int64(epochCount)-1)) * constant.BlocksPerEpoch } @@ -335,7 +343,7 @@ func isEpoch(v uint64) bool { return v%constant.BlocksPerEpoch == 0 } -func getCurrentEpoch(v uint64) uint64 { +func GetCurrentEpoch(v uint64) uint64 { epochCount := v / constant.BlocksPerEpoch return epochCount * constant.BlocksPerEpoch } diff --git a/module/prover_test.go b/module/prover_test.go index 0da6fce..060609f 100644 --- a/module/prover_test.go +++ b/module/prover_test.go @@ -2,7 +2,6 @@ package module import ( "context" - "github.com/datachainlab/ibc-parlia-relay/module/constant" "math/big" "testing" "time" @@ -349,7 +348,15 @@ func (ts *ProverTestSuite) TestCreateMsgCreateClient() { finalizedHeader, err := ts.prover.GetLatestFinalizedHeader() ts.Require().NoError(err) - previousEpoch, err := ts.chain.Header(context.TODO(), (finalizedHeader.GetHeight().GetRevisionHeight()/constant.BlocksPerEpoch-1)*constant.BlocksPerEpoch) + target, err := finalizedHeader.(*Header).Target() + ts.Require().NoError(err) + stateRoot, err := ts.prover.GetStorageRoot(target) + ts.Require().NoError(err) + previousEpoch := GetPreviousEpoch(finalizedHeader.GetHeight().GetRevisionHeight()) + previousValidatorSet, err := ts.prover.QueryValidatorSet(previousEpoch) + ts.Require().NoError(err) + currentEpoch := GetCurrentEpoch(finalizedHeader.GetHeight().GetRevisionHeight()) + currentValidatorSet, err := ts.prover.QueryValidatorSet(currentEpoch) ts.Require().NoError(err) msg, err := ts.prover.CreateMsgCreateClient("", finalizedHeader, types.AccAddress{}) ts.Require().NoError(err) @@ -363,17 +370,14 @@ func (ts *ProverTestSuite) TestCreateMsgCreateClient() { ts.Require().Equal(common.Bytes2Hex(cs.IbcStoreAddress), ibcHandlerAddress) var commitment [32]byte ts.Require().Equal(common.Bytes2Hex(cs.IbcCommitmentsSlot), common.Bytes2Hex(commitment[:])) - ts.Require().Equal(int64(cs.GetLatestHeight().GetRevisionHeight()), previousEpoch.Number.Int64()) - ts.Require().Equal(cs.GetLatestHeight().GetRevisionNumber(), uint64(0)) + ts.Require().Equal(cs.GetLatestHeight(), finalizedHeader.GetHeight()) var consState ConsensusState ts.Require().NoError(proto.Unmarshal(msg.ConsensusState.Value, &consState)) - validatorSet, err := ExtractValidatorSet(previousEpoch) - ts.Require().NoError(err) - - ts.Require().Equal(consState.ValidatorsHash, crypto.Keccak256(validatorSet...)) - ts.Require().Equal(consState.Timestamp, previousEpoch.Time) - ts.Require().Equal(common.BytesToHash(consState.StateRoot), ts.prover.getStateRootOrEmpty(previousEpoch)) + ts.Require().Equal(consState.CurrentValidatorsHash, crypto.Keccak256(currentValidatorSet...)) + ts.Require().Equal(consState.PreviousValidatorsHash, crypto.Keccak256(previousValidatorSet...)) + ts.Require().Equal(consState.Timestamp, target.Time) + ts.Require().Equal(common.BytesToHash(consState.StateRoot), stateRoot) } func (ts *ProverTestSuite) TestQueryClientStateWithProof() { diff --git a/proto/ibc/lightclients/parlia/v1/parlia.proto b/proto/ibc/lightclients/parlia/v1/parlia.proto index c9b31aa..c7131ae 100644 --- a/proto/ibc/lightclients/parlia/v1/parlia.proto +++ b/proto/ibc/lightclients/parlia/v1/parlia.proto @@ -36,7 +36,8 @@ message Header { message ConsensusState { bytes state_root = 1; uint64 timestamp = 2; - bytes validators_hash = 3; + bytes current_validators_hash = 3; + bytes previous_validators_hash = 4; } message Misbehaviour { diff --git a/tool/testdata/internal/create_client.go b/tool/testdata/internal/create_client.go index 1dbc12b..8fa1946 100644 --- a/tool/testdata/internal/create_client.go +++ b/tool/testdata/internal/create_client.go @@ -1,13 +1,11 @@ package internal import ( - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" "github.com/datachainlab/ibc-parlia-relay/module" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/spf13/cobra" "log" - "time" ) type createClientModule struct { @@ -15,39 +13,46 @@ type createClientModule struct { func (m *createClientModule) createClientSuccessCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "success", - Short: "create CreateClient testdata for success", + Use: "success", RunE: func(cmd *cobra.Command, args []string) error { - _, chain, err := createProver() + prover, _, err := createProver() if err != nil { return err } - latest, err := chain.LatestHeight() + header, err := prover.GetLatestFinalizedHeader() + message, err := prover.CreateMsgCreateClient("", header, common.HexToAddress(mainAndTestNetIbcAddress).Bytes()) if err != nil { return err } - var commitmentsSlot [32]byte - // create initial client state - latestHeight := types.NewHeight(latest.GetRevisionNumber(), latest.GetRevisionHeight()) - clientState := module.ClientState{ - TrustingPeriod: 100 * time.Second, - MaxClockDrift: 1 * time.Millisecond, - ChainId: 56, - LatestHeight: &latestHeight, - Frozen: false, - IbcStoreAddress: common.HexToAddress(mainAndTestNetIbcAddress).Bytes(), - IbcCommitmentsSlot: commitmentsSlot[:], + clientState, err := message.ClientState.Marshal() + if err != nil { + return err + } + consState, err := message.ConsensusState.Marshal() + if err != nil { + return err } - anyClientState, err := codectypes.NewAnyWithValue(&clientState) + currentValidatorSet, err := prover.QueryValidatorSet(module.GetCurrentEpoch(header.GetHeight().GetRevisionHeight())) if err != nil { return err } - csb, err := anyClientState.Marshal() + previousValidatorSet, err := prover.QueryValidatorSet(module.GetPreviousEpoch(header.GetHeight().GetRevisionHeight())) if err != nil { return err } - log.Println("clientState", common.Bytes2Hex(csb)) - log.Println("height", latestHeight) + target, err := header.(*module.Header).Target() + if err != nil { + return err + } + storageRoot, err := prover.GetStorageRoot(target) + log.Println("clientState", common.Bytes2Hex(clientState)) + log.Println("consensusState", common.Bytes2Hex(consState)) + log.Println("height", target.Number) + log.Println("time", target.Time) + log.Println("currentValidatorSet", common.BytesToHash(crypto.Keccak256(currentValidatorSet...))) + log.Println("previousValidatorSet", common.Bytes2Hex(crypto.Keccak256(previousValidatorSet...))) + log.Println("storageRoot", storageRoot) + return nil }, } @@ -56,8 +61,7 @@ func (m *createClientModule) createClientSuccessCmd() *cobra.Command { func CreateCreateClient() *cobra.Command { cmd := &cobra.Command{ - Use: "create", - Short: "Create testdata for Create client. ", + Use: "create", } m := createClientModule{} cmd.AddCommand(m.createClientSuccessCmd()) diff --git a/tool/testdata/internal/header.go b/tool/testdata/internal/header.go index 0de1b28..a53ec6f 100644 --- a/tool/testdata/internal/header.go +++ b/tool/testdata/internal/header.go @@ -13,12 +13,10 @@ type headerModule struct { func (m *headerModule) success() *cobra.Command { cmd := &cobra.Command{ - Use: "success", - Short: "create updateClient testdata for success", + Use: "success", } cmd.AddCommand(&cobra.Command{ - Use: "latest", - Short: "for latest block", + Use: "latest", RunE: func(cmd *cobra.Command, args []string) error { prover, chain, err := createProver() if err != nil { @@ -34,8 +32,7 @@ func (m *headerModule) success() *cobra.Command { var num uint64 specified := &cobra.Command{ - Use: "specified", - Short: "for specified block", + Use: "specified", RunE: func(cmd *cobra.Command, args []string) error { prover, _, err := createProver() if err != nil { @@ -78,8 +75,7 @@ func (m *headerModule) printHeader(prover *module.Prover, height uint64) error { func CreateHeader() *cobra.Command { cmd := &cobra.Command{ - Use: "header", - Short: "Create testdata for update client. ", + Use: "header", } m := headerModule{} cmd.AddCommand(m.success()) diff --git a/tool/testdata/internal/histroy.go b/tool/testdata/internal/histroy.go index 47f1f3b..a37414a 100644 --- a/tool/testdata/internal/histroy.go +++ b/tool/testdata/internal/histroy.go @@ -5,7 +5,6 @@ import ( "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" "github.com/cosmos/ibc-go/v7/modules/core/exported" "github.com/datachainlab/ibc-parlia-relay/module" - "github.com/datachainlab/ibc-parlia-relay/module/constant" "github.com/ethereum/go-ethereum/common" "github.com/spf13/cobra" "log" @@ -19,8 +18,7 @@ type historyModule struct { func (m *historyModule) mainnet() *cobra.Command { var num uint64 cmd := &cobra.Command{ - Use: "mainnet", - Short: "create many data testdata", + Use: "mainnet", RunE: func(cmd *cobra.Command, args []string) error { log.Printf("num = %d\n", num) @@ -48,8 +46,7 @@ func (m *historyModule) mainnet() *cobra.Command { func (m *historyModule) testnet() *cobra.Command { var num uint64 cmd := &cobra.Command{ - Use: "testnet", - Short: "create many data testdata", + Use: "testnet", RunE: func(cmd *cobra.Command, args []string) error { log.Printf("num = %d\n", num) @@ -153,14 +150,12 @@ func (m *historyModule) outputMsgClient(prover *module.Prover, firstNumber uint6 if err != nil { return 0, err } - epochs := firstHeader.GetHeight().GetRevisionHeight() / constant.BlocksPerEpoch - return (epochs - 1) * constant.BlocksPerEpoch, os.WriteFile(path, serialized, 0666) + return firstHeader.GetHeight().GetRevisionHeight(), os.WriteFile(path, serialized, 0666) } func CreateHistoryClient() *cobra.Command { cmd := &cobra.Command{ - Use: "history", - Short: "Create testdata for update client. ", + Use: "history", } m := historyModule{} cmd.AddCommand(m.mainnet()) diff --git a/tool/testdata/internal/membership/verify_membership.go b/tool/testdata/internal/membership/verify_membership.go new file mode 100644 index 0000000..c72aef6 --- /dev/null +++ b/tool/testdata/internal/membership/verify_membership.go @@ -0,0 +1,112 @@ +package membership + +import ( + "context" + "fmt" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + types3 "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/datachainlab/ethereum-ibc-relay-chain/pkg/relay/ethereum" + "github.com/datachainlab/ibc-parlia-relay/module" + "github.com/ethereum/go-ethereum/common" + "github.com/hyperledger-labs/yui-relayer/core" + "github.com/spf13/cobra" + "log" + "math/big" +) + +const ( + hdwMnemonic = "math razor capable expose worth grape metal sunset metal sudden usage scheme" + hdwPath = "m/44'/60'/0'/0/0" + ibcAddress = "0x702E40245797c5a2108A566b3CE2Bf14Bc6aF841" +) + +type verifyMembershipModule struct { +} + +func (m *verifyMembershipModule) latest() *cobra.Command { + return &cobra.Command{ + Use: "latest", + RunE: func(cmd *cobra.Command, args []string) error { + chainID := int64(9999) + connection := conntypes.ConnectionEnd{ + ClientId: "xx-parlia-0", + Versions: []*conntypes.Version{{ + Identifier: "1", + Features: []string{"ORDER_ORDERED", "ORDER_UNORDERED"}, + }}, + State: conntypes.OPEN, + Counterparty: conntypes.Counterparty{ + ClientId: "xx-parlia-0", + ConnectionId: "connection-0", + Prefix: types3.MerklePrefix{ + KeyPrefix: []byte("ibc"), + }, + }, + DelayPeriod: 0, + } + + commitment, err := connection.Marshal() + if err != nil { + return err + } + + path := host.ConnectionPath("connection-0") + stateRoot, proof, proofHeight, err := m.proveState(chainID, 8645, path, commitment) + if err != nil { + log.Panic(err) + } + log.Println("proofHeight", proofHeight) + log.Println("proof", common.Bytes2Hex(proof)) + log.Println("stateRoot", stateRoot) + log.Println("value", common.Bytes2Hex(commitment)) + return nil + }, + } +} + +func (m *verifyMembershipModule) proveState(chainID int64, port int64, path string, value []byte) (common.Hash, []byte, types.Height, error) { + chain, err := ethereum.NewChain(ethereum.ChainConfig{ + EthChainId: chainID, + RpcAddr: fmt.Sprintf("http://localhost:%d", port), + HdwMnemonic: hdwMnemonic, + HdwPath: hdwPath, + IbcAddress: ibcAddress, + }) + if err != nil { + return common.Hash{}, nil, types.Height{}, err + } + latest, err := chain.LatestHeight() + if err != nil { + return common.Hash{}, nil, types.Height{}, err + } + config := module.ProverConfig{ + Debug: true, + } + prover := module.NewProver(module.NewChain(chain), &config).(*module.Prover) + + ctx := core.NewQueryContext(context.Background(), latest) + + header, err := chain.Client().HeaderByNumber(ctx.Context(), big.NewInt(int64(latest.GetRevisionHeight()))) + if err != nil { + return common.Hash{}, nil, types.Height{}, err + } + + stateRoot, err := prover.GetStorageRoot(header) + if err != nil { + return common.Hash{}, nil, types.Height{}, err + } + + proof, proofHeight, err := prover.ProveState(ctx, path, value) + return stateRoot, proof, proofHeight, err +} + +func CreateVerifyMembership() *cobra.Command { + cmd := &cobra.Command{ + Use: "verify_membership", + } + m := verifyMembershipModule{} + cmd.AddCommand(m.latest()) + return cmd +} diff --git a/tool/testdata/internal/misbehavior.go b/tool/testdata/internal/misbehavior.go index 0f18258..595ed56 100644 --- a/tool/testdata/internal/misbehavior.go +++ b/tool/testdata/internal/misbehavior.go @@ -18,8 +18,7 @@ type misbehaviorModule struct { func (m *misbehaviorModule) success() *cobra.Command { return &cobra.Command{ - Use: "success", - Short: "create misbehavior testdata for success", + Use: "success", RunE: func(cmd *cobra.Command, args []string) error { chainID := int64(9999) targetHeight, header1, err := m.getLocalHeader(chainID, 8645, 0) @@ -53,8 +52,7 @@ func (m *misbehaviorModule) success() *cobra.Command { func (m *misbehaviorModule) error() *cobra.Command { return &cobra.Command{ - Use: "error", - Short: "create misbehavior testdata for error", + Use: "error", RunE: func(cmd *cobra.Command, args []string) error { prover, chain, err := createProver() if err != nil { @@ -155,8 +153,7 @@ func (m *misbehaviorModule) getLocalHeader(chainID int64, port int64, targetHeig func CreateMisbehavior() *cobra.Command { cmd := &cobra.Command{ - Use: "misbehavior", - Short: "Create testdata for misbehavior. ", + Use: "misbehavior", } m := misbehaviorModule{} cmd.AddCommand(m.success()) diff --git a/tool/testdata/internal/update_client.go b/tool/testdata/internal/update_client.go index 3b1e9f5..ecc4c7d 100644 --- a/tool/testdata/internal/update_client.go +++ b/tool/testdata/internal/update_client.go @@ -87,13 +87,22 @@ func (m *updateClientModule) error() *cobra.Command { if err != nil { return err } + trustedHeight := header.(*module.Header).TrustedHeight.GetRevisionHeight() + trustedCurrentValidatorSet, err := prover.QueryValidatorSet(module.GetCurrentEpoch(trustedHeight)) + if err != nil { + return err + } + trustedPreviousValidatorSet, err := prover.QueryValidatorSet(module.GetPreviousEpoch(trustedHeight)) + if err != nil { + return err + } log.Println("header", common.Bytes2Hex(marshal)) log.Println("height", header.GetHeight().GetRevisionHeight()) - log.Println("trustedHeight", header.(*module.Header).TrustedHeight.GetRevisionHeight()) - epochCount := header.GetHeight().GetRevisionHeight() / constant.BlocksPerEpoch - log.Println("currentEpochHeight", epochCount*constant.BlocksPerEpoch) - log.Println("currentValidatorHash", common.Bytes2Hex(crypto.Keccak256(header.(*module.Header).CurrentValidators...))) - log.Println("previousValidatorHash", common.Bytes2Hex(crypto.Keccak256(header.(*module.Header).PreviousValidators...))) + log.Println("trustedHeight", trustedHeight) + log.Println("trustedCurrentValidatorHash", common.Bytes2Hex(crypto.Keccak256(trustedCurrentValidatorSet...))) + log.Println("trustedPreviousValidatorHash", common.Bytes2Hex(crypto.Keccak256(trustedPreviousValidatorSet...))) + log.Println("newCurrentValidatorHash", common.Bytes2Hex(crypto.Keccak256(header.(*module.Header).CurrentValidators...))) + log.Println("newPreviousValidatorHash", common.Bytes2Hex(crypto.Keccak256(header.(*module.Header).PreviousValidators...))) return nil }, } @@ -134,17 +143,21 @@ func (m *updateClientModule) printHeader(prover *module.Prover, height uint64) e if err != nil { return err } + trustedHeight := header.TrustedHeight.GetRevisionHeight() + trustedCurrentValidatorSet, err := prover.QueryValidatorSet(module.GetCurrentEpoch(trustedHeight)) + if err != nil { + return err + } + trustedPreviousValidatorSet, err := prover.QueryValidatorSet(module.GetPreviousEpoch(trustedHeight)) + if err != nil { + return err + } log.Println("header", common.Bytes2Hex(marshal)) log.Println("stateRoot", account.Root) log.Println("height", header.GetHeight().GetRevisionHeight()) - log.Println("trustedHeight", header.TrustedHeight.GetRevisionHeight()) - epochCount := header.GetHeight().GetRevisionHeight() / constant.BlocksPerEpoch - log.Println("currentEpochHeight", epochCount*constant.BlocksPerEpoch) - - // validators hash - log.Println("currentValidatorSize", len(header.CurrentValidators)) - log.Println("currentValidatorHash", common.Bytes2Hex(crypto.Keccak256(header.CurrentValidators...))) - log.Println("previousValidatorHash", common.Bytes2Hex(crypto.Keccak256(header.PreviousValidators...))) + log.Println("trustedHeight", trustedHeight) + log.Println("trustedCurrentValidatorHash", common.Bytes2Hex(crypto.Keccak256(trustedCurrentValidatorSet...))) + log.Println("trustedPreviousValidatorHash", common.Bytes2Hex(crypto.Keccak256(trustedPreviousValidatorSet...))) if target.Number.Uint64()%constant.BlocksPerEpoch == 0 { newValidators, err := module.ExtractValidatorSet(target) if err != nil { @@ -153,8 +166,11 @@ func (m *updateClientModule) printHeader(prover *module.Prover, height uint64) e if len(newValidators) != mainNetValidatorSize { return fmt.Errorf("invalid validator size for test") } - log.Println("newValidatorHash", common.Bytes2Hex(crypto.Keccak256(newValidators...))) + log.Println("newCurrentValidatorHash", common.Bytes2Hex(crypto.Keccak256(newValidators...))) + } else { + log.Println("newCurrentValidatorHash", common.Bytes2Hex(crypto.Keccak256(header.CurrentValidators...))) } + log.Println("newPreviousValidatorHash", common.Bytes2Hex(crypto.Keccak256(header.PreviousValidators...))) return nil } diff --git a/tool/testdata/main.go b/tool/testdata/main.go index 9d1d7f3..3fc1aea 100644 --- a/tool/testdata/main.go +++ b/tool/testdata/main.go @@ -3,6 +3,7 @@ package main import ( "context" "github.com/datachainlab/ibc-parlia-relay/tool/testdata/internal" + "github.com/datachainlab/ibc-parlia-relay/tool/testdata/internal/membership" "github.com/spf13/cobra" "github.com/spf13/viper" "log" @@ -18,6 +19,7 @@ func main() { rootCmd.AddCommand(internal.CreateUpdateClient()) rootCmd.AddCommand(internal.CreateHistoryClient()) rootCmd.AddCommand(internal.CreateHeader()) + rootCmd.AddCommand(membership.CreateVerifyMembership()) if err := rootCmd.ExecuteContext(context.Background()); err != nil { log.Panicf("Failed to run command : %+v", err)