-
Notifications
You must be signed in to change notification settings - Fork 47
/
antispam_fee_decorator.go
54 lines (48 loc) · 1.77 KB
/
antispam_fee_decorator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package msgfee
import (
"github.com/iov-one/weave"
"github.com/iov-one/weave/coin"
"github.com/iov-one/weave/errors"
)
// AntispamFeeDecorator implements a decorator that for each processed transaction
// asks for a minimal fee. The fee is defined globally in the app.
// If fee is not set (zero value) or is less than the fee already asked for the transaction
// then this decorator is a noop.
type AntispamFeeDecorator struct {
fee coin.Coin
}
var _ weave.Decorator = (*AntispamFeeDecorator)(nil)
// NewAntispamFeeDecorator returns an AntispamFeeDecorator
func NewAntispamFeeDecorator(fee coin.Coin) *AntispamFeeDecorator {
if fee.IsZero() {
// Returning a nil is a way to inform weave to ignore this
// decorator. Instead of checking during the runtime if the fee
// is zero, we can create a no operation (ignored) decorator
// instance instead.
return nil
}
return &AntispamFeeDecorator{fee: fee}
}
func (d *AntispamFeeDecorator) Check(ctx weave.Context, store weave.KVStore, tx weave.Tx, next weave.Checker) (*weave.CheckResult, error) {
res, err := next.Check(ctx, store, tx)
if d == nil { // Since NewAntispamFeeDecorator can return nil, let's be graceful here
return res, err
}
if err != nil {
return nil, err
}
if res.RequiredFee.IsZero() {
return nil, errors.Wrap(errors.ErrEmpty, "required must not be zero")
}
if !res.RequiredFee.SameType(d.fee) {
return nil, errors.Wrapf(errors.ErrCurrency,
"antispam fee has the wrong type: expected %q, got %q", d.fee.Ticker, res.RequiredFee.Ticker)
}
if !res.RequiredFee.IsGTE(d.fee) {
res.RequiredFee = d.fee
}
return res, nil
}
func (d *AntispamFeeDecorator) Deliver(ctx weave.Context, store weave.KVStore, tx weave.Tx, next weave.Deliverer) (*weave.DeliverResult, error) {
return next.Deliver(ctx, store, tx)
}