diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index b355c4ed5..b8de60670 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -74,8 +74,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 + auth.ProtoBaseAccount, // prototype ) // add handlers diff --git a/cmd/gaia/cmd/gaiadebug/hack.go b/cmd/gaia/cmd/gaiadebug/hack.go index ddc8466c7..e3b601337 100644 --- a/cmd/gaia/cmd/gaiadebug/hack.go +++ b/cmd/gaia/cmd/gaiadebug/hack.go @@ -157,8 +157,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 + auth.ProtoBaseAccount, // prototype ) // add handlers diff --git a/docs/core/app3.md b/docs/core/app3.md index 450b1a59e..459f48c83 100644 --- a/docs/core/app3.md +++ b/docs/core/app3.md @@ -105,7 +105,7 @@ Creating an AccountMapper is easy - we just need to specify a codec, a capability key, and a prototype of the object being encoded ```go -accountMapper := auth.NewAccountMapper(cdc, keyAccount, &auth.BaseAccount{}) +accountMapper := auth.NewAccountMapper(cdc, keyAccount, auth.ProtoBaseAccount) ``` Then we can get, modify, and set accounts. For instance, we could double the @@ -335,7 +335,7 @@ func NewApp3(logger log.Logger, db dbm.DB) *bapp.BaseApp { keyFees := sdk.NewKVStoreKey("fee") // TODO // Set various mappers/keepers to interact easily with underlying stores - accountMapper := auth.NewAccountMapper(cdc, keyAccount, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, keyAccount, auth.ProtoBaseAccount) coinKeeper := bank.NewKeeper(accountMapper) feeKeeper := auth.NewFeeCollectionKeeper(cdc, keyFees) diff --git a/docs/core/examples/app3.go b/docs/core/examples/app3.go index f99e34b8b..853ad687e 100644 --- a/docs/core/examples/app3.go +++ b/docs/core/examples/app3.go @@ -28,7 +28,7 @@ func NewApp3(logger log.Logger, db dbm.DB) *bapp.BaseApp { keyFees := sdk.NewKVStoreKey("fee") // TODO // Set various mappers/keepers to interact easily with underlying stores - accountMapper := auth.NewAccountMapper(cdc, keyAccount, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, keyAccount, auth.ProtoBaseAccount) coinKeeper := bank.NewKeeper(accountMapper) feeKeeper := auth.NewFeeCollectionKeeper(cdc, keyFees) diff --git a/docs/core/examples/app4.go b/docs/core/examples/app4.go index daabe1561..a8ef37cee 100644 --- a/docs/core/examples/app4.go +++ b/docs/core/examples/app4.go @@ -28,7 +28,7 @@ func NewApp4(logger log.Logger, db dbm.DB) *bapp.BaseApp { keyAccount := sdk.NewKVStoreKey("acc") // Set various mappers/keepers to interact easily with underlying stores - accountMapper := auth.NewAccountMapper(cdc, keyAccount, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, keyAccount, auth.ProtoBaseAccount) coinKeeper := bank.NewKeeper(accountMapper) // TODO diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 6df74ef28..7b2c7af3a 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -62,8 +62,8 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // define and attach the mappers and keepers app.accountMapper = auth.NewAccountMapper( cdc, - app.keyAccount, // target store - &types.AppAccount{}, // prototype + app.keyAccount, // target store + auth.ProtoBaseAccount, // prototype ) app.coinKeeper = bank.NewKeeper(app.accountMapper) app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace)) diff --git a/examples/democoin/app/app.go b/examples/democoin/app/app.go index 6ea7d5247..51d10002a 100644 --- a/examples/democoin/app/app.go +++ b/examples/democoin/app/app.go @@ -71,7 +71,7 @@ func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp { app.accountMapper = auth.NewAccountMapper( cdc, app.capKeyAccountStore, // target store - &types.AppAccount{}, // prototype + types.ProtoAppAccount, // prototype ) // Add handlers. diff --git a/examples/democoin/types/account.go b/examples/democoin/types/account.go index e49191257..8eb9b0ae4 100644 --- a/examples/democoin/types/account.go +++ b/examples/democoin/types/account.go @@ -21,6 +21,11 @@ type AppAccount struct { Name string `json:"name"` } +// Constructor for AppAccount +func ProtoAppAccount() auth.Account { + return &AppAccount{} +} + // nolint func (acc AppAccount) GetName() string { return acc.Name } func (acc *AppAccount) SetName(name string) { acc.Name = name } diff --git a/examples/democoin/x/cool/keeper_test.go b/examples/democoin/x/cool/keeper_test.go index f0d65a545..ab59ea610 100644 --- a/examples/democoin/x/cool/keeper_test.go +++ b/examples/democoin/x/cool/keeper_test.go @@ -29,7 +29,7 @@ func TestCoolKeeper(t *testing.T) { cdc := wire.NewCodec() auth.RegisterBaseAccount(cdc) - am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) + am := auth.NewAccountMapper(cdc, capKey, auth.ProtoBaseAccount) ctx := sdk.NewContext(ms, abci.Header{}, false, nil) ck := bank.NewKeeper(am) keeper := NewKeeper(capKey, ck, DefaultCodespace) diff --git a/examples/democoin/x/pow/handler_test.go b/examples/democoin/x/pow/handler_test.go index 863a0dc6c..a203d2776 100644 --- a/examples/democoin/x/pow/handler_test.go +++ b/examples/democoin/x/pow/handler_test.go @@ -19,7 +19,7 @@ func TestPowHandler(t *testing.T) { cdc := wire.NewCodec() auth.RegisterBaseAccount(cdc) - am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) + am := auth.NewAccountMapper(cdc, capKey, auth.ProtoBaseAccount) ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger()) config := NewConfig("pow", int64(1)) ck := bank.NewKeeper(am) diff --git a/examples/democoin/x/pow/keeper_test.go b/examples/democoin/x/pow/keeper_test.go index 7a9b86984..a6802cb21 100644 --- a/examples/democoin/x/pow/keeper_test.go +++ b/examples/democoin/x/pow/keeper_test.go @@ -32,7 +32,7 @@ func TestPowKeeperGetSet(t *testing.T) { cdc := wire.NewCodec() auth.RegisterBaseAccount(cdc) - am := auth.NewAccountMapper(cdc, capKey, &auth.BaseAccount{}) + am := auth.NewAccountMapper(cdc, capKey, auth.ProtoBaseAccount) ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger()) config := NewConfig("pow", int64(1)) ck := bank.NewKeeper(am) diff --git a/examples/democoin/x/simplestake/keeper_test.go b/examples/democoin/x/simplestake/keeper_test.go index 35910b921..026f34346 100644 --- a/examples/democoin/x/simplestake/keeper_test.go +++ b/examples/democoin/x/simplestake/keeper_test.go @@ -35,7 +35,7 @@ func TestKeeperGetSet(t *testing.T) { cdc := wire.NewCodec() auth.RegisterBaseAccount(cdc) - accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, authKey, auth.ProtoBaseAccount) stakeKeeper := NewKeeper(capKey, bank.NewKeeper(accountMapper), DefaultCodespace) ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger()) addr := sdk.AccAddress([]byte("some-address")) @@ -65,7 +65,7 @@ func TestBonding(t *testing.T) { ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger()) - accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, authKey, auth.ProtoBaseAccount) coinKeeper := bank.NewKeeper(accountMapper) stakeKeeper := NewKeeper(capKey, coinKeeper, DefaultCodespace) addr := sdk.AccAddress([]byte("some-address")) diff --git a/x/auth/account.go b/x/auth/account.go index 0e9e3075c..3340c8bd5 100644 --- a/x/auth/account.go +++ b/x/auth/account.go @@ -46,6 +46,11 @@ type BaseAccount struct { Sequence int64 `json:"sequence"` } +// Prototype function for BaseAccount +func ProtoBaseAccount() Account { + return &BaseAccount{} +} + func NewBaseAccountWithAddress(addr sdk.AccAddress) BaseAccount { return BaseAccount{ Address: addr, diff --git a/x/auth/ante_test.go b/x/auth/ante_test.go index 8147edb2c..c30013d32 100644 --- a/x/auth/ante_test.go +++ b/x/auth/ante_test.go @@ -112,7 +112,7 @@ func TestAnteHandlerSigErrors(t *testing.T) { ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) - mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + mapper := NewAccountMapper(cdc, capKey, ProtoBaseAccount) feeCollector := NewFeeCollectionKeeper(cdc, capKey2) anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger()) @@ -165,7 +165,7 @@ func TestAnteHandlerAccountNumbers(t *testing.T) { ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) - mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + mapper := NewAccountMapper(cdc, capKey, ProtoBaseAccount) feeCollector := NewFeeCollectionKeeper(cdc, capKey2) anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger()) @@ -224,7 +224,7 @@ func TestAnteHandlerSequences(t *testing.T) { ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) - mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + mapper := NewAccountMapper(cdc, capKey, ProtoBaseAccount) feeCollector := NewFeeCollectionKeeper(cdc, capKey2) anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger()) @@ -302,7 +302,7 @@ func TestAnteHandlerFees(t *testing.T) { ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) - mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + mapper := NewAccountMapper(cdc, capKey, ProtoBaseAccount) feeCollector := NewFeeCollectionKeeper(cdc, capKey2) anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger()) @@ -344,7 +344,7 @@ func TestAnteHandlerMemoGas(t *testing.T) { ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) - mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + mapper := NewAccountMapper(cdc, capKey, ProtoBaseAccount) feeCollector := NewFeeCollectionKeeper(cdc, capKey2) anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger()) @@ -387,7 +387,7 @@ func TestAnteHandlerMultiSigner(t *testing.T) { ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) - mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + mapper := NewAccountMapper(cdc, capKey, ProtoBaseAccount) feeCollector := NewFeeCollectionKeeper(cdc, capKey2) anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger()) @@ -438,7 +438,7 @@ func TestAnteHandlerBadSignBytes(t *testing.T) { ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) - mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + mapper := NewAccountMapper(cdc, capKey, ProtoBaseAccount) feeCollector := NewFeeCollectionKeeper(cdc, capKey2) anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger()) @@ -519,7 +519,7 @@ func TestAnteHandlerSetPubKey(t *testing.T) { ms, capKey, capKey2 := setupMultiStore() cdc := wire.NewCodec() RegisterBaseAccount(cdc) - mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + mapper := NewAccountMapper(cdc, capKey, ProtoBaseAccount) feeCollector := NewFeeCollectionKeeper(cdc, capKey2) anteHandler := NewAnteHandler(mapper, feeCollector) ctx := sdk.NewContext(ms, abci.Header{ChainID: "mychainid"}, false, log.NewNopLogger()) diff --git a/x/auth/mapper.go b/x/auth/mapper.go index 88cedcb15..244527af3 100644 --- a/x/auth/mapper.go +++ b/x/auth/mapper.go @@ -1,9 +1,6 @@ package auth import ( - "fmt" - "reflect" - sdk "github.com/cosmos/cosmos-sdk/types" wire "github.com/cosmos/cosmos-sdk/wire" "github.com/tendermint/tendermint/crypto" @@ -18,8 +15,8 @@ type AccountMapper struct { // The (unexposed) key used to access the store from the Context. key sdk.StoreKey - // The prototypical Account concrete type. - proto Account + // The prototypical Account constructor. + proto func() Account // The wire codec for binary encoding/decoding of accounts. cdc *wire.Codec @@ -28,7 +25,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 Account) AccountMapper { +func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto func() Account) AccountMapper { return AccountMapper{ key: key, proto: proto, @@ -38,7 +35,7 @@ func NewAccountMapper(cdc *wire.Codec, key sdk.StoreKey, proto Account) AccountM // Implaements sdk.AccountMapper. func (am AccountMapper) NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) Account { - acc := am.clonePrototype() + acc := am.proto() err := acc.SetAddress(addr) if err != nil { // Handle w/ #870 @@ -158,30 +155,6 @@ func (am AccountMapper) GetNextAccountNumber(ctx sdk.Context) int64 { //---------------------------------------- // misc. -// Creates a new struct (or pointer to struct) from am.proto. -func (am AccountMapper) clonePrototype() Account { - protoRt := reflect.TypeOf(am.proto) - if protoRt.Kind() == reflect.Ptr { - protoCrt := protoRt.Elem() - if protoCrt.Kind() != reflect.Struct { - panic("accountMapper requires a struct proto sdk.Account, or a pointer to one") - } - protoRv := reflect.New(protoCrt) - 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 - } - - protoRv := reflect.New(protoRt).Elem() - 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 Account) []byte { bz, err := am.cdc.MarshalBinaryBare(acc) if err != nil { diff --git a/x/auth/mapper_test.go b/x/auth/mapper_test.go index e7271a2ae..679ee12cd 100644 --- a/x/auth/mapper_test.go +++ b/x/auth/mapper_test.go @@ -32,7 +32,7 @@ func TestAccountMapperGetSet(t *testing.T) { // make context and mapper ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger()) - mapper := NewAccountMapper(cdc, capKey, &BaseAccount{}) + mapper := NewAccountMapper(cdc, capKey, ProtoBaseAccount) addr := sdk.AccAddress([]byte("some-address")) diff --git a/x/bank/keeper_test.go b/x/bank/keeper_test.go index 7b27d45fa..c9d7c4119 100644 --- a/x/bank/keeper_test.go +++ b/x/bank/keeper_test.go @@ -33,7 +33,7 @@ func TestKeeper(t *testing.T) { auth.RegisterBaseAccount(cdc) ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger()) - accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, authKey, auth.ProtoBaseAccount) coinKeeper := NewKeeper(accountMapper) addr := sdk.AccAddress([]byte("addr1")) @@ -118,7 +118,7 @@ func TestSendKeeper(t *testing.T) { auth.RegisterBaseAccount(cdc) ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger()) - accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, authKey, auth.ProtoBaseAccount) coinKeeper := NewKeeper(accountMapper) sendKeeper := NewSendKeeper(accountMapper) @@ -187,7 +187,7 @@ func TestViewKeeper(t *testing.T) { auth.RegisterBaseAccount(cdc) ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewNopLogger()) - accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, authKey, auth.ProtoBaseAccount) coinKeeper := NewKeeper(accountMapper) viewKeeper := NewViewKeeper(accountMapper) diff --git a/x/ibc/ibc_test.go b/x/ibc/ibc_test.go index 8c91921bd..06e2bd167 100644 --- a/x/ibc/ibc_test.go +++ b/x/ibc/ibc_test.go @@ -64,7 +64,7 @@ func TestIBC(t *testing.T) { key := sdk.NewKVStoreKey("ibc") ctx := defaultContext(key) - am := auth.NewAccountMapper(cdc, key, &auth.BaseAccount{}) + am := auth.NewAccountMapper(cdc, key, auth.ProtoBaseAccount) ck := bank.NewKeeper(am) src := newAddress() diff --git a/x/mock/app.go b/x/mock/app.go index 83d17ba68..27f3b9d46 100644 --- a/x/mock/app.go +++ b/x/mock/app.go @@ -58,7 +58,7 @@ func NewApp() *App { app.AccountMapper = auth.NewAccountMapper( app.Cdc, app.KeyAccount, - &auth.BaseAccount{}, + auth.ProtoBaseAccount, ) // Initialize the app. The chainers and blockers can be overwritten before diff --git a/x/slashing/test_common.go b/x/slashing/test_common.go index c5320cb24..e2058f09f 100644 --- a/x/slashing/test_common.go +++ b/x/slashing/test_common.go @@ -59,7 +59,7 @@ func createTestInput(t *testing.T) (sdk.Context, bank.Keeper, stake.Keeper, Keep require.Nil(t, err) ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewTMLogger(os.Stdout)) cdc := createTestCodec() - accountMapper := auth.NewAccountMapper(cdc, keyAcc, &auth.BaseAccount{}) + accountMapper := auth.NewAccountMapper(cdc, keyAcc, auth.ProtoBaseAccount) ck := bank.NewKeeper(accountMapper) sk := stake.NewKeeper(cdc, keyStake, ck, stake.DefaultCodespace) genesis := stake.DefaultGenesisState() diff --git a/x/stake/keeper/test_common.go b/x/stake/keeper/test_common.go index 983933123..21073a1ff 100644 --- a/x/stake/keeper/test_common.go +++ b/x/stake/keeper/test_common.go @@ -101,9 +101,9 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, log.NewNopLogger()) cdc := MakeTestCodec() accountMapper := auth.NewAccountMapper( - cdc, // amino codec - keyAcc, // target store - &auth.BaseAccount{}, // prototype + cdc, // amino codec + keyAcc, // target store + auth.ProtoBaseAccount, // prototype ) ck := bank.NewKeeper(accountMapper) keeper := NewKeeper(cdc, keyStake, ck, types.DefaultCodespace)