Add SetOption to all middleware and handlers
This commit is contained in:
+3
-1
@@ -12,7 +12,9 @@ const (
|
||||
)
|
||||
|
||||
// Chain enforces that this tx was bound to the named chain
|
||||
type Chain struct{}
|
||||
type Chain struct {
|
||||
PassOption
|
||||
}
|
||||
|
||||
func (_ Chain) Name() string {
|
||||
return NameRecovery
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ func TestChain(t *testing.T) {
|
||||
store := types.NewMemKVStore()
|
||||
|
||||
// build the stack
|
||||
ok := OKHandler{msg}
|
||||
ok := OKHandler{Log: msg}
|
||||
app := New(Chain{}).Use(ok)
|
||||
|
||||
for idx, tc := range cases {
|
||||
|
||||
+6
-1
@@ -19,6 +19,7 @@ const (
|
||||
// OKHandler just used to return okay to everything
|
||||
type OKHandler struct {
|
||||
Log string
|
||||
basecoin.NopOption
|
||||
}
|
||||
|
||||
var _ basecoin.Handler = OKHandler{}
|
||||
@@ -38,7 +39,9 @@ func (ok OKHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx base
|
||||
}
|
||||
|
||||
// EchoHandler returns success, echoing res.Data = tx bytes
|
||||
type EchoHandler struct{}
|
||||
type EchoHandler struct {
|
||||
basecoin.NopOption
|
||||
}
|
||||
|
||||
var _ basecoin.Handler = EchoHandler{}
|
||||
|
||||
@@ -61,6 +64,7 @@ func (_ EchoHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx bas
|
||||
// FailHandler always returns an error
|
||||
type FailHandler struct {
|
||||
Err error
|
||||
basecoin.NopOption
|
||||
}
|
||||
|
||||
var _ basecoin.Handler = FailHandler{}
|
||||
@@ -83,6 +87,7 @@ func (f FailHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx bas
|
||||
type PanicHandler struct {
|
||||
Msg string
|
||||
Err error
|
||||
basecoin.NopOption
|
||||
}
|
||||
|
||||
var _ basecoin.Handler = PanicHandler{}
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestOK(t *testing.T) {
|
||||
data := "this looks okay"
|
||||
tx := basecoin.Tx{}
|
||||
|
||||
ok := OKHandler{data}
|
||||
ok := OKHandler{Log: data}
|
||||
res, err := ok.CheckTx(ctx, store, tx)
|
||||
assert.Nil(err, "%+v", err)
|
||||
assert.Equal(data, res.Log)
|
||||
@@ -38,7 +38,7 @@ func TestFail(t *testing.T) {
|
||||
msg := "big problem"
|
||||
tx := basecoin.Tx{}
|
||||
|
||||
fail := FailHandler{errors.New(msg)}
|
||||
fail := FailHandler{Err: errors.New(msg)}
|
||||
_, err := fail.CheckTx(ctx, store, tx)
|
||||
if assert.NotNil(err) {
|
||||
assert.Equal(msg, err.Error())
|
||||
|
||||
@@ -15,6 +15,7 @@ const (
|
||||
// Required Actor, otherwise passes along the call untouched
|
||||
type CheckMiddleware struct {
|
||||
Required basecoin.Actor
|
||||
PassOption
|
||||
}
|
||||
|
||||
var _ Middleware = CheckMiddleware{}
|
||||
@@ -40,6 +41,7 @@ func (p CheckMiddleware) DeliverTx(ctx basecoin.Context, store types.KVStore, tx
|
||||
// GrantMiddleware tries to set the permission to this Actor, which may be prohibited
|
||||
type GrantMiddleware struct {
|
||||
Auth basecoin.Actor
|
||||
PassOption
|
||||
}
|
||||
|
||||
var _ Middleware = GrantMiddleware{}
|
||||
|
||||
+52
-8
@@ -1,18 +1,12 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
||||
"github.com/tendermint/basecoin"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
)
|
||||
|
||||
type CheckerMiddle interface {
|
||||
CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Checker) (basecoin.Result, error)
|
||||
}
|
||||
|
||||
type DeliverMiddle interface {
|
||||
DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Deliver) (basecoin.Result, error)
|
||||
}
|
||||
|
||||
// Middleware is anything that wraps another handler to enhance functionality.
|
||||
//
|
||||
// You can use utilities in handlers to construct them, the interfaces
|
||||
@@ -20,5 +14,55 @@ type DeliverMiddle interface {
|
||||
type Middleware interface {
|
||||
CheckerMiddle
|
||||
DeliverMiddle
|
||||
SetOptionMiddle
|
||||
basecoin.Named
|
||||
}
|
||||
|
||||
type CheckerMiddle interface {
|
||||
CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Checker) (basecoin.Result, error)
|
||||
}
|
||||
|
||||
type CheckerMiddleFunc func(basecoin.Context, types.KVStore, basecoin.Tx, basecoin.Checker) (basecoin.Result, error)
|
||||
|
||||
func (c CheckerMiddleFunc) CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Checker) (basecoin.Result, error) {
|
||||
return c(ctx, store, tx, next)
|
||||
}
|
||||
|
||||
type DeliverMiddle interface {
|
||||
DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Deliver) (basecoin.Result, error)
|
||||
}
|
||||
|
||||
type DeliverMiddleFunc func(basecoin.Context, types.KVStore, basecoin.Tx, basecoin.Deliver) (basecoin.Result, error)
|
||||
|
||||
func (d DeliverMiddleFunc) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Deliver) (basecoin.Result, error) {
|
||||
return d(ctx, store, tx, next)
|
||||
}
|
||||
|
||||
type SetOptionMiddle interface {
|
||||
SetOption(l log.Logger, store types.KVStore, key, value string, next basecoin.SetOptioner) (string, error)
|
||||
}
|
||||
|
||||
type SetOptionMiddleFunc func(log.Logger, types.KVStore, string, string, basecoin.SetOptioner) (string, error)
|
||||
|
||||
func (c SetOptionMiddleFunc) SetOption(l log.Logger, store types.KVStore, key, value string, next basecoin.SetOptioner) (string, error) {
|
||||
return c(l, store, key, value, next)
|
||||
}
|
||||
|
||||
// holders
|
||||
type PassCheck struct{}
|
||||
|
||||
func (_ PassCheck) CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Checker) (basecoin.Result, error) {
|
||||
return next.CheckTx(ctx, store, tx)
|
||||
}
|
||||
|
||||
type PassDeliver struct{}
|
||||
|
||||
func (_ PassDeliver) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Deliver) (basecoin.Result, error) {
|
||||
return next.DeliverTx(ctx, store, tx)
|
||||
}
|
||||
|
||||
type PassOption struct{}
|
||||
|
||||
func (_ PassOption) SetOption(l log.Logger, store types.KVStore, key, value string, next basecoin.SetOptioner) (string, error) {
|
||||
return next.SetOption(l, store, key, value)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package stack
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
||||
"github.com/tendermint/basecoin"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
)
|
||||
@@ -48,6 +50,20 @@ func (_ Logger) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin
|
||||
return
|
||||
}
|
||||
|
||||
func (_ Logger) SetOption(l log.Logger, store types.KVStore, key, value string, next basecoin.SetOptioner) (string, error) {
|
||||
start := time.Now()
|
||||
res, err := next.SetOption(l, store, key, value)
|
||||
delta := time.Now().Sub(start)
|
||||
// TODO: log the value being set also?
|
||||
l = l.With("duration", micros(delta)).With("key", key)
|
||||
if err == nil {
|
||||
l.Info("SetOption", "log", res)
|
||||
} else {
|
||||
l.Error("SetOption", "err", err)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
// micros returns how many microseconds passed in a call
|
||||
func micros(d time.Duration) int {
|
||||
return int(d.Seconds() * 1000000)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
||||
"github.com/tendermint/basecoin"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
)
|
||||
@@ -37,6 +39,10 @@ func (m *middleware) DeliverTx(ctx basecoin.Context, store types.KVStore, tx bas
|
||||
return m.middleware.DeliverTx(ctx, store, tx, next)
|
||||
}
|
||||
|
||||
func (m *middleware) SetOption(l log.Logger, store types.KVStore, key, value string) (string, error) {
|
||||
return m.middleware.SetOption(l, store, key, value, m.next)
|
||||
}
|
||||
|
||||
// Stack is the entire application stack
|
||||
type Stack struct {
|
||||
middles []Middleware
|
||||
|
||||
@@ -42,8 +42,8 @@ func TestPermissionSandbox(t *testing.T) {
|
||||
for i, tc := range cases {
|
||||
app := New(
|
||||
Recovery{}, // we need this so panics turn to errors
|
||||
GrantMiddleware{tc.grant},
|
||||
CheckMiddleware{tc.require},
|
||||
GrantMiddleware{Auth: tc.grant},
|
||||
CheckMiddleware{Required: tc.require},
|
||||
).Use(EchoHandler{})
|
||||
|
||||
res, err := app.CheckTx(ctx, store, raw)
|
||||
|
||||
@@ -14,7 +14,9 @@ const (
|
||||
NameMultiplexer = "mplx"
|
||||
)
|
||||
|
||||
type Multiplexer struct{}
|
||||
type Multiplexer struct {
|
||||
PassOption
|
||||
}
|
||||
|
||||
func (_ Multiplexer) Name() string {
|
||||
return NameMultiplexer
|
||||
|
||||
@@ -3,6 +3,8 @@ package stack
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
||||
"github.com/tendermint/basecoin"
|
||||
"github.com/tendermint/basecoin/errors"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
@@ -39,6 +41,15 @@ func (_ Recovery) DeliverTx(ctx basecoin.Context, store types.KVStore, tx baseco
|
||||
return next.DeliverTx(ctx, store, tx)
|
||||
}
|
||||
|
||||
func (_ Recovery) SetOption(l log.Logger, store types.KVStore, key, value string, next basecoin.SetOptioner) (log string, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = normalizePanic(r)
|
||||
}
|
||||
}()
|
||||
return next.SetOption(l, store, key, value)
|
||||
}
|
||||
|
||||
// normalizePanic makes sure we can get a nice TMError (with stack) out of it
|
||||
func normalizePanic(p interface{}) error {
|
||||
if err, isErr := p.(error); isErr {
|
||||
|
||||
+3
-1
@@ -13,7 +13,9 @@ const (
|
||||
NameSigs = "sigs"
|
||||
)
|
||||
|
||||
type Signatures struct{}
|
||||
type Signatures struct {
|
||||
PassOption
|
||||
}
|
||||
|
||||
func (_ Signatures) Name() string {
|
||||
return NameSigs
|
||||
|
||||
@@ -58,7 +58,7 @@ func TestSignatureChecks(t *testing.T) {
|
||||
app := New(
|
||||
Recovery{}, // we need this so panics turn to errors
|
||||
Signatures{},
|
||||
CheckMiddleware{tc.check},
|
||||
CheckMiddleware{Required: tc.check},
|
||||
).Use(OKHandler{})
|
||||
|
||||
var tx basecoin.Tx
|
||||
|
||||
Reference in New Issue
Block a user