From 43883b75b6b8d7391fa889e95d52cefa06a467da Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 20 Dec 2024 18:53:31 +0800 Subject: [PATCH 01/17] Update lockup.proto and run proto gen --- api/sourcehub/tier/v1beta1/lockup.pulsar.go | 149 ++++---------------- proto/sourcehub/tier/v1beta1/lockup.proto | 11 +- x/tier/types/lockup.pb.go | 120 ++++------------ 3 files changed, 59 insertions(+), 221 deletions(-) diff --git a/api/sourcehub/tier/v1beta1/lockup.pulsar.go b/api/sourcehub/tier/v1beta1/lockup.pulsar.go index faa6994..52ffc37 100644 --- a/api/sourcehub/tier/v1beta1/lockup.pulsar.go +++ b/api/sourcehub/tier/v1beta1/lockup.pulsar.go @@ -21,7 +21,6 @@ var ( fd_Lockup_validator_address protoreflect.FieldDescriptor fd_Lockup_amount protoreflect.FieldDescriptor fd_Lockup_creation_height protoreflect.FieldDescriptor - fd_Lockup_unbond_time protoreflect.FieldDescriptor fd_Lockup_unlock_time protoreflect.FieldDescriptor ) @@ -32,7 +31,6 @@ func init() { fd_Lockup_validator_address = md_Lockup.Fields().ByName("validator_address") fd_Lockup_amount = md_Lockup.Fields().ByName("amount") fd_Lockup_creation_height = md_Lockup.Fields().ByName("creation_height") - fd_Lockup_unbond_time = md_Lockup.Fields().ByName("unbond_time") fd_Lockup_unlock_time = md_Lockup.Fields().ByName("unlock_time") } @@ -125,12 +123,6 @@ func (x *fastReflection_Lockup) Range(f func(protoreflect.FieldDescriptor, proto return } } - if x.UnbondTime != nil { - value := protoreflect.ValueOfMessage(x.UnbondTime.ProtoReflect()) - if !f(fd_Lockup_unbond_time, value) { - return - } - } if x.UnlockTime != nil { value := protoreflect.ValueOfMessage(x.UnlockTime.ProtoReflect()) if !f(fd_Lockup_unlock_time, value) { @@ -160,8 +152,6 @@ func (x *fastReflection_Lockup) Has(fd protoreflect.FieldDescriptor) bool { return x.Amount != "" case "sourcehub.tier.v1beta1.Lockup.creation_height": return x.CreationHeight != int64(0) - case "sourcehub.tier.v1beta1.Lockup.unbond_time": - return x.UnbondTime != nil case "sourcehub.tier.v1beta1.Lockup.unlock_time": return x.UnlockTime != nil default: @@ -188,8 +178,6 @@ func (x *fastReflection_Lockup) Clear(fd protoreflect.FieldDescriptor) { x.Amount = "" case "sourcehub.tier.v1beta1.Lockup.creation_height": x.CreationHeight = int64(0) - case "sourcehub.tier.v1beta1.Lockup.unbond_time": - x.UnbondTime = nil case "sourcehub.tier.v1beta1.Lockup.unlock_time": x.UnlockTime = nil default: @@ -220,9 +208,6 @@ func (x *fastReflection_Lockup) Get(descriptor protoreflect.FieldDescriptor) pro case "sourcehub.tier.v1beta1.Lockup.creation_height": value := x.CreationHeight return protoreflect.ValueOfInt64(value) - case "sourcehub.tier.v1beta1.Lockup.unbond_time": - value := x.UnbondTime - return protoreflect.ValueOfMessage(value.ProtoReflect()) case "sourcehub.tier.v1beta1.Lockup.unlock_time": value := x.UnlockTime return protoreflect.ValueOfMessage(value.ProtoReflect()) @@ -254,8 +239,6 @@ func (x *fastReflection_Lockup) Set(fd protoreflect.FieldDescriptor, value proto x.Amount = value.Interface().(string) case "sourcehub.tier.v1beta1.Lockup.creation_height": x.CreationHeight = value.Int() - case "sourcehub.tier.v1beta1.Lockup.unbond_time": - x.UnbondTime = value.Message().Interface().(*timestamppb.Timestamp) case "sourcehub.tier.v1beta1.Lockup.unlock_time": x.UnlockTime = value.Message().Interface().(*timestamppb.Timestamp) default: @@ -278,11 +261,6 @@ func (x *fastReflection_Lockup) Set(fd protoreflect.FieldDescriptor, value proto // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Lockup) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "sourcehub.tier.v1beta1.Lockup.unbond_time": - if x.UnbondTime == nil { - x.UnbondTime = new(timestamppb.Timestamp) - } - return protoreflect.ValueOfMessage(x.UnbondTime.ProtoReflect()) case "sourcehub.tier.v1beta1.Lockup.unlock_time": if x.UnlockTime == nil { x.UnlockTime = new(timestamppb.Timestamp) @@ -317,9 +295,6 @@ func (x *fastReflection_Lockup) NewField(fd protoreflect.FieldDescriptor) protor return protoreflect.ValueOfString("") case "sourcehub.tier.v1beta1.Lockup.creation_height": return protoreflect.ValueOfInt64(int64(0)) - case "sourcehub.tier.v1beta1.Lockup.unbond_time": - m := new(timestamppb.Timestamp) - return protoreflect.ValueOfMessage(m.ProtoReflect()) case "sourcehub.tier.v1beta1.Lockup.unlock_time": m := new(timestamppb.Timestamp) return protoreflect.ValueOfMessage(m.ProtoReflect()) @@ -407,10 +382,6 @@ func (x *fastReflection_Lockup) ProtoMethods() *protoiface.Methods { if x.CreationHeight != 0 { n += 1 + runtime.Sov(uint64(x.CreationHeight)) } - if x.UnbondTime != nil { - l = options.Size(x.UnbondTime) - n += 1 + l + runtime.Sov(uint64(l)) - } if x.UnlockTime != nil { l = options.Size(x.UnlockTime) n += 1 + l + runtime.Sov(uint64(l)) @@ -456,20 +427,6 @@ func (x *fastReflection_Lockup) ProtoMethods() *protoiface.Methods { copy(dAtA[i:], encoded) i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) i-- - dAtA[i] = 0x32 - } - if x.UnbondTime != nil { - encoded, err := options.Marshal(x.UnbondTime) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- dAtA[i] = 0x2a } if x.CreationHeight != 0 { @@ -663,42 +620,6 @@ func (x *fastReflection_Lockup) ProtoMethods() *protoiface.Methods { } } case 5: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field UnbondTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - if x.UnbondTime == nil { - x.UnbondTime = ×tamppb.Timestamp{} - } - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.UnbondTime); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - case 6: if wireType != 2 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field UnlockTime", wireType) } @@ -791,14 +712,10 @@ type Lockup struct { DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` ValidatorAddress string `protobuf:"bytes,2,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` Amount string `protobuf:"bytes,3,opt,name=amount,proto3" json:"amount,omitempty"` - // The following fields are only used for unlocking lockups. - // - // The height at which the lockup was created. + // The height at which the lockup was created / updated. CreationHeight int64 `protobuf:"varint,4,opt,name=creation_height,json=creationHeight,proto3" json:"creation_height,omitempty"` - // The time at which the stake undelegation will be completed. - UnbondTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=unbond_time,json=unbondTime,proto3" json:"unbond_time,omitempty"` - // The time at which the stake unlocking will be completed. - UnlockTime *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=unlock_time,json=unlockTime,proto3" json:"unlock_time,omitempty"` + // The time after which the unlocking lockup can be completed. + UnlockTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=unlock_time,json=unlockTime,proto3" json:"unlock_time,omitempty"` } func (x *Lockup) Reset() { @@ -849,13 +766,6 @@ func (x *Lockup) GetCreationHeight() int64 { return 0 } -func (x *Lockup) GetUnbondTime() *timestamppb.Timestamp { - if x != nil { - return x.UnbondTime - } - return nil -} - func (x *Lockup) GetUnlockTime() *timestamppb.Timestamp { if x != nil { return x.UnlockTime @@ -875,7 +785,7 @@ var file_sourcehub_tier_v1beta1_lockup_proto_rawDesc = []byte{ 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x93, 0x03, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, + 0xd0, 0x02, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, @@ -892,29 +802,25 @@ var file_sourcehub_tier_v1beta1_lockup_proto_rawDesc = []byte{ 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, - 0x41, 0x0a, 0x0b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, + 0x41, 0x0a, 0x0b, 0x75, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x42, 0x04, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x0a, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x75, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x42, 0x04, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x0a, 0x75, 0x6e, 0x6c, 0x6f, 0x63, - 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x42, 0xd8, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x42, 0x0b, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x33, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, - 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2f, - 0x74, 0x69, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x74, 0x69, 0x65, - 0x72, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x54, 0x58, 0xaa, 0x02, - 0x16, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x54, 0x69, 0x65, 0x72, 0x2e, - 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x16, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x68, 0x75, 0x62, 0x5c, 0x54, 0x69, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xe2, 0x02, 0x22, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x5c, 0x54, 0x69, 0x65, - 0x72, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, - 0x62, 0x3a, 0x3a, 0x54, 0x69, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x42, 0x04, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x0a, 0x75, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, + 0x6d, 0x65, 0x42, 0xd8, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x42, 0x0b, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x33, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2f, 0x74, 0x69, 0x65, + 0x72, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x74, 0x69, 0x65, 0x72, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x54, 0x58, 0xaa, 0x02, 0x16, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x54, 0x69, 0x65, 0x72, 0x2e, 0x56, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x16, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, + 0x5c, 0x54, 0x69, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x22, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x5c, 0x54, 0x69, 0x65, 0x72, 0x5c, 0x56, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x18, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x3a, 0x3a, + 0x54, 0x69, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -935,13 +841,12 @@ var file_sourcehub_tier_v1beta1_lockup_proto_goTypes = []interface{}{ (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp } var file_sourcehub_tier_v1beta1_lockup_proto_depIdxs = []int32{ - 1, // 0: sourcehub.tier.v1beta1.Lockup.unbond_time:type_name -> google.protobuf.Timestamp - 1, // 1: sourcehub.tier.v1beta1.Lockup.unlock_time:type_name -> google.protobuf.Timestamp - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 1, // 0: sourcehub.tier.v1beta1.Lockup.unlock_time:type_name -> google.protobuf.Timestamp + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_sourcehub_tier_v1beta1_lockup_proto_init() } diff --git a/proto/sourcehub/tier/v1beta1/lockup.proto b/proto/sourcehub/tier/v1beta1/lockup.proto index 9e0c188..43dc681 100644 --- a/proto/sourcehub/tier/v1beta1/lockup.proto +++ b/proto/sourcehub/tier/v1beta1/lockup.proto @@ -17,14 +17,9 @@ message Lockup { (gogoproto.nullable) = false ]; - // The following fields are only used for unlocking lockups. - // - // The height at which the lockup was created. + // The height at which the lockup was created / updated. int64 creation_height = 4; - // The time at which the stake undelegation will be completed. - google.protobuf.Timestamp unbond_time = 5 [(gogoproto.stdtime) = true]; - - // The time at which the stake unlocking will be completed. - google.protobuf.Timestamp unlock_time = 6 [(gogoproto.stdtime) = true]; + // The time after which the unlocking lockup can be completed. + google.protobuf.Timestamp unlock_time = 5 [(gogoproto.stdtime) = true]; } diff --git a/x/tier/types/lockup.pb.go b/x/tier/types/lockup.pb.go index 5bce5bf..c7c56c7 100644 --- a/x/tier/types/lockup.pb.go +++ b/x/tier/types/lockup.pb.go @@ -34,14 +34,10 @@ type Lockup struct { DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` ValidatorAddress string `protobuf:"bytes,2,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` Amount cosmossdk_io_math.Int `protobuf:"bytes,3,opt,name=amount,proto3,customtype=cosmossdk.io/math.Int" json:"amount"` - // The following fields are only used for unlocking lockups. - // - // The height at which the lockup was created. + // The height at which the lockup was created / updated. CreationHeight int64 `protobuf:"varint,4,opt,name=creation_height,json=creationHeight,proto3" json:"creation_height,omitempty"` - // The time at which the stake undelegation will be completed. - UnbondTime *time.Time `protobuf:"bytes,5,opt,name=unbond_time,json=unbondTime,proto3,stdtime" json:"unbond_time,omitempty"` - // The time at which the stake unlocking will be completed. - UnlockTime *time.Time `protobuf:"bytes,6,opt,name=unlock_time,json=unlockTime,proto3,stdtime" json:"unlock_time,omitempty"` + // The time after which the unlocking lockup can be completed. + UnlockTime *time.Time `protobuf:"bytes,5,opt,name=unlock_time,json=unlockTime,proto3,stdtime" json:"unlock_time,omitempty"` } func (m *Lockup) Reset() { *m = Lockup{} } @@ -98,13 +94,6 @@ func (m *Lockup) GetCreationHeight() int64 { return 0 } -func (m *Lockup) GetUnbondTime() *time.Time { - if m != nil { - return m.UnbondTime - } - return nil -} - func (m *Lockup) GetUnlockTime() *time.Time { if m != nil { return m.UnlockTime @@ -121,33 +110,32 @@ func init() { } var fileDescriptor_2e0e6f58f533fc52 = []byte{ - // 407 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xd1, 0x8a, 0x13, 0x31, - 0x14, 0x86, 0x1b, 0xbb, 0x16, 0xcc, 0x82, 0xba, 0xc3, 0x2a, 0x63, 0xc1, 0x69, 0xd5, 0x0b, 0x0b, - 0xd2, 0x84, 0xd5, 0x27, 0xd8, 0x8a, 0x60, 0x41, 0xbc, 0xa8, 0xe2, 0x85, 0x37, 0x25, 0x33, 0x13, - 0xd3, 0xd0, 0x4e, 0x4e, 0x49, 0xce, 0x54, 0x7d, 0x8b, 0x05, 0x5f, 0xa5, 0x0f, 0xb1, 0x97, 0x4b, - 0xaf, 0xc4, 0x8b, 0x55, 0xda, 0x17, 0x91, 0x4c, 0xd2, 0x15, 0xf7, 0x6a, 0xef, 0xe6, 0xfc, 0xf3, - 0xff, 0xdf, 0x0f, 0x27, 0x87, 0x3e, 0x73, 0x50, 0xdb, 0x42, 0xce, 0xea, 0x9c, 0xa3, 0x96, 0x96, - 0xaf, 0x4e, 0x72, 0x89, 0xe2, 0x84, 0x2f, 0xa0, 0x98, 0xd7, 0x4b, 0xb6, 0xb4, 0x80, 0x90, 0x3c, - 0xbc, 0x32, 0x31, 0x6f, 0x62, 0xd1, 0xd4, 0x7d, 0x54, 0x80, 0xab, 0xc0, 0x4d, 0x1b, 0x17, 0x0f, - 0x43, 0x88, 0x74, 0x8f, 0x15, 0x28, 0x08, 0xba, 0xff, 0x8a, 0x6a, 0x4f, 0x01, 0xa8, 0x85, 0xe4, - 0xcd, 0x94, 0xd7, 0x5f, 0x38, 0xea, 0x4a, 0x3a, 0x14, 0x55, 0x6c, 0x7a, 0xfa, 0xa3, 0x4d, 0x3b, - 0xef, 0x9a, 0xea, 0xe4, 0x0d, 0x3d, 0x2a, 0xe5, 0x42, 0x2a, 0x81, 0x60, 0xa7, 0xa2, 0x2c, 0xad, - 0x74, 0x2e, 0x25, 0x7d, 0x32, 0xb8, 0x33, 0x4a, 0x37, 0xeb, 0xe1, 0x71, 0xac, 0x3b, 0x0d, 0x7f, - 0x3e, 0xa0, 0xd5, 0x46, 0x4d, 0xee, 0x5f, 0x45, 0xa2, 0x9e, 0xbc, 0xa7, 0x47, 0x2b, 0xb1, 0xd0, - 0xe5, 0x7f, 0x98, 0x5b, 0x0d, 0xe6, 0xc9, 0x66, 0x3d, 0x7c, 0x1c, 0x31, 0x9f, 0xf6, 0x9e, 0x6b, - 0xbc, 0xd5, 0x35, 0x3d, 0x79, 0x4d, 0x3b, 0xa2, 0x82, 0xda, 0x60, 0xda, 0x6e, 0x20, 0x2f, 0xce, - 0x2f, 0x7b, 0xad, 0x5f, 0x97, 0xbd, 0x07, 0x01, 0xe4, 0xca, 0x39, 0xd3, 0xc0, 0x2b, 0x81, 0x33, - 0x36, 0x36, 0xb8, 0x59, 0x0f, 0x69, 0x6c, 0x18, 0x1b, 0x9c, 0xc4, 0x68, 0xf2, 0x9c, 0xde, 0x2b, - 0xac, 0x14, 0xa8, 0xc1, 0x4c, 0x67, 0x52, 0xab, 0x19, 0xa6, 0x07, 0x7d, 0x32, 0x68, 0x4f, 0xee, - 0xee, 0xe5, 0xb7, 0x8d, 0x9a, 0x9c, 0xd2, 0xc3, 0xda, 0xe4, 0x60, 0xca, 0xa9, 0xdf, 0x54, 0x7a, - 0xbb, 0x4f, 0x06, 0x87, 0x2f, 0xbb, 0x2c, 0xac, 0x91, 0xed, 0xd7, 0xc8, 0x3e, 0xee, 0xd7, 0x38, - 0x3a, 0x38, 0xfb, 0xdd, 0x23, 0x13, 0x1a, 0x42, 0x5e, 0x0e, 0x08, 0xff, 0x9c, 0x01, 0xd1, 0xb9, - 0x39, 0xc2, 0x87, 0xbc, 0x3c, 0x1a, 0x9f, 0x6f, 0x33, 0x72, 0xb1, 0xcd, 0xc8, 0x9f, 0x6d, 0x46, - 0xce, 0x76, 0x59, 0xeb, 0x62, 0x97, 0xb5, 0x7e, 0xee, 0xb2, 0xd6, 0x67, 0xae, 0x34, 0xfa, 0xb3, - 0x28, 0xa0, 0xe2, 0xe1, 0x48, 0x8c, 0xc4, 0xaf, 0x60, 0xe7, 0xfc, 0xdf, 0x5d, 0x7d, 0x0b, 0x97, - 0x85, 0xdf, 0x97, 0xd2, 0xe5, 0x9d, 0xa6, 0xf0, 0xd5, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe7, - 0x59, 0x99, 0xc1, 0x78, 0x02, 0x00, 0x00, + // 390 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x52, 0xdd, 0x8a, 0xd3, 0x40, + 0x14, 0xee, 0xec, 0xae, 0x05, 0x67, 0x41, 0xdd, 0xb0, 0x4a, 0x2c, 0x98, 0x56, 0xbd, 0xb0, 0x20, + 0x9d, 0x61, 0xf5, 0x09, 0xb6, 0x22, 0x58, 0x10, 0x2f, 0xaa, 0x78, 0xe1, 0x4d, 0x98, 0x24, 0xe3, + 0x64, 0x68, 0x92, 0x53, 0x66, 0x4e, 0xaa, 0xbe, 0xc5, 0x3e, 0x4c, 0x1f, 0x62, 0x2f, 0x4b, 0xaf, + 0xc4, 0x8b, 0x55, 0xda, 0x17, 0x91, 0x64, 0x26, 0x2b, 0xf6, 0x6e, 0xce, 0x37, 0xdf, 0x0f, 0x7c, + 0xe7, 0xd0, 0xe7, 0x16, 0x6a, 0x93, 0xca, 0xbc, 0x4e, 0x38, 0x6a, 0x69, 0xf8, 0xea, 0x22, 0x91, + 0x28, 0x2e, 0x78, 0x01, 0xe9, 0xa2, 0x5e, 0xb2, 0xa5, 0x01, 0x84, 0xe0, 0xd1, 0x2d, 0x89, 0x35, + 0x24, 0xe6, 0x49, 0x83, 0xc7, 0x29, 0xd8, 0x12, 0x6c, 0xdc, 0xb2, 0xb8, 0x1b, 0x9c, 0x64, 0x70, + 0xae, 0x40, 0x81, 0xc3, 0x9b, 0x97, 0x47, 0x87, 0x0a, 0x40, 0x15, 0x92, 0xb7, 0x53, 0x52, 0x7f, + 0xe5, 0xa8, 0x4b, 0x69, 0x51, 0x94, 0x3e, 0xe9, 0xd9, 0xe6, 0x88, 0xf6, 0xdf, 0xb7, 0xd1, 0xc1, + 0x5b, 0x7a, 0x96, 0xc9, 0x42, 0x2a, 0x81, 0x60, 0x62, 0x91, 0x65, 0x46, 0x5a, 0x1b, 0x92, 0x11, + 0x19, 0xdf, 0x9d, 0x86, 0xdb, 0xf5, 0xe4, 0xdc, 0xc7, 0x5d, 0xba, 0x9f, 0x8f, 0x68, 0x74, 0xa5, + 0xe6, 0x0f, 0x6e, 0x25, 0x1e, 0x0f, 0x3e, 0xd0, 0xb3, 0x95, 0x28, 0x74, 0xf6, 0x9f, 0xcd, 0x51, + 0x6b, 0xf3, 0x74, 0xbb, 0x9e, 0x3c, 0xf1, 0x36, 0x9f, 0x3b, 0xce, 0x81, 0xdf, 0xea, 0x00, 0x0f, + 0xde, 0xd0, 0xbe, 0x28, 0xa1, 0xae, 0x30, 0x3c, 0x6e, 0x4d, 0x5e, 0x5e, 0xdf, 0x0c, 0x7b, 0xbf, + 0x6e, 0x86, 0x0f, 0x9d, 0x91, 0xcd, 0x16, 0x4c, 0x03, 0x2f, 0x05, 0xe6, 0x6c, 0x56, 0xe1, 0x76, + 0x3d, 0xa1, 0x3e, 0x61, 0x56, 0xe1, 0xdc, 0x4b, 0x83, 0x17, 0xf4, 0x7e, 0x6a, 0xa4, 0x40, 0x0d, + 0x55, 0x9c, 0x4b, 0xad, 0x72, 0x0c, 0x4f, 0x46, 0x64, 0x7c, 0x3c, 0xbf, 0xd7, 0xc1, 0xef, 0x5a, + 0x34, 0xb8, 0xa4, 0xa7, 0x75, 0xd5, 0xec, 0x22, 0x6e, 0x9a, 0x0a, 0xef, 0x8c, 0xc8, 0xf8, 0xf4, + 0xd5, 0x80, 0xb9, 0x1a, 0x59, 0x57, 0x23, 0xfb, 0xd4, 0xd5, 0x38, 0x3d, 0xb9, 0xfa, 0x3d, 0x24, + 0x73, 0xea, 0x44, 0x0d, 0x3c, 0x9d, 0x5d, 0xef, 0x22, 0xb2, 0xd9, 0x45, 0xe4, 0xcf, 0x2e, 0x22, + 0x57, 0xfb, 0xa8, 0xb7, 0xd9, 0x47, 0xbd, 0x9f, 0xfb, 0xa8, 0xf7, 0x85, 0x2b, 0x8d, 0xcd, 0x4e, + 0x53, 0x28, 0xb9, 0xdb, 0x70, 0x25, 0xf1, 0x1b, 0x98, 0x05, 0xff, 0x77, 0x14, 0xdf, 0xdd, 0x59, + 0xe0, 0x8f, 0xa5, 0xb4, 0x49, 0xbf, 0x0d, 0x7c, 0xfd, 0x37, 0x00, 0x00, 0xff, 0xff, 0x6a, 0xdd, + 0x62, 0x98, 0x35, 0x02, 0x00, 0x00, } func (m *Lockup) Marshal() (dAtA []byte, err error) { @@ -178,16 +166,6 @@ func (m *Lockup) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= n1 i = encodeVarintLockup(dAtA, i, uint64(n1)) i-- - dAtA[i] = 0x32 - } - if m.UnbondTime != nil { - n2, err2 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.UnbondTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.UnbondTime):]) - if err2 != nil { - return 0, err2 - } - i -= n2 - i = encodeVarintLockup(dAtA, i, uint64(n2)) - i-- dAtA[i] = 0x2a } if m.CreationHeight != 0 { @@ -252,10 +230,6 @@ func (m *Lockup) Size() (n int) { if m.CreationHeight != 0 { n += 1 + sovLockup(uint64(m.CreationHeight)) } - if m.UnbondTime != nil { - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.UnbondTime) - n += 1 + l + sovLockup(uint64(l)) - } if m.UnlockTime != nil { l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.UnlockTime) n += 1 + l + sovLockup(uint64(l)) @@ -416,42 +390,6 @@ func (m *Lockup) Unmarshal(dAtA []byte) error { } } case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UnbondTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowLockup - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthLockup - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthLockup - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.UnbondTime == nil { - m.UnbondTime = new(time.Time) - } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(m.UnbondTime, dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field UnlockTime", wireType) } From 8f4160901efc799420d67942624c606a75e74bb2 Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 20 Dec 2024 18:57:09 +0800 Subject: [PATCH 02/17] Remove unused event attribute, update genesis and related tests --- x/tier/module/genesis.go | 2 +- x/tier/module/genesis_test.go | 16 ---------------- x/tier/types/events.go | 1 - 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/x/tier/module/genesis.go b/x/tier/module/genesis.go index d16a74b..17f261c 100644 --- a/x/tier/module/genesis.go +++ b/x/tier/module/genesis.go @@ -21,7 +21,7 @@ func InitGenesis(ctx context.Context, k keeper.Keeper, genState types.GenesisSta if k.HasLockup(ctx, delAddr, valAddr) { k.AddLockup(ctx, delAddr, valAddr, lockup.Amount) } else { - k.SaveLockup(ctx, lockup.UnlockTime != nil, delAddr, valAddr, lockup.Amount, lockup.CreationHeight, lockup.UnbondTime, lockup.UnlockTime) + k.SaveLockup(ctx, lockup.UnlockTime != nil, delAddr, valAddr, lockup.Amount, lockup.CreationHeight, lockup.UnlockTime) } } } diff --git a/x/tier/module/genesis_test.go b/x/tier/module/genesis_test.go index 6aac0b7..84b1340 100644 --- a/x/tier/module/genesis_test.go +++ b/x/tier/module/genesis_test.go @@ -30,7 +30,6 @@ func TestGenesis(t *testing.T) { ValidatorAddress: "sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm", Amount: math.NewInt(1000), CreationHeight: 1, - UnbondTime: ×tamp1, UnlockTime: ×tamp1, }, { @@ -38,7 +37,6 @@ func TestGenesis(t *testing.T) { ValidatorAddress: "sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm", Amount: math.NewInt(500), CreationHeight: 2, - UnbondTime: ×tamp2, UnlockTime: ×tamp2, }, { @@ -46,7 +44,6 @@ func TestGenesis(t *testing.T) { ValidatorAddress: "sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm", Amount: math.NewInt(2000), CreationHeight: 3, - UnbondTime: ×tamp3, UnlockTime: ×tamp3, }, }, @@ -63,12 +60,6 @@ func TestGenesis(t *testing.T) { require.Equal(t, lockup.ValidatorAddress, got.Lockups[i].ValidatorAddress) require.Equal(t, lockup.Amount, got.Lockups[i].Amount) require.Equal(t, lockup.CreationHeight, got.Lockups[i].CreationHeight) - if lockup.UnbondTime != nil { - require.NotNil(t, got.Lockups[i].UnbondTime) - require.Equal(t, lockup.UnbondTime.UTC(), got.Lockups[i].UnbondTime.UTC()) - } else { - require.Nil(t, got.Lockups[i].UnbondTime) - } if lockup.UnlockTime != nil { require.NotNil(t, got.Lockups[i].UnlockTime) require.Equal(t, lockup.UnlockTime.UTC(), got.Lockups[i].UnlockTime.UTC()) @@ -82,10 +73,6 @@ func TestGenesis(t *testing.T) { } func TestInitWithMultipleIdenticalLockups(t *testing.T) { - timestamp1 := time.Date(2006, time.January, 2, 15, 4, 5, 1, time.UTC) - timestamp2 := time.Date(2006, time.January, 2, 15, 4, 5, 2, time.UTC) - timestamp3 := time.Date(2006, time.January, 2, 15, 4, 5, 3, time.UTC) - genesisState := types.GenesisState{ Params: types.DefaultParams(), Lockups: []types.Lockup{ @@ -94,7 +81,6 @@ func TestInitWithMultipleIdenticalLockups(t *testing.T) { ValidatorAddress: "sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm", Amount: math.NewInt(1000), CreationHeight: 1, - UnbondTime: ×tamp1, UnlockTime: nil, }, { @@ -102,7 +88,6 @@ func TestInitWithMultipleIdenticalLockups(t *testing.T) { ValidatorAddress: "sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm", Amount: math.NewInt(2000), CreationHeight: 2, - UnbondTime: ×tamp2, UnlockTime: nil, }, { @@ -110,7 +95,6 @@ func TestInitWithMultipleIdenticalLockups(t *testing.T) { ValidatorAddress: "sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm", Amount: math.NewInt(3000), CreationHeight: 3, - UnbondTime: ×tamp3, UnlockTime: nil, }, }, diff --git a/x/tier/types/events.go b/x/tier/types/events.go index 48c6f3e..39847b6 100644 --- a/x/tier/types/events.go +++ b/x/tier/types/events.go @@ -11,6 +11,5 @@ const ( AttributeKeyCreationHeight = "creation_height" AttributeKeyDestinationValidator = "destination_validator" AttributeKeySourceValidator = "source_validator" - AttributeKeyUnbondTime = "unbond_time" AttributeKeyUnlockTime = "unlock_time" ) From 62a09a50bd2c0633a9d25a17653901f0cab85842 Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 20 Dec 2024 19:02:19 +0800 Subject: [PATCH 03/17] Add creation_height to MsgUnlockResponse and run proto gen --- api/sourcehub/tier/v1beta1/tx.pulsar.go | 257 +++++++++++++++--------- proto/sourcehub/tier/v1beta1/tx.proto | 1 + x/tier/types/tx.pb.go | 132 +++++++----- 3 files changed, 243 insertions(+), 147 deletions(-) diff --git a/api/sourcehub/tier/v1beta1/tx.pulsar.go b/api/sourcehub/tier/v1beta1/tx.pulsar.go index ae35756..4332207 100644 --- a/api/sourcehub/tier/v1beta1/tx.pulsar.go +++ b/api/sourcehub/tier/v1beta1/tx.pulsar.go @@ -2358,12 +2358,14 @@ func (x *fastReflection_MsgUnlock) ProtoMethods() *protoiface.Methods { var ( md_MsgUnlockResponse protoreflect.MessageDescriptor fd_MsgUnlockResponse_completion_time protoreflect.FieldDescriptor + fd_MsgUnlockResponse_creation_height protoreflect.FieldDescriptor ) func init() { file_sourcehub_tier_v1beta1_tx_proto_init() md_MsgUnlockResponse = File_sourcehub_tier_v1beta1_tx_proto.Messages().ByName("MsgUnlockResponse") fd_MsgUnlockResponse_completion_time = md_MsgUnlockResponse.Fields().ByName("completion_time") + fd_MsgUnlockResponse_creation_height = md_MsgUnlockResponse.Fields().ByName("creation_height") } var _ protoreflect.Message = (*fastReflection_MsgUnlockResponse)(nil) @@ -2437,6 +2439,12 @@ func (x *fastReflection_MsgUnlockResponse) Range(f func(protoreflect.FieldDescri return } } + if x.CreationHeight != int64(0) { + value := protoreflect.ValueOfInt64(x.CreationHeight) + if !f(fd_MsgUnlockResponse_creation_height, value) { + return + } + } } // Has reports whether a field is populated. @@ -2454,6 +2462,8 @@ func (x *fastReflection_MsgUnlockResponse) Has(fd protoreflect.FieldDescriptor) switch fd.FullName() { case "sourcehub.tier.v1beta1.MsgUnlockResponse.completion_time": return x.CompletionTime != nil + case "sourcehub.tier.v1beta1.MsgUnlockResponse.creation_height": + return x.CreationHeight != int64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: sourcehub.tier.v1beta1.MsgUnlockResponse")) @@ -2472,6 +2482,8 @@ func (x *fastReflection_MsgUnlockResponse) Clear(fd protoreflect.FieldDescriptor switch fd.FullName() { case "sourcehub.tier.v1beta1.MsgUnlockResponse.completion_time": x.CompletionTime = nil + case "sourcehub.tier.v1beta1.MsgUnlockResponse.creation_height": + x.CreationHeight = int64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: sourcehub.tier.v1beta1.MsgUnlockResponse")) @@ -2491,6 +2503,9 @@ func (x *fastReflection_MsgUnlockResponse) Get(descriptor protoreflect.FieldDesc case "sourcehub.tier.v1beta1.MsgUnlockResponse.completion_time": value := x.CompletionTime return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "sourcehub.tier.v1beta1.MsgUnlockResponse.creation_height": + value := x.CreationHeight + return protoreflect.ValueOfInt64(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: sourcehub.tier.v1beta1.MsgUnlockResponse")) @@ -2513,6 +2528,8 @@ func (x *fastReflection_MsgUnlockResponse) Set(fd protoreflect.FieldDescriptor, switch fd.FullName() { case "sourcehub.tier.v1beta1.MsgUnlockResponse.completion_time": x.CompletionTime = value.Message().Interface().(*timestamppb.Timestamp) + case "sourcehub.tier.v1beta1.MsgUnlockResponse.creation_height": + x.CreationHeight = value.Int() default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: sourcehub.tier.v1beta1.MsgUnlockResponse")) @@ -2538,6 +2555,8 @@ func (x *fastReflection_MsgUnlockResponse) Mutable(fd protoreflect.FieldDescript x.CompletionTime = new(timestamppb.Timestamp) } return protoreflect.ValueOfMessage(x.CompletionTime.ProtoReflect()) + case "sourcehub.tier.v1beta1.MsgUnlockResponse.creation_height": + panic(fmt.Errorf("field creation_height of message sourcehub.tier.v1beta1.MsgUnlockResponse is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: sourcehub.tier.v1beta1.MsgUnlockResponse")) @@ -2554,6 +2573,8 @@ func (x *fastReflection_MsgUnlockResponse) NewField(fd protoreflect.FieldDescrip case "sourcehub.tier.v1beta1.MsgUnlockResponse.completion_time": m := new(timestamppb.Timestamp) return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "sourcehub.tier.v1beta1.MsgUnlockResponse.creation_height": + return protoreflect.ValueOfInt64(int64(0)) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: sourcehub.tier.v1beta1.MsgUnlockResponse")) @@ -2627,6 +2648,9 @@ func (x *fastReflection_MsgUnlockResponse) ProtoMethods() *protoiface.Methods { l = options.Size(x.CompletionTime) n += 1 + l + runtime.Sov(uint64(l)) } + if x.CreationHeight != 0 { + n += 1 + runtime.Sov(uint64(x.CreationHeight)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -2656,6 +2680,11 @@ func (x *fastReflection_MsgUnlockResponse) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if x.CreationHeight != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.CreationHeight)) + i-- + dAtA[i] = 0x10 + } if x.CompletionTime != nil { encoded, err := options.Marshal(x.CompletionTime) if err != nil { @@ -2755,6 +2784,25 @@ func (x *fastReflection_MsgUnlockResponse) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err } iNdEx = postIndex + case 2: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CreationHeight", wireType) + } + x.CreationHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.CreationHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -5044,6 +5092,7 @@ type MsgUnlockResponse struct { unknownFields protoimpl.UnknownFields CompletionTime *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=completion_time,json=completionTime,proto3" json:"completion_time,omitempty"` + CreationHeight int64 `protobuf:"varint,2,opt,name=creation_height,json=creationHeight,proto3" json:"creation_height,omitempty"` } func (x *MsgUnlockResponse) Reset() { @@ -5073,6 +5122,13 @@ func (x *MsgUnlockResponse) GetCompletionTime() *timestamppb.Timestamp { return nil } +func (x *MsgUnlockResponse) GetCreationHeight() int64 { + if x != nil { + return x.CreationHeight + } + return 0 +} + // MsgRedelegate is the Msg/Redelegate request type. type MsgRedelegate struct { state protoimpl.MessageState @@ -5322,108 +5378,111 @@ var file_sourcehub_tier_v1beta1_tx_proto_rawDesc = []byte{ 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x05, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x3a, 0x16, 0x82, 0xe7, 0xb0, 0x2a, 0x11, 0x64, 0x65, 0x6c, - 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x67, - 0x0a, 0x11, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, - 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xd8, 0x02, 0x0a, 0x0d, 0x4d, 0x73, 0x67, 0x52, - 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, - 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, - 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x55, 0x0a, 0x15, 0x73, 0x72, 0x63, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x13, 0x73, 0x72, 0x63, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x64, 0x73, 0x74, 0x5f, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x64, 0x73, 0x74, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3a, - 0x0a, 0x05, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, - 0xb0, 0x2a, 0x01, 0x52, 0x05, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x3a, 0x16, 0x82, 0xe7, 0xb0, 0x2a, - 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x22, 0x6b, 0x0a, 0x15, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x63, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, - 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, - 0xa3, 0x02, 0x0a, 0x12, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x6c, - 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, - 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, - 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x35, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x05, 0x73, - 0x74, 0x61, 0x6b, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x16, 0x82, - 0xe7, 0xb0, 0x2a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x1c, 0x0a, 0x1a, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, - 0x65, 0x6c, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x32, 0xf7, 0x03, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x68, 0x0a, 0x0c, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x27, 0x2e, 0x73, 0x6f, + 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x90, + 0x01, 0x0a, 0x11, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, + 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x22, 0xd8, 0x02, 0x0a, 0x0d, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, + 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x73, 0x72, + 0x63, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x73, 0x72, + 0x63, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x55, 0x0a, 0x15, 0x64, 0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x13, 0x64, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3a, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x6b, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, + 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x05, 0x73, + 0x74, 0x61, 0x6b, 0x65, 0x3a, 0x16, 0x82, 0xe7, 0xb0, 0x2a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x6b, 0x0a, 0x15, + 0x4d, 0x73, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, + 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xa3, 0x02, 0x0a, 0x12, 0x4d, 0x73, + 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, + 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, + 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x6b, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, + 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x27, + 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x16, 0x82, 0xe7, 0xb0, 0x2a, 0x11, 0x64, 0x65, + 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, + 0x1c, 0x0a, 0x1a, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x6c, 0x6f, + 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xf7, 0x03, + 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x68, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x27, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, + 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, + 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x2f, + 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x50, 0x0a, 0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x1f, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4d, 0x73, 0x67, 0x4c, 0x6f, 0x63, 0x6b, 0x1a, 0x27, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x56, 0x0a, 0x06, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x21, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x2f, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, - 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, - 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x1f, 0x2e, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4c, 0x6f, 0x63, 0x6b, 0x1a, 0x27, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0x29, + 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x6e, 0x6c, 0x6f, 0x63, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0a, 0x52, 0x65, 0x64, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x25, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x1a, 0x2d, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4c, 0x6f, 0x63, 0x6b, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x06, 0x55, 0x6e, 0x6c, 0x6f, 0x63, - 0x6b, 0x12, 0x21, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x6e, - 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0x29, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, - 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, - 0x67, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x62, 0x0a, 0x0a, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x25, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, + 0x0f, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, + 0x12, 0x2a, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, + 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x1a, 0x32, 0x2e, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, + 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xd4, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, - 0x67, 0x61, 0x74, 0x65, 0x1a, 0x2d, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, - 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, - 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x0f, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x6c, - 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x2a, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, - 0x75, 0x62, 0x2e, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x4d, 0x73, 0x67, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x69, - 0x6e, 0x67, 0x1a, 0x32, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x74, - 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, - 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xd4, 0x01, - 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, - 0x74, 0x69, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x07, 0x54, 0x78, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x33, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, - 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x68, 0x75, 0x62, 0x2f, 0x74, 0x69, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x3b, 0x74, 0x69, 0x65, 0x72, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x53, - 0x54, 0x58, 0xaa, 0x02, 0x16, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x54, - 0x69, 0x65, 0x72, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x16, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x5c, 0x54, 0x69, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x22, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, - 0x5c, 0x54, 0x69, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x68, 0x75, 0x62, 0x3a, 0x3a, 0x54, 0x69, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x33, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2f, 0x74, 0x69, + 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x74, 0x69, 0x65, 0x72, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x54, 0x58, 0xaa, 0x02, 0x16, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x54, 0x69, 0x65, 0x72, 0x2e, 0x56, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x16, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, + 0x62, 0x5c, 0x54, 0x69, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, + 0x22, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x5c, 0x54, 0x69, 0x65, 0x72, 0x5c, + 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x68, 0x75, 0x62, 0x3a, + 0x3a, 0x54, 0x69, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/sourcehub/tier/v1beta1/tx.proto b/proto/sourcehub/tier/v1beta1/tx.proto index c85bf59..b02d738 100644 --- a/proto/sourcehub/tier/v1beta1/tx.proto +++ b/proto/sourcehub/tier/v1beta1/tx.proto @@ -85,6 +85,7 @@ message MsgUnlockResponse { (amino.dont_omitempty) = true, (gogoproto.stdtime) = true ]; + int64 creation_height = 2; } // MsgRedelegate is the Msg/Redelegate request type. diff --git a/x/tier/types/tx.pb.go b/x/tier/types/tx.pb.go index 301c0e1..bb5d803 100644 --- a/x/tier/types/tx.pb.go +++ b/x/tier/types/tx.pb.go @@ -291,6 +291,7 @@ func (m *MsgUnlock) GetStake() types.Coin { // MsgUnlockResponse defines the response structure for executing a MsgUnlock message. type MsgUnlockResponse struct { CompletionTime time.Time `protobuf:"bytes,1,opt,name=completion_time,json=completionTime,proto3,stdtime" json:"completion_time"` + CreationHeight int64 `protobuf:"varint,2,opt,name=creation_height,json=creationHeight,proto3" json:"creation_height,omitempty"` } func (m *MsgUnlockResponse) Reset() { *m = MsgUnlockResponse{} } @@ -333,6 +334,13 @@ func (m *MsgUnlockResponse) GetCompletionTime() time.Time { return time.Time{} } +func (m *MsgUnlockResponse) GetCreationHeight() int64 { + if m != nil { + return m.CreationHeight + } + return 0 +} + // MsgRedelegate is the Msg/Redelegate request type. type MsgRedelegate struct { DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` @@ -571,54 +579,55 @@ func init() { func init() { proto.RegisterFile("sourcehub/tier/v1beta1/tx.proto", fileDescriptor_a120ff6388a0dc08) } var fileDescriptor_a120ff6388a0dc08 = []byte{ - // 749 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x55, 0x3d, 0x4f, 0x1b, 0x4b, - 0x14, 0xf5, 0xda, 0xc0, 0x93, 0x87, 0x07, 0x7e, 0xde, 0xc7, 0x87, 0x59, 0xbd, 0xb7, 0x06, 0x47, - 0x11, 0xc4, 0x12, 0xbb, 0xc2, 0x28, 0x29, 0xe8, 0x30, 0x8a, 0x94, 0x48, 0x71, 0x84, 0x9c, 0x40, - 0x91, 0xc6, 0x1a, 0xaf, 0x27, 0xe3, 0x95, 0xbd, 0x3b, 0x9b, 0x9d, 0xb1, 0x03, 0x5d, 0x94, 0x32, - 0x15, 0xff, 0x21, 0x4d, 0x4a, 0x0a, 0xfe, 0x40, 0x3a, 0x4a, 0x44, 0x45, 0x95, 0x44, 0x50, 0xf0, - 0x07, 0xa2, 0xa4, 0x8d, 0x66, 0x76, 0x76, 0x0d, 0x0b, 0x36, 0x96, 0x42, 0xa4, 0x48, 0x69, 0xec, - 0x9d, 0x7b, 0xcf, 0x9c, 0x99, 0x73, 0xee, 0xdc, 0x19, 0x90, 0xa7, 0xa4, 0xe3, 0x5b, 0xa8, 0xd9, - 0xa9, 0x9b, 0xcc, 0x46, 0xbe, 0xd9, 0x5d, 0xa9, 0x23, 0x06, 0x57, 0x4c, 0xb6, 0x63, 0x78, 0x3e, - 0x61, 0x44, 0x9d, 0x89, 0x00, 0x06, 0x07, 0x18, 0x12, 0xa0, 0x65, 0xa1, 0x63, 0xbb, 0xc4, 0x14, - 0xbf, 0x01, 0x54, 0xd3, 0x2d, 0x42, 0x1d, 0x42, 0xcd, 0x3a, 0xa4, 0x28, 0x22, 0xb2, 0x88, 0xed, - 0xca, 0xfc, 0xac, 0xcc, 0x3b, 0x14, 0x9b, 0xdd, 0x15, 0xfe, 0x27, 0x13, 0x73, 0x41, 0xa2, 0x26, - 0x46, 0x66, 0x30, 0x90, 0xa9, 0x29, 0x4c, 0x30, 0x09, 0xe2, 0xfc, 0x4b, 0x46, 0xf3, 0x98, 0x10, - 0xdc, 0x46, 0xa6, 0x18, 0xd5, 0x3b, 0x2f, 0x4d, 0x66, 0x3b, 0x88, 0x32, 0xe8, 0x78, 0x12, 0x70, - 0xa7, 0x8f, 0x2c, 0x0f, 0xfa, 0xd0, 0x91, 0xdc, 0x85, 0x8f, 0x0a, 0xc8, 0x54, 0x28, 0xde, 0xf2, - 0x1a, 0x90, 0xa1, 0x4d, 0x91, 0x51, 0x1f, 0x80, 0x34, 0xec, 0xb0, 0x26, 0xf1, 0x6d, 0xb6, 0x9b, - 0x53, 0xe6, 0x95, 0xa5, 0x74, 0x39, 0x77, 0x7c, 0xb0, 0x3c, 0x25, 0x37, 0xb5, 0xde, 0x68, 0xf8, - 0x88, 0xd2, 0x67, 0xcc, 0xb7, 0x5d, 0x5c, 0xed, 0x41, 0xd5, 0x75, 0x30, 0x16, 0x70, 0xe7, 0x92, - 0xf3, 0xca, 0xd2, 0x78, 0x49, 0x37, 0xae, 0xf7, 0xcd, 0x08, 0xd6, 0x29, 0xa7, 0x0f, 0x3f, 0xe5, - 0x13, 0x1f, 0xce, 0xf7, 0x8b, 0x4a, 0x55, 0x4e, 0x5c, 0x5b, 0x7d, 0x7b, 0xbe, 0x5f, 0xec, 0x51, - 0xbe, 0x3b, 0xdf, 0x2f, 0xce, 0xf7, 0x64, 0xec, 0x04, 0x42, 0x62, 0xfb, 0x2d, 0xcc, 0x81, 0xd9, - 0x58, 0xa8, 0x8a, 0xa8, 0x47, 0x5c, 0x8a, 0x0a, 0x5f, 0x15, 0xf0, 0x57, 0x85, 0xe2, 0x27, 0xc4, - 0x6a, 0xa9, 0x0f, 0x41, 0xb6, 0x81, 0xda, 0x08, 0x43, 0x46, 0xfc, 0x1a, 0x0c, 0x44, 0xdc, 0x28, - 0xef, 0x9f, 0x68, 0x8a, 0x8c, 0xab, 0x4f, 0x41, 0xb6, 0x0b, 0xdb, 0x76, 0xe3, 0x12, 0x4d, 0x52, - 0xd0, 0x2c, 0x1c, 0x1f, 0x2c, 0xff, 0x2f, 0x69, 0xb6, 0x43, 0x4c, 0x8c, 0xaf, 0x1b, 0x8b, 0xab, - 0x6b, 0x60, 0x94, 0x32, 0xd8, 0x42, 0xb9, 0x94, 0x30, 0x6d, 0xce, 0x90, 0x04, 0xfc, 0x04, 0x45, - 0x8e, 0x6d, 0x10, 0xdb, 0xbd, 0xe8, 0x57, 0x30, 0x65, 0x6d, 0x86, 0xdb, 0x75, 0x55, 0x55, 0x21, - 0x2b, 0x8a, 0xca, 0x55, 0x47, 0x4e, 0x7c, 0x53, 0x40, 0x9a, 0xbb, 0xe4, 0xb6, 0xff, 0x30, 0x2f, - 0x30, 0xc8, 0x46, 0xba, 0x43, 0x37, 0xd4, 0x2a, 0xc8, 0x58, 0xc4, 0xf1, 0xda, 0x88, 0xd9, 0xc4, - 0xad, 0xf1, 0xce, 0x11, 0xea, 0xc7, 0x4b, 0x9a, 0x11, 0xb4, 0x95, 0x11, 0xb6, 0x95, 0xf1, 0x3c, - 0x6c, 0xab, 0xf2, 0x04, 0x5f, 0x73, 0xef, 0x73, 0x5e, 0x09, 0xd6, 0x9d, 0xec, 0x31, 0x70, 0x4c, - 0xe1, 0x24, 0x09, 0x26, 0x2a, 0x14, 0x57, 0x91, 0xdc, 0x03, 0xba, 0x2d, 0x97, 0xb7, 0xc0, 0x34, - 0xf5, 0xad, 0xda, 0x4f, 0x38, 0xfd, 0x2f, 0xf5, 0xad, 0x78, 0x8a, 0xd3, 0x36, 0x28, 0xbb, 0x86, - 0x36, 0x35, 0x34, 0x6d, 0x83, 0xb2, 0xed, 0xbe, 0x35, 0x1c, 0xb9, 0xbd, 0x1a, 0xb6, 0xc0, 0xf4, - 0x25, 0x67, 0x7f, 0x69, 0x1d, 0xdf, 0x27, 0x81, 0x5a, 0xa1, 0x78, 0x03, 0xba, 0x16, 0x6a, 0x07, - 0xe7, 0xc6, 0x76, 0xf1, 0xef, 0xda, 0x32, 0xf7, 0x87, 0x6e, 0x99, 0x11, 0x2e, 0x5b, 0x3a, 0xad, - 0x2e, 0x82, 0x8c, 0xe5, 0x23, 0x28, 0x6c, 0x6b, 0x22, 0x1b, 0x37, 0x99, 0xa8, 0x57, 0xaa, 0x3a, - 0x19, 0x86, 0x1f, 0x89, 0x68, 0xdf, 0x92, 0xfc, 0x07, 0xb4, 0xab, 0x26, 0x85, 0x75, 0x29, 0x7d, - 0x4f, 0x81, 0x54, 0x85, 0x62, 0xb5, 0x09, 0xfe, 0xbe, 0xf4, 0xb4, 0x2c, 0xf6, 0x7b, 0x12, 0x62, - 0x17, 0xb8, 0x66, 0x0e, 0x09, 0x8c, 0x4e, 0xc2, 0x26, 0x18, 0x11, 0xb7, 0x7c, 0x7e, 0xc0, 0x44, - 0x0e, 0xd0, 0x16, 0x6f, 0x00, 0x44, 0x8c, 0xdb, 0x60, 0x4c, 0xde, 0x96, 0x0b, 0x83, 0x36, 0x23, - 0x20, 0xda, 0xbd, 0x1b, 0x21, 0x11, 0x6f, 0x1d, 0x80, 0x0b, 0x77, 0xc4, 0xdd, 0x01, 0x13, 0x7b, - 0x30, 0x6d, 0x79, 0x28, 0x58, 0xb4, 0xc6, 0x2b, 0x90, 0x89, 0x9f, 0xdf, 0xe2, 0x00, 0x86, 0x18, - 0x56, 0x2b, 0x0d, 0x8f, 0x0d, 0x97, 0xd4, 0x46, 0xdf, 0xf0, 0x6e, 0x2a, 0x3f, 0x3e, 0x3c, 0xd5, - 0x95, 0xa3, 0x53, 0x5d, 0xf9, 0x72, 0xaa, 0x2b, 0x7b, 0x67, 0x7a, 0xe2, 0xe8, 0x4c, 0x4f, 0x9c, - 0x9c, 0xe9, 0x89, 0x17, 0x26, 0xb6, 0x19, 0x27, 0xb4, 0x88, 0x63, 0x06, 0xf4, 0x2e, 0x62, 0xaf, - 0x89, 0xdf, 0x32, 0xaf, 0xbc, 0xf0, 0x6c, 0xd7, 0x43, 0xb4, 0x3e, 0x26, 0x7a, 0x77, 0xf5, 0x47, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x7e, 0xbd, 0x9a, 0xa0, 0x09, 0x00, 0x00, + // 758 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x56, 0x3f, 0x4f, 0x1b, 0x4b, + 0x10, 0xf7, 0xd9, 0x86, 0x27, 0x2f, 0x0f, 0xfc, 0x7c, 0x8f, 0x3f, 0xe6, 0xf4, 0xde, 0x19, 0x1c, + 0x45, 0x10, 0x4b, 0xdc, 0x09, 0xa3, 0xa4, 0xa0, 0xc3, 0x28, 0x52, 0x22, 0xc5, 0x11, 0x72, 0x02, + 0x45, 0x1a, 0x6b, 0x7d, 0xde, 0xac, 0x4f, 0xf6, 0xdd, 0x3a, 0xb7, 0x6b, 0x07, 0xba, 0x28, 0x65, + 0x2a, 0xbe, 0x43, 0x9a, 0x94, 0x14, 0x7c, 0x81, 0x74, 0x94, 0x88, 0x8a, 0x2a, 0x89, 0xa0, 0xe0, + 0x0b, 0x44, 0x49, 0x1b, 0xed, 0xde, 0xde, 0x19, 0x0e, 0xdb, 0x58, 0x0a, 0x91, 0x22, 0xa5, 0xb1, + 0xbd, 0x33, 0xbf, 0xfd, 0xcd, 0xce, 0x6f, 0x66, 0x76, 0x0d, 0x72, 0x94, 0x74, 0x3c, 0x0b, 0x35, + 0x3a, 0x35, 0x93, 0xd9, 0xc8, 0x33, 0xbb, 0xab, 0x35, 0xc4, 0xe0, 0xaa, 0xc9, 0x76, 0x8d, 0xb6, + 0x47, 0x18, 0x51, 0x67, 0x43, 0x80, 0xc1, 0x01, 0x86, 0x04, 0x68, 0x19, 0xe8, 0xd8, 0x2e, 0x31, + 0xc5, 0xa7, 0x0f, 0xd5, 0x74, 0x8b, 0x50, 0x87, 0x50, 0xb3, 0x06, 0x29, 0x0a, 0x89, 0x2c, 0x62, + 0xbb, 0xd2, 0x3f, 0x27, 0xfd, 0x0e, 0xc5, 0x66, 0x77, 0x95, 0x7f, 0x49, 0xc7, 0xbc, 0xef, 0xa8, + 0x8a, 0x95, 0xe9, 0x2f, 0xa4, 0x6b, 0x1a, 0x13, 0x4c, 0x7c, 0x3b, 0xff, 0x25, 0xad, 0x39, 0x4c, + 0x08, 0x6e, 0x21, 0x53, 0xac, 0x6a, 0x9d, 0x97, 0x26, 0xb3, 0x1d, 0x44, 0x19, 0x74, 0xda, 0x12, + 0x70, 0x67, 0x40, 0x5a, 0x6d, 0xe8, 0x41, 0x47, 0x72, 0xe7, 0x3f, 0x2a, 0x20, 0x5d, 0xa6, 0x78, + 0xbb, 0x5d, 0x87, 0x0c, 0x6d, 0x09, 0x8f, 0xfa, 0x00, 0xa4, 0x60, 0x87, 0x35, 0x88, 0x67, 0xb3, + 0xbd, 0xac, 0xb2, 0xa0, 0x2c, 0xa7, 0x4a, 0xd9, 0x93, 0xc3, 0x95, 0x69, 0x79, 0xa8, 0x8d, 0x7a, + 0xdd, 0x43, 0x94, 0x3e, 0x63, 0x9e, 0xed, 0xe2, 0x4a, 0x0f, 0xaa, 0x6e, 0x80, 0x71, 0x9f, 0x3b, + 0x1b, 0x5f, 0x50, 0x96, 0x27, 0x8a, 0xba, 0xd1, 0x5f, 0x37, 0xc3, 0x8f, 0x53, 0x4a, 0x1d, 0x7d, + 0xca, 0xc5, 0x3e, 0x5c, 0x1c, 0x14, 0x94, 0x8a, 0xdc, 0xb8, 0xbe, 0xf6, 0xf6, 0xe2, 0xa0, 0xd0, + 0xa3, 0x7c, 0x77, 0x71, 0x50, 0x58, 0xe8, 0xa5, 0xb1, 0xeb, 0x27, 0x12, 0x39, 0x6f, 0x7e, 0x1e, + 0xcc, 0x45, 0x4c, 0x15, 0x44, 0xdb, 0xc4, 0xa5, 0x28, 0xff, 0x55, 0x01, 0x7f, 0x95, 0x29, 0x7e, + 0x42, 0xac, 0xa6, 0xfa, 0x10, 0x64, 0xea, 0xa8, 0x85, 0x30, 0x64, 0xc4, 0xab, 0x42, 0x3f, 0x89, + 0x1b, 0xd3, 0xfb, 0x27, 0xdc, 0x22, 0xed, 0xea, 0x53, 0x90, 0xe9, 0xc2, 0x96, 0x5d, 0xbf, 0x42, + 0x13, 0x17, 0x34, 0x8b, 0x27, 0x87, 0x2b, 0xff, 0x4b, 0x9a, 0x9d, 0x00, 0x13, 0xe1, 0xeb, 0x46, + 0xec, 0xea, 0x3a, 0x18, 0xa3, 0x0c, 0x36, 0x51, 0x36, 0x21, 0x44, 0x9b, 0x37, 0x24, 0x01, 0xef, + 0xa0, 0x50, 0xb1, 0x4d, 0x62, 0xbb, 0x97, 0xf5, 0xf2, 0xb7, 0xac, 0xcf, 0x72, 0xb9, 0xae, 0x67, + 0x95, 0xcf, 0x88, 0xa2, 0xf2, 0xac, 0x43, 0x25, 0xbe, 0x29, 0x20, 0xc5, 0x55, 0x72, 0x5b, 0x7f, + 0x98, 0x16, 0xfb, 0x0a, 0xc8, 0x84, 0x89, 0x07, 0x72, 0xa8, 0x15, 0x90, 0xb6, 0x88, 0xd3, 0x6e, + 0x21, 0x66, 0x13, 0xb7, 0xca, 0x47, 0x47, 0xa4, 0x3f, 0x51, 0xd4, 0x0c, 0x7f, 0xae, 0x8c, 0x60, + 0xae, 0x8c, 0xe7, 0xc1, 0x5c, 0x95, 0x26, 0x79, 0xd0, 0xfd, 0xcf, 0x39, 0xc5, 0x0f, 0x3c, 0xd5, + 0x63, 0xe0, 0x18, 0x75, 0x09, 0xa4, 0x2d, 0x0f, 0x41, 0xc1, 0xd8, 0x40, 0x36, 0x6e, 0x30, 0xa1, + 0x45, 0xa2, 0x32, 0x15, 0x98, 0x1f, 0x09, 0x6b, 0xfe, 0x34, 0x0e, 0x26, 0xcb, 0x14, 0x57, 0x90, + 0x3c, 0x2d, 0xba, 0xad, 0x7a, 0x6c, 0x83, 0x19, 0xea, 0x59, 0xd5, 0x9f, 0xa8, 0xc9, 0xbf, 0xd4, + 0xb3, 0xa2, 0x2e, 0x4e, 0x5b, 0xa7, 0xac, 0x0f, 0x6d, 0x62, 0x64, 0xda, 0x3a, 0x65, 0x3b, 0x03, + 0xab, 0x9d, 0xbc, 0xbd, 0x6a, 0x37, 0xc1, 0xcc, 0x15, 0x65, 0x7f, 0x65, 0xc1, 0xf3, 0xef, 0xe3, + 0x40, 0x2d, 0x53, 0xbc, 0x09, 0x5d, 0x0b, 0xb5, 0xfc, 0x06, 0xb3, 0x5d, 0xfc, 0xbb, 0x0e, 0xd7, + 0xfd, 0x91, 0x87, 0x2b, 0xc9, 0xd3, 0x96, 0x4a, 0xf7, 0xeb, 0xea, 0x64, 0xbf, 0xae, 0x1e, 0x58, + 0x92, 0xff, 0x80, 0x76, 0x5d, 0xa4, 0xa0, 0x2e, 0xc5, 0xef, 0x09, 0x90, 0x28, 0x53, 0xac, 0x36, + 0xc0, 0xdf, 0x57, 0x1e, 0xa1, 0xa5, 0x41, 0x8f, 0x47, 0xe4, 0xaa, 0xd7, 0xcc, 0x11, 0x81, 0x61, + 0x27, 0x6c, 0x81, 0xa4, 0x78, 0x0f, 0x72, 0x43, 0x36, 0x72, 0x80, 0xb6, 0x74, 0x03, 0x20, 0x64, + 0xdc, 0x01, 0xe3, 0xf2, 0x5e, 0x5d, 0x1c, 0x76, 0x18, 0x01, 0xd1, 0xee, 0xdd, 0x08, 0x09, 0x79, + 0x6b, 0x00, 0x5c, 0xba, 0x23, 0xee, 0x0e, 0xd9, 0xd8, 0x83, 0x69, 0x2b, 0x23, 0xc1, 0xc2, 0x18, + 0xaf, 0x40, 0x3a, 0xda, 0xbf, 0x85, 0x21, 0x0c, 0x11, 0xac, 0x56, 0x1c, 0x1d, 0x1b, 0x84, 0xd4, + 0xc6, 0xde, 0xf0, 0x69, 0x2a, 0x3d, 0x3e, 0x3a, 0xd3, 0x95, 0xe3, 0x33, 0x5d, 0xf9, 0x72, 0xa6, + 0x2b, 0xfb, 0xe7, 0x7a, 0xec, 0xf8, 0x5c, 0x8f, 0x9d, 0x9e, 0xeb, 0xb1, 0x17, 0x26, 0xb6, 0x19, + 0x27, 0xb4, 0x88, 0x63, 0xfa, 0xf4, 0x2e, 0x62, 0xaf, 0x89, 0xd7, 0x34, 0xaf, 0xfd, 0x17, 0x60, + 0x7b, 0x6d, 0x44, 0x6b, 0xe3, 0x62, 0x76, 0xd7, 0x7e, 0x04, 0x00, 0x00, 0xff, 0xff, 0x39, 0xd5, + 0x68, 0x21, 0xca, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1057,6 +1066,11 @@ func (m *MsgUnlockResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.CreationHeight != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.CreationHeight)) + i-- + dAtA[i] = 0x10 + } n4, err4 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) if err4 != nil { return 0, err4 @@ -1318,6 +1332,9 @@ func (m *MsgUnlockResponse) Size() (n int) { _ = l l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime) n += 1 + l + sovTx(uint64(l)) + if m.CreationHeight != 0 { + n += 1 + sovTx(uint64(m.CreationHeight)) + } return n } @@ -1963,6 +1980,25 @@ func (m *MsgUnlockResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CreationHeight", wireType) + } + m.CreationHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CreationHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) From 491cc45b776152c41ecb91fe5091dabe2cab30e8 Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 20 Dec 2024 19:51:38 +0800 Subject: [PATCH 04/17] Improve lockup logic, update UnlockingLockup query, fix lockup and query tests --- x/tier/keeper/grpc_query.go | 5 +-- x/tier/keeper/grpc_query_test.go | 23 ++++------- x/tier/keeper/lockup.go | 68 ++++++++++++-------------------- x/tier/keeper/lockup_test.go | 63 ++++++++++++----------------- 4 files changed, 60 insertions(+), 99 deletions(-) diff --git a/x/tier/keeper/grpc_query.go b/x/tier/keeper/grpc_query.go index f4f417c..9045d83 100644 --- a/x/tier/keeper/grpc_query.go +++ b/x/tier/keeper/grpc_query.go @@ -98,7 +98,7 @@ func (q Querier) UnlockingLockup(ctx context.Context, req *types.UnlockingLockup return nil, status.Error(codes.InvalidArgument, "invalid validator address") } - found, amt, unbondTime, unlockTime := q.GetUnlockingLockup(ctx, delAddr, valAddr, req.CreationHeight) + found, amt, unlockTime := q.GetUnlockingLockup(ctx, delAddr, valAddr, req.CreationHeight) if !found { return &types.UnlockingLockupResponse{Lockup: types.Lockup{DelegatorAddress: req.DelegatorAddress, ValidatorAddress: req.ValidatorAddress, Amount: amt}}, nil } @@ -107,8 +107,7 @@ func (q Querier) UnlockingLockup(ctx context.Context, req *types.UnlockingLockup DelegatorAddress: req.DelegatorAddress, ValidatorAddress: req.ValidatorAddress, Amount: amt, - UnbondTime: &unbondTime, - UnlockTime: &unlockTime, + UnlockTime: unlockTime, } return &types.UnlockingLockupResponse{Lockup: *lockup}, nil diff --git a/x/tier/keeper/grpc_query_test.go b/x/tier/keeper/grpc_query_test.go index 9429f8f..07a978d 100644 --- a/x/tier/keeper/grpc_query_test.go +++ b/x/tier/keeper/grpc_query_test.go @@ -88,10 +88,9 @@ func TestUnlockingLockupQuery(t *testing.T) { ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now()) - keeper.SetLockup(ctx, true, delAddr, valAddr, amount, nil) + keeper.SetLockup(ctx, true, delAddr, valAddr, amount) - unbondTime := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) - unlockTime := unbondTime + unlockTime := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) querier := tierkeeper.NewQuerier(keeper) response, err := querier.UnlockingLockup(ctx, &types.UnlockingLockupRequest{ @@ -100,8 +99,7 @@ func TestUnlockingLockupQuery(t *testing.T) { CreationHeight: 1, }) - // use normalized time to confirm SetLockup() logic - unbondTimeUTC := unbondTime.UTC() + // normalize time to confirm SetLockup() logic unlockTimeUTC := unlockTime.UTC() require.NoError(t, err) @@ -110,7 +108,6 @@ func TestUnlockingLockupQuery(t *testing.T) { DelegatorAddress: delAddr.String(), ValidatorAddress: valAddr.String(), Amount: amount, - UnbondTime: &unbondTimeUTC, UnlockTime: &unlockTimeUTC, }, }, response) @@ -129,16 +126,14 @@ func TestUnlockingLockupsQuery(t *testing.T) { require.NoError(t, err) ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now()) - keeper.SetLockup(ctx, true, delAddr, valAddr, amount1, nil) + keeper.SetLockup(ctx, true, delAddr, valAddr, amount1) - unbondTime1 := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) - unlockTime1 := unbondTime1 + unlockTime1 := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) - ctx = ctx.WithBlockHeight(2).WithBlockTime(unbondTime1) - keeper.SetLockup(ctx, true, delAddr, valAddr, amount2, nil) + ctx = ctx.WithBlockHeight(2).WithBlockTime(unlockTime1) + keeper.SetLockup(ctx, true, delAddr, valAddr, amount2) - unbondTime2 := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) - unlockTime2 := unbondTime2 + unlockTime2 := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) querier := tierkeeper.NewQuerier(keeper) response, err := querier.UnlockingLockups(ctx, &types.UnlockingLockupsRequest{ @@ -150,11 +145,9 @@ func TestUnlockingLockupsQuery(t *testing.T) { require.Equal(t, amount1, response.Lockup[0].Amount) require.Equal(t, int64(1), response.Lockup[0].CreationHeight) - require.Equal(t, &unbondTime1, response.Lockup[0].UnbondTime) require.Equal(t, &unlockTime1, response.Lockup[0].UnlockTime) require.Equal(t, amount2, response.Lockup[1].Amount) require.Equal(t, int64(2), response.Lockup[1].CreationHeight) - require.Equal(t, &unbondTime2, response.Lockup[1].UnbondTime) require.Equal(t, &unlockTime2, response.Lockup[1].UnlockTime) } diff --git a/x/tier/keeper/lockup.go b/x/tier/keeper/lockup.go index fe284a0..ba86e17 100644 --- a/x/tier/keeper/lockup.go +++ b/x/tier/keeper/lockup.go @@ -36,14 +36,8 @@ func (k Keeper) GetAllLockups(ctx context.Context) []types.Lockup { // SaveLockup stores lockup or unlocking lockup based on the specified params. // It is used in SubtractUnlockingLockup to override the same record considering existing creationHeight, // as well as for importing lockups from the GenesisState.Lockups as part of the InitGenesis(). -func (k Keeper) SaveLockup(ctx context.Context, unlocking bool, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt math.Int, - creationHeight int64, unbondTime *time.Time, unlockTime *time.Time) { - - var unbTime, unlTime *time.Time - if unbondTime != nil { - utcTime := unbondTime.UTC() - unbTime = &utcTime - } +func (k Keeper) SaveLockup(ctx context.Context, unlocking bool, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt math.Int, creationHeight int64, unlockTime *time.Time) { + var unlTime *time.Time if unlockTime != nil { utcTime := unlockTime.UTC() unlTime = &utcTime @@ -53,7 +47,6 @@ func (k Keeper) SaveLockup(ctx context.Context, unlocking bool, delAddr sdk.AccA ValidatorAddress: valAddr.String(), Amount: amt, CreationHeight: creationHeight, - UnbondTime: unbTime, UnlockTime: unlTime, } @@ -72,20 +65,20 @@ func (k Keeper) SaveLockup(ctx context.Context, unlocking bool, delAddr sdk.AccA // SetLockup stores or updates a lockup in the state based on the key from LockupKey/UnlockingLockupKey. // We normalize lockup times to UTC before saving to the store for consistentcy. -func (k Keeper) SetLockup(ctx context.Context, unlocking bool, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt math.Int, unbondTime *time.Time) (int64, *time.Time, time.Time) { +func (k Keeper) SetLockup(ctx context.Context, unlocking bool, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt math.Int) (int64, *time.Time) { sdkCtx := sdk.UnwrapSDKContext(ctx) params := k.GetParams(ctx) creationHeight := sdkCtx.BlockHeight() - epochDuration := *params.EpochDuration - - unlockTime := sdkCtx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) - // use unbondTime from stakingKeeper.Undelegate() if present, set it to match unlockTime otherwise - var unbTime *time.Time - if unbondTime != nil { - utcTime := unbondTime.UTC() - unbTime = &utcTime + + // use different key and set unlockTime for unlocking lockups + var unlockTime *time.Time + var key []byte + if unlocking { + unlTime := sdkCtx.BlockTime().Add(*params.EpochDuration * time.Duration(params.UnlockingEpochs)) + unlockTime = &unlTime + key = types.UnlockingLockupKey(delAddr, valAddr, creationHeight) } else { - unbTime = &unlockTime + key = types.LockupKey(delAddr, valAddr) } lockup := &types.Lockup{ @@ -93,23 +86,14 @@ func (k Keeper) SetLockup(ctx context.Context, unlocking bool, delAddr sdk.AccAd ValidatorAddress: valAddr.String(), Amount: amt, CreationHeight: creationHeight, - UnbondTime: unbTime, - UnlockTime: &unlockTime, - } - - // use different key for unlocking lockups - var key []byte - if unlocking { - key = types.UnlockingLockupKey(delAddr, valAddr, creationHeight) - } else { - key = types.LockupKey(delAddr, valAddr) + UnlockTime: unlockTime, } b := k.cdc.MustMarshal(lockup) store := k.lockupStore(ctx, unlocking) store.Set(key, b) - return creationHeight, unbTime, unlockTime + return creationHeight, unlockTime } func (k Keeper) GetLockups(ctx context.Context, delAddr sdk.AccAddress) []types.Lockup { @@ -166,20 +150,18 @@ func (k Keeper) HasLockup(ctx context.Context, delAddr sdk.AccAddress, valAddr s } // GetUnlockingLockup returns existing unlocking lockup data if found, otherwise returns defaults. -func (k Keeper) GetUnlockingLockup(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, creationHeight int64) ( - found bool, amt math.Int, unbondTime time.Time, unlockTime time.Time) { - +func (k Keeper) GetUnlockingLockup(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, creationHeight int64) (bool, math.Int, *time.Time) { key := types.UnlockingLockupKey(delAddr, valAddr, creationHeight) store := k.lockupStore(ctx, true) b := store.Get(key) if b == nil { - return false, math.ZeroInt(), time.Time{}, time.Time{} + return false, math.ZeroInt(), nil } var lockup types.Lockup k.cdc.MustUnmarshal(b, &lockup) - return true, lockup.Amount, *lockup.UnbondTime, *lockup.UnlockTime + return true, lockup.Amount, lockup.UnlockTime } // removeLockup removes existing lockup (delAddr/valAddr/). @@ -200,7 +182,7 @@ func (k Keeper) removeUnlockingLockup(ctx context.Context, delAddr sdk.AccAddres func (k Keeper) AddLockup(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt math.Int) { lockedAmt := k.GetLockupAmount(ctx, delAddr, valAddr) amt = amt.Add(lockedAmt) - k.SetLockup(ctx, false, delAddr, valAddr, amt, nil) + k.SetLockup(ctx, false, delAddr, valAddr, amt) } // SubtractLockup subtracts provided amt from the existing delAddr/valAddr lockup. @@ -209,7 +191,7 @@ func (k Keeper) SubtractLockup(ctx context.Context, delAddr sdk.AccAddress, valA // subtracted amt must not be larger than the lockedAmt if amt.GT(lockedAmt) { - return types.ErrInvalidAmount.Wrap("invalid amount") + return types.ErrInvalidAmount.Wrap("subtract lockup") } // remove lockup record completely if subtracted amt is equal to lockedAmt @@ -224,7 +206,7 @@ func (k Keeper) SubtractLockup(ctx context.Context, delAddr sdk.AccAddress, valA return errorsmod.Wrapf(err, "subtract %s from locked amount %s", amt, lockedAmt) } - k.SetLockup(ctx, false, delAddr, valAddr, newAmt, nil) + k.SetLockup(ctx, false, delAddr, valAddr, newAmt) return nil } @@ -232,16 +214,16 @@ func (k Keeper) SubtractLockup(ctx context.Context, delAddr sdk.AccAddress, valA // SubtractUnlockingLockup subtracts provided amt from the existing unlocking lockup (delAddr/valAddr/creationHeight/). func (k Keeper) SubtractUnlockingLockup(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, creationHeight int64, amt math.Int) error { // get full unlocking lockup record because we must pass valid time(s) to SaveLockup - found, lockedAmt, unbondTime, unlockTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) + found, lockedAmt, unlockTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) // return early if not found if !found { - return nil + return types.ErrNotFound.Wrap("subtract unlocking lockup") } // subtracted amt must not be larger than the lockedAmt if amt.GT(lockedAmt) { - return types.ErrInvalidAmount.Wrap("invalid amount") + return types.ErrInvalidAmount.Wrap("subtract unlocking lockup") } // remove lockup record completely if subtracted amt is equal to lockedAmt @@ -253,10 +235,10 @@ func (k Keeper) SubtractUnlockingLockup(ctx context.Context, delAddr sdk.AccAddr // subtract amt from the lockedAmt othwerwise newAmt, err := lockedAmt.SafeSub(amt) if err != nil { - return errorsmod.Wrapf(err, "subtract %s from unlocking lockup locked amount %s", amt, lockedAmt) + return errorsmod.Wrapf(err, "subtract %s from unlocking lockup with amount %s", amt, lockedAmt) } - k.SaveLockup(ctx, true, delAddr, valAddr, newAmt, creationHeight, &unbondTime, &unlockTime) + k.SaveLockup(ctx, true, delAddr, valAddr, newAmt, creationHeight, unlockTime) return nil } diff --git a/x/tier/keeper/lockup_test.go b/x/tier/keeper/lockup_test.go index 589ab46..4825e7f 100644 --- a/x/tier/keeper/lockup_test.go +++ b/x/tier/keeper/lockup_test.go @@ -21,8 +21,6 @@ func TestSetAndGetLockup(t *testing.T) { k, ctx := testutil.SetupKeeper(t) now := time.Now() - params := k.GetParams(ctx) - epochDuration := *params.EpochDuration creationHeight := int64(10) amount := math.NewInt(1000) @@ -33,10 +31,7 @@ func TestSetAndGetLockup(t *testing.T) { ctx = ctx.WithBlockHeight(creationHeight).WithBlockTime(now) - unbondTime := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) - unlockTime := unbondTime - - k.SetLockup(ctx, false, delAddr, valAddr, amount, nil) + k.SetLockup(ctx, false, delAddr, valAddr, amount) store := k.GetAllLockups(ctx) require.Len(t, store, 1) @@ -46,8 +41,7 @@ func TestSetAndGetLockup(t *testing.T) { require.Equal(t, valAddr.String(), lockup.ValidatorAddress) require.Equal(t, amount, lockup.Amount) require.Equal(t, creationHeight, lockup.CreationHeight) - require.Equal(t, unbondTime.UTC(), *lockup.UnbondTime) - require.Equal(t, unlockTime.UTC(), *lockup.UnlockTime) + require.Nil(t, lockup.UnlockTime) } func TestAddLockup(t *testing.T) { @@ -117,8 +111,8 @@ func TestGetAllLockups(t *testing.T) { valAddr2, err := sdk.ValAddressFromBech32("sourcevaloper13fj7t2yptf9k6ad6fv38434znzay4s4pjk0r4f") require.Nil(t, err) - k.SetLockup(ctx, false, delAddr1, valAddr1, amount1, nil) - k.SetLockup(ctx, false, delAddr2, valAddr2, amount2, nil) + k.SetLockup(ctx, false, delAddr1, valAddr1, amount1) + k.SetLockup(ctx, false, delAddr2, valAddr2, amount2) lockups := k.GetAllLockups(ctx) require.Len(t, lockups, 2) @@ -162,7 +156,7 @@ func TestMustIterateUnlockingLockups(t *testing.T) { valAddr, err := sdk.ValAddressFromBech32("sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm") require.Nil(t, err) - k.SetLockup(ctx, true, delAddr, valAddr, amount, nil) + k.SetLockup(ctx, true, delAddr, valAddr, amount) count := 0 k.MustIterateUnlockingLockups(ctx, func(delAddr sdk.AccAddress, valAddr sdk.ValAddress, creationHeight int64, lockup types.Lockup) { @@ -190,17 +184,17 @@ func TestIterateLockups(t *testing.T) { require.Nil(t, err) ctx = ctx.WithBlockHeight(1) - k.SetLockup(ctx, false, delAddr1, valAddr1, math.NewInt(1000), nil) - k.SetLockup(ctx, false, delAddr2, valAddr2, math.NewInt(500), nil) + k.SetLockup(ctx, false, delAddr1, valAddr1, math.NewInt(1000)) + k.SetLockup(ctx, false, delAddr2, valAddr2, math.NewInt(500)) ctx = ctx.WithBlockHeight(2) - k.SetLockup(ctx, true, delAddr1, valAddr1, math.NewInt(200), nil) + k.SetLockup(ctx, true, delAddr1, valAddr1, math.NewInt(200)) ctx = ctx.WithBlockHeight(3) - k.SetLockup(ctx, true, delAddr1, valAddr1, math.NewInt(200), nil) + k.SetLockup(ctx, true, delAddr1, valAddr1, math.NewInt(200)) ctx = ctx.WithBlockHeight(4) - k.SetLockup(ctx, true, delAddr1, valAddr1, math.NewInt(200), nil) + k.SetLockup(ctx, true, delAddr1, valAddr1, math.NewInt(200)) lockupsCount := 0 err = k.IterateLockups(ctx, false, func(delAddr sdk.AccAddress, valAddr sdk.ValAddress, creationHeight int64, lockup types.Lockup) error { @@ -218,7 +212,6 @@ func TestIterateLockups(t *testing.T) { require.NotNil(t, delAddr) require.NotNil(t, valAddr) require.True(t, lockup.Amount.IsPositive()) - require.NotNil(t, lockup.UnbondTime) require.NotNil(t, lockup.UnlockTime) unlockingLockupsCount++ return nil @@ -295,22 +288,19 @@ func TestGetUnlockingLockup(t *testing.T) { ctx = ctx.WithBlockHeight(creationHeight).WithBlockTime(now) - unbondTime := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) - unlockTime := unbondTime + unlockTime := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) - k.SetLockup(ctx, true, delAddr, valAddr, amount, nil) + k.SetLockup(ctx, true, delAddr, valAddr, amount) - found, amt, gotUnbondTime, gotUnlockTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) + found, amt, gotUnlockTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.True(t, found, "unlocking lockup should be found") require.Equal(t, amount, amt, "amount should match the one set") - require.Equal(t, unbondTime, gotUnbondTime, "unbondTime should match the one set") - require.Equal(t, unlockTime, gotUnlockTime, "unlockTime should match the one set") + require.Equal(t, unlockTime, *gotUnlockTime, "unlockTime should match the one set") - found, amt, gotUnbondTime, gotUnlockTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight+1) + found, amt, gotUnlockTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight+1) require.False(t, found, "this unlocking lockup does not exist") require.True(t, amt.IsZero(), "amount should be zero") - require.True(t, gotUnbondTime.IsZero(), "unbond time should be zero") - require.True(t, gotUnlockTime.IsZero(), "unlock time should be zero") + require.Nil(t, gotUnlockTime, "unlock time should be nil") } func TestGetLockup(t *testing.T) { @@ -327,11 +317,7 @@ func TestGetLockup(t *testing.T) { ctx = ctx.WithBlockHeight(creationHeight).WithBlockTime(now) - params := k.GetParams(ctx) - unbondTime := ctx.BlockTime().Add(*params.EpochDuration * time.Duration(params.UnlockingEpochs)) - unlockTime := unbondTime - - k.SetLockup(ctx, false, delAddr, valAddr, amount, nil) + k.SetLockup(ctx, false, delAddr, valAddr, amount) lockup := k.GetLockup(ctx, delAddr, valAddr) @@ -340,8 +326,7 @@ func TestGetLockup(t *testing.T) { require.Equal(t, valAddr.String(), lockup.ValidatorAddress, "validator address should match") require.Equal(t, amount, lockup.Amount, "amount should match") require.Equal(t, creationHeight, lockup.CreationHeight, "creation height should match") - require.Equal(t, unbondTime.UTC(), *lockup.UnbondTime, "unbond time should match") - require.Equal(t, unlockTime.UTC(), *lockup.UnlockTime, "unlock time should match") + require.Nil(t, lockup.UnlockTime, "unlock time should be nil") nonExistentValAddr, err := sdk.ValAddressFromBech32("sourcevaloper13fj7t2yptf9k6ad6fv38434znzay4s4pjk0r4f") require.NoError(t, err) @@ -364,10 +349,10 @@ func TestGetLockups(t *testing.T) { require.NoError(t, err) ctx = ctx.WithBlockHeight(10).WithBlockTime(time.Now()) - k.SetLockup(ctx, false, delAddr, valAddr1, amount1, nil) + k.SetLockup(ctx, false, delAddr, valAddr1, amount1) ctx = ctx.WithBlockHeight(11).WithBlockTime(time.Now().Add(time.Minute)) - k.SetLockup(ctx, false, delAddr, valAddr2, amount2, nil) + k.SetLockup(ctx, false, delAddr, valAddr2, amount2) lockups := k.GetLockups(ctx, delAddr) @@ -396,15 +381,16 @@ func TestSubtractUnlockingLockup(t *testing.T) { require.NoError(t, err) ctx = ctx.WithBlockHeight(creationHeight) - k.SetLockup(ctx, true, delAddr, valAddr, unlockingLockupAmount, nil) + k.SetLockup(ctx, true, delAddr, valAddr, unlockingLockupAmount) // subtract partial amount err = k.SubtractUnlockingLockup(ctx, delAddr, valAddr, creationHeight, cancelUnlockAmount) require.NoError(t, err) - found, lockedAmt, _, _ := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) + found, lockedAmt, unlockTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.True(t, found) require.Equal(t, cancelUnlockAmount, lockedAmt) + require.Equal(t, unlockTime, unlockTime) // TODO: compare to expected unlock time // try to subtract more than the locked amount err = k.SubtractUnlockingLockup(ctx, delAddr, valAddr, creationHeight, cancelUnlockAmount2) @@ -414,7 +400,8 @@ func TestSubtractUnlockingLockup(t *testing.T) { err = k.SubtractUnlockingLockup(ctx, delAddr, valAddr, creationHeight, cancelUnlockAmount) require.NoError(t, err) - found, lockedAmt, _, _ = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) + found, lockedAmt, unlockTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.False(t, found) require.True(t, lockedAmt.IsZero()) + require.Equal(t, unlockTime, unlockTime) // TODO: compare to expected unlock time } From 4a7b2a4def36449a9161616b248bc3cf885c9c99 Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 20 Dec 2024 19:53:00 +0800 Subject: [PATCH 05/17] Refactor Lock(), Unlock(), Redelegate(), and CancelUnlocking(); update corresponding tests --- x/tier/keeper/keeper.go | 193 +++++++----------------------- x/tier/keeper/keeper_mock_test.go | 67 ++--------- x/tier/keeper/keeper_test.go | 88 ++++++-------- 3 files changed, 83 insertions(+), 265 deletions(-) diff --git a/x/tier/keeper/keeper.go b/x/tier/keeper/keeper.go index 69636f5..1e4863e 100644 --- a/x/tier/keeper/keeper.go +++ b/x/tier/keeper/keeper.go @@ -137,33 +137,19 @@ func (k Keeper) CompleteUnlocking(ctx context.Context) error { // Lock locks the stake of a delegator to a validator. func (k Keeper) Lock(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt math.Int) error { - // specified amt must be a positive integer + // Specified amt must be a positive integer if !amt.IsPositive() { - return types.ErrInvalidAmount.Wrap("invalid amount") - } - - sdkCtx := sdk.UnwrapSDKContext(ctx) - modAddr := authtypes.NewModuleAddress(types.ModuleName) - - validator, err := k.stakingKeeper.GetValidator(ctx, valAddr) - if err != nil { - return types.ErrInvalidAddress.Wrapf("validator address %s: %s", valAddr, err) + return types.ErrInvalidAmount.Wrap("lock negative amount") } // Move the stake from delegator to the module stake := sdk.NewCoin(appparams.DefaultBondDenom, amt) coins := sdk.NewCoins(stake) - err = k.bankKeeper.DelegateCoinsFromAccountToModule(ctx, delAddr, types.ModuleName, coins) + err := k.bankKeeper.DelegateCoinsFromAccountToModule(ctx, delAddr, types.ModuleName, coins) if err != nil { return errorsmod.Wrapf(err, "delegate %s from account to module", stake) } - // Delegate the stake to the validator. - _, err = k.stakingKeeper.Delegate(ctx, modAddr, stake.Amount, stakingtypes.Unbonded, validator, true) - if err != nil { - return errorsmod.Wrapf(err, "delegate %s", stake) - } - // Record the lockup k.AddLockup(ctx, delAddr, valAddr, stake.Amount) @@ -174,7 +160,7 @@ func (k Keeper) Lock(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.Va return errorsmod.Wrap(err, "mint credit") } - sdkCtx.EventManager().EmitEvent( + sdk.UnwrapSDKContext(ctx).EventManager().EmitEvent( sdk.NewEvent( types.EventTypeLock, sdk.NewAttribute(stakingtypes.AttributeKeyDelegator, delAddr.String()), @@ -186,95 +172,56 @@ func (k Keeper) Lock(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.Va return nil } -// Unlock initiates the unlocking of stake of a delegator from a validator. -// The stake will be unlocked after the unlocking period has passed. -func (k Keeper) Unlock(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt math.Int) ( - unbondTime time.Time, unlockTime time.Time, creationHeight int64, err error) { - - // specified amt must be a positive integer +// Unlock initiates the unlocking of the specified lockup amount of a delegator from a validator. +// The specified lockup amount will be unlocked in CompleteUnlocking after the unlocking period has passed. +func (k Keeper) Unlock(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt math.Int) (*time.Time, int64, error) { + // Specified amt must be a positive integer if !amt.IsPositive() { - return time.Time{}, time.Time{}, 0, types.ErrInvalidAmount.Wrap("invalid amount") + return nil, 0, types.ErrInvalidAmount.Wrap("unlock negative amount") } - sdkCtx := sdk.UnwrapSDKContext(ctx) - modAddr := authtypes.NewModuleAddress(types.ModuleName) - - validator, err := k.stakingKeeper.GetValidator(ctx, valAddr) + // Subtract the lockup from the validator + err := k.SubtractLockup(ctx, delAddr, valAddr, amt) if err != nil { - return time.Time{}, time.Time{}, 0, types.ErrInvalidAddress.Wrapf("validator address %s: %s", valAddr, err) + return nil, 0, errorsmod.Wrap(err, "subtract lockup") } - err = k.SubtractLockup(ctx, delAddr, valAddr, amt) - if err != nil { - return time.Time{}, time.Time{}, 0, errorsmod.Wrap(err, "subtract lockup") - } + // Create unlocking lockup record at the current block height and set unlockTime + creationHeight, unlockTime := k.SetLockup(ctx, true, delAddr, valAddr, amt) - shares, err := k.stakingKeeper.ValidateUnbondAmount(ctx, modAddr, valAddr, amt) - if err != nil { - return time.Time{}, time.Time{}, 0, errorsmod.Wrap(err, "validate unbond amount") - } - - if shares.IsZero() { - return time.Time{}, time.Time{}, 0, errorsmod.Wrap(stakingtypes.ErrInsufficientShares, "calculated shares are zero") - } - - // adjust token amount to match the actual undelegated tokens - tokenAmount := validator.TokensFromSharesTruncated(shares).TruncateInt() - if tokenAmount.LT(amt) { - amt = tokenAmount - } - - unbondTime, _, err = k.stakingKeeper.Undelegate(ctx, modAddr, valAddr, shares) - if err != nil { - return time.Time{}, time.Time{}, 0, errorsmod.Wrap(err, "undelegate") - } - - creationHeight, _, unlockTime = k.SetLockup(ctx, true, delAddr, valAddr, amt, &unbondTime) - - sdkCtx.EventManager().EmitEvent( + sdk.UnwrapSDKContext(ctx).EventManager().EmitEvent( sdk.NewEvent( types.EventTypeUnlock, sdk.NewAttribute(stakingtypes.AttributeKeyDelegator, delAddr.String()), sdk.NewAttribute(stakingtypes.AttributeKeyValidator, valAddr.String()), sdk.NewAttribute(sdk.AttributeKeyAmount, amt.String()), - sdk.NewAttribute(types.AttributeKeyUnbondTime, unbondTime.String()), sdk.NewAttribute(types.AttributeKeyUnlockTime, unlockTime.String()), sdk.NewAttribute(types.AttributeKeyCreationHeight, fmt.Sprintf("%d", creationHeight)), ), ) - return unbondTime, unlockTime, creationHeight, nil + return unlockTime, creationHeight, nil } -// Redelegate redelegates the stake of a delegator from a source validator to a destination validator. -// The redelegation will be completed after the unbonding period has passed. -func (k Keeper) Redelegate(ctx context.Context, delAddr sdk.AccAddress, srcValAddr, dstValAddr sdk.ValAddress, amt math.Int) ( - completionTime time.Time, err error) { - - // specified amt must be a positive integer +// Redelegate moves the stake of a delegator from a source validator to a destination validator. +// The redelegation will be completed immediately because we keep the stake within the tier module. +func (k Keeper) Redelegate(ctx context.Context, delAddr sdk.AccAddress, srcValAddr, dstValAddr sdk.ValAddress, amt math.Int) (*time.Time, error) { + // Specified amt must be a positive integer if !amt.IsPositive() { - return time.Time{}, types.ErrInvalidAmount.Wrap("invalid amount") + return nil, types.ErrInvalidAmount.Wrap("redelegate negative amount") } - sdkCtx := sdk.UnwrapSDKContext(ctx) - modAddr := authtypes.NewModuleAddress(types.ModuleName) - - err = k.SubtractLockup(ctx, delAddr, srcValAddr, amt) + // Subtract the lockup from the source validator + err := k.SubtractLockup(ctx, delAddr, srcValAddr, amt) if err != nil { - return time.Time{}, errorsmod.Wrap(err, "subtract locked stake from source validator") + return nil, errorsmod.Wrap(err, "subtract lockup from source validator") } + // Add the lockup to the destination validator k.AddLockup(ctx, delAddr, dstValAddr, amt) - shares, err := k.stakingKeeper.ValidateUnbondAmount(ctx, modAddr, srcValAddr, amt) - if err != nil { - return time.Time{}, errorsmod.Wrap(err, "validate unbond amount") - } - - completionTime, err = k.stakingKeeper.BeginRedelegation(ctx, modAddr, srcValAddr, dstValAddr, shares) - if err != nil { - return time.Time{}, errorsmod.Wrap(err, "begin redelegation") - } + sdkCtx := sdk.UnwrapSDKContext(ctx) + completionTime := sdkCtx.BlockTime() sdkCtx.EventManager().EmitEvent( sdk.NewEvent( @@ -287,92 +234,32 @@ func (k Keeper) Redelegate(ctx context.Context, delAddr sdk.AccAddress, srcValAd ), ) - return completionTime, nil + return &completionTime, nil } // CancelUnlocking effectively cancels the pending unlocking lockup partially or in full. -// Reverts the specified amt if a valid value is provided (e.g. amt != nil && 0 < amt < unbondEntry.Balance). -// Otherwise, cancels unlocking lockup record in full (e.g. unbondEntry.Balance). -func (k Keeper) CancelUnlocking(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, creationHeight int64, amt *math.Int) error { - sdkCtx := sdk.UnwrapSDKContext(ctx) - modAddr := authtypes.NewModuleAddress(types.ModuleName) - - validator, err := k.stakingKeeper.GetValidator(ctx, valAddr) - if err != nil { - return types.ErrInvalidAddress.Wrapf("validator address %s: %s", valAddr, err) - } - - ubd, err := k.stakingKeeper.GetUnbondingDelegation(ctx, modAddr, valAddr) - if err != nil { - return errorsmod.Wrapf(err, "unbonding delegation not found for delegator %s and validator %s", modAddr, valAddr) - } - - // find unbonding delegation entry by CreationHeight - // TODO: handle edge case with 2+ messages at the same height - var ( - unbondEntryIndex int64 = -1 - unbondEntry stakingtypes.UnbondingDelegationEntry - ) - - for i, entry := range ubd.Entries { - if entry.CreationHeight == creationHeight && entry.CompletionTime.After(sdkCtx.BlockTime()) { - unbondEntryIndex = int64(i) - unbondEntry = entry - break - } - } - - if unbondEntryIndex == -1 { - return errorsmod.Wrapf( - stakingtypes.ErrNoUnbondingDelegation, - "no valid unbonding entry found for creation height %d", - creationHeight, - ) - } - - // revert the specified amt if set and is positive, otherwise revert the entire UnbondingDelegationEntry - restoreAmount := unbondEntry.Balance - if amt != nil && amt.IsPositive() && amt.LT(unbondEntry.Balance) { - restoreAmount = *amt - } - - _, err = k.stakingKeeper.Delegate(ctx, modAddr, restoreAmount, stakingtypes.Unbonding, validator, false) - if err != nil { - return errorsmod.Wrap(err, "failed to delegate tokens back to validator") - } - - // update or remove the unbonding delegation entry - remainingBalance := unbondEntry.Balance.Sub(restoreAmount) - if remainingBalance.IsZero() { - ubd.RemoveEntry(unbondEntryIndex) - } else { - unbondEntry.Balance = remainingBalance - unbondEntry.InitialBalance = unbondEntry.InitialBalance.Sub(restoreAmount) - ubd.Entries[unbondEntryIndex] = unbondEntry +// Reverts the specified amt if a valid value is provided (e.g. 0 < amt < unlocking lockup amount). +func (k Keeper) CancelUnlocking(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, creationHeight int64, amt math.Int) error { + // Specified amt must be a positive integer + if !amt.IsPositive() { + return types.ErrInvalidAmount.Wrap("cancel unlocking negative amount") } - // update or remove the unbonding delegation in the store - if len(ubd.Entries) == 0 { - err = k.stakingKeeper.RemoveUnbondingDelegation(ctx, ubd) - } else { - err = k.stakingKeeper.SetUnbondingDelegation(ctx, ubd) - } + // Subtract the specified unlocking lockup amt + err := k.SubtractUnlockingLockup(ctx, delAddr, valAddr, creationHeight, amt) if err != nil { - return errorsmod.Wrap(err, "failed to update unbonding delegation") + return errorsmod.Wrap(err, "subtract unlocking lockup") } - // remove unlocking lockup if no amt was specified (e.g. no partial unlocking lockup cancelation) - k.SubtractUnlockingLockup(ctx, delAddr, valAddr, creationHeight, restoreAmount) + // Add the specified amt back to existing lockup (without modifying the unlock/unbond times) + k.AddLockup(ctx, delAddr, valAddr, amt) - // add restoreAmount back to the lockup (without modifying the unlock/unbond times) - k.AddLockup(ctx, delAddr, valAddr, restoreAmount) - - sdkCtx.EventManager().EmitEvent( + sdk.UnwrapSDKContext(ctx).EventManager().EmitEvent( sdk.NewEvent( types.EventTypeCancelUnlocking, sdk.NewAttribute(stakingtypes.AttributeKeyDelegator, delAddr.String()), sdk.NewAttribute(stakingtypes.AttributeKeyValidator, valAddr.String()), - sdk.NewAttribute(sdk.AttributeKeyAmount, restoreAmount.String()), + sdk.NewAttribute(sdk.AttributeKeyAmount, amt.String()), sdk.NewAttribute(types.AttributeKeyCreationHeight, fmt.Sprintf("%d", creationHeight)), ), ) diff --git a/x/tier/keeper/keeper_mock_test.go b/x/tier/keeper/keeper_mock_test.go index 5f246d2..4e8592f 100644 --- a/x/tier/keeper/keeper_mock_test.go +++ b/x/tier/keeper/keeper_mock_test.go @@ -11,7 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/golang/mock/gomock" appparams "github.com/sourcenetwork/sourcehub/app/params" test "github.com/sourcenetwork/sourcehub/testutil" @@ -84,11 +83,6 @@ func (suite *KeeperTestSuite) TestLock() { valAddr, err := sdk.ValAddressFromBech32("sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm") suite.Require().NoError(err) - validator := stakingtypes.Validator{ - OperatorAddress: valAddr.String(), - Status: stakingtypes.Bonded, - } - epochInfo := epochstypes.EpochInfo{ Identifier: types.EpochIdentifier, CurrentEpochStartTime: suite.ctx.BlockTime().Add(-10 * time.Minute), @@ -100,26 +94,18 @@ func (suite *KeeperTestSuite) TestLock() { MintCoins(gomock.Any(), types.ModuleName, creditCoins). Return(nil).Times(1) - suite.bankKeeper.EXPECT(). - SendCoinsFromModuleToAccount(gomock.Any(), moduleName, delAddr, creditCoins). - Return(nil).Times(1) - - suite.stakingKeeper.EXPECT(). - GetValidator(gomock.Any(), valAddr). - Return(validator, nil).Times(1) - suite.bankKeeper.EXPECT(). DelegateCoinsFromAccountToModule(gomock.Any(), delAddr, types.ModuleName, coins). Return(nil).Times(1) - suite.stakingKeeper.EXPECT(). - Delegate(gomock.Any(), gomock.Any(), amount, stakingtypes.Unbonded, validator, true). - Return(math.LegacyNewDecFromInt(amount), nil).Times(1) - suite.epochsKeeper.EXPECT(). GetEpochInfo(gomock.Any(), types.EpochIdentifier). Return(epochInfo).Times(1) + suite.bankKeeper.EXPECT(). + SendCoinsFromModuleToAccount(gomock.Any(), moduleName, delAddr, creditCoins). + Return(nil).Times(1) + // perform lock and verify that lockup is set correctly err = suite.tierKeeper.Lock(suite.ctx, delAddr, valAddr, amount) suite.Require().NoError(err) @@ -145,18 +131,7 @@ func (suite *KeeperTestSuite) TestUnlock() { EpochDuration: &epochDuration, } - validator := stakingtypes.Validator{ - OperatorAddress: valAddr.String(), - Status: stakingtypes.Bonded, - DelegatorShares: math.LegacyNewDec(1_000_000), - Tokens: math.NewInt(2_000_000), - } - // confirm that keeper methods are called as expected - suite.stakingKeeper.EXPECT(). - GetValidator(gomock.Any(), valAddr). - Return(validator, nil).Times(1) - suite.bankKeeper.EXPECT(). GetBalance( gomock.Any(), @@ -166,22 +141,6 @@ func (suite *KeeperTestSuite) TestUnlock() { sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(2000)), ).AnyTimes() - suite.stakingKeeper.EXPECT(). - ValidateUnbondAmount( - gomock.Any(), - authtypes.NewModuleAddress(moduleName), - valAddr, - amount, - ).Return(math.LegacyNewDecFromInt(amount), nil).Times(1) - - suite.stakingKeeper.EXPECT(). - Undelegate( - gomock.Any(), - authtypes.NewModuleAddress(moduleName), - valAddr, - math.LegacyNewDecFromInt(amount), - ).Return(suite.ctx.BlockTime().Add(24*time.Hour), amount, nil).Times(1) - suite.tierKeeper.SetParams(suite.ctx, params) // add a lockup and verify that it exists before trying to unlock @@ -190,21 +149,19 @@ func (suite *KeeperTestSuite) TestUnlock() { suite.Require().Equal(amount, lockedAmt, "expected lockup amount to be set") // perform unlock and verify that unlocking lockup is set correctly - unbondTime, unlockTime, creationHeight, err := suite.tierKeeper.Unlock(suite.ctx, delAddr, valAddr, amount) + unlockTime, creationHeight, err := suite.tierKeeper.Unlock(suite.ctx, delAddr, valAddr, amount) suite.Require().NoError(err) expectedUnlockTime := suite.ctx.BlockTime().Add(time.Duration(params.UnlockingEpochs) * *params.EpochDuration) - suite.Require().Equal(expectedUnlockTime, unlockTime) + suite.Require().NotEmpty(unlockTime) + suite.Require().Equal(expectedUnlockTime, *unlockTime) suite.Require().Equal(suite.ctx.BlockHeight(), creationHeight) - suite.Require().NotEmpty(unbondTime) - suite.Require().True(unbondTime.After(suite.ctx.BlockTime())) } // TestRedelegate is using mock keepers to verify that required function calls are made as expected on Redelegate(). func (suite *KeeperTestSuite) TestRedelegate() { amount := math.NewInt(1000) completionTime := suite.ctx.BlockTime() - shares := math.LegacyNewDecFromInt(amount) delAddr, err := sdk.AccAddressFromBech32("source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et") suite.Require().NoError(err) @@ -216,18 +173,10 @@ func (suite *KeeperTestSuite) TestRedelegate() { // add initial lockup to the source validator suite.tierKeeper.AddLockup(suite.ctx, delAddr, srcValAddr, amount) - suite.stakingKeeper.EXPECT(). - ValidateUnbondAmount(gomock.Any(), authtypes.NewModuleAddress(types.ModuleName), srcValAddr, amount). - Return(shares, nil).Times(1) - - suite.stakingKeeper.EXPECT(). - BeginRedelegation(gomock.Any(), authtypes.NewModuleAddress(types.ModuleName), srcValAddr, dstValAddr, shares). - Return(completionTime, nil).Times(1) - // perform redelegate and verify that lockups were updated successfully resultCompletionTime, err := suite.tierKeeper.Redelegate(suite.ctx, delAddr, srcValAddr, dstValAddr, amount) suite.Require().NoError(err) - suite.Require().Equal(completionTime, resultCompletionTime) + suite.Require().Equal(completionTime, *resultCompletionTime) srcLockedAmt := suite.tierKeeper.GetLockupAmount(suite.ctx, delAddr, srcValAddr) dstLockedAmt := suite.tierKeeper.GetLockupAmount(suite.ctx, delAddr, dstValAddr) diff --git a/x/tier/keeper/keeper_test.go b/x/tier/keeper/keeper_test.go index 9dbb80f..e6da95b 100644 --- a/x/tier/keeper/keeper_test.go +++ b/x/tier/keeper/keeper_test.go @@ -8,7 +8,6 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/sourcenetwork/sourcehub/app" appparams "github.com/sourcenetwork/sourcehub/app/params" @@ -103,12 +102,12 @@ func TestUnlock(t *testing.T) { require.Equal(t, lockAmount, lockedAmt) // unlocking invalid amounts should fail - _, _, _, err = k.Unlock(ctx, delAddr, valAddr, invalidUnlockAmount) + _, _, err = k.Unlock(ctx, delAddr, valAddr, invalidUnlockAmount) require.Error(t, err) - _, _, _, err = k.Unlock(ctx, delAddr, valAddr, math.ZeroInt()) + _, _, err = k.Unlock(ctx, delAddr, valAddr, math.ZeroInt()) require.Error(t, err) - unbondTime, unlockTime, creationHeight, err := k.Unlock(ctx, delAddr, valAddr, unlockAmount) + unlockTime, creationHeight, err := k.Unlock(ctx, delAddr, valAddr, unlockAmount) require.NoError(t, err) // verify that lockup was updated @@ -116,10 +115,9 @@ func TestUnlock(t *testing.T) { require.Equal(t, lockAmount.Sub(unlockAmount), lockedAmt) // check the unlocking entry - found, amt, unbTime, unlTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) + found, amt, unlTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.True(t, found) require.Equal(t, unlockAmount, amt) - require.Equal(t, unbondTime, unbTime) require.Equal(t, unlockTime, unlTime) } @@ -200,19 +198,16 @@ func TestCompleteUnlocking(t *testing.T) { balance := k.GetBankKeeper().GetBalance(ctx, delAddr, appparams.DefaultBondDenom) require.Equal(t, initialDelegatorBalance.Sub(lockAmount), balance.Amount) - adjustedUnlockAmount := unlockAmount.Sub(math.OneInt()) - // unlock tokens - unbondTime, unlockTime, creationHeight, err := k.Unlock(ctx, delAddr, valAddr, unlockAmount) + unlockTime, creationHeight, err := k.Unlock(ctx, delAddr, valAddr, unlockAmount) require.NoError(t, err) lockup = k.GetLockupAmount(ctx, delAddr, valAddr) require.Equal(t, math.ZeroInt(), lockup) - found, amt, unbTime, unlTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) + found, amt, unlTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.True(t, found) - require.Equal(t, adjustedUnlockAmount, amt) - require.Equal(t, unbondTime, unbTime) + require.Equal(t, unlockAmount, amt) require.Equal(t, unlockTime, unlTime) balance = k.GetBankKeeper().GetBalance(ctx, delAddr, appparams.DefaultBondDenom) @@ -221,15 +216,9 @@ func TestCompleteUnlocking(t *testing.T) { // advance block time by 60 days ctx = ctx.WithBlockTime(sdk.UnwrapSDKContext(ctx).BlockTime().Add(60 * 24 * time.Hour)) - // complete unbonding via the staking keeper - modAddr := authtypes.NewModuleAddress(types.ModuleName) - _, err = k.GetStakingKeeper().CompleteUnbonding(ctx, modAddr, valAddr) - require.NoError(t, err) - - found, amt, unbTime, unlTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) + found, amt, unlTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.True(t, found) - require.Equal(t, adjustedUnlockAmount, amt) - require.Equal(t, unbondTime, unbTime) + require.Equal(t, unlockAmount, amt) require.Equal(t, unlockTime, unlTime) // complete unlocking of matured unlocking lockups @@ -238,20 +227,18 @@ func TestCompleteUnlocking(t *testing.T) { // verify that the balance is correct balance = k.GetBankKeeper().GetBalance(ctx, delAddr, appparams.DefaultBondDenom) - require.Equal(t, initialDelegatorBalance.Sub(math.OneInt()), balance.Amount) + require.Equal(t, initialDelegatorBalance, balance.Amount) } // TestCancelUnlocking verifies that the unlocking lockup is removed on keeper.CancelUnlocking(). func TestCancelUnlocking(t *testing.T) { k, ctx := testutil.SetupKeeper(t) - initialAmount := math.NewInt(1000) + initialLockAmount := math.NewInt(1000) + updatedLockAmount := math.NewInt(700) unlockAmount := math.NewInt(500) partialUnlockAmount := math.NewInt(200) - adjustedInitialAmount := initialAmount.Sub(math.OneInt()) // 999 - adjustedUnlockAmount := unlockAmount.Sub(math.OneInt()) // 499 - newLockAmount := initialAmount.Sub(unlockAmount).Add(partialUnlockAmount) - adjustedUnlockAmountFinal := initialAmount.Sub(unlockAmount).Sub(partialUnlockAmount).Sub(math.OneInt()) + remainingUnlockAmount := math.NewInt(300) delAddr, err := sdk.AccAddressFromBech32("source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9") require.NoError(t, err) @@ -267,41 +254,39 @@ func TestCancelUnlocking(t *testing.T) { ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now()) // lock the initialAmount - err = k.Lock(ctx, delAddr, valAddr, initialAmount) + err = k.Lock(ctx, delAddr, valAddr, initialLockAmount) require.NoError(t, err) // verify that lockup was added lockedAmt := k.GetLockupAmount(ctx, delAddr, valAddr) - require.Equal(t, initialAmount, lockedAmt) + require.Equal(t, initialLockAmount, lockedAmt) // unlock the unlockAmount (partial unlock) - unbondTime, unlockTime, creationHeight, err := k.Unlock(ctx, delAddr, valAddr, unlockAmount) + unlockTime, creationHeight, err := k.Unlock(ctx, delAddr, valAddr, unlockAmount) require.NoError(t, err) // verify that lockup was updated lockedAmt = k.GetLockupAmount(ctx, delAddr, valAddr) - require.Equal(t, initialAmount.Sub(unlockAmount), lockedAmt) // 500 + require.Equal(t, initialLockAmount.Sub(unlockAmount), lockedAmt) // 500 // check the unlocking entry based on adjusted unlock amount - found, amt, unbTime, unlTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) + found, amt, unlTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.True(t, found) - require.Equal(t, adjustedUnlockAmount, amt) // 499 - require.Equal(t, unbondTime, unbTime) + require.Equal(t, unlockAmount, amt) // 500 require.Equal(t, unlockTime, unlTime) // partially cancel the unlocking lockup - err = k.CancelUnlocking(ctx, delAddr, valAddr, creationHeight, &partialUnlockAmount) + err = k.CancelUnlocking(ctx, delAddr, valAddr, creationHeight, partialUnlockAmount) require.NoError(t, err) // verify that lockup was updated lockupAmount := k.GetLockupAmount(ctx, delAddr, valAddr) - require.Equal(t, newLockAmount, lockupAmount) // 700 + require.Equal(t, updatedLockAmount, lockupAmount) // 700 // check the unlocking entry - found, amt, unbTime, unlTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) + found, amt, unlTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.Equal(t, true, found) - require.Equal(t, adjustedUnlockAmountFinal, amt) // 299 - require.Equal(t, unbondTime, unbTime) + require.Equal(t, remainingUnlockAmount, amt) // 300 require.Equal(t, unlockTime, unlTime) // advance block height by 1 so that subsequent unlocking lockup is stored separately @@ -310,47 +295,44 @@ func TestCancelUnlocking(t *testing.T) { ctx = ctx.WithBlockHeight(2).WithBlockTime(ctx.BlockTime().Add(time.Minute)) // add new unlocking lockup record at height 2 to fully unlock the remaining adjustedUnlockAmountFinal - unbondTime2, unlockTime2, creationHeight2, err := k.Unlock(ctx, delAddr, valAddr, adjustedUnlockAmountFinal) + unlockTime2, creationHeight2, err := k.Unlock(ctx, delAddr, valAddr, remainingUnlockAmount) require.NoError(t, err) // verify that lockup was updated lockedAmt = k.GetLockupAmount(ctx, delAddr, valAddr) - require.Equal(t, newLockAmount.Sub(adjustedUnlockAmountFinal), lockedAmt) // 401 + require.Equal(t, updatedLockAmount.Sub(remainingUnlockAmount), lockedAmt) // 400 // check the unlocking entry based on adjusted unlock amount - found, amt, unbTime, unlTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight2) + found, amt, unlTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight2) require.True(t, found) - require.Equal(t, adjustedUnlockAmountFinal.Sub(math.OneInt()), amt) // 298 - require.Equal(t, unbondTime2, unbTime) + require.Equal(t, remainingUnlockAmount, amt) // 300 require.Equal(t, unlockTime2, unlTime) // cancel (remove) the unlocking lockup at height 2 - err = k.CancelUnlocking(ctx, delAddr, valAddr, creationHeight2, nil) + err = k.CancelUnlocking(ctx, delAddr, valAddr, creationHeight2, remainingUnlockAmount) require.NoError(t, err) // verify that lockup was updated lockupAmount = k.GetLockupAmount(ctx, delAddr, valAddr) - require.Equal(t, newLockAmount.Sub(math.OneInt()), lockupAmount) // 699 + require.Equal(t, updatedLockAmount, lockupAmount) // 700 // there is still a partial unlocking lockup at height 1 since we did not cancel it's whole amount - found, amt, unbTime, unlTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, 1) + found, amt, unlTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.Equal(t, true, found) - require.Equal(t, adjustedUnlockAmountFinal, amt) // 299 - require.Equal(t, unbondTime, unbTime) + require.Equal(t, remainingUnlockAmount, amt) // 300 require.Equal(t, unlockTime, unlTime) // cancel (remove) the remaining unlocking lockup at height 1 - err = k.CancelUnlocking(ctx, delAddr, valAddr, 1, nil) + err = k.CancelUnlocking(ctx, delAddr, valAddr, creationHeight, remainingUnlockAmount) require.NoError(t, err) // verify that lockup was updated lockupAmount = k.GetLockupAmount(ctx, delAddr, valAddr) - require.Equal(t, adjustedInitialAmount.Sub(math.OneInt()), lockupAmount) // 998 + require.Equal(t, initialLockAmount, lockupAmount) // 100 // confirm that unlocking lockup was removed if we cancel whole amount (e.g. use nil) - found, amt, unbTime, unlTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) + found, amt, unlTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.Equal(t, false, found) require.Equal(t, math.ZeroInt(), amt) - require.Equal(t, time.Time{}, unbTime) - require.Equal(t, time.Time{}, unlTime) + require.Nil(t, unlTime) } From 06bdcaaa392ff8a921c31e80420189f10268f960 Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 20 Dec 2024 19:53:16 +0800 Subject: [PATCH 06/17] Update msg_server and affected tests --- x/tier/keeper/msg_cancel_unlocking_test.go | 28 +++++++++++----------- x/tier/keeper/msg_redelegate_test.go | 11 ++++----- x/tier/keeper/msg_server.go | 9 +++---- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/x/tier/keeper/msg_cancel_unlocking_test.go b/x/tier/keeper/msg_cancel_unlocking_test.go index 615eda5..7b68915 100644 --- a/x/tier/keeper/msg_cancel_unlocking_test.go +++ b/x/tier/keeper/msg_cancel_unlocking_test.go @@ -74,7 +74,7 @@ func TestMsgCancelUnlocking(t *testing.T) { initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), ctx, valAddress, initialValidatorBalance) err = k.Lock(ctx, delAddress, valAddress, validCoin.Amount) require.NoError(t, err) - _, _, _, err = k.Unlock(ctx, delAddress, valAddress, validCoin.Amount) + _, _, err = k.Unlock(ctx, delAddress, valAddress, validCoin.Amount) require.NoError(t, err) return ctx } @@ -105,6 +105,17 @@ func TestMsgCancelUnlocking(t *testing.T) { expErr: true, expErrMsg: "invalid amount", }, + { + name: "excess unlocking amount", + input: &types.MsgCancelUnlocking{ + DelegatorAddress: delAddr, + ValidatorAddress: valAddr, + CreationHeight: 1, + Stake: excessCoin, + }, + expErr: true, + expErrMsg: "invalid amount", + }, { name: "non-existent unlocking", input: &types.MsgCancelUnlocking{ @@ -114,7 +125,7 @@ func TestMsgCancelUnlocking(t *testing.T) { Stake: validCoin, }, expErr: true, - expErrMsg: "no unbonding delegation found", + expErrMsg: "not found", }, { name: "invalid delegator address", @@ -158,18 +169,7 @@ func TestMsgCancelUnlocking(t *testing.T) { Stake: validCoin, }, expErr: false, - expectedAmount: validCoin.Amount.Sub(math.OneInt()), - }, - { - name: "excess unlocking amount", - input: &types.MsgCancelUnlocking{ - DelegatorAddress: delAddr, - ValidatorAddress: valAddr, - CreationHeight: 1, - Stake: excessCoin, - }, - expErr: false, - expectedAmount: validCoin.Amount.Sub(math.OneInt()), + expectedAmount: validCoin.Amount, }, } diff --git a/x/tier/keeper/msg_redelegate_test.go b/x/tier/keeper/msg_redelegate_test.go index e52ff01..c377521 100644 --- a/x/tier/keeper/msg_redelegate_test.go +++ b/x/tier/keeper/msg_redelegate_test.go @@ -43,11 +43,8 @@ func TestMsgRedelegate(t *testing.T) { err = k.Lock(ctx, delAddress, srcValAddress, validCoin.Amount) require.NoError(t, err) - stakingParams, err := k.GetStakingKeeper().(*stakingkeeper.Keeper).GetParams(ctx) - require.NoError(t, err) - - // expectedCompletionTime should match the default staking unbonding time (e.g. 21 days) - expectedCompletionTime := sdkCtx.BlockTime().Add(stakingParams.UnbondingTime) + // expectedCompletionTime should match current block time + expectedCompletionTime := sdkCtx.BlockTime() testCases := []struct { name string @@ -74,7 +71,7 @@ func TestMsgRedelegate(t *testing.T) { Stake: sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(500)), }, expErr: true, - expErrMsg: "subtract locked stake from source validator", + expErrMsg: "subtract lockup from source validator", }, { name: "invalid stake amount (zero)", @@ -110,7 +107,7 @@ func TestMsgRedelegate(t *testing.T) { Stake: validCoin, }, expErr: true, - expErrMsg: "subtract locked stake from source validator", + expErrMsg: "subtract lockup from source validator", }, { name: "source and destination validator are the same", diff --git a/x/tier/keeper/msg_server.go b/x/tier/keeper/msg_server.go index b6aaf8a..f527251 100644 --- a/x/tier/keeper/msg_server.go +++ b/x/tier/keeper/msg_server.go @@ -56,19 +56,20 @@ func (m msgServer) Unlock(ctx context.Context, msg *types.MsgUnlock) (*types.Msg delAddr := sdk.MustAccAddressFromBech32(msg.DelegatorAddress) valAddr := types.MustValAddressFromBech32(msg.ValidatorAddress) - _, unlockTime, _, err := m.Keeper.Unlock(ctx, delAddr, valAddr, msg.Stake.Amount) + unlockTime, creationHeight, err := m.Keeper.Unlock(ctx, delAddr, valAddr, msg.Stake.Amount) if err != nil { return nil, errorsmod.Wrap(err, "undelegate") } - return &types.MsgUnlockResponse{CompletionTime: unlockTime}, nil + return &types.MsgUnlockResponse{CompletionTime: *unlockTime, CreationHeight: creationHeight}, nil } func (m msgServer) CancelUnlocking(ctx context.Context, msg *types.MsgCancelUnlocking) (*types.MsgCancelUnlockingResponse, error) { + // Input validation has been done by ValidateBasic. delAddr := sdk.MustAccAddressFromBech32(msg.DelegatorAddress) valAddr := types.MustValAddressFromBech32(msg.ValidatorAddress) - err := m.Keeper.CancelUnlocking(ctx, delAddr, valAddr, msg.CreationHeight, &msg.Stake.Amount) + err := m.Keeper.CancelUnlocking(ctx, delAddr, valAddr, msg.CreationHeight, msg.Stake.Amount) if err != nil { return nil, errorsmod.Wrap(err, "cancel unlocking") } @@ -87,5 +88,5 @@ func (m msgServer) Redelegate(ctx context.Context, msg *types.MsgRedelegate) (*t return nil, errorsmod.Wrap(err, "redelegate") } - return &types.MsgRedelegateResponse{CompletionTime: completionTime}, nil + return &types.MsgRedelegateResponse{CompletionTime: *completionTime}, nil } From 50e8c29141bd1b3410a6c9e60e7d820a8fdee326 Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 20 Dec 2024 21:06:46 +0800 Subject: [PATCH 07/17] Fix lockup tests --- x/tier/keeper/lockup_test.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/x/tier/keeper/lockup_test.go b/x/tier/keeper/lockup_test.go index 4825e7f..ab26e59 100644 --- a/x/tier/keeper/lockup_test.go +++ b/x/tier/keeper/lockup_test.go @@ -288,19 +288,19 @@ func TestGetUnlockingLockup(t *testing.T) { ctx = ctx.WithBlockHeight(creationHeight).WithBlockTime(now) - unlockTime := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) + expectedUnlockTime := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) k.SetLockup(ctx, true, delAddr, valAddr, amount) - found, amt, gotUnlockTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) + found, amt, unlockTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.True(t, found, "unlocking lockup should be found") require.Equal(t, amount, amt, "amount should match the one set") - require.Equal(t, unlockTime, *gotUnlockTime, "unlockTime should match the one set") + require.Equal(t, expectedUnlockTime, *unlockTime, "unlockTime should match the one set") - found, amt, gotUnlockTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight+1) + found, amt, unlockTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight+1) require.False(t, found, "this unlocking lockup does not exist") require.True(t, amt.IsZero(), "amount should be zero") - require.Nil(t, gotUnlockTime, "unlock time should be nil") + require.Nil(t, unlockTime, "unlock time should be nil") } func TestGetLockup(t *testing.T) { @@ -370,6 +370,8 @@ func TestGetLockups(t *testing.T) { func TestSubtractUnlockingLockup(t *testing.T) { k, ctx := testutil.SetupKeeper(t) + params := k.GetParams(ctx) + epochDuration := *params.EpochDuration unlockingLockupAmount := math.NewInt(1000) cancelUnlockAmount := math.NewInt(500) cancelUnlockAmount2 := math.NewInt(2000) @@ -380,7 +382,10 @@ func TestSubtractUnlockingLockup(t *testing.T) { valAddr, err := sdk.ValAddressFromBech32("sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm") require.NoError(t, err) - ctx = ctx.WithBlockHeight(creationHeight) + ctx = ctx.WithBlockHeight(creationHeight).WithBlockTime(time.Now()) + + expectedUnlockTime := ctx.BlockTime().Add(epochDuration * time.Duration(params.UnlockingEpochs)) + k.SetLockup(ctx, true, delAddr, valAddr, unlockingLockupAmount) // subtract partial amount @@ -390,7 +395,7 @@ func TestSubtractUnlockingLockup(t *testing.T) { found, lockedAmt, unlockTime := k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.True(t, found) require.Equal(t, cancelUnlockAmount, lockedAmt) - require.Equal(t, unlockTime, unlockTime) // TODO: compare to expected unlock time + require.Equal(t, expectedUnlockTime, *unlockTime) // try to subtract more than the locked amount err = k.SubtractUnlockingLockup(ctx, delAddr, valAddr, creationHeight, cancelUnlockAmount2) @@ -403,5 +408,5 @@ func TestSubtractUnlockingLockup(t *testing.T) { found, lockedAmt, unlockTime = k.GetUnlockingLockup(ctx, delAddr, valAddr, creationHeight) require.False(t, found) require.True(t, lockedAmt.IsZero()) - require.Equal(t, unlockTime, unlockTime) // TODO: compare to expected unlock time + require.Nil(t, unlockTime) } From 66678fc1e25c4d6d015c3b63af179d03899cfb94 Mon Sep 17 00:00:00 2001 From: Ivan Date: Sun, 22 Dec 2024 00:41:19 +0800 Subject: [PATCH 08/17] Set epochInfo in the test tier keeper --- testutil/keeper/tier.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/testutil/keeper/tier.go b/testutil/keeper/tier.go index a553a51..62b468b 100644 --- a/testutil/keeper/tier.go +++ b/testutil/keeper/tier.go @@ -150,6 +150,15 @@ func TierKeeper(t testing.TB) (keeper.Keeper, sdk.Context) { log.NewNopLogger(), ) + epochInfo := epochstypes.EpochInfo{ + Identifier: types.EpochIdentifier, + CurrentEpoch: 1, + CurrentEpochStartTime: ctx.BlockTime(), + Duration: time.Hour * 24 * 30, + } + + epochsKeeper.SetEpochInfo(ctx, epochInfo) + k := keeper.NewKeeper( cdc, runtime.NewKVStoreService(storeKey), From a734eb0d2e1ff0f1feb31ab35ea57d18aac9f02c Mon Sep 17 00:00:00 2001 From: Ivan Date: Sun, 22 Dec 2024 00:44:25 +0800 Subject: [PATCH 09/17] Refactor calculations from proratedCredit() into calculateProratedCredit() --- x/tier/keeper/calculate_credit.go | 28 ++++++++++++++++++++++++++++ x/tier/keeper/credit.go | 22 +++++++--------------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/x/tier/keeper/calculate_credit.go b/x/tier/keeper/calculate_credit.go index 0d15fd6..5fe5cfa 100644 --- a/x/tier/keeper/calculate_credit.go +++ b/x/tier/keeper/calculate_credit.go @@ -1,6 +1,8 @@ package keeper import ( + "time" + "cosmossdk.io/math" "github.com/sourcenetwork/sourcehub/x/tier/types" @@ -41,3 +43,29 @@ func calculateCredit(rateList []types.Rate, lockedAmt, lockingAmt math.Int) math return credit } + +func calculateProratedCredit( + rates []types.Rate, + lockedAmt, lockingAmt math.Int, + currentEpochStartTime time.Time, + epochDuration time.Duration, +) math.Int { + // Calculate the reward credits earned on the new lock. + credit := calculateCredit(rates, lockedAmt, lockingAmt) + + // Prorate the credit based on the time elapsed in the current epoch. + sinceCurrentEpoch := time.Since(currentEpochStartTime).Milliseconds() + epochDurationMs := epochDuration.Milliseconds() + + if epochDurationMs == 0 { + return math.ZeroInt() + } + + // This check is required because is possible that sinceCurrentEpoch can be greater than epochDuration + // (e.g. chain paused for longer than the epoch duration or misconfigured epoch duration). + if sinceCurrentEpoch < epochDurationMs { + credit = credit.MulRaw(sinceCurrentEpoch).QuoRaw(epochDurationMs) + } + + return credit +} diff --git a/x/tier/keeper/credit.go b/x/tier/keeper/credit.go index 8a43854..2429006 100644 --- a/x/tier/keeper/credit.go +++ b/x/tier/keeper/credit.go @@ -3,7 +3,6 @@ package keeper import ( "context" "errors" - "time" errorsmod "cosmossdk.io/errors" "cosmossdk.io/math" @@ -39,24 +38,17 @@ func (k Keeper) MintCredit(ctx context.Context, addr sdk.AccAddress, amt math.In // proratedCredit calculates the credits earned on the lockingAmt. func (k Keeper) proratedCredit(ctx context.Context, delAddr sdk.AccAddress, lockingAmt math.Int) math.Int { - // Calculate the reward credits earned on the new lock. rates := k.GetParams(ctx).RewardRates lockedAmt := k.TotalAmountByAddr(ctx, delAddr) - credit := calculateCredit(rates, lockedAmt, lockingAmt) - - // Pro-rate the credit based on the time elapsed in the current epoch. epochInfo := k.epochsKeeper.GetEpochInfo(ctx, types.EpochIdentifier) - sinceCurrentEpoch := time.Since(epochInfo.CurrentEpochStartTime).Milliseconds() - epochDuration := epochInfo.Duration.Milliseconds() - - // TODO: is this check necessary? - // Under what condition can sinceCurrentEpoch be greater than epochDuration? - // What happens if the chain is paused for a long time? - if sinceCurrentEpoch < epochDuration { - credit = credit.MulRaw(sinceCurrentEpoch).QuoRaw(epochDuration) - } - return credit + return calculateProratedCredit( + rates, + lockedAmt, + lockingAmt, + epochInfo.CurrentEpochStartTime, + epochInfo.Duration, + ) } // burnAllCredits burns all the reward credits in the system. From eec241e4aa781644b594dd61c2720ae197f0abb7 Mon Sep 17 00:00:00 2001 From: Ivan Date: Sun, 22 Dec 2024 00:54:01 +0800 Subject: [PATCH 10/17] Add Test_CalculateProratedCredit --- x/tier/keeper/calculate_credit_test.go | 217 +++++++++++++++++++++++++ 1 file changed, 217 insertions(+) diff --git a/x/tier/keeper/calculate_credit_test.go b/x/tier/keeper/calculate_credit_test.go index bf859ad..681311e 100644 --- a/x/tier/keeper/calculate_credit_test.go +++ b/x/tier/keeper/calculate_credit_test.go @@ -4,6 +4,7 @@ import ( "fmt" "reflect" "testing" + "time" "cosmossdk.io/math" @@ -97,3 +98,219 @@ func Test_CalculateCredit(t *testing.T) { }) } } + +func Test_CalculateProratedCredit(t *testing.T) { + tests := []struct { + name string + lockedAmt int64 + lockingAmt int64 + epochStartTime time.Time + epochDuration time.Duration + expectedCredit int64 + }{ + { + /* + Default rate for locking 300+ tokens is 150, but since the reward rates are tiered: + - 0-100 tokens are prorated at a rate of 1.0 (100%). + - 100-200 tokens are prorated at a rate of 1.1 (110%). + - 200-300 tokens are prorated at a rate of 1.2 (120%). + - 300+ tokens are prorated at a rate of 1.5 (150%). + For a locking amount of 10,000,000, the total is 14,999,550 + 100 + 110 + 120 = 14,999,880. + After 2 minutes in a 5-minute epoch, the expected credit amount should be: + 14,999,880 * 120,000 ms / 300,000 ms = 14,999,880 * 0.4 = 5,999,952. + */ + name: "Large amount in the middle of the epoch", + lockedAmt: 0, + lockingAmt: 10_000_000, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 5_999_952, + }, + { + name: "Large amount at the first second of the epoch", + lockedAmt: 0, + lockingAmt: 10_000_000, + epochStartTime: time.Now().UTC().Add(-5 * time.Minute).Add(1 * time.Second), + epochDuration: time.Minute * 5, + expectedCredit: 14_949_880, + }, + { + name: "Large amount at the last second of the epoch", + lockedAmt: 0, + lockingAmt: 10_000_000, + epochStartTime: time.Now().UTC().Add(-1 * time.Second), + epochDuration: time.Minute * 5, + expectedCredit: 49_999, + }, + { + name: "At the beginning of an epoch", + lockedAmt: 0, + lockingAmt: 0, + epochStartTime: time.Now().UTC(), + epochDuration: time.Minute * 5, + expectedCredit: 0, + }, + { + name: "In the middle of an epoch", + lockedAmt: 0, + lockingAmt: 100, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 40, + }, + { + name: "At the end of an epoch", + lockedAmt: 0, + lockingAmt: 100, + epochStartTime: time.Now().UTC().Add(-5 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 100, + }, + { + name: "Negative locking amount", + lockedAmt: 0, + lockingAmt: -100, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 0, + }, + { + name: "Zero locking amount", + lockedAmt: 0, + lockingAmt: 0, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 0, + }, + { + name: "Locking amount with 1.1 rate", + lockedAmt: 0, + lockingAmt: 100, + epochStartTime: time.Now().UTC().Add(-4 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 80, + }, + { + name: "Locking amount with 1.2 rate", + lockedAmt: 0, + lockingAmt: 200, + epochStartTime: time.Now().UTC().Add(-3 * time.Minute), + epochDuration: time.Minute * 6, + expectedCredit: 105, + }, + { + name: "Locking amount with 1.5 rate", + lockedAmt: 0, + lockingAmt: 300, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 132, + }, + { + name: "Zero epoch duration", + lockedAmt: 0, + lockingAmt: 100, + epochStartTime: time.Now().UTC(), + epochDuration: 0, + expectedCredit: 0, + }, + { + name: "Short epoch duration", + lockedAmt: 0, + lockingAmt: 100, + epochStartTime: time.Now().UTC().Add(-30 * time.Second), + epochDuration: time.Minute * 1, + expectedCredit: 50, + }, + { + name: "Long epoch duration", + lockedAmt: 0, + lockingAmt: 100, + epochStartTime: time.Now().UTC().Add(-12 * 30 * time.Hour), + epochDuration: time.Hour * 24 * 30, + expectedCredit: 50, + }, + { + name: "Epoch duration less than sinceCurrentEpoch", + lockedAmt: 0, + lockingAmt: 100, + epochStartTime: time.Now().UTC().Add(-10 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 100, + }, + { + name: "Small locking amount and short epoch", + lockedAmt: 0, + lockingAmt: 9, + epochStartTime: time.Now().UTC().Add(-3 * time.Second), + epochDuration: time.Second * 10, + expectedCredit: 2, + }, + { + name: "Small locking amount and long epoch", + lockedAmt: 0, + lockingAmt: 11, + epochStartTime: time.Now().UTC().Add(-10 * time.Minute), + epochDuration: time.Hour * 2, + expectedCredit: 0, + }, + { + name: "Large locking amount and short epoch", + lockedAmt: 0, + lockingAmt: 1_000_003, + epochStartTime: time.Now().UTC().Add(-1 * time.Second), + epochDuration: time.Second * 5, + expectedCredit: 299_976, + }, + { + name: "Large locking amount and long epoch", + lockedAmt: 0, + lockingAmt: 1_000_003, + epochStartTime: time.Now().UTC().Add(-1 * time.Hour), + epochDuration: time.Hour * 5, + expectedCredit: 299_976, + }, + { + name: "Locking amount causing uneven division", + lockedAmt: 0, + lockingAmt: 7, + epochStartTime: time.Now().UTC().Add(-10 * time.Second), + epochDuration: time.Second * 33, + expectedCredit: 2, + }, + { + name: "Epoch duration causing uneven division", + lockedAmt: 0, + lockingAmt: 1234, + epochStartTime: time.Now().UTC().Add(-4 * time.Second), + epochDuration: time.Second * 9, + expectedCredit: 769, + }, + } + + rates := []types.Rate{ + {Amount: math.NewInt(300), Rate: 150}, + {Amount: math.NewInt(200), Rate: 120}, + {Amount: math.NewInt(100), Rate: 110}, + {Amount: math.NewInt(0), Rate: 100}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + lockedAmt := math.NewInt(tt.lockedAmt) + lockingAmt := math.NewInt(tt.lockingAmt) + + credit := calculateProratedCredit( + rates, + lockedAmt, + lockingAmt, + tt.epochStartTime, + tt.epochDuration, + ) + + if !credit.Equal(math.NewInt(tt.expectedCredit)) { + t.Errorf("calculateProratedCredit() = %v, expected %v", credit, tt.expectedCredit) + } + }) + } +} From 13ca3fec5c935a55b09d9d92d51c561629251c3e Mon Sep 17 00:00:00 2001 From: Ivan Date: Mon, 23 Dec 2024 21:17:46 +0800 Subject: [PATCH 11/17] Add more test cases --- x/tier/keeper/calculate_credit_test.go | 64 ++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/x/tier/keeper/calculate_credit_test.go b/x/tier/keeper/calculate_credit_test.go index 681311e..46f9394 100644 --- a/x/tier/keeper/calculate_credit_test.go +++ b/x/tier/keeper/calculate_credit_test.go @@ -286,6 +286,70 @@ func Test_CalculateProratedCredit(t *testing.T) { epochDuration: time.Second * 9, expectedCredit: 769, }, + { + name: "Locking amount with 1.0 rate and previously locked amount", + lockedAmt: 40, + lockingAmt: 40, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 16, // 40 * 1.0 * 2/5 + }, + { + name: "Locking amount with 1.1 rate and previously locked amount", + lockedAmt: 100, + lockingAmt: 100, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 44, // 100 * 1.1 * 2/5 + }, + { + name: "Locking amount with 1.5 rate and previously locked amount", + lockedAmt: 300, + lockingAmt: 300, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 180, // 300 * 1.5 * 2/5 + }, + { + name: "Locking amount with 1.2 + 1.1 rate and previously locked amount", + lockedAmt: 150, + lockingAmt: 150, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 70, // ((100 * 1.2) + (50 * 1.1)) * 2/5 + }, + { + name: "Locking amount with 1.5 + 1.2 rate and previously locked amount", + lockedAmt: 200, + lockingAmt: 200, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 108, // ((100 * 1.5) + (100 * 1.2)) * 2/5 + }, + { + name: "Locking amount with 1.5 + 1.2 + 1.1 + 1.0 rate and previously locked amount", + lockedAmt: 50, + lockingAmt: 350, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 172, // ((100 * 1.5) + (100 * 1.2) + (100 * 1.1) + (50 * 1.0)) * 2/5 + }, + { + name: "Locking small amount with large previously locked amount", + lockedAmt: 1_000_000, + lockingAmt: 100, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 60, // 100 * 1.5 * 2/5 + }, + { + name: "Locking large amount with large previously locked amount", + lockedAmt: 1_000_000, + lockingAmt: 10_000_000, + epochStartTime: time.Now().UTC().Add(-2 * time.Minute), + epochDuration: time.Minute * 5, + expectedCredit: 6_000_000, // 10,000,000 * 1.5 * 2/5 + }, } rates := []types.Rate{ From 6d375ff65745602ff9a4ae0556fb12f57dccbf23 Mon Sep 17 00:00:00 2001 From: Ivan Date: Mon, 6 Jan 2025 08:39:10 +0800 Subject: [PATCH 12/17] Add Test_BurnAllCredits and Test_ResetAllCredits --- x/tier/keeper/credit.go | 8 +- x/tier/keeper/credit_test.go | 201 ++++++++++++++++++++++++++++++++++- x/tier/keeper/epoch_hook.go | 4 +- 3 files changed, 206 insertions(+), 7 deletions(-) diff --git a/x/tier/keeper/credit.go b/x/tier/keeper/credit.go index 2429006..4e87949 100644 --- a/x/tier/keeper/credit.go +++ b/x/tier/keeper/credit.go @@ -51,9 +51,9 @@ func (k Keeper) proratedCredit(ctx context.Context, delAddr sdk.AccAddress, lock ) } -// burnAllCredits burns all the reward credits in the system. +// BurnAllCredits burns all the reward credits in the system. // It is called at the end of each epoch. -func (k Keeper) burnAllCredits(ctx context.Context) error { +func (k Keeper) BurnAllCredits(ctx context.Context) error { // Note that we can't simply iterate through the lockup records because credits // are transferrable and can be stored in accounts that are not tracked by lockups. // Instead, we iterate through all the balances to find and burn the credits. @@ -86,8 +86,8 @@ func (k Keeper) burnAllCredits(ctx context.Context) error { return err } -// resetAllCredits resets all the credits in the system. -func (k Keeper) resetAllCredits(ctx context.Context) error { +// ResetAllCredits resets all the credits in the system. +func (k Keeper) ResetAllCredits(ctx context.Context) error { // Reward to a delegator is calculated based on the total locked amount // to all validators. Since each lockup entry only records locked amount // for a single validator, we need to iterate through all the lockups to diff --git a/x/tier/keeper/credit_test.go b/x/tier/keeper/credit_test.go index cb40d2a..8a7445b 100644 --- a/x/tier/keeper/credit_test.go +++ b/x/tier/keeper/credit_test.go @@ -4,9 +4,12 @@ import ( "testing" "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + "github.com/sourcenetwork/sourcehub/app/params" testutil "github.com/sourcenetwork/sourcehub/testutil" + "github.com/sourcenetwork/sourcehub/x/tier/types" ) func Test_MintCredit(t *testing.T) { @@ -53,3 +56,199 @@ func Test_MintCredit(t *testing.T) { }) } } + +func Test_BurnAllCredits(t *testing.T) { + tests := []struct { + name string + creditBalances map[string]int64 + openBalances map[string]int64 + wantErr bool + }{ + { + name: "Burn all credits successfully (single address)", + creditBalances: map[string]int64{"source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": 100}, + openBalances: map[string]int64{}, + wantErr: false, + }, + { + name: "No addresses have credits", + creditBalances: map[string]int64{}, + openBalances: map[string]int64{}, + wantErr: false, + }, + { + name: "Multiple addresses with credits", + creditBalances: map[string]int64{ + "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": 50, + "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9": 150, + }, + openBalances: map[string]int64{}, + wantErr: false, + }, + { + name: "Burn credits when addresses also hold $OPEN", + creditBalances: map[string]int64{ + "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": 80, + "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9": 200, + }, + openBalances: map[string]int64{ + "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": 9999, + "source1n34fvpteuanu2nx2a4hql4jvcrcnal3gsrjppy": 888, + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + k, ctx := testutil.SetupKeeper(t) + + // Mint and distribute credits + for addrStr, balance := range tt.creditBalances { + addr := sdk.MustAccAddressFromBech32(addrStr) + coins := sdk.NewCoins(sdk.NewCoin(params.CreditDenom, math.NewInt(balance))) + err := k.GetBankKeeper().MintCoins(ctx, types.ModuleName, coins) + require.NoError(t, err, "MintCoins failed") + err = k.GetBankKeeper().SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, coins) + require.NoError(t, err, "SendCoinsFromModuleToAccount failed") + } + + // Mint and distribute $OPEN + for addrStr, balance := range tt.openBalances { + addr := sdk.MustAccAddressFromBech32(addrStr) + coins := sdk.NewCoins(sdk.NewCoin(params.OpenDenom, math.NewInt(balance))) + err := k.GetBankKeeper().MintCoins(ctx, types.ModuleName, coins) + require.NoError(t, err, "MintCoins $OPEN failed") + err = k.GetBankKeeper().SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, coins) + require.NoError(t, err, "SendCoinsFromModuleToAccount $OPEN failed") + } + + // Burn all credits + err := k.BurnAllCredits(ctx) + if (err != nil) != tt.wantErr { + t.Errorf("BurnAllCredits() error = %v, wantErr %v", err, tt.wantErr) + } + + // Verify that all credit balances are zero + for addrStr, origBalance := range tt.creditBalances { + addr := sdk.MustAccAddressFromBech32(addrStr) + bal := k.GetBankKeeper().GetBalance(ctx, addr, params.CreditDenom) + if !bal.IsZero() { + t.Errorf("Expected all credit burned for %s, original = %d, still found = %s", + addrStr, origBalance, bal.Amount) + } + } + + // Verify that $OPEN balances are unchanged + for addrStr, expectedBalance := range tt.openBalances { + addr := sdk.MustAccAddressFromBech32(addrStr) + bal := k.GetBankKeeper().GetBalance(ctx, addr, params.OpenDenom) + if !bal.Amount.Equal(math.NewInt(expectedBalance)) { + t.Errorf("Non-credit denom incorrectly burned. For %s, got = %d, expected = %d", + addrStr, bal.Amount.Int64(), expectedBalance) + } + } + }) + } +} + +func Test_ResetAllCredits(t *testing.T) { + tests := []struct { + name string + lockups map[string][]int64 + expectedCredit map[string]int64 + wantErr bool + }{ + { + name: "Reset all credits successfully (single address, single lockup)", + lockups: map[string][]int64{ + "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": {100}, + }, + expectedCredit: map[string]int64{ + "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": 100, + }, + wantErr: false, + }, + { + name: "No lockups", + lockups: map[string][]int64{}, + expectedCredit: map[string]int64{}, + wantErr: false, + }, + { + name: "Multiple addresses with multiple lockups", + lockups: map[string][]int64{ + "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": {50, 50}, + "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9": {10, 20}, + "source1n34fvpteuanu2nx2a4hql4jvcrcnal3gsrjppy": {10, 10, 30}, + }, + expectedCredit: map[string]int64{ + "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": 100, // 50 + 50 + "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9": 30, // 10 + 20 + "source1n34fvpteuanu2nx2a4hql4jvcrcnal3gsrjppy": 50, // 10 + 10 + 30 + }, + wantErr: false, + }, + { + name: "Multiple addresses with multiple lockups (with reward rates)", + lockups: map[string][]int64{ + "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": {100, 100}, + "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9": {100, 200, 300}, + "source1n34fvpteuanu2nx2a4hql4jvcrcnal3gsrjppy": {500, 1000}, + }, + expectedCredit: map[string]int64{ + "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": 210, // 100 + 100 + (10 rewards) + "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9": 780, // 100 + 200 + 300 + (180 rewards) + "source1n34fvpteuanu2nx2a4hql4jvcrcnal3gsrjppy": 2130, // 500 + 1000 + (630 rewards) + }, + wantErr: false, + }, + } + + valAddr, err := sdk.ValAddressFromBech32("sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm") + require.NoError(t, err) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + k, ctx := testutil.SetupKeeper(t) + + // Set default params + err := k.SetParams(ctx, types.DefaultParams()) + require.NoError(t, err) + + // Add lockups + for addrStr, lockupAmounts := range tt.lockups { + addr := sdk.MustAccAddressFromBech32(addrStr) + for _, amt := range lockupAmounts { + k.AddLockup(ctx, addr, valAddr, math.NewInt(amt)) + } + } + + // Reset all credits + err = k.ResetAllCredits(ctx) + if (err != nil) != tt.wantErr { + t.Errorf("ResetAllCredits() error = %v, wantErr %v", err, tt.wantErr) + } + + // Check expected credits + for addrStr, expected := range tt.expectedCredit { + addr := sdk.MustAccAddressFromBech32(addrStr) + bal := k.GetBankKeeper().GetBalance(ctx, addr, params.CreditDenom) + if !bal.Amount.Equal(math.NewInt(expected)) { + t.Errorf("Incorrect credit balance for %s, got = %v, expected = %v", addrStr, bal.Amount, expected) + } + } + + // Addresses not in expectedCredit should have zero credit + for addrStr := range tt.lockups { + if _, ok := tt.expectedCredit[addrStr]; !ok { + addr := sdk.MustAccAddressFromBech32(addrStr) + bal := k.GetBankKeeper().GetBalance(ctx, addr, params.CreditDenom) + if !bal.IsZero() { + t.Errorf("Address %s was not in expectedCredit, but has credit = %v", addrStr, bal.Amount) + } + } + } + }) + } +} diff --git a/x/tier/keeper/epoch_hook.go b/x/tier/keeper/epoch_hook.go index 84ad026..6cdfa17 100644 --- a/x/tier/keeper/epoch_hook.go +++ b/x/tier/keeper/epoch_hook.go @@ -32,12 +32,12 @@ func (h EpochHooks) BeforeEpochStart(ctx context.Context, epochIdentifier string h.keeper.Logger().Info("resetting all credits", "epochID", epochIdentifier, "epochNumber", epochNumber) - err := h.keeper.burnAllCredits(ctx) + err := h.keeper.BurnAllCredits(ctx) if err != nil { return errorsmod.Wrapf(err, "burn all credits") } - err = h.keeper.resetAllCredits(ctx) + err = h.keeper.ResetAllCredits(ctx) if err != nil { return errorsmod.Wrapf(err, "reset all credits") } From ef4dbd067e4f2d1315363d6d6b2ebd47d86ddf52 Mon Sep 17 00:00:00 2001 From: Ivan Date: Mon, 6 Jan 2025 13:39:27 +0800 Subject: [PATCH 13/17] Update Test_ResetAllCredits --- x/tier/keeper/credit_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/x/tier/keeper/credit_test.go b/x/tier/keeper/credit_test.go index 8a7445b..2fc4259 100644 --- a/x/tier/keeper/credit_test.go +++ b/x/tier/keeper/credit_test.go @@ -181,6 +181,7 @@ func Test_ResetAllCredits(t *testing.T) { "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": {50, 50}, "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9": {10, 20}, "source1n34fvpteuanu2nx2a4hql4jvcrcnal3gsrjppy": {10, 10, 30}, + "source1cy0p47z24ejzvq55pu3lesxwf73xnrnd0lyxme": {}, }, expectedCredit: map[string]int64{ "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": 100, // 50 + 50 @@ -195,6 +196,7 @@ func Test_ResetAllCredits(t *testing.T) { "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": {100, 100}, "source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9": {100, 200, 300}, "source1n34fvpteuanu2nx2a4hql4jvcrcnal3gsrjppy": {500, 1000}, + "source1cy0p47z24ejzvq55pu3lesxwf73xnrnd0lyxme": {}, }, expectedCredit: map[string]int64{ "source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et": 210, // 100 + 100 + (10 rewards) @@ -235,7 +237,8 @@ func Test_ResetAllCredits(t *testing.T) { addr := sdk.MustAccAddressFromBech32(addrStr) bal := k.GetBankKeeper().GetBalance(ctx, addr, params.CreditDenom) if !bal.Amount.Equal(math.NewInt(expected)) { - t.Errorf("Incorrect credit balance for %s, got = %v, expected = %v", addrStr, bal.Amount, expected) + t.Errorf("Incorrect credit balance for %s, got = %v, expected = %v", + addrStr, bal.Amount, expected) } } @@ -245,7 +248,8 @@ func Test_ResetAllCredits(t *testing.T) { addr := sdk.MustAccAddressFromBech32(addrStr) bal := k.GetBankKeeper().GetBalance(ctx, addr, params.CreditDenom) if !bal.IsZero() { - t.Errorf("Address %s was not in expectedCredit, but has credit = %v", addrStr, bal.Amount) + t.Errorf("Address %s was not in expectedCredit, but has credit = %v", + addrStr, bal.Amount) } } } From dd7e39357241025ced15f1f69618cb922ce9a224 Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 7 Jan 2025 14:44:29 +0800 Subject: [PATCH 14/17] Improve/refactor tests to keep mintCredit, burnAllCredits, and resetAllCredits package-private --- testutil/utils.go | 7 -- x/tier/keeper/credit.go | 14 +-- x/tier/keeper/credit_test.go | 21 ++-- x/tier/keeper/epoch_hook.go | 4 +- x/tier/keeper/keeper.go | 2 +- x/tier/keeper/keeper_common_test.go | 169 ++++++++++++++++++++++++++++ x/tier/keeper/keeper_test.go | 46 ++++---- x/tier/keeper/lockup_test.go | 33 +++--- x/tier/keeper/main_test.go | 13 +++ 9 files changed, 237 insertions(+), 72 deletions(-) create mode 100644 x/tier/keeper/keeper_common_test.go create mode 100644 x/tier/keeper/main_test.go diff --git a/testutil/utils.go b/testutil/utils.go index c4d3983..f5fce7d 100644 --- a/testutil/utils.go +++ b/testutil/utils.go @@ -17,8 +17,6 @@ import ( stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/gogoproto/proto" - keepertest "github.com/sourcenetwork/sourcehub/testutil/keeper" - tierkeeper "github.com/sourcenetwork/sourcehub/x/tier/keeper" "github.com/stretchr/testify/require" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -95,8 +93,3 @@ func CreateTestEncodingConfig() EncodingConfig { Amino: codec.NewLegacyAmino(), } } - -func SetupKeeper(t *testing.T) (*tierkeeper.Keeper, sdk.Context) { - k, ctx := keepertest.TierKeeper(t) - return &k, ctx -} diff --git a/x/tier/keeper/credit.go b/x/tier/keeper/credit.go index 4e87949..cb78f4b 100644 --- a/x/tier/keeper/credit.go +++ b/x/tier/keeper/credit.go @@ -12,8 +12,8 @@ import ( "github.com/sourcenetwork/sourcehub/x/tier/types" ) -// MintCredit mints a coin and sends it to the specified address. -func (k Keeper) MintCredit(ctx context.Context, addr sdk.AccAddress, amt math.Int) error { +// mintCredit mints a coin and sends it to the specified address. +func (k Keeper) mintCredit(ctx context.Context, addr sdk.AccAddress, amt math.Int) error { if _, err := sdk.AccAddressFromBech32(addr.String()); err != nil { return errorsmod.Wrap(err, "invalid address") } @@ -51,9 +51,9 @@ func (k Keeper) proratedCredit(ctx context.Context, delAddr sdk.AccAddress, lock ) } -// BurnAllCredits burns all the reward credits in the system. +// burnAllCredits burns all the reward credits in the system. // It is called at the end of each epoch. -func (k Keeper) BurnAllCredits(ctx context.Context) error { +func (k Keeper) burnAllCredits(ctx context.Context) error { // Note that we can't simply iterate through the lockup records because credits // are transferrable and can be stored in accounts that are not tracked by lockups. // Instead, we iterate through all the balances to find and burn the credits. @@ -86,8 +86,8 @@ func (k Keeper) BurnAllCredits(ctx context.Context) error { return err } -// ResetAllCredits resets all the credits in the system. -func (k Keeper) ResetAllCredits(ctx context.Context) error { +// resetAllCredits resets all the credits in the system. +func (k Keeper) resetAllCredits(ctx context.Context) error { // Reward to a delegator is calculated based on the total locked amount // to all validators. Since each lockup entry only records locked amount // for a single validator, we need to iterate through all the lockups to @@ -109,7 +109,7 @@ func (k Keeper) ResetAllCredits(ctx context.Context) error { for delStrAddr, amt := range lockedAmts { delAddr := sdk.MustAccAddressFromBech32(delStrAddr) credit := calculateCredit(rates, math.ZeroInt(), amt) - err := k.MintCredit(ctx, delAddr, credit) + err := k.mintCredit(ctx, delAddr, credit) if err != nil { return errorsmod.Wrapf(err, "mint %s to %s", credit, delAddr) } diff --git a/x/tier/keeper/credit_test.go b/x/tier/keeper/credit_test.go index 2fc4259..fd4618d 100644 --- a/x/tier/keeper/credit_test.go +++ b/x/tier/keeper/credit_test.go @@ -1,4 +1,4 @@ -package keeper_test +package keeper import ( "testing" @@ -8,7 +8,6 @@ import ( "github.com/stretchr/testify/require" "github.com/sourcenetwork/sourcehub/app/params" - testutil "github.com/sourcenetwork/sourcehub/testutil" "github.com/sourcenetwork/sourcehub/x/tier/types" ) @@ -47,11 +46,11 @@ func Test_MintCredit(t *testing.T) { } amt := math.NewInt(tt.amt) - k, ctx := testutil.SetupKeeper(t) + k, ctx := setupKeeper(t) - err := k.MintCredit(ctx, addr, amt) + err := k.mintCredit(ctx, addr, amt) if (err != nil) != tt.wantErr { - t.Errorf("MintCredit() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("mintCredit() error = %v, wantErr %v", err, tt.wantErr) } }) } @@ -101,7 +100,7 @@ func Test_BurnAllCredits(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := setupKeeper(t) // Mint and distribute credits for addrStr, balance := range tt.creditBalances { @@ -124,9 +123,9 @@ func Test_BurnAllCredits(t *testing.T) { } // Burn all credits - err := k.BurnAllCredits(ctx) + err := k.burnAllCredits(ctx) if (err != nil) != tt.wantErr { - t.Errorf("BurnAllCredits() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("burnAllCredits() error = %v, wantErr %v", err, tt.wantErr) } // Verify that all credit balances are zero @@ -212,7 +211,7 @@ func Test_ResetAllCredits(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := setupKeeper(t) // Set default params err := k.SetParams(ctx, types.DefaultParams()) @@ -227,9 +226,9 @@ func Test_ResetAllCredits(t *testing.T) { } // Reset all credits - err = k.ResetAllCredits(ctx) + err = k.resetAllCredits(ctx) if (err != nil) != tt.wantErr { - t.Errorf("ResetAllCredits() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("resetAllCredits() error = %v, wantErr %v", err, tt.wantErr) } // Check expected credits diff --git a/x/tier/keeper/epoch_hook.go b/x/tier/keeper/epoch_hook.go index 6cdfa17..84ad026 100644 --- a/x/tier/keeper/epoch_hook.go +++ b/x/tier/keeper/epoch_hook.go @@ -32,12 +32,12 @@ func (h EpochHooks) BeforeEpochStart(ctx context.Context, epochIdentifier string h.keeper.Logger().Info("resetting all credits", "epochID", epochIdentifier, "epochNumber", epochNumber) - err := h.keeper.BurnAllCredits(ctx) + err := h.keeper.burnAllCredits(ctx) if err != nil { return errorsmod.Wrapf(err, "burn all credits") } - err = h.keeper.ResetAllCredits(ctx) + err = h.keeper.resetAllCredits(ctx) if err != nil { return errorsmod.Wrapf(err, "reset all credits") } diff --git a/x/tier/keeper/keeper.go b/x/tier/keeper/keeper.go index 1e4863e..9599172 100644 --- a/x/tier/keeper/keeper.go +++ b/x/tier/keeper/keeper.go @@ -155,7 +155,7 @@ func (k Keeper) Lock(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.Va // Mint credits creditAmt := k.proratedCredit(ctx, delAddr, amt) - err = k.MintCredit(ctx, delAddr, creditAmt) + err = k.mintCredit(ctx, delAddr, creditAmt) if err != nil { return errorsmod.Wrap(err, "mint credit") } diff --git a/x/tier/keeper/keeper_common_test.go b/x/tier/keeper/keeper_common_test.go new file mode 100644 index 0000000..0a49d4a --- /dev/null +++ b/x/tier/keeper/keeper_common_test.go @@ -0,0 +1,169 @@ +package keeper + +import ( + "testing" + "time" + + cryptocdc "github.com/cosmos/cosmos-sdk/crypto/codec" + appparams "github.com/sourcenetwork/sourcehub/app/params" + + "cosmossdk.io/log" + "cosmossdk.io/store" + "cosmossdk.io/store/metrics" + storetypes "cosmossdk.io/store/types" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/runtime" + sdk "github.com/cosmos/cosmos-sdk/types" + authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + epochskeeper "github.com/sourcenetwork/sourcehub/x/epochs/keeper" + epochstypes "github.com/sourcenetwork/sourcehub/x/epochs/types" + + distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + "github.com/sourcenetwork/sourcehub/x/tier/types" + "github.com/stretchr/testify/require" +) + +func setupKeeper(t testing.TB) (Keeper, sdk.Context) { + storeKey := storetypes.NewKVStoreKey(types.StoreKey) + authStoreKey := storetypes.NewKVStoreKey(authtypes.StoreKey) + bankStoreKey := storetypes.NewKVStoreKey(banktypes.StoreKey) + stakingStoreKey := storetypes.NewKVStoreKey(stakingtypes.StoreKey) + distrStoreKey := storetypes.NewKVStoreKey(distrtypes.StoreKey) + epochsStoreKey := storetypes.NewKVStoreKey(epochstypes.StoreKey) + + db := dbm.NewMemDB() + stateStore := store.NewCommitMultiStore(db, log.NewNopLogger(), metrics.NewNoOpMetrics()) + stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(authStoreKey, storetypes.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(bankStoreKey, storetypes.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(stakingStoreKey, storetypes.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(distrStoreKey, storetypes.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(epochsStoreKey, storetypes.StoreTypeIAVL, db) + require.NoError(t, stateStore.LoadLatestVersion()) + + registry := codectypes.NewInterfaceRegistry() + cryptocdc.RegisterInterfaces(registry) + authtypes.RegisterInterfaces(registry) + banktypes.RegisterInterfaces(registry) + stakingtypes.RegisterInterfaces(registry) + distrtypes.RegisterInterfaces(registry) + + cdc := codec.NewProtoCodec(registry) + authority := authtypes.NewModuleAddress(govtypes.ModuleName) + bech32Prefix := "source" + addressCodec := authcodec.NewBech32Codec(bech32Prefix) + valOperCodec := authcodec.NewBech32Codec(bech32Prefix + "valoper") + valConsCodec := authcodec.NewBech32Codec(bech32Prefix + "valcons") + + maccPerms := map[string][]string{ + authtypes.FeeCollectorName: nil, + types.ModuleName: {authtypes.Minter, authtypes.Burner, authtypes.Staking}, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + distrtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + } + + authKeeper := authkeeper.NewAccountKeeper( + cdc, + runtime.NewKVStoreService(authStoreKey), + authtypes.ProtoBaseAccount, + maccPerms, + addressCodec, + bech32Prefix, + authority.String(), + ) + + blockedAddrs := make(map[string]bool) + for acc := range maccPerms { + blockedAddrs[authtypes.NewModuleAddress(acc).String()] = true + } + bankKeeper := bankkeeper.NewBaseKeeper( + cdc, + runtime.NewKVStoreService(bankStoreKey), + authKeeper, + blockedAddrs, + authority.String(), + log.NewNopLogger(), + ) + + ctx := sdk.NewContext(stateStore, cmtproto.Header{}, false, log.NewNopLogger()) + ctx = ctx.WithBlockHeight(1).WithChainID("sourcehub").WithBlockTime(time.Unix(1000000000, 0)) + + appparams.RegisterDenoms(ctx, bankKeeper) + + bondedPool := authtypes.NewEmptyModuleAccount(stakingtypes.BondedPoolName, authtypes.Burner, authtypes.Staking) + notBondedPool := authtypes.NewEmptyModuleAccount(stakingtypes.NotBondedPoolName, authtypes.Burner, authtypes.Staking) + tierPool := authtypes.NewEmptyModuleAccount(types.ModuleName, authtypes.Minter, authtypes.Burner) + distrPool := authtypes.NewEmptyModuleAccount(distrtypes.ModuleName) + + if authKeeper.GetModuleAccount(ctx, stakingtypes.BondedPoolName) == nil { + authKeeper.SetModuleAccount(ctx, bondedPool) + } + if authKeeper.GetModuleAccount(ctx, stakingtypes.NotBondedPoolName) == nil { + authKeeper.SetModuleAccount(ctx, notBondedPool) + } + if authKeeper.GetModuleAccount(ctx, types.ModuleName) == nil { + authKeeper.SetModuleAccount(ctx, tierPool) + } + if authKeeper.GetModuleAccount(ctx, distrtypes.ModuleName) == nil { + authKeeper.SetModuleAccount(ctx, distrPool) + } + + stakingKeeper := stakingkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(stakingStoreKey), + authKeeper, + bankKeeper, + authority.String(), + valOperCodec, + valConsCodec, + ) + + stakingParams := stakingtypes.DefaultParams() + stakingParams.BondDenom = appparams.DefaultBondDenom + require.NoError(t, stakingKeeper.SetParams(ctx, stakingParams)) + + distributionKeeper := distrkeeper.NewKeeper( + cdc, + runtime.NewKVStoreService(distrStoreKey), + authKeeper, + bankKeeper, + stakingKeeper, + authority.String(), + authority.String(), + ) + + epochsKeeper := epochskeeper.NewKeeper( + runtime.NewKVStoreService(epochsStoreKey), + log.NewNopLogger(), + ) + + k := NewKeeper( + cdc, + runtime.NewKVStoreService(storeKey), + log.NewNopLogger(), + authority.String(), + bankKeeper, + stakingKeeper, + epochsKeeper, + distributionKeeper, + ) + + // Initialize params + if err := k.SetParams(ctx, types.DefaultParams()); err != nil { + panic(err) + } + + return k, ctx +} diff --git a/x/tier/keeper/keeper_test.go b/x/tier/keeper/keeper_test.go index e6da95b..65dade1 100644 --- a/x/tier/keeper/keeper_test.go +++ b/x/tier/keeper/keeper_test.go @@ -8,21 +8,17 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking/keeper" - "github.com/sourcenetwork/sourcehub/app" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" appparams "github.com/sourcenetwork/sourcehub/app/params" testutil "github.com/sourcenetwork/sourcehub/testutil" - tierkeeper "github.com/sourcenetwork/sourcehub/x/tier/keeper" + keepertest "github.com/sourcenetwork/sourcehub/testutil/keeper" + "github.com/sourcenetwork/sourcehub/x/tier/keeper" "github.com/sourcenetwork/sourcehub/x/tier/types" "github.com/stretchr/testify/require" ) -func init() { - app.SetConfig(false) -} - // initializeValidator creates a validator and verifies that it was set correctly. -func initializeValidator(t *testing.T, k *keeper.Keeper, ctx sdk.Context, valAddr sdk.ValAddress, initialTokens math.Int) { +func initializeValidator(t *testing.T, k *stakingkeeper.Keeper, ctx sdk.Context, valAddr sdk.ValAddress, initialTokens math.Int) { validator := testutil.CreateTestValidator(t, ctx, k, valAddr, cosmosed25519.GenPrivKey().PubKey(), initialTokens) gotValidator, err := k.GetValidator(ctx, valAddr) require.Nil(t, err) @@ -30,7 +26,7 @@ func initializeValidator(t *testing.T, k *keeper.Keeper, ctx sdk.Context, valAdd } // initializeDelegator initializes ba delegator with balance. -func initializeDelegator(t *testing.T, k *tierkeeper.Keeper, ctx sdk.Context, delAddr sdk.AccAddress, initialBalance math.Int) { +func initializeDelegator(t *testing.T, k *keeper.Keeper, ctx sdk.Context, delAddr sdk.AccAddress, initialBalance math.Int) { initialDelegatorBalance := sdk.NewCoins(sdk.NewCoin("open", initialBalance)) err := k.GetBankKeeper().MintCoins(ctx, types.ModuleName, initialDelegatorBalance) require.NoError(t, err) @@ -40,7 +36,7 @@ func initializeDelegator(t *testing.T, k *tierkeeper.Keeper, ctx sdk.Context, de // TestLock verifies that a valid lockup is created on keeper.Lock(). func TestLock(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) amount := math.NewInt(1000) invalidAmount := math.NewInt(-100) @@ -51,9 +47,9 @@ func TestLock(t *testing.T) { require.NoError(t, err) initialDelegatorBalance := math.NewInt(2000) - initializeDelegator(t, k, ctx, delAddr, initialDelegatorBalance) + initializeDelegator(t, &k, ctx, delAddr, initialDelegatorBalance) initialValidatorBalance := math.NewInt(1000) - initializeValidator(t, k.GetStakingKeeper().(*keeper.Keeper), ctx, valAddr, initialValidatorBalance) + initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), ctx, valAddr, initialValidatorBalance) // set initial block height and time ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now()) @@ -75,7 +71,7 @@ func TestLock(t *testing.T) { // TestUnlock verifies that a valid unlocking lockup is created on keeper.Unock(). func TestUnlock(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) lockAmount := math.NewInt(1000) unlockAmount := math.NewInt(500) @@ -87,9 +83,9 @@ func TestUnlock(t *testing.T) { require.NoError(t, err) initialDelegatorBalance := math.NewInt(2000) - initializeDelegator(t, k, ctx, delAddr, initialDelegatorBalance) + initializeDelegator(t, &k, ctx, delAddr, initialDelegatorBalance) initialValidatorBalance := math.NewInt(1000) - initializeValidator(t, k.GetStakingKeeper().(*keeper.Keeper), ctx, valAddr, initialValidatorBalance) + initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), ctx, valAddr, initialValidatorBalance) // set initial block height and time ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now()) @@ -123,7 +119,7 @@ func TestUnlock(t *testing.T) { // TestRedelegate verifies that a locked amount is correctly redelegated on keeper.Redelegate(). func TestRedelegate(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) amount := math.NewInt(1000) invalidAmount := math.NewInt(-100) @@ -136,10 +132,10 @@ func TestRedelegate(t *testing.T) { require.NoError(t, err) initialDelegatorBalance := math.NewInt(2000) - initializeDelegator(t, k, ctx, delAddr, initialDelegatorBalance) + initializeDelegator(t, &k, ctx, delAddr, initialDelegatorBalance) initialValidatorBalance := math.NewInt(1000) - initializeValidator(t, k.GetStakingKeeper().(*keeper.Keeper), ctx, srcValAddr, initialValidatorBalance) - initializeValidator(t, k.GetStakingKeeper().(*keeper.Keeper), ctx, dstValAddr, initialValidatorBalance) + initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), ctx, srcValAddr, initialValidatorBalance) + initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), ctx, dstValAddr, initialValidatorBalance) // set initial block height and time ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now()) @@ -171,7 +167,7 @@ func TestRedelegate(t *testing.T) { // TestCompleteUnlocking verifies that 'fully unlocked' unlocking lockups are removed on keeper.CompleteUnlocking(). // Block time is advanced by 60 days from when keeper.Unlock() is called to make sure that the unlock time is in the past. func TestCompleteUnlocking(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) lockAmount := math.NewInt(123_456) unlockAmount := math.NewInt(123_456) @@ -182,9 +178,9 @@ func TestCompleteUnlocking(t *testing.T) { require.NoError(t, err) initialDelegatorBalance := math.NewInt(200_000) - initializeDelegator(t, k, ctx, delAddr, initialDelegatorBalance) + initializeDelegator(t, &k, ctx, delAddr, initialDelegatorBalance) initialValidatorBalance := math.NewInt(1_000_000) - initializeValidator(t, k.GetStakingKeeper().(*keeper.Keeper), ctx, valAddr, initialValidatorBalance) + initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), ctx, valAddr, initialValidatorBalance) // set initial block height and time ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now()) @@ -232,7 +228,7 @@ func TestCompleteUnlocking(t *testing.T) { // TestCancelUnlocking verifies that the unlocking lockup is removed on keeper.CancelUnlocking(). func TestCancelUnlocking(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) initialLockAmount := math.NewInt(1000) updatedLockAmount := math.NewInt(700) @@ -246,9 +242,9 @@ func TestCancelUnlocking(t *testing.T) { require.NoError(t, err) initialDelegatorBalance := math.NewInt(200_000) - initializeDelegator(t, k, ctx, delAddr, initialDelegatorBalance) + initializeDelegator(t, &k, ctx, delAddr, initialDelegatorBalance) initialValidatorBalance := math.NewInt(10_000_000) - initializeValidator(t, k.GetStakingKeeper().(*keeper.Keeper), ctx, valAddr, initialValidatorBalance) + initializeValidator(t, k.GetStakingKeeper().(*stakingkeeper.Keeper), ctx, valAddr, initialValidatorBalance) // set initial block height and time ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now()) diff --git a/x/tier/keeper/lockup_test.go b/x/tier/keeper/lockup_test.go index ab26e59..1a50f92 100644 --- a/x/tier/keeper/lockup_test.go +++ b/x/tier/keeper/lockup_test.go @@ -7,18 +7,13 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/sourcenetwork/sourcehub/app" - testutil "github.com/sourcenetwork/sourcehub/testutil" + keepertest "github.com/sourcenetwork/sourcehub/testutil/keeper" "github.com/sourcenetwork/sourcehub/x/tier/types" "github.com/stretchr/testify/require" ) -func init() { - app.SetConfig(true) -} - func TestSetAndGetLockup(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) now := time.Now() creationHeight := int64(10) @@ -45,7 +40,7 @@ func TestSetAndGetLockup(t *testing.T) { } func TestAddLockup(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) amount := math.NewInt(500) @@ -61,7 +56,7 @@ func TestAddLockup(t *testing.T) { } func TestSubtractLockup(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) lockupAmount := math.NewInt(1000) partialSubtractAmount := math.NewInt(500) @@ -96,7 +91,7 @@ func TestSubtractLockup(t *testing.T) { } func TestGetAllLockups(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) amount1 := math.NewInt(1000) amount2 := math.NewInt(500) @@ -124,7 +119,7 @@ func TestGetAllLockups(t *testing.T) { } func TestMustIterateLockups(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) amount := math.NewInt(1000) @@ -147,7 +142,7 @@ func TestMustIterateLockups(t *testing.T) { } func TestMustIterateUnlockingLockups(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) amount := math.NewInt(1000) @@ -171,7 +166,7 @@ func TestMustIterateUnlockingLockups(t *testing.T) { } func TestIterateLockups(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) delAddr1, err := sdk.AccAddressFromBech32("source1wjj5v5rlf57kayyeskncpu4hwev25ty645p2et") require.Nil(t, err) @@ -226,7 +221,7 @@ func TestIterateLockups(t *testing.T) { } func TestTotalAmountByAddr(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) delAddr1, err := sdk.AccAddressFromBech32("source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9") require.NoError(t, err) @@ -255,7 +250,7 @@ func TestTotalAmountByAddr(t *testing.T) { } func TestHasLockup(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) delAddr, err := sdk.AccAddressFromBech32("source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9") require.NoError(t, err) @@ -273,7 +268,7 @@ func TestHasLockup(t *testing.T) { } func TestGetUnlockingLockup(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) now := time.Now() params := k.GetParams(ctx) @@ -304,7 +299,7 @@ func TestGetUnlockingLockup(t *testing.T) { } func TestGetLockup(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) now := time.Now() creationHeight := int64(10) @@ -336,7 +331,7 @@ func TestGetLockup(t *testing.T) { } func TestGetLockups(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) amount1 := math.NewInt(1000) amount2 := math.NewInt(500) @@ -368,7 +363,7 @@ func TestGetLockups(t *testing.T) { } func TestSubtractUnlockingLockup(t *testing.T) { - k, ctx := testutil.SetupKeeper(t) + k, ctx := keepertest.TierKeeper(t) params := k.GetParams(ctx) epochDuration := *params.EpochDuration diff --git a/x/tier/keeper/main_test.go b/x/tier/keeper/main_test.go new file mode 100644 index 0000000..5ebc34f --- /dev/null +++ b/x/tier/keeper/main_test.go @@ -0,0 +1,13 @@ +package keeper_test + +import ( + "os" + "testing" + + "github.com/sourcenetwork/sourcehub/app" +) + +func TestMain(m *testing.M) { + app.SetConfig(true) + os.Exit(m.Run()) +} From 3df6c0c5c657b0b16a7967a075bb1658e5dd0aa0 Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 7 Jan 2025 17:42:04 +0800 Subject: [PATCH 15/17] Uuse block time instead of actual time in calculateProratedCredit() --- x/tier/keeper/calculate_credit.go | 3 ++- x/tier/keeper/calculate_credit_test.go | 17 +++++++++-------- x/tier/keeper/credit.go | 1 + 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/x/tier/keeper/calculate_credit.go b/x/tier/keeper/calculate_credit.go index 5fe5cfa..ce12804 100644 --- a/x/tier/keeper/calculate_credit.go +++ b/x/tier/keeper/calculate_credit.go @@ -49,12 +49,13 @@ func calculateProratedCredit( lockedAmt, lockingAmt math.Int, currentEpochStartTime time.Time, epochDuration time.Duration, + currentBlockTime time.Time, ) math.Int { // Calculate the reward credits earned on the new lock. credit := calculateCredit(rates, lockedAmt, lockingAmt) // Prorate the credit based on the time elapsed in the current epoch. - sinceCurrentEpoch := time.Since(currentEpochStartTime).Milliseconds() + sinceCurrentEpoch := currentBlockTime.Sub(currentEpochStartTime).Milliseconds() epochDurationMs := epochDuration.Milliseconds() if epochDurationMs == 0 { diff --git a/x/tier/keeper/calculate_credit_test.go b/x/tier/keeper/calculate_credit_test.go index 46f9394..d0da897 100644 --- a/x/tier/keeper/calculate_credit_test.go +++ b/x/tier/keeper/calculate_credit_test.go @@ -11,7 +11,7 @@ import ( "github.com/sourcenetwork/sourcehub/x/tier/types" ) -func Test_CalculateCredit(t *testing.T) { +func TestCalculateCredit(t *testing.T) { rateList := []types.Rate{ {Amount: math.NewInt(300), Rate: 150}, {Amount: math.NewInt(200), Rate: 120}, @@ -99,7 +99,7 @@ func Test_CalculateCredit(t *testing.T) { } } -func Test_CalculateProratedCredit(t *testing.T) { +func TestCalculateProratedCredit(t *testing.T) { tests := []struct { name string lockedAmt int64 @@ -145,10 +145,10 @@ func Test_CalculateProratedCredit(t *testing.T) { { name: "At the beginning of an epoch", lockedAmt: 0, - lockingAmt: 0, - epochStartTime: time.Now().UTC(), + lockingAmt: 100, + epochStartTime: time.Now().UTC().Add(-5 * time.Minute), epochDuration: time.Minute * 5, - expectedCredit: 0, + expectedCredit: 100, }, { name: "In the middle of an epoch", @@ -162,9 +162,9 @@ func Test_CalculateProratedCredit(t *testing.T) { name: "At the end of an epoch", lockedAmt: 0, lockingAmt: 100, - epochStartTime: time.Now().UTC().Add(-5 * time.Minute), + epochStartTime: time.Now().UTC(), epochDuration: time.Minute * 5, - expectedCredit: 100, + expectedCredit: 0, }, { name: "Negative locking amount", @@ -226,7 +226,7 @@ func Test_CalculateProratedCredit(t *testing.T) { name: "Long epoch duration", lockedAmt: 0, lockingAmt: 100, - epochStartTime: time.Now().UTC().Add(-12 * 30 * time.Hour), + epochStartTime: time.Now().UTC().Add(-15 * 24 * time.Hour), epochDuration: time.Hour * 24 * 30, expectedCredit: 50, }, @@ -370,6 +370,7 @@ func Test_CalculateProratedCredit(t *testing.T) { lockingAmt, tt.epochStartTime, tt.epochDuration, + time.Now().UTC(), ) if !credit.Equal(math.NewInt(tt.expectedCredit)) { diff --git a/x/tier/keeper/credit.go b/x/tier/keeper/credit.go index cb78f4b..742a75d 100644 --- a/x/tier/keeper/credit.go +++ b/x/tier/keeper/credit.go @@ -48,6 +48,7 @@ func (k Keeper) proratedCredit(ctx context.Context, delAddr sdk.AccAddress, lock lockingAmt, epochInfo.CurrentEpochStartTime, epochInfo.Duration, + sdk.UnwrapSDKContext(ctx).BlockTime(), ) } From 1f40bd0ac6aa31c40612310a1289950929ca1efa Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 7 Jan 2025 17:47:47 +0800 Subject: [PATCH 16/17] Add GetEpochsKeeper() and SetEpochInfo(), fix message server tests --- testutil/mocks.go | 14 ++++++++++++++ x/tier/keeper/keeper.go | 5 +++++ x/tier/keeper/msg_cancel_unlocking_test.go | 13 +++++++++++++ x/tier/keeper/msg_lock_test.go | 13 +++++++++++++ x/tier/keeper/msg_redelegate_test.go | 12 ++++++++++++ x/tier/keeper/msg_unlock_test.go | 12 ++++++++++++ x/tier/types/expected_keepers.go | 2 ++ 7 files changed, 71 insertions(+) diff --git a/testutil/mocks.go b/testutil/mocks.go index d2c9e2b..d5e55a1 100644 --- a/testutil/mocks.go +++ b/testutil/mocks.go @@ -433,3 +433,17 @@ func (mr *MockEpochsKeeperMockRecorder) GetEpochInfo(ctx, identifier interface{} mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEpochInfo", reflect.TypeOf((*MockEpochsKeeper)(nil).GetEpochInfo), ctx, identifier) } + +func (m *MockEpochsKeeper) SetEpochInfo(ctx context.Context, info epochstypes.EpochInfo) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetEpochInfo", ctx, info) +} + +func (mr *MockEpochsKeeperMockRecorder) SetEpochInfo(ctx, info interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType( + mr.mock, "SetEpochInfo", + reflect.TypeOf((*MockEpochsKeeper)(nil).SetEpochInfo), + ctx, info, + ) +} diff --git a/x/tier/keeper/keeper.go b/x/tier/keeper/keeper.go index 9599172..76d8d0d 100644 --- a/x/tier/keeper/keeper.go +++ b/x/tier/keeper/keeper.go @@ -81,6 +81,11 @@ func (k Keeper) GetBankKeeper() types.BankKeeper { return k.bankKeeper } +// GetEpochsKeeper returns the module's EpochsKeeper. +func (k Keeper) GetEpochsKeeper() types.EpochsKeeper { + return k.epochsKeeper +} + // Logger returns a module-specific logger. func (k Keeper) Logger() log.Logger { return k.logger.With("module", fmt.Sprintf("x/%s", types.ModuleName)) diff --git a/x/tier/keeper/msg_cancel_unlocking_test.go b/x/tier/keeper/msg_cancel_unlocking_test.go index 7b68915..f476de0 100644 --- a/x/tier/keeper/msg_cancel_unlocking_test.go +++ b/x/tier/keeper/msg_cancel_unlocking_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "testing" + "time" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" @@ -9,6 +10,7 @@ import ( "github.com/stretchr/testify/require" appparams "github.com/sourcenetwork/sourcehub/app/params" + epochstypes "github.com/sourcenetwork/sourcehub/x/epochs/types" "github.com/sourcenetwork/sourcehub/x/tier/keeper" "github.com/sourcenetwork/sourcehub/x/tier/types" ) @@ -52,6 +54,17 @@ func TestMsgCancelUnlocking(t *testing.T) { k, ms, ctx := setupMsgServer(t) sdkCtx := sdk.UnwrapSDKContext(ctx) + p := types.DefaultParams() + require.NoError(t, k.SetParams(ctx, p)) + + epoch := epochstypes.EpochInfo{ + Identifier: types.EpochIdentifier, + CurrentEpoch: 1, + CurrentEpochStartTime: sdkCtx.BlockTime().Add(-5 * time.Minute), + Duration: 5 * time.Minute, + } + k.GetEpochsKeeper().SetEpochInfo(ctx, epoch) + validCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(100)) partialCancelCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(50)) excessCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(500)) diff --git a/x/tier/keeper/msg_lock_test.go b/x/tier/keeper/msg_lock_test.go index 779e4d2..f61ec05 100644 --- a/x/tier/keeper/msg_lock_test.go +++ b/x/tier/keeper/msg_lock_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "testing" + "time" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" @@ -9,6 +10,7 @@ import ( stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" appparams "github.com/sourcenetwork/sourcehub/app/params" + epochstypes "github.com/sourcenetwork/sourcehub/x/epochs/types" "github.com/sourcenetwork/sourcehub/x/tier/types" ) @@ -16,6 +18,17 @@ func TestMsgLock(t *testing.T) { k, ms, ctx := setupMsgServer(t) sdkCtx := sdk.UnwrapSDKContext(ctx) + p := types.DefaultParams() + require.NoError(t, k.SetParams(ctx, p)) + + epoch := epochstypes.EpochInfo{ + Identifier: types.EpochIdentifier, + CurrentEpoch: 1, + CurrentEpochStartTime: sdkCtx.BlockTime().Add(-5 * time.Minute), + Duration: 5 * time.Minute, + } + k.GetEpochsKeeper().SetEpochInfo(ctx, epoch) + validCoin1 := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(100)) validCoin2 := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(3000)) zeroCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.ZeroInt()) diff --git a/x/tier/keeper/msg_redelegate_test.go b/x/tier/keeper/msg_redelegate_test.go index c377521..1fd1519 100644 --- a/x/tier/keeper/msg_redelegate_test.go +++ b/x/tier/keeper/msg_redelegate_test.go @@ -10,6 +10,7 @@ import ( stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" appparams "github.com/sourcenetwork/sourcehub/app/params" + epochstypes "github.com/sourcenetwork/sourcehub/x/epochs/types" "github.com/sourcenetwork/sourcehub/x/tier/types" ) @@ -17,6 +18,17 @@ func TestMsgRedelegate(t *testing.T) { k, ms, ctx := setupMsgServer(t) sdkCtx := sdk.UnwrapSDKContext(ctx) + p := types.DefaultParams() + require.NoError(t, k.SetParams(ctx, p)) + + epoch := epochstypes.EpochInfo{ + Identifier: types.EpochIdentifier, + CurrentEpoch: 1, + CurrentEpochStartTime: sdkCtx.BlockTime().Add(-5 * time.Minute), + Duration: 5 * time.Minute, + } + k.GetEpochsKeeper().SetEpochInfo(ctx, epoch) + validCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(100)) zeroCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.ZeroInt()) negativeAmount := math.NewInt(-100) diff --git a/x/tier/keeper/msg_unlock_test.go b/x/tier/keeper/msg_unlock_test.go index c1365bf..e38a9b4 100644 --- a/x/tier/keeper/msg_unlock_test.go +++ b/x/tier/keeper/msg_unlock_test.go @@ -10,6 +10,7 @@ import ( stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" appparams "github.com/sourcenetwork/sourcehub/app/params" + epochstypes "github.com/sourcenetwork/sourcehub/x/epochs/types" "github.com/sourcenetwork/sourcehub/x/tier/types" ) @@ -17,6 +18,17 @@ func TestMsgUnlock(t *testing.T) { k, ms, ctx := setupMsgServer(t) sdkCtx := sdk.UnwrapSDKContext(ctx) + p := types.DefaultParams() + require.NoError(t, k.SetParams(ctx, p)) + + epoch := epochstypes.EpochInfo{ + Identifier: types.EpochIdentifier, + CurrentEpoch: 1, + CurrentEpochStartTime: sdkCtx.BlockTime().Add(-5 * time.Minute), + Duration: 5 * time.Minute, + } + k.GetEpochsKeeper().SetEpochInfo(ctx, epoch) + validCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.NewInt(100)) zeroCoin := sdk.NewCoin(appparams.DefaultBondDenom, math.ZeroInt()) negativeAmount := math.NewInt(-100) diff --git a/x/tier/types/expected_keepers.go b/x/tier/types/expected_keepers.go index 15b0114..7d4bac3 100644 --- a/x/tier/types/expected_keepers.go +++ b/x/tier/types/expected_keepers.go @@ -12,8 +12,10 @@ import ( epochstypes "github.com/sourcenetwork/sourcehub/x/epochs/types" ) +// EpochsKeeper defines the expected interface for the Epochs module. type EpochsKeeper interface { GetEpochInfo(ctx context.Context, identifier string) epochstypes.EpochInfo + SetEpochInfo(ctx context.Context, info epochstypes.EpochInfo) } // StakingKeeper defines the expected interface for the Staking module. From 3eba5364b23893befcbdb4bbaae2a12ac903f889 Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 7 Jan 2025 17:50:12 +0800 Subject: [PATCH 17/17] Add TestProratedCredit with cases matching TestCalculateProratedCredit --- x/tier/keeper/credit_test.go | 284 ++++++++++++++++++++++++++++++++++- 1 file changed, 281 insertions(+), 3 deletions(-) diff --git a/x/tier/keeper/credit_test.go b/x/tier/keeper/credit_test.go index fd4618d..cda0838 100644 --- a/x/tier/keeper/credit_test.go +++ b/x/tier/keeper/credit_test.go @@ -2,16 +2,18 @@ package keeper import ( "testing" + "time" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" "github.com/sourcenetwork/sourcehub/app/params" + epochstypes "github.com/sourcenetwork/sourcehub/x/epochs/types" "github.com/sourcenetwork/sourcehub/x/tier/types" ) -func Test_MintCredit(t *testing.T) { +func TestMintCredit(t *testing.T) { tests := []struct { name string addr string @@ -56,7 +58,283 @@ func Test_MintCredit(t *testing.T) { } } -func Test_BurnAllCredits(t *testing.T) { +func TestProratedCredit(t *testing.T) { + k, ctx := setupKeeper(t) + + baseTime := time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC) + + cases := []struct { + name string + locked int64 + locking int64 + remainingMs int64 + totalMs int64 + want int64 + }{ + { + name: "Large amount in the middle of the epoch", + locked: 0, + locking: 10_000_000, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 5_999_952, + }, + { + name: "Large amount at the first second of the epoch", + locked: 0, + locking: 10_000_000, + remainingMs: 299_000, // 4 minutes 59 seconds + totalMs: 300_000, // 5 minutes + want: 14_949_880, + }, + { + name: "Large amount at the last second of the epoch", + locked: 0, + locking: 10_000_000, + remainingMs: 1000, // 1 second + totalMs: 300_000, // 5 minutes + want: 49_999, + }, + { + name: "At the beginning of an epoch", + locked: 0, + locking: 100, + remainingMs: 300_000, // 5 minutes + totalMs: 300_000, // 5 minutes + want: 100, + }, + { + name: "In the middle of an epoch", + locked: 0, + locking: 100, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 40, + }, + { + name: "At the end of an epoch", + locked: 0, + locking: 100, + remainingMs: 0, + totalMs: 300_000, // 5 minutes + want: 0, + }, + { + name: "Negative locking amount", + locked: 0, + locking: -100, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 0, + }, + { + name: "Zero locking amount", + locked: 0, + locking: 0, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 0, + }, + { + name: "Locking amount with 1.1 rate", + locked: 0, + locking: 100, + remainingMs: 240_000, // 4 minutes + totalMs: 300_000, // 5 minutes + want: 80, + }, + { + name: "Locking amount with 1.2 rate", + locked: 0, + locking: 200, + remainingMs: 180_000, // 3 minutes + totalMs: 360_000, // 6 minutes + want: 105, + }, + { + name: "Locking amount with 1.5 rate", + locked: 0, + locking: 300, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 132, + }, + { + name: "Zero epoch duration", + locked: 0, + locking: 100, + remainingMs: 0, + totalMs: 0, + want: 0, + }, + { + name: "Short epoch duration", + locked: 0, + locking: 100, + remainingMs: 30_000, // 30 seconds + totalMs: 60_000, // 1 minute + want: 50, + }, + { + name: "Long epoch duration", + locked: 0, + locking: 100, + remainingMs: 1_296_000_000, // 15 days + totalMs: 2_592_000_000, // 30 days + want: 50, + }, + { + name: "Epoch duration less than sinceCurrentEpoch", + locked: 0, + locking: 100, + remainingMs: 600_000, // 10 minutes + totalMs: 300_000, // 5 minutes + want: 100, + }, + { + name: "Small locking amount and short epoch", + locked: 0, + locking: 9, + remainingMs: 3000, // 3 seconds + totalMs: 10_000, // 10 seconds + want: 2, + }, + { + name: "Small locking amount and long epoch", + locked: 0, + locking: 11, + remainingMs: 600_000, // 10 minutes + totalMs: 7_200_000, // 2 hours + want: 0, + }, + { + name: "Large locking amount and short epoch", + locked: 0, + locking: 1_000_003, + remainingMs: 1000, // 1 second + totalMs: 5000, // 5 seconds + want: 299_976, + }, + { + name: "Large locking amount and long epoch", + locked: 0, + locking: 1_000_003, + remainingMs: 3_600_000, // 1 hour + totalMs: 18_000_000, // 5 hours + want: 299_976, + }, + { + name: "Locking amount causing uneven division", + locked: 0, + locking: 7, + remainingMs: 10_000, // 10 seconds + totalMs: 33_000, // 33 seconds + want: 2, + }, + { + name: "Epoch duration causing uneven division", + locked: 0, + locking: 1234, + remainingMs: 4000, // 4 seconds + totalMs: 9000, // 9 seconds + want: 769, + }, + { + name: "Locking amount with 1.0 rate and previously locked amount", + locked: 40, + locking: 40, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 16, // 40 * 1.0 * 2/5 + }, + { + name: "Locking amount with 1.1 rate and previously locked amount", + locked: 100, + locking: 100, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 44, // 100 * 1.1 * 2/5 + }, + { + name: "Locking amount with 1.5 rate and previously locked amount", + locked: 300, + locking: 300, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 180, // 300 * 1.5 * 2/5 + }, + { + name: "Locking amount with 1.2 + 1.1 rate and previously locked amount", + locked: 150, + locking: 150, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 70, // ((100 * 1.2) + (50 * 1.1)) * 2/5 + }, + { + name: "Locking amount with 1.5 + 1.2 rate and previously locked amount", + locked: 200, + locking: 200, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 108, // ((100 * 1.5) + (100 * 1.2)) * 2/5 + }, + { + name: "Locking amount with 1.5 + 1.2 + 1.1 + 1.0 rate and previously locked amount", + locked: 50, + locking: 350, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 172, // ((100 * 1.5) + (100 * 1.2) + (100 * 1.1) + (50 * 1.0)) * 2/5 + }, + { + name: "Locking small amount with large previously locked amount", + locked: 1_000_000, + locking: 100, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 60, // 100 * 1.5 * 2/5 + }, + { + name: "Locking large amount with large previously locked amount", + locked: 1_000_000, + locking: 10_000_000, + remainingMs: 120_000, // 2 minutes + totalMs: 300_000, // 5 minutes + want: 6_000_000, // 10,000,000 * 1.5 * 2/5 + }, + } + + p := types.DefaultParams() + require.NoError(t, k.SetParams(ctx, p)) + + delAddr := sdk.MustAccAddressFromBech32("source1m4f5a896t7fzd9vc7pfgmc3fxkj8n24s68fcw9") + valAddr, err := sdk.ValAddressFromBech32("sourcevaloper1cy0p47z24ejzvq55pu3lesxwf73xnrnd0pzkqm") + require.NoError(t, err) + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + ctx = ctx.WithBlockTime(baseTime).WithBlockHeight(1) + + epochInfo := epochstypes.EpochInfo{ + Identifier: types.EpochIdentifier, + CurrentEpoch: 1, + CurrentEpochStartTime: baseTime.Add(-time.Duration(tc.remainingMs) * time.Millisecond), + Duration: time.Duration(tc.totalMs) * time.Millisecond, + } + k.epochsKeeper.SetEpochInfo(ctx, epochInfo) + + k.removeLockup(ctx, delAddr, valAddr) + if tc.locked > 0 { + k.AddLockup(ctx, delAddr, valAddr, math.NewInt(tc.locked)) + } + got := k.proratedCredit(ctx, delAddr, math.NewInt(tc.locking)) + require.Equal(t, tc.want, got.Int64()) + }) + } +} + +func TestBurnAllCredits(t *testing.T) { tests := []struct { name string creditBalances map[string]int64 @@ -151,7 +429,7 @@ func Test_BurnAllCredits(t *testing.T) { } } -func Test_ResetAllCredits(t *testing.T) { +func TestResetAllCredits(t *testing.T) { tests := []struct { name string lockups map[string][]int64