Add a custom lockup account to hold locked tokens #72

Merged
nabarun merged 6 commits from pm-lockup-account into mainnet 2025-05-16 09:26:10 +00:00
12 changed files with 1514 additions and 4 deletions

View File

@ -43,7 +43,7 @@ build-linux:
$(BUILD_TARGETS): go.sum $(BUILDDIR)/
@echo "--> installing laconicd"
go $@ $(BUILD_FLAGS) $(BUILD_ARGS) ./...
go $@ $(BUILD_FLAGS) $(BUILD_ARGS) ./cmd/laconicd
$(BUILDDIR)/:
mkdir -p $(BUILDDIR)/

View File

@ -27,6 +27,8 @@ Run with a single node fixture:
./scripts/init.sh clean
```
See [lockup.md](./lockup.md) for lockup account usage.
## Tests
Run tests:

View File

@ -0,0 +1,755 @@
// Code generated by protoc-gen-go-pulsar. DO NOT EDIT.
package typesv1
import (
fmt "fmt"
_ "github.com/cosmos/cosmos-proto"
runtime "github.com/cosmos/cosmos-proto/runtime"
_ "github.com/cosmos/cosmos-sdk/types/tx/amino"
types "github.com/cosmos/cosmos-sdk/x/auth/types"
_ "github.com/cosmos/gogoproto/gogoproto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoiface "google.golang.org/protobuf/runtime/protoiface"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
io "io"
reflect "reflect"
sync "sync"
)
var (
md_LockupAccount protoreflect.MessageDescriptor
fd_LockupAccount_base_account protoreflect.FieldDescriptor
fd_LockupAccount_name protoreflect.FieldDescriptor
fd_LockupAccount_distribution protoreflect.FieldDescriptor
)
func init() {
file_cerc_types_v1_lockup_proto_init()
md_LockupAccount = File_cerc_types_v1_lockup_proto.Messages().ByName("LockupAccount")
fd_LockupAccount_base_account = md_LockupAccount.Fields().ByName("base_account")
fd_LockupAccount_name = md_LockupAccount.Fields().ByName("name")
fd_LockupAccount_distribution = md_LockupAccount.Fields().ByName("distribution")
}
var _ protoreflect.Message = (*fastReflection_LockupAccount)(nil)
type fastReflection_LockupAccount LockupAccount
func (x *LockupAccount) ProtoReflect() protoreflect.Message {
return (*fastReflection_LockupAccount)(x)
}
func (x *LockupAccount) slowProtoReflect() protoreflect.Message {
mi := &file_cerc_types_v1_lockup_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
var _fastReflection_LockupAccount_messageType fastReflection_LockupAccount_messageType
var _ protoreflect.MessageType = fastReflection_LockupAccount_messageType{}
type fastReflection_LockupAccount_messageType struct{}
func (x fastReflection_LockupAccount_messageType) Zero() protoreflect.Message {
return (*fastReflection_LockupAccount)(nil)
}
func (x fastReflection_LockupAccount_messageType) New() protoreflect.Message {
return new(fastReflection_LockupAccount)
}
func (x fastReflection_LockupAccount_messageType) Descriptor() protoreflect.MessageDescriptor {
return md_LockupAccount
}
// Descriptor returns message descriptor, which contains only the protobuf
// type information for the message.
func (x *fastReflection_LockupAccount) Descriptor() protoreflect.MessageDescriptor {
return md_LockupAccount
}
// Type returns the message type, which encapsulates both Go and protobuf
// type information. If the Go type information is not needed,
// it is recommended that the message descriptor be used instead.
func (x *fastReflection_LockupAccount) Type() protoreflect.MessageType {
return _fastReflection_LockupAccount_messageType
}
// New returns a newly allocated and mutable empty message.
func (x *fastReflection_LockupAccount) New() protoreflect.Message {
return new(fastReflection_LockupAccount)
}
// Interface unwraps the message reflection interface and
// returns the underlying ProtoMessage interface.
func (x *fastReflection_LockupAccount) Interface() protoreflect.ProtoMessage {
return (*LockupAccount)(x)
}
// Range iterates over every populated field in an undefined order,
// calling f for each field descriptor and value encountered.
// Range returns immediately if f returns false.
// While iterating, mutating operations may only be performed
// on the current field descriptor.
func (x *fastReflection_LockupAccount) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
if x.BaseAccount != nil {
value := protoreflect.ValueOfMessage(x.BaseAccount.ProtoReflect())
if !f(fd_LockupAccount_base_account, value) {
return
}
}
if x.Name != "" {
value := protoreflect.ValueOfString(x.Name)
if !f(fd_LockupAccount_name, value) {
return
}
}
if x.Distribution != "" {
value := protoreflect.ValueOfString(x.Distribution)
if !f(fd_LockupAccount_distribution, value) {
return
}
}
}
// Has reports whether a field is populated.
//
// Some fields have the property of nullability where it is possible to
// distinguish between the default value of a field and whether the field
// was explicitly populated with the default value. Singular message fields,
// member fields of a oneof, and proto2 scalar fields are nullable. Such
// fields are populated only if explicitly set.
//
// In other cases (aside from the nullable cases above),
// a proto3 scalar field is populated if it contains a non-zero value, and
// a repeated field is populated if it is non-empty.
func (x *fastReflection_LockupAccount) Has(fd protoreflect.FieldDescriptor) bool {
switch fd.FullName() {
case "cerc.types.v1.LockupAccount.base_account":
return x.BaseAccount != nil
case "cerc.types.v1.LockupAccount.name":
return x.Name != ""
case "cerc.types.v1.LockupAccount.distribution":
return x.Distribution != ""
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cerc.types.v1.LockupAccount"))
}
panic(fmt.Errorf("message cerc.types.v1.LockupAccount does not contain field %s", fd.FullName()))
}
}
// Clear clears the field such that a subsequent Has call reports false.
//
// Clearing an extension field clears both the extension type and value
// associated with the given field number.
//
// Clear is a mutating operation and unsafe for concurrent use.
func (x *fastReflection_LockupAccount) Clear(fd protoreflect.FieldDescriptor) {
switch fd.FullName() {
case "cerc.types.v1.LockupAccount.base_account":
x.BaseAccount = nil
case "cerc.types.v1.LockupAccount.name":
x.Name = ""
case "cerc.types.v1.LockupAccount.distribution":
x.Distribution = ""
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cerc.types.v1.LockupAccount"))
}
panic(fmt.Errorf("message cerc.types.v1.LockupAccount does not contain field %s", fd.FullName()))
}
}
// Get retrieves the value for a field.
//
// For unpopulated scalars, it returns the default value, where
// the default value of a bytes scalar is guaranteed to be a copy.
// For unpopulated composite types, it returns an empty, read-only view
// of the value; to obtain a mutable reference, use Mutable.
func (x *fastReflection_LockupAccount) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value {
switch descriptor.FullName() {
case "cerc.types.v1.LockupAccount.base_account":
value := x.BaseAccount
return protoreflect.ValueOfMessage(value.ProtoReflect())
case "cerc.types.v1.LockupAccount.name":
value := x.Name
return protoreflect.ValueOfString(value)
case "cerc.types.v1.LockupAccount.distribution":
value := x.Distribution
return protoreflect.ValueOfString(value)
default:
if descriptor.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cerc.types.v1.LockupAccount"))
}
panic(fmt.Errorf("message cerc.types.v1.LockupAccount does not contain field %s", descriptor.FullName()))
}
}
// Set stores the value for a field.
//
// For a field belonging to a oneof, it implicitly clears any other field
// that may be currently set within the same oneof.
// For extension fields, it implicitly stores the provided ExtensionType.
// When setting a composite type, it is unspecified whether the stored value
// aliases the source's memory in any way. If the composite value is an
// empty, read-only value, then it panics.
//
// Set is a mutating operation and unsafe for concurrent use.
func (x *fastReflection_LockupAccount) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) {
switch fd.FullName() {
case "cerc.types.v1.LockupAccount.base_account":
x.BaseAccount = value.Message().Interface().(*types.BaseAccount)
case "cerc.types.v1.LockupAccount.name":
x.Name = value.Interface().(string)
case "cerc.types.v1.LockupAccount.distribution":
x.Distribution = value.Interface().(string)
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cerc.types.v1.LockupAccount"))
}
panic(fmt.Errorf("message cerc.types.v1.LockupAccount does not contain field %s", fd.FullName()))
}
}
// Mutable returns a mutable reference to a composite type.
//
// If the field is unpopulated, it may allocate a composite value.
// For a field belonging to a oneof, it implicitly clears any other field
// that may be currently set within the same oneof.
// For extension fields, it implicitly stores the provided ExtensionType
// if not already stored.
// It panics if the field does not contain a composite type.
//
// Mutable is a mutating operation and unsafe for concurrent use.
func (x *fastReflection_LockupAccount) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
switch fd.FullName() {
case "cerc.types.v1.LockupAccount.base_account":
if x.BaseAccount == nil {
x.BaseAccount = new(types.BaseAccount)
}
return protoreflect.ValueOfMessage(x.BaseAccount.ProtoReflect())
case "cerc.types.v1.LockupAccount.name":
panic(fmt.Errorf("field name of message cerc.types.v1.LockupAccount is not mutable"))
case "cerc.types.v1.LockupAccount.distribution":
panic(fmt.Errorf("field distribution of message cerc.types.v1.LockupAccount is not mutable"))
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cerc.types.v1.LockupAccount"))
}
panic(fmt.Errorf("message cerc.types.v1.LockupAccount does not contain field %s", fd.FullName()))
}
}
// NewField returns a new value that is assignable to the field
// for the given descriptor. For scalars, this returns the default value.
// For lists, maps, and messages, this returns a new, empty, mutable value.
func (x *fastReflection_LockupAccount) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
switch fd.FullName() {
case "cerc.types.v1.LockupAccount.base_account":
m := new(types.BaseAccount)
return protoreflect.ValueOfMessage(m.ProtoReflect())
case "cerc.types.v1.LockupAccount.name":
return protoreflect.ValueOfString("")
case "cerc.types.v1.LockupAccount.distribution":
return protoreflect.ValueOfString("")
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cerc.types.v1.LockupAccount"))
}
panic(fmt.Errorf("message cerc.types.v1.LockupAccount does not contain field %s", fd.FullName()))
}
}
// WhichOneof reports which field within the oneof is populated,
// returning nil if none are populated.
// It panics if the oneof descriptor does not belong to this message.
func (x *fastReflection_LockupAccount) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
switch d.FullName() {
default:
panic(fmt.Errorf("%s is not a oneof field in cerc.types.v1.LockupAccount", d.FullName()))
}
panic("unreachable")
}
// GetUnknown retrieves the entire list of unknown fields.
// The caller may only mutate the contents of the RawFields
// if the mutated bytes are stored back into the message with SetUnknown.
func (x *fastReflection_LockupAccount) GetUnknown() protoreflect.RawFields {
return x.unknownFields
}
// SetUnknown stores an entire list of unknown fields.
// The raw fields must be syntactically valid according to the wire format.
// An implementation may panic if this is not the case.
// Once stored, the caller must not mutate the content of the RawFields.
// An empty RawFields may be passed to clear the fields.
//
// SetUnknown is a mutating operation and unsafe for concurrent use.
func (x *fastReflection_LockupAccount) SetUnknown(fields protoreflect.RawFields) {
x.unknownFields = fields
}
// IsValid reports whether the message is valid.
//
// An invalid message is an empty, read-only value.
//
// An invalid message often corresponds to a nil pointer of the concrete
// message type, but the details are implementation dependent.
// Validity is not part of the protobuf data model, and may not
// be preserved in marshaling or other operations.
func (x *fastReflection_LockupAccount) IsValid() bool {
return x != nil
}
// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations.
// This method may return nil.
//
// The returned methods type is identical to
// "google.golang.org/protobuf/runtime/protoiface".Methods.
// Consult the protoiface package documentation for details.
func (x *fastReflection_LockupAccount) ProtoMethods() *protoiface.Methods {
size := func(input protoiface.SizeInput) protoiface.SizeOutput {
x := input.Message.Interface().(*LockupAccount)
if x == nil {
return protoiface.SizeOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Size: 0,
}
}
options := runtime.SizeInputToOptions(input)
_ = options
var n int
var l int
_ = l
if x.BaseAccount != nil {
l = options.Size(x.BaseAccount)
n += 1 + l + runtime.Sov(uint64(l))
}
l = len(x.Name)
if l > 0 {
n += 1 + l + runtime.Sov(uint64(l))
}
l = len(x.Distribution)
if l > 0 {
n += 1 + l + runtime.Sov(uint64(l))
}
if x.unknownFields != nil {
n += len(x.unknownFields)
}
return protoiface.SizeOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Size: n,
}
}
marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) {
x := input.Message.Interface().(*LockupAccount)
if x == nil {
return protoiface.MarshalOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Buf: input.Buf,
}, nil
}
options := runtime.MarshalInputToOptions(input)
_ = options
size := options.Size(x)
dAtA := make([]byte, size)
i := len(dAtA)
_ = i
var l int
_ = l
if x.unknownFields != nil {
i -= len(x.unknownFields)
copy(dAtA[i:], x.unknownFields)
}
if len(x.Distribution) > 0 {
i -= len(x.Distribution)
copy(dAtA[i:], x.Distribution)
i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Distribution)))
i--
dAtA[i] = 0x1a
}
if len(x.Name) > 0 {
i -= len(x.Name)
copy(dAtA[i:], x.Name)
i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Name)))
i--
dAtA[i] = 0x12
}
if x.BaseAccount != nil {
encoded, err := options.Marshal(x.BaseAccount)
if err != nil {
return protoiface.MarshalOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Buf: input.Buf,
}, err
}
i -= len(encoded)
copy(dAtA[i:], encoded)
i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded)))
i--
dAtA[i] = 0xa
}
if input.Buf != nil {
input.Buf = append(input.Buf, dAtA...)
} else {
input.Buf = dAtA
}
return protoiface.MarshalOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Buf: input.Buf,
}, nil
}
unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
x := input.Message.Interface().(*LockupAccount)
if x == nil {
return protoiface.UnmarshalOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Flags: input.Flags,
}, nil
}
options := runtime.UnmarshalInputToOptions(input)
_ = options
dAtA := input.Buf
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
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++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: LockupAccount: wiretype end group for non-group")
}
if fieldNum <= 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: LockupAccount: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field BaseAccount", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow
}
if iNdEx >= l {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
if postIndex > l {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
}
if x.BaseAccount == nil {
x.BaseAccount = &types.BaseAccount{}
}
if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.BaseAccount); err != nil {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
}
var stringLen uint64
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++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
if postIndex > l {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
}
x.Name = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Distribution", wireType)
}
var stringLen uint64
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++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
if postIndex > l {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
}
x.Distribution = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := runtime.Skip(dAtA[iNdEx:])
if err != nil {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
if (iNdEx + skippy) > l {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
}
if !options.DiscardUnknown {
x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
}
iNdEx += skippy
}
}
if iNdEx > l {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
}
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil
}
return &protoiface.Methods{
NoUnkeyedLiterals: struct{}{},
Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown,
Size: size,
Marshal: marshal,
Unmarshal: unmarshal,
Merge: nil,
CheckInitialized: nil,
}
}
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.0
// protoc (unknown)
// source: cerc/types/v1/lockup.proto
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// LockupAccount extends the Cosmos SDK BaseAccount with a name and distribution
// field. It satisfies the ModuleAccountI interface to allow querying it as a
// module account.
type LockupAccount struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
BaseAccount *types.BaseAccount `protobuf:"bytes,1,opt,name=base_account,json=baseAccount,proto3" json:"base_account,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Distribution string `protobuf:"bytes,3,opt,name=distribution,proto3" json:"distribution,omitempty"`
}
func (x *LockupAccount) Reset() {
*x = LockupAccount{}
if protoimpl.UnsafeEnabled {
mi := &file_cerc_types_v1_lockup_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LockupAccount) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LockupAccount) ProtoMessage() {}
// Deprecated: Use LockupAccount.ProtoReflect.Descriptor instead.
func (*LockupAccount) Descriptor() ([]byte, []int) {
return file_cerc_types_v1_lockup_proto_rawDescGZIP(), []int{0}
}
func (x *LockupAccount) GetBaseAccount() *types.BaseAccount {
if x != nil {
return x.BaseAccount
}
return nil
}
func (x *LockupAccount) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *LockupAccount) GetDistribution() string {
if x != nil {
return x.Distribution
}
return ""
}
var File_cerc_types_v1_lockup_proto protoreflect.FileDescriptor
var file_cerc_types_v1_lockup_proto_rawDesc = []byte{
0x0a, 0x1a, 0x63, 0x65, 0x72, 0x63, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f,
0x6c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x63, 0x65,
0x72, 0x63, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x1a, 0x11, 0x61, 0x6d, 0x69,
0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19,
0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73,
0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
0x73, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61,
0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
0x8b, 0x02, 0x0a, 0x0d, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x12, 0x49, 0x0a, 0x0c, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73,
0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61,
0x73, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x04, 0xd0, 0xde, 0x1f, 0x01, 0x52,
0x0b, 0x62, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x12, 0x22, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75,
0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x77, 0x88, 0xa0, 0x1f, 0x00, 0xca, 0xb4, 0x2d, 0x22, 0x63, 0x6f,
0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61,
0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49,
0xca, 0xb4, 0x2d, 0x1c, 0x63, 0x65, 0x72, 0x63, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76,
0x31, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49,
0x8a, 0xe7, 0xb0, 0x2a, 0x15, 0x6c, 0x61, 0x63, 0x6f, 0x6e, 0x69, 0x63, 0x2f, 0x4c, 0x6f, 0x63,
0x6b, 0x75, 0x70, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x92, 0xe7, 0xb0, 0x2a, 0x0e, 0x6c,
0x6f, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0xad, 0x01,
0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x65, 0x72, 0x63, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73,
0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4c, 0x6f, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f,
0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x2e, 0x76, 0x64, 0x62, 0x2e, 0x74, 0x6f, 0x2f, 0x63,
0x65, 0x72, 0x63, 0x2d, 0x69, 0x6f, 0x2f, 0x6c, 0x61, 0x63, 0x6f, 0x6e, 0x69, 0x63, 0x64, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x63, 0x65, 0x72, 0x63, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x76,
0x31, 0x3b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x54, 0x58, 0xaa,
0x02, 0x0d, 0x43, 0x65, 0x72, 0x63, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, 0x31, 0xca,
0x02, 0x0d, 0x43, 0x65, 0x72, 0x63, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5c, 0x56, 0x31, 0xe2,
0x02, 0x19, 0x43, 0x65, 0x72, 0x63, 0x5c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5c, 0x56, 0x31, 0x5c,
0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x43, 0x65,
0x72, 0x63, 0x3a, 0x3a, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_cerc_types_v1_lockup_proto_rawDescOnce sync.Once
file_cerc_types_v1_lockup_proto_rawDescData = file_cerc_types_v1_lockup_proto_rawDesc
)
func file_cerc_types_v1_lockup_proto_rawDescGZIP() []byte {
file_cerc_types_v1_lockup_proto_rawDescOnce.Do(func() {
file_cerc_types_v1_lockup_proto_rawDescData = protoimpl.X.CompressGZIP(file_cerc_types_v1_lockup_proto_rawDescData)
})
return file_cerc_types_v1_lockup_proto_rawDescData
}
var file_cerc_types_v1_lockup_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_cerc_types_v1_lockup_proto_goTypes = []interface{}{
(*LockupAccount)(nil), // 0: cerc.types.v1.LockupAccount
(*types.BaseAccount)(nil), // 1: cosmos.auth.v1beta1.BaseAccount
}
var file_cerc_types_v1_lockup_proto_depIdxs = []int32{
1, // 0: cerc.types.v1.LockupAccount.base_account:type_name -> cosmos.auth.v1beta1.BaseAccount
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_cerc_types_v1_lockup_proto_init() }
func file_cerc_types_v1_lockup_proto_init() {
if File_cerc_types_v1_lockup_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_cerc_types_v1_lockup_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LockupAccount); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_cerc_types_v1_lockup_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_cerc_types_v1_lockup_proto_goTypes,
DependencyIndexes: file_cerc_types_v1_lockup_proto_depIdxs,
MessageInfos: file_cerc_types_v1_lockup_proto_msgTypes,
}.Build()
File_cerc_types_v1_lockup_proto = out.File
file_cerc_types_v1_lockup_proto_rawDesc = nil
file_cerc_types_v1_lockup_proto_goTypes = nil
file_cerc_types_v1_lockup_proto_depIdxs = nil
}

