cosmos-sdk/modules/fee/handler.go

118 lines
3.3 KiB
Go
Raw Normal View History

package fee
2017-06-01 11:01:19 -07:00
import (
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/errors"
2017-07-06 05:59:45 -07:00
"github.com/tendermint/basecoin/modules/coin"
"github.com/tendermint/basecoin/stack"
2017-07-06 05:23:38 -07:00
"github.com/tendermint/basecoin/state"
2017-06-01 11:01:19 -07:00
)
2017-07-06 02:30:03 -07:00
// NameFee - namespace for the fee module
const NameFee = "fee"
// Bank is a default location for the fees, but pass anything into
// the middleware constructor
var Bank = basecoin.Actor{App: NameFee, Address: []byte("bank")}
2017-07-12 10:06:55 -07:00
// SimpleFeeMiddleware - middleware for fee checking, constant amount
// It used modules.coin to move the money
type SimpleFeeMiddleware struct {
// the fee must be the same denomination and >= this amount
// if the amount is 0, then the fee tx wrapper is optional
MinFee coin.Coin
// all fees go here, which could be a dump (Bank) or something reachable
// by other app logic
2017-07-12 10:06:55 -07:00
Collector basecoin.Actor
2017-07-30 14:26:25 -07:00
stack.PassInitState
stack.PassInitValidate
2017-06-01 11:01:19 -07:00
}
2017-07-12 10:06:55 -07:00
var _ stack.Middleware = SimpleFeeMiddleware{}
// NewSimpleFeeMiddleware returns a fee handler with a fixed minimum fee.
//
// If minFee is 0, then the FeeTx is optional
2017-07-12 11:22:42 -07:00
func NewSimpleFeeMiddleware(minFee coin.Coin, collector basecoin.Actor) SimpleFeeMiddleware {
2017-07-12 10:06:55 -07:00
return SimpleFeeMiddleware{
2017-07-12 11:22:42 -07:00
MinFee: minFee,
Collector: collector,
2017-07-12 10:06:55 -07:00
}
2017-06-01 11:01:19 -07:00
}
2017-07-06 02:30:03 -07:00
// Name - return the namespace for the fee module
2017-07-12 10:06:55 -07:00
func (SimpleFeeMiddleware) Name() string {
return NameFee
}
2017-07-06 02:30:03 -07:00
// CheckTx - check the transaction
func (h SimpleFeeMiddleware) CheckTx(ctx basecoin.Context, store state.SimpleDB, tx basecoin.Tx, next basecoin.Checker) (res basecoin.CheckResult, err error) {
fee, err := h.verifyFee(ctx, tx)
if err != nil {
2017-08-04 04:50:55 -07:00
if IsSkipFeesErr(err) {
return next.CheckTx(ctx, store, tx)
}
return res, err
}
var paid, used uint
if !fee.Fee.IsZero() { // now, try to make a IPC call to coins...
send := coin.NewSendOneTx(fee.Payer, h.Collector, coin.Coins{fee.Fee})
sendRes, err := next.CheckTx(ctx, store, send)
if err != nil {
return res, err
}
paid = uint(fee.Fee.Amount)
used = sendRes.GasAllocated
}
res, err = next.CheckTx(ctx, store, fee.Tx)
// add the given fee to the price for gas, plus one query
if err == nil {
res.GasPayment += paid
res.GasAllocated += used
}
return res, err
2017-06-01 11:01:19 -07:00
}
2017-07-06 02:30:03 -07:00
// DeliverTx - send the fee handler transaction
func (h SimpleFeeMiddleware) DeliverTx(ctx basecoin.Context, store state.SimpleDB, tx basecoin.Tx, next basecoin.Deliver) (res basecoin.DeliverResult, err error) {
fee, err := h.verifyFee(ctx, tx)
if IsSkipFeesErr(err) {
return next.DeliverTx(ctx, store, tx)
}
if err != nil {
return res, err
}
if !fee.Fee.IsZero() { // now, try to make a IPC call to coins...
send := coin.NewSendOneTx(fee.Payer, h.Collector, coin.Coins{fee.Fee})
_, err = next.DeliverTx(ctx, store, send)
if err != nil {
return res, err
}
}
return next.DeliverTx(ctx, store, fee.Tx)
2017-07-12 10:06:55 -07:00
}
func (h SimpleFeeMiddleware) verifyFee(ctx basecoin.Context, tx basecoin.Tx) (Fee, error) {
2017-07-12 10:06:55 -07:00
feeTx, ok := tx.Unwrap().(Fee)
2017-06-01 11:01:19 -07:00
if !ok {
2017-07-12 10:06:55 -07:00
// the fee wrapper is not required if there is no minimum
if h.MinFee.IsZero() {
return feeTx, ErrSkipFees()
2017-07-12 10:06:55 -07:00
}
return feeTx, errors.ErrInvalidFormat(TypeFees, tx)
}
// see if it is the proper denom and big enough
2017-07-12 10:06:55 -07:00
fee := feeTx.Fee
if fee.Denom != h.MinFee.Denom {
return feeTx, ErrWrongFeeDenom(h.MinFee.Denom)
}
2017-07-12 10:06:55 -07:00
if !fee.IsGTE(h.MinFee) {
return feeTx, ErrInsufficientFees()
2017-06-01 11:01:19 -07:00
}
return feeTx, nil
2017-06-01 11:01:19 -07:00
}