Add a custom lockup account to hold locked tokens (#72)

Part of https://www.notion.so/Lockup-LPS-tokens-into-a-module-account-1f2a6b22d472802cbb35e8ce052d22ca

- Added a command to create the custom lockup account in genesis:
  ```bash
  laconicd genesis add-genesis-lockup-account <account_name> <distribution-json-file> <coin>[,<coin>...]
  ```

Reviewed-on: cerc-io/laconicd#72
Co-authored-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
Co-committed-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
This commit is contained in:
2025-05-16 09:26:10 +00:00
committed by nabarun
parent 7af9e9d496
commit 59236e5ce6
12 changed files with 1514 additions and 4 deletions
+51
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
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")
)