feat(accounts): use account number as state prefix for account state (#18664)

Co-authored-by: unknown unknown <unknown@unknown>
This commit is contained in:
testinginprod 2023-12-11 12:44:01 +01:00 committed by GitHub
parent 8b894f73b1
commit 39865d852f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 223 additions and 91 deletions

View File

@ -554,62 +554,63 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods {
}
}
var _ protoreflect.List = (*_GenesisAccount_3_list)(nil)
var _ protoreflect.List = (*_GenesisAccount_4_list)(nil)
type _GenesisAccount_3_list struct {
type _GenesisAccount_4_list struct {
list *[]*KVPair
}
func (x *_GenesisAccount_3_list) Len() int {
func (x *_GenesisAccount_4_list) Len() int {
if x.list == nil {
return 0
}
return len(*x.list)
}
func (x *_GenesisAccount_3_list) Get(i int) protoreflect.Value {
func (x *_GenesisAccount_4_list) Get(i int) protoreflect.Value {
return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect())
}
func (x *_GenesisAccount_3_list) Set(i int, value protoreflect.Value) {
func (x *_GenesisAccount_4_list) Set(i int, value protoreflect.Value) {
valueUnwrapped := value.Message()
concreteValue := valueUnwrapped.Interface().(*KVPair)
(*x.list)[i] = concreteValue
}
func (x *_GenesisAccount_3_list) Append(value protoreflect.Value) {
func (x *_GenesisAccount_4_list) Append(value protoreflect.Value) {
valueUnwrapped := value.Message()
concreteValue := valueUnwrapped.Interface().(*KVPair)
*x.list = append(*x.list, concreteValue)
}
func (x *_GenesisAccount_3_list) AppendMutable() protoreflect.Value {
func (x *_GenesisAccount_4_list) AppendMutable() protoreflect.Value {
v := new(KVPair)
*x.list = append(*x.list, v)
return protoreflect.ValueOfMessage(v.ProtoReflect())
}
func (x *_GenesisAccount_3_list) Truncate(n int) {
func (x *_GenesisAccount_4_list) Truncate(n int) {
for i := n; i < len(*x.list); i++ {
(*x.list)[i] = nil
}
*x.list = (*x.list)[:n]
}
func (x *_GenesisAccount_3_list) NewElement() protoreflect.Value {
func (x *_GenesisAccount_4_list) NewElement() protoreflect.Value {
v := new(KVPair)
return protoreflect.ValueOfMessage(v.ProtoReflect())
}
func (x *_GenesisAccount_3_list) IsValid() bool {
func (x *_GenesisAccount_4_list) IsValid() bool {
return x.list != nil
}
var (
md_GenesisAccount protoreflect.MessageDescriptor
fd_GenesisAccount_address protoreflect.FieldDescriptor
fd_GenesisAccount_account_type protoreflect.FieldDescriptor
fd_GenesisAccount_state protoreflect.FieldDescriptor
md_GenesisAccount protoreflect.MessageDescriptor
fd_GenesisAccount_address protoreflect.FieldDescriptor
fd_GenesisAccount_account_type protoreflect.FieldDescriptor
fd_GenesisAccount_account_number protoreflect.FieldDescriptor
fd_GenesisAccount_state protoreflect.FieldDescriptor
)
func init() {
@ -617,6 +618,7 @@ func init() {
md_GenesisAccount = File_cosmos_accounts_v1_genesis_proto.Messages().ByName("GenesisAccount")
fd_GenesisAccount_address = md_GenesisAccount.Fields().ByName("address")
fd_GenesisAccount_account_type = md_GenesisAccount.Fields().ByName("account_type")
fd_GenesisAccount_account_number = md_GenesisAccount.Fields().ByName("account_number")
fd_GenesisAccount_state = md_GenesisAccount.Fields().ByName("state")
}
@ -697,8 +699,14 @@ func (x *fastReflection_GenesisAccount) Range(f func(protoreflect.FieldDescripto
return
}
}
if x.AccountNumber != uint64(0) {
value := protoreflect.ValueOfUint64(x.AccountNumber)
if !f(fd_GenesisAccount_account_number, value) {
return
}
}
if len(x.State) != 0 {
value := protoreflect.ValueOfList(&_GenesisAccount_3_list{list: &x.State})
value := protoreflect.ValueOfList(&_GenesisAccount_4_list{list: &x.State})
if !f(fd_GenesisAccount_state, value) {
return
}
@ -722,6 +730,8 @@ func (x *fastReflection_GenesisAccount) Has(fd protoreflect.FieldDescriptor) boo
return x.Address != ""
case "cosmos.accounts.v1.GenesisAccount.account_type":
return x.AccountType != ""
case "cosmos.accounts.v1.GenesisAccount.account_number":
return x.AccountNumber != uint64(0)
case "cosmos.accounts.v1.GenesisAccount.state":
return len(x.State) != 0
default:
@ -744,6 +754,8 @@ func (x *fastReflection_GenesisAccount) Clear(fd protoreflect.FieldDescriptor) {
x.Address = ""
case "cosmos.accounts.v1.GenesisAccount.account_type":
x.AccountType = ""
case "cosmos.accounts.v1.GenesisAccount.account_number":
x.AccountNumber = uint64(0)
case "cosmos.accounts.v1.GenesisAccount.state":
x.State = nil
default:
@ -768,11 +780,14 @@ func (x *fastReflection_GenesisAccount) Get(descriptor protoreflect.FieldDescrip
case "cosmos.accounts.v1.GenesisAccount.account_type":
value := x.AccountType
return protoreflect.ValueOfString(value)
case "cosmos.accounts.v1.GenesisAccount.account_number":
value := x.AccountNumber
return protoreflect.ValueOfUint64(value)
case "cosmos.accounts.v1.GenesisAccount.state":
if len(x.State) == 0 {
return protoreflect.ValueOfList(&_GenesisAccount_3_list{})
return protoreflect.ValueOfList(&_GenesisAccount_4_list{})
}
listValue := &_GenesisAccount_3_list{list: &x.State}
listValue := &_GenesisAccount_4_list{list: &x.State}
return protoreflect.ValueOfList(listValue)
default:
if descriptor.IsExtension() {
@ -798,9 +813,11 @@ func (x *fastReflection_GenesisAccount) Set(fd protoreflect.FieldDescriptor, val
x.Address = value.Interface().(string)
case "cosmos.accounts.v1.GenesisAccount.account_type":
x.AccountType = value.Interface().(string)
case "cosmos.accounts.v1.GenesisAccount.account_number":
x.AccountNumber = value.Uint()
case "cosmos.accounts.v1.GenesisAccount.state":
lv := value.List()
clv := lv.(*_GenesisAccount_3_list)
clv := lv.(*_GenesisAccount_4_list)
x.State = *clv.list
default:
if fd.IsExtension() {
@ -826,12 +843,14 @@ func (x *fastReflection_GenesisAccount) Mutable(fd protoreflect.FieldDescriptor)
if x.State == nil {
x.State = []*KVPair{}
}
value := &_GenesisAccount_3_list{list: &x.State}
value := &_GenesisAccount_4_list{list: &x.State}
return protoreflect.ValueOfList(value)
case "cosmos.accounts.v1.GenesisAccount.address":
panic(fmt.Errorf("field address of message cosmos.accounts.v1.GenesisAccount is not mutable"))
case "cosmos.accounts.v1.GenesisAccount.account_type":
panic(fmt.Errorf("field account_type of message cosmos.accounts.v1.GenesisAccount is not mutable"))
case "cosmos.accounts.v1.GenesisAccount.account_number":
panic(fmt.Errorf("field account_number of message cosmos.accounts.v1.GenesisAccount is not mutable"))
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.accounts.v1.GenesisAccount"))
@ -849,9 +868,11 @@ func (x *fastReflection_GenesisAccount) NewField(fd protoreflect.FieldDescriptor
return protoreflect.ValueOfString("")
case "cosmos.accounts.v1.GenesisAccount.account_type":
return protoreflect.ValueOfString("")
case "cosmos.accounts.v1.GenesisAccount.account_number":
return protoreflect.ValueOfUint64(uint64(0))
case "cosmos.accounts.v1.GenesisAccount.state":
list := []*KVPair{}
return protoreflect.ValueOfList(&_GenesisAccount_3_list{list: &list})
return protoreflect.ValueOfList(&_GenesisAccount_4_list{list: &list})
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.accounts.v1.GenesisAccount"))
@ -929,6 +950,9 @@ func (x *fastReflection_GenesisAccount) ProtoMethods() *protoiface.Methods {
if l > 0 {
n += 1 + l + runtime.Sov(uint64(l))
}
if x.AccountNumber != 0 {
n += 1 + runtime.Sov(uint64(x.AccountNumber))
}
if len(x.State) > 0 {
for _, e := range x.State {
l = options.Size(e)
@ -977,9 +1001,14 @@ func (x *fastReflection_GenesisAccount) ProtoMethods() *protoiface.Methods {
copy(dAtA[i:], encoded)
i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded)))
i--
dAtA[i] = 0x1a
dAtA[i] = 0x22
}
}
if x.AccountNumber != 0 {
i = runtime.EncodeVarint(dAtA, i, uint64(x.AccountNumber))
i--
dAtA[i] = 0x18
}
if len(x.AccountType) > 0 {
i -= len(x.AccountType)
copy(dAtA[i:], x.AccountType)
@ -1108,6 +1137,25 @@ func (x *fastReflection_GenesisAccount) ProtoMethods() *protoiface.Methods {
x.AccountType = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field AccountNumber", wireType)
}
x.AccountNumber = 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.AccountNumber |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 2 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field State", wireType)
}
@ -1733,8 +1781,10 @@ type GenesisAccount struct {
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
// account_type is the account type of the account.
AccountType string `protobuf:"bytes,2,opt,name=account_type,json=accountType,proto3" json:"account_type,omitempty"`
// account_number is the account number of the account.
AccountNumber uint64 `protobuf:"varint,3,opt,name=account_number,json=accountNumber,proto3" json:"account_number,omitempty"`
// state is the account state represented as a slice of raw key value byte pairs.
State []*KVPair `protobuf:"bytes,3,rep,name=state,proto3" json:"state,omitempty"`
State []*KVPair `protobuf:"bytes,4,rep,name=state,proto3" json:"state,omitempty"`
}
func (x *GenesisAccount) Reset() {
@ -1771,6 +1821,13 @@ func (x *GenesisAccount) GetAccountType() string {
return ""
}
func (x *GenesisAccount) GetAccountNumber() uint64 {
if x != nil {
return x.AccountNumber
}
return 0
}
func (x *GenesisAccount) GetState() []*KVPair {
if x != nil {
return x.State
@ -1837,31 +1894,34 @@ var file_cosmos_accounts_v1_genesis_proto_rawDesc = []byte{
0x08, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x41, 0x63, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x52, 0x08, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x7f, 0x0a,
0x0e, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12,
0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x05,
0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6f,
0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31,
0x2e, 0x4b, 0x56, 0x50, 0x61, 0x69, 0x72, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x30,
0x0a, 0x06, 0x4b, 0x56, 0x50, 0x61, 0x69, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x42, 0xc0, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e,
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e,
0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x63, 0x6f, 0x73,
0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f,
0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x31,
0x3b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x41,
0x58, 0xaa, 0x02, 0x12, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c,
0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1e, 0x43, 0x6f,
0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5c, 0x56, 0x31,
0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, 0x43,
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x3a,
0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x75, 0x6e, 0x74, 0x52, 0x08, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0xa6, 0x01,
0x0a, 0x0e, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a,
0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18,
0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x75,
0x6d, 0x62, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x56, 0x50, 0x61, 0x69, 0x72, 0x52,
0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x30, 0x0a, 0x06, 0x4b, 0x56, 0x50, 0x61, 0x69, 0x72,
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b,
0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0xc0, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d,
0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
0x2e, 0x76, 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74,
0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69,
0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x41, 0x58, 0xaa, 0x02, 0x12, 0x43, 0x6f, 0x73, 0x6d,
0x6f, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02,
0x12, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61,
0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x14, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41,
0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
}
var (

View File

@ -18,8 +18,10 @@ message GenesisAccount {
string address = 1;
// account_type is the account type of the account.
string account_type = 2;
// account_number is the account number of the account.
uint64 account_number = 3;
// state is the account state represented as a slice of raw key value byte pairs.
repeated KVPair state = 3;
repeated KVPair state = 4;
}
// KVPair defines a key value pair.

View File

@ -12,8 +12,8 @@ import (
"cosmossdk.io/store/v2"
"cosmossdk.io/store/v2/commitment"
"cosmossdk.io/store/v2/commitment/iavl"
"cosmossdk.io/store/v2/storage"
"cosmossdk.io/store/v2/pruning"
"cosmossdk.io/store/v2/storage"
"cosmossdk.io/store/v2/storage/sqlite"
)

View File

@ -19,8 +19,12 @@ func (k Keeper) ExportState(ctx context.Context) (*v1.GenesisState, error) {
genState.AccountNumber = accountNumber
err = k.AccountsByType.Walk(ctx, nil, func(key []byte, value string) (stop bool, err error) {
accState, err := k.exportAccount(ctx, key, value)
err = k.AccountsByType.Walk(ctx, nil, func(accAddr []byte, accType string) (stop bool, err error) {
accNum, err := k.AccountByNumber.Get(ctx, accAddr)
if err != nil {
return true, err
}
accState, err := k.exportAccount(ctx, accAddr, accType, accNum)
if err != nil {
return true, err
}
@ -34,20 +38,21 @@ func (k Keeper) ExportState(ctx context.Context) (*v1.GenesisState, error) {
return genState, nil
}
func (k Keeper) exportAccount(ctx context.Context, addr []byte, accType string) (*v1.GenesisAccount, error) {
func (k Keeper) exportAccount(ctx context.Context, addr []byte, accType string, accNum uint64) (*v1.GenesisAccount, error) {
addrString, err := k.addressCodec.BytesToString(addr)
if err != nil {
return nil, err
}
account := &v1.GenesisAccount{
Address: addrString,
AccountType: accType,
Address: addrString,
AccountType: accType,
AccountNumber: accNum,
State: nil,
}
rng := new(collections.Range[[]byte]).
Prefix(addr)
err = k.AccountsState.Walk(ctx, rng, func(key, value []byte) (stop bool, err error) {
rng := collections.NewPrefixedPairRange[uint64, []byte](accNum)
err = k.AccountsState.Walk(ctx, rng, func(key collections.Pair[uint64, []byte], value []byte) (stop bool, err error) {
account.State = append(account.State, &v1.KVPair{
Key: key,
Key: key.K2(),
Value: value,
})
return false, nil
@ -84,8 +89,12 @@ func (k Keeper) importAccount(ctx context.Context, acc *v1.GenesisAccount) error
if err != nil {
return err
}
err = k.AccountByNumber.Set(ctx, addrBytes, acc.AccountNumber)
if err != nil {
return err
}
for _, kv := range acc.State {
err = k.AccountsState.Set(ctx, kv.Key, kv.Value)
err = k.AccountsState.Set(ctx, collections.Join(acc.AccountNumber, kv.Key), kv.Value)
if err != nil {
return err
}

View File

@ -2,6 +2,7 @@ package implementation
import (
"context"
"encoding/binary"
"cosmossdk.io/collections"
"cosmossdk.io/core/store"
@ -38,14 +39,15 @@ type contextValue struct {
func MakeAccountContext(
ctx context.Context,
storeSvc store.KVStoreService,
accountAddr,
accNumber uint64,
accountAddr []byte,
sender []byte,
moduleExec ModuleExecFunc,
moduleExecUntyped ModuleExecUntypedFunc,
moduleQuery ModuleQueryFunc,
) context.Context {
return context.WithValue(ctx, contextKey{}, contextValue{
store: prefixstore.New(storeSvc.OpenKVStore(ctx), append(AccountStatePrefix, accountAddr...)),
store: makeAccountStore(ctx, storeSvc, accNumber),
sender: sender,
whoami: accountAddr,
originalContext: ctx,
@ -55,6 +57,15 @@ func MakeAccountContext(
})
}
// makeAccountStore creates the prefixed store for the account.
// It uses the number of the account, this gives constant size
// bytes prefixes for the account state.
func makeAccountStore(ctx context.Context, storeSvc store.KVStoreService, accNum uint64) store.KVStore {
prefix := make([]byte, 8)
binary.BigEndian.PutUint64(prefix, accNum)
return prefixstore.New(storeSvc.OpenKVStore(ctx), append(AccountStatePrefix, prefix...))
}
// ExecModuleUntyped can be used to execute a message towards a module, when the response type is unknown.
func ExecModuleUntyped(ctx context.Context, msg ProtoMsg) (ProtoMsg, error) {
// get sender

View File

@ -2,6 +2,7 @@ package implementation
import (
"context"
"encoding/binary"
"testing"
"github.com/cosmos/gogoproto/types"
@ -17,7 +18,7 @@ func TestMakeAccountContext(t *testing.T) {
sender := []byte("sender")
sb := collections.NewSchemaBuilderFromAccessor(OpenKVStore)
accountCtx := MakeAccountContext(originalContext, storeService, accountAddr, sender, nil, nil, nil)
accountCtx := MakeAccountContext(originalContext, storeService, 1, accountAddr, sender, nil, nil, nil)
// ensure whoami
require.Equal(t, accountAddr, Whoami(accountCtx))
@ -37,13 +38,13 @@ func TestMakeAccountContext(t *testing.T) {
// this store is the global x/accounts module store.
store := storeService.OpenKVStore(originalContext)
// now we want the value to be store in the following accounts prefix (AccountsStatePrefix + accountAddr + itemPrefix)
value, err := store.Get(append(AccountStatePrefix, append(accountAddr, itemPrefix...)...))
// now we want the value to be store in the following accounts prefix (AccountsStatePrefix + big_endian(acc_number=1) + itemPrefix)
value, err := store.Get(append(AccountStatePrefix, append(binary.BigEndian.AppendUint64(nil, 1), itemPrefix...)...))
require.NoError(t, err)
require.Equal(t, []byte{0, 0, 0, 0, 0, 0, 3, 232}, value)
// ensure calling ExecModule works
accountCtx = MakeAccountContext(originalContext, storeService, []byte("legit-exec-module"), []byte("invoker"), func(ctx context.Context, sender []byte, msg, msgResp ProtoMsg) error {
accountCtx = MakeAccountContext(originalContext, storeService, 1, []byte("legit-exec-module"), []byte("invoker"), func(ctx context.Context, sender []byte, msg, msgResp ProtoMsg) error {
// ensure we unwrapped the context when invoking a module call
require.Equal(t, originalContext, ctx)
Merge(msgResp, &types.StringValue{Value: "module exec was called"})
@ -55,7 +56,7 @@ func TestMakeAccountContext(t *testing.T) {
require.True(t, Equal(&types.StringValue{Value: "module exec was called"}, resp))
// ensure calling ExecModuleUntyped works
accountCtx = MakeAccountContext(originalContext, storeService, []byte("legit-exec-module-untyped"), []byte("invoker"), nil, func(ctx context.Context, sender []byte, msg ProtoMsg) (ProtoMsg, error) {
accountCtx = MakeAccountContext(originalContext, storeService, 1, []byte("legit-exec-module-untyped"), []byte("invoker"), nil, func(ctx context.Context, sender []byte, msg ProtoMsg) (ProtoMsg, error) {
require.Equal(t, originalContext, ctx)
return &types.StringValue{Value: "module exec untyped was called"}, nil
}, nil)
@ -66,7 +67,7 @@ func TestMakeAccountContext(t *testing.T) {
// ensure calling QueryModule works, also by setting everything else communication related to nil
// we can guarantee that exec paths do not impact query paths.
accountCtx = MakeAccountContext(originalContext, storeService, nil, nil, nil, nil, func(ctx context.Context, req, resp ProtoMsg) error {
accountCtx = MakeAccountContext(originalContext, storeService, 1, nil, nil, nil, nil, func(ctx context.Context, req, resp ProtoMsg) error {
require.Equal(t, originalContext, ctx)
Merge(resp, &types.StringValue{Value: "module query was called"})
return nil

View File

@ -86,7 +86,7 @@ func NewKeeper(
AccountNumber: collections.NewSequence(sb, AccountNumberKey, "account_number"),
AccountsByType: collections.NewMap(sb, AccountTypeKeyPrefix, "accounts_by_type", collections.BytesKey, collections.StringValue),
AccountByNumber: collections.NewMap(sb, AccountByNumber, "account_by_number", collections.BytesKey, collections.Uint64Value),
AccountsState: collections.NewMap(sb, implementation.AccountStatePrefix, "accounts_state", collections.BytesKey, collections.BytesValue),
AccountsState: collections.NewMap(sb, implementation.AccountStatePrefix, "accounts_state", collections.PairKeyCodec(collections.Uint64Key, collections.BytesKey), collections.BytesValue),
}
schema, err := sb.Build()
@ -125,9 +125,9 @@ type Keeper struct {
// AccountsState keeps track of the state of each account.
// NOTE: this is only used for genesis import and export.
// Contracts set and get their own state but this helps providing a nice mapping
// between: (account address, account state key) => account state value.
AccountsState collections.Map[[]byte, []byte]
// Account set and get their own state but this helps providing a nice mapping
// between: (account number, account state key) => account state value.
AccountsState collections.Map[collections.Pair[uint64, []byte], []byte]
}
// Init creates a new account of the given type.
@ -155,7 +155,7 @@ func (k Keeper) Init(
}
// make the context and init the account
ctx = k.makeAccountContext(ctx, accountAddr, creator, false)
ctx = k.makeAccountContext(ctx, num, accountAddr, creator, false)
resp, err := impl.Init(ctx, initRequest)
if err != nil {
return nil, nil, err
@ -194,8 +194,14 @@ func (k Keeper) Execute(
return nil, err
}
// get account number
accountNum, err := k.AccountByNumber.Get(ctx, accountAddr)
if err != nil {
return nil, err
}
// make the context and execute the account state transition.
ctx = k.makeAccountContext(ctx, accountAddr, sender, false)
ctx = k.makeAccountContext(ctx, accountNum, accountAddr, sender, false)
return impl.Execute(ctx, execRequest)
}
@ -220,8 +226,13 @@ func (k Keeper) Query(
return nil, err
}
accountNum, err := k.AccountByNumber.Get(ctx, accountAddr)
if err != nil {
return nil, err
}
// make the context and execute the account query
ctx = k.makeAccountContext(ctx, accountAddr, nil, true)
ctx = k.makeAccountContext(ctx, accountNum, accountAddr, nil, true)
return impl.Query(ctx, queryRequest)
}
@ -240,12 +251,13 @@ func (k Keeper) makeAddress(accNum uint64) ([]byte, error) {
}
// makeAccountContext makes a new context for the given account.
func (k Keeper) makeAccountContext(ctx context.Context, accountAddr, sender []byte, isQuery bool) context.Context {
func (k Keeper) makeAccountContext(ctx context.Context, accountNumber uint64, accountAddr, sender []byte, isQuery bool) context.Context {
// if it's not a query we create a context that allows to do anything.
if !isQuery {
return implementation.MakeAccountContext(
ctx,
k.storeService,
accountNumber,
accountAddr,
sender,
k.sendModuleMessage,
@ -259,6 +271,7 @@ func (k Keeper) makeAccountContext(ctx context.Context, accountAddr, sender []by
return implementation.MakeAccountContext(
ctx,
k.storeService,
accountNumber,
accountAddr,
nil,
func(ctx context.Context, sender []byte, msg, msgResp implementation.ProtoMsg) error {
@ -349,9 +362,9 @@ func (k Keeper) queryModule(ctx context.Context, queryReq, queryResp implementat
return handlers[0](ctx, queryReq, queryResp)
}
const msgInterfaceName = "cosmos.accounts.Msg.v1"
const msgInterfaceName = "cosmos.accounts.v1.MsgInterface"
// creates a new interface type which is a alias of the proto message interface to avoid conflicts with sdk.Msg
// creates a new interface type which is an alias of the proto message interface to avoid conflicts with sdk.Msg
type msgInterface implementation.ProtoMsg
var msgInterfaceType = (*msgInterface)(nil)

View File

@ -83,8 +83,10 @@ type GenesisAccount struct {
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
// account_type is the account type of the account.
AccountType string `protobuf:"bytes,2,opt,name=account_type,json=accountType,proto3" json:"account_type,omitempty"`
// account_number is the account number of the account.
AccountNumber uint64 `protobuf:"varint,3,opt,name=account_number,json=accountNumber,proto3" json:"account_number,omitempty"`
// state is the account state represented as a slice of raw key value byte pairs.
State []*KVPair `protobuf:"bytes,3,rep,name=state,proto3" json:"state,omitempty"`
State []*KVPair `protobuf:"bytes,4,rep,name=state,proto3" json:"state,omitempty"`
}
func (m *GenesisAccount) Reset() { *m = GenesisAccount{} }
@ -134,6 +136,13 @@ func (m *GenesisAccount) GetAccountType() string {
return ""
}
func (m *GenesisAccount) GetAccountNumber() uint64 {
if m != nil {
return m.AccountNumber
}
return 0
}
func (m *GenesisAccount) GetState() []*KVPair {
if m != nil {
return m.State
@ -205,7 +214,7 @@ func init() {
func init() { proto.RegisterFile("cosmos/accounts/v1/genesis.proto", fileDescriptor_409859d32eae9438) }
var fileDescriptor_409859d32eae9438 = []byte{
// 280 bytes of a gzipped FileDescriptorProto
// 285 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0xce, 0x2f, 0xce,
0xcd, 0x2f, 0xd6, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0x29, 0xd6, 0x2f, 0x33, 0xd4, 0x4f,
0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x82, 0xa8,
@ -213,17 +222,17 @@ var fileDescriptor_409859d32eae9438 = []byte{
0x2c, 0x49, 0x15, 0x52, 0xe5, 0xe2, 0x83, 0x4a, 0xc7, 0xe7, 0x95, 0xe6, 0x26, 0xa5, 0x16, 0x49,
0x30, 0x2a, 0x30, 0x6a, 0xb0, 0x04, 0xf1, 0x42, 0x45, 0xfd, 0xc0, 0x82, 0x42, 0x76, 0x5c, 0x1c,
0x30, 0x53, 0x24, 0x98, 0x14, 0x98, 0x35, 0xb8, 0x8d, 0x94, 0xf4, 0x30, 0x4d, 0xd7, 0x83, 0x1a,
0xed, 0x08, 0x11, 0x0a, 0x82, 0xeb, 0x51, 0xaa, 0xe7, 0xe2, 0x43, 0x95, 0x13, 0x92, 0xe0, 0x62,
0x4f, 0x4c, 0x49, 0x29, 0x4a, 0x2d, 0x2e, 0x06, 0xdb, 0xc8, 0x19, 0x04, 0xe3, 0x0a, 0x29, 0x72,
0xf1, 0xc0, 0x9c, 0x54, 0x52, 0x59, 0x90, 0x2a, 0xc1, 0x04, 0x96, 0xe6, 0x86, 0x8a, 0x85, 0x54,
0x16, 0xa4, 0x0a, 0x19, 0x70, 0xb1, 0x16, 0x83, 0x9c, 0x2f, 0xc1, 0x0c, 0x76, 0x8b, 0x14, 0x36,
0xb7, 0x78, 0x87, 0x05, 0x24, 0x66, 0x16, 0x05, 0x41, 0x14, 0x2a, 0x19, 0x70, 0xb1, 0x41, 0x04,
0x84, 0x04, 0xb8, 0x98, 0xb3, 0x53, 0x2b, 0xc1, 0x96, 0xf2, 0x04, 0x81, 0x98, 0x42, 0x22, 0x5c,
0xac, 0x65, 0x89, 0x39, 0xa5, 0x10, 0x9b, 0x78, 0x82, 0x20, 0x1c, 0x27, 0x93, 0x13, 0x8f, 0xe4,
0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f,
0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x92, 0x82, 0xd8, 0x56, 0x9c, 0x92, 0xad, 0x97, 0x99,
0xaf, 0x5f, 0x81, 0x1c, 0x03, 0x49, 0x6c, 0xe0, 0xa0, 0x37, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff,
0x11, 0x08, 0x28, 0x3a, 0x9e, 0x01, 0x00, 0x00,
0xed, 0x08, 0x11, 0x0a, 0x82, 0xeb, 0x51, 0x5a, 0xc6, 0xc8, 0xc5, 0x87, 0x2a, 0x29, 0x24, 0xc1,
0xc5, 0x9e, 0x98, 0x92, 0x52, 0x94, 0x5a, 0x5c, 0x0c, 0xb6, 0x92, 0x33, 0x08, 0xc6, 0x15, 0x52,
0xe4, 0xe2, 0x81, 0xb9, 0xa9, 0xa4, 0xb2, 0x20, 0x55, 0x82, 0x09, 0x2c, 0xcd, 0x0d, 0x15, 0x0b,
0xa9, 0x2c, 0xc0, 0xe6, 0x6c, 0x66, 0x6c, 0xce, 0x36, 0xe0, 0x62, 0x2d, 0x06, 0x79, 0x53, 0x82,
0x05, 0xec, 0x66, 0x29, 0x6c, 0x6e, 0xf6, 0x0e, 0x0b, 0x48, 0xcc, 0x2c, 0x0a, 0x82, 0x28, 0x54,
0x32, 0xe0, 0x62, 0x83, 0x08, 0x08, 0x09, 0x70, 0x31, 0x67, 0xa7, 0x56, 0x82, 0xdd, 0xc6, 0x13,
0x04, 0x62, 0x0a, 0x89, 0x70, 0xb1, 0x96, 0x25, 0xe6, 0x94, 0x42, 0x1c, 0xc4, 0x13, 0x04, 0xe1,
0x38, 0x99, 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13,
0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x14, 0xc4, 0xb6,
0xe2, 0x94, 0x6c, 0xbd, 0xcc, 0x7c, 0xfd, 0x0a, 0xe4, 0x98, 0x4a, 0x62, 0x03, 0x47, 0x91, 0x31,
0x20, 0x00, 0x00, 0xff, 0xff, 0x52, 0xae, 0xf2, 0xc5, 0xc6, 0x01, 0x00, 0x00,
}
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
@ -299,9 +308,14 @@ func (m *GenesisAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
dAtA[i] = 0x22
}
}
if m.AccountNumber != 0 {
i = encodeVarintGenesis(dAtA, i, uint64(m.AccountNumber))
i--
dAtA[i] = 0x18
}
if len(m.AccountType) > 0 {
i -= len(m.AccountType)
copy(dAtA[i:], m.AccountType)
@ -399,6 +413,9 @@ func (m *GenesisAccount) Size() (n int) {
if l > 0 {
n += 1 + l + sovGenesis(uint64(l))
}
if m.AccountNumber != 0 {
n += 1 + sovGenesis(uint64(m.AccountNumber))
}
if len(m.State) > 0 {
for _, e := range m.State {
l = e.Size()
@ -628,6 +645,25 @@ func (m *GenesisAccount) Unmarshal(dAtA []byte) error {
m.AccountType = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field AccountNumber", wireType)
}
m.AccountNumber = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.AccountNumber |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field State", wireType)
}