Refactor CoinMapper
CoinMapper is now called CoinKeeper to differentiate it from AccountMapper. A Mapper retrieves things from a store. A Keeper exposes functionality of coins and maintain invariants. bank.NewHandler takes a CoinKeeper instead of the entire AccountMapper.
This commit is contained in:
parent
51dca8f0a9
commit
8837af66bd
|
@ -25,6 +25,6 @@ func (app *BasecoinApp) initRouterHandlers() {
|
|||
|
||||
// All handlers must be added here.
|
||||
// The order matters.
|
||||
app.router.AddRoute("bank", bank.NewHandler(app.accountMapper))
|
||||
app.router.AddRoute("bank", bank.NewHandler(bank.NewCoinKeeper(app.accountMapper)))
|
||||
app.router.AddRoute("sketchy", sketchy.NewHandler())
|
||||
}
|
||||
|
|
|
@ -77,6 +77,19 @@ func (am accountMapper) SetAccount(ctx sdk.Context, acc sdk.Account) {
|
|||
store.Set(addr, bz)
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// sealedAccountMapper
|
||||
|
||||
type sealedAccountMapper struct {
|
||||
accountMapper
|
||||
}
|
||||
|
||||
// There's no way for external modules to mutate the
|
||||
// sam.accountMapper.ctx from here, even with reflection.
|
||||
func (sam sealedAccountMapper) WireCodec() *wire.Codec {
|
||||
panic("accountMapper is sealed")
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// misc.
|
||||
|
||||
|
@ -139,16 +152,3 @@ func (am accountMapper) decodeAccount(bz []byte) sdk.Account {
|
|||
return reflect.ValueOf(accPtr).Elem().Interface().(sdk.Account)
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// sealedAccountMapper
|
||||
|
||||
type sealedAccountMapper struct {
|
||||
accountMapper
|
||||
}
|
||||
|
||||
// There's no way for external modules to mutate the
|
||||
// sam.accountMapper.ctx from here, even with reflection.
|
||||
func (sam sealedAccountMapper) WireCodec() *wire.Codec {
|
||||
panic("accountMapper is sealed")
|
||||
}
|
||||
|
|
|
@ -7,37 +7,33 @@ import (
|
|||
)
|
||||
|
||||
// Handle all "bank" type messages.
|
||||
// NOTE: Technically, NewHandler only needs a CoinMapper
|
||||
func NewHandler(am sdk.AccountMapper) sdk.Handler {
|
||||
|
||||
func NewHandler(ck CoinKeeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
cm := CoinMapper{am}
|
||||
switch msg := msg.(type) {
|
||||
case SendMsg:
|
||||
return handleSendMsg(ctx, cm, msg)
|
||||
return handleSendMsg(ctx, ck, msg)
|
||||
case IssueMsg:
|
||||
return handleIssueMsg(ctx, cm, msg)
|
||||
return handleIssueMsg(ctx, ck, msg)
|
||||
default:
|
||||
errMsg := "Unrecognized bank Msg type: " + reflect.TypeOf(msg).Name()
|
||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Handle SendMsg.
|
||||
func handleSendMsg(ctx sdk.Context, cm CoinMapper, msg SendMsg) sdk.Result {
|
||||
func handleSendMsg(ctx sdk.Context, ck CoinKeeper, msg SendMsg) sdk.Result {
|
||||
// NOTE: totalIn == totalOut should already have been checked
|
||||
|
||||
for _, in := range msg.Inputs {
|
||||
_, err := cm.SubtractCoins(ctx, in.Address, in.Coins)
|
||||
_, err := ck.SubtractCoins(ctx, in.Address, in.Coins)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
}
|
||||
|
||||
for _, out := range msg.Outputs {
|
||||
_, err := cm.AddCoins(ctx, out.Address, out.Coins)
|
||||
_, err := ck.AddCoins(ctx, out.Address, out.Coins)
|
||||
if err != nil {
|
||||
return err.Result()
|
||||
}
|
||||
|
@ -47,6 +43,6 @@ func handleSendMsg(ctx sdk.Context, cm CoinMapper, msg SendMsg) sdk.Result {
|
|||
}
|
||||
|
||||
// Handle IssueMsg.
|
||||
func handleIssueMsg(ctx sdk.Context, cm CoinMapper, msg IssueMsg) sdk.Result {
|
||||
func handleIssueMsg(ctx sdk.Context, ck CoinKeeper, msg IssueMsg) sdk.Result {
|
||||
panic("not implemented yet")
|
||||
}
|
||||
|
|
|
@ -3,18 +3,24 @@ package bank
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// CoinMapper manages transfers between accounts
|
||||
type CoinMapper struct {
|
||||
// CoinKeeper manages transfers between accounts
|
||||
type CoinKeeper struct {
|
||||
am sdk.AccountMapper
|
||||
}
|
||||
|
||||
// NewCoinKeeper returns a new CoinKeeper
|
||||
func NewCoinKeeper(am sdk.AccountMapper) CoinKeeper {
|
||||
return CoinKeeper{am: am}
|
||||
}
|
||||
|
||||
// SubtractCoins subtracts amt from the coins at the addr.
|
||||
func (cm CoinMapper) SubtractCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) {
|
||||
acc := cm.am.GetAccount(ctx, addr)
|
||||
func (ck CoinKeeper) SubtractCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) {
|
||||
acc := ck.am.GetAccount(ctx, addr)
|
||||
if acc == nil {
|
||||
return amt, sdk.ErrUnrecognizedAddress(addr)
|
||||
}
|
||||
|
@ -26,21 +32,21 @@ func (cm CoinMapper) SubtractCoins(ctx sdk.Context, addr crypto.Address, amt sdk
|
|||
}
|
||||
|
||||
acc.SetCoins(newCoins)
|
||||
cm.am.SetAccount(ctx, acc)
|
||||
ck.am.SetAccount(ctx, acc)
|
||||
return newCoins, nil
|
||||
}
|
||||
|
||||
// AddCoins adds amt to the coins at the addr.
|
||||
func (cm CoinMapper) AddCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) {
|
||||
acc := cm.am.GetAccount(ctx, addr)
|
||||
func (ck CoinKeeper) AddCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) {
|
||||
acc := ck.am.GetAccount(ctx, addr)
|
||||
if acc == nil {
|
||||
acc = cm.am.NewAccountWithAddress(ctx, addr)
|
||||
acc = ck.am.NewAccountWithAddress(ctx, addr)
|
||||
}
|
||||
|
||||
coins := acc.GetCoins()
|
||||
newCoins := coins.Plus(amt)
|
||||
|
||||
acc.SetCoins(newCoins)
|
||||
cm.am.SetAccount(ctx, acc)
|
||||
ck.am.SetAccount(ctx, acc)
|
||||
return newCoins, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue