From 3055d939edd968deee8a0c2ad33fef8664e8bd1d Mon Sep 17 00:00:00 2001 From: sunnya97 Date: Wed, 23 May 2018 19:26:54 -0700 Subject: [PATCH 01/10] in progress --- baseapp/baseapp.go | 3 +- client/context/helpers.go | 9 +- client/context/types.go | 6 +- client/tx/query.go | 3 +- cmd/gaia/app/app.go | 13 +- cmd/gaia/app/genesis.go | 11 +- types/account.go | 29 ----- types/handler.go | 3 - types/signature.go | 10 -- types/tx_msg.go | 117 ----------------- x/auth/account.go | 25 ++++ x/auth/ante.go | 30 ++--- x/auth/client/cli/account.go | 7 +- x/auth/context.go | 8 +- x/auth/mapper.go | 30 +++-- x/auth/stdtx.go | 131 ++++++++++++++++++++ x/auth/wire.go | 12 -- x/bank/keeper.go | 27 ++-- x/{auth => baseaccount}/baseaccount.go | 9 +- x/{auth => baseaccount}/baseaccount_test.go | 2 +- x/{auth => baseaccount}/handler.go | 13 +- x/{auth => baseaccount}/msgs.go | 7 +- x/{auth => baseaccount}/msgs_test.go | 2 +- x/baseaccount/wire.go | 14 +++ x/stake/test_common.go | 13 +- 25 files changed, 270 insertions(+), 264 deletions(-) delete mode 100644 types/signature.go create mode 100644 x/auth/account.go create mode 100644 x/auth/stdtx.go delete mode 100644 x/auth/wire.go rename x/{auth => baseaccount}/baseaccount.go (90%) rename x/{auth => baseaccount}/baseaccount_test.go (99%) rename x/{auth => baseaccount}/handler.go (58%) rename x/{auth => baseaccount}/msgs.go (87%) rename x/{auth => baseaccount}/msgs_test.go (97%) create mode 100644 x/baseaccount/wire.go diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index ef3bbc3c79..4ce8a05d9b 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" ) // Key to store the header in the DB itself. @@ -125,7 +126,7 @@ func (app *BaseApp) SetTxDecoder(txDecoder sdk.TxDecoder) { // default custom logic for transaction decoding func defaultTxDecoder(cdc *wire.Codec) sdk.TxDecoder { return func(txBytes []byte) (sdk.Tx, sdk.Error) { - var tx = sdk.StdTx{} + var tx = auth.StdTx{} if len(txBytes) == 0 { return nil, sdk.ErrTxDecode("txBytes are empty") diff --git a/client/context/helpers.go b/client/context/helpers.go index 562bde9b4c..f4686befde 100644 --- a/client/context/helpers.go +++ b/client/context/helpers.go @@ -6,6 +6,7 @@ import ( "github.com/pkg/errors" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" rpcclient "github.com/tendermint/tendermint/rpc/client" ctypes "github.com/tendermint/tendermint/rpc/core/types" cmn "github.com/tendermint/tmlibs/common" @@ -109,11 +110,11 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w return nil, errors.Errorf("Chain ID required but not specified") } sequence := ctx.Sequence - signMsg := sdk.StdSignMsg{ + signMsg := auth.StdSignMsg{ ChainID: chainID, Sequences: []int64{sequence}, Msg: msg, - Fee: sdk.NewStdFee(10000, sdk.Coin{}), // TODO run simulate to estimate gas? + Fee: auth.NewStdFee(10000, sdk.Coin{}), // TODO run simulate to estimate gas? } keybase, err := keys.GetKeyBase() @@ -128,14 +129,14 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w if err != nil { return nil, err } - sigs := []sdk.StdSignature{{ + sigs := []auth.StdSignature{{ PubKey: pubkey, Signature: sig, Sequence: sequence, }} // marshal bytes - tx := sdk.NewStdTx(signMsg.Msg, signMsg.Fee, sigs) + tx := auth.NewStdTx(signMsg.Msg, signMsg.Fee, sigs) return cdc.MarshalBinary(tx) } diff --git a/client/context/types.go b/client/context/types.go index e580027d67..da15b32936 100644 --- a/client/context/types.go +++ b/client/context/types.go @@ -3,7 +3,7 @@ package context import ( rpcclient "github.com/tendermint/tendermint/rpc/client" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) // typical context created in sdk modules for transactions/queries @@ -15,7 +15,7 @@ type CoreContext struct { FromAddressName string Sequence int64 Client rpcclient.Client - Decoder sdk.AccountDecoder + Decoder auth.AccountDecoder AccountStore string } @@ -63,7 +63,7 @@ func (c CoreContext) WithClient(client rpcclient.Client) CoreContext { } // WithDecoder - return a copy of the context with an updated Decoder -func (c CoreContext) WithDecoder(decoder sdk.AccountDecoder) CoreContext { +func (c CoreContext) WithDecoder(decoder auth.AccountDecoder) CoreContext { c.Decoder = decoder return c } diff --git a/client/tx/query.go b/client/tx/query.go index 2078b78831..7673dd38db 100644 --- a/client/tx/query.go +++ b/client/tx/query.go @@ -17,6 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" ) // Get the default command for a tx query @@ -95,7 +96,7 @@ type txInfo struct { } func parseTx(cdc *wire.Codec, txBytes []byte) (sdk.Tx, error) { - var tx sdk.StdTx + var tx auth.StdTx err := cdc.UnmarshalBinary(txBytes, &tx) if err != nil { return nil, err diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 5ff532bffa..df4429ee25 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/baseaccount" "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/cosmos/cosmos-sdk/x/stake" ) @@ -40,7 +41,7 @@ type GaiaApp struct { keyStake *sdk.KVStoreKey // Manage getting and setting accounts - accountMapper sdk.AccountMapper + accountMapper auth.AccountMapper coinKeeper bank.Keeper ibcMapper ibc.Mapper stakeKeeper stake.Keeper @@ -62,8 +63,8 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { // define the accountMapper app.accountMapper = auth.NewAccountMapper( app.cdc, - app.keyAccount, // target store - &auth.BaseAccount{}, // prototype + app.keyAccount, // target store + &baseaccount.BaseAccount{}, // prototype ) // add handlers @@ -81,7 +82,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { app.SetInitChainer(app.initChainer) app.SetEndBlocker(stake.NewEndBlocker(app.stakeKeeper)) app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, stake.FeeHandler)) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) err := app.LoadLatestVersion(app.keyMain) if err != nil { cmn.Exit(err.Error()) @@ -96,7 +97,7 @@ func MakeCodec() *wire.Codec { ibc.RegisterWire(cdc) bank.RegisterWire(cdc) stake.RegisterWire(cdc) - auth.RegisterWire(cdc) + baseaccount.RegisterWire(cdc) sdk.RegisterWire(cdc) wire.RegisterCrypto(cdc) return cdc @@ -131,7 +132,7 @@ func (app *GaiaApp) ExportAppStateJSON() (appState json.RawMessage, err error) { // iterate to get the accounts accounts := []GenesisAccount{} - appendAccount := func(acc sdk.Account) (stop bool) { + appendAccount := func(acc auth.Account) (stop bool) { account := NewGenesisAccountI(acc) accounts = append(accounts, account) return false diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index 7cb7564dd3..fb02a19ef4 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -13,6 +13,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/baseaccount" "github.com/cosmos/cosmos-sdk/x/stake" ) @@ -28,14 +29,14 @@ type GenesisAccount struct { Coins sdk.Coins `json:"coins"` } -func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount { +func NewGenesisAccount(acc *baseaccount.BaseAccount) GenesisAccount { return GenesisAccount{ Address: acc.Address, Coins: acc.Coins, } } -func NewGenesisAccountI(acc sdk.Account) GenesisAccount { +func NewGenesisAccountI(acc auth.Account) GenesisAccount { return GenesisAccount{ Address: acc.GetAddress(), Coins: acc.GetCoins(), @@ -43,8 +44,8 @@ func NewGenesisAccountI(acc sdk.Account) GenesisAccount { } // convert GenesisAccount to auth.BaseAccount -func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { - return &auth.BaseAccount{ +func (ga *GenesisAccount) ToAccount() (acc *baseaccount.BaseAccount) { + return &baseaccount.BaseAccount{ Address: ga.Address, Coins: ga.Coins.Sort(), } @@ -148,7 +149,7 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso } // create the genesis account, give'm few steaks and a buncha token with there name - accAuth := auth.NewBaseAccountWithAddress(genTx.Address) + accAuth := baseaccount.NewBaseAccountWithAddress(genTx.Address) accAuth.Coins = sdk.Coins{ {genTx.Name + "Token", 1000}, {"steak", freeFermionsAcc}, diff --git a/types/account.go b/types/account.go index 74cd87f38c..be8b90a1cd 100644 --- a/types/account.go +++ b/types/account.go @@ -4,7 +4,6 @@ import ( "encoding/hex" "errors" - crypto "github.com/tendermint/go-crypto" cmn "github.com/tendermint/tmlibs/common" ) @@ -22,31 +21,3 @@ func GetAddress(address string) (addr Address, err error) { } return Address(bz), nil } - -// Account is a standard account using a sequence number for replay protection -// and a pubkey for authentication. -type Account interface { - GetAddress() Address - SetAddress(Address) error // errors if already set. - - GetPubKey() crypto.PubKey // can return nil. - SetPubKey(crypto.PubKey) error - - GetSequence() int64 - SetSequence(int64) error - - GetCoins() Coins - SetCoins(Coins) error -} - -// AccountMapper stores and retrieves accounts from stores -// retrieved from the context. -type AccountMapper interface { - NewAccountWithAddress(ctx Context, addr Address) Account - GetAccount(ctx Context, addr Address) Account - SetAccount(ctx Context, acc Account) - IterateAccounts(ctx Context, process func(Account) (stop bool)) -} - -// AccountDecoder unmarshals account bytes -type AccountDecoder func(accountBytes []byte) (Account, error) diff --git a/types/handler.go b/types/handler.go index 679a3b1a78..129f42647a 100644 --- a/types/handler.go +++ b/types/handler.go @@ -3,8 +3,5 @@ package types // core function variable which application runs for transactions type Handler func(ctx Context, msg Msg) Result -// core function variable which application runs to handle fees -type FeeHandler func(ctx Context, tx Tx, fee Coins) - // If newCtx.IsZero(), ctx is used instead. type AnteHandler func(ctx Context, tx Tx) (newCtx Context, result Result, abort bool) diff --git a/types/signature.go b/types/signature.go deleted file mode 100644 index 5bca2f6069..0000000000 --- a/types/signature.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -import crypto "github.com/tendermint/go-crypto" - -// Standard Signature -type StdSignature struct { - crypto.PubKey `json:"pub_key"` // optional - crypto.Signature `json:"signature"` - Sequence int64 `json:"sequence"` -} diff --git a/types/tx_msg.go b/types/tx_msg.go index e17d152a5f..186cf9b242 100644 --- a/types/tx_msg.go +++ b/types/tx_msg.go @@ -31,123 +31,6 @@ type Tx interface { // Gets the Msg. GetMsg() Msg - - // Signatures returns the signature of signers who signed the Msg. - // CONTRACT: Length returned is same as length of - // pubkeys returned from MsgKeySigners, and the order - // matches. - // CONTRACT: If the signature is missing (ie the Msg is - // invalid), then the corresponding signature is - // .Empty(). - GetSignatures() []StdSignature -} - -var _ Tx = (*StdTx)(nil) - -// StdTx is a standard way to wrap a Msg with Fee and Signatures. -// NOTE: the first signature is the FeePayer (Signatures must not be nil). -type StdTx struct { - Msg `json:"msg"` - Fee StdFee `json:"fee"` - Signatures []StdSignature `json:"signatures"` -} - -func NewStdTx(msg Msg, fee StdFee, sigs []StdSignature) StdTx { - return StdTx{ - Msg: msg, - Fee: fee, - Signatures: sigs, - } -} - -//nolint -func (tx StdTx) GetMsg() Msg { return tx.Msg } -func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures } - -// FeePayer returns the address responsible for paying the fees -// for the transactions. It's the first address returned by msg.GetSigners(). -// If GetSigners() is empty, this panics. -func FeePayer(tx Tx) Address { - return tx.GetMsg().GetSigners()[0] -} - -//__________________________________________________________ - -// StdFee includes the amount of coins paid in fees and the maximum -// gas to be used by the transaction. The ratio yields an effective "gasprice", -// which must be above some miminum to be accepted into the mempool. -type StdFee struct { - Amount Coins `json:"amount"` - Gas int64 `json:"gas"` -} - -func NewStdFee(gas int64, amount ...Coin) StdFee { - return StdFee{ - Amount: amount, - Gas: gas, - } -} - -// fee bytes for signing later -func (fee StdFee) Bytes() []byte { - // normalize. XXX - // this is a sign of something ugly - // (in the lcd_test, client side its null, - // server side its []) - if len(fee.Amount) == 0 { - fee.Amount = Coins{} - } - bz, err := json.Marshal(fee) // TODO - if err != nil { - panic(err) - } - return bz -} - -//__________________________________________________________ - -// StdSignDoc is replay-prevention structure. -// It includes the result of msg.GetSignBytes(), -// as well as the ChainID (prevent cross chain replay) -// and the Sequence numbers for each signature (prevent -// inchain replay and enforce tx ordering per account). -type StdSignDoc struct { - ChainID string `json:"chain_id"` - Sequences []int64 `json:"sequences"` - FeeBytes []byte `json:"fee_bytes"` - MsgBytes []byte `json:"msg_bytes"` - AltBytes []byte `json:"alt_bytes"` -} - -// StdSignBytes returns the bytes to sign for a transaction. -// TODO: change the API to just take a chainID and StdTx ? -func StdSignBytes(chainID string, sequences []int64, fee StdFee, msg Msg) []byte { - bz, err := json.Marshal(StdSignDoc{ - ChainID: chainID, - Sequences: sequences, - FeeBytes: fee.Bytes(), - MsgBytes: msg.GetSignBytes(), - }) - if err != nil { - panic(err) - } - return bz -} - -// StdSignMsg is a convenience structure for passing along -// a Msg with the other requirements for a StdSignDoc before -// it is signed. For use in the CLI. -type StdSignMsg struct { - ChainID string - Sequences []int64 - Fee StdFee - Msg Msg - // XXX: Alt -} - -// get message bytes -func (msg StdSignMsg) Bytes() []byte { - return StdSignBytes(msg.ChainID, msg.Sequences, msg.Fee, msg.Msg) } //__________________________________________________________ diff --git a/x/auth/account.go b/x/auth/account.go new file mode 100644 index 0000000000..28366467aa --- /dev/null +++ b/x/auth/account.go @@ -0,0 +1,25 @@ +package auth + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + crypto "github.com/tendermint/go-crypto" +) + +// Account is a standard account using a sequence number for replay protection +// and a pubkey for authentication. +type Account interface { + GetAddress() sdk.Address + SetAddress(sdk.Address) error // errors if already set. + + GetPubKey() crypto.PubKey // can return nil. + SetPubKey(crypto.PubKey) error + + GetSequence() int64 + SetSequence(int64) error + + GetCoins() sdk.Coins + SetCoins(sdk.Coins) error +} + +// AccountDecoder unmarshals account bytes +type AccountDecoder func(accountBytes []byte) (Account, error) diff --git a/x/auth/ante.go b/x/auth/ante.go index 248083206d..2139524077 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -15,13 +15,20 @@ const ( // NewAnteHandler returns an AnteHandler that checks // and increments sequence numbers, checks signatures, // and deducts fees from the first signer. -func NewAnteHandler(am sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHandler { +func NewAnteHandler(am AccountMapper) sdk.AnteHandler { + return func( ctx sdk.Context, tx sdk.Tx, ) (_ sdk.Context, _ sdk.Result, abort bool) { + // This AnteHandler requires Txs to be StdTxs + stdTx, ok := tx.(StdTx) + if !ok { + return ctx, sdk.ErrInternal("tx must be sdk.StdTx").Result(), true + } + // Assert that there are signatures. - var sigs = tx.GetSignatures() + var sigs = stdTx.GetSignatures() if len(sigs) == 0 { return ctx, sdk.ErrUnauthorized("no signers").Result(), @@ -30,12 +37,6 @@ func NewAnteHandler(am sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHan msg := tx.GetMsg() - // TODO: will this always be a stdtx? should that be used in the function signature? - stdTx, ok := tx.(sdk.StdTx) - if !ok { - return ctx, sdk.ErrInternal("tx must be sdk.StdTx").Result(), true - } - // Assert that number of signatures is correct. var signerAddrs = msg.GetSigners() if len(sigs) != len(signerAddrs) { @@ -56,10 +57,10 @@ func NewAnteHandler(am sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHan if chainID == "" { chainID = viper.GetString("chain-id") } - signBytes := sdk.StdSignBytes(ctx.ChainID(), sequences, fee, msg) + signBytes := StdSignBytes(ctx.ChainID(), sequences, fee, msg) // Check sig and nonce and collect signer accounts. - var signerAccs = make([]sdk.Account, len(signerAddrs)) + var signerAccs = make([]Account, len(signerAddrs)) for i := 0; i < len(sigs); i++ { signerAddr, sig := signerAddrs[i], sigs[i] @@ -77,7 +78,6 @@ func NewAnteHandler(am sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHan // TODO: min fee if !fee.Amount.IsZero() { signerAcc, res = deductFees(signerAcc, fee) - feeHandler(ctx, tx, fee.Amount) if !res.IsOK() { return ctx, res, true } @@ -104,9 +104,9 @@ func NewAnteHandler(am sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHan // verify the signature and increment the sequence. // if the account doesn't have a pubkey, set it. func processSig( - ctx sdk.Context, am sdk.AccountMapper, - addr sdk.Address, sig sdk.StdSignature, signBytes []byte) ( - acc sdk.Account, res sdk.Result) { + ctx sdk.Context, am AccountMapper, + addr sdk.Address, sig StdSignature, signBytes []byte) ( + acc Account, res sdk.Result) { // Get the account. acc = am.GetAccount(ctx, addr) @@ -152,7 +152,7 @@ func processSig( // Deduct the fee from the account. // We could use the CoinKeeper (in addition to the AccountMapper, // because the CoinKeeper doesn't give us accounts), but it seems easier to do this. -func deductFees(acc sdk.Account, fee sdk.StdFee) (sdk.Account, sdk.Result) { +func deductFees(acc Account, fee StdFee) (Account, sdk.Result) { coins := acc.GetCoins() feeAmount := fee.Amount diff --git a/x/auth/client/cli/account.go b/x/auth/client/cli/account.go index b45cb12ddf..08bd520fb1 100644 --- a/x/auth/client/cli/account.go +++ b/x/auth/client/cli/account.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" ) // GetAccountCmd for the auth.BaseAccount type @@ -17,8 +18,8 @@ func GetAccountCmdDefault(storeName string, cdc *wire.Codec) *cobra.Command { } // Get account decoder for auth.DefaultAccount -func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { - return func(accBytes []byte) (acct sdk.Account, err error) { +func GetAccountDecoder(cdc *wire.Codec) auth.AccountDecoder { + return func(accBytes []byte) (acct auth.Account, err error) { // acct := new(auth.BaseAccount) err = cdc.UnmarshalBinaryBare(accBytes, &acct) if err != nil { @@ -30,7 +31,7 @@ func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { // GetAccountCmd returns a query account that will display the // state of the account at a given address -func GetAccountCmd(storeName string, cdc *wire.Codec, decoder sdk.AccountDecoder) *cobra.Command { +func GetAccountCmd(storeName string, cdc *wire.Codec, decoder auth.AccountDecoder) *cobra.Command { return &cobra.Command{ Use: "account [address]", Short: "Query account balance", diff --git a/x/auth/context.go b/x/auth/context.go index b233f1e861..40fb177858 100644 --- a/x/auth/context.go +++ b/x/auth/context.go @@ -34,15 +34,15 @@ const ( ) // add the signers to the context -func WithSigners(ctx types.Context, accounts []types.Account) types.Context { +func WithSigners(ctx types.Context, accounts []Account) types.Context { return ctx.WithValue(contextKeySigners, accounts) } // get the signers from the context -func GetSigners(ctx types.Context) []types.Account { +func GetSigners(ctx types.Context) []Account { v := ctx.Value(contextKeySigners) if v == nil { - return []types.Account{} + return []Account{} } - return v.([]types.Account) + return v.([]Account) } diff --git a/x/auth/mapper.go b/x/auth/mapper.go index 3666f13b69..cdab2480e3 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -9,9 +9,6 @@ import ( crypto "github.com/tendermint/go-crypto" ) -var _ sdk.AccountMapper = (*AccountMapper)(nil) - -// Implements sdk.AccountMapper. // This AccountMapper encodes/decodes accounts using the // go-amino (binary) encoding/decoding library. type AccountMapper struct { @@ -19,8 +16,8 @@ type AccountMapper struct { // The (unexposed) key used to access the store from the Context. key sdk.StoreKey - // The prototypical sdk.Account concrete type. - proto sdk.Account + // The prototypical Account concrete type. + proto Account // The wire codec for binary encoding/decoding of accounts. cdc *wire.Codec @@ -29,7 +26,7 @@ type AccountMapper struct { // NewAccountMapper returns a new sdk.AccountMapper that // uses go-amino to (binary) encode and decode concrete sdk.Accounts. // nolint -func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto sdk.Account) AccountMapper { +func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto Account) AccountMapper { return AccountMapper{ key: key, proto: proto, @@ -38,14 +35,14 @@ func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto sdk.Account) Acco } // Implaements sdk.AccountMapper. -func (am AccountMapper) NewAccountWithAddress(ctx sdk.Context, addr sdk.Address) sdk.Account { +func (am AccountMapper) NewAccountWithAddress(ctx sdk.Context, addr sdk.Address) Account { acc := am.clonePrototype() acc.SetAddress(addr) return acc } // Implements sdk.AccountMapper. -func (am AccountMapper) GetAccount(ctx sdk.Context, addr sdk.Address) sdk.Account { +func (am AccountMapper) GetAccount(ctx sdk.Context, addr sdk.Address) Account { store := ctx.KVStore(am.key) bz := store.Get(addr) if bz == nil { @@ -56,7 +53,7 @@ func (am AccountMapper) GetAccount(ctx sdk.Context, addr sdk.Address) sdk.Accoun } // Implements sdk.AccountMapper. -func (am AccountMapper) SetAccount(ctx sdk.Context, acc sdk.Account) { +func (am AccountMapper) SetAccount(ctx sdk.Context, acc Account) { addr := acc.GetAddress() store := ctx.KVStore(am.key) bz := am.encodeAccount(acc) @@ -64,7 +61,7 @@ func (am AccountMapper) SetAccount(ctx sdk.Context, acc sdk.Account) { } // Implements sdk.AccountMapper. -func (am AccountMapper) IterateAccounts(ctx sdk.Context, process func(sdk.Account) (stop bool)) { +func (am AccountMapper) IterateAccounts(ctx sdk.Context, process func(Account) (stop bool)) { store := ctx.KVStore(am.key) iter := store.Iterator(nil, nil) for { @@ -89,7 +86,8 @@ func (am AccountMapper) GetPubKey(ctx sdk.Context, addr sdk.Address) (crypto.Pub return acc.GetPubKey(), nil } -func (am AccountMapper) setPubKey(ctx sdk.Context, addr sdk.Address, newPubKey crypto.PubKey) sdk.Error { +// Sets the PubKey of the account at address +func (am AccountMapper) SetPubKey(ctx sdk.Context, addr sdk.Address, newPubKey crypto.PubKey) sdk.Error { acc := am.GetAccount(ctx, addr) if acc == nil { return sdk.ErrUnknownAddress(addr.String()) @@ -122,7 +120,7 @@ func (am AccountMapper) setSequence(ctx sdk.Context, addr sdk.Address, newSequen // misc. // Creates a new struct (or pointer to struct) from am.proto. -func (am AccountMapper) clonePrototype() sdk.Account { +func (am AccountMapper) clonePrototype() Account { protoRt := reflect.TypeOf(am.proto) if protoRt.Kind() == reflect.Ptr { protoCrt := protoRt.Elem() @@ -130,7 +128,7 @@ func (am AccountMapper) clonePrototype() sdk.Account { panic("accountMapper requires a struct proto sdk.Account, or a pointer to one") } protoRv := reflect.New(protoCrt) - clone, ok := protoRv.Interface().(sdk.Account) + clone, ok := protoRv.Interface().(Account) if !ok { panic(fmt.Sprintf("accountMapper requires a proto sdk.Account, but %v doesn't implement sdk.Account", protoRt)) } @@ -138,14 +136,14 @@ func (am AccountMapper) clonePrototype() sdk.Account { } protoRv := reflect.New(protoRt).Elem() - clone, ok := protoRv.Interface().(sdk.Account) + clone, ok := protoRv.Interface().(Account) if !ok { panic(fmt.Sprintf("accountMapper requires a proto sdk.Account, but %v doesn't implement sdk.Account", protoRt)) } return clone } -func (am AccountMapper) encodeAccount(acc sdk.Account) []byte { +func (am AccountMapper) encodeAccount(acc Account) []byte { bz, err := am.cdc.MarshalBinaryBare(acc) if err != nil { panic(err) @@ -153,7 +151,7 @@ func (am AccountMapper) encodeAccount(acc sdk.Account) []byte { return bz } -func (am AccountMapper) decodeAccount(bz []byte) (acc sdk.Account) { +func (am AccountMapper) decodeAccount(bz []byte) (acc Account) { err := am.cdc.UnmarshalBinaryBare(bz, &acc) if err != nil { panic(err) diff --git a/x/auth/stdtx.go b/x/auth/stdtx.go new file mode 100644 index 0000000000..bc01b01490 --- /dev/null +++ b/x/auth/stdtx.go @@ -0,0 +1,131 @@ +package auth + +import ( + "encoding/json" + + sdk "github.com/cosmos/cosmos-sdk/types" + crypto "github.com/tendermint/go-crypto" +) + +var _ sdk.Tx = (*StdTx)(nil) + +// StdTx is a standard way to wrap a Msg with Fee and Signatures. +// NOTE: the first signature is the FeePayer (Signatures must not be nil). +type StdTx struct { + Msg sdk.Msg `json:"msg"` + Fee StdFee `json:"fee"` + Signatures []StdSignature `json:"signatures"` +} + +func NewStdTx(msg sdk.Msg, fee StdFee, sigs []StdSignature) StdTx { + return StdTx{ + Msg: msg, + Fee: fee, + Signatures: sigs, + } +} + +//nolint +func (tx StdTx) GetMsg() sdk.Msg { return tx.Msg } + +// Signatures returns the signature of signers who signed the Msg. +// CONTRACT: Length returned is same as length of +// pubkeys returned from MsgKeySigners, and the order +// matches. +// CONTRACT: If the signature is missing (ie the Msg is +// invalid), then the corresponding signature is +// .Empty(). +func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures } + +// FeePayer returns the address responsible for paying the fees +// for the transactions. It's the first address returned by msg.GetSigners(). +// If GetSigners() is empty, this panics. +func FeePayer(tx sdk.Tx) sdk.Address { + return tx.GetMsg().GetSigners()[0] +} + +//__________________________________________________________ + +// StdFee includes the amount of coins paid in fees and the maximum +// gas to be used by the transaction. The ratio yields an effective "gasprice", +// which must be above some miminum to be accepted into the mempool. +type StdFee struct { + Amount sdk.Coins `json:"amount"` + Gas int64 `json:"gas"` +} + +func NewStdFee(gas int64, amount ...sdk.Coin) StdFee { + return StdFee{ + Amount: amount, + Gas: gas, + } +} + +// fee bytes for signing later +func (fee StdFee) Bytes() []byte { + // normalize. XXX + // this is a sign of something ugly + // (in the lcd_test, client side its null, + // server side its []) + if len(fee.Amount) == 0 { + fee.Amount = sdk.Coins{} + } + bz, err := json.Marshal(fee) // TODO + if err != nil { + panic(err) + } + return bz +} + +//__________________________________________________________ + +// StdSignDoc is replay-prevention structure. +// It includes the result of msg.GetSignBytes(), +// as well as the ChainID (prevent cross chain replay) +// and the Sequence numbers for each signature (prevent +// inchain replay and enforce tx ordering per account). +type StdSignDoc struct { + ChainID string `json:"chain_id"` + Sequences []int64 `json:"sequences"` + FeeBytes []byte `json:"fee_bytes"` + MsgBytes []byte `json:"msg_bytes"` + AltBytes []byte `json:"alt_bytes"` +} + +// StdSignBytes returns the bytes to sign for a transaction. +// TODO: change the API to just take a chainID and StdTx ? +func StdSignBytes(chainID string, sequences []int64, fee StdFee, msg sdk.Msg) []byte { + bz, err := json.Marshal(StdSignDoc{ + ChainID: chainID, + Sequences: sequences, + FeeBytes: fee.Bytes(), + MsgBytes: msg.GetSignBytes(), + }) + if err != nil { + panic(err) + } + return bz +} + +// StdSignMsg is a convenience structure for passing along +// a Msg with the other requirements for a StdSignDoc before +// it is signed. For use in the CLI. +type StdSignMsg struct { + ChainID string + Sequences []int64 + Fee StdFee + Msg sdk.Msg + // XXX: Alt +} + +// get message bytes +func (msg StdSignMsg) Bytes() []byte { + return StdSignBytes(msg.ChainID, msg.Sequences, msg.Fee, msg.Msg) +} + +// Standard Signature +type StdSignature struct { + crypto.PubKey `json:"pub_key"` // optional + crypto.Signature `json:"signature"` + Sequence int64 `json:"sequence"` +} diff --git a/x/auth/wire.go b/x/auth/wire.go deleted file mode 100644 index 9db1b85cca..0000000000 --- a/x/auth/wire.go +++ /dev/null @@ -1,12 +0,0 @@ -package auth - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/wire" -) - -// Register concrete types on wire codec for default AppAccount -func RegisterWire(cdc *wire.Codec) { - cdc.RegisterInterface((*sdk.Account)(nil), nil) - cdc.RegisterConcrete(&BaseAccount{}, "auth/Account", nil) -} diff --git a/x/bank/keeper.go b/x/bank/keeper.go index 6ef73c68b6..b14da4d81f 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -4,6 +4,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) const ( @@ -16,11 +17,11 @@ const ( // Keeper manages transfers between accounts type Keeper struct { - am sdk.AccountMapper + am auth.AccountMapper } // NewKeeper returns a new Keeper -func NewKeeper(am sdk.AccountMapper) Keeper { +func NewKeeper(am auth.AccountMapper) Keeper { return Keeper{am: am} } @@ -63,11 +64,11 @@ func (keeper Keeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs [ // SendKeeper only allows transfers between accounts, without the possibility of creating coins type SendKeeper struct { - am sdk.AccountMapper + am auth.AccountMapper } // NewSendKeeper returns a new Keeper -func NewSendKeeper(am sdk.AccountMapper) SendKeeper { +func NewSendKeeper(am auth.AccountMapper) SendKeeper { return SendKeeper{am: am} } @@ -95,11 +96,11 @@ func (keeper SendKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outpu // ViewKeeper only allows reading of balances type ViewKeeper struct { - am sdk.AccountMapper + am auth.AccountMapper } // NewViewKeeper returns a new Keeper -func NewViewKeeper(am sdk.AccountMapper) ViewKeeper { +func NewViewKeeper(am auth.AccountMapper) ViewKeeper { return ViewKeeper{am: am} } @@ -115,7 +116,7 @@ func (keeper ViewKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coi //______________________________________________________________________________________________ -func getCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address) sdk.Coins { +func getCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address) sdk.Coins { ctx.GasMeter().ConsumeGas(costGetCoins, "getCoins") acc := am.GetAccount(ctx, addr) if acc == nil { @@ -124,7 +125,7 @@ func getCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address) sdk.Coins return acc.GetCoins() } -func setCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) sdk.Error { +func setCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt sdk.Coins) sdk.Error { ctx.GasMeter().ConsumeGas(costSetCoins, "setCoins") acc := am.GetAccount(ctx, addr) if acc == nil { @@ -136,13 +137,13 @@ func setCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.C } // HasCoins returns whether or not an account has at least amt coins. -func hasCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) bool { +func hasCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt sdk.Coins) bool { ctx.GasMeter().ConsumeGas(costHasCoins, "hasCoins") return getCoins(ctx, am, addr).IsGTE(amt) } // SubtractCoins subtracts amt from the coins at the addr. -func subtractCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { +func subtractCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { ctx.GasMeter().ConsumeGas(costSubtractCoins, "subtractCoins") oldCoins := getCoins(ctx, am, addr) newCoins := oldCoins.Minus(amt) @@ -155,7 +156,7 @@ func subtractCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt } // AddCoins adds amt to the coins at the addr. -func addCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { +func addCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { ctx.GasMeter().ConsumeGas(costAddCoins, "addCoins") oldCoins := getCoins(ctx, am, addr) newCoins := oldCoins.Plus(amt) @@ -169,7 +170,7 @@ func addCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.C // SendCoins moves coins from one account to another // NOTE: Make sure to revert state changes from tx on error -func sendCoins(ctx sdk.Context, am sdk.AccountMapper, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) (sdk.Tags, sdk.Error) { +func sendCoins(ctx sdk.Context, am auth.AccountMapper, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) (sdk.Tags, sdk.Error) { _, subTags, err := subtractCoins(ctx, am, fromAddr, amt) if err != nil { return nil, err @@ -185,7 +186,7 @@ func sendCoins(ctx sdk.Context, am sdk.AccountMapper, fromAddr sdk.Address, toAd // InputOutputCoins handles a list of inputs and outputs // NOTE: Make sure to revert state changes from tx on error -func inputOutputCoins(ctx sdk.Context, am sdk.AccountMapper, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) { +func inputOutputCoins(ctx sdk.Context, am auth.AccountMapper, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) { allTags := sdk.EmptyTags() for _, in := range inputs { diff --git a/x/auth/baseaccount.go b/x/baseaccount/baseaccount.go similarity index 90% rename from x/auth/baseaccount.go rename to x/baseaccount/baseaccount.go index ff907fc387..9701ac41dc 100644 --- a/x/auth/baseaccount.go +++ b/x/baseaccount/baseaccount.go @@ -1,18 +1,19 @@ -package auth +package baseaccount import ( "errors" - "github.com/tendermint/go-crypto" + crypto "github.com/tendermint/go-crypto" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" ) //----------------------------------------------------------- // BaseAccount -var _ sdk.Account = (*BaseAccount)(nil) +var _ auth.Account = (*BaseAccount)(nil) // BaseAccount - base account structure. // Extend this by embedding this in your AppAccount. @@ -82,7 +83,7 @@ func (acc *BaseAccount) SetSequence(seq int64) error { // Most users shouldn't use this, but this comes handy for tests. func RegisterBaseAccount(cdc *wire.Codec) { - cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterInterface((*auth.Account)(nil), nil) cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil) wire.RegisterCrypto(cdc) } diff --git a/x/auth/baseaccount_test.go b/x/baseaccount/baseaccount_test.go similarity index 99% rename from x/auth/baseaccount_test.go rename to x/baseaccount/baseaccount_test.go index d3363e4fb0..ed1a322c2f 100644 --- a/x/auth/baseaccount_test.go +++ b/x/baseaccount/baseaccount_test.go @@ -1,4 +1,4 @@ -package auth +package baseaccount import ( "testing" diff --git a/x/auth/handler.go b/x/baseaccount/handler.go similarity index 58% rename from x/auth/handler.go rename to x/baseaccount/handler.go index 8a0e1061ae..46307c8818 100644 --- a/x/auth/handler.go +++ b/x/baseaccount/handler.go @@ -1,19 +1,20 @@ -package auth +package baseaccount import ( "reflect" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) -// NewHandler returns a handler for "auth" type messages. -func NewHandler(am AccountMapper) sdk.Handler { +// NewHandler returns a handler for "baseaccount" type messages. +func NewHandler(am auth.AccountMapper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { case MsgChangeKey: return handleMsgChangeKey(ctx, am, msg) default: - errMsg := "Unrecognized auth Msg type: " + reflect.TypeOf(msg).Name() + errMsg := "Unrecognized baseaccount Msg type: " + reflect.TypeOf(msg).Name() return sdk.ErrUnknownRequest(errMsg).Result() } } @@ -21,9 +22,9 @@ func NewHandler(am AccountMapper) sdk.Handler { // Handle MsgChangeKey // Should be very expensive, because once this happens, an account is un-prunable -func handleMsgChangeKey(ctx sdk.Context, am AccountMapper, msg MsgChangeKey) sdk.Result { +func handleMsgChangeKey(ctx sdk.Context, am auth.AccountMapper, msg MsgChangeKey) sdk.Result { - err := am.setPubKey(ctx, msg.Address, msg.NewPubKey) + err := am.SetPubKey(ctx, msg.Address, msg.NewPubKey) if err != nil { return err.Result() } diff --git a/x/auth/msgs.go b/x/baseaccount/msgs.go similarity index 87% rename from x/auth/msgs.go rename to x/baseaccount/msgs.go index 545b296e5b..f0319ac7fe 100644 --- a/x/auth/msgs.go +++ b/x/baseaccount/msgs.go @@ -1,11 +1,10 @@ -package auth +package baseaccount import ( "encoding/json" - "github.com/tendermint/go-crypto" - sdk "github.com/cosmos/cosmos-sdk/types" + crypto "github.com/tendermint/go-crypto" ) // MsgChangeKey - high level transaction of the auth module @@ -22,7 +21,7 @@ func NewMsgChangeKey(addr sdk.Address, pubkey crypto.PubKey) MsgChangeKey { } // Implements Msg. -func (msg MsgChangeKey) Type() string { return "auth" } +func (msg MsgChangeKey) Type() string { return "baseaccount" } // Implements Msg. func (msg MsgChangeKey) ValidateBasic() sdk.Error { diff --git a/x/auth/msgs_test.go b/x/baseaccount/msgs_test.go similarity index 97% rename from x/auth/msgs_test.go rename to x/baseaccount/msgs_test.go index 30c98b073b..46797fa0d8 100644 --- a/x/auth/msgs_test.go +++ b/x/baseaccount/msgs_test.go @@ -1,4 +1,4 @@ -package auth +package baseaccount import ( "testing" diff --git a/x/baseaccount/wire.go b/x/baseaccount/wire.go new file mode 100644 index 0000000000..4c77d1c72c --- /dev/null +++ b/x/baseaccount/wire.go @@ -0,0 +1,14 @@ +package baseaccount + +import ( + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" +) + +// Register concrete types on wire codec +func RegisterWire(cdc *wire.Codec) { + cdc.RegisterInterface((*auth.Account)(nil), nil) + cdc.RegisterConcrete(&BaseAccount{}, "baseaccount/BaseAccount", nil) + wire.RegisterCrypto(cdc) + cdc.RegisterConcrete(MsgChangeKey{}, "baseaccount/changekey", nil) +} diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 27acebe086..5a87081af1 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -17,6 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/baseaccount" ) // dummy addresses used for testing @@ -129,8 +130,8 @@ func makeTestCodec() *wire.Codec { cdc.RegisterConcrete(MsgUnbond{}, "test/stake/Unbond", nil) // Register AppAccount - cdc.RegisterInterface((*sdk.Account)(nil), nil) - cdc.RegisterConcrete(&auth.BaseAccount{}, "test/stake/Account", nil) + cdc.RegisterInterface((*auth.Account)(nil), nil) + cdc.RegisterConcrete(&baseaccount.BaseAccount{}, "test/stake/Account", nil) wire.RegisterCrypto(cdc) return cdc @@ -148,7 +149,7 @@ func paramsNoInflation() Params { } // hogpodge of all sorts of input required for testing -func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context, sdk.AccountMapper, Keeper) { +func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context, auth.AccountMapper, Keeper) { db := dbm.NewMemDB() keyStake := sdk.NewKVStoreKey("stake") keyMain := keyStake //sdk.NewKVStoreKey("main") //TODO fix multistore @@ -161,9 +162,9 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, nil, log.NewNopLogger()) cdc := makeTestCodec() accountMapper := auth.NewAccountMapper( - cdc, // amino codec - keyMain, // target store - &auth.BaseAccount{}, // prototype + cdc, // amino codec + keyMain, // target store + &baseaccount.BaseAccount{}, // prototype ) ck := bank.NewKeeper(accountMapper) keeper := NewKeeper(cdc, keyStake, ck, DefaultCodespace) From 34a10072b4c9ded9d70250c55f7c476e9de71893 Mon Sep 17 00:00:00 2001 From: sunnya97 Date: Wed, 23 May 2018 19:47:33 -0700 Subject: [PATCH 02/10] in progress --- x/auth/client/rest/query.go | 7 ++++--- x/ibc/client/cli/relay.go | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 52244fec9c..a60ce5cdb2 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -10,19 +10,20 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" - auth "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + "github.com/cosmos/cosmos-sdk/x/auth" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" ) // register REST routes func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, storeName string) { r.HandleFunc( "/accounts/{address}", - QueryAccountRequestHandlerFn(storeName, cdc, auth.GetAccountDecoder(cdc), ctx), + QueryAccountRequestHandlerFn(storeName, cdc, authcmd.GetAccountDecoder(cdc), ctx), ).Methods("GET") } // query accountREST Handler -func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder sdk.AccountDecoder, ctx context.CoreContext) http.HandlerFunc { +func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder auth.AccountDecoder, ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) addr := vars["address"] diff --git a/x/ibc/client/cli/relay.go b/x/ibc/client/cli/relay.go index 86e8b1dbf8..7fd9a8fcc1 100644 --- a/x/ibc/client/cli/relay.go +++ b/x/ibc/client/cli/relay.go @@ -12,6 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc" ) @@ -27,7 +28,7 @@ const ( type relayCommander struct { cdc *wire.Codec address sdk.Address - decoder sdk.AccountDecoder + decoder auth.AccountDecoder mainStore string ibcStore string From cb527126600cddd895f5671bed8dbcdca270415d Mon Sep 17 00:00:00 2001 From: sunnya97 Date: Wed, 23 May 2018 19:26:54 -0700 Subject: [PATCH 03/10] in progress --- baseapp/baseapp.go | 3 +- client/context/helpers.go | 9 +- client/context/types.go | 6 +- client/tx/query.go | 3 +- cmd/gaia/app/app.go | 18 ++- cmd/gaia/app/genesis.go | 11 +- types/account.go | 29 ----- types/handler.go | 3 - types/signature.go | 10 -- types/tx_msg.go | 117 ----------------- x/auth/account.go | 25 ++++ x/auth/ante.go | 30 ++--- x/auth/client/cli/account.go | 7 +- x/auth/context.go | 8 +- x/auth/mapper.go | 30 +++-- x/auth/stdtx.go | 131 ++++++++++++++++++++ x/auth/wire.go | 12 -- x/bank/keeper.go | 27 ++-- x/{auth => baseaccount}/baseaccount.go | 9 +- x/{auth => baseaccount}/baseaccount_test.go | 2 +- x/{auth => baseaccount}/handler.go | 13 +- x/{auth => baseaccount}/msgs.go | 7 +- x/{auth => baseaccount}/msgs_test.go | 2 +- x/baseaccount/wire.go | 14 +++ x/stake/test_common.go | 16 ++- 25 files changed, 280 insertions(+), 262 deletions(-) delete mode 100644 types/signature.go create mode 100644 x/auth/account.go create mode 100644 x/auth/stdtx.go delete mode 100644 x/auth/wire.go rename x/{auth => baseaccount}/baseaccount.go (90%) rename x/{auth => baseaccount}/baseaccount_test.go (99%) rename x/{auth => baseaccount}/handler.go (58%) rename x/{auth => baseaccount}/msgs.go (87%) rename x/{auth => baseaccount}/msgs_test.go (97%) create mode 100644 x/baseaccount/wire.go diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index ef3bbc3c79..4ce8a05d9b 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -15,6 +15,7 @@ import ( "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" ) // Key to store the header in the DB itself. @@ -125,7 +126,7 @@ func (app *BaseApp) SetTxDecoder(txDecoder sdk.TxDecoder) { // default custom logic for transaction decoding func defaultTxDecoder(cdc *wire.Codec) sdk.TxDecoder { return func(txBytes []byte) (sdk.Tx, sdk.Error) { - var tx = sdk.StdTx{} + var tx = auth.StdTx{} if len(txBytes) == 0 { return nil, sdk.ErrTxDecode("txBytes are empty") diff --git a/client/context/helpers.go b/client/context/helpers.go index 562bde9b4c..f4686befde 100644 --- a/client/context/helpers.go +++ b/client/context/helpers.go @@ -6,6 +6,7 @@ import ( "github.com/pkg/errors" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" rpcclient "github.com/tendermint/tendermint/rpc/client" ctypes "github.com/tendermint/tendermint/rpc/core/types" cmn "github.com/tendermint/tmlibs/common" @@ -109,11 +110,11 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w return nil, errors.Errorf("Chain ID required but not specified") } sequence := ctx.Sequence - signMsg := sdk.StdSignMsg{ + signMsg := auth.StdSignMsg{ ChainID: chainID, Sequences: []int64{sequence}, Msg: msg, - Fee: sdk.NewStdFee(10000, sdk.Coin{}), // TODO run simulate to estimate gas? + Fee: auth.NewStdFee(10000, sdk.Coin{}), // TODO run simulate to estimate gas? } keybase, err := keys.GetKeyBase() @@ -128,14 +129,14 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msg sdk.Msg, cdc *w if err != nil { return nil, err } - sigs := []sdk.StdSignature{{ + sigs := []auth.StdSignature{{ PubKey: pubkey, Signature: sig, Sequence: sequence, }} // marshal bytes - tx := sdk.NewStdTx(signMsg.Msg, signMsg.Fee, sigs) + tx := auth.NewStdTx(signMsg.Msg, signMsg.Fee, sigs) return cdc.MarshalBinary(tx) } diff --git a/client/context/types.go b/client/context/types.go index e580027d67..da15b32936 100644 --- a/client/context/types.go +++ b/client/context/types.go @@ -3,7 +3,7 @@ package context import ( rpcclient "github.com/tendermint/tendermint/rpc/client" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) // typical context created in sdk modules for transactions/queries @@ -15,7 +15,7 @@ type CoreContext struct { FromAddressName string Sequence int64 Client rpcclient.Client - Decoder sdk.AccountDecoder + Decoder auth.AccountDecoder AccountStore string } @@ -63,7 +63,7 @@ func (c CoreContext) WithClient(client rpcclient.Client) CoreContext { } // WithDecoder - return a copy of the context with an updated Decoder -func (c CoreContext) WithDecoder(decoder sdk.AccountDecoder) CoreContext { +func (c CoreContext) WithDecoder(decoder auth.AccountDecoder) CoreContext { c.Decoder = decoder return c } diff --git a/client/tx/query.go b/client/tx/query.go index 2078b78831..7673dd38db 100644 --- a/client/tx/query.go +++ b/client/tx/query.go @@ -17,6 +17,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" ) // Get the default command for a tx query @@ -95,7 +96,7 @@ type txInfo struct { } func parseTx(cdc *wire.Codec, txBytes []byte) (sdk.Tx, error) { - var tx sdk.StdTx + var tx auth.StdTx err := cdc.UnmarshalBinary(txBytes, &tx) if err != nil { return nil, err diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 42869c9558..9436c8b0fc 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -14,7 +14,11 @@ import ( "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" +<<<<<<< HEAD feed "github.com/cosmos/cosmos-sdk/x/fee_distribution" +======= + "github.com/cosmos/cosmos-sdk/x/baseaccount" +>>>>>>> in progress "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/cosmos/cosmos-sdk/x/stake" ) @@ -41,7 +45,7 @@ type GaiaApp struct { keyStake *sdk.KVStoreKey // Manage getting and setting accounts - accountMapper sdk.AccountMapper + accountMapper auth.AccountMapper coinKeeper bank.Keeper ibcMapper ibc.Mapper stakeKeeper stake.Keeper @@ -63,8 +67,8 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { // define the accountMapper app.accountMapper = auth.NewAccountMapper( app.cdc, - app.keyAccount, // target store - &auth.BaseAccount{}, // prototype + app.keyAccount, // target store + &baseaccount.BaseAccount{}, // prototype ) // add handlers @@ -82,7 +86,11 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { app.SetInitChainer(app.initChainer) app.SetEndBlocker(stake.NewEndBlocker(app.stakeKeeper)) app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake) +<<<<<<< HEAD app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, feed.BurnFeeHandler)) +======= + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) +>>>>>>> in progress err := app.LoadLatestVersion(app.keyMain) if err != nil { cmn.Exit(err.Error()) @@ -97,7 +105,7 @@ func MakeCodec() *wire.Codec { ibc.RegisterWire(cdc) bank.RegisterWire(cdc) stake.RegisterWire(cdc) - auth.RegisterWire(cdc) + baseaccount.RegisterWire(cdc) sdk.RegisterWire(cdc) wire.RegisterCrypto(cdc) return cdc @@ -132,7 +140,7 @@ func (app *GaiaApp) ExportAppStateJSON() (appState json.RawMessage, err error) { // iterate to get the accounts accounts := []GenesisAccount{} - appendAccount := func(acc sdk.Account) (stop bool) { + appendAccount := func(acc auth.Account) (stop bool) { account := NewGenesisAccountI(acc) accounts = append(accounts, account) return false diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index 525fe8ab07..6914ec4927 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -13,6 +13,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/baseaccount" "github.com/cosmos/cosmos-sdk/x/stake" ) @@ -28,14 +29,14 @@ type GenesisAccount struct { Coins sdk.Coins `json:"coins"` } -func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount { +func NewGenesisAccount(acc *baseaccount.BaseAccount) GenesisAccount { return GenesisAccount{ Address: acc.Address, Coins: acc.Coins, } } -func NewGenesisAccountI(acc sdk.Account) GenesisAccount { +func NewGenesisAccountI(acc auth.Account) GenesisAccount { return GenesisAccount{ Address: acc.GetAddress(), Coins: acc.GetCoins(), @@ -43,8 +44,8 @@ func NewGenesisAccountI(acc sdk.Account) GenesisAccount { } // convert GenesisAccount to auth.BaseAccount -func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { - return &auth.BaseAccount{ +func (ga *GenesisAccount) ToAccount() (acc *baseaccount.BaseAccount) { + return &baseaccount.BaseAccount{ Address: ga.Address, Coins: ga.Coins.Sort(), } @@ -148,7 +149,7 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso } // create the genesis account, give'm few steaks and a buncha token with there name - accAuth := auth.NewBaseAccountWithAddress(genTx.Address) + accAuth := baseaccount.NewBaseAccountWithAddress(genTx.Address) accAuth.Coins = sdk.Coins{ {genTx.Name + "Token", 1000}, {"steak", freeFermionsAcc}, diff --git a/types/account.go b/types/account.go index 74cd87f38c..be8b90a1cd 100644 --- a/types/account.go +++ b/types/account.go @@ -4,7 +4,6 @@ import ( "encoding/hex" "errors" - crypto "github.com/tendermint/go-crypto" cmn "github.com/tendermint/tmlibs/common" ) @@ -22,31 +21,3 @@ func GetAddress(address string) (addr Address, err error) { } return Address(bz), nil } - -// Account is a standard account using a sequence number for replay protection -// and a pubkey for authentication. -type Account interface { - GetAddress() Address - SetAddress(Address) error // errors if already set. - - GetPubKey() crypto.PubKey // can return nil. - SetPubKey(crypto.PubKey) error - - GetSequence() int64 - SetSequence(int64) error - - GetCoins() Coins - SetCoins(Coins) error -} - -// AccountMapper stores and retrieves accounts from stores -// retrieved from the context. -type AccountMapper interface { - NewAccountWithAddress(ctx Context, addr Address) Account - GetAccount(ctx Context, addr Address) Account - SetAccount(ctx Context, acc Account) - IterateAccounts(ctx Context, process func(Account) (stop bool)) -} - -// AccountDecoder unmarshals account bytes -type AccountDecoder func(accountBytes []byte) (Account, error) diff --git a/types/handler.go b/types/handler.go index 679a3b1a78..129f42647a 100644 --- a/types/handler.go +++ b/types/handler.go @@ -3,8 +3,5 @@ package types // core function variable which application runs for transactions type Handler func(ctx Context, msg Msg) Result -// core function variable which application runs to handle fees -type FeeHandler func(ctx Context, tx Tx, fee Coins) - // If newCtx.IsZero(), ctx is used instead. type AnteHandler func(ctx Context, tx Tx) (newCtx Context, result Result, abort bool) diff --git a/types/signature.go b/types/signature.go deleted file mode 100644 index 5bca2f6069..0000000000 --- a/types/signature.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -import crypto "github.com/tendermint/go-crypto" - -// Standard Signature -type StdSignature struct { - crypto.PubKey `json:"pub_key"` // optional - crypto.Signature `json:"signature"` - Sequence int64 `json:"sequence"` -} diff --git a/types/tx_msg.go b/types/tx_msg.go index e17d152a5f..186cf9b242 100644 --- a/types/tx_msg.go +++ b/types/tx_msg.go @@ -31,123 +31,6 @@ type Tx interface { // Gets the Msg. GetMsg() Msg - - // Signatures returns the signature of signers who signed the Msg. - // CONTRACT: Length returned is same as length of - // pubkeys returned from MsgKeySigners, and the order - // matches. - // CONTRACT: If the signature is missing (ie the Msg is - // invalid), then the corresponding signature is - // .Empty(). - GetSignatures() []StdSignature -} - -var _ Tx = (*StdTx)(nil) - -// StdTx is a standard way to wrap a Msg with Fee and Signatures. -// NOTE: the first signature is the FeePayer (Signatures must not be nil). -type StdTx struct { - Msg `json:"msg"` - Fee StdFee `json:"fee"` - Signatures []StdSignature `json:"signatures"` -} - -func NewStdTx(msg Msg, fee StdFee, sigs []StdSignature) StdTx { - return StdTx{ - Msg: msg, - Fee: fee, - Signatures: sigs, - } -} - -//nolint -func (tx StdTx) GetMsg() Msg { return tx.Msg } -func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures } - -// FeePayer returns the address responsible for paying the fees -// for the transactions. It's the first address returned by msg.GetSigners(). -// If GetSigners() is empty, this panics. -func FeePayer(tx Tx) Address { - return tx.GetMsg().GetSigners()[0] -} - -//__________________________________________________________ - -// StdFee includes the amount of coins paid in fees and the maximum -// gas to be used by the transaction. The ratio yields an effective "gasprice", -// which must be above some miminum to be accepted into the mempool. -type StdFee struct { - Amount Coins `json:"amount"` - Gas int64 `json:"gas"` -} - -func NewStdFee(gas int64, amount ...Coin) StdFee { - return StdFee{ - Amount: amount, - Gas: gas, - } -} - -// fee bytes for signing later -func (fee StdFee) Bytes() []byte { - // normalize. XXX - // this is a sign of something ugly - // (in the lcd_test, client side its null, - // server side its []) - if len(fee.Amount) == 0 { - fee.Amount = Coins{} - } - bz, err := json.Marshal(fee) // TODO - if err != nil { - panic(err) - } - return bz -} - -//__________________________________________________________ - -// StdSignDoc is replay-prevention structure. -// It includes the result of msg.GetSignBytes(), -// as well as the ChainID (prevent cross chain replay) -// and the Sequence numbers for each signature (prevent -// inchain replay and enforce tx ordering per account). -type StdSignDoc struct { - ChainID string `json:"chain_id"` - Sequences []int64 `json:"sequences"` - FeeBytes []byte `json:"fee_bytes"` - MsgBytes []byte `json:"msg_bytes"` - AltBytes []byte `json:"alt_bytes"` -} - -// StdSignBytes returns the bytes to sign for a transaction. -// TODO: change the API to just take a chainID and StdTx ? -func StdSignBytes(chainID string, sequences []int64, fee StdFee, msg Msg) []byte { - bz, err := json.Marshal(StdSignDoc{ - ChainID: chainID, - Sequences: sequences, - FeeBytes: fee.Bytes(), - MsgBytes: msg.GetSignBytes(), - }) - if err != nil { - panic(err) - } - return bz -} - -// StdSignMsg is a convenience structure for passing along -// a Msg with the other requirements for a StdSignDoc before -// it is signed. For use in the CLI. -type StdSignMsg struct { - ChainID string - Sequences []int64 - Fee StdFee - Msg Msg - // XXX: Alt -} - -// get message bytes -func (msg StdSignMsg) Bytes() []byte { - return StdSignBytes(msg.ChainID, msg.Sequences, msg.Fee, msg.Msg) } //__________________________________________________________ diff --git a/x/auth/account.go b/x/auth/account.go new file mode 100644 index 0000000000..28366467aa --- /dev/null +++ b/x/auth/account.go @@ -0,0 +1,25 @@ +package auth + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + crypto "github.com/tendermint/go-crypto" +) + +// Account is a standard account using a sequence number for replay protection +// and a pubkey for authentication. +type Account interface { + GetAddress() sdk.Address + SetAddress(sdk.Address) error // errors if already set. + + GetPubKey() crypto.PubKey // can return nil. + SetPubKey(crypto.PubKey) error + + GetSequence() int64 + SetSequence(int64) error + + GetCoins() sdk.Coins + SetCoins(sdk.Coins) error +} + +// AccountDecoder unmarshals account bytes +type AccountDecoder func(accountBytes []byte) (Account, error) diff --git a/x/auth/ante.go b/x/auth/ante.go index 21d17fb9be..d57c8558ef 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -15,13 +15,20 @@ const ( // NewAnteHandler returns an AnteHandler that checks // and increments sequence numbers, checks signatures, // and deducts fees from the first signer. -func NewAnteHandler(am sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHandler { +func NewAnteHandler(am AccountMapper) sdk.AnteHandler { + return func( ctx sdk.Context, tx sdk.Tx, ) (_ sdk.Context, _ sdk.Result, abort bool) { + // This AnteHandler requires Txs to be StdTxs + stdTx, ok := tx.(StdTx) + if !ok { + return ctx, sdk.ErrInternal("tx must be sdk.StdTx").Result(), true + } + // Assert that there are signatures. - var sigs = tx.GetSignatures() + var sigs = stdTx.GetSignatures() if len(sigs) == 0 { return ctx, sdk.ErrUnauthorized("no signers").Result(), @@ -30,12 +37,6 @@ func NewAnteHandler(am sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHan msg := tx.GetMsg() - // TODO: will this always be a stdtx? should that be used in the function signature? - stdTx, ok := tx.(sdk.StdTx) - if !ok { - return ctx, sdk.ErrInternal("tx must be sdk.StdTx").Result(), true - } - // Assert that number of signatures is correct. var signerAddrs = msg.GetSigners() if len(sigs) != len(signerAddrs) { @@ -56,10 +57,10 @@ func NewAnteHandler(am sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHan if chainID == "" { chainID = viper.GetString("chain-id") } - signBytes := sdk.StdSignBytes(ctx.ChainID(), sequences, fee, msg) + signBytes := StdSignBytes(ctx.ChainID(), sequences, fee, msg) // Check sig and nonce and collect signer accounts. - var signerAccs = make([]sdk.Account, len(signerAddrs)) + var signerAccs = make([]Account, len(signerAddrs)) for i := 0; i < len(sigs); i++ { signerAddr, sig := signerAddrs[i], sigs[i] @@ -77,7 +78,6 @@ func NewAnteHandler(am sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHan // TODO: min fee if !fee.Amount.IsZero() { signerAcc, res = deductFees(signerAcc, fee) - feeHandler(ctx, tx, fee.Amount) if !res.IsOK() { return ctx, res, true } @@ -104,9 +104,9 @@ func NewAnteHandler(am sdk.AccountMapper, feeHandler sdk.FeeHandler) sdk.AnteHan // verify the signature and increment the sequence. // if the account doesn't have a pubkey, set it. func processSig( - ctx sdk.Context, am sdk.AccountMapper, - addr sdk.Address, sig sdk.StdSignature, signBytes []byte) ( - acc sdk.Account, res sdk.Result) { + ctx sdk.Context, am AccountMapper, + addr sdk.Address, sig StdSignature, signBytes []byte) ( + acc Account, res sdk.Result) { // Get the account. acc = am.GetAccount(ctx, addr) @@ -152,7 +152,7 @@ func processSig( // Deduct the fee from the account. // We could use the CoinKeeper (in addition to the AccountMapper, // because the CoinKeeper doesn't give us accounts), but it seems easier to do this. -func deductFees(acc sdk.Account, fee sdk.StdFee) (sdk.Account, sdk.Result) { +func deductFees(acc Account, fee StdFee) (Account, sdk.Result) { coins := acc.GetCoins() feeAmount := fee.Amount diff --git a/x/auth/client/cli/account.go b/x/auth/client/cli/account.go index b45cb12ddf..08bd520fb1 100644 --- a/x/auth/client/cli/account.go +++ b/x/auth/client/cli/account.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" ) // GetAccountCmd for the auth.BaseAccount type @@ -17,8 +18,8 @@ func GetAccountCmdDefault(storeName string, cdc *wire.Codec) *cobra.Command { } // Get account decoder for auth.DefaultAccount -func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { - return func(accBytes []byte) (acct sdk.Account, err error) { +func GetAccountDecoder(cdc *wire.Codec) auth.AccountDecoder { + return func(accBytes []byte) (acct auth.Account, err error) { // acct := new(auth.BaseAccount) err = cdc.UnmarshalBinaryBare(accBytes, &acct) if err != nil { @@ -30,7 +31,7 @@ func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { // GetAccountCmd returns a query account that will display the // state of the account at a given address -func GetAccountCmd(storeName string, cdc *wire.Codec, decoder sdk.AccountDecoder) *cobra.Command { +func GetAccountCmd(storeName string, cdc *wire.Codec, decoder auth.AccountDecoder) *cobra.Command { return &cobra.Command{ Use: "account [address]", Short: "Query account balance", diff --git a/x/auth/context.go b/x/auth/context.go index b233f1e861..40fb177858 100644 --- a/x/auth/context.go +++ b/x/auth/context.go @@ -34,15 +34,15 @@ const ( ) // add the signers to the context -func WithSigners(ctx types.Context, accounts []types.Account) types.Context { +func WithSigners(ctx types.Context, accounts []Account) types.Context { return ctx.WithValue(contextKeySigners, accounts) } // get the signers from the context -func GetSigners(ctx types.Context) []types.Account { +func GetSigners(ctx types.Context) []Account { v := ctx.Value(contextKeySigners) if v == nil { - return []types.Account{} + return []Account{} } - return v.([]types.Account) + return v.([]Account) } diff --git a/x/auth/mapper.go b/x/auth/mapper.go index 3666f13b69..cdab2480e3 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -9,9 +9,6 @@ import ( crypto "github.com/tendermint/go-crypto" ) -var _ sdk.AccountMapper = (*AccountMapper)(nil) - -// Implements sdk.AccountMapper. // This AccountMapper encodes/decodes accounts using the // go-amino (binary) encoding/decoding library. type AccountMapper struct { @@ -19,8 +16,8 @@ type AccountMapper struct { // The (unexposed) key used to access the store from the Context. key sdk.StoreKey - // The prototypical sdk.Account concrete type. - proto sdk.Account + // The prototypical Account concrete type. + proto Account // The wire codec for binary encoding/decoding of accounts. cdc *wire.Codec @@ -29,7 +26,7 @@ type AccountMapper struct { // NewAccountMapper returns a new sdk.AccountMapper that // uses go-amino to (binary) encode and decode concrete sdk.Accounts. // nolint -func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto sdk.Account) AccountMapper { +func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto Account) AccountMapper { return AccountMapper{ key: key, proto: proto, @@ -38,14 +35,14 @@ func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto sdk.Account) Acco } // Implaements sdk.AccountMapper. -func (am AccountMapper) NewAccountWithAddress(ctx sdk.Context, addr sdk.Address) sdk.Account { +func (am AccountMapper) NewAccountWithAddress(ctx sdk.Context, addr sdk.Address) Account { acc := am.clonePrototype() acc.SetAddress(addr) return acc } // Implements sdk.AccountMapper. -func (am AccountMapper) GetAccount(ctx sdk.Context, addr sdk.Address) sdk.Account { +func (am AccountMapper) GetAccount(ctx sdk.Context, addr sdk.Address) Account { store := ctx.KVStore(am.key) bz := store.Get(addr) if bz == nil { @@ -56,7 +53,7 @@ func (am AccountMapper) GetAccount(ctx sdk.Context, addr sdk.Address) sdk.Accoun } // Implements sdk.AccountMapper. -func (am AccountMapper) SetAccount(ctx sdk.Context, acc sdk.Account) { +func (am AccountMapper) SetAccount(ctx sdk.Context, acc Account) { addr := acc.GetAddress() store := ctx.KVStore(am.key) bz := am.encodeAccount(acc) @@ -64,7 +61,7 @@ func (am AccountMapper) SetAccount(ctx sdk.Context, acc sdk.Account) { } // Implements sdk.AccountMapper. -func (am AccountMapper) IterateAccounts(ctx sdk.Context, process func(sdk.Account) (stop bool)) { +func (am AccountMapper) IterateAccounts(ctx sdk.Context, process func(Account) (stop bool)) { store := ctx.KVStore(am.key) iter := store.Iterator(nil, nil) for { @@ -89,7 +86,8 @@ func (am AccountMapper) GetPubKey(ctx sdk.Context, addr sdk.Address) (crypto.Pub return acc.GetPubKey(), nil } -func (am AccountMapper) setPubKey(ctx sdk.Context, addr sdk.Address, newPubKey crypto.PubKey) sdk.Error { +// Sets the PubKey of the account at address +func (am AccountMapper) SetPubKey(ctx sdk.Context, addr sdk.Address, newPubKey crypto.PubKey) sdk.Error { acc := am.GetAccount(ctx, addr) if acc == nil { return sdk.ErrUnknownAddress(addr.String()) @@ -122,7 +120,7 @@ func (am AccountMapper) setSequence(ctx sdk.Context, addr sdk.Address, newSequen // misc. // Creates a new struct (or pointer to struct) from am.proto. -func (am AccountMapper) clonePrototype() sdk.Account { +func (am AccountMapper) clonePrototype() Account { protoRt := reflect.TypeOf(am.proto) if protoRt.Kind() == reflect.Ptr { protoCrt := protoRt.Elem() @@ -130,7 +128,7 @@ func (am AccountMapper) clonePrototype() sdk.Account { panic("accountMapper requires a struct proto sdk.Account, or a pointer to one") } protoRv := reflect.New(protoCrt) - clone, ok := protoRv.Interface().(sdk.Account) + clone, ok := protoRv.Interface().(Account) if !ok { panic(fmt.Sprintf("accountMapper requires a proto sdk.Account, but %v doesn't implement sdk.Account", protoRt)) } @@ -138,14 +136,14 @@ func (am AccountMapper) clonePrototype() sdk.Account { } protoRv := reflect.New(protoRt).Elem() - clone, ok := protoRv.Interface().(sdk.Account) + clone, ok := protoRv.Interface().(Account) if !ok { panic(fmt.Sprintf("accountMapper requires a proto sdk.Account, but %v doesn't implement sdk.Account", protoRt)) } return clone } -func (am AccountMapper) encodeAccount(acc sdk.Account) []byte { +func (am AccountMapper) encodeAccount(acc Account) []byte { bz, err := am.cdc.MarshalBinaryBare(acc) if err != nil { panic(err) @@ -153,7 +151,7 @@ func (am AccountMapper) encodeAccount(acc sdk.Account) []byte { return bz } -func (am AccountMapper) decodeAccount(bz []byte) (acc sdk.Account) { +func (am AccountMapper) decodeAccount(bz []byte) (acc Account) { err := am.cdc.UnmarshalBinaryBare(bz, &acc) if err != nil { panic(err) diff --git a/x/auth/stdtx.go b/x/auth/stdtx.go new file mode 100644 index 0000000000..bc01b01490 --- /dev/null +++ b/x/auth/stdtx.go @@ -0,0 +1,131 @@ +package auth + +import ( + "encoding/json" + + sdk "github.com/cosmos/cosmos-sdk/types" + crypto "github.com/tendermint/go-crypto" +) + +var _ sdk.Tx = (*StdTx)(nil) + +// StdTx is a standard way to wrap a Msg with Fee and Signatures. +// NOTE: the first signature is the FeePayer (Signatures must not be nil). +type StdTx struct { + Msg sdk.Msg `json:"msg"` + Fee StdFee `json:"fee"` + Signatures []StdSignature `json:"signatures"` +} + +func NewStdTx(msg sdk.Msg, fee StdFee, sigs []StdSignature) StdTx { + return StdTx{ + Msg: msg, + Fee: fee, + Signatures: sigs, + } +} + +//nolint +func (tx StdTx) GetMsg() sdk.Msg { return tx.Msg } + +// Signatures returns the signature of signers who signed the Msg. +// CONTRACT: Length returned is same as length of +// pubkeys returned from MsgKeySigners, and the order +// matches. +// CONTRACT: If the signature is missing (ie the Msg is +// invalid), then the corresponding signature is +// .Empty(). +func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures } + +// FeePayer returns the address responsible for paying the fees +// for the transactions. It's the first address returned by msg.GetSigners(). +// If GetSigners() is empty, this panics. +func FeePayer(tx sdk.Tx) sdk.Address { + return tx.GetMsg().GetSigners()[0] +} + +//__________________________________________________________ + +// StdFee includes the amount of coins paid in fees and the maximum +// gas to be used by the transaction. The ratio yields an effective "gasprice", +// which must be above some miminum to be accepted into the mempool. +type StdFee struct { + Amount sdk.Coins `json:"amount"` + Gas int64 `json:"gas"` +} + +func NewStdFee(gas int64, amount ...sdk.Coin) StdFee { + return StdFee{ + Amount: amount, + Gas: gas, + } +} + +// fee bytes for signing later +func (fee StdFee) Bytes() []byte { + // normalize. XXX + // this is a sign of something ugly + // (in the lcd_test, client side its null, + // server side its []) + if len(fee.Amount) == 0 { + fee.Amount = sdk.Coins{} + } + bz, err := json.Marshal(fee) // TODO + if err != nil { + panic(err) + } + return bz +} + +//__________________________________________________________ + +// StdSignDoc is replay-prevention structure. +// It includes the result of msg.GetSignBytes(), +// as well as the ChainID (prevent cross chain replay) +// and the Sequence numbers for each signature (prevent +// inchain replay and enforce tx ordering per account). +type StdSignDoc struct { + ChainID string `json:"chain_id"` + Sequences []int64 `json:"sequences"` + FeeBytes []byte `json:"fee_bytes"` + MsgBytes []byte `json:"msg_bytes"` + AltBytes []byte `json:"alt_bytes"` +} + +// StdSignBytes returns the bytes to sign for a transaction. +// TODO: change the API to just take a chainID and StdTx ? +func StdSignBytes(chainID string, sequences []int64, fee StdFee, msg sdk.Msg) []byte { + bz, err := json.Marshal(StdSignDoc{ + ChainID: chainID, + Sequences: sequences, + FeeBytes: fee.Bytes(), + MsgBytes: msg.GetSignBytes(), + }) + if err != nil { + panic(err) + } + return bz +} + +// StdSignMsg is a convenience structure for passing along +// a Msg with the other requirements for a StdSignDoc before +// it is signed. For use in the CLI. +type StdSignMsg struct { + ChainID string + Sequences []int64 + Fee StdFee + Msg sdk.Msg + // XXX: Alt +} + +// get message bytes +func (msg StdSignMsg) Bytes() []byte { + return StdSignBytes(msg.ChainID, msg.Sequences, msg.Fee, msg.Msg) +} + +// Standard Signature +type StdSignature struct { + crypto.PubKey `json:"pub_key"` // optional + crypto.Signature `json:"signature"` + Sequence int64 `json:"sequence"` +} diff --git a/x/auth/wire.go b/x/auth/wire.go deleted file mode 100644 index 9db1b85cca..0000000000 --- a/x/auth/wire.go +++ /dev/null @@ -1,12 +0,0 @@ -package auth - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/wire" -) - -// Register concrete types on wire codec for default AppAccount -func RegisterWire(cdc *wire.Codec) { - cdc.RegisterInterface((*sdk.Account)(nil), nil) - cdc.RegisterConcrete(&BaseAccount{}, "auth/Account", nil) -} diff --git a/x/bank/keeper.go b/x/bank/keeper.go index 6ef73c68b6..b14da4d81f 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -4,6 +4,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) const ( @@ -16,11 +17,11 @@ const ( // Keeper manages transfers between accounts type Keeper struct { - am sdk.AccountMapper + am auth.AccountMapper } // NewKeeper returns a new Keeper -func NewKeeper(am sdk.AccountMapper) Keeper { +func NewKeeper(am auth.AccountMapper) Keeper { return Keeper{am: am} } @@ -63,11 +64,11 @@ func (keeper Keeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs [ // SendKeeper only allows transfers between accounts, without the possibility of creating coins type SendKeeper struct { - am sdk.AccountMapper + am auth.AccountMapper } // NewSendKeeper returns a new Keeper -func NewSendKeeper(am sdk.AccountMapper) SendKeeper { +func NewSendKeeper(am auth.AccountMapper) SendKeeper { return SendKeeper{am: am} } @@ -95,11 +96,11 @@ func (keeper SendKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outpu // ViewKeeper only allows reading of balances type ViewKeeper struct { - am sdk.AccountMapper + am auth.AccountMapper } // NewViewKeeper returns a new Keeper -func NewViewKeeper(am sdk.AccountMapper) ViewKeeper { +func NewViewKeeper(am auth.AccountMapper) ViewKeeper { return ViewKeeper{am: am} } @@ -115,7 +116,7 @@ func (keeper ViewKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coi //______________________________________________________________________________________________ -func getCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address) sdk.Coins { +func getCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address) sdk.Coins { ctx.GasMeter().ConsumeGas(costGetCoins, "getCoins") acc := am.GetAccount(ctx, addr) if acc == nil { @@ -124,7 +125,7 @@ func getCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address) sdk.Coins return acc.GetCoins() } -func setCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) sdk.Error { +func setCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt sdk.Coins) sdk.Error { ctx.GasMeter().ConsumeGas(costSetCoins, "setCoins") acc := am.GetAccount(ctx, addr) if acc == nil { @@ -136,13 +137,13 @@ func setCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.C } // HasCoins returns whether or not an account has at least amt coins. -func hasCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) bool { +func hasCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt sdk.Coins) bool { ctx.GasMeter().ConsumeGas(costHasCoins, "hasCoins") return getCoins(ctx, am, addr).IsGTE(amt) } // SubtractCoins subtracts amt from the coins at the addr. -func subtractCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { +func subtractCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { ctx.GasMeter().ConsumeGas(costSubtractCoins, "subtractCoins") oldCoins := getCoins(ctx, am, addr) newCoins := oldCoins.Minus(amt) @@ -155,7 +156,7 @@ func subtractCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt } // AddCoins adds amt to the coins at the addr. -func addCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { +func addCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { ctx.GasMeter().ConsumeGas(costAddCoins, "addCoins") oldCoins := getCoins(ctx, am, addr) newCoins := oldCoins.Plus(amt) @@ -169,7 +170,7 @@ func addCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.C // SendCoins moves coins from one account to another // NOTE: Make sure to revert state changes from tx on error -func sendCoins(ctx sdk.Context, am sdk.AccountMapper, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) (sdk.Tags, sdk.Error) { +func sendCoins(ctx sdk.Context, am auth.AccountMapper, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) (sdk.Tags, sdk.Error) { _, subTags, err := subtractCoins(ctx, am, fromAddr, amt) if err != nil { return nil, err @@ -185,7 +186,7 @@ func sendCoins(ctx sdk.Context, am sdk.AccountMapper, fromAddr sdk.Address, toAd // InputOutputCoins handles a list of inputs and outputs // NOTE: Make sure to revert state changes from tx on error -func inputOutputCoins(ctx sdk.Context, am sdk.AccountMapper, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) { +func inputOutputCoins(ctx sdk.Context, am auth.AccountMapper, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) { allTags := sdk.EmptyTags() for _, in := range inputs { diff --git a/x/auth/baseaccount.go b/x/baseaccount/baseaccount.go similarity index 90% rename from x/auth/baseaccount.go rename to x/baseaccount/baseaccount.go index ff907fc387..9701ac41dc 100644 --- a/x/auth/baseaccount.go +++ b/x/baseaccount/baseaccount.go @@ -1,18 +1,19 @@ -package auth +package baseaccount import ( "errors" - "github.com/tendermint/go-crypto" + crypto "github.com/tendermint/go-crypto" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" ) //----------------------------------------------------------- // BaseAccount -var _ sdk.Account = (*BaseAccount)(nil) +var _ auth.Account = (*BaseAccount)(nil) // BaseAccount - base account structure. // Extend this by embedding this in your AppAccount. @@ -82,7 +83,7 @@ func (acc *BaseAccount) SetSequence(seq int64) error { // Most users shouldn't use this, but this comes handy for tests. func RegisterBaseAccount(cdc *wire.Codec) { - cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterInterface((*auth.Account)(nil), nil) cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil) wire.RegisterCrypto(cdc) } diff --git a/x/auth/baseaccount_test.go b/x/baseaccount/baseaccount_test.go similarity index 99% rename from x/auth/baseaccount_test.go rename to x/baseaccount/baseaccount_test.go index d3363e4fb0..ed1a322c2f 100644 --- a/x/auth/baseaccount_test.go +++ b/x/baseaccount/baseaccount_test.go @@ -1,4 +1,4 @@ -package auth +package baseaccount import ( "testing" diff --git a/x/auth/handler.go b/x/baseaccount/handler.go similarity index 58% rename from x/auth/handler.go rename to x/baseaccount/handler.go index 8a0e1061ae..46307c8818 100644 --- a/x/auth/handler.go +++ b/x/baseaccount/handler.go @@ -1,19 +1,20 @@ -package auth +package baseaccount import ( "reflect" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) -// NewHandler returns a handler for "auth" type messages. -func NewHandler(am AccountMapper) sdk.Handler { +// NewHandler returns a handler for "baseaccount" type messages. +func NewHandler(am auth.AccountMapper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { case MsgChangeKey: return handleMsgChangeKey(ctx, am, msg) default: - errMsg := "Unrecognized auth Msg type: " + reflect.TypeOf(msg).Name() + errMsg := "Unrecognized baseaccount Msg type: " + reflect.TypeOf(msg).Name() return sdk.ErrUnknownRequest(errMsg).Result() } } @@ -21,9 +22,9 @@ func NewHandler(am AccountMapper) sdk.Handler { // Handle MsgChangeKey // Should be very expensive, because once this happens, an account is un-prunable -func handleMsgChangeKey(ctx sdk.Context, am AccountMapper, msg MsgChangeKey) sdk.Result { +func handleMsgChangeKey(ctx sdk.Context, am auth.AccountMapper, msg MsgChangeKey) sdk.Result { - err := am.setPubKey(ctx, msg.Address, msg.NewPubKey) + err := am.SetPubKey(ctx, msg.Address, msg.NewPubKey) if err != nil { return err.Result() } diff --git a/x/auth/msgs.go b/x/baseaccount/msgs.go similarity index 87% rename from x/auth/msgs.go rename to x/baseaccount/msgs.go index 545b296e5b..f0319ac7fe 100644 --- a/x/auth/msgs.go +++ b/x/baseaccount/msgs.go @@ -1,11 +1,10 @@ -package auth +package baseaccount import ( "encoding/json" - "github.com/tendermint/go-crypto" - sdk "github.com/cosmos/cosmos-sdk/types" + crypto "github.com/tendermint/go-crypto" ) // MsgChangeKey - high level transaction of the auth module @@ -22,7 +21,7 @@ func NewMsgChangeKey(addr sdk.Address, pubkey crypto.PubKey) MsgChangeKey { } // Implements Msg. -func (msg MsgChangeKey) Type() string { return "auth" } +func (msg MsgChangeKey) Type() string { return "baseaccount" } // Implements Msg. func (msg MsgChangeKey) ValidateBasic() sdk.Error { diff --git a/x/auth/msgs_test.go b/x/baseaccount/msgs_test.go similarity index 97% rename from x/auth/msgs_test.go rename to x/baseaccount/msgs_test.go index 30c98b073b..46797fa0d8 100644 --- a/x/auth/msgs_test.go +++ b/x/baseaccount/msgs_test.go @@ -1,4 +1,4 @@ -package auth +package baseaccount import ( "testing" diff --git a/x/baseaccount/wire.go b/x/baseaccount/wire.go new file mode 100644 index 0000000000..4c77d1c72c --- /dev/null +++ b/x/baseaccount/wire.go @@ -0,0 +1,14 @@ +package baseaccount + +import ( + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" +) + +// Register concrete types on wire codec +func RegisterWire(cdc *wire.Codec) { + cdc.RegisterInterface((*auth.Account)(nil), nil) + cdc.RegisterConcrete(&BaseAccount{}, "baseaccount/BaseAccount", nil) + wire.RegisterCrypto(cdc) + cdc.RegisterConcrete(MsgChangeKey{}, "baseaccount/changekey", nil) +} diff --git a/x/stake/test_common.go b/x/stake/test_common.go index 2dac36069e..19487c5785 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -16,6 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/baseaccount" ) // dummy addresses used for testing @@ -72,8 +73,8 @@ func makeTestCodec() *wire.Codec { cdc.RegisterConcrete(MsgUnbond{}, "test/stake/Unbond", nil) // Register AppAccount - cdc.RegisterInterface((*sdk.Account)(nil), nil) - cdc.RegisterConcrete(&auth.BaseAccount{}, "test/stake/Account", nil) + cdc.RegisterInterface((*auth.Account)(nil), nil) + cdc.RegisterConcrete(&baseaccount.BaseAccount{}, "test/stake/Account", nil) wire.RegisterCrypto(cdc) return cdc @@ -91,7 +92,12 @@ func paramsNoInflation() Params { } // hogpodge of all sorts of input required for testing +<<<<<<< HEAD func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context, sdk.AccountMapper, Keeper) { +======= +func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context, auth.AccountMapper, Keeper) { + db := dbm.NewMemDB() +>>>>>>> in progress keyStake := sdk.NewKVStoreKey("stake") keyAcc := sdk.NewKVStoreKey("acc") @@ -105,9 +111,9 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, nil, log.NewNopLogger()) cdc := makeTestCodec() accountMapper := auth.NewAccountMapper( - cdc, // amino codec - keyAcc, // target store - &auth.BaseAccount{}, // prototype + cdc, // amino codec + keyMain, // target store + &baseaccount.BaseAccount{}, // prototype ) ck := bank.NewKeeper(accountMapper) keeper := NewKeeper(cdc, keyStake, ck, DefaultCodespace) From 56d1c48812ce44bbc9ea179ee727bbc01071a95a Mon Sep 17 00:00:00 2001 From: sunnya97 Date: Wed, 23 May 2018 19:47:33 -0700 Subject: [PATCH 04/10] in progress --- x/auth/client/rest/query.go | 7 ++++--- x/ibc/client/cli/relay.go | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 52244fec9c..a60ce5cdb2 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -10,19 +10,20 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" - auth "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + "github.com/cosmos/cosmos-sdk/x/auth" + authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" ) // register REST routes func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, storeName string) { r.HandleFunc( "/accounts/{address}", - QueryAccountRequestHandlerFn(storeName, cdc, auth.GetAccountDecoder(cdc), ctx), + QueryAccountRequestHandlerFn(storeName, cdc, authcmd.GetAccountDecoder(cdc), ctx), ).Methods("GET") } // query accountREST Handler -func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder sdk.AccountDecoder, ctx context.CoreContext) http.HandlerFunc { +func QueryAccountRequestHandlerFn(storeName string, cdc *wire.Codec, decoder auth.AccountDecoder, ctx context.CoreContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) addr := vars["address"] diff --git a/x/ibc/client/cli/relay.go b/x/ibc/client/cli/relay.go index 3a1e63a84a..caf96d60a4 100644 --- a/x/ibc/client/cli/relay.go +++ b/x/ibc/client/cli/relay.go @@ -12,6 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/ibc" ) @@ -27,7 +28,7 @@ const ( type relayCommander struct { cdc *wire.Codec address sdk.Address - decoder sdk.AccountDecoder + decoder auth.AccountDecoder mainStore string ibcStore string accStore string From 5d7c3af1b8577f3df20ee00704398ca23f8c95c8 Mon Sep 17 00:00:00 2001 From: sunnya97 Date: Wed, 23 May 2018 22:09:01 -0700 Subject: [PATCH 05/10] works --- Gopkg.lock | 47 +--------- baseapp/baseapp_test.go | 15 ++-- client/lcd/lcd_test.go | 5 +- cmd/gaia/app/app.go | 7 +- cmd/gaia/app/app_test.go | 12 +-- cmd/gaia/app/genesis.go | 9 +- examples/basecoin/app/app.go | 10 +-- examples/basecoin/app/app_test.go | 12 +-- examples/basecoin/types/account.go | 6 +- examples/democoin/app/app.go | 8 +- examples/democoin/app/app_test.go | 16 ++-- examples/democoin/types/account.go | 6 +- .../democoin/x/simplestake/keeper_test.go | 7 +- examples/kvstore/tx.go | 3 +- mock/tx.go | 3 +- x/auth/account.go | 81 +++++++++++++++++ .../account_test.go} | 2 +- x/auth/ante.go | 2 +- x/auth/ante_test.go | 34 +++---- x/auth/context_test.go | 2 +- x/{baseaccount => auth}/handler.go | 7 +- x/{baseaccount => auth}/msgs.go | 4 +- x/{baseaccount => auth}/msgs_test.go | 2 +- types/tx_msg_test.go => x/auth/stdtx_test.go | 16 ++-- x/auth/wire.go | 12 +++ x/baseaccount/baseaccount.go | 89 ------------------- x/baseaccount/wire.go | 14 --- x/ibc/ibc_test.go | 4 +- x/stake/test_common.go | 9 +- 29 files changed, 197 insertions(+), 247 deletions(-) rename x/{baseaccount/baseaccount_test.go => auth/account_test.go} (99%) rename x/{baseaccount => auth}/handler.go (79%) rename x/{baseaccount => auth}/msgs.go (91%) rename x/{baseaccount => auth}/msgs_test.go (97%) rename types/tx_msg_test.go => x/auth/stdtx_test.go (70%) create mode 100644 x/auth/wire.go delete mode 100644 x/baseaccount/baseaccount.go delete mode 100644 x/baseaccount/wire.go diff --git a/Gopkg.lock b/Gopkg.lock index dcc57cab33..37a32820c2 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -13,51 +13,6 @@ packages = ["btcec"] revision = "1432d294a5b055c297457c25434efbf13384cc46" -[[projects]] - name = "github.com/cosmos/cosmos-sdk" - packages = [ - "baseapp", - "client", - "client/context", - "client/keys", - "client/lcd", - "client/rpc", - "client/tx", - "cmd/gaia/app", - "examples/basecoin/app", - "examples/basecoin/types", - "examples/democoin/app", - "examples/democoin/types", - "examples/democoin/x/cool", - "examples/democoin/x/cool/client/cli", - "examples/democoin/x/pow", - "examples/democoin/x/pow/client/cli", - "examples/democoin/x/simplestake", - "examples/democoin/x/simplestake/client/cli", - "examples/democoin/x/sketchy", - "mock", - "server", - "store", - "tests", - "types", - "version", - "wire", - "x/auth", - "x/auth/client/cli", - "x/auth/client/rest", - "x/bank", - "x/bank/client", - "x/bank/client/cli", - "x/bank/client/rest", - "x/ibc", - "x/ibc/client/cli", - "x/ibc/client/rest", - "x/stake", - "x/stake/client/cli" - ] - revision = "187be1a5df81de1fd71da9053102d3a4868ec979" - version = "v0.17.2" - [[projects]] name = "github.com/davecgh/go-spew" packages = ["spew"] @@ -502,6 +457,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "9b6ee069da61cf1815c332c5624e8af99b51ea72e2e9b91d780db92299598dcc" + inputs-digest = "7540d2ecdb5d7d5084ab4e6132e929bbd501bd6add3006d8f08a6b2c127e0c7d" solver-name = "gps-cdcl" solver-version = 1 diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 969a9f9add..61498b1b19 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -11,13 +11,14 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/abci/types" - "github.com/tendermint/go-crypto" + crypto "github.com/tendermint/go-crypto" cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" ) func defaultLogger() log.Logger { @@ -446,12 +447,12 @@ type testUpdatePowerTx struct { const msgType = "testUpdatePowerTx" -func (tx testUpdatePowerTx) Type() string { return msgType } -func (tx testUpdatePowerTx) GetMsg() sdk.Msg { return tx } -func (tx testUpdatePowerTx) GetSignBytes() []byte { return nil } -func (tx testUpdatePowerTx) ValidateBasic() sdk.Error { return nil } -func (tx testUpdatePowerTx) GetSigners() []sdk.Address { return nil } -func (tx testUpdatePowerTx) GetSignatures() []sdk.StdSignature { return nil } +func (tx testUpdatePowerTx) Type() string { return msgType } +func (tx testUpdatePowerTx) GetMsg() sdk.Msg { return tx } +func (tx testUpdatePowerTx) GetSignBytes() []byte { return nil } +func (tx testUpdatePowerTx) ValidateBasic() sdk.Error { return nil } +func (tx testUpdatePowerTx) GetSigners() []sdk.Address { return nil } +func (tx testUpdatePowerTx) GetSignatures() []auth.StdSignature { return nil } func TestValidatorChange(t *testing.T) { diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 66a8a4085f..29b4ba1124 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -35,6 +35,7 @@ import ( btypes "github.com/cosmos/cosmos-sdk/examples/basecoin/types" tests "github.com/cosmos/cosmos-sdk/tests" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) var ( @@ -436,11 +437,11 @@ func request(t *testing.T, port, method, path string, payload []byte) (*http.Res return res, string(output) } -func getAccount(t *testing.T, sendAddr string) sdk.Account { +func getAccount(t *testing.T, sendAddr string) auth.Account { // get the account to get the sequence res, body := request(t, port, "GET", "/accounts/"+sendAddr, nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var acc sdk.Account + var acc auth.Account err := cdc.UnmarshalJSON([]byte(body), &acc) require.Nil(t, err) return acc diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index df4429ee25..b2f51498ba 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -14,7 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/cosmos/cosmos-sdk/x/baseaccount" "github.com/cosmos/cosmos-sdk/x/ibc" "github.com/cosmos/cosmos-sdk/x/stake" ) @@ -63,8 +62,8 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { // define the accountMapper app.accountMapper = auth.NewAccountMapper( app.cdc, - app.keyAccount, // target store - &baseaccount.BaseAccount{}, // prototype + app.keyAccount, // target store + &auth.BaseAccount{}, // prototype ) // add handlers @@ -97,7 +96,7 @@ func MakeCodec() *wire.Codec { ibc.RegisterWire(cdc) bank.RegisterWire(cdc) stake.RegisterWire(cdc) - baseaccount.RegisterWire(cdc) + auth.RegisterWire(cdc) sdk.RegisterWire(cdc) wire.RegisterCrypto(cdc) return cdc diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 42a56959ca..b6f1c9e03c 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -38,7 +38,7 @@ var ( coins = sdk.Coins{{"foocoin", 10}} halfCoins = sdk.Coins{{"foocoin", 5}} manyCoins = sdk.Coins{{"foocoin", 1}, {"barcoin", 1}} - fee = sdk.StdFee{ + fee = auth.StdFee{ sdk.Coins{{"foocoin", 0}}, 100000, } @@ -463,17 +463,17 @@ func CheckBalance(t *testing.T, gapp *GaiaApp, addr sdk.Address, balExpected str assert.Equal(t, balExpected, fmt.Sprintf("%v", res2.GetCoins())) } -func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) sdk.StdTx { - sigs := make([]sdk.StdSignature, len(priv)) +func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { + sigs := make([]auth.StdSignature, len(priv)) for i, p := range priv { - sigs[i] = sdk.StdSignature{ + sigs[i] = auth.StdSignature{ PubKey: p.PubKey(), - Signature: p.Sign(sdk.StdSignBytes(chainID, seq, fee, msg)), + Signature: p.Sign(auth.StdSignBytes(chainID, seq, fee, msg)), Sequence: seq[i], } } - return sdk.NewStdTx(msg, fee, sigs) + return auth.NewStdTx(msg, fee, sigs) } diff --git a/cmd/gaia/app/genesis.go b/cmd/gaia/app/genesis.go index 6914ec4927..8cf45e84a2 100644 --- a/cmd/gaia/app/genesis.go +++ b/cmd/gaia/app/genesis.go @@ -13,7 +13,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/baseaccount" "github.com/cosmos/cosmos-sdk/x/stake" ) @@ -29,7 +28,7 @@ type GenesisAccount struct { Coins sdk.Coins `json:"coins"` } -func NewGenesisAccount(acc *baseaccount.BaseAccount) GenesisAccount { +func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount { return GenesisAccount{ Address: acc.Address, Coins: acc.Coins, @@ -44,8 +43,8 @@ func NewGenesisAccountI(acc auth.Account) GenesisAccount { } // convert GenesisAccount to auth.BaseAccount -func (ga *GenesisAccount) ToAccount() (acc *baseaccount.BaseAccount) { - return &baseaccount.BaseAccount{ +func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) { + return &auth.BaseAccount{ Address: ga.Address, Coins: ga.Coins.Sort(), } @@ -149,7 +148,7 @@ func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState jso } // create the genesis account, give'm few steaks and a buncha token with there name - accAuth := baseaccount.NewBaseAccountWithAddress(genTx.Address) + accAuth := auth.NewBaseAccountWithAddress(genTx.Address) accAuth.Coins = sdk.Coins{ {genTx.Name + "Token", 1000}, {"steak", freeFermionsAcc}, diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index b1a434fa2c..610a9e5525 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -35,7 +35,7 @@ type BasecoinApp struct { keyStake *sdk.KVStoreKey // Manage getting and setting accounts - accountMapper sdk.AccountMapper + accountMapper auth.AccountMapper coinKeeper bank.Keeper ibcMapper ibc.Mapper stakeKeeper stake.Keeper @@ -70,7 +70,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // register message routes app.Router(). - AddRoute("auth", auth.NewHandler(app.accountMapper.(auth.AccountMapper))). + AddRoute("auth", auth.NewHandler(app.accountMapper)). AddRoute("bank", bank.NewHandler(app.coinKeeper)). AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)). AddRoute("stake", stake.NewHandler(app.stakeKeeper)) @@ -78,7 +78,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // Initialize BaseApp. app.SetInitChainer(app.initChainer) app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, auth.BurnFeeHandler)) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) err := app.LoadLatestVersion(app.keyMain) if err != nil { cmn.Exit(err.Error()) @@ -96,7 +96,7 @@ func MakeCodec() *wire.Codec { ibc.RegisterWire(cdc) // register custom AppAccount - cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterInterface((*auth.Account)(nil), nil) cdc.RegisterConcrete(&types.AppAccount{}, "basecoin/Account", nil) return cdc } @@ -129,7 +129,7 @@ func (app *BasecoinApp) ExportAppStateJSON() (appState json.RawMessage, err erro // iterate to get the accounts accounts := []*types.GenesisAccount{} - appendAccount := func(acc sdk.Account) (stop bool) { + appendAccount := func(acc auth.Account) (stop bool) { account := &types.GenesisAccount{ Address: acc.GetAddress(), Coins: acc.GetCoins(), diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index d0b59f3313..e297288d3f 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -37,7 +37,7 @@ var ( coins = sdk.Coins{{"foocoin", 10}} halfCoins = sdk.Coins{{"foocoin", 5}} manyCoins = sdk.Coins{{"foocoin", 1}, {"barcoin", 1}} - fee = sdk.StdFee{ + fee = auth.StdFee{ sdk.Coins{{"foocoin", 0}}, 100000, } @@ -471,17 +471,17 @@ func TestIBCMsgs(t *testing.T) { SignCheckDeliver(t, bapp, receiveMsg, []int64{3}, false, priv1) } -func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) sdk.StdTx { - sigs := make([]sdk.StdSignature, len(priv)) +func genTx(msg sdk.Msg, seq []int64, priv ...crypto.PrivKeyEd25519) auth.StdTx { + sigs := make([]auth.StdSignature, len(priv)) for i, p := range priv { - sigs[i] = sdk.StdSignature{ + sigs[i] = auth.StdSignature{ PubKey: p.PubKey(), - Signature: p.Sign(sdk.StdSignBytes(chainID, seq, fee, msg)), + Signature: p.Sign(auth.StdSignBytes(chainID, seq, fee, msg)), Sequence: seq[i], } } - return sdk.NewStdTx(msg, fee, sigs) + return auth.NewStdTx(msg, fee, sigs) } diff --git a/examples/basecoin/types/account.go b/examples/basecoin/types/account.go index e6eb5d7b46..223e0b9eb1 100644 --- a/examples/basecoin/types/account.go +++ b/examples/basecoin/types/account.go @@ -6,7 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" ) -var _ sdk.Account = (*AppAccount)(nil) +var _ auth.Account = (*AppAccount)(nil) // Custom extensions for this application. This is just an example of // extending auth.BaseAccount with custom fields. @@ -23,8 +23,8 @@ func (acc AppAccount) GetName() string { return acc.Name } func (acc *AppAccount) SetName(name string) { acc.Name = name } // Get the AccountDecoder function for the custom AppAccount -func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { - return func(accBytes []byte) (res sdk.Account, err error) { +func GetAccountDecoder(cdc *wire.Codec) auth.AccountDecoder { + return func(accBytes []byte) (res auth.Account, err error) { if len(accBytes) == 0 { return nil, sdk.ErrTxDecode("accBytes are empty") } diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 7c8250b189..9696630b6e 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -46,7 +46,7 @@ type DemocoinApp struct { stakeKeeper simplestake.Keeper // Manage getting and setting accounts - accountMapper sdk.AccountMapper + accountMapper auth.AccountMapper } func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { @@ -89,7 +89,7 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { // Initialize BaseApp. app.SetInitChainer(app.initChainerFn(app.coolKeeper, app.powKeeper)) app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyPowStore, app.capKeyIBCStore, app.capKeyStakingStore) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, auth.BurnFeeHandler)) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) err := app.LoadLatestVersion(app.capKeyMainStore) if err != nil { cmn.Exit(err.Error()) @@ -109,7 +109,7 @@ func MakeCodec() *wire.Codec { simplestake.RegisterWire(cdc) // Register AppAccount - cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterInterface((*auth.Account)(nil), nil) cdc.RegisterConcrete(&types.AppAccount{}, "democoin/Account", nil) return cdc } @@ -158,7 +158,7 @@ func (app *DemocoinApp) ExportAppStateJSON() (appState json.RawMessage, err erro // iterate to get the accounts accounts := []*types.GenesisAccount{} - appendAccount := func(acc sdk.Account) (stop bool) { + appendAccount := func(acc auth.Account) (stop bool) { account := &types.GenesisAccount{ Address: acc.GetAddress(), Coins: acc.GetCoins(), diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index b0f188f10b..e025c50627 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -31,7 +31,7 @@ var ( addr1 = priv1.PubKey().Address() addr2 = crypto.GenPrivKeyEd25519().PubKey().Address() coins = sdk.Coins{{"foocoin", 10}} - fee = sdk.StdFee{ + fee = auth.StdFee{ sdk.Coins{{"foocoin", 0}}, 1000000, } @@ -93,8 +93,8 @@ func TestMsgs(t *testing.T) { sequences := []int64{0} for i, m := range msgs { - sig := priv1.Sign(sdk.StdSignBytes(chainID, sequences, fee, m.msg)) - tx := sdk.NewStdTx(m.msg, fee, []sdk.StdSignature{{ + sig := priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, m.msg)) + tx := auth.NewStdTx(m.msg, fee, []auth.StdSignature{{ PubKey: priv1.PubKey(), Signature: sig, }}) @@ -194,8 +194,8 @@ func TestMsgSendWithAccounts(t *testing.T) { // Sign the tx sequences := []int64{0} - sig := priv1.Sign(sdk.StdSignBytes(chainID, sequences, fee, sendMsg)) - tx := sdk.NewStdTx(sendMsg, fee, []sdk.StdSignature{{ + sig := priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, sendMsg)) + tx := auth.NewStdTx(sendMsg, fee, []auth.StdSignature{{ PubKey: priv1.PubKey(), Signature: sig, }}) @@ -227,7 +227,7 @@ func TestMsgSendWithAccounts(t *testing.T) { // resigning the tx with the bumped sequence should work sequences = []int64{1} - sig = priv1.Sign(sdk.StdSignBytes(chainID, sequences, fee, tx.Msg)) + sig = priv1.Sign(auth.StdSignBytes(chainID, sequences, fee, tx.Msg)) tx.Signatures[0].Signature = sig res = bapp.Deliver(tx) assert.Equal(t, sdk.ABCICodeOK, res.Code, res.Log) @@ -394,9 +394,9 @@ func TestHandler(t *testing.T) { func SignCheckDeliver(t *testing.T, bapp *DemocoinApp, msg sdk.Msg, seq int64, expPass bool) { // Sign the tx - tx := sdk.NewStdTx(msg, fee, []sdk.StdSignature{{ + tx := auth.NewStdTx(msg, fee, []auth.StdSignature{{ PubKey: priv1.PubKey(), - Signature: priv1.Sign(sdk.StdSignBytes(chainID, []int64{seq}, fee, msg)), + Signature: priv1.Sign(auth.StdSignBytes(chainID, []int64{seq}, fee, msg)), Sequence: seq, }}) diff --git a/examples/democoin/types/account.go b/examples/democoin/types/account.go index 8a744229ad..211cf3c416 100644 --- a/examples/democoin/types/account.go +++ b/examples/democoin/types/account.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/examples/democoin/x/pow" ) -var _ sdk.Account = (*AppAccount)(nil) +var _ auth.Account = (*AppAccount)(nil) // Custom extensions for this application. This is just an example of // extending auth.BaseAccount with custom fields. @@ -26,8 +26,8 @@ func (acc AppAccount) GetName() string { return acc.Name } func (acc *AppAccount) SetName(name string) { acc.Name = name } // Get the AccountDecoder function for the custom AppAccount -func GetAccountDecoder(cdc *wire.Codec) sdk.AccountDecoder { - return func(accBytes []byte) (res sdk.Account, err error) { +func GetAccountDecoder(cdc *wire.Codec) auth.AccountDecoder { + return func(accBytes []byte) (res auth.Account, err error) { if len(accBytes) == 0 { return nil, sdk.ErrTxDecode("accBytes are empty") } diff --git a/examples/democoin/x/simplestake/keeper_test.go b/examples/democoin/x/simplestake/keeper_test.go index 302a2e58b6..515c19cc59 100644 --- a/examples/democoin/x/simplestake/keeper_test.go +++ b/examples/democoin/x/simplestake/keeper_test.go @@ -31,10 +31,13 @@ func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey, *sdk.KVStoreKey) { } func TestKeeperGetSet(t *testing.T) { - ms, _, capKey := setupMultiStore() + ms, authKey, capKey := setupMultiStore() + cdc := wire.NewCodec() + auth.RegisterBaseAccount(cdc) ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) - stakeKeeper := NewKeeper(capKey, bank.NewKeeper(nil), DefaultCodespace) + accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) + stakeKeeper := NewKeeper(capKey, bank.NewKeeper(accountMapper), DefaultCodespace) addr := sdk.Address([]byte("some-address")) bi := stakeKeeper.getBondInfo(ctx, addr) diff --git a/examples/kvstore/tx.go b/examples/kvstore/tx.go index 12bce0736f..fa32d93bfb 100644 --- a/examples/kvstore/tx.go +++ b/examples/kvstore/tx.go @@ -4,6 +4,7 @@ import ( "bytes" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) // An sdk.Tx which is its own sdk.Msg. @@ -34,7 +35,7 @@ func (tx kvstoreTx) GetSigners() []sdk.Address { return nil } -func (tx kvstoreTx) GetSignatures() []sdk.StdSignature { +func (tx kvstoreTx) GetSignatures() []auth.StdSignature { return nil } diff --git a/mock/tx.go b/mock/tx.go index 81dea45718..bd437f2d08 100644 --- a/mock/tx.go +++ b/mock/tx.go @@ -6,6 +6,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" ) // An sdk.Tx which is its own sdk.Msg. @@ -47,7 +48,7 @@ func (tx kvstoreTx) GetSigners() []sdk.Address { return nil } -func (tx kvstoreTx) GetSignatures() []sdk.StdSignature { +func (tx kvstoreTx) GetSignatures() []auth.StdSignature { return nil } diff --git a/x/auth/account.go b/x/auth/account.go index 28366467aa..0ae72a8a64 100644 --- a/x/auth/account.go +++ b/x/auth/account.go @@ -1,7 +1,10 @@ package auth import ( + "errors" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" crypto "github.com/tendermint/go-crypto" ) @@ -23,3 +26,81 @@ type Account interface { // AccountDecoder unmarshals account bytes type AccountDecoder func(accountBytes []byte) (Account, error) + +//----------------------------------------------------------- +// BaseAccount + +var _ Account = (*BaseAccount)(nil) + +// BaseAccount - base account structure. +// Extend this by embedding this in your AppAccount. +// See the examples/basecoin/types/account.go for an example. +type BaseAccount struct { + Address sdk.Address `json:"address"` + Coins sdk.Coins `json:"coins"` + PubKey crypto.PubKey `json:"public_key"` + Sequence int64 `json:"sequence"` +} + +func NewBaseAccountWithAddress(addr sdk.Address) BaseAccount { + return BaseAccount{ + Address: addr, + } +} + +// Implements sdk.Account. +func (acc BaseAccount) GetAddress() sdk.Address { + return acc.Address +} + +// Implements sdk.Account. +func (acc *BaseAccount) SetAddress(addr sdk.Address) error { + if len(acc.Address) != 0 { + return errors.New("cannot override BaseAccount address") + } + acc.Address = addr + return nil +} + +// Implements sdk.Account. +func (acc BaseAccount) GetPubKey() crypto.PubKey { + return acc.PubKey +} + +// Implements sdk.Account. +func (acc *BaseAccount) SetPubKey(pubKey crypto.PubKey) error { + acc.PubKey = pubKey + return nil +} + +// Implements sdk.Account. +func (acc *BaseAccount) GetCoins() sdk.Coins { + return acc.Coins +} + +// Implements sdk.Account. +func (acc *BaseAccount) SetCoins(coins sdk.Coins) error { + acc.Coins = coins + return nil +} + +// Implements sdk.Account. +func (acc *BaseAccount) GetSequence() int64 { + return acc.Sequence +} + +// Implements sdk.Account. +func (acc *BaseAccount) SetSequence(seq int64) error { + acc.Sequence = seq + return nil +} + +//---------------------------------------- +// Wire + +// Most users shouldn't use this, but this comes handy for tests. +func RegisterBaseAccount(cdc *wire.Codec) { + cdc.RegisterInterface((*Account)(nil), nil) + cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil) + wire.RegisterCrypto(cdc) +} diff --git a/x/baseaccount/baseaccount_test.go b/x/auth/account_test.go similarity index 99% rename from x/baseaccount/baseaccount_test.go rename to x/auth/account_test.go index ed1a322c2f..d3363e4fb0 100644 --- a/x/baseaccount/baseaccount_test.go +++ b/x/auth/account_test.go @@ -1,4 +1,4 @@ -package baseaccount +package auth import ( "testing" diff --git a/x/auth/ante.go b/x/auth/ante.go index d57c8558ef..c92a87641a 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -24,7 +24,7 @@ func NewAnteHandler(am AccountMapper) sdk.AnteHandler { // This AnteHandler requires Txs to be StdTxs stdTx, ok := tx.(StdTx) if !ok { - return ctx, sdk.ErrInternal("tx must be sdk.StdTx").Result(), true + return ctx, sdk.ErrInternal("tx must be StdTx").Result(), true } // Assert that there are signatures. diff --git a/x/auth/ante_test.go b/x/auth/ante_test.go index ec296b12be..fcde2b464b 100644 --- a/x/auth/ante_test.go +++ b/x/auth/ante_test.go @@ -17,8 +17,8 @@ func newTestMsg(addrs ...sdk.Address) *sdk.TestMsg { return sdk.NewTestMsg(addrs...) } -func newStdFee() sdk.StdFee { - return sdk.NewStdFee(100, +func newStdFee() StdFee { + return NewStdFee(100, sdk.Coin{"atom", 150}, ) } @@ -52,17 +52,17 @@ func checkInvalidTx(t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, assert.Equal(t, sdk.ToABCICode(sdk.CodespaceRoot, code), result.Code) } -func newTestTx(ctx sdk.Context, msg sdk.Msg, privs []crypto.PrivKey, seqs []int64, fee sdk.StdFee) sdk.Tx { - signBytes := sdk.StdSignBytes(ctx.ChainID(), seqs, fee, msg) +func newTestTx(ctx sdk.Context, msg sdk.Msg, privs []crypto.PrivKey, seqs []int64, fee StdFee) sdk.Tx { + signBytes := StdSignBytes(ctx.ChainID(), seqs, fee, msg) return newTestTxWithSignBytes(msg, privs, seqs, fee, signBytes) } -func newTestTxWithSignBytes(msg sdk.Msg, privs []crypto.PrivKey, seqs []int64, fee sdk.StdFee, signBytes []byte) sdk.Tx { - sigs := make([]sdk.StdSignature, len(privs)) +func newTestTxWithSignBytes(msg sdk.Msg, privs []crypto.PrivKey, seqs []int64, fee StdFee, signBytes []byte) sdk.Tx { + sigs := make([]StdSignature, len(privs)) for i, priv := range privs { - sigs[i] = sdk.StdSignature{PubKey: priv.PubKey(), Signature: priv.Sign(signBytes), Sequence: seqs[i]} + sigs[i] = StdSignature{PubKey: priv.PubKey(), Signature: priv.Sign(signBytes), Sequence: seqs[i]} } - tx := sdk.NewStdTx(msg, fee, sigs) + tx := NewStdTx(msg, fee, sigs) return tx } @@ -73,7 +73,7 @@ func TestAnteHandlerSigErrors(t *testing.T) { cdc := wire.NewCodec() RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper, BurnFeeHandler) + anteHandler := NewAnteHandler(mapper) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses @@ -114,7 +114,7 @@ func TestAnteHandlerSequences(t *testing.T) { cdc := wire.NewCodec() RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper, BurnFeeHandler) + anteHandler := NewAnteHandler(mapper) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses @@ -180,7 +180,7 @@ func TestAnteHandlerFees(t *testing.T) { cdc := wire.NewCodec() RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper, BurnFeeHandler) + anteHandler := NewAnteHandler(mapper) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses @@ -194,7 +194,7 @@ func TestAnteHandlerFees(t *testing.T) { var tx sdk.Tx msg := newTestMsg(addr1) privs, seqs := []crypto.PrivKey{priv1}, []int64{0} - fee := sdk.NewStdFee(100, + fee := NewStdFee(100, sdk.Coin{"atom", 150}, ) @@ -217,7 +217,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { cdc := wire.NewCodec() RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper, BurnFeeHandler) + anteHandler := NewAnteHandler(mapper) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses @@ -252,7 +252,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { cases := []struct { chainID string seqs []int64 - fee sdk.StdFee + fee StdFee msg sdk.Msg code sdk.CodeType }{ @@ -268,7 +268,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { for _, cs := range cases { tx := newTestTxWithSignBytes( msg, privs, seqs, fee, - sdk.StdSignBytes(cs.chainID, cs.seqs, cs.fee, cs.msg), + StdSignBytes(cs.chainID, cs.seqs, cs.fee, cs.msg), ) checkInvalidTx(t, anteHandler, ctx, tx, cs.code) } @@ -292,7 +292,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) { cdc := wire.NewCodec() RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper, BurnFeeHandler) + anteHandler := NewAnteHandler(mapper) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses @@ -322,7 +322,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) { // test public key not found msg = newTestMsg(addr2) tx = newTestTx(ctx, msg, privs, seqs, fee) - sigs := tx.GetSignatures() + sigs := tx.(StdTx).GetSignatures() sigs[0].PubKey = nil checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInvalidPubKey) diff --git a/x/auth/context_test.go b/x/auth/context_test.go index 89e318e0a1..e1db131679 100644 --- a/x/auth/context_test.go +++ b/x/auth/context_test.go @@ -26,7 +26,7 @@ func TestContextWithSigners(t *testing.T) { signers := GetSigners(ctx) assert.Equal(t, 0, len(signers)) - ctx2 := WithSigners(ctx, []sdk.Account{&acc1, &acc2}) + ctx2 := WithSigners(ctx, []Account{&acc1, &acc2}) // original context is unchanged signers = GetSigners(ctx) diff --git a/x/baseaccount/handler.go b/x/auth/handler.go similarity index 79% rename from x/baseaccount/handler.go rename to x/auth/handler.go index 46307c8818..764c6f7a28 100644 --- a/x/baseaccount/handler.go +++ b/x/auth/handler.go @@ -1,14 +1,13 @@ -package baseaccount +package auth import ( "reflect" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" ) // NewHandler returns a handler for "baseaccount" type messages. -func NewHandler(am auth.AccountMapper) sdk.Handler { +func NewHandler(am AccountMapper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { case MsgChangeKey: @@ -22,7 +21,7 @@ func NewHandler(am auth.AccountMapper) sdk.Handler { // Handle MsgChangeKey // Should be very expensive, because once this happens, an account is un-prunable -func handleMsgChangeKey(ctx sdk.Context, am auth.AccountMapper, msg MsgChangeKey) sdk.Result { +func handleMsgChangeKey(ctx sdk.Context, am AccountMapper, msg MsgChangeKey) sdk.Result { err := am.SetPubKey(ctx, msg.Address, msg.NewPubKey) if err != nil { diff --git a/x/baseaccount/msgs.go b/x/auth/msgs.go similarity index 91% rename from x/baseaccount/msgs.go rename to x/auth/msgs.go index f0319ac7fe..c449b837b1 100644 --- a/x/baseaccount/msgs.go +++ b/x/auth/msgs.go @@ -1,4 +1,4 @@ -package baseaccount +package auth import ( "encoding/json" @@ -21,7 +21,7 @@ func NewMsgChangeKey(addr sdk.Address, pubkey crypto.PubKey) MsgChangeKey { } // Implements Msg. -func (msg MsgChangeKey) Type() string { return "baseaccount" } +func (msg MsgChangeKey) Type() string { return "auth" } // Implements Msg. func (msg MsgChangeKey) ValidateBasic() sdk.Error { diff --git a/x/baseaccount/msgs_test.go b/x/auth/msgs_test.go similarity index 97% rename from x/baseaccount/msgs_test.go rename to x/auth/msgs_test.go index 46797fa0d8..30c98b073b 100644 --- a/x/baseaccount/msgs_test.go +++ b/x/auth/msgs_test.go @@ -1,4 +1,4 @@ -package baseaccount +package auth import ( "testing" diff --git a/types/tx_msg_test.go b/x/auth/stdtx_test.go similarity index 70% rename from types/tx_msg_test.go rename to x/auth/stdtx_test.go index f72cdea26e..412b37c20d 100644 --- a/types/tx_msg_test.go +++ b/x/auth/stdtx_test.go @@ -1,4 +1,4 @@ -package types +package auth import ( "testing" @@ -6,18 +6,20 @@ import ( "github.com/stretchr/testify/assert" crypto "github.com/tendermint/go-crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" ) -func newStdFee() StdFee { - return NewStdFee(100, - Coin{"atom", 150}, - ) -} +// func newStdFee() StdFee { +// return NewStdFee(100, +// Coin{"atom", 150}, +// ) +// } func TestStdTx(t *testing.T) { priv := crypto.GenPrivKeyEd25519() addr := priv.PubKey().Address() - msg := NewTestMsg(addr) + msg := sdk.NewTestMsg(addr) fee := newStdFee() sigs := []StdSignature{} diff --git a/x/auth/wire.go b/x/auth/wire.go new file mode 100644 index 0000000000..42b34b96d5 --- /dev/null +++ b/x/auth/wire.go @@ -0,0 +1,12 @@ +package auth + +import ( + "github.com/cosmos/cosmos-sdk/wire" +) + +// Register concrete types on wire codec for default AppAccount +func RegisterWire(cdc *wire.Codec) { + cdc.RegisterInterface((*Account)(nil), nil) + cdc.RegisterConcrete(&BaseAccount{}, "auth/Account", nil) + cdc.RegisterConcrete(MsgChangeKey{}, "auth/ChangeKey", nil) +} diff --git a/x/baseaccount/baseaccount.go b/x/baseaccount/baseaccount.go deleted file mode 100644 index 9701ac41dc..0000000000 --- a/x/baseaccount/baseaccount.go +++ /dev/null @@ -1,89 +0,0 @@ -package baseaccount - -import ( - "errors" - - crypto "github.com/tendermint/go-crypto" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/wire" - "github.com/cosmos/cosmos-sdk/x/auth" -) - -//----------------------------------------------------------- -// BaseAccount - -var _ auth.Account = (*BaseAccount)(nil) - -// BaseAccount - base account structure. -// Extend this by embedding this in your AppAccount. -// See the examples/basecoin/types/account.go for an example. -type BaseAccount struct { - Address sdk.Address `json:"address"` - Coins sdk.Coins `json:"coins"` - PubKey crypto.PubKey `json:"public_key"` - Sequence int64 `json:"sequence"` -} - -func NewBaseAccountWithAddress(addr sdk.Address) BaseAccount { - return BaseAccount{ - Address: addr, - } -} - -// Implements sdk.Account. -func (acc BaseAccount) GetAddress() sdk.Address { - return acc.Address -} - -// Implements sdk.Account. -func (acc *BaseAccount) SetAddress(addr sdk.Address) error { - if len(acc.Address) != 0 { - return errors.New("cannot override BaseAccount address") - } - acc.Address = addr - return nil -} - -// Implements sdk.Account. -func (acc BaseAccount) GetPubKey() crypto.PubKey { - return acc.PubKey -} - -// Implements sdk.Account. -func (acc *BaseAccount) SetPubKey(pubKey crypto.PubKey) error { - acc.PubKey = pubKey - return nil -} - -// Implements sdk.Account. -func (acc *BaseAccount) GetCoins() sdk.Coins { - return acc.Coins -} - -// Implements sdk.Account. -func (acc *BaseAccount) SetCoins(coins sdk.Coins) error { - acc.Coins = coins - return nil -} - -// Implements sdk.Account. -func (acc *BaseAccount) GetSequence() int64 { - return acc.Sequence -} - -// Implements sdk.Account. -func (acc *BaseAccount) SetSequence(seq int64) error { - acc.Sequence = seq - return nil -} - -//---------------------------------------- -// Wire - -// Most users shouldn't use this, but this comes handy for tests. -func RegisterBaseAccount(cdc *wire.Codec) { - cdc.RegisterInterface((*auth.Account)(nil), nil) - cdc.RegisterConcrete(&BaseAccount{}, "cosmos-sdk/BaseAccount", nil) - wire.RegisterCrypto(cdc) -} diff --git a/x/baseaccount/wire.go b/x/baseaccount/wire.go deleted file mode 100644 index 4c77d1c72c..0000000000 --- a/x/baseaccount/wire.go +++ /dev/null @@ -1,14 +0,0 @@ -package baseaccount - -import ( - "github.com/cosmos/cosmos-sdk/wire" - "github.com/cosmos/cosmos-sdk/x/auth" -) - -// Register concrete types on wire codec -func RegisterWire(cdc *wire.Codec) { - cdc.RegisterInterface((*auth.Account)(nil), nil) - cdc.RegisterConcrete(&BaseAccount{}, "baseaccount/BaseAccount", nil) - wire.RegisterCrypto(cdc) - cdc.RegisterConcrete(MsgChangeKey{}, "baseaccount/changekey", nil) -} diff --git a/x/ibc/ibc_test.go b/x/ibc/ibc_test.go index 60cc59bad9..e13df4f8dd 100644 --- a/x/ibc/ibc_test.go +++ b/x/ibc/ibc_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" abci "github.com/tendermint/abci/types" - "github.com/tendermint/go-crypto" + crypto "github.com/tendermint/go-crypto" dbm "github.com/tendermint/tmlibs/db" "github.com/tendermint/tmlibs/log" @@ -49,7 +49,7 @@ func makeCodec() *wire.Codec { cdc.RegisterConcrete(IBCReceiveMsg{}, "test/ibc/IBCReceiveMsg", nil) // Register AppAccount - cdc.RegisterInterface((*sdk.Account)(nil), nil) + cdc.RegisterInterface((*auth.Account)(nil), nil) cdc.RegisterConcrete(&auth.BaseAccount{}, "test/ibc/Account", nil) wire.RegisterCrypto(cdc) diff --git a/x/stake/test_common.go b/x/stake/test_common.go index e75faaf01a..b7a5152c09 100644 --- a/x/stake/test_common.go +++ b/x/stake/test_common.go @@ -16,7 +16,6 @@ import ( "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/cosmos/cosmos-sdk/x/baseaccount" ) // dummy addresses used for testing @@ -74,7 +73,7 @@ func makeTestCodec() *wire.Codec { // Register AppAccount cdc.RegisterInterface((*auth.Account)(nil), nil) - cdc.RegisterConcrete(&baseaccount.BaseAccount{}, "test/stake/Account", nil) + cdc.RegisterConcrete(&auth.BaseAccount{}, "test/stake/Account", nil) wire.RegisterCrypto(cdc) return cdc @@ -107,9 +106,9 @@ func createTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, nil, log.NewNopLogger()) cdc := makeTestCodec() accountMapper := auth.NewAccountMapper( - cdc, // amino codec - keyAcc, // target store - &baseaccount.BaseAccount{}, // prototype + cdc, // amino codec + keyAcc, // target store + &auth.BaseAccount{}, // prototype ) ck := bank.NewKeeper(accountMapper) keeper := NewKeeper(cdc, keyStake, ck, DefaultCodespace) From d3bdb09ffce1a6cb2ed941f3d614b8999e5c423b Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Fri, 25 May 2018 20:29:40 -0700 Subject: [PATCH 06/10] passes, needs tests --- cmd/gaia/app/app.go | 11 +++--- examples/basecoin/app/app.go | 11 +++--- examples/democoin/app/app.go | 13 ++++---- x/auth/ante.go | 8 +++-- x/auth/ante_test.go | 25 ++++++++------ x/auth/context_test.go | 2 +- x/auth/feekeeper.go | 65 ++++++++++++++++++++++++++++++++++++ x/auth/mapper_test.go | 8 +++-- 8 files changed, 111 insertions(+), 32 deletions(-) create mode 100644 x/auth/feekeeper.go diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index b2f51498ba..dbecada004 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -40,10 +40,11 @@ type GaiaApp struct { keyStake *sdk.KVStoreKey // Manage getting and setting accounts - accountMapper auth.AccountMapper - coinKeeper bank.Keeper - ibcMapper ibc.Mapper - stakeKeeper stake.Keeper + accountMapper auth.AccountMapper + feeCollectionKeeper auth.FeeCollectionKeeper + coinKeeper bank.Keeper + ibcMapper ibc.Mapper + stakeKeeper stake.Keeper } func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { @@ -81,7 +82,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp { app.SetInitChainer(app.initChainer) app.SetEndBlocker(stake.NewEndBlocker(app.stakeKeeper)) app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) err := app.LoadLatestVersion(app.keyMain) if err != nil { cmn.Exit(err.Error()) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 610a9e5525..086fa32b36 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -35,10 +35,11 @@ type BasecoinApp struct { keyStake *sdk.KVStoreKey // Manage getting and setting accounts - accountMapper auth.AccountMapper - coinKeeper bank.Keeper - ibcMapper ibc.Mapper - stakeKeeper stake.Keeper + accountMapper auth.AccountMapper + feeCollectionKeeper auth.FeeCollectionKeeper + coinKeeper bank.Keeper + ibcMapper ibc.Mapper + stakeKeeper stake.Keeper } func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { @@ -78,7 +79,7 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // Initialize BaseApp. app.SetInitChainer(app.initChainer) app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) err := app.LoadLatestVersion(app.keyMain) if err != nil { cmn.Exit(err.Error()) diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 9696630b6e..2075a64da0 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -39,11 +39,12 @@ type DemocoinApp struct { capKeyStakingStore *sdk.KVStoreKey // keepers - coinKeeper bank.Keeper - coolKeeper cool.Keeper - powKeeper pow.Keeper - ibcMapper ibc.Mapper - stakeKeeper simplestake.Keeper + feeCollectionKeeper auth.FeeCollectionKeeper + coinKeeper bank.Keeper + coolKeeper cool.Keeper + powKeeper pow.Keeper + ibcMapper ibc.Mapper + stakeKeeper simplestake.Keeper // Manage getting and setting accounts accountMapper auth.AccountMapper @@ -89,7 +90,7 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { // Initialize BaseApp. app.SetInitChainer(app.initChainerFn(app.coolKeeper, app.powKeeper)) app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyPowStore, app.capKeyIBCStore, app.capKeyStakingStore) - app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper)) + app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) err := app.LoadLatestVersion(app.capKeyMainStore) if err != nil { cmn.Exit(err.Error()) diff --git a/x/auth/ante.go b/x/auth/ante.go index c92a87641a..21f8df0fbd 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -9,13 +9,14 @@ import ( ) const ( - verifyCost = 100 + deductFeesCost sdk.Gas = 10 + verifyCost = 100 ) // NewAnteHandler returns an AnteHandler that checks // and increments sequence numbers, checks signatures, // and deducts fees from the first signer. -func NewAnteHandler(am AccountMapper) sdk.AnteHandler { +func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler { return func( ctx sdk.Context, tx sdk.Tx, @@ -77,7 +78,10 @@ func NewAnteHandler(am AccountMapper) sdk.AnteHandler { if i == 0 { // TODO: min fee if !fee.Amount.IsZero() { + ctx.GasMeter().ConsumeGas(deductFeesCost, "deductFees") signerAcc, res = deductFees(signerAcc, fee) + fck.addCollectedFees(ctx, fee.Amount) + if !res.IsOK() { return ctx, res, true } diff --git a/x/auth/ante_test.go b/x/auth/ante_test.go index fcde2b464b..e21be8f16f 100644 --- a/x/auth/ante_test.go +++ b/x/auth/ante_test.go @@ -69,11 +69,12 @@ func newTestTxWithSignBytes(msg sdk.Msg, privs []crypto.PrivKey, seqs []int64, f // Test various error cases in the AnteHandler control flow. func TestAnteHandlerSigErrors(t *testing.T) { // setup - ms, capKey := setupMultiStore() + ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper) + feeCollector := NewFeeCollectionKeeper(cdc, capKey2) + anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses @@ -110,11 +111,12 @@ func TestAnteHandlerSigErrors(t *testing.T) { // Test logic around sequence checking with one signer and many signers. func TestAnteHandlerSequences(t *testing.T) { // setup - ms, capKey := setupMultiStore() + ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper) + feeCollector := NewFeeCollectionKeeper(cdc, capKey2) + anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses @@ -176,11 +178,12 @@ func TestAnteHandlerSequences(t *testing.T) { // Test logic around fee deduction. func TestAnteHandlerFees(t *testing.T) { // setup - ms, capKey := setupMultiStore() + ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper) + feeCollector := NewFeeCollectionKeeper(cdc, capKey2) + anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses @@ -213,11 +216,12 @@ func TestAnteHandlerFees(t *testing.T) { func TestAnteHandlerBadSignBytes(t *testing.T) { // setup - ms, capKey := setupMultiStore() + ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper) + feeCollector := NewFeeCollectionKeeper(cdc, capKey2) + anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses @@ -288,11 +292,12 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { func TestAnteHandlerSetPubKey(t *testing.T) { // setup - ms, capKey := setupMultiStore() + ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) - anteHandler := NewAnteHandler(mapper) + feeCollector := NewFeeCollectionKeeper(cdc, capKey2) + anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) // keys and addresses diff --git a/x/auth/context_test.go b/x/auth/context_test.go index e1db131679..a93de44d0c 100644 --- a/x/auth/context_test.go +++ b/x/auth/context_test.go @@ -12,7 +12,7 @@ import ( ) func TestContextWithSigners(t *testing.T) { - ms, _ := setupMultiStore() + ms, _, _ := setupMultiStore() ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, nil, log.NewNopLogger()) _, _, addr1 := keyPubAddr() diff --git a/x/auth/feekeeper.go b/x/auth/feekeeper.go new file mode 100644 index 0000000000..0828fb3652 --- /dev/null +++ b/x/auth/feekeeper.go @@ -0,0 +1,65 @@ +package auth + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + wire "github.com/cosmos/cosmos-sdk/wire" +) + +// This FeeCollectionKeeper handles collection of fees in the anteHandler +// and setting of MinFees for different fee tokens +type FeeCollectionKeeper struct { + + // The (unexposed) key used to access the fee store from the Context. + key sdk.StoreKey + + // The wire codec for binary encoding/decoding of accounts. + cdc *wire.Codec +} + +// NewFeeKeeper returns a new FeeKeeper +func NewFeeCollectionKeeper(cdc *wire.Codec, key sdk.StoreKey) FeeCollectionKeeper { + return FeeCollectionKeeper{ + key: key, + cdc: cdc, + } +} + +// Adds to Collected Fee Pool +func (fck FeeCollectionKeeper) GetCollectedFees(ctx sdk.Context) sdk.Coins { + store := ctx.KVStore(fck.key) + bz := store.Get([]byte("collectedFees")) + if bz == nil { + return sdk.Coins{} + } + + feePool := &(sdk.Coins{}) + err := fck.cdc.UnmarshalBinary(bz, feePool) + if err != nil { + panic("should not happen") + } + return *feePool +} + +// Sets to Collected Fee Pool +func (fck FeeCollectionKeeper) setCollectedFees(ctx sdk.Context, coins sdk.Coins) { + bz, err := fck.cdc.MarshalBinary(coins) + if err != nil { + panic("should not happen") + } + + store := ctx.KVStore(fck.key) + store.Set([]byte("collectedFees"), bz) +} + +// Adds to Collected Fee Pool +func (fck FeeCollectionKeeper) addCollectedFees(ctx sdk.Context, coins sdk.Coins) sdk.Coins { + newCoins := fck.GetCollectedFees(ctx).Plus(coins) + fck.setCollectedFees(ctx, newCoins) + + return newCoins +} + +// Clears the collected Fee Pool +func (fck FeeCollectionKeeper) ClearCollectedFees(ctx sdk.Context) { + fck.setCollectedFees(ctx, sdk.Coins{}) +} diff --git a/x/auth/mapper_test.go b/x/auth/mapper_test.go index cdd418990a..7f6397069a 100644 --- a/x/auth/mapper_test.go +++ b/x/auth/mapper_test.go @@ -14,17 +14,19 @@ import ( wire "github.com/cosmos/cosmos-sdk/wire" ) -func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { +func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey, *sdk.KVStoreKey) { db := dbm.NewMemDB() capKey := sdk.NewKVStoreKey("capkey") + capKey2 := sdk.NewKVStoreKey("capkey2") ms := store.NewCommitMultiStore(db) ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db) ms.LoadLatestVersion() - return ms, capKey + return ms, capKey, capKey2 } func TestAccountMapperGetSet(t *testing.T) { - ms, capKey := setupMultiStore() + ms, capKey, _ := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) From f81a70b3150606c2d24ed028f2605990500eb208 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Fri, 25 May 2018 20:48:27 -0700 Subject: [PATCH 07/10] added keeper tests --- x/auth/feekeeper_test.go | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 x/auth/feekeeper_test.go diff --git a/x/auth/feekeeper_test.go b/x/auth/feekeeper_test.go new file mode 100644 index 0000000000..2f1ffc59bc --- /dev/null +++ b/x/auth/feekeeper_test.go @@ -0,0 +1,75 @@ +package auth + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + abci "github.com/tendermint/abci/types" + "github.com/tendermint/tmlibs/log" + + sdk "github.com/cosmos/cosmos-sdk/types" + wire "github.com/cosmos/cosmos-sdk/wire" +) + +var ( + emptyCoins = sdk.Coins{} + oneCoin = sdk.Coins{{"foocoin", 1}} + twoCoins = sdk.Coins{{"foocoin", 2}} +) + +func TestFeeCollectionKeeperGetSet(t *testing.T) { + ms, _, capKey2 := setupMultiStore() + cdc := wire.NewCodec() + + // make context and keeper + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) + fck := NewFeeCollectionKeeper(cdc, capKey2) + + // no coins initially + currFees := fck.GetCollectedFees(ctx) + assert.True(t, currFees.IsEqual(emptyCoins)) + + // set feeCollection to oneCoin + fck.setCollectedFees(ctx, oneCoin) + + // check that it is equal to oneCoin + assert.True(t, fck.GetCollectedFees(ctx).IsEqual(oneCoin)) +} + +func TestFeeCollectionKeeperAdd(t *testing.T) { + ms, _, capKey2 := setupMultiStore() + cdc := wire.NewCodec() + + // make context and keeper + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) + fck := NewFeeCollectionKeeper(cdc, capKey2) + + // no coins initially + assert.True(t, fck.GetCollectedFees(ctx).IsEqual(emptyCoins)) + + // add oneCoin and check that pool is now oneCoin + fck.addCollectedFees(ctx, oneCoin) + assert.True(t, fck.GetCollectedFees(ctx).IsEqual(oneCoin)) + + // add oneCoin again and check that pool is now twoCoins + fck.addCollectedFees(ctx, oneCoin) + assert.True(t, fck.GetCollectedFees(ctx).IsEqual(twoCoins)) +} + +func TestFeeCollectionKeeperClear(t *testing.T) { + ms, _, capKey2 := setupMultiStore() + cdc := wire.NewCodec() + + // make context and keeper + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewNopLogger()) + fck := NewFeeCollectionKeeper(cdc, capKey2) + + // set coins initially + fck.setCollectedFees(ctx, twoCoins) + assert.True(t, fck.GetCollectedFees(ctx).IsEqual(twoCoins)) + + // clear fees and see that pool is now empty + fck.ClearCollectedFees(ctx) + assert.True(t, fck.GetCollectedFees(ctx).IsEqual(emptyCoins)) +} From 4f6c77d8cba765f8f31125c3c753ed86efc88d5d Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Fri, 25 May 2018 21:10:09 -0700 Subject: [PATCH 08/10] antehandler tests --- x/auth/ante.go | 3 +-- x/auth/ante_test.go | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/x/auth/ante.go b/x/auth/ante.go index 21f8df0fbd..9663bcfe45 100644 --- a/x/auth/ante.go +++ b/x/auth/ante.go @@ -80,11 +80,10 @@ func NewAnteHandler(am AccountMapper, fck FeeCollectionKeeper) sdk.AnteHandler { if !fee.Amount.IsZero() { ctx.GasMeter().ConsumeGas(deductFeesCost, "deductFees") signerAcc, res = deductFees(signerAcc, fee) - fck.addCollectedFees(ctx, fee.Amount) - if !res.IsOK() { return ctx, res, true } + fck.addCollectedFees(ctx, fee.Amount) } } diff --git a/x/auth/ante_test.go b/x/auth/ante_test.go index e21be8f16f..b7f22e5d54 100644 --- a/x/auth/ante_test.go +++ b/x/auth/ante_test.go @@ -209,9 +209,13 @@ func TestAnteHandlerFees(t *testing.T) { mapper.SetAccount(ctx, acc1) checkInvalidTx(t, anteHandler, ctx, tx, sdk.CodeInsufficientFunds) + assert.True(t, feeCollector.GetCollectedFees(ctx).IsEqual(emptyCoins)) + acc1.SetCoins(sdk.Coins{{"atom", 150}}) mapper.SetAccount(ctx, acc1) checkValidTx(t, anteHandler, ctx, tx) + + assert.True(t, feeCollector.GetCollectedFees(ctx).IsEqual(sdk.Coins{{"atom", 150}})) } func TestAnteHandlerBadSignBytes(t *testing.T) { From bf02cdcf974c2f22b7b61e18483a48ea63a6d43f Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Fri, 25 May 2018 21:14:49 -0700 Subject: [PATCH 09/10] address Chris review --- x/auth/feekeeper.go | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/x/auth/feekeeper.go b/x/auth/feekeeper.go index 0828fb3652..3e03a81aa2 100644 --- a/x/auth/feekeeper.go +++ b/x/auth/feekeeper.go @@ -5,6 +5,10 @@ import ( wire "github.com/cosmos/cosmos-sdk/wire" ) +var ( + collectedFeesKey = []byte("collectedFees") +) + // This FeeCollectionKeeper handles collection of fees in the anteHandler // and setting of MinFees for different fee tokens type FeeCollectionKeeper struct { @@ -27,28 +31,21 @@ func NewFeeCollectionKeeper(cdc *wire.Codec, key sdk.StoreKey) FeeCollectionKeep // Adds to Collected Fee Pool func (fck FeeCollectionKeeper) GetCollectedFees(ctx sdk.Context) sdk.Coins { store := ctx.KVStore(fck.key) - bz := store.Get([]byte("collectedFees")) + bz := store.Get(collectedFeesKey) if bz == nil { return sdk.Coins{} } feePool := &(sdk.Coins{}) - err := fck.cdc.UnmarshalBinary(bz, feePool) - if err != nil { - panic("should not happen") - } + fck.cdc.MustUnmarshalBinary(bz, feePool) return *feePool } // Sets to Collected Fee Pool func (fck FeeCollectionKeeper) setCollectedFees(ctx sdk.Context, coins sdk.Coins) { - bz, err := fck.cdc.MarshalBinary(coins) - if err != nil { - panic("should not happen") - } - + bz := fck.cdc.MustMarshalBinary(coins) store := ctx.KVStore(fck.key) - store.Set([]byte("collectedFees"), bz) + store.Set(collectedFeesKey, bz) } // Adds to Collected Fee Pool From 92356b7d9be1b63d764073fe9843264fba556047 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Sat, 26 May 2018 04:36:05 -0400 Subject: [PATCH 10/10] changelog update --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73f5e5f880..19c50d56e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ ## 0.18.1 +BREAKING CHANGES + +* [x/auth] move stuff specific to auth anteHandler to the auth module rather than the types folder. This includes: + * StdTx (and its related stuff i.e. StdSignDoc, etc) + * StdFee + * StdSignature + * Account interface + * Related to this organization, I also: +* [x/auth] got rid of AccountMapper interface (in favor of the struct already in auth module) +* [x/auth] removed the FeeHandler function from the AnteHandler, Replaced with FeeKeeper +* [x/auth] Removed GetSignatures() from Tx interface (as different Tx styles might use something different than StdSignature) + BUG FIXES * auto-sequencing transactions correctly * query sequence via account store