diff --git a/examples/basecoin/app.go b/examples/basecoin/app.go index e1181d041..06ab7d0f9 100644 --- a/examples/basecoin/app.go +++ b/examples/basecoin/app.go @@ -1,66 +1 @@ package main - -import ( - "encoding/json" - "path" - - crypto "github.com/tendermint/go-crypto" - - "github.com/cosmos/cosmos-sdk/types" - acm "github.com/cosmos/cosmos-sdk/x/account" - "github.com/cosmos/cosmos-sdk/x/sendtx" - "github.com/cosmos/cosmos-sdk/x/store" -) - -func txParser(txBytes []byte) (types.Tx, error) { - var tx sendtx.SendTx - err := json.Unmarshal(txBytes, &tx) - return tx, err -} - -//----------------------------------------------------------------------------- - -type AccountStore struct { - kvStore types.KVStore -} - -func newAccountStore(kvStore types.KVStore) store.AccountStore { - return AccountStore{kvStore} -} - -func (accStore AccountStore) NewAccountWithAddress(addr crypto.Address) store.Account { - return acm.NewBaseAccountWithAddress(addr) -} - -func (accStore AccountStore) GetAccount(addr crypto.Address) store.Account { - v := accStore.kvStore.Get(keyAccount(addr)) - - if len(v) == 0 { - return nil - } - - acc := new(acm.BaseAccount) - if err := json.Unmarshal(v, acc); err != nil { - panic(err) - } - - return acc -} - -func (accStore AccountStore) SetAccount(acc store.Account) { - b, err := json.Marshal(acc) - if err != nil { - panic(err) - } - - appAcc, ok := acc.(*acm.BaseAccount) - if !ok { - panic("acc is not *acm.BaseAccount") // XXX - } - - accStore.kvStore.Set(keyAccount(appAcc.Address()), b) -} - -func keyAccount(addr crypto.Address) []byte { - return []byte(path.Join("account", string(addr))) -} diff --git a/examples/basecoin/main.go b/examples/basecoin/main.go index 149f4a6dd..5f1eb78e5 100644 --- a/examples/basecoin/main.go +++ b/examples/basecoin/main.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "os" @@ -11,6 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/app" "github.com/cosmos/cosmos-sdk/store" "github.com/cosmos/cosmos-sdk/types" + acm "github.com/cosmos/cosmos-sdk/x/account" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/sendtx" ) @@ -38,14 +40,14 @@ func main() { handler := types.ChainDecorators( // recover.Decorator(), // logger.Decorator(), - auth.DecoratorFn(newAccountStore), + auth.DecoratorFn(acm.NewAccountStore), ).WithHandler( - sendtx.TransferHandlerFn(newAccountStore), + sendtx.TransferHandlerFn(acm.NewAccountStore), ) // TODO: load genesis // TODO: InitChain with validators - // accounts := newAccountStore(multiStore.GetKVStore("main")) + // accounts := acm.NewAccountStore(multiStore.GetKVStore("main")) // TODO: set the genesis accounts // Set everything on the app and load latest @@ -72,3 +74,11 @@ func main() { }) return } + +func txParser(txBytes []byte) (types.Tx, error) { + var tx sendtx.SendTx + err := json.Unmarshal(txBytes, &tx) + return tx, err +} + +//----------------------------------------------------------------------------- diff --git a/x/store/account.go b/types/account.go similarity index 65% rename from x/store/account.go rename to types/account.go index 456530170..0175abd40 100644 --- a/x/store/account.go +++ b/types/account.go @@ -1,9 +1,7 @@ -package store +package types import ( crypto "github.com/tendermint/go-crypto" - - "github.com/cosmos/cosmos-sdk/x/coin" ) // AccountStore indexes accounts by address. @@ -13,19 +11,14 @@ type AccountStore interface { SetAccount(acc Account) } -// Account is a standard balance account -// using a sequence number for replay protection -// and a single pubkey for authentication. -// TODO: multisig accounts? +// Account is a standard account using a sequence number for replay protection +// and a pubkey for authentication. type Account interface { Address() crypto.Address GetPubKey() crypto.PubKey SetPubKey(crypto.PubKey) error - GetCoins() coin.Coins - SetCoins(coin.Coins) error - GetSequence() int64 SetSequence(int64) error diff --git a/types/model.go b/types/model.go new file mode 100644 index 000000000..4f0a87c56 --- /dev/null +++ b/types/model.go @@ -0,0 +1,15 @@ +package types + +import crypto "github.com/tendermint/go-crypto" + +type Model interface { + Address() crypto.Address + + Get(key interface{}) interface{} + Set(key interface{}, value interface{}) +} + +type ModelStore interface { + Load(addr crypto.Address) Model + Store(m Model) +} diff --git a/x/account/store.go b/x/account/store.go new file mode 100644 index 000000000..ec9030afd --- /dev/null +++ b/x/account/store.go @@ -0,0 +1,54 @@ +package account + +import ( + "encoding/json" + "path" + + "github.com/cosmos/cosmos-sdk/types" + crypto "github.com/tendermint/go-crypto" +) + +type AccountStore struct { + kvStore types.KVStore +} + +func NewAccountStore(kvStore types.KVStore) types.AccountStore { + return AccountStore{kvStore} +} + +func (accStore AccountStore) NewAccountWithAddress(addr crypto.Address) types.Account { + return NewBaseAccountWithAddress(addr) +} + +func (accStore AccountStore) GetAccount(addr crypto.Address) types.Account { + v := accStore.kvStore.Get(keyAccount(addr)) + + if len(v) == 0 { + return nil + } + + acc := new(BaseAccount) + if err := json.Unmarshal(v, acc); err != nil { + panic(err) + } + + return acc +} + +func (accStore AccountStore) SetAccount(acc types.Account) { + b, err := json.Marshal(acc) + if err != nil { + panic(err) + } + + appAcc, ok := acc.(*BaseAccount) + if !ok { + panic("acc is not *BaseAccount") // XXX + } + + accStore.kvStore.Set(keyAccount(appAcc.Address()), b) +} + +func keyAccount(addr crypto.Address) []byte { + return []byte(path.Join("account", string(addr))) +} diff --git a/x/auth/context.go b/x/auth/context.go index 43c182a23..07e86b7d6 100644 --- a/x/auth/context.go +++ b/x/auth/context.go @@ -2,7 +2,6 @@ package auth import ( "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/store" ) /* @@ -25,10 +24,10 @@ const ( contextKeyAccount contextKey = iota ) -func SetAccount(ctx types.Context, account store.Account) types.Context { +func SetAccount(ctx types.Context, account types.Account) types.Context { return ctx.WithValueUnsafe(contextKeyAccount, account) } -func GetAccount(ctx types.Context) store.Account { - return ctx.Value(contextKeyAccount).(store.Account) +func GetAccount(ctx types.Context) types.Account { + return ctx.Value(contextKeyAccount).(types.Account) } diff --git a/x/auth/decorator.go b/x/auth/decorator.go index 5bd443368..23966d722 100644 --- a/x/auth/decorator.go +++ b/x/auth/decorator.go @@ -1,11 +1,8 @@ package auth -import ( - "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/store" -) +import "github.com/cosmos/cosmos-sdk/types" -func DecoratorFn(newAccountStore func(types.KVStore) store.AccountStore) types.Decorator { +func DecoratorFn(newAccountStore func(types.KVStore) types.AccountStore) types.Decorator { return func(ctx types.Context, ms types.MultiStore, tx types.Tx, next types.Handler) types.Result { accountStore := newAccountStore(ms.GetKVStore("main")) @@ -29,15 +26,7 @@ func DecoratorFn(newAccountStore func(types.KVStore) store.AccountStore) types.D for i, sig := range signatures { // get account - _acc := accountStore.GetAccount(signers[i]) - - // assert it has the right methods - acc, ok := _acc.(Auther) - if !ok { - return types.Result{ - Code: 1, // TODO - } - } + acc := accountStore.GetAccount(signers[i]) // if no pubkey, set pubkey if acc.GetPubKey().Empty() { @@ -49,13 +38,14 @@ func DecoratorFn(newAccountStore func(types.KVStore) store.AccountStore) types.D } } - // check sequence number + // check and incremenet sequence number seq := acc.GetSequence() if seq != sig.Sequence { return types.Result{ Code: 1, // TODO } } + acc.SetSequence(seq + 1) // check sig if !sig.PubKey.VerifyBytes(tx.SignBytes(), sig.Signature) { diff --git a/x/auth/types.go b/x/auth/types.go deleted file mode 100644 index aaa8018cf..000000000 --- a/x/auth/types.go +++ /dev/null @@ -1,16 +0,0 @@ -package auth - -import ( - "github.com/cosmos/cosmos-sdk/x/store" - crypto "github.com/tendermint/go-crypto" -) - -var _ Auther = (store.Account)(nil) - -type Auther interface { - GetPubKey() crypto.PubKey - SetPubKey(crypto.PubKey) error - - GetSequence() int64 - SetSequence(int64) error -} diff --git a/x/store/errors.go b/x/coinstore/errors.go similarity index 99% rename from x/store/errors.go rename to x/coinstore/errors.go index bcdb3d3f0..2e63b4c75 100644 --- a/x/store/errors.go +++ b/x/coinstore/errors.go @@ -1,5 +1,5 @@ //nolint -package store +package coinstore import ( "github.com/cosmos/cosmos-sdk/errors" diff --git a/x/store/coin.go b/x/coinstore/store.go similarity index 91% rename from x/store/coin.go rename to x/coinstore/store.go index 8626b235d..163e49041 100644 --- a/x/store/coin.go +++ b/x/coinstore/store.go @@ -1,8 +1,9 @@ -package store +package coinstore import ( "fmt" + "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/coin" crypto "github.com/tendermint/go-crypto" ) @@ -17,7 +18,7 @@ type Coinser interface { // CoinStore manages transfers between accounts type CoinStore struct { - AccountStore + types.AccountStore } // SubtractCoins subtracts amt from the coins at the addr. @@ -36,7 +37,7 @@ func (cs CoinStore) SubtractCoins(addr crypto.Address, amt Coins) (Coins, error) } acc.SetCoins(newCoins) - cs.SetAccount(acc.(Account)) + cs.SetAccount(acc.(types.Account)) return newCoins, nil } @@ -53,7 +54,7 @@ func (cs CoinStore) AddCoins(addr crypto.Address, amt Coins) (Coins, error) { newCoins := coins.Plus(amt) acc.SetCoins(newCoins) - cs.SetAccount(acc.(Account)) + cs.SetAccount(acc.(types.Account)) return newCoins, nil } diff --git a/x/sendtx/handler.go b/x/sendtx/handler.go index fba7a5a3c..0fc4886e6 100644 --- a/x/sendtx/handler.go +++ b/x/sendtx/handler.go @@ -2,14 +2,14 @@ package sendtx import ( "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/store" + "github.com/cosmos/cosmos-sdk/x/coinstore" ) -func TransferHandlerFn(newAccStore func(types.KVStore) store.AccountStore) types.Handler { +func TransferHandlerFn(newAccStore func(types.KVStore) types.AccountStore) types.Handler { return func(ctx types.Context, ms types.MultiStore, tx types.Tx) types.Result { accStore := newAccStore(ms.GetKVStore("main")) - cs := store.CoinStore{accStore} + cs := coinstore.CoinStore{accStore} sendTx, ok := tx.(SendTx) if !ok { diff --git a/x/sendtx/tx.go b/x/sendtx/tx.go index 16f121f21..e89434e80 100644 --- a/x/sendtx/tx.go +++ b/x/sendtx/tx.go @@ -8,7 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/coin" - "github.com/cosmos/cosmos-sdk/x/store" + "github.com/cosmos/cosmos-sdk/x/coinstore" ) type ( @@ -30,16 +30,16 @@ type TxInput struct { // ValidateBasic - validate transaction input func (txIn TxInput) ValidateBasic() error { if len(txIn.Address) == 0 { - return store.ErrInvalidAddress(txIn.Address.String()) + return coinstore.ErrInvalidAddress(txIn.Address.String()) } if txIn.Sequence < 0 { return ErrInvalidSequence(txIn.Sequence) } if !txIn.Coins.IsValid() { - return store.ErrInvalidCoins(txIn.Coins.String()) + return coinstore.ErrInvalidCoins(txIn.Coins.String()) } if !txIn.Coins.IsPositive() { - return store.ErrInvalidCoins(txIn.Coins.String()) + return coinstore.ErrInvalidCoins(txIn.Coins.String()) } return nil } @@ -75,13 +75,13 @@ type TxOutput struct { // ValidateBasic - validate transaction output func (txOut TxOutput) ValidateBasic() error { if len(txOut.Address) == 0 { - return store.ErrInvalidAddress(txOut.Address.String()) + return coinstore.ErrInvalidAddress(txOut.Address.String()) } if !txOut.Coins.IsValid() { - return store.ErrInvalidCoins(txOut.Coins.String()) + return coinstore.ErrInvalidCoins(txOut.Coins.String()) } if !txOut.Coins.IsPositive() { - return store.ErrInvalidCoins(txOut.Coins.String()) + return coinstore.ErrInvalidCoins(txOut.Coins.String()) } return nil } @@ -135,7 +135,7 @@ func (tx SendTx) ValidateBasic() error { } // make sure inputs and outputs match if !totalIn.IsEqual(totalOut) { - return store.ErrInvalidCoins(totalIn.String()) // TODO + return coinstore.ErrInvalidCoins(totalIn.String()) // TODO } return nil }