2018-01-22 05:44:24 -08:00
|
|
|
package auth
|
|
|
|
|
|
|
|
import (
|
2019-02-21 00:49:57 -08:00
|
|
|
"fmt"
|
|
|
|
|
2018-12-10 06:27:25 -08:00
|
|
|
"github.com/tendermint/tendermint/crypto"
|
|
|
|
|
2019-04-30 09:31:38 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
2018-01-22 05:44:24 -08:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
2019-06-24 13:45:09 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/x/auth/exported"
|
2019-06-05 16:26:17 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
2019-04-30 09:31:38 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/x/params/subspace"
|
2018-01-22 05:44:24 -08:00
|
|
|
)
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// AccountKeeper encodes/decodes accounts using the go-amino (binary)
|
2018-12-20 11:09:43 -08:00
|
|
|
// encoding/decoding library.
|
2018-10-20 23:22:48 -07:00
|
|
|
type AccountKeeper struct {
|
2018-01-22 05:44:24 -08:00
|
|
|
// The (unexposed) key used to access the store from the Context.
|
|
|
|
key sdk.StoreKey
|
|
|
|
|
2018-06-25 19:05:47 -07:00
|
|
|
// The prototypical Account constructor.
|
2019-06-24 13:45:09 -07:00
|
|
|
proto func() exported.Account
|
2018-01-22 05:44:24 -08:00
|
|
|
|
2018-09-13 11:17:32 -07:00
|
|
|
// The codec codec for binary encoding/decoding of accounts.
|
|
|
|
cdc *codec.Codec
|
2018-12-20 11:09:43 -08:00
|
|
|
|
2019-04-30 09:31:38 -07:00
|
|
|
paramSubspace subspace.Subspace
|
2018-01-22 05:44:24 -08:00
|
|
|
}
|
|
|
|
|
2018-12-20 11:09:43 -08:00
|
|
|
// NewAccountKeeper returns a new sdk.AccountKeeper that uses go-amino to
|
|
|
|
// (binary) encode and decode concrete sdk.Accounts.
|
2018-04-18 21:49:24 -07:00
|
|
|
// nolint
|
2018-12-20 11:09:43 -08:00
|
|
|
func NewAccountKeeper(
|
2019-06-24 13:45:09 -07:00
|
|
|
cdc *codec.Codec, key sdk.StoreKey, paramstore subspace.Subspace, proto func() exported.Account,
|
2018-12-20 11:09:43 -08:00
|
|
|
) AccountKeeper {
|
|
|
|
|
2018-10-20 23:22:48 -07:00
|
|
|
return AccountKeeper{
|
2018-12-20 11:09:43 -08:00
|
|
|
key: key,
|
|
|
|
proto: proto,
|
|
|
|
cdc: cdc,
|
2019-06-05 16:26:17 -07:00
|
|
|
paramSubspace: paramstore.WithKeyTable(types.ParamKeyTable()),
|
2018-01-22 05:44:24 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// NewAccountWithAddress implements sdk.AccountKeeper.
|
2019-06-24 13:45:09 -07:00
|
|
|
func (ak AccountKeeper) NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) exported.Account {
|
2018-12-20 11:09:43 -08:00
|
|
|
acc := ak.proto()
|
2018-06-28 15:52:10 -07:00
|
|
|
err := acc.SetAddress(addr)
|
|
|
|
if err != nil {
|
|
|
|
// Handle w/ #870
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-12-20 11:09:43 -08:00
|
|
|
err = acc.SetAccountNumber(ak.GetNextAccountNumber(ctx))
|
2018-06-28 15:52:10 -07:00
|
|
|
if err != nil {
|
|
|
|
// Handle w/ #870
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-06-11 19:30:54 -07:00
|
|
|
return acc
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// NewAccount creates a new account
|
2019-06-24 13:45:09 -07:00
|
|
|
func (ak AccountKeeper) NewAccount(ctx sdk.Context, acc exported.Account) exported.Account {
|
2019-02-08 13:35:19 -08:00
|
|
|
if err := acc.SetAccountNumber(ak.GetNextAccountNumber(ctx)); err != nil {
|
2018-06-28 15:52:10 -07:00
|
|
|
panic(err)
|
|
|
|
}
|
2018-01-22 05:44:24 -08:00
|
|
|
return acc
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// GetAccount implements sdk.AccountKeeper.
|
2019-06-24 13:45:09 -07:00
|
|
|
func (ak AccountKeeper) GetAccount(ctx sdk.Context, addr sdk.AccAddress) exported.Account {
|
2018-12-20 11:09:43 -08:00
|
|
|
store := ctx.KVStore(ak.key)
|
2019-06-05 16:26:17 -07:00
|
|
|
bz := store.Get(types.AddressStoreKey(addr))
|
2018-01-22 05:44:24 -08:00
|
|
|
if bz == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2018-12-20 11:09:43 -08:00
|
|
|
acc := ak.decodeAccount(bz)
|
2018-01-22 05:44:24 -08:00
|
|
|
return acc
|
|
|
|
}
|
2019-02-13 15:01:50 -08:00
|
|
|
|
|
|
|
// GetAllAccounts returns all accounts in the accountKeeper.
|
2019-06-24 13:45:09 -07:00
|
|
|
func (ak AccountKeeper) GetAllAccounts(ctx sdk.Context) []exported.Account {
|
|
|
|
accounts := []exported.Account{}
|
|
|
|
appendAccount := func(acc exported.Account) (stop bool) {
|
2019-02-13 15:01:50 -08:00
|
|
|
accounts = append(accounts, acc)
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
ak.IterateAccounts(ctx, appendAccount)
|
|
|
|
return accounts
|
|
|
|
}
|
2018-01-22 05:44:24 -08:00
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// SetAccount implements sdk.AccountKeeper.
|
2019-06-24 13:45:09 -07:00
|
|
|
func (ak AccountKeeper) SetAccount(ctx sdk.Context, acc exported.Account) {
|
2018-01-22 05:44:24 -08:00
|
|
|
addr := acc.GetAddress()
|
2018-12-20 11:09:43 -08:00
|
|
|
store := ctx.KVStore(ak.key)
|
2019-02-08 13:35:19 -08:00
|
|
|
bz, err := ak.cdc.MarshalBinaryBare(acc)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2019-06-05 16:26:17 -07:00
|
|
|
store.Set(types.AddressStoreKey(addr), bz)
|
2018-01-22 05:44:24 -08:00
|
|
|
}
|
|
|
|
|
2018-10-04 07:20:31 -07:00
|
|
|
// RemoveAccount removes an account for the account mapper store.
|
2019-02-08 13:35:19 -08:00
|
|
|
// NOTE: this will cause supply invariant violation if called
|
2019-06-24 13:45:09 -07:00
|
|
|
func (ak AccountKeeper) RemoveAccount(ctx sdk.Context, acc exported.Account) {
|
2018-10-04 07:20:31 -07:00
|
|
|
addr := acc.GetAddress()
|
2018-12-20 11:09:43 -08:00
|
|
|
store := ctx.KVStore(ak.key)
|
2019-06-05 16:26:17 -07:00
|
|
|
store.Delete(types.AddressStoreKey(addr))
|
2018-10-04 07:20:31 -07:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// IterateAccounts implements sdk.AccountKeeper.
|
2019-06-24 13:45:09 -07:00
|
|
|
func (ak AccountKeeper) IterateAccounts(ctx sdk.Context, process func(exported.Account) (stop bool)) {
|
2018-12-20 11:09:43 -08:00
|
|
|
store := ctx.KVStore(ak.key)
|
2019-06-05 16:26:17 -07:00
|
|
|
iter := sdk.KVStorePrefixIterator(store, types.AddressStoreKeyPrefix)
|
2018-08-20 23:54:12 -07:00
|
|
|
defer iter.Close()
|
2018-04-27 07:59:47 -07:00
|
|
|
for {
|
|
|
|
if !iter.Valid() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
val := iter.Value()
|
2018-12-20 11:09:43 -08:00
|
|
|
acc := ak.decodeAccount(val)
|
2018-04-27 17:00:33 -07:00
|
|
|
if process(acc) {
|
2018-04-27 07:59:47 -07:00
|
|
|
return
|
|
|
|
}
|
|
|
|
iter.Next()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// GetPubKey Returns the PubKey of the account at address
|
2018-12-20 11:09:43 -08:00
|
|
|
func (ak AccountKeeper) GetPubKey(ctx sdk.Context, addr sdk.AccAddress) (crypto.PubKey, sdk.Error) {
|
|
|
|
acc := ak.GetAccount(ctx, addr)
|
2018-05-06 22:13:32 -07:00
|
|
|
if acc == nil {
|
2019-02-21 00:49:57 -08:00
|
|
|
return nil, sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", addr))
|
2018-05-06 22:13:32 -07:00
|
|
|
}
|
|
|
|
return acc.GetPubKey(), nil
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// GetSequence Returns the Sequence of the account at address
|
2018-12-20 11:09:43 -08:00
|
|
|
func (ak AccountKeeper) GetSequence(ctx sdk.Context, addr sdk.AccAddress) (uint64, sdk.Error) {
|
|
|
|
acc := ak.GetAccount(ctx, addr)
|
2018-05-06 22:13:32 -07:00
|
|
|
if acc == nil {
|
2019-02-21 00:49:57 -08:00
|
|
|
return 0, sdk.ErrUnknownAddress(fmt.Sprintf("account %s does not exist", addr))
|
2018-05-06 22:13:32 -07:00
|
|
|
}
|
|
|
|
return acc.GetSequence(), nil
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:19 -08:00
|
|
|
// GetNextAccountNumber Returns and increments the global account number counter
|
2018-12-20 11:09:43 -08:00
|
|
|
func (ak AccountKeeper) GetNextAccountNumber(ctx sdk.Context) uint64 {
|
2018-11-26 03:29:21 -08:00
|
|
|
var accNumber uint64
|
2018-12-20 11:09:43 -08:00
|
|
|
store := ctx.KVStore(ak.key)
|
2019-06-05 16:26:17 -07:00
|
|
|
bz := store.Get(types.GlobalAccountNumberKey)
|
2018-06-11 19:30:54 -07:00
|
|
|
if bz == nil {
|
|
|
|
accNumber = 0
|
|
|
|
} else {
|
2018-12-20 11:09:43 -08:00
|
|
|
err := ak.cdc.UnmarshalBinaryLengthPrefixed(bz, &accNumber)
|
2018-06-11 19:30:54 -07:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-20 11:09:43 -08:00
|
|
|
bz = ak.cdc.MustMarshalBinaryLengthPrefixed(accNumber + 1)
|
2019-06-05 16:26:17 -07:00
|
|
|
store.Set(types.GlobalAccountNumberKey, bz)
|
2018-06-11 19:30:54 -07:00
|
|
|
|
|
|
|
return accNumber
|
|
|
|
}
|
|
|
|
|
2019-02-28 11:40:32 -08:00
|
|
|
// -----------------------------------------------------------------------------
|
2018-12-20 11:09:43 -08:00
|
|
|
// Params
|
|
|
|
|
|
|
|
// SetParams sets the auth module's parameters.
|
2019-06-05 16:26:17 -07:00
|
|
|
func (ak AccountKeeper) SetParams(ctx sdk.Context, params types.Params) {
|
2018-12-20 11:09:43 -08:00
|
|
|
ak.paramSubspace.SetParamSet(ctx, ¶ms)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetParams gets the auth module's parameters.
|
2019-06-05 16:26:17 -07:00
|
|
|
func (ak AccountKeeper) GetParams(ctx sdk.Context) (params types.Params) {
|
2018-12-20 11:09:43 -08:00
|
|
|
ak.paramSubspace.GetParamSet(ctx, ¶ms)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-02-28 11:40:32 -08:00
|
|
|
// -----------------------------------------------------------------------------
|
2018-12-20 11:09:43 -08:00
|
|
|
// Misc.
|
2018-01-22 05:44:24 -08:00
|
|
|
|
2019-06-24 13:45:09 -07:00
|
|
|
func (ak AccountKeeper) decodeAccount(bz []byte) (acc exported.Account) {
|
2018-12-20 11:09:43 -08:00
|
|
|
err := ak.cdc.UnmarshalBinaryBare(bz, &acc)
|
2018-04-06 17:25:08 -07:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
2018-01-22 05:44:24 -08:00
|
|
|
}
|
2018-04-06 17:25:08 -07:00
|
|
|
return
|
2018-01-22 05:44:24 -08:00
|
|
|
}
|