View File

@ -18,6 +18,7 @@ import (
bondkeeper "git.vdb.to/cerc-io/laconicd/x/bond/keeper"
onboardingkeeper "git.vdb.to/cerc-io/laconicd/x/onboarding/keeper"
registrykeeper "git.vdb.to/cerc-io/laconicd/x/registry/keeper"
types "git.vdb.to/cerc-io/laconicd/x/types/v1"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
@ -27,9 +28,11 @@ import (
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
@ -174,6 +177,10 @@ func NewLaconicApp(
return nil, err
}
// Register custom interfaces
RegisterCustomInterfaces(app.interfaceRegistry)
RegisterCustomLegacyAminoCodec(app.legacyAmino)
app.App = appBuilder.Build(db, traceStore, baseAppOptions...)
// register streaming services
@ -241,6 +248,42 @@ func (app *LaconicApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.AP
}
}
func RegisterCustomInterfaces(interfaceRegistry codectypes.InterfaceRegistry) {
// Custom LockupAccount type needs to be registered to be able to use it as a genesis account
interfaceRegistry.RegisterImplementations((*authtypes.GenesisAccount)(nil), &types.LockupAccount{})
// LockupAccount extends auth Account
interfaceRegistry.RegisterInterface(
"cosmos.auth.v1beta1.AccountI",
(*sdk.AccountI)(nil),
&types.LockupAccount{},
)
// LockupAccount extends auth ModuleAccount
interfaceRegistry.RegisterInterface(
"cosmos.auth.v1beta1.ModuleAccountI",
(*sdk.ModuleAccountI)(nil),
&types.LockupAccount{},
)
interfaceRegistry.RegisterInterface(
"cosmos.auth.v1beta1.GenesisAccount",
(*authtypes.GenesisAccount)(nil),
&types.LockupAccount{},
)
interfaceRegistry.RegisterInterface(
"cerc.types.v1.LockupAccountI",
(*types.LockupAccountI)(nil),
&types.LockupAccount{},
)
}
func RegisterCustomLegacyAminoCodec(registrar *codec.LegacyAmino) {
registrar.RegisterInterface((*types.LockupAccountI)(nil), nil)
registrar.RegisterConcrete(&types.LockupAccount{}, "laconic/LockupAccount", nil)
}
// setCustomAnteHandler overwrites default ante handlers with custom ante handlers
// Reference: https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/x/auth/tx/config/config.go#L149
func (app *LaconicApp) setCustomAnteHandler() {

View File

@ -33,6 +33,7 @@ modules:
- account: registry
- account: record_rent
- account: authority_rent
- account: lps_lockup
- name: bank
config:
"@type": cosmos.bank.module.v1.Module

View File

@ -0,0 +1,154 @@
package cmd
import (
"encoding/json"
"fmt"
"os"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server"
"github.com/spf13/cobra"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
types "git.vdb.to/cerc-io/laconicd/x/types/v1"
)
const (
flagAppendMode = "append"
)
// AddGenesisLockupAccountCmd returns add-genesis-lockup-account cobra Command.
func AddGenesisLockupAccountCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "add-genesis-lockup-account <account_name> <distribution-json-file> <coin>[,<coin>...]",
Short: "Add genesis lockup account with give name",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx := client.GetClientContextFromCmd(cmd)
serverCtx := server.GetServerContextFromCmd(cmd)
config := serverCtx.Config
config.SetRoot(clientCtx.HomeDir)
moduleName := args[0]
distributionFilePath := args[1]
var distribution map[string]interface{}
distributionBytes, err := os.ReadFile(distributionFilePath)
if err != nil {
return fmt.Errorf("failed to read %s file: %w", distributionFilePath, err)
}
if err = json.Unmarshal(distributionBytes, &distribution); err != nil {
return fmt.Errorf("distribution is invalid json: %v", err)
}
appendflag, _ := cmd.Flags().GetBool(flagAppendMode)
return AddGenesisLockupAccount(clientCtx.Codec, moduleName, string(distributionBytes), appendflag, config.GenesisFile(), args[2])
},
}
cmd.Flags().Bool(flagAppendMode, false, "append the coins to an account already in the genesis.json file")
return cmd
}
func AddGenesisLockupAccount(
cdc codec.Codec,
moduleName string,
distribution string,
appendAcct bool,
genesisFileURL, amountStr string,
) error {
coins, err := sdk.ParseCoinsNormalized(amountStr)
if err != nil {
return fmt.Errorf("failed to parse coins: %w", err)
}
// create concrete account type based on input parameters
moduleAccount := authtypes.NewEmptyModuleAccount(moduleName)
accAddr := moduleAccount.GetAddress()
balances := banktypes.Balance{Address: accAddr.String(), Coins: coins.Sort()}
genAccount := &types.LockupAccount{
BaseAccount: moduleAccount.BaseAccount,
Name: moduleAccount.Name,
Distribution: distribution,
}
if err := genAccount.Validate(); err != nil {
return fmt.Errorf("failed to validate new genesis account: %w", err)
}
appState, appGenesis, err := genutiltypes.GenesisStateFromGenFile(genesisFileURL)
if err != nil {
return fmt.Errorf("failed to unmarshal genesis state: %w", err)
}
authGenState := authtypes.GetGenesisStateFromAppState(cdc, appState)
accs, err := authtypes.UnpackAccounts(authGenState.Accounts)
if err != nil {
return fmt.Errorf("failed to get accounts from any: %w", err)
}
bankGenState := banktypes.GetGenesisStateFromAppState(cdc, appState)
if accs.Contains(accAddr) {
if !appendAcct {
return fmt.Errorf(" Account %s already exists\nUse `append` flag to append account at existing address", accAddr)
}
genesisB := banktypes.GetGenesisStateFromAppState(cdc, appState)
for idx, acc := range genesisB.Balances {
if acc.Address != accAddr.String() {
continue
}
updatedCoins := acc.Coins.Add(coins...)
bankGenState.Balances[idx] = banktypes.Balance{Address: accAddr.String(), Coins: updatedCoins.Sort()}
break
}
} else {
// Add the new account to the set of genesis accounts and sanitize the accounts afterwards.
accs = append(accs, genAccount)
accs = authtypes.SanitizeGenesisAccounts(accs)
genAccs, err := authtypes.PackAccounts(accs)
if err != nil {
return fmt.Errorf("failed to convert accounts into any's: %w", err)
}
authGenState.Accounts = genAccs
authGenStateBz, err := cdc.MarshalJSON(&authGenState)
if err != nil {
return fmt.Errorf("failed to marshal auth genesis state: %w", err)
}
appState[authtypes.ModuleName] = authGenStateBz
bankGenState.Balances = append(bankGenState.Balances, balances)
}
bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances)
bankGenState.Supply = bankGenState.Supply.Add(balances.Coins...)
bankGenStateBz, err := cdc.MarshalJSON(bankGenState)
if err != nil {
return fmt.Errorf("failed to marshal bank genesis state: %w", err)
}
appState[banktypes.ModuleName] = bankGenStateBz
appStateJSON, err := json.Marshal(appState)
if err != nil {
return fmt.Errorf("failed to marshal application genesis state: %w", err)
}
appGenesis.AppState = appStateJSON
return genutil.ExportGenesisFile(appGenesis, genesisFileURL)
}

