cosmos-sdk/modules/fee/handler.go

86 lines
2.2 KiB
Go

package fee
import (
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/errors"
"github.com/tendermint/basecoin/stack"
"github.com/tendermint/basecoin/types"
)
// NameFee - namespace for the fee module
const NameFee = "fee"
// AccountChecker - interface used by SimpleFeeHandler
type AccountChecker interface {
// Get amount checks the current amount
GetAmount(store types.KVStore, addr basecoin.Actor) (types.Coins, error)
// ChangeAmount modifies the balance by the given amount and returns the new balance
// always returns an error if leading to negative balance
ChangeAmount(store types.KVStore, addr basecoin.Actor, coins types.Coins) (types.Coins, error)
}
// SimpleFeeHandler - checker object for fee checking
type SimpleFeeHandler struct {
AccountChecker
MinFee types.Coins
stack.PassOption
}
// Name - return the namespace for the fee module
func (SimpleFeeHandler) Name() string {
return NameFee
}
var _ stack.Middleware = SimpleFeeHandler{}
// Yes, I know refactor a bit... really too late already
// CheckTx - check the transaction
func (h SimpleFeeHandler) CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Checker) (res basecoin.Result, err error) {
feeTx, ok := tx.Unwrap().(*Fee)
if !ok {
return res, errors.ErrInvalidFormat(tx)
}
fees := types.Coins{feeTx.Fee}
if !fees.IsGTE(h.MinFee) {
return res, ErrInsufficientFees()
}
if !ctx.HasPermission(feeTx.Payer) {
return res, errors.ErrUnauthorized()
}
_, err = h.ChangeAmount(store, feeTx.Payer, fees.Negative())
if err != nil {
return res, err
}
return basecoin.Result{Log: "Valid tx"}, nil
}
// DeliverTx - send the fee handler transaction
func (h SimpleFeeHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Deliver) (res basecoin.Result, err error) {
feeTx, ok := tx.Unwrap().(*Fee)
if !ok {
return res, errors.ErrInvalidFormat(tx)
}
fees := types.Coins{feeTx.Fee}
if !fees.IsGTE(h.MinFee) {
return res, ErrInsufficientFees()
}
if !ctx.HasPermission(feeTx.Payer) {
return res, errors.ErrUnauthorized()
}
_, err = h.ChangeAmount(store, feeTx.Payer, fees.Negative())
if err != nil {
return res, err
}
return next.DeliverTx(ctx, store, feeTx.Next())
}