From 33f7dafbd20f756759aa3691670ae6f4f65b8d40 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 31 Aug 2023 18:11:17 +0200 Subject: [PATCH 1/5] feat!: Add start time for continuous vesting accounts --- api/cosmos/vesting/v1beta1/tx.pulsar.go | 241 ++++++++++++------- proto/cosmos/vesting/v1beta1/tx.proto | 2 + x/auth/vesting/client/cli/tx.go | 10 +- x/auth/vesting/msg_server.go | 14 +- x/auth/vesting/types/msgs.go | 3 +- x/auth/vesting/types/tx.pb.go | 118 ++++++--- x/auth/vesting/types/vesting_account_test.go | 58 +++-- 7 files changed, 295 insertions(+), 151 deletions(-) diff --git a/api/cosmos/vesting/v1beta1/tx.pulsar.go b/api/cosmos/vesting/v1beta1/tx.pulsar.go index 3b6e23692bf3..1b2f5e15eb20 100644 --- a/api/cosmos/vesting/v1beta1/tx.pulsar.go +++ b/api/cosmos/vesting/v1beta1/tx.pulsar.go @@ -75,6 +75,7 @@ var ( fd_MsgCreateVestingAccount_amount protoreflect.FieldDescriptor fd_MsgCreateVestingAccount_end_time protoreflect.FieldDescriptor fd_MsgCreateVestingAccount_delayed protoreflect.FieldDescriptor + fd_MsgCreateVestingAccount_start_time protoreflect.FieldDescriptor ) func init() { @@ -85,6 +86,7 @@ func init() { fd_MsgCreateVestingAccount_amount = md_MsgCreateVestingAccount.Fields().ByName("amount") fd_MsgCreateVestingAccount_end_time = md_MsgCreateVestingAccount.Fields().ByName("end_time") fd_MsgCreateVestingAccount_delayed = md_MsgCreateVestingAccount.Fields().ByName("delayed") + fd_MsgCreateVestingAccount_start_time = md_MsgCreateVestingAccount.Fields().ByName("start_time") } var _ protoreflect.Message = (*fastReflection_MsgCreateVestingAccount)(nil) @@ -182,6 +184,12 @@ func (x *fastReflection_MsgCreateVestingAccount) Range(f func(protoreflect.Field return } } + if x.StartTime != int64(0) { + value := protoreflect.ValueOfInt64(x.StartTime) + if !f(fd_MsgCreateVestingAccount_start_time, value) { + return + } + } } // Has reports whether a field is populated. @@ -207,6 +215,8 @@ func (x *fastReflection_MsgCreateVestingAccount) Has(fd protoreflect.FieldDescri return x.EndTime != int64(0) case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.delayed": return x.Delayed != false + case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.start_time": + return x.StartTime != int64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.vesting.v1beta1.MsgCreateVestingAccount")) @@ -233,6 +243,8 @@ func (x *fastReflection_MsgCreateVestingAccount) Clear(fd protoreflect.FieldDesc x.EndTime = int64(0) case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.delayed": x.Delayed = false + case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.start_time": + x.StartTime = int64(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.vesting.v1beta1.MsgCreateVestingAccount")) @@ -267,6 +279,9 @@ func (x *fastReflection_MsgCreateVestingAccount) Get(descriptor protoreflect.Fie case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.delayed": value := x.Delayed return protoreflect.ValueOfBool(value) + case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.start_time": + value := x.StartTime + return protoreflect.ValueOfInt64(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.vesting.v1beta1.MsgCreateVestingAccount")) @@ -299,6 +314,8 @@ func (x *fastReflection_MsgCreateVestingAccount) Set(fd protoreflect.FieldDescri x.EndTime = value.Int() case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.delayed": x.Delayed = value.Bool() + case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.start_time": + x.StartTime = value.Int() default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.vesting.v1beta1.MsgCreateVestingAccount")) @@ -333,6 +350,8 @@ func (x *fastReflection_MsgCreateVestingAccount) Mutable(fd protoreflect.FieldDe panic(fmt.Errorf("field end_time of message cosmos.vesting.v1beta1.MsgCreateVestingAccount is not mutable")) case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.delayed": panic(fmt.Errorf("field delayed of message cosmos.vesting.v1beta1.MsgCreateVestingAccount is not mutable")) + case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.start_time": + panic(fmt.Errorf("field start_time of message cosmos.vesting.v1beta1.MsgCreateVestingAccount is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.vesting.v1beta1.MsgCreateVestingAccount")) @@ -357,6 +376,8 @@ func (x *fastReflection_MsgCreateVestingAccount) NewField(fd protoreflect.FieldD return protoreflect.ValueOfInt64(int64(0)) case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.delayed": return protoreflect.ValueOfBool(false) + case "cosmos.vesting.v1beta1.MsgCreateVestingAccount.start_time": + return protoreflect.ValueOfInt64(int64(0)) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.vesting.v1beta1.MsgCreateVestingAccount")) @@ -446,6 +467,9 @@ func (x *fastReflection_MsgCreateVestingAccount) ProtoMethods() *protoiface.Meth if x.Delayed { n += 2 } + if x.StartTime != 0 { + n += 1 + runtime.Sov(uint64(x.StartTime)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -475,6 +499,11 @@ func (x *fastReflection_MsgCreateVestingAccount) ProtoMethods() *protoiface.Meth i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if x.StartTime != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.StartTime)) + i-- + dAtA[i] = 0x30 + } if x.Delayed { i-- if x.Delayed { @@ -706,6 +735,25 @@ func (x *fastReflection_MsgCreateVestingAccount) ProtoMethods() *protoiface.Meth } } x.Delayed = bool(v != 0) + case 6: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field StartTime", wireType) + } + x.StartTime = 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.StartTime |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -3127,6 +3175,8 @@ type MsgCreateVestingAccount struct { // end of vesting as unix time (in seconds). EndTime int64 `protobuf:"varint,4,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` Delayed bool `protobuf:"varint,5,opt,name=delayed,proto3" json:"delayed,omitempty"` + // start of vesting as unix time (in seconds). + StartTime int64 `protobuf:"varint,6,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` } func (x *MsgCreateVestingAccount) Reset() { @@ -3184,6 +3234,13 @@ func (x *MsgCreateVestingAccount) GetDelayed() bool { return false } +func (x *MsgCreateVestingAccount) GetStartTime() int64 { + if x != nil { + return x.StartTime + } + return 0 +} + // MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type. type MsgCreateVestingAccountResponse struct { state protoimpl.MessageState @@ -3405,7 +3462,7 @@ var file_cosmos_vesting_v1beta1_tx_proto_rawDesc = []byte{ 0x61, 0x31, 0x2f, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, - 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfd, 0x02, 0x0a, + 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9c, 0x03, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, @@ -3425,100 +3482,102 @@ var file_cosmos_vesting_v1beta1_tx_proto_rawDesc = []byte{ 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x3a, 0x3c, - 0xe8, 0xa0, 0x1f, 0x01, 0x82, 0xe7, 0xb0, 0x2a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x22, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, - 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x21, 0x0a, 0x1f, - 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0xcf, 0x02, 0x0a, 0x1f, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, + 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x3a, 0x3c, 0xe8, + 0xa0, 0x1f, 0x01, 0x82, 0xe7, 0xb0, 0x2a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x22, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, + 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x21, 0x0a, 0x1f, 0x4d, + 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xcf, + 0x02, 0x0a, 0x1f, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, + 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x3a, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x17, 0xf2, 0xde, 0x1f, 0x13, 0x79, 0x61, + 0x6d, 0x6c, 0x3a, 0x22, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x22, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x34, + 0x0a, 0x0a, 0x74, 0x6f, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x15, 0xf2, 0xde, 0x1f, 0x11, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x74, 0x6f, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x52, 0x09, 0x74, 0x6f, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x79, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, + 0x20, 0x03, 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, + 0x46, 0xc8, 0xde, 0x1f, 0x00, 0xaa, 0xdf, 0x1f, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x69, 0x6e, + 0x73, 0x9a, 0xe7, 0xb0, 0x2a, 0x0c, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x69, + 0x6e, 0x73, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x3a, + 0x3f, 0xe8, 0xa0, 0x1f, 0x01, 0x82, 0xe7, 0xb0, 0x2a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x25, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, + 0x65, 0x72, 0x6d, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x22, 0x29, 0x0a, 0x27, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x12, 0x3a, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x17, 0xf2, 0xde, 0x1f, 0x13, 0x79, - 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x22, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x34, 0x0a, 0x0a, 0x74, 0x6f, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x15, 0xf2, 0xde, 0x1f, 0x11, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x74, - 0x6f, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x52, 0x09, 0x74, 0x6f, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x79, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x03, 0x20, 0x03, 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, 0x46, 0xc8, 0xde, 0x1f, 0x00, 0xaa, 0xdf, 0x1f, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x69, - 0x6e, 0x73, 0x9a, 0xe7, 0xb0, 0x2a, 0x0c, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x63, 0x6f, - 0x69, 0x6e, 0x73, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x3a, 0x3f, 0xe8, 0xa0, 0x1f, 0x01, 0x82, 0xe7, 0xb0, 0x2a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x25, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x50, 0x65, 0x72, 0x6d, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x22, 0x29, 0x0a, 0x27, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, - 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x97, 0x02, 0x0a, - 0x1f, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, - 0x69, 0x63, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, - 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, - 0x69, 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, - 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x65, - 0x72, 0x69, 0x6f, 0x64, 0x73, 0x3a, 0x3f, 0xe8, 0xa0, 0x1f, 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x0c, - 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, - 0x25, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x56, 0x65, 0x73, 0x74, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x29, 0x0a, 0x27, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x56, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x32, 0xc5, 0x03, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x80, 0x01, 0x0a, 0x14, 0x43, 0x72, + 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x97, 0x02, 0x0a, 0x1f, + 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, + 0x63, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x52, 0x0a, 0x0f, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, 0x69, + 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, + 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, + 0x69, 0x6f, 0x64, 0x73, 0x3a, 0x3f, 0xe8, 0xa0, 0x1f, 0x00, 0x82, 0xe7, 0xb0, 0x2a, 0x0c, 0x66, + 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x25, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x56, 0x65, 0x73, 0x74, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x29, 0x0a, 0x27, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x32, 0xc5, 0x03, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x80, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, + 0x6e, 0x74, 0x1a, 0x37, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x1a, 0x37, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x98, 0x01, 0x0a, - 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, - 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x3f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, - 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, - 0x64, 0x69, 0x63, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x1a, 0x3f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x56, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xd7, 0x01, 0x0a, 0x1a, 0x63, 0x6f, - 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, - 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x76, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x76, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x56, - 0x58, 0xaa, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x67, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x16, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x5c, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0xe2, 0x02, 0x22, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x56, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x43, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x3a, 0x3a, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x1c, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x4c, + 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, + 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x3f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x76, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, + 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, + 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x37, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, + 0x69, 0x63, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x1a, 0x3f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x56, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xd7, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x76, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x36, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x76, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x76, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x56, 0x58, + 0xaa, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x5c, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0xe2, 0x02, 0x22, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x56, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x3a, 0x3a, 0x56, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/cosmos/vesting/v1beta1/tx.proto b/proto/cosmos/vesting/v1beta1/tx.proto index 67008724c4d1..899803a3fd78 100644 --- a/proto/cosmos/vesting/v1beta1/tx.proto +++ b/proto/cosmos/vesting/v1beta1/tx.proto @@ -49,6 +49,8 @@ message MsgCreateVestingAccount { // end of vesting as unix time (in seconds). int64 end_time = 4; bool delayed = 5; + // start of vesting as unix time (in seconds). + int64 start_time = 6; } // MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type. diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index fe6a0c341f21..1941203802ff 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -20,7 +20,8 @@ import ( // Transaction command flags const ( - FlagDelayed = "delayed" + FlagDelayed = "delayed" + FlagStartTime = "start-time" ) // GetTxCmd returns vesting module's transaction commands. @@ -79,13 +80,18 @@ timestamp.`, } delayed, _ := cmd.Flags().GetBool(FlagDelayed) + startTime, err := cmd.Flags().GetInt64(FlagStartTime) + if err != nil { + return err + } - msg := types.NewMsgCreateVestingAccount(clientCtx.GetFromAddress(), toAddr, amount, endTime, delayed) + msg := types.NewMsgCreateVestingAccount(clientCtx.GetFromAddress(), toAddr, amount, startTime, endTime, delayed) return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, } cmd.Flags().Bool(FlagDelayed, false, "Create a delayed vesting account if true") + cmd.Flags().Int64(FlagStartTime, 0, "Optional start time (as a UNIX epoch timestamp) for continuous vesting accounts. If 0 (default), the block's time of the block this tx is committed to will be used.") flags.AddTxFlagsToCmd(cmd) return cmd diff --git a/x/auth/vesting/msg_server.go b/x/auth/vesting/msg_server.go index b5d0e139bf73..a9dd91cc016b 100644 --- a/x/auth/vesting/msg_server.go +++ b/x/auth/vesting/msg_server.go @@ -44,7 +44,11 @@ func (s msgServer) CreateVestingAccount(ctx context.Context, msg *types.MsgCreat } if msg.EndTime <= 0 { - return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "invalid end time") + return nil, sdkerrors.ErrInvalidRequest.Wrap("invalid end time") + } + + if msg.EndTime <= msg.StartTime { + return nil, sdkerrors.ErrInvalidRequest.Wrap("invalid start and end time (must be start < end)") } if err := s.BankKeeper.IsSendEnabledCoins(ctx, msg.Amount...); err != nil { @@ -70,8 +74,12 @@ func (s msgServer) CreateVestingAccount(ctx context.Context, msg *types.MsgCreat if msg.Delayed { vestingAccount = types.NewDelayedVestingAccountRaw(baseVestingAccount) } else { - sdkctx := sdk.UnwrapSDKContext(ctx) - vestingAccount = types.NewContinuousVestingAccountRaw(baseVestingAccount, sdkctx.HeaderInfo().Time.Unix()) + start := msg.StartTime + if msg.StartTime == 0 { + sdkctx := sdk.UnwrapSDKContext(ctx) + start = sdkctx.HeaderInfo().Time.Unix() + } + vestingAccount = types.NewContinuousVestingAccountRaw(baseVestingAccount, start) } s.AccountKeeper.SetAccount(ctx, vestingAccount) diff --git a/x/auth/vesting/types/msgs.go b/x/auth/vesting/types/msgs.go index 296fa8845921..f973abc98df9 100644 --- a/x/auth/vesting/types/msgs.go +++ b/x/auth/vesting/types/msgs.go @@ -11,11 +11,12 @@ var ( ) // NewMsgCreateVestingAccount returns a reference to a new MsgCreateVestingAccount. -func NewMsgCreateVestingAccount(fromAddr, toAddr sdk.AccAddress, amount sdk.Coins, endTime int64, delayed bool) *MsgCreateVestingAccount { +func NewMsgCreateVestingAccount(fromAddr, toAddr sdk.AccAddress, amount sdk.Coins, startTime, endTime int64, delayed bool) *MsgCreateVestingAccount { return &MsgCreateVestingAccount{ FromAddress: fromAddr.String(), ToAddress: toAddr.String(), Amount: amount, + StartTime: startTime, EndTime: endTime, Delayed: delayed, } diff --git a/x/auth/vesting/types/tx.pb.go b/x/auth/vesting/types/tx.pb.go index 2d46bb32daca..2fc268a3f6c5 100644 --- a/x/auth/vesting/types/tx.pb.go +++ b/x/auth/vesting/types/tx.pb.go @@ -42,6 +42,8 @@ type MsgCreateVestingAccount struct { // end of vesting as unix time (in seconds). EndTime int64 `protobuf:"varint,4,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` Delayed bool `protobuf:"varint,5,opt,name=delayed,proto3" json:"delayed,omitempty"` + // start of vesting as unix time (in seconds). + StartTime int64 `protobuf:"varint,6,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` } func (m *MsgCreateVestingAccount) Reset() { *m = MsgCreateVestingAccount{} } @@ -112,6 +114,13 @@ func (m *MsgCreateVestingAccount) GetDelayed() bool { return false } +func (m *MsgCreateVestingAccount) GetStartTime() int64 { + if m != nil { + return m.StartTime + } + return 0 +} + // MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type. type MsgCreateVestingAccountResponse struct { } @@ -381,49 +390,50 @@ func init() { func init() { proto.RegisterFile("cosmos/vesting/v1beta1/tx.proto", fileDescriptor_5338ca97811f9792) } var fileDescriptor_5338ca97811f9792 = []byte{ - // 670 bytes of a gzipped FileDescriptorProto + // 676 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x95, 0xbf, 0x6f, 0xd3, 0x40, 0x14, 0xc7, 0xe3, 0xba, 0xbf, 0x72, 0xad, 0x40, 0x35, 0x85, 0xba, 0x11, 0xb5, 0x53, 0x0b, 0x44, 0xa8, 0x54, 0x5b, 0x2d, 0x48, 0x95, 0x02, 0x52, 0xd5, 0x54, 0x62, 0x81, 0x4a, 0xc8, 0x20, 0x06, 0x96, 0xe8, 0x62, 0x1f, 0xae, 0xd5, 0xda, 0x17, 0xf9, 0xae, 0x55, 0xb3, 0x55, 0x8c, 0x4c, 0x6c, - 0x20, 0x26, 0x46, 0xc4, 0xd4, 0x81, 0x7f, 0x01, 0xa9, 0x1b, 0x15, 0x13, 0x53, 0x40, 0xc9, 0x10, - 0xe6, 0xee, 0x48, 0xe8, 0x7c, 0xe7, 0x90, 0x14, 0x3b, 0x69, 0x99, 0x58, 0xe2, 0xf8, 0xde, 0xf7, - 0xfb, 0xee, 0xf9, 0xf3, 0xee, 0xd9, 0x40, 0x77, 0x30, 0x09, 0x30, 0xb1, 0xf6, 0x11, 0xa1, 0x7e, - 0xe8, 0x59, 0xfb, 0x2b, 0x35, 0x44, 0xe1, 0x8a, 0x45, 0x0f, 0xcc, 0x7a, 0x84, 0x29, 0x56, 0xae, - 0x71, 0x81, 0x29, 0x04, 0xa6, 0x10, 0x14, 0x66, 0x3d, 0xec, 0xe1, 0x58, 0x62, 0xb1, 0x7f, 0x5c, - 0x5d, 0xd0, 0x44, 0xba, 0x1a, 0x24, 0xa8, 0x9b, 0xcb, 0xc1, 0x7e, 0x28, 0xe2, 0xf3, 0x3c, 0x5e, - 0xe5, 0x46, 0x91, 0x9a, 0x87, 0x6e, 0x64, 0x54, 0x92, 0x6c, 0xcc, 0x55, 0x73, 0x42, 0x15, 0x10, - 0xa6, 0x60, 0x17, 0x11, 0x98, 0x81, 0x81, 0x1f, 0x62, 0x2b, 0xfe, 0xe5, 0x4b, 0xc6, 0xaf, 0x11, - 0x30, 0xb7, 0x45, 0xbc, 0xcd, 0x08, 0x41, 0x8a, 0x9e, 0xf1, 0x34, 0x1b, 0x8e, 0x83, 0xf7, 0x42, - 0xaa, 0xdc, 0x03, 0xd3, 0x2f, 0x22, 0x1c, 0x54, 0xa1, 0xeb, 0x46, 0x88, 0x10, 0x55, 0x2a, 0x4a, - 0xa5, 0x7c, 0x45, 0xfd, 0xfa, 0x69, 0x79, 0x56, 0x54, 0xb5, 0xc1, 0x23, 0x4f, 0x68, 0xe4, 0x87, - 0x9e, 0x3d, 0xc5, 0xd4, 0x62, 0x49, 0x59, 0x03, 0x80, 0xe2, 0xae, 0x75, 0x64, 0x88, 0x35, 0x4f, - 0x71, 0x62, 0x6c, 0x80, 0x71, 0x18, 0xb0, 0xfd, 0x55, 0xb9, 0x28, 0x97, 0xa6, 0x56, 0xe7, 0x4d, - 0xe1, 0x60, 0xbc, 0x12, 0xb4, 0xe6, 0x26, 0xf6, 0xc3, 0xca, 0x83, 0xe3, 0xa6, 0x9e, 0xfb, 0xf8, - 0x5d, 0x2f, 0x79, 0x3e, 0xdd, 0xde, 0xab, 0x99, 0x0e, 0x0e, 0x04, 0x2f, 0x71, 0x59, 0x26, 0xee, - 0x8e, 0x45, 0x1b, 0x75, 0x44, 0x62, 0x03, 0x79, 0xd7, 0x39, 0x5a, 0x9a, 0xde, 0x45, 0x1e, 0x74, - 0x1a, 0x55, 0x46, 0x9c, 0x7c, 0xe8, 0x1c, 0x2d, 0x49, 0xb6, 0xd8, 0x50, 0x99, 0x07, 0x93, 0x28, - 0x74, 0xab, 0xd4, 0x0f, 0x90, 0x3a, 0x5a, 0x94, 0x4a, 0xb2, 0x3d, 0x81, 0x42, 0xf7, 0xa9, 0x1f, - 0x20, 0x45, 0x05, 0x13, 0x2e, 0xda, 0x85, 0x0d, 0xe4, 0xaa, 0x63, 0x45, 0xa9, 0x34, 0x69, 0x27, - 0xb7, 0xe5, 0xfb, 0x3f, 0xdf, 0xeb, 0xd2, 0x4b, 0x96, 0xb8, 0x17, 0xd6, 0xab, 0xce, 0xd1, 0x92, - 0xd1, 0x53, 0x44, 0x06, 0x63, 0x63, 0x11, 0xe8, 0x19, 0x21, 0x1b, 0x91, 0x3a, 0x0e, 0x09, 0x32, - 0xbe, 0x8c, 0xf4, 0x68, 0x1e, 0xa3, 0x28, 0x80, 0x21, 0x0a, 0xe9, 0x23, 0xec, 0xec, 0x20, 0x37, - 0x69, 0x55, 0x39, 0xb5, 0x55, 0x73, 0xa7, 0x4d, 0xfd, 0x4a, 0x03, 0x06, 0xbb, 0x65, 0xa3, 0x37, - 0x6a, 0xf4, 0x77, 0xea, 0x6e, 0x4a, 0xa7, 0xae, 0x9e, 0x36, 0xf5, 0x19, 0xee, 0xfc, 0x13, 0x33, - 0xfe, 0x8f, 0x36, 0x95, 0xd7, 0x33, 0x89, 0xdf, 0x4c, 0x23, 0xce, 0x90, 0xf5, 0xd1, 0x32, 0x6e, - 0x83, 0x5b, 0x43, 0x80, 0x76, 0xe1, 0xbf, 0x39, 0x03, 0xdf, 0xc7, 0xae, 0xef, 0x9c, 0x99, 0x93, - 0xc5, 0x34, 0xf8, 0xfd, 0x8c, 0x17, 0xfe, 0x66, 0xdc, 0x0b, 0x73, 0x01, 0x00, 0x42, 0x61, 0x44, - 0xf9, 0xd1, 0x93, 0xe3, 0xa3, 0x97, 0x8f, 0x57, 0xe2, 0xc3, 0x67, 0x83, 0xcb, 0x62, 0xc2, 0xab, - 0xf5, 0xb8, 0x04, 0xa2, 0x8e, 0xc6, 0xd0, 0x35, 0x33, 0xfd, 0xcd, 0x63, 0xf2, 0x4a, 0x2b, 0x79, - 0x46, 0x9e, 0xc3, 0xbb, 0x24, 0x24, 0x3c, 0x42, 0x62, 0x88, 0xb9, 0x0b, 0x41, 0xf4, 0xb1, 0xcb, - 0x1e, 0x3c, 0x03, 0x62, 0x0a, 0x98, 0x04, 0xe2, 0xea, 0x67, 0x19, 0xc8, 0x5b, 0xc4, 0x53, 0x0e, - 0x25, 0x30, 0x9b, 0xfa, 0xa6, 0xb1, 0xb2, 0x9e, 0x23, 0x63, 0x36, 0x0a, 0x6b, 0x17, 0x34, 0x24, - 0xa5, 0x28, 0x6f, 0x25, 0x70, 0x7d, 0xe0, 0x24, 0x0d, 0xcf, 0x9c, 0x6e, 0x2c, 0xac, 0xff, 0xa3, - 0x31, 0xbd, 0xb4, 0xb4, 0x73, 0x76, 0xae, 0xd2, 0x52, 0x8c, 0xe7, 0x2b, 0x6d, 0x40, 0x03, 0x0b, - 0x63, 0x87, 0xec, 0x0c, 0x55, 0x1e, 0x1e, 0xb7, 0x34, 0xe9, 0xa4, 0xa5, 0x49, 0x3f, 0x5a, 0x9a, - 0xf4, 0xba, 0xad, 0xe5, 0x4e, 0xda, 0x5a, 0xee, 0x5b, 0x5b, 0xcb, 0x3d, 0x5f, 0x19, 0x38, 0xda, - 0x07, 0x16, 0xdc, 0xa3, 0xdb, 0xdd, 0xaf, 0x56, 0x3c, 0xe9, 0xb5, 0xf1, 0xf8, 0x03, 0x74, 0xe7, - 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x25, 0x64, 0x77, 0xbb, 0x5e, 0x07, 0x00, 0x00, + 0x20, 0xc4, 0xc0, 0x88, 0x98, 0x3a, 0xf0, 0x2f, 0x20, 0x75, 0xa3, 0x62, 0x62, 0x2a, 0x28, 0x19, + 0xc2, 0xdc, 0xbf, 0x00, 0x9d, 0xef, 0x1c, 0x92, 0x60, 0x27, 0x2d, 0x13, 0x4b, 0xdd, 0xdc, 0xfb, + 0x7e, 0xdf, 0x3d, 0x7f, 0xde, 0xbd, 0x33, 0xd0, 0x1d, 0x4c, 0x02, 0x4c, 0xac, 0x7d, 0x44, 0xa8, + 0x1f, 0x7a, 0xd6, 0xfe, 0x4a, 0x0d, 0x51, 0xb8, 0x62, 0xd1, 0x03, 0xb3, 0x1e, 0x61, 0x8a, 0x95, + 0x6b, 0x5c, 0x60, 0x0a, 0x81, 0x29, 0x04, 0x85, 0x59, 0x0f, 0x7b, 0x38, 0x96, 0x58, 0xec, 0x3f, + 0xae, 0x2e, 0x68, 0x22, 0x5d, 0x0d, 0x12, 0xd4, 0xc9, 0xe5, 0x60, 0x3f, 0x14, 0xf1, 0x79, 0x1e, + 0xaf, 0x72, 0xa3, 0x48, 0xcd, 0x43, 0x37, 0x32, 0x2a, 0x49, 0x36, 0xe6, 0xaa, 0x39, 0xa1, 0x0a, + 0x08, 0x53, 0xb0, 0x87, 0x08, 0xcc, 0xc0, 0xc0, 0x0f, 0xb1, 0x15, 0xff, 0xe5, 0x4b, 0xc6, 0x7b, + 0x19, 0xcc, 0x6d, 0x11, 0x6f, 0x33, 0x42, 0x90, 0xa2, 0x67, 0x3c, 0xcd, 0x86, 0xe3, 0xe0, 0xbd, + 0x90, 0x2a, 0xf7, 0xc0, 0xf4, 0x8b, 0x08, 0x07, 0x55, 0xe8, 0xba, 0x11, 0x22, 0x44, 0x95, 0x8a, + 0x52, 0x29, 0x5f, 0x51, 0xbf, 0x7d, 0x5e, 0x9e, 0x15, 0x55, 0x6d, 0xf0, 0xc8, 0x13, 0x1a, 0xf9, + 0xa1, 0x67, 0x4f, 0x31, 0xb5, 0x58, 0x52, 0xd6, 0x00, 0xa0, 0xb8, 0x63, 0x1d, 0x19, 0x62, 0xcd, + 0x53, 0x9c, 0x18, 0x1b, 0x60, 0x1c, 0x06, 0x6c, 0x7f, 0x55, 0x2e, 0xca, 0xa5, 0xa9, 0xd5, 0x79, + 0x53, 0x38, 0x18, 0xaf, 0x04, 0xad, 0xb9, 0x89, 0xfd, 0xb0, 0xf2, 0xe0, 0xf8, 0x54, 0xcf, 0x7d, + 0xfa, 0xa1, 0x97, 0x3c, 0x9f, 0x6e, 0xef, 0xd5, 0x4c, 0x07, 0x07, 0x82, 0x97, 0x78, 0x2c, 0x13, + 0x77, 0xc7, 0xa2, 0x8d, 0x3a, 0x22, 0xb1, 0x81, 0xbc, 0x6b, 0x1f, 0x2d, 0x4d, 0xef, 0x22, 0x0f, + 0x3a, 0x8d, 0x2a, 0x23, 0x4e, 0x3e, 0xb6, 0x8f, 0x96, 0x24, 0x5b, 0x6c, 0xa8, 0xcc, 0x83, 0x49, + 0x14, 0xba, 0x55, 0xea, 0x07, 0x48, 0x1d, 0x2d, 0x4a, 0x25, 0xd9, 0x9e, 0x40, 0xa1, 0xfb, 0xd4, + 0x0f, 0x90, 0xa2, 0x82, 0x09, 0x17, 0xed, 0xc2, 0x06, 0x72, 0xd5, 0xb1, 0xa2, 0x54, 0x9a, 0xb4, + 0x93, 0x9f, 0xca, 0x02, 0x00, 0x84, 0xc2, 0x88, 0x72, 0xdb, 0x78, 0x6c, 0xcb, 0xc7, 0x2b, 0xcc, + 0x58, 0xbe, 0xff, 0xeb, 0x83, 0x2e, 0xbd, 0x64, 0xfb, 0x76, 0xb3, 0x7c, 0xd5, 0x3e, 0x5a, 0x32, + 0xba, 0x6a, 0xcc, 0x68, 0x81, 0xb1, 0x08, 0xf4, 0x8c, 0x90, 0x8d, 0x48, 0x1d, 0x87, 0x04, 0x19, + 0x5f, 0x47, 0xba, 0x34, 0x8f, 0x51, 0x14, 0xc0, 0x10, 0x85, 0xf4, 0x11, 0x76, 0x76, 0x90, 0x9b, + 0x74, 0xb2, 0x9c, 0xda, 0xc9, 0xb9, 0xb3, 0x53, 0xfd, 0x4a, 0x03, 0x06, 0xbb, 0x65, 0xa3, 0x3b, + 0x6a, 0xf4, 0x36, 0xf2, 0x6e, 0x4a, 0x23, 0xaf, 0x9e, 0x9d, 0xea, 0x33, 0xdc, 0xf9, 0x27, 0x66, + 0xfc, 0x1f, 0x5d, 0x2c, 0xaf, 0x67, 0x12, 0xbf, 0x99, 0x46, 0x9c, 0x21, 0xeb, 0xa1, 0x65, 0xdc, + 0x06, 0xb7, 0x86, 0x00, 0xed, 0xc0, 0x7f, 0xd3, 0x07, 0xdf, 0xc7, 0xae, 0xef, 0xf4, 0x8d, 0xd1, + 0x62, 0x1a, 0xfc, 0x5e, 0xc6, 0x0b, 0x7f, 0x33, 0xee, 0x86, 0xd9, 0x7b, 0xc4, 0xe4, 0xbe, 0x23, + 0xa6, 0xd8, 0xe0, 0xb2, 0xb8, 0x00, 0xaa, 0xf5, 0xb8, 0x04, 0xa2, 0x8e, 0xc6, 0xd0, 0x35, 0x33, + 0xfd, 0x62, 0x32, 0x79, 0xa5, 0x95, 0x3c, 0x23, 0xcf, 0xe1, 0x5d, 0x12, 0x12, 0x1e, 0x21, 0x31, + 0xc4, 0xdc, 0x85, 0x20, 0xfa, 0xd8, 0x65, 0x2f, 0x9e, 0x01, 0x31, 0x05, 0x4c, 0x02, 0x71, 0xf5, + 0x8b, 0x0c, 0xe4, 0x2d, 0xe2, 0x29, 0x87, 0x12, 0x98, 0x4d, 0xbd, 0x88, 0xac, 0xac, 0xf7, 0xc8, + 0x98, 0x8d, 0xc2, 0xda, 0x05, 0x0d, 0x49, 0x29, 0xca, 0x5b, 0x09, 0x5c, 0x1f, 0x38, 0x49, 0xc3, + 0x33, 0xa7, 0x1b, 0x0b, 0xeb, 0xff, 0x68, 0x4c, 0x2f, 0x2d, 0xed, 0x9c, 0x9d, 0xab, 0xb4, 0x14, + 0xe3, 0xf9, 0x4a, 0x1b, 0xd0, 0xc0, 0xc2, 0xd8, 0x21, 0x3b, 0x43, 0x95, 0x87, 0xc7, 0x4d, 0x4d, + 0x3a, 0x69, 0x6a, 0xd2, 0xcf, 0xa6, 0x26, 0xbd, 0x6e, 0x69, 0xb9, 0x93, 0x96, 0x96, 0xfb, 0xde, + 0xd2, 0x72, 0xcf, 0x57, 0x06, 0x8e, 0xf6, 0x81, 0x05, 0xf7, 0xe8, 0x76, 0xe7, 0xa3, 0x16, 0x4f, + 0x7a, 0x6d, 0x3c, 0xfe, 0x3e, 0xdd, 0xf9, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xe4, 0xab, 0x5c, 0x40, + 0x7d, 0x07, 0x00, 0x00, } func (this *MsgCreateVestingAccount) Equal(that interface{}) bool { @@ -465,6 +475,9 @@ func (this *MsgCreateVestingAccount) Equal(that interface{}) bool { if this.Delayed != that1.Delayed { return false } + if this.StartTime != that1.StartTime { + return false + } return true } func (this *MsgCreatePermanentLockedAccount) Equal(that interface{}) bool { @@ -695,6 +708,11 @@ func (m *MsgCreateVestingAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l + if m.StartTime != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.StartTime)) + i-- + dAtA[i] = 0x30 + } if m.Delayed { i-- if m.Delayed { @@ -954,6 +972,9 @@ func (m *MsgCreateVestingAccount) Size() (n int) { if m.Delayed { n += 2 } + if m.StartTime != 0 { + n += 1 + sovTx(uint64(m.StartTime)) + } return n } @@ -1205,6 +1226,25 @@ func (m *MsgCreateVestingAccount) Unmarshal(dAtA []byte) error { } } m.Delayed = bool(v != 0) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartTime", wireType) + } + m.StartTime = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartTime |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/x/auth/vesting/types/vesting_account_test.go b/x/auth/vesting/types/vesting_account_test.go index 74cdfe59c5a5..2b5da9d4586c 100644 --- a/x/auth/vesting/types/vesting_account_test.go +++ b/x/auth/vesting/types/vesting_account_test.go @@ -67,70 +67,98 @@ func (s *VestingAccountTestSuite) SetupTest() { func TestGetVestedCoinsContVestingAcc(t *testing.T) { now := tmtime.Now() - endTime := now.Add(24 * time.Hour) + startTime := now.Add(24 * time.Hour) + endTime := startTime.Add(24 * time.Hour) bacc, origCoins := initBaseAccount() - cva, err := types.NewContinuousVestingAccount(bacc, origCoins, now.Unix(), endTime.Unix()) + cva, err := types.NewContinuousVestingAccount(bacc, origCoins, startTime.Unix(), endTime.Unix()) require.NoError(t, err) - // require no coins vested in the very beginning of the vesting schedule + // require no coins vested _before_ the start time of the vesting schedule vestedCoins := cva.GetVestedCoins(now) require.Nil(t, vestedCoins) + // require no coins vested _before_ the very beginning of the vesting schedule + vestedCoins = cva.GetVestedCoins(startTime.Add(-1)) + require.Nil(t, vestedCoins) + // require all coins vested at the end of the vesting schedule vestedCoins = cva.GetVestedCoins(endTime) require.Equal(t, origCoins, vestedCoins) // require 50% of coins vested - vestedCoins = cva.GetVestedCoins(now.Add(12 * time.Hour)) + vestedCoins = cva.GetVestedCoins(startTime.Add(12 * time.Hour)) require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestedCoins) + // require 75% of coins vested + vestedCoins = cva.GetVestedCoins(startTime.Add(18 * time.Hour)) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 750), sdk.NewInt64Coin(stakeDenom, 75)}, vestedCoins) + // require 100% of coins vested - vestedCoins = cva.GetVestedCoins(now.Add(48 * time.Hour)) + vestedCoins = cva.GetVestedCoins(endTime) require.Equal(t, origCoins, vestedCoins) } func TestGetVestingCoinsContVestingAcc(t *testing.T) { now := tmtime.Now() - endTime := now.Add(24 * time.Hour) + startTime := now.Add(24 * time.Hour) + endTime := startTime.Add(24 * time.Hour) bacc, origCoins := initBaseAccount() - cva, err := types.NewContinuousVestingAccount(bacc, origCoins, now.Unix(), endTime.Unix()) + cva, err := types.NewContinuousVestingAccount(bacc, origCoins, startTime.Unix(), endTime.Unix()) require.NoError(t, err) - // require all coins vesting in the beginning of the vesting schedule + // require all coins vesting before the start time of the vesting schedule vestingCoins := cva.GetVestingCoins(now) require.Equal(t, origCoins, vestingCoins) + // require all coins vesting right before the start time of the vesting schedule + vestingCoins = cva.GetVestingCoins(startTime.Add(-1)) + require.Equal(t, origCoins, vestingCoins) + // require no coins vesting at the end of the vesting schedule vestingCoins = cva.GetVestingCoins(endTime) require.Equal(t, emptyCoins, vestingCoins) - // require 50% of coins vesting - vestingCoins = cva.GetVestingCoins(now.Add(12 * time.Hour)) + // require 50% of coins vesting in the middle between start and end time + vestingCoins = cva.GetVestingCoins(startTime.Add(12 * time.Hour)) require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestingCoins) + + // require 25% of coins vesting after 3/4 of the time between start and end time has passed + vestingCoins = cva.GetVestingCoins(startTime.Add(18 * time.Hour)) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}, vestingCoins) } func TestSpendableCoinsContVestingAcc(t *testing.T) { now := tmtime.Now() - endTime := now.Add(24 * time.Hour) + startTime := now.Add(24 * time.Hour) + endTime := startTime.Add(24 * time.Hour) bacc, origCoins := initBaseAccount() - cva, err := types.NewContinuousVestingAccount(bacc, origCoins, now.Unix(), endTime.Unix()) + cva, err := types.NewContinuousVestingAccount(bacc, origCoins, startTime.Unix(), endTime.Unix()) require.NoError(t, err) - // require that all original coins are locked at the end of the vesting + // require that all original coins are locked before the beginning of the vesting // schedule lockedCoins := cva.LockedCoins(now) require.Equal(t, origCoins, lockedCoins) - // require that there exist no locked coins in the beginning of the + // require that all original coins are locked at the beginning of the vesting + // schedule + lockedCoins = cva.LockedCoins(startTime) + require.Equal(t, origCoins, lockedCoins) + + // require that there exist no locked coins in the end of the vesting schedule lockedCoins = cva.LockedCoins(endTime) require.Equal(t, sdk.NewCoins(), lockedCoins) // require that all vested coins (50%) are spendable - lockedCoins = cva.LockedCoins(now.Add(12 * time.Hour)) + lockedCoins = cva.LockedCoins(startTime.Add(12 * time.Hour)) require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, lockedCoins) + + // require 25% of coins vesting after 3/4 of the time between start and end time has passed + lockedCoins = cva.LockedCoins(startTime.Add(18 * time.Hour)) + require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}, lockedCoins) } func TestTrackDelegationContVestingAcc(t *testing.T) { From 43a1e235198a2e6682fb87b7cc14e6e1b0c718f9 Mon Sep 17 00:00:00 2001 From: Callum Waters Date: Wed, 27 Sep 2023 15:26:08 +0200 Subject: [PATCH 2/5] implement suggestions --- CHANGELOG.md | 1 + api/cosmos/vesting/v1beta1/tx.pulsar.go | 2 ++ proto/cosmos/vesting/v1beta1/tx.proto | 2 ++ x/auth/vesting/client/cli/tx.go | 2 +- x/auth/vesting/types/msgs.go | 13 ++++++++++++- x/auth/vesting/types/tx.pb.go | 2 ++ x/auth/vesting/types/vesting_account_test.go | 12 ++++++++---- 7 files changed, 28 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a7d5d013f2c..dac888789b64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (genutil) [#17571](https://github.com/cosmos/cosmos-sdk/pull/17571) Allow creation of `AppGenesis` without a file lookup. * (server) [#17094](https://github.com/cosmos/cosmos-sdk/pull/17094) Add duration `shutdown-grace` for resource clean up (closing database handles) before exit. * (x/gov) [#17780](https://github.com/cosmos/cosmos-sdk/pull/17780) Recover panics and turn them into errors when executing x/gov proposals. +* (x/auth/vesting) [#17810](https://github.com/cosmos/cosmos-sdk/pull/17810) Add the ability to specify a start time for continuous vesting accounts. ### Improvements diff --git a/api/cosmos/vesting/v1beta1/tx.pulsar.go b/api/cosmos/vesting/v1beta1/tx.pulsar.go index 1b2f5e15eb20..eb30f58863fe 100644 --- a/api/cosmos/vesting/v1beta1/tx.pulsar.go +++ b/api/cosmos/vesting/v1beta1/tx.pulsar.go @@ -3176,6 +3176,8 @@ type MsgCreateVestingAccount struct { EndTime int64 `protobuf:"varint,4,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` Delayed bool `protobuf:"varint,5,opt,name=delayed,proto3" json:"delayed,omitempty"` // start of vesting as unix time (in seconds). + // + // Since 0.51.x StartTime int64 `protobuf:"varint,6,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` } diff --git a/proto/cosmos/vesting/v1beta1/tx.proto b/proto/cosmos/vesting/v1beta1/tx.proto index 899803a3fd78..97af97906d3b 100644 --- a/proto/cosmos/vesting/v1beta1/tx.proto +++ b/proto/cosmos/vesting/v1beta1/tx.proto @@ -50,6 +50,8 @@ message MsgCreateVestingAccount { int64 end_time = 4; bool delayed = 5; // start of vesting as unix time (in seconds). + // + // Since 0.51.x int64 start_time = 6; } diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index 1941203802ff..fabb048d10cf 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -85,7 +85,7 @@ timestamp.`, return err } - msg := types.NewMsgCreateVestingAccount(clientCtx.GetFromAddress(), toAddr, amount, startTime, endTime, delayed) + msg := types.NewMsgCreateVestingAccountWithStartTime(clientCtx.GetFromAddress(), toAddr, amount, startTime, endTime, delayed) return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, } diff --git a/x/auth/vesting/types/msgs.go b/x/auth/vesting/types/msgs.go index f973abc98df9..01fc0bff954f 100644 --- a/x/auth/vesting/types/msgs.go +++ b/x/auth/vesting/types/msgs.go @@ -11,7 +11,18 @@ var ( ) // NewMsgCreateVestingAccount returns a reference to a new MsgCreateVestingAccount. -func NewMsgCreateVestingAccount(fromAddr, toAddr sdk.AccAddress, amount sdk.Coins, startTime, endTime int64, delayed bool) *MsgCreateVestingAccount { +func NewMsgCreateVestingAccount(fromAddr, toAddr sdk.AccAddress, amount sdk.Coins, endTime int64, delayed bool) *MsgCreateVestingAccount { + return &MsgCreateVestingAccount{ + FromAddress: fromAddr.String(), + ToAddress: toAddr.String(), + Amount: amount, + EndTime: endTime, + Delayed: delayed, + } +} + +// NewMsgCreateVestingAccount returns a reference to a new MsgCreateVestingAccount. +func NewMsgCreateVestingAccountWithStartTime(fromAddr, toAddr sdk.AccAddress, amount sdk.Coins, startTime, endTime int64, delayed bool) *MsgCreateVestingAccount { return &MsgCreateVestingAccount{ FromAddress: fromAddr.String(), ToAddress: toAddr.String(), diff --git a/x/auth/vesting/types/tx.pb.go b/x/auth/vesting/types/tx.pb.go index 2fc268a3f6c5..8f0c36549fac 100644 --- a/x/auth/vesting/types/tx.pb.go +++ b/x/auth/vesting/types/tx.pb.go @@ -43,6 +43,8 @@ type MsgCreateVestingAccount struct { EndTime int64 `protobuf:"varint,4,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` Delayed bool `protobuf:"varint,5,opt,name=delayed,proto3" json:"delayed,omitempty"` // start of vesting as unix time (in seconds). + // + // Since 0.51.x StartTime int64 `protobuf:"varint,6,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` } diff --git a/x/auth/vesting/types/vesting_account_test.go b/x/auth/vesting/types/vesting_account_test.go index 2b5da9d4586c..b0776c1d6d95 100644 --- a/x/auth/vesting/types/vesting_account_test.go +++ b/x/auth/vesting/types/vesting_account_test.go @@ -87,11 +87,13 @@ func TestGetVestedCoinsContVestingAcc(t *testing.T) { require.Equal(t, origCoins, vestedCoins) // require 50% of coins vested - vestedCoins = cva.GetVestedCoins(startTime.Add(12 * time.Hour)) + t50 := time.Duration(0.5 * float64(endTime.Sub(startTime))) + vestedCoins = cva.GetVestedCoins(startTime.Add(t50)) require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestedCoins) // require 75% of coins vested - vestedCoins = cva.GetVestedCoins(startTime.Add(18 * time.Hour)) + t75 := time.Duration(0.75 * float64(endTime.Sub(startTime))) + vestedCoins = cva.GetVestedCoins(startTime.Add(t75)) require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 750), sdk.NewInt64Coin(stakeDenom, 75)}, vestedCoins) // require 100% of coins vested @@ -121,11 +123,13 @@ func TestGetVestingCoinsContVestingAcc(t *testing.T) { require.Equal(t, emptyCoins, vestingCoins) // require 50% of coins vesting in the middle between start and end time - vestingCoins = cva.GetVestingCoins(startTime.Add(12 * time.Hour)) + t50 := time.Duration(0.5 * float64(endTime.Sub(startTime))) + vestingCoins = cva.GetVestingCoins(startTime.Add(t50)) require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}, vestingCoins) // require 25% of coins vesting after 3/4 of the time between start and end time has passed - vestingCoins = cva.GetVestingCoins(startTime.Add(18 * time.Hour)) + t75 := time.Duration(0.75 * float64(endTime.Sub(startTime))) + vestingCoins = cva.GetVestingCoins(startTime.Add(t75)) require.Equal(t, sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}, vestingCoins) } From ed3e83c4c2970bbac6998854fd3354842f35c191 Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Mon, 16 Oct 2023 12:38:17 +0200 Subject: [PATCH 3/5] remove extra code --- x/auth/vesting/types/msgs.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/x/auth/vesting/types/msgs.go b/x/auth/vesting/types/msgs.go index 01fc0bff954f..296fa8845921 100644 --- a/x/auth/vesting/types/msgs.go +++ b/x/auth/vesting/types/msgs.go @@ -21,18 +21,6 @@ func NewMsgCreateVestingAccount(fromAddr, toAddr sdk.AccAddress, amount sdk.Coin } } -// NewMsgCreateVestingAccount returns a reference to a new MsgCreateVestingAccount. -func NewMsgCreateVestingAccountWithStartTime(fromAddr, toAddr sdk.AccAddress, amount sdk.Coins, startTime, endTime int64, delayed bool) *MsgCreateVestingAccount { - return &MsgCreateVestingAccount{ - FromAddress: fromAddr.String(), - ToAddress: toAddr.String(), - Amount: amount, - StartTime: startTime, - EndTime: endTime, - Delayed: delayed, - } -} - // NewMsgCreatePermanentLockedAccount returns a reference to a new MsgCreatePermanentLockedAccount. func NewMsgCreatePermanentLockedAccount(fromAddr, toAddr sdk.AccAddress, amount sdk.Coins) *MsgCreatePermanentLockedAccount { return &MsgCreatePermanentLockedAccount{ From 71d341dbd6bbe780e620edf7057ff0dbe714514c Mon Sep 17 00:00:00 2001 From: Marko Date: Mon, 16 Oct 2023 13:48:18 +0200 Subject: [PATCH 4/5] Update x/auth/vesting/msg_server.go Co-authored-by: Julien Robert --- x/auth/vesting/msg_server.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x/auth/vesting/msg_server.go b/x/auth/vesting/msg_server.go index a9dd91cc016b..6df0f825c21d 100644 --- a/x/auth/vesting/msg_server.go +++ b/x/auth/vesting/msg_server.go @@ -43,6 +43,10 @@ func (s msgServer) CreateVestingAccount(ctx context.Context, msg *types.MsgCreat return nil, err } + if msg.StartTime < 0 { + return nil, sdkerrors.ErrInvalidRequest.Wrap("invalid start time") + } + if msg.EndTime <= 0 { return nil, sdkerrors.ErrInvalidRequest.Wrap("invalid end time") } From 1bc9f8bdfb3cbd89ed7d6e6ecb092cc2dd051549 Mon Sep 17 00:00:00 2001 From: marbar3778 Date: Wed, 18 Oct 2023 13:47:24 +0200 Subject: [PATCH 5/5] fix lint --- x/auth/vesting/msg_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/auth/vesting/msg_server.go b/x/auth/vesting/msg_server.go index 6df0f825c21d..c459c3ca7f7a 100644 --- a/x/auth/vesting/msg_server.go +++ b/x/auth/vesting/msg_server.go @@ -46,7 +46,7 @@ func (s msgServer) CreateVestingAccount(ctx context.Context, msg *types.MsgCreat if msg.StartTime < 0 { return nil, sdkerrors.ErrInvalidRequest.Wrap("invalid start time") } - + if msg.EndTime <= 0 { return nil, sdkerrors.ErrInvalidRequest.Wrap("invalid end time") }