View File

@ -58,10 +58,14 @@ func initRootCmd(rootCmd *cobra.Command, txConfig client.TxConfig, basicManager
startCmd.RunE = newStartCmd.RunE
})
// Capture the genesis command from genutilcli and add new commands
genesisCmd := genutilcli.Commands(txConfig, basicManager, app.DefaultNodeHome)
genesisCmd.AddCommand(AddGenesisLockupAccountCmd())
// add keybase, auxiliary RPC, query, genesis, and tx child commands
rootCmd.AddCommand(
server.StatusCommand(),
genutilcli.Commands(txConfig, basicManager, app.DefaultNodeHome),
genesisCmd,
queryCommand(),
txCommand(),
keys.Commands(),

View File

@ -25,11 +25,12 @@ import (
"github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
txmodule "github.com/cosmos/cosmos-sdk/x/auth/tx/config"
"github.com/cosmos/cosmos-sdk/x/auth/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"git.vdb.to/cerc-io/laconicd/app"
"git.vdb.to/cerc-io/laconicd/app/params"
"git.vdb.to/cerc-io/laconicd/gql"
types "git.vdb.to/cerc-io/laconicd/x/types/v1"
)
const EnvPrefix = "LACONIC"
@ -135,7 +136,7 @@ func ProvideClientContext(
WithTxConfig(txConfig).
WithLegacyAmino(legacyAmino).
WithInput(os.Stdin).
WithAccountRetriever(types.AccountRetriever{}).
WithAccountRetriever(authtypes.AccountRetriever{}).
WithHomeDir(app.DefaultNodeHome).
WithViper(EnvPrefix) // env variable prefix
@ -148,6 +149,10 @@ func ProvideClientContext(
clientCtx.HomeDir = ""
clientCtx.KeyringDir = ""
// Custom LockupAccount type needs to be registered
interfaceRegistry.RegisterImplementations((*types.LockupAccountI)(nil), &types.LockupAccount{})
interfaceRegistry.RegisterImplementations((*authtypes.GenesisAccount)(nil), &types.LockupAccount{})
return clientCtx
}

47
lockup.md Normal file
View File

@ -0,0 +1,47 @@
# Lockup Account Usage
* Add a genesis lockup account:
```bash
laconicd genesis add-genesis-lockup-account <account_name> <distribution-json-file> <coin>[,<coin>...]
# Example
# laconicd genesis add-genesis-lockup-account lps_lockup distribution.json 1000alps
```
* This adds a `LockupAccount` with given name and balance in the genesis file
* The lockup account can be queried as shown below once the chain starts
* Query a lockup account:
```bash
laconicd query auth module-account <account_name>
# Example
# laconicd query auth module-account lps_lockup
# account:
# type: laconic/LockupAccount
# value:
# base_account:
# account_number: "1"
# address: laconic1mprsxp9jqe0d0lp88fxuccthwgy7tqgt5x9y65
# distribution: |-
# {
# ...
```
* Query a lockup account's balance:
```bash
laconicd query bank balances <address>
# Example
lockup_account_address=$(laconicd query auth module-account lps_lockup -o json | jq -r '.account.value.base_account.address')
laconicd query bank balances $lockup_account_address
balances:
- amount: "1000"
denom: alps
pagination:
total: "1"
```

View File

@ -0,0 +1,26 @@
syntax = "proto3";
package cerc.types.v1;
import "amino/amino.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/auth/v1beta1/auth.proto";
import "gogoproto/gogo.proto";
option go_package = "git.vdb.to/cerc-io/laconicd/x/types/v1";
// LockupAccount extends the Cosmos SDK BaseAccount with a name and distribution
// field. It satisfies the ModuleAccountI interface to allow querying it as a
// module account.
message LockupAccount {
option (amino.name) = "laconic/LockupAccount";
option (amino.message_encoding) = "lockup_account";
option (gogoproto.goproto_getters) = false;
option (cosmos_proto.implements_interface) =
"cosmos.auth.v1beta1.ModuleAccountI";
option (cosmos_proto.implements_interface) = "cerc.types.v1.LockupAccountI";
cosmos.auth.v1beta1.BaseAccount base_account = 1 [ (gogoproto.embed) = true ];
string name = 2;
string distribution = 3;
}

51
x/types/v1/lockup.go Normal file
View File

@ -0,0 +1,51 @@
package v1
import (
"errors"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
var (
_ authtypes.GenesisAccount = (*LockupAccount)(nil)
_ LockupAccountI = (*LockupAccount)(nil)
)
// LockupAccountI defines an account interface for lockup account with token distribution
type LockupAccountI interface {
sdk.ModuleAccountI
GetDistribution() string
}
// Validate checks for errors on the account fields
func (la LockupAccount) Validate() error {
if la.BaseAccount == nil {
return errors.New("uninitialized LockupAccount: BaseAccount is nil")
}
return la.BaseAccount.Validate()
}
// HasPermission returns whether or not the account has permission.
// Return false as the lockup account doesn't have any permissions
func (la LockupAccount) HasPermission(permission string) bool {
return false
}
// GetName returns the name of the holder's module
func (la LockupAccount) GetName() string {
return la.Name
}
// GetPermissions returns permissions granted to the module account
// Return empty as the lockup account doesn't have any permissions
func (la LockupAccount) GetPermissions() []string {
return []string{}
}
// GetDistribution returns the total token distribution
func (la LockupAccount) GetDistribution() string {
return la.Distribution
}

422
x/types/v1/lockup.pb.go Normal file
View File

@ -0,0 +1,422 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cerc/types/v1/lockup.proto
package v1
import (
fmt "fmt"
_ "github.com/cosmos/cosmos-proto"
_ "github.com/cosmos/cosmos-sdk/types/tx/amino"
types "github.com/cosmos/cosmos-sdk/x/auth/types"
_ "github.com/cosmos/gogoproto/gogoproto"
proto "github.com/cosmos/gogoproto/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// LockupAccount extends the Cosmos SDK BaseAccount with a name and distribution
// field. It satisfies the ModuleAccountI interface to allow querying it as a
// module account.
type LockupAccount struct {
*types.BaseAccount `protobuf:"bytes,1,opt,name=base_account,json=baseAccount,proto3,embedded=base_account" json:"base_account,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Distribution string `protobuf:"bytes,3,opt,name=distribution,proto3" json:"distribution,omitempty"`
}
func (m *LockupAccount) Reset() { *m = LockupAccount{} }
func (m *LockupAccount) String() string { return proto.CompactTextString(m) }
func (*LockupAccount) ProtoMessage() {}
func (*LockupAccount) Descriptor() ([]byte, []int) {
return fileDescriptor_8fa58dc19f6348bf, []int{0}
}
func (m *LockupAccount) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *LockupAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_LockupAccount.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 *LockupAccount) XXX_Merge(src proto.Message) {
xxx_messageInfo_LockupAccount.Merge(m, src)
}
func (m *LockupAccount) XXX_Size() int {
return m.Size()
}
func (m *LockupAccount) XXX_DiscardUnknown() {
xxx_messageInfo_LockupAccount.DiscardUnknown(m)
}
var xxx_messageInfo_LockupAccount proto.InternalMessageInfo
func init() {
proto.RegisterType((*LockupAccount)(nil), "cerc.types.v1.LockupAccount")
}
func init() { proto.RegisterFile("cerc/types/v1/lockup.proto", fileDescriptor_8fa58dc19f6348bf) }
var fileDescriptor_8fa58dc19f6348bf = []byte{
// 335 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4a, 0x4e, 0x2d, 0x4a,
0xd6, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x2f, 0x33, 0xd4, 0xcf, 0xc9, 0x4f, 0xce, 0x2e, 0x2d,
0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x05, 0xc9, 0xe9, 0x81, 0xe5, 0xf4, 0xca, 0x0c,
0xa5, 0x04, 0x13, 0x73, 0x33, 0xf3, 0xf2, 0xf5, 0xc1, 0x24, 0x44, 0x85, 0x94, 0x64, 0x72, 0x7e,
0x71, 0x6e, 0x7e, 0x71, 0x3c, 0x98, 0xa7, 0x0f, 0xe1, 0x40, 0xa5, 0xe4, 0x20, 0x3c, 0xfd, 0xc4,
0xd2, 0x92, 0x0c, 0xfd, 0x32, 0xc3, 0xa4, 0xd4, 0x92, 0x44, 0x43, 0x30, 0x07, 0x2a, 0x2f, 0x92,
0x9e, 0x9f, 0x9e, 0x0f, 0xd1, 0x07, 0x62, 0x41, 0x44, 0x95, 0xba, 0x99, 0xb8, 0x78, 0x7d, 0xc0,
0x6e, 0x70, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0x11, 0xf2, 0xe4, 0xe2, 0x49, 0x4a, 0x2c, 0x4e,
0x8d, 0x4f, 0x84, 0xf0, 0x25, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, 0x14, 0xf4, 0xa0, 0x96, 0x81,
0x4d, 0x84, 0x1a, 0xaf, 0xe7, 0x94, 0x58, 0x9c, 0x0a, 0xd5, 0xe7, 0xc4, 0x72, 0xe1, 0x9e, 0x3c,
0x63, 0x10, 0x77, 0x12, 0x42, 0x48, 0x48, 0x88, 0x8b, 0x25, 0x2f, 0x31, 0x37, 0x55, 0x82, 0x49,
0x81, 0x51, 0x83, 0x33, 0x08, 0xcc, 0x16, 0x52, 0xe2, 0xe2, 0x49, 0xc9, 0x2c, 0x2e, 0x29, 0xca,
0x4c, 0x2a, 0x2d, 0xc9, 0xcc, 0xcf, 0x93, 0x60, 0x06, 0xcb, 0xa1, 0x88, 0x59, 0x95, 0x77, 0x2c,
0x90, 0x67, 0x38, 0xb5, 0x45, 0x57, 0x09, 0x9b, 0x9d, 0xbe, 0xf9, 0x29, 0xa5, 0x39, 0x30, 0x2b,
0x3c, 0x4f, 0x6d, 0xd1, 0x95, 0x41, 0x09, 0x35, 0x3d, 0x14, 0xdf, 0x78, 0x76, 0x3d, 0xdf, 0xa0,
0x25, 0x9a, 0x93, 0x98, 0x9c, 0x9f, 0x97, 0x99, 0xac, 0x8f, 0x22, 0x35, 0xe9, 0xf9, 0x06, 0x2d,
0x3e, 0x48, 0xf0, 0xc3, 0xfc, 0xea, 0xe4, 0x70, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c,
0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72,
0x0c, 0x51, 0x6a, 0xe9, 0x99, 0x25, 0x7a, 0x65, 0x29, 0x49, 0x7a, 0xa0, 0x60, 0x4f, 0x2d, 0x4a,
0xd6, 0xcd, 0xcc, 0xd7, 0x87, 0x1a, 0x9b, 0xa2, 0x5f, 0x01, 0x8f, 0xcf, 0x24, 0x36, 0x70, 0xb0,
0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x2e, 0x89, 0x9d, 0x6b, 0xe7, 0x01, 0x00, 0x00,
}
func (m *LockupAccount) 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 *LockupAccount) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *LockupAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Distribution) > 0 {
i -= len(m.Distribution)
copy(dAtA[i:], m.Distribution)
i = encodeVarintLockup(dAtA, i, uint64(len(m.Distribution)))
i--
dAtA[i] = 0x1a
}
if len(m.Name) > 0 {
i -= len(m.Name)
copy(dAtA[i:], m.Name)
i = encodeVarintLockup(dAtA, i, uint64(len(m.Name)))
i--
dAtA[i] = 0x12
}
if m.BaseAccount != nil {
{
size, err := m.BaseAccount.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintLockup(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintLockup(dAtA []byte, offset int, v uint64) int {
offset -= sovLockup(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *LockupAccount) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.BaseAccount != nil {
l = m.BaseAccount.Size()
n += 1 + l + sovLockup(uint64(l))
}
l = len(m.Name)
if l > 0 {
n += 1 + l + sovLockup(uint64(l))
}
l = len(m.Distribution)
if l > 0 {
n += 1 + l + sovLockup(uint64(l))
}
return n
}
func sovLockup(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozLockup(x uint64) (n int) {
return sovLockup(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *LockupAccount) 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 ErrIntOverflowLockup
}
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: LockupAccount: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: LockupAccount: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field BaseAccount", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowLockup
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthLockup
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthLockup
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.BaseAccount == nil {
m.BaseAccount = &types.BaseAccount{}
}
if err := m.BaseAccount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowLockup
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthLockup
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthLockup
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Name = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Distribution", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowLockup
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthLockup
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthLockup
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Distribution = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipLockup(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthLockup
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipLockup(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowLockup
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowLockup
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowLockup
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthLockup
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupLockup
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthLockup
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthLockup = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowLockup = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupLockup = fmt.Errorf("proto: unexpected end of group")
)