Add CheckHandler as a helper
This commit is contained in:
parent
7e7f124bc9
commit
9ea34e9c8f
|
@ -18,14 +18,19 @@ const (
|
||||||
|
|
||||||
//nolint
|
//nolint
|
||||||
const (
|
const (
|
||||||
ByteRawTx = 0x1
|
ByteRawTx = 0xF0
|
||||||
|
ByteCheckTx = 0xF1
|
||||||
|
|
||||||
TypeRawTx = "raw"
|
TypeRawTx = "raw"
|
||||||
|
TypeCheckTx = NameCheck + "/tx"
|
||||||
|
|
||||||
rawMaxSize = 2000 * 1000
|
rawMaxSize = 2000 * 1000
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
basecoin.TxMapper.
|
basecoin.TxMapper.
|
||||||
RegisterImplementation(RawTx{}, TypeRawTx, ByteRawTx)
|
RegisterImplementation(RawTx{}, TypeRawTx, ByteRawTx).
|
||||||
|
RegisterImplementation(CheckTx{}, TypeCheckTx, ByteCheckTx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RawTx just contains bytes that can be hex-ified
|
// RawTx just contains bytes that can be hex-ified
|
||||||
|
@ -49,6 +54,24 @@ func (r RawTx) ValidateBasic() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckTx contains a list of permissions to be tested
|
||||||
|
type CheckTx struct {
|
||||||
|
Required []basecoin.Actor
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ basecoin.TxInner = CheckTx{}
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func NewCheckTx(req []basecoin.Actor) basecoin.Tx {
|
||||||
|
return CheckTx{req}.Wrap()
|
||||||
|
}
|
||||||
|
func (c CheckTx) Wrap() basecoin.Tx {
|
||||||
|
return basecoin.Tx{c}
|
||||||
|
}
|
||||||
|
func (CheckTx) ValidateBasic() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// OKHandler just used to return okay to everything
|
// OKHandler just used to return okay to everything
|
||||||
type OKHandler struct {
|
type OKHandler struct {
|
||||||
Log string
|
Log string
|
||||||
|
@ -148,3 +171,34 @@ func (p PanicHandler) DeliverTx(ctx basecoin.Context, store state.KVStore, tx ba
|
||||||
}
|
}
|
||||||
panic(p.Msg)
|
panic(p.Msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckHandler accepts CheckTx and verifies the permissions
|
||||||
|
type CheckHandler struct {
|
||||||
|
PassOption
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name - return handler's name
|
||||||
|
func (CheckHandler) Name() string {
|
||||||
|
return NameCheck
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckTx verifies the permissions
|
||||||
|
func (c CheckHandler) CheckTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
|
||||||
|
check, ok := tx.Unwrap().(CheckTx)
|
||||||
|
if !ok {
|
||||||
|
return res, errors.ErrUnknownTxType(tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, perm := range check.Required {
|
||||||
|
if !ctx.HasPermission(perm) {
|
||||||
|
return res, errors.ErrUnauthorized()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeliverTx verifies the permissions
|
||||||
|
func (c CheckHandler) DeliverTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
|
||||||
|
// until something changes, just do the same as check
|
||||||
|
return c.CheckTx(ctx, store, tx)
|
||||||
|
}
|
||||||
|
|
|
@ -62,3 +62,38 @@ func TestPanic(t *testing.T) {
|
||||||
assert.Panics(func() { fail.CheckTx(ctx, store, tx) })
|
assert.Panics(func() { fail.CheckTx(ctx, store, tx) })
|
||||||
assert.Panics(func() { fail.DeliverTx(ctx, store, tx) })
|
assert.Panics(func() { fail.DeliverTx(ctx, store, tx) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCheck(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
ctx := MockContext("check-chain", 123)
|
||||||
|
store := state.NewMemKVStore()
|
||||||
|
h := CheckHandler{}
|
||||||
|
|
||||||
|
a := basecoin.Actor{App: "foo", Address: []byte("baz")}
|
||||||
|
b := basecoin.Actor{App: "si-ly", Address: []byte("bar")}
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
valid bool
|
||||||
|
signers, required []basecoin.Actor
|
||||||
|
}{
|
||||||
|
{true, []basecoin.Actor{a}, []basecoin.Actor{a}},
|
||||||
|
{true, []basecoin.Actor{a, b}, []basecoin.Actor{a}},
|
||||||
|
{false, []basecoin.Actor{a}, []basecoin.Actor{a, b}},
|
||||||
|
{false, []basecoin.Actor{a}, []basecoin.Actor{b}},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range cases {
|
||||||
|
tx := CheckTx{tc.required}.Wrap()
|
||||||
|
myCtx := ctx.WithPermissions(tc.signers...)
|
||||||
|
_, err := h.CheckTx(myCtx, store, tx)
|
||||||
|
_, err2 := h.DeliverTx(myCtx, store, tx)
|
||||||
|
if tc.valid {
|
||||||
|
assert.Nil(err, "%d: %+v", i, err)
|
||||||
|
assert.Nil(err2, "%d: %+v", i, err2)
|
||||||
|
} else {
|
||||||
|
assert.NotNil(err, "%d", i)
|
||||||
|
assert.NotNil(err2, "%d", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NameCheck = "chck"
|
NameCheck = "check"
|
||||||
NameGrant = "grnt"
|
NameGrant = "grant"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckMiddleware returns an error if the tx doesn't have auth of this
|
// CheckMiddleware returns an error if the tx doesn't have auth of this
|
||||||
|
|
Loading…
Reference in New Issue