2017-06-01 11:01:19 -07:00
|
|
|
package handlers
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/tendermint/basecoin"
|
|
|
|
"github.com/tendermint/basecoin/errors"
|
2017-06-01 11:26:43 -07:00
|
|
|
"github.com/tendermint/basecoin/txs"
|
2017-06-01 11:01:19 -07:00
|
|
|
"github.com/tendermint/basecoin/types"
|
|
|
|
)
|
|
|
|
|
2017-06-27 10:22:25 -07:00
|
|
|
const (
|
|
|
|
NameFee = "fee"
|
|
|
|
)
|
|
|
|
|
2017-06-01 11:26:43 -07:00
|
|
|
type AccountChecker interface {
|
|
|
|
// Get amount checks the current amount
|
2017-06-29 06:29:36 -07:00
|
|
|
GetAmount(store types.KVStore, addr basecoin.Actor) (types.Coins, error)
|
2017-06-01 11:01:19 -07:00
|
|
|
|
2017-06-01 11:26:43 -07:00
|
|
|
// ChangeAmount modifies the balance by the given amount and returns the new balance
|
|
|
|
// always returns an error if leading to negative balance
|
2017-06-29 06:29:36 -07:00
|
|
|
ChangeAmount(store types.KVStore, addr basecoin.Actor, coins types.Coins) (types.Coins, error)
|
2017-06-01 11:01:19 -07:00
|
|
|
}
|
|
|
|
|
2017-06-01 11:26:43 -07:00
|
|
|
type SimpleFeeHandler struct {
|
|
|
|
AccountChecker
|
|
|
|
MinFee types.Coins
|
2017-06-01 11:01:19 -07:00
|
|
|
}
|
|
|
|
|
2017-06-27 10:22:25 -07:00
|
|
|
func (_ SimpleFeeHandler) Name() string {
|
|
|
|
return NameFee
|
|
|
|
}
|
|
|
|
|
2017-06-27 10:40:48 -07:00
|
|
|
var _ basecoin.Middleware = SimpleFeeHandler{}
|
2017-06-01 11:26:43 -07:00
|
|
|
|
|
|
|
// Yes, I know refactor a bit... really too late already
|
2017-06-01 11:01:19 -07:00
|
|
|
|
2017-06-27 10:40:48 -07:00
|
|
|
func (h SimpleFeeHandler) CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Checker) (res basecoin.Result, err error) {
|
2017-06-01 11:26:43 -07:00
|
|
|
feeTx, ok := tx.Unwrap().(*txs.Fee)
|
2017-06-01 11:01:19 -07:00
|
|
|
if !ok {
|
2017-06-01 11:26:43 -07:00
|
|
|
return res, errors.InvalidFormat()
|
|
|
|
}
|
|
|
|
|
|
|
|
fees := types.Coins{feeTx.Fee}
|
|
|
|
if !fees.IsGTE(h.MinFee) {
|
|
|
|
return res, errors.InsufficientFees()
|
|
|
|
}
|
|
|
|
|
2017-06-29 06:29:36 -07:00
|
|
|
if !ctx.HasPermission(feeTx.Payer) {
|
2017-06-01 11:01:19 -07:00
|
|
|
return res, errors.Unauthorized()
|
|
|
|
}
|
|
|
|
|
2017-06-01 11:26:43 -07:00
|
|
|
_, err = h.ChangeAmount(store, feeTx.Payer, fees.Negative())
|
2017-06-01 11:01:19 -07:00
|
|
|
if err != nil {
|
|
|
|
return res, err
|
|
|
|
}
|
|
|
|
|
2017-06-01 11:26:43 -07:00
|
|
|
return basecoin.Result{Log: "Valid tx"}, nil
|
2017-06-01 11:01:19 -07:00
|
|
|
}
|
|
|
|
|
2017-06-27 10:40:48 -07:00
|
|
|
func (h SimpleFeeHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Deliver) (res basecoin.Result, err error) {
|
2017-06-01 11:26:43 -07:00
|
|
|
feeTx, ok := tx.Unwrap().(*txs.Fee)
|
2017-06-01 11:01:19 -07:00
|
|
|
if !ok {
|
2017-06-01 11:26:43 -07:00
|
|
|
return res, errors.InvalidFormat()
|
|
|
|
}
|
|
|
|
|
|
|
|
fees := types.Coins{feeTx.Fee}
|
|
|
|
if !fees.IsGTE(h.MinFee) {
|
|
|
|
return res, errors.InsufficientFees()
|
|
|
|
}
|
|
|
|
|
2017-06-29 06:29:36 -07:00
|
|
|
if !ctx.HasPermission(feeTx.Payer) {
|
2017-06-01 11:01:19 -07:00
|
|
|
return res, errors.Unauthorized()
|
|
|
|
}
|
|
|
|
|
2017-06-01 11:26:43 -07:00
|
|
|
_, err = h.ChangeAmount(store, feeTx.Payer, fees.Negative())
|
2017-06-01 11:01:19 -07:00
|
|
|
if err != nil {
|
|
|
|
return res, err
|
|
|
|
}
|
|
|
|
|
2017-06-27 10:40:48 -07:00
|
|
|
return next.DeliverTx(ctx, store, feeTx.Next())
|
2017-06-01 11:01:19 -07:00
|
|
|
}
|