From d0c475a7745c7e6d14c309d9ba50dd8a63a8ae18 Mon Sep 17 00:00:00 2001 From: ltacker Date: Wed, 27 Jul 2022 11:59:27 +0200 Subject: [PATCH 01/13] proto --- proto/claim/params.proto | 9 ++ x/claim/types/params.pb.go | 304 ++++++++++++++++++++++++++++++++++++- 2 files changed, 305 insertions(+), 8 deletions(-) diff --git a/proto/claim/params.proto b/proto/claim/params.proto index b3eccb215..282883b37 100644 --- a/proto/claim/params.proto +++ b/proto/claim/params.proto @@ -2,10 +2,19 @@ syntax = "proto3"; package tendermint.spn.claim; import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; option go_package = "github.com/tendermint/spn/x/claim/types"; // Params defines the parameters for the module. message Params { + DecayInformation decayInformation = 1 [(gogoproto.nullable) = false]; option (gogoproto.goproto_stringer) = false; } + +// DecayInformation defines the information about decay for the airdrop +// when claimable airdrop amount starts to decrease and when it ends +message DecayInformation { + google.protobuf.Duration decayStart = 1 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + google.protobuf.Duration decayEnd = 2 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; +} diff --git a/x/claim/types/params.pb.go b/x/claim/types/params.pb.go index 876e86956..162851603 100644 --- a/x/claim/types/params.pb.go +++ b/x/claim/types/params.pb.go @@ -7,15 +7,19 @@ import ( fmt "fmt" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + _ "google.golang.org/protobuf/types/known/durationpb" io "io" math "math" math_bits "math/bits" + time "time" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf +var _ = time.Kitchen // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -25,6 +29,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params defines the parameters for the module. type Params struct { + DecayInformation DecayInformation `protobuf:"bytes,1,opt,name=decayInformation,proto3" json:"decayInformation"` } func (m *Params) Reset() { *m = Params{} } @@ -59,24 +64,94 @@ func (m *Params) XXX_DiscardUnknown() { var xxx_messageInfo_Params proto.InternalMessageInfo +func (m *Params) GetDecayInformation() DecayInformation { + if m != nil { + return m.DecayInformation + } + return DecayInformation{} +} + +// DecayInformation defines the information about decay for the airdrop +// when claimable airdrop amount starts to decrease and when it ends +type DecayInformation struct { + DecayStart time.Duration `protobuf:"bytes,1,opt,name=decayStart,proto3,stdduration" json:"decayStart"` + DecayEnd time.Duration `protobuf:"bytes,2,opt,name=decayEnd,proto3,stdduration" json:"decayEnd"` +} + +func (m *DecayInformation) Reset() { *m = DecayInformation{} } +func (m *DecayInformation) String() string { return proto.CompactTextString(m) } +func (*DecayInformation) ProtoMessage() {} +func (*DecayInformation) Descriptor() ([]byte, []int) { + return fileDescriptor_adbfc9fc41f7a9d2, []int{1} +} +func (m *DecayInformation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DecayInformation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DecayInformation.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DecayInformation) XXX_Merge(src proto.Message) { + xxx_messageInfo_DecayInformation.Merge(m, src) +} +func (m *DecayInformation) XXX_Size() int { + return m.Size() +} +func (m *DecayInformation) XXX_DiscardUnknown() { + xxx_messageInfo_DecayInformation.DiscardUnknown(m) +} + +var xxx_messageInfo_DecayInformation proto.InternalMessageInfo + +func (m *DecayInformation) GetDecayStart() time.Duration { + if m != nil { + return m.DecayStart + } + return 0 +} + +func (m *DecayInformation) GetDecayEnd() time.Duration { + if m != nil { + return m.DecayEnd + } + return 0 +} + func init() { proto.RegisterType((*Params)(nil), "tendermint.spn.claim.Params") + proto.RegisterType((*DecayInformation)(nil), "tendermint.spn.claim.DecayInformation") } func init() { proto.RegisterFile("claim/params.proto", fileDescriptor_adbfc9fc41f7a9d2) } var fileDescriptor_adbfc9fc41f7a9d2 = []byte{ - // 151 bytes of a gzipped FileDescriptorProto + // 277 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4a, 0xce, 0x49, 0xcc, 0xcc, 0xd5, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x29, 0x49, 0xcd, 0x4b, 0x49, 0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x2b, 0x2e, 0xc8, 0xd3, 0x03, - 0x2b, 0x91, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd0, 0x07, 0xb1, 0x20, 0x6a, 0x95, 0xf8, - 0xb8, 0xd8, 0x02, 0xc0, 0x7a, 0xad, 0x58, 0x66, 0x2c, 0x90, 0x67, 0x70, 0x72, 0x3c, 0xf1, 0x48, - 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, - 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xf5, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, - 0xe4, 0xfc, 0x5c, 0x7d, 0x84, 0x05, 0xfa, 0xc5, 0x05, 0x79, 0xfa, 0x15, 0xfa, 0x10, 0x57, 0x94, - 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x4d, 0x36, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xa9, - 0x90, 0x93, 0xcf, 0x9b, 0x00, 0x00, 0x00, + 0x2b, 0x91, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd0, 0x07, 0xb1, 0x20, 0x6a, 0xa5, 0xe4, + 0xd2, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0xc1, 0xbc, 0xa4, 0xd2, 0x34, 0xfd, 0x94, 0xd2, 0xa2, + 0xc4, 0x92, 0xcc, 0xfc, 0x3c, 0x88, 0xbc, 0x52, 0x06, 0x17, 0x5b, 0x00, 0xd8, 0x6c, 0xa1, 0x08, + 0x2e, 0x81, 0x94, 0xd4, 0xe4, 0xc4, 0x4a, 0xcf, 0xbc, 0xb4, 0xfc, 0xa2, 0x5c, 0xb0, 0x1a, 0x09, + 0x46, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x35, 0x3d, 0x6c, 0x16, 0xea, 0xb9, 0xa0, 0xa9, 0x76, 0x62, + 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xc3, 0x14, 0x2b, 0x96, 0x19, 0x0b, 0xe4, 0x19, 0x94, 0x66, + 0x30, 0x72, 0x09, 0xa0, 0x6b, 0x11, 0x72, 0xe6, 0xe2, 0x02, 0x2b, 0x0f, 0x2e, 0x49, 0x2c, 0x2a, + 0x81, 0x5a, 0x27, 0xa9, 0x07, 0x71, 0xb3, 0x1e, 0xcc, 0xcd, 0x7a, 0x2e, 0x50, 0x37, 0x3b, 0x71, + 0x80, 0x6c, 0x98, 0x71, 0x5f, 0x9e, 0x31, 0x08, 0x49, 0x9b, 0x90, 0x3d, 0x17, 0x07, 0x98, 0xe7, + 0x9a, 0x97, 0x22, 0xc1, 0x44, 0xbc, 0x11, 0x70, 0x4d, 0x4e, 0x8e, 0x27, 0x1e, 0xc9, 0x31, 0x5e, + 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, + 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, 0x9e, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, + 0xab, 0x8f, 0x08, 0x04, 0xfd, 0xe2, 0x82, 0x3c, 0xfd, 0x0a, 0x7d, 0x48, 0xd4, 0x94, 0x54, 0x16, + 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x6d, 0x32, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x8d, 0x20, 0xef, + 0xf8, 0xb0, 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -99,6 +174,55 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.DecayInformation.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *DecayInformation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DecayInformation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DecayInformation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + n2, err2 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.DecayEnd, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.DecayEnd):]) + if err2 != nil { + return 0, err2 + } + i -= n2 + i = encodeVarintParams(dAtA, i, uint64(n2)) + i-- + dAtA[i] = 0x12 + n3, err3 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.DecayStart, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.DecayStart):]) + if err3 != nil { + return 0, err3 + } + i -= n3 + i = encodeVarintParams(dAtA, i, uint64(n3)) + i-- + dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -119,6 +243,21 @@ func (m *Params) Size() (n int) { } var l int _ = l + l = m.DecayInformation.Size() + n += 1 + l + sovParams(uint64(l)) + return n +} + +func (m *DecayInformation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.DecayStart) + n += 1 + l + sovParams(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.DecayEnd) + n += 1 + l + sovParams(uint64(l)) return n } @@ -157,6 +296,155 @@ func (m *Params) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DecayInformation", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DecayInformation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DecayInformation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DecayInformation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DecayInformation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DecayStart", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.DecayStart, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DecayEnd", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.DecayEnd, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) From 015ec1bc5f4a95ff70a3710e22982732f05e743c Mon Sep 17 00:00:00 2001 From: ltacker Date: Wed, 27 Jul 2022 12:09:14 +0200 Subject: [PATCH 02/13] decay validate --- proto/claim/params.proto | 6 ++-- x/claim/types/decay.go | 12 ++++++++ x/claim/types/params.pb.go | 56 +++++++++++++++++++------------------- 3 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 x/claim/types/decay.go diff --git a/proto/claim/params.proto b/proto/claim/params.proto index 282883b37..d08ad8b46 100644 --- a/proto/claim/params.proto +++ b/proto/claim/params.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package tendermint.spn.claim; import "gogoproto/gogo.proto"; -import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; option go_package = "github.com/tendermint/spn/x/claim/types"; @@ -15,6 +15,6 @@ message Params { // DecayInformation defines the information about decay for the airdrop // when claimable airdrop amount starts to decrease and when it ends message DecayInformation { - google.protobuf.Duration decayStart = 1 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - google.protobuf.Duration decayEnd = 2 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + google.protobuf.Timestamp decayStart = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + google.protobuf.Timestamp decayEnd = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; } diff --git a/x/claim/types/decay.go b/x/claim/types/decay.go new file mode 100644 index 000000000..cc2247d05 --- /dev/null +++ b/x/claim/types/decay.go @@ -0,0 +1,12 @@ +package types + +import ( + "fmt" +) + +// Validate validates the decay information +func (m DecayInformation) Validate() error { + if m.DecayStart.After(m.DecayEnd) { + return fmt.Errorf("decay starts after decay end %s > %s", m.DecayStart.String(), m.DecayEnd.String()) + } +} diff --git a/x/claim/types/params.pb.go b/x/claim/types/params.pb.go index 162851603..8c54a4e53 100644 --- a/x/claim/types/params.pb.go +++ b/x/claim/types/params.pb.go @@ -8,7 +8,7 @@ import ( _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" - _ "google.golang.org/protobuf/types/known/durationpb" + _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" @@ -74,8 +74,8 @@ func (m *Params) GetDecayInformation() DecayInformation { // DecayInformation defines the information about decay for the airdrop // when claimable airdrop amount starts to decrease and when it ends type DecayInformation struct { - DecayStart time.Duration `protobuf:"bytes,1,opt,name=decayStart,proto3,stdduration" json:"decayStart"` - DecayEnd time.Duration `protobuf:"bytes,2,opt,name=decayEnd,proto3,stdduration" json:"decayEnd"` + DecayStart time.Time `protobuf:"bytes,1,opt,name=decayStart,proto3,stdtime" json:"decayStart"` + DecayEnd time.Time `protobuf:"bytes,2,opt,name=decayEnd,proto3,stdtime" json:"decayEnd"` } func (m *DecayInformation) Reset() { *m = DecayInformation{} } @@ -111,18 +111,18 @@ func (m *DecayInformation) XXX_DiscardUnknown() { var xxx_messageInfo_DecayInformation proto.InternalMessageInfo -func (m *DecayInformation) GetDecayStart() time.Duration { +func (m *DecayInformation) GetDecayStart() time.Time { if m != nil { return m.DecayStart } - return 0 + return time.Time{} } -func (m *DecayInformation) GetDecayEnd() time.Duration { +func (m *DecayInformation) GetDecayEnd() time.Time { if m != nil { return m.DecayEnd } - return 0 + return time.Time{} } func init() { @@ -133,25 +133,25 @@ func init() { func init() { proto.RegisterFile("claim/params.proto", fileDescriptor_adbfc9fc41f7a9d2) } var fileDescriptor_adbfc9fc41f7a9d2 = []byte{ - // 277 bytes of a gzipped FileDescriptorProto + // 281 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4a, 0xce, 0x49, 0xcc, 0xcc, 0xd5, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x29, 0x49, 0xcd, 0x4b, 0x49, 0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x2b, 0x2e, 0xc8, 0xd3, 0x03, 0x2b, 0x91, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd0, 0x07, 0xb1, 0x20, 0x6a, 0xa5, 0xe4, - 0xd2, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0xc1, 0xbc, 0xa4, 0xd2, 0x34, 0xfd, 0x94, 0xd2, 0xa2, - 0xc4, 0x92, 0xcc, 0xfc, 0x3c, 0x88, 0xbc, 0x52, 0x06, 0x17, 0x5b, 0x00, 0xd8, 0x6c, 0xa1, 0x08, - 0x2e, 0x81, 0x94, 0xd4, 0xe4, 0xc4, 0x4a, 0xcf, 0xbc, 0xb4, 0xfc, 0xa2, 0x5c, 0xb0, 0x1a, 0x09, - 0x46, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x35, 0x3d, 0x6c, 0x16, 0xea, 0xb9, 0xa0, 0xa9, 0x76, 0x62, - 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xc3, 0x14, 0x2b, 0x96, 0x19, 0x0b, 0xe4, 0x19, 0x94, 0x66, - 0x30, 0x72, 0x09, 0xa0, 0x6b, 0x11, 0x72, 0xe6, 0xe2, 0x02, 0x2b, 0x0f, 0x2e, 0x49, 0x2c, 0x2a, - 0x81, 0x5a, 0x27, 0xa9, 0x07, 0x71, 0xb3, 0x1e, 0xcc, 0xcd, 0x7a, 0x2e, 0x50, 0x37, 0x3b, 0x71, - 0x80, 0x6c, 0x98, 0x71, 0x5f, 0x9e, 0x31, 0x08, 0x49, 0x9b, 0x90, 0x3d, 0x17, 0x07, 0x98, 0xe7, - 0x9a, 0x97, 0x22, 0xc1, 0x44, 0xbc, 0x11, 0x70, 0x4d, 0x4e, 0x8e, 0x27, 0x1e, 0xc9, 0x31, 0x5e, - 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, - 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, 0x9e, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, - 0xab, 0x8f, 0x08, 0x04, 0xfd, 0xe2, 0x82, 0x3c, 0xfd, 0x0a, 0x7d, 0x48, 0xd4, 0x94, 0x54, 0x16, - 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x6d, 0x32, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x8d, 0x20, 0xef, - 0xf8, 0xb0, 0x01, 0x00, 0x00, + 0xd3, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0xc1, 0xbc, 0xa4, 0xd2, 0x34, 0xfd, 0x92, 0xcc, 0xdc, + 0xd4, 0xe2, 0x92, 0xc4, 0xdc, 0x02, 0x88, 0x02, 0xa5, 0x0c, 0x2e, 0xb6, 0x00, 0xb0, 0xe1, 0x42, + 0x11, 0x5c, 0x02, 0x29, 0xa9, 0xc9, 0x89, 0x95, 0x9e, 0x79, 0x69, 0xf9, 0x45, 0xb9, 0x89, 0x25, + 0x99, 0xf9, 0x79, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0x6a, 0x7a, 0xd8, 0x6c, 0xd4, 0x73, + 0x41, 0x53, 0xed, 0xc4, 0x72, 0xe2, 0x9e, 0x3c, 0x43, 0x10, 0x86, 0x29, 0x56, 0x2c, 0x33, 0x16, + 0xc8, 0x33, 0x28, 0xcd, 0x62, 0xe4, 0x12, 0x40, 0xd7, 0x22, 0xe4, 0xc2, 0xc5, 0x05, 0x56, 0x1e, + 0x5c, 0x92, 0x58, 0x54, 0x02, 0xb5, 0x4e, 0x4a, 0x0f, 0xe2, 0x68, 0x3d, 0x98, 0xa3, 0xf5, 0x42, + 0x60, 0x8e, 0x76, 0xe2, 0x00, 0x59, 0x31, 0xe1, 0xbe, 0x3c, 0x63, 0x10, 0x92, 0x3e, 0x21, 0x07, + 0x2e, 0x0e, 0x30, 0xcf, 0x35, 0x2f, 0x45, 0x82, 0x89, 0x04, 0x33, 0xe0, 0xba, 0x9c, 0x1c, 0x4f, + 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, + 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x3d, 0x3d, 0xb3, 0x24, 0xa3, 0x34, + 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0x11, 0x0c, 0xfa, 0xc5, 0x05, 0x79, 0xfa, 0x15, 0xfa, 0x90, + 0xd8, 0x29, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0x5b, 0x65, 0x0c, 0x08, 0x00, 0x00, 0xff, + 0xff, 0x94, 0xad, 0x96, 0xfe, 0xb3, 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -207,7 +207,7 @@ func (m *DecayInformation) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - n2, err2 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.DecayEnd, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.DecayEnd):]) + n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.DecayEnd, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.DecayEnd):]) if err2 != nil { return 0, err2 } @@ -215,7 +215,7 @@ func (m *DecayInformation) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintParams(dAtA, i, uint64(n2)) i-- dAtA[i] = 0x12 - n3, err3 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.DecayStart, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.DecayStart):]) + n3, err3 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.DecayStart, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.DecayStart):]) if err3 != nil { return 0, err3 } @@ -254,9 +254,9 @@ func (m *DecayInformation) Size() (n int) { } var l int _ = l - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.DecayStart) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.DecayStart) n += 1 + l + sovParams(uint64(l)) - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.DecayEnd) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.DecayEnd) n += 1 + l + sovParams(uint64(l)) return n } @@ -408,7 +408,7 @@ func (m *DecayInformation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.DecayStart, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.DecayStart, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -441,7 +441,7 @@ func (m *DecayInformation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.DecayEnd, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.DecayEnd, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex From 2098f3a6ad23aebe59a73d65cbf78f700161e823 Mon Sep 17 00:00:00 2001 From: ltacker Date: Wed, 27 Jul 2022 13:24:53 +0200 Subject: [PATCH 03/13] enabled --- proto/claim/params.proto | 5 +-- x/claim/types/decay.go | 4 ++- x/claim/types/params.pb.go | 72 ++++++++++++++++++++++++++++++-------- 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/proto/claim/params.proto b/proto/claim/params.proto index d08ad8b46..866631f36 100644 --- a/proto/claim/params.proto +++ b/proto/claim/params.proto @@ -15,6 +15,7 @@ message Params { // DecayInformation defines the information about decay for the airdrop // when claimable airdrop amount starts to decrease and when it ends message DecayInformation { - google.protobuf.Timestamp decayStart = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - google.protobuf.Timestamp decayEnd = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + bool enabled = 1; + google.protobuf.Timestamp decayStart = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + google.protobuf.Timestamp decayEnd = 3 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; } diff --git a/x/claim/types/decay.go b/x/claim/types/decay.go index cc2247d05..21844e222 100644 --- a/x/claim/types/decay.go +++ b/x/claim/types/decay.go @@ -6,7 +6,9 @@ import ( // Validate validates the decay information func (m DecayInformation) Validate() error { - if m.DecayStart.After(m.DecayEnd) { + if m.Enabled && m.DecayStart.After(m.DecayEnd) { return fmt.Errorf("decay starts after decay end %s > %s", m.DecayStart.String(), m.DecayEnd.String()) } + + return nil } diff --git a/x/claim/types/params.pb.go b/x/claim/types/params.pb.go index 8c54a4e53..c350a4d76 100644 --- a/x/claim/types/params.pb.go +++ b/x/claim/types/params.pb.go @@ -74,8 +74,9 @@ func (m *Params) GetDecayInformation() DecayInformation { // DecayInformation defines the information about decay for the airdrop // when claimable airdrop amount starts to decrease and when it ends type DecayInformation struct { - DecayStart time.Time `protobuf:"bytes,1,opt,name=decayStart,proto3,stdtime" json:"decayStart"` - DecayEnd time.Time `protobuf:"bytes,2,opt,name=decayEnd,proto3,stdtime" json:"decayEnd"` + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + DecayStart time.Time `protobuf:"bytes,2,opt,name=decayStart,proto3,stdtime" json:"decayStart"` + DecayEnd time.Time `protobuf:"bytes,3,opt,name=decayEnd,proto3,stdtime" json:"decayEnd"` } func (m *DecayInformation) Reset() { *m = DecayInformation{} } @@ -111,6 +112,13 @@ func (m *DecayInformation) XXX_DiscardUnknown() { var xxx_messageInfo_DecayInformation proto.InternalMessageInfo +func (m *DecayInformation) GetEnabled() bool { + if m != nil { + return m.Enabled + } + return false +} + func (m *DecayInformation) GetDecayStart() time.Time { if m != nil { return m.DecayStart @@ -133,7 +141,7 @@ func init() { func init() { proto.RegisterFile("claim/params.proto", fileDescriptor_adbfc9fc41f7a9d2) } var fileDescriptor_adbfc9fc41f7a9d2 = []byte{ - // 281 bytes of a gzipped FileDescriptorProto + // 300 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4a, 0xce, 0x49, 0xcc, 0xcc, 0xd5, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x29, 0x49, 0xcd, 0x4b, 0x49, 0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x2b, 0x2e, 0xc8, 0xd3, 0x03, @@ -143,15 +151,16 @@ var fileDescriptor_adbfc9fc41f7a9d2 = []byte{ 0x11, 0x5c, 0x02, 0x29, 0xa9, 0xc9, 0x89, 0x95, 0x9e, 0x79, 0x69, 0xf9, 0x45, 0xb9, 0x89, 0x25, 0x99, 0xf9, 0x79, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0x6a, 0x7a, 0xd8, 0x6c, 0xd4, 0x73, 0x41, 0x53, 0xed, 0xc4, 0x72, 0xe2, 0x9e, 0x3c, 0x43, 0x10, 0x86, 0x29, 0x56, 0x2c, 0x33, 0x16, - 0xc8, 0x33, 0x28, 0xcd, 0x62, 0xe4, 0x12, 0x40, 0xd7, 0x22, 0xe4, 0xc2, 0xc5, 0x05, 0x56, 0x1e, - 0x5c, 0x92, 0x58, 0x54, 0x02, 0xb5, 0x4e, 0x4a, 0x0f, 0xe2, 0x68, 0x3d, 0x98, 0xa3, 0xf5, 0x42, - 0x60, 0x8e, 0x76, 0xe2, 0x00, 0x59, 0x31, 0xe1, 0xbe, 0x3c, 0x63, 0x10, 0x92, 0x3e, 0x21, 0x07, - 0x2e, 0x0e, 0x30, 0xcf, 0x35, 0x2f, 0x45, 0x82, 0x89, 0x04, 0x33, 0xe0, 0xba, 0x9c, 0x1c, 0x4f, - 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, - 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x3d, 0x3d, 0xb3, 0x24, 0xa3, 0x34, - 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0x11, 0x0c, 0xfa, 0xc5, 0x05, 0x79, 0xfa, 0x15, 0xfa, 0x90, - 0xd8, 0x29, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0x5b, 0x65, 0x0c, 0x08, 0x00, 0x00, 0xff, - 0xff, 0x94, 0xad, 0x96, 0xfe, 0xb3, 0x01, 0x00, 0x00, + 0xc8, 0x33, 0x28, 0x6d, 0x61, 0xe4, 0x12, 0x40, 0xd7, 0x22, 0x24, 0xc1, 0xc5, 0x9e, 0x9a, 0x97, + 0x98, 0x94, 0x93, 0x9a, 0x02, 0xb6, 0x8b, 0x23, 0x08, 0xc6, 0x15, 0x72, 0xe1, 0xe2, 0x02, 0x1b, + 0x14, 0x5c, 0x92, 0x58, 0x54, 0x22, 0xc1, 0x04, 0x76, 0x88, 0x94, 0x1e, 0xc4, 0x3b, 0x7a, 0x30, + 0xef, 0xe8, 0x85, 0xc0, 0xbc, 0xe3, 0xc4, 0x01, 0xb2, 0x7c, 0xc2, 0x7d, 0x79, 0xc6, 0x20, 0x24, + 0x7d, 0x42, 0x0e, 0x5c, 0x1c, 0x60, 0x9e, 0x6b, 0x5e, 0x8a, 0x04, 0x33, 0x09, 0x66, 0xc0, 0x75, + 0x39, 0x39, 0x9e, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, + 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x7a, 0x7a, 0x66, + 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0x22, 0x80, 0xf4, 0x8b, 0x0b, 0xf2, 0xf4, + 0x2b, 0xf4, 0x21, 0xf1, 0x56, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0xb6, 0xca, 0x18, 0x10, + 0x00, 0x00, 0xff, 0xff, 0x64, 0x15, 0x99, 0xd0, 0xcd, 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -214,7 +223,7 @@ func (m *DecayInformation) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= n2 i = encodeVarintParams(dAtA, i, uint64(n2)) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a n3, err3 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.DecayStart, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.DecayStart):]) if err3 != nil { return 0, err3 @@ -222,7 +231,17 @@ func (m *DecayInformation) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= n3 i = encodeVarintParams(dAtA, i, uint64(n3)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x12 + if m.Enabled { + i-- + if m.Enabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -254,6 +273,9 @@ func (m *DecayInformation) Size() (n int) { } var l int _ = l + if m.Enabled { + n += 2 + } l = github_com_gogo_protobuf_types.SizeOfStdTime(m.DecayStart) n += 1 + l + sovParams(uint64(l)) l = github_com_gogo_protobuf_types.SizeOfStdTime(m.DecayEnd) @@ -380,6 +402,26 @@ func (m *DecayInformation) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Enabled = bool(v != 0) + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field DecayStart", wireType) } @@ -412,7 +454,7 @@ func (m *DecayInformation) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field DecayEnd", wireType) } From a165c8e854389809d92288f495f7d6a879ff13fb Mon Sep 17 00:00:00 2001 From: ltacker Date: Wed, 27 Jul 2022 13:34:45 +0200 Subject: [PATCH 04/13] decay info param --- x/claim/types/params.go | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/x/claim/types/params.go b/x/claim/types/params.go index 357196ad6..84308e897 100644 --- a/x/claim/types/params.go +++ b/x/claim/types/params.go @@ -1,35 +1,59 @@ package types import ( + "fmt" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "gopkg.in/yaml.v2" + "time" ) var _ paramtypes.ParamSet = (*Params)(nil) +var ( + KeyDecayInformation = []byte("DecayInformation") +) + // ParamKeyTable the param key table for launch module func ParamKeyTable() paramtypes.KeyTable { return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) } // NewParams creates a new Params instance -func NewParams() Params { - return Params{} +func NewParams(di DecayInformation) Params { + return Params{ + DecayInformation: di, + } } // DefaultParams returns a default set of parameters func DefaultParams() Params { - return NewParams() + return NewParams(DecayInformation{ + Enabled: false, + DecayStart: time.UnixMilli(0), + DecayEnd: time.UnixMilli(0), + }) } // ParamSetPairs get the params.ParamSet func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { - return paramtypes.ParamSetPairs{} + return paramtypes.ParamSetPairs{ + paramtypes.NewParamSetPair(KeyDecayInformation, &p.DecayInformation, validateDecayInformation), + } } // Validate validates the set of params func (p Params) Validate() error { - return nil + return validateDecayInformation(p.DecayInformation) +} + +// validateDecayInformation validates the DecayInformation param +func validateDecayInformation(v interface{}) error { + decayInfo, ok := v.(DecayInformation) + if !ok { + return fmt.Errorf("invalid parameter type: %T", v) + } + + return decayInfo.Validate() } // String implements the Stringer interface. From 037e7c1372f7a661a1d5a08c89ddf5fe8a90e92b Mon Sep 17 00:00:00 2001 From: ltacker Date: Wed, 27 Jul 2022 15:02:18 +0200 Subject: [PATCH 05/13] implement validate tests --- x/claim/types/decay_test.go | 61 ++++++++++++++++++++++++++ x/claim/types/genesis_test.go | 37 ++++++++++++++++ x/claim/types/params_test.go | 81 +++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 x/claim/types/decay_test.go create mode 100644 x/claim/types/params_test.go diff --git a/x/claim/types/decay_test.go b/x/claim/types/decay_test.go new file mode 100644 index 000000000..9f60e0628 --- /dev/null +++ b/x/claim/types/decay_test.go @@ -0,0 +1,61 @@ +package types_test + +import ( + "github.com/stretchr/testify/require" + "github.com/tendermint/spn/x/claim/types" + "testing" + "time" +) + +func TestDecayInformation_Validate(t *testing.T) { + tests := []struct { + name string + decayInfo types.DecayInformation + wantErr bool + }{ + { + name: "should validate decay information with disabled", + decayInfo: types.DecayInformation{ + Enabled: false, + DecayStart: time.UnixMilli(2000), + DecayEnd: time.UnixMilli(1000), + }, + }, + { + name: "should validate decay information with enabled and start equals to end", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.UnixMilli(1000), + DecayEnd: time.UnixMilli(1000), + }, + }, + { + name: "should validate decay information with enabled and end greater than start", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.UnixMilli(1000), + DecayEnd: time.UnixMilli(10000), + }, + }, + { + name: "should prevent validate decay information with enabled and start greater than end", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.UnixMilli(1001), + DecayEnd: time.UnixMilli(1000), + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.decayInfo.Validate() + + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/x/claim/types/genesis_test.go b/x/claim/types/genesis_test.go index f2737a200..a1f360011 100644 --- a/x/claim/types/genesis_test.go +++ b/x/claim/types/genesis_test.go @@ -2,6 +2,7 @@ package types_test import ( "testing" + "time" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" @@ -33,6 +34,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should validate airdrop supply sum of claim amounts", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -65,6 +67,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should allow genesis state with no airdrop supply", genState: &types.GenesisState{ + Params: types.DefaultParams(), Missions: []types.Mission{ { MissionID: 0, @@ -78,6 +81,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should allow genesis state with no mission", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -95,6 +99,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should allow mission with 0 weight", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -122,6 +127,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should allow claim record with completed missions", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -151,6 +157,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should allow claim record with missions all completed", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -180,6 +187,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should allow claim record with zero weight mission completed", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -209,6 +217,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should validate genesis state with initial claim enabled", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -236,6 +245,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should prevent validate duplicated claimRecord", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: "duplicate", @@ -259,6 +269,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should prevent validate claim record with non positive allocation", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -282,6 +293,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should prevent validate airdrop supply higher than sum of claim amounts", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -305,6 +317,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should prevent validate airdrop supply lower than sum of claim amounts", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -328,6 +341,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should prevent validate invalid airdrop supply with records with completed missions", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -356,6 +370,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should prevent validate claim record with non existing mission", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -380,6 +395,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should prevent validate invalid genesis supply coin", genState: &types.GenesisState{ + Params: types.DefaultParams(), AirdropSupply: sdk.Coin{}, Missions: []types.Mission{ { @@ -393,6 +409,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should prevent validate duplicated mission", genState: &types.GenesisState{ + Params: types.DefaultParams(), Missions: []types.Mission{ { MissionID: 0, @@ -409,6 +426,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should prevent validate mission list weights are not equal to 1", genState: &types.GenesisState{ + Params: types.DefaultParams(), Missions: []types.Mission{ { MissionID: 0, @@ -425,6 +443,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "should prevent validate initial claim enabled with non existing mission", genState: &types.GenesisState{ + Params: types.DefaultParams(), ClaimRecords: []types.ClaimRecord{ { Address: sample.Address(r), @@ -443,6 +462,24 @@ func TestGenesisState_Validate(t *testing.T) { }, valid: false, }, + { + desc: "should prevent validate genesis state with invalid param", + genState: &types.GenesisState{ + Params: types.NewParams(types.DecayInformation{ + Enabled: true, + DecayStart: time.UnixMilli(1001), + DecayEnd: time.UnixMilli(1000), + }), + Missions: []types.Mission{ + { + MissionID: 0, + Weight: sdk.OneDec(), + }, + }, + AirdropSupply: tc.Coin(t, "0foo"), + }, + valid: false, + }, // this line is used by starport scaffolding # types/genesis/testcase } { t.Run(tt.desc, func(t *testing.T) { diff --git a/x/claim/types/params_test.go b/x/claim/types/params_test.go new file mode 100644 index 000000000..f0cd551f9 --- /dev/null +++ b/x/claim/types/params_test.go @@ -0,0 +1,81 @@ +package types + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestParams_Validate(t *testing.T) { + tests := []struct { + name string + params Params + wantErr bool + }{ + { + name: "should prevent validate params with invalid decay information", + params: NewParams(DecayInformation{ + Enabled: true, + DecayStart: time.UnixMilli(1001), + DecayEnd: time.UnixMilli(1000), + }), + wantErr: true, + }, + { + name: "should validate valid params", + params: DefaultParams(), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.params.Validate() + + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestValidateDecayInformation(t *testing.T) { + tests := []struct { + name string + decayInformation interface{} + wantErr bool + }{ + { + name: "should prevent validate decay information with invalid interface", + decayInformation: "test", + wantErr: true, + }, + { + name: "should prevent validate invalid decay information", + decayInformation: DecayInformation{ + Enabled: true, + DecayStart: time.UnixMilli(1001), + DecayEnd: time.UnixMilli(1000), + }, + wantErr: true, + }, + { + name: "should validate valid decay information", + decayInformation: DecayInformation{ + Enabled: false, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateDecayInformation(tt.decayInformation) + + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} From 0202e2cf57856048b8968d6877d0b37182349e2e Mon Sep 17 00:00:00 2001 From: ltacker Date: Wed, 27 Jul 2022 15:29:53 +0200 Subject: [PATCH 06/13] decay factor --- x/claim/types/decay.go | 40 +++++++++++++++++++++++++++++++++++++ x/claim/types/decay_test.go | 24 ++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/x/claim/types/decay.go b/x/claim/types/decay.go index 21844e222..c9c55d43d 100644 --- a/x/claim/types/decay.go +++ b/x/claim/types/decay.go @@ -2,6 +2,8 @@ package types import ( "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" + "time" ) // Validate validates the decay information @@ -12,3 +14,41 @@ func (m DecayInformation) Validate() error { return nil } + +// ApplyDecayFactor reduces the coins depending on the decay factor from decay information +// coins decrease from decay start to zero at decay end +func (m DecayInformation) ApplyDecayFactor(coins sdk.Coins, currentTime time.Time) sdk.Coins { + // no decay factor applied + if coins.Empty() || !m.Enabled || currentTime.Before(m.DecayStart) { + return coins + } + + // coins reduced to 0 if decay ended + if currentTime.After(m.DecayEnd) { + return sdk.NewCoins() + } + + // calculate decay factor + timeToDec := func(t time.Time) sdk.Dec { + return sdk.NewDecFromInt(sdk.NewInt(t.Unix())) + } + + current, start, end := timeToDec(currentTime), timeToDec(m.DecayStart), timeToDec(m.DecayEnd) + + // (end-current)/(end-start) + decayFactor := (end.Sub(current)).Quo(end.Sub(start)) + + // apply decay factor to each denom + newCoins := sdk.NewCoins() + for _, coin := range coins { + amountDec := sdk.NewDecFromInt(coin.Amount) + newAmount := amountDec.Mul(decayFactor).TruncateInt() + + newCoins = append(newCoins, sdk.NewCoin( + coin.Denom, + newAmount, + )) + } + + return newCoins +} diff --git a/x/claim/types/decay_test.go b/x/claim/types/decay_test.go index 9f60e0628..1308dbcf2 100644 --- a/x/claim/types/decay_test.go +++ b/x/claim/types/decay_test.go @@ -1,6 +1,7 @@ package types_test import ( + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" "github.com/tendermint/spn/x/claim/types" "testing" @@ -59,3 +60,26 @@ func TestDecayInformation_Validate(t *testing.T) { }) } } + +func TestDecayInformation_ApplyDecayFactor(t *testing.T) { + tests := []struct { + name string + decayInfo types.DecayInformation + coins sdk.Coins + currentTime time.Time + expectedCoins sdk.Coins + }{ + {}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + newCoins := tt.decayInfo.ApplyDecayFactor(tt.coins, tt.currentTime) + + require.True(t, newCoins.IsEqual(tt.expectedCoins), + "new coins are not equal to expected coins, %s != %s", + newCoins.String(), + tt.expectedCoins.String(), + ) + }) + } +} From 9b1bea7a18f0717b6eb9e8742c5fb9263ee40250 Mon Sep 17 00:00:00 2001 From: ltacker Date: Wed, 27 Jul 2022 15:56:45 +0200 Subject: [PATCH 07/13] add apply tests --- x/claim/types/decay.go | 14 +++-- x/claim/types/decay_test.go | 109 +++++++++++++++++++++++++++++++++++- 2 files changed, 116 insertions(+), 7 deletions(-) diff --git a/x/claim/types/decay.go b/x/claim/types/decay.go index c9c55d43d..ff744dab2 100644 --- a/x/claim/types/decay.go +++ b/x/claim/types/decay.go @@ -24,7 +24,7 @@ func (m DecayInformation) ApplyDecayFactor(coins sdk.Coins, currentTime time.Tim } // coins reduced to 0 if decay ended - if currentTime.After(m.DecayEnd) { + if currentTime.Equal(m.DecayEnd) || currentTime.After(m.DecayEnd) { return sdk.NewCoins() } @@ -44,11 +44,13 @@ func (m DecayInformation) ApplyDecayFactor(coins sdk.Coins, currentTime time.Tim amountDec := sdk.NewDecFromInt(coin.Amount) newAmount := amountDec.Mul(decayFactor).TruncateInt() - newCoins = append(newCoins, sdk.NewCoin( - coin.Denom, - newAmount, - )) + if !newAmount.IsZero() { + newCoins = append(newCoins, sdk.NewCoin( + coin.Denom, + newAmount, + )) + } } - return newCoins + return newCoins.Sort() } diff --git a/x/claim/types/decay_test.go b/x/claim/types/decay_test.go index 1308dbcf2..9aa984542 100644 --- a/x/claim/types/decay_test.go +++ b/x/claim/types/decay_test.go @@ -3,6 +3,7 @@ package types_test import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + tc "github.com/tendermint/spn/testutil/constructor" "github.com/tendermint/spn/x/claim/types" "testing" "time" @@ -69,7 +70,113 @@ func TestDecayInformation_ApplyDecayFactor(t *testing.T) { currentTime time.Time expectedCoins sdk.Coins }{ - {}, + { + name: "should apply no change if decay disabled", + decayInfo: types.DecayInformation{ + Enabled: false, + }, + coins: tc.Coins(t, "100foo,100bar"), + expectedCoins: tc.Coins(t, "100foo,100bar"), + }, + { + name: "should apply no change if decay not started", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.Unix(1000, 0), + DecayEnd: time.Unix(10000, 0), + }, + currentTime: time.Unix(500, 0), + coins: tc.Coins(t, "100foo,100bar"), + expectedCoins: tc.Coins(t, "100foo,100bar"), + }, + { + name: "should return zero coins if end of decay", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.Unix(1000, 0), + DecayEnd: time.Unix(10000, 0), + }, + currentTime: time.Unix(10000, 0), + coins: tc.Coins(t, "100foo,100bar"), + expectedCoins: sdk.NewCoins(), + }, + { + name: "should return zero coins if end of decay without start", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.Unix(10000, 0), + DecayEnd: time.Unix(10000, 0), + }, + currentTime: time.Unix(10000, 0), + coins: tc.Coins(t, "100foo,100bar"), + expectedCoins: sdk.NewCoins(), + }, + { + name: "should return zero coins if decay ended", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.Unix(1000, 0), + DecayEnd: time.Unix(10000, 0), + }, + currentTime: time.Unix(10001, 0), + coins: tc.Coins(t, "100foo,100bar"), + expectedCoins: sdk.NewCoins(), + }, + { + name: "should apply half decay factor", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.Unix(10000, 0), + DecayEnd: time.Unix(20000, 0), + }, + currentTime: time.Unix(15000, 0), + coins: tc.Coins(t, "200000foo,2000000bar"), + expectedCoins: tc.Coins(t, "100000foo,1000000bar"), + }, + { + name: "should apply 0.6 decay factor", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.Unix(10000, 0), + DecayEnd: time.Unix(20000, 0), + }, + currentTime: time.Unix(14000, 0), + coins: tc.Coins(t, "100000foo,1000000bar"), + expectedCoins: tc.Coins(t, "60000foo,600000bar"), + }, + { + name: "should apply 0.2 decay factor", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.Unix(10000, 0), + DecayEnd: time.Unix(20000, 0), + }, + currentTime: time.Unix(18000, 0), + coins: tc.Coins(t, "100000foo,1000000bar"), + expectedCoins: tc.Coins(t, "20000foo,200000bar"), + }, + { + name: "should apply decay factor and truncate decimals", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.Unix(10000, 0), + DecayEnd: time.Unix(20000, 0), + }, + currentTime: time.Unix(15000, 0), + coins: tc.Coins(t, "100000foo,1bar,1000000000003baz"), + expectedCoins: tc.Coins(t, "50000foo,500000000001baz"), + }, + { + name: "should return ze coins if factor applied to zero coins", + decayInfo: types.DecayInformation{ + Enabled: true, + DecayStart: time.Unix(10000, 0), + DecayEnd: time.Unix(20000, 0), + }, + currentTime: time.Unix(15000, 0), + coins: sdk.NewCoins(), + expectedCoins: sdk.NewCoins(), + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From fec84415d7c9232efb68d2d30fbd4aaa491aa5eb Mon Sep 17 00:00:00 2001 From: ltacker Date: Sat, 30 Jul 2022 18:07:05 +0200 Subject: [PATCH 08/13] fix test --- testutil/keeper/initializer.go | 2 +- x/claim/keeper/params.go | 11 +++++++++-- x/claim/keeper/params_test.go | 8 +++++--- x/claim/types/decay.go | 10 ++++++++++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/testutil/keeper/initializer.go b/testutil/keeper/initializer.go index 779c58123..cde8a4d42 100644 --- a/testutil/keeper/initializer.go +++ b/testutil/keeper/initializer.go @@ -443,7 +443,7 @@ func (i initializer) Claim( i.StateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil) paramKeeper.Subspace(claimtypes.ModuleName) - subspace, _ := paramKeeper.GetSubspace(participationtypes.ModuleName) + subspace, _ := paramKeeper.GetSubspace(claimtypes.ModuleName) return claimkeeper.NewKeeper( i.Codec, diff --git a/x/claim/keeper/params.go b/x/claim/keeper/params.go index 4a910cc00..b6e0d444e 100644 --- a/x/claim/keeper/params.go +++ b/x/claim/keeper/params.go @@ -7,11 +7,18 @@ import ( ) // GetParams get all parameters as types.Params -func (k Keeper) GetParams(ctx sdk.Context) types.Params { - return types.NewParams() +func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { + k.paramstore.GetParamSet(ctx, ¶ms) + return params } // SetParams set the params func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { k.paramstore.SetParamSet(ctx, ¶ms) } + +// DecayInformation returns the param that defines decay information +func (k Keeper) DecayInformation(ctx sdk.Context) (totalSupplyRange types.DecayInformation) { + k.paramstore.Get(ctx, types.KeyDecayInformation, &totalSupplyRange) + return +} diff --git a/x/claim/keeper/params_test.go b/x/claim/keeper/params_test.go index 1e12e51d0..dbaca897d 100644 --- a/x/claim/keeper/params_test.go +++ b/x/claim/keeper/params_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -12,9 +13,10 @@ import ( func TestGetParams(t *testing.T) { ctx, tk, _ := testkeeper.NewTestSetup(t) - params := types.DefaultParams() - + params := types.NewParams(types.NewEnabledDecay( + time.Unix(1000, 0), + time.Unix(10000, 0), + )) tk.ClaimKeeper.SetParams(ctx, params) - require.EqualValues(t, params, tk.ClaimKeeper.GetParams(ctx)) } diff --git a/x/claim/types/decay.go b/x/claim/types/decay.go index ff744dab2..717f42f5a 100644 --- a/x/claim/types/decay.go +++ b/x/claim/types/decay.go @@ -6,6 +6,16 @@ import ( "time" ) +// NewEnabledDecay returns decay information with a decay start and end +func NewEnabledDecay(start, end time.Time) DecayInformation { + // convert all time to UTC + return DecayInformation{ + Enabled: true, + DecayStart: start.UTC(), + DecayEnd: end.UTC(), + } +} + // Validate validates the decay information func (m DecayInformation) Validate() error { if m.Enabled && m.DecayStart.After(m.DecayEnd) { From 4d410963c7b6927459a3cf7983e8d54638e8a8e5 Mon Sep 17 00:00:00 2001 From: ltacker Date: Fri, 5 Aug 2022 15:19:09 +0200 Subject: [PATCH 09/13] decay constructors --- x/claim/types/decay.go | 13 ++++++++++++- x/claim/types/decay_test.go | 14 ++++++++++++++ x/claim/types/params.go | 7 +------ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/x/claim/types/decay.go b/x/claim/types/decay.go index 717f42f5a..8c2315869 100644 --- a/x/claim/types/decay.go +++ b/x/claim/types/decay.go @@ -2,10 +2,21 @@ package types import ( "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" "time" + + sdk "github.com/cosmos/cosmos-sdk/types" ) +// NewDisabledDecay returns decay information with disabled decay +func NewDisabledDecay() DecayInformation { + // convert all time to UTC + return DecayInformation{ + Enabled: false, + DecayStart: time.UnixMilli(0).UTC(), + DecayEnd: time.UnixMilli(0).UTC(), + } +} + // NewEnabledDecay returns decay information with a decay start and end func NewEnabledDecay(start, end time.Time) DecayInformation { // convert all time to UTC diff --git a/x/claim/types/decay_test.go b/x/claim/types/decay_test.go index 9aa984542..6fe05d117 100644 --- a/x/claim/types/decay_test.go +++ b/x/claim/types/decay_test.go @@ -9,6 +9,20 @@ import ( "time" ) +func TestNewDisabledDecay(t *testing.T) { + decayInfo := types.NewDisabledDecay() + require.False(t, decayInfo.Enabled) +} + +func TestNewEnabledDecay(t *testing.T) { + start := time.UnixMilli(1000) + end := time.UnixMilli(2000) + decayInfo := types.NewEnabledDecay(start, end) + require.True(t, decayInfo.Enabled) + require.True(t, decayInfo.DecayStart.Equal(start)) + require.True(t, decayInfo.DecayEnd.Equal(end)) +} + func TestDecayInformation_Validate(t *testing.T) { tests := []struct { name string diff --git a/x/claim/types/params.go b/x/claim/types/params.go index 84308e897..fb93bdca9 100644 --- a/x/claim/types/params.go +++ b/x/claim/types/params.go @@ -4,7 +4,6 @@ import ( "fmt" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "gopkg.in/yaml.v2" - "time" ) var _ paramtypes.ParamSet = (*Params)(nil) @@ -27,11 +26,7 @@ func NewParams(di DecayInformation) Params { // DefaultParams returns a default set of parameters func DefaultParams() Params { - return NewParams(DecayInformation{ - Enabled: false, - DecayStart: time.UnixMilli(0), - DecayEnd: time.UnixMilli(0), - }) + return NewParams(NewDisabledDecay()) } // ParamSetPairs get the params.ParamSet From bd75965706d4aab71b716ea06ad1e21eba7deff4 Mon Sep 17 00:00:00 2001 From: ltacker Date: Fri, 5 Aug 2022 15:31:58 +0200 Subject: [PATCH 10/13] apply decay factor --- x/claim/keeper/mission.go | 11 +++++++++++ x/claim/types/errors.go | 1 + 2 files changed, 12 insertions(+) diff --git a/x/claim/keeper/mission.go b/x/claim/keeper/mission.go index 5f46b3699..3d93d0cbe 100644 --- a/x/claim/keeper/mission.go +++ b/x/claim/keeper/mission.go @@ -93,6 +93,17 @@ func (k Keeper) CompleteMission(ctx sdk.Context, missionID uint64, address strin claimableAmount := claimRecord.ClaimableFromMission(mission) claimable := sdk.NewCoins(sdk.NewCoin(airdropSupply.Denom, claimableAmount)) + // calculate claimable after decay factor + decayInfo := k.DecayInformation(ctx) + if decayInfo.Enabled { + claimable = decayInfo.ApplyDecayFactor(claimable, ctx.BlockTime()) + } + + // check final claimable non-zero + if claimable.Empty() { + return types.ErrNoClaimable + } + // decrease airdrop supply airdropSupply.Amount = airdropSupply.Amount.Sub(claimableAmount) if airdropSupply.Amount.IsNegative() { diff --git a/x/claim/types/errors.go b/x/claim/types/errors.go index 53da14b77..fd224d13a 100644 --- a/x/claim/types/errors.go +++ b/x/claim/types/errors.go @@ -15,4 +15,5 @@ var ( ErrInitialClaimNotFound = sdkerrors.Register(ModuleName, 6, "initial claim information not found") ErrInitialClaimNotEnabled = sdkerrors.Register(ModuleName, 7, "initial claim not enabled") ErrMissionCompleteFailure = sdkerrors.Register(ModuleName, 8, "mission failed to complete") + ErrNoClaimable = sdkerrors.Register(ModuleName, 9, "no amount to be claimed") ) From f452b3d6029e4f7d677b479b2069a89986cd9176 Mon Sep 17 00:00:00 2001 From: ltacker Date: Fri, 5 Aug 2022 16:06:09 +0200 Subject: [PATCH 11/13] decay tests --- x/claim/keeper/mission.go | 2 +- x/claim/keeper/mission_test.go | 102 ++++++++++++++++++++++++++++++--- 2 files changed, 95 insertions(+), 9 deletions(-) diff --git a/x/claim/keeper/mission.go b/x/claim/keeper/mission.go index 3d93d0cbe..fa561b79c 100644 --- a/x/claim/keeper/mission.go +++ b/x/claim/keeper/mission.go @@ -105,7 +105,7 @@ func (k Keeper) CompleteMission(ctx sdk.Context, missionID uint64, address strin } // decrease airdrop supply - airdropSupply.Amount = airdropSupply.Amount.Sub(claimableAmount) + airdropSupply.Amount = airdropSupply.Amount.Sub(claimable.AmountOf(airdropSupply.Denom)) if airdropSupply.Amount.IsNegative() { return spnerrors.Critical("airdrop supply is lower than total claimable") } diff --git a/x/claim/keeper/mission_test.go b/x/claim/keeper/mission_test.go index 0d5f415fc..0e0fe48c7 100644 --- a/x/claim/keeper/mission_test.go +++ b/x/claim/keeper/mission_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "testing" + "time" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" @@ -70,6 +71,8 @@ func TestKeeper_CompleteMission(t *testing.T) { airdropSupply sdk.Coin mission types.Mission claimRecord types.ClaimRecord + params types.Params + blockTime time.Time } // prepare addresses @@ -92,6 +95,7 @@ func TestKeeper_CompleteMission(t *testing.T) { noAirdropSupply: true, claimRecord: sample.ClaimRecord(r), mission: sample.Mission(r), + params: types.DefaultParams(), }, missionID: 1, address: sample.Address(r), @@ -107,6 +111,7 @@ func TestKeeper_CompleteMission(t *testing.T) { Claimable: sdk.OneInt(), CompletedMissions: []uint64{1}, }, + params: types.DefaultParams(), }, missionID: 1, address: addr[0], @@ -121,6 +126,7 @@ func TestKeeper_CompleteMission(t *testing.T) { MissionID: 1, Weight: sdk.OneDec(), }, + params: types.DefaultParams(), }, missionID: 1, address: sample.Address(r), @@ -139,6 +145,7 @@ func TestKeeper_CompleteMission(t *testing.T) { Claimable: sdk.OneInt(), CompletedMissions: []uint64{1}, }, + params: types.DefaultParams(), }, missionID: 1, address: addr[1], @@ -156,6 +163,7 @@ func TestKeeper_CompleteMission(t *testing.T) { Address: addr[2], Claimable: sdk.NewIntFromUint64(10000), }, + params: types.DefaultParams(), }, missionID: 1, address: addr[2], @@ -173,6 +181,7 @@ func TestKeeper_CompleteMission(t *testing.T) { Address: "invalid", Claimable: sdk.OneInt(), }, + params: types.DefaultParams(), }, missionID: 1, address: "invalid", @@ -190,13 +199,14 @@ func TestKeeper_CompleteMission(t *testing.T) { Address: addr[3], Claimable: sdk.NewIntFromUint64(1000), }, + params: types.DefaultParams(), }, missionID: 1, address: addr[3], expectedBalance: tc.Coin(t, "1000foo"), }, { - name: "should allow distributing no fund for mission with 0 weight", + name: "should prevent distributing fund for mission with 0 weight", inputState: inputState{ airdropSupply: tc.Coin(t, "1000foo"), mission: types.Mission{ @@ -207,10 +217,11 @@ func TestKeeper_CompleteMission(t *testing.T) { Address: addr[4], Claimable: sdk.NewIntFromUint64(1000), }, + params: types.DefaultParams(), }, - missionID: 1, - address: addr[4], - expectedBalance: tc.Coin(t, "0foo"), + missionID: 1, + address: addr[4], + err: types.ErrNoClaimable, }, { name: "should allow distributing half for mission with 0.5 weight", @@ -224,6 +235,7 @@ func TestKeeper_CompleteMission(t *testing.T) { Address: addr[5], Claimable: sdk.NewIntFromUint64(500), }, + params: types.DefaultParams(), }, missionID: 1, address: addr[5], @@ -241,13 +253,14 @@ func TestKeeper_CompleteMission(t *testing.T) { Address: addr[6], Claimable: sdk.NewIntFromUint64(201), }, + params: types.DefaultParams(), }, missionID: 1, address: addr[6], expectedBalance: tc.Coin(t, "100foo"), }, { - name: "should allow distributing no fund for empty claim record", + name: "should prevent distributing fund for empty claim record", inputState: inputState{ airdropSupply: tc.Coin(t, "1000foo"), mission: types.Mission{ @@ -258,10 +271,11 @@ func TestKeeper_CompleteMission(t *testing.T) { Address: addr[7], Claimable: sdk.ZeroInt(), }, + params: types.DefaultParams(), }, - missionID: 1, - address: addr[7], - expectedBalance: tc.Coin(t, "0foo"), + missionID: 1, + address: addr[7], + err: types.ErrNoClaimable, }, { name: "should allow distributing airdrop with other already completed missions", @@ -276,15 +290,84 @@ func TestKeeper_CompleteMission(t *testing.T) { Claimable: sdk.NewIntFromUint64(10000), CompletedMissions: []uint64{0, 1, 2, 4, 5, 6}, }, + params: types.DefaultParams(), }, missionID: 3, address: addr[8], expectedBalance: tc.Coin(t, "3000bar"), }, + { + name: "should allow applying decay factor if enabled", + inputState: inputState{ + airdropSupply: tc.Coin(t, "1000foo"), + mission: types.Mission{ + MissionID: 1, + Weight: tc.Dec(t, "0.5"), + }, + claimRecord: types.ClaimRecord{ + Address: addr[9], + Claimable: sdk.NewIntFromUint64(1000), + }, + params: types.NewParams(types.NewEnabledDecay( + time.Unix(1000, 0), + time.Unix(2000, 0), + )), + blockTime: time.Unix(1500, 0), + }, + missionID: 1, + address: addr[9], + expectedBalance: tc.Coin(t, "250foo"), + }, + { + name: "should allow distributing all funds if decay factor if enabled and decay not started", + inputState: inputState{ + airdropSupply: tc.Coin(t, "1000foo"), + mission: types.Mission{ + MissionID: 1, + Weight: tc.Dec(t, "0.5"), + }, + claimRecord: types.ClaimRecord{ + Address: addr[10], + Claimable: sdk.NewIntFromUint64(1000), + }, + params: types.NewParams(types.NewEnabledDecay( + time.Unix(1000, 0), + time.Unix(2000, 0), + )), + blockTime: time.Unix(999, 0), + }, + missionID: 1, + address: addr[10], + expectedBalance: tc.Coin(t, "500foo"), + }, + { + name: "should prevent distributing funds if decay ended", + inputState: inputState{ + airdropSupply: tc.Coin(t, "1000foo"), + mission: types.Mission{ + MissionID: 1, + Weight: tc.Dec(t, "0.5"), + }, + claimRecord: types.ClaimRecord{ + Address: addr[11], + Claimable: sdk.NewIntFromUint64(1000), + }, + params: types.NewParams(types.NewEnabledDecay( + time.Unix(1000, 0), + time.Unix(2000, 0), + )), + blockTime: time.Unix(2001, 0), + }, + missionID: 1, + address: addr[11], + err: types.ErrNoClaimable, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // initialize input state + require.NoError(t, tt.inputState.params.Validate()) + tk.ClaimKeeper.SetParams(ctx, tt.inputState.params) if !tt.inputState.noAirdropSupply { err := tk.ClaimKeeper.InitializeAirdropSupply(ctx, tt.inputState.airdropSupply) require.NoError(t, err) @@ -295,6 +378,9 @@ func TestKeeper_CompleteMission(t *testing.T) { if !tt.inputState.noClaimRecord { tk.ClaimKeeper.SetClaimRecord(ctx, tt.inputState.claimRecord) } + if !tt.inputState.blockTime.IsZero() { + ctx = ctx.WithBlockTime(tt.inputState.blockTime) + } err := tk.ClaimKeeper.CompleteMission(ctx, tt.missionID, tt.address) if tt.err != nil { From 9b2dc101b07c08076a3dd5ac6a42be9e3377465d Mon Sep 17 00:00:00 2001 From: ltacker Date: Fri, 5 Aug 2022 16:13:33 +0200 Subject: [PATCH 12/13] remove unnecessary condition --- x/claim/keeper/mission.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/x/claim/keeper/mission.go b/x/claim/keeper/mission.go index fa561b79c..fe264d693 100644 --- a/x/claim/keeper/mission.go +++ b/x/claim/keeper/mission.go @@ -95,9 +95,7 @@ func (k Keeper) CompleteMission(ctx sdk.Context, missionID uint64, address strin // calculate claimable after decay factor decayInfo := k.DecayInformation(ctx) - if decayInfo.Enabled { - claimable = decayInfo.ApplyDecayFactor(claimable, ctx.BlockTime()) - } + claimable = decayInfo.ApplyDecayFactor(claimable, ctx.BlockTime()) // check final claimable non-zero if claimable.Empty() { From a0a8a78b3e7d7823b60ce6ded724e162a9e48929 Mon Sep 17 00:00:00 2001 From: ltacker Date: Wed, 10 Aug 2022 14:07:55 +0200 Subject: [PATCH 13/13] format --- testutil/gen_app.go | 5 +++-- x/claim/types/decay_test.go | 6 ++++-- x/claim/types/params.go | 1 + x/mint/keeper/integration_test.go | 6 ++++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/testutil/gen_app.go b/testutil/gen_app.go index 6a2d73cac..913b9efb9 100644 --- a/testutil/gen_app.go +++ b/testutil/gen_app.go @@ -13,11 +13,12 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - spnapp "github.com/tendermint/spn/app" - "github.com/tendermint/spn/cmd" "github.com/tendermint/tendermint/libs/log" tmtypes "github.com/tendermint/tendermint/types" dbm "github.com/tendermint/tm-db" + + spnapp "github.com/tendermint/spn/app" + "github.com/tendermint/spn/cmd" ) func GenApp(withGenesis bool, invCheckPeriod uint) (*spnapp.App, spnapp.GenesisState) { diff --git a/x/claim/types/decay_test.go b/x/claim/types/decay_test.go index 6fe05d117..ab68b2bb0 100644 --- a/x/claim/types/decay_test.go +++ b/x/claim/types/decay_test.go @@ -1,12 +1,14 @@ package types_test import ( + "testing" + "time" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + tc "github.com/tendermint/spn/testutil/constructor" "github.com/tendermint/spn/x/claim/types" - "testing" - "time" ) func TestNewDisabledDecay(t *testing.T) { diff --git a/x/claim/types/params.go b/x/claim/types/params.go index fb93bdca9..29cf213bc 100644 --- a/x/claim/types/params.go +++ b/x/claim/types/params.go @@ -2,6 +2,7 @@ package types import ( "fmt" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "gopkg.in/yaml.v2" ) diff --git a/x/mint/keeper/integration_test.go b/x/mint/keeper/integration_test.go index f1c14b0a8..34b7234d4 100644 --- a/x/mint/keeper/integration_test.go +++ b/x/mint/keeper/integration_test.go @@ -2,13 +2,15 @@ package keeper_test import ( "encoding/json" + "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + abci "github.com/tendermint/tendermint/abci/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + spnapp "github.com/tendermint/spn/app" "github.com/tendermint/spn/testutil" "github.com/tendermint/spn/x/mint/types" - abci "github.com/tendermint/tendermint/abci/types" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) // returns context and an app with updated mint keeper