x/auth module spec / code reconciliation (#2964)
This commit is contained in:
parent
816248987f
commit
ba5e87ca6f
|
@ -43,7 +43,8 @@ IMPROVEMENTS
|
|||
* Gaia
|
||||
|
||||
* SDK
|
||||
* \#1277 Complete bank module specification
|
||||
- \#1277 Complete bank module specification
|
||||
- \#2963 Complete auth module specification
|
||||
* \#2914 No longer withdraw validator rewards on bond/unbond, but rather move
|
||||
the rewards to the respective validator's pools.
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# Auth module specification
|
||||
|
||||
## Abstract
|
||||
|
||||
This document specifies the auth module of the Cosmos SDK.
|
||||
|
||||
The auth module is responsible for specifying the base transaction and account types
|
||||
for an application, since the SDK itself is agnostic to these particulars. It contains
|
||||
the ante handler, where all basic transaction validity checks (signatures, nonces, auxiliary fields)
|
||||
are performed, and exposes the account keeper, which allows other modules to read, write, and modify accounts.
|
||||
|
||||
This module will be used in the Cosmos Hub.
|
||||
|
||||
## Contents
|
||||
|
||||
1. **[State](state.md)**
|
||||
1. [Accounts](state.md#accounts)
|
||||
1. [Account Interface](state.md#account-interface)
|
||||
1. [Base Account](state.md#baseaccount)
|
||||
1. [Vesting Account](state.md#vestingaccount)
|
||||
1. **[Types](types.md)**
|
||||
1. [StdFee](types.md#stdfee)
|
||||
1. [StdSignature](types.md#stdsignature)
|
||||
1. [StdTx](types.md#stdtx)
|
||||
1. [StdSignDoc](types.md#stdsigndoc)
|
||||
1. **[Keepers](keepers.md)**
|
||||
1. [AccountKeeper](keepers.md#account-keeper)
|
||||
1. **[Handlers](handlers.md)**
|
||||
1. [Ante Handler](handlers.md#ante-handler)
|
|
@ -0,0 +1,38 @@
|
|||
## Handlers
|
||||
|
||||
The auth module presently has no transaction handlers of its own, but does expose
|
||||
the special `AnteHandler`, used for performing basic validity checks on a transaction,
|
||||
such that it could be thrown out of the mempool. Note that the ante handler is called on
|
||||
`CheckTx`, but *also* on `DeliverTx`, as Tendermint proposers presently have the ability
|
||||
to include in their proposed block transactions which fail `CheckTx`.
|
||||
|
||||
### Ante Handler
|
||||
|
||||
```golang
|
||||
anteHandler(ak AccountKeeper, fck FeeCollectionKeeper, tx sdk.Tx)
|
||||
if !tx.(StdTx)
|
||||
fail with "not a StdTx"
|
||||
|
||||
if isCheckTx and tx.Fee < config.SubjectiveMinimumFee
|
||||
fail with "insufficient fee for mempool inclusion"
|
||||
|
||||
if tx.ValidateBasic() != nil
|
||||
fail with "tx failed ValidateBasic"
|
||||
|
||||
if tx.Fee > 0
|
||||
account = GetAccount(tx.GetSigners()[0])
|
||||
coins := acount.GetCoins()
|
||||
if coins < tx.Fee
|
||||
fail with "insufficient fee to pay for transaction"
|
||||
account.SetCoins(coins - tx.Fee)
|
||||
fck.AddCollectedFees(tx.Fee)
|
||||
|
||||
for index, signature in tx.GetSignatures()
|
||||
account = GetAccount(tx.GetSigners()[index])
|
||||
bytesToSign := StdSignBytes(chainID, acc.GetAccountNumber(),
|
||||
acc.GetSequence(), tx.Fee, tx.Msgs, tx.Memo)
|
||||
if !signature.Verify(bytesToSign)
|
||||
fail with "invalid signature"
|
||||
|
||||
return
|
||||
```
|
|
@ -0,0 +1,39 @@
|
|||
## Keepers
|
||||
|
||||
The auth module only exposes one keeper, the account keeper, which can be used to read and write accounts.
|
||||
|
||||
### Account Keeper
|
||||
|
||||
Presently only one fully-permissioned account keeper is exposed, which has the ability to both read and write
|
||||
all fields of all accounts, and to iterate over all stored accounts.
|
||||
|
||||
```golang
|
||||
type AccountKeeper interface {
|
||||
// Return a new account with the next account number and the specified address. Does not save the new account to the store.
|
||||
NewAccountWithAddress(AccAddress) Account
|
||||
|
||||
// Return a new account with the next account number. Does not save the new account to the store.
|
||||
NewAccount(Account) Account
|
||||
|
||||
// Retrieve an account from the store
|
||||
GetAccount(AccAddress) Account
|
||||
|
||||
// Set an account in the store
|
||||
SetAccount(Account)
|
||||
|
||||
// Remove an account from the store
|
||||
RemoveAccount(Account)
|
||||
|
||||
// Iterate over all accounts, calling the provided function. Stop iteraiton when it returns false.
|
||||
IterateAccounts(func(Account) (bool))
|
||||
|
||||
// Fetch the public key of an account at a specified address
|
||||
GetPubKey(AccAddress) PubKey
|
||||
|
||||
// Fetch the sequence of an account at a specified address
|
||||
GetSequence(AccAddress) uint64
|
||||
|
||||
// Fetch the next account number, and increment the internal counter
|
||||
GetNextAccountNumber() uint64
|
||||
}
|
||||
```
|
|
@ -0,0 +1,58 @@
|
|||
## State
|
||||
|
||||
### Accounts
|
||||
|
||||
Accounts contain authentication information for a uniquely identified external user of an SDK blockchain,
|
||||
including public key, address, and account number / sequence number for replay protection. For efficiency,
|
||||
since account balances must also be fetched to pay fees, account structs also store the balance of a user
|
||||
as `sdk.Coins`.
|
||||
|
||||
Accounts are exposed externally as an interface, and stored internally as
|
||||
either a base account or vesting account. Module clients wishing to add more
|
||||
account types may do so.
|
||||
|
||||
- `0x01 | Address -> amino(account)`
|
||||
|
||||
#### Account Interface
|
||||
|
||||
The account interface exposes methods to read and write standard account information.
|
||||
Note that all of these methods operate on an account struct confirming to the interface
|
||||
- in order to write the account to the store, the account keeper will need to be used.
|
||||
|
||||
```golang
|
||||
type Account interface {
|
||||
GetAddress() AccAddress
|
||||
SetAddress(AccAddress)
|
||||
|
||||
GetPubKey() PubKey
|
||||
SetPubKey(PubKey)
|
||||
|
||||
GetAccountNumber() uint64
|
||||
SetAccountNumber(uint64)
|
||||
|
||||
GetSequence() uint64
|
||||
SetSequence(uint64)
|
||||
|
||||
GetCoins() Coins
|
||||
SetCoins(Coins)
|
||||
}
|
||||
```
|
||||
|
||||
#### Base Account
|
||||
|
||||
A base account is the simplest and most common account type, which just stores all requisite
|
||||
fields directly in a struct.
|
||||
|
||||
```golang
|
||||
type BaseAccount struct {
|
||||
Address AccAddress
|
||||
Coins Coins
|
||||
PubKey PubKey
|
||||
AccountNumber uint64
|
||||
Sequence uint64
|
||||
}
|
||||
```
|
||||
|
||||
#### Vesting Account
|
||||
|
||||
See [Vesting](vesting.md).
|
|
@ -0,0 +1,65 @@
|
|||
## Types
|
||||
|
||||
Besides accounts (specified in [State](state.md)), the types exposed by the auth module
|
||||
are `StdFee`, the combination of an amount and gas limit, `StdSignature`, the combination
|
||||
of an optional public key and a cryptographic signature as a byte array, `StdTx`,
|
||||
a struct which implements the `sdk.Tx` interface using `StdFee` and `StdSignature`, and
|
||||
`StdSignDoc`, a replay-prevention structure for `StdTx` which transaction senders must sign over.
|
||||
|
||||
### StdFee
|
||||
|
||||
A `StdFee` is simply the combination of a fee amount, in any number of denominations,
|
||||
and a gas limit (where dividing the amount by the gas limit gives a "gas price").
|
||||
|
||||
```golang
|
||||
type StdFee struct {
|
||||
Amount Coins
|
||||
Gas uint64
|
||||
}
|
||||
```
|
||||
|
||||
### StdSignature
|
||||
|
||||
A `StdSignature` is the combination of an optional public key and a cryptographic signature
|
||||
as a byte array. The SDK is agnostic to particular key or signature formats and supports any
|
||||
supported by the `PubKey` interface.
|
||||
|
||||
```golang
|
||||
type StdSignature struct {
|
||||
PubKey PubKey
|
||||
Signature []byte
|
||||
}
|
||||
```
|
||||
|
||||
### StdTx
|
||||
|
||||
A `StdTx` is a struct which implements the `sdk.Tx` interface, and is likely to be generic
|
||||
enough to serve the purposes of many Cosmos SDK blockchains.
|
||||
|
||||
```golang
|
||||
type StdTx struct {
|
||||
Msgs []sdk.Msg
|
||||
Fee StdFee
|
||||
Signatures []StdSignature
|
||||
Memo string
|
||||
}
|
||||
```
|
||||
|
||||
### StdSignDoc
|
||||
|
||||
A `StdSignDoc` is a replay-prevention structure to be signed over, which ensures that
|
||||
any submitted transaction (which is simply a signature over a particular bytestring)
|
||||
will only be executable once on a particular blockchain.
|
||||
|
||||
`json.RawMessage` is preferred over using the SDK types for future compatibility.
|
||||
|
||||
```golang
|
||||
type StdSignDoc struct {
|
||||
AccountNumber uint64
|
||||
ChainID string
|
||||
Fee json.RawMessage
|
||||
Memo string
|
||||
Msgs []json.RawMessage
|
||||
Sequence uint64
|
||||
}
|
||||
```
|
|
@ -6,7 +6,12 @@ import (
|
|||
"github.com/tendermint/tendermint/crypto"
|
||||
)
|
||||
|
||||
var globalAccountNumberKey = []byte("globalAccountNumber")
|
||||
var (
|
||||
// Prefix for account-by-address store
|
||||
AddressStoreKeyPrefix = []byte{0x01}
|
||||
|
||||
globalAccountNumberKey = []byte("globalAccountNumber")
|
||||
)
|
||||
|
||||
// This AccountKeeper encodes/decodes accounts using the
|
||||
// go-amino (binary) encoding/decoding library.
|
||||
|
@ -61,7 +66,7 @@ func (am AccountKeeper) NewAccount(ctx sdk.Context, acc Account) Account {
|
|||
|
||||
// Turn an address to key used to get it from the account store
|
||||
func AddressStoreKey(addr sdk.AccAddress) []byte {
|
||||
return append([]byte("account:"), addr.Bytes()...)
|
||||
return append(AddressStoreKeyPrefix, addr.Bytes()...)
|
||||
}
|
||||
|
||||
// Implements sdk.AccountKeeper.
|
||||
|
@ -93,7 +98,7 @@ func (am AccountKeeper) RemoveAccount(ctx sdk.Context, acc Account) {
|
|||
// Implements sdk.AccountKeeper.
|
||||
func (am AccountKeeper) IterateAccounts(ctx sdk.Context, process func(Account) (stop bool)) {
|
||||
store := ctx.KVStore(am.key)
|
||||
iter := sdk.KVStorePrefixIterator(store, []byte("account:"))
|
||||
iter := sdk.KVStorePrefixIterator(store, AddressStoreKeyPrefix)
|
||||
defer iter.Close()
|
||||
for {
|
||||
if !iter.Valid() {
|
||||
|
|
Loading…
Reference in New Issue