More thorough tests on coin module
This commit is contained in:
parent
27a31953f9
commit
673b51f3b0
|
@ -43,21 +43,21 @@ func (h Handler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoi
|
|||
return basecoin.Result{}, nil
|
||||
}
|
||||
|
||||
func checkTx(ctx basecoin.Context, tx basecoin.Tx) (*SendTx, error) {
|
||||
func checkTx(ctx basecoin.Context, tx basecoin.Tx) (send SendTx, err error) {
|
||||
// check if the tx is proper type and valid
|
||||
send, ok := tx.Unwrap().(*SendTx)
|
||||
send, ok := tx.Unwrap().(SendTx)
|
||||
if !ok {
|
||||
return nil, errors.UnknownTxType(tx)
|
||||
return send, errors.UnknownTxType(tx)
|
||||
}
|
||||
err := send.ValidateBasic()
|
||||
err = send.ValidateBasic()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return send, err
|
||||
}
|
||||
|
||||
// check if all inputs have permission
|
||||
for _, in := range send.Inputs {
|
||||
if !ctx.HasPermission(in.Address) {
|
||||
return nil, errors.Unauthorized()
|
||||
return send, errors.Unauthorized()
|
||||
}
|
||||
}
|
||||
return send, nil
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package coin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tendermint/basecoin"
|
||||
"github.com/tendermint/basecoin/stack"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
)
|
||||
|
||||
func TestHandlerPermissions(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
// TODO: need to update this when we actually have token store
|
||||
h := Handler{}
|
||||
|
||||
// these are all valid, except for minusCoins
|
||||
addr1 := basecoin.Actor{App: "coin", Address: []byte{1, 2}}
|
||||
addr2 := basecoin.Actor{App: "role", Address: []byte{7, 8}}
|
||||
someCoins := types.Coins{{"atom", 123}}
|
||||
minusCoins := types.Coins{{"eth", -34}}
|
||||
|
||||
cases := []struct {
|
||||
valid bool
|
||||
tx SendTx
|
||||
perms []basecoin.Actor
|
||||
}{
|
||||
// auth works with different apps
|
||||
{true,
|
||||
SendTx{
|
||||
Inputs: []TxInput{NewTxInput(addr1, someCoins, 2)},
|
||||
Outputs: []TxOutput{NewTxOutput(addr2, someCoins)}},
|
||||
[]basecoin.Actor{addr1}},
|
||||
{true,
|
||||
SendTx{
|
||||
Inputs: []TxInput{NewTxInput(addr2, someCoins, 2)},
|
||||
Outputs: []TxOutput{NewTxOutput(addr1, someCoins)}},
|
||||
[]basecoin.Actor{addr1, addr2}},
|
||||
// wrong permissions fail
|
||||
{false,
|
||||
SendTx{
|
||||
Inputs: []TxInput{NewTxInput(addr1, someCoins, 2)},
|
||||
Outputs: []TxOutput{NewTxOutput(addr2, someCoins)}},
|
||||
[]basecoin.Actor{}},
|
||||
{false,
|
||||
SendTx{
|
||||
Inputs: []TxInput{NewTxInput(addr1, someCoins, 2)},
|
||||
Outputs: []TxOutput{NewTxOutput(addr2, someCoins)}},
|
||||
[]basecoin.Actor{addr2}},
|
||||
// invalid input fails
|
||||
{false,
|
||||
SendTx{
|
||||
Inputs: []TxInput{NewTxInput(addr1, minusCoins, 2)},
|
||||
Outputs: []TxOutput{NewTxOutput(addr2, minusCoins)}},
|
||||
[]basecoin.Actor{addr2}},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
ctx := stack.MockContext().WithPermissions(tc.perms...)
|
||||
_, err := h.CheckTx(ctx, nil, tc.tx.Wrap())
|
||||
if tc.valid {
|
||||
assert.Nil(err, "%d: %+v", i, err)
|
||||
} else {
|
||||
assert.NotNil(err, "%d", i)
|
||||
}
|
||||
|
||||
_, err = h.DeliverTx(ctx, nil, tc.tx.Wrap())
|
||||
if tc.valid {
|
||||
assert.Nil(err, "%d: %+v", i, err)
|
||||
} else {
|
||||
assert.NotNil(err, "%d", i)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -9,6 +9,16 @@ import (
|
|||
"github.com/tendermint/basecoin/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
basecoin.TxMapper.RegisterImplementation(SendTx{}, TypeSend, ByteSend)
|
||||
}
|
||||
|
||||
// we reserve the 0x20-0x3f range for standard modules
|
||||
const (
|
||||
ByteSend = 0x20
|
||||
TypeSend = "send"
|
||||
)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type TxInput struct {
|
||||
|
|
|
@ -4,8 +4,10 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/basecoin"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
)
|
||||
|
||||
// these are some constructs for the test cases
|
||||
|
@ -169,5 +171,33 @@ func TestTxValidateTx(t *testing.T) {
|
|||
assert.NotNil(err, "%d", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTxSerializeTx(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
addr1 := basecoin.Actor{App: "coin", Address: []byte{1, 2}}
|
||||
addr2 := basecoin.Actor{App: "coin", Address: []byte{3, 4}}
|
||||
someCoins := types.Coins{{"atom", 123}}
|
||||
|
||||
send := SendTx{
|
||||
Inputs: []TxInput{NewTxInput(addr1, someCoins, 2)},
|
||||
Outputs: []TxOutput{NewTxOutput(addr2, someCoins)},
|
||||
}.Wrap()
|
||||
|
||||
js, err := data.ToJSON(send)
|
||||
require.Nil(err)
|
||||
var tx basecoin.Tx
|
||||
err = data.FromJSON(js, &tx)
|
||||
require.Nil(err)
|
||||
assert.Equal(send, tx)
|
||||
|
||||
bin, err := data.ToWire(send)
|
||||
require.Nil(err)
|
||||
var tx2 basecoin.Tx
|
||||
err = data.FromWire(bin, &tx2)
|
||||
require.Nil(err)
|
||||
assert.Equal(send, tx2)
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package stack
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
||||
"github.com/tendermint/basecoin"
|
||||
)
|
||||
|
||||
type mockContext struct {
|
||||
perms []basecoin.Actor
|
||||
log.Logger
|
||||
}
|
||||
|
||||
func MockContext() basecoin.Context {
|
||||
return mockContext{
|
||||
Logger: log.NewNopLogger(),
|
||||
}
|
||||
}
|
||||
|
||||
var _ basecoin.Context = mockContext{}
|
||||
|
||||
// WithPermissions will panic if they try to set permission without the proper app
|
||||
func (c mockContext) WithPermissions(perms ...basecoin.Actor) basecoin.Context {
|
||||
return mockContext{
|
||||
perms: append(c.perms, perms...),
|
||||
Logger: c.Logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (c mockContext) HasPermission(perm basecoin.Actor) bool {
|
||||
for _, p := range c.perms {
|
||||
if perm.App == p.App && bytes.Equal(perm.Address, p.Address) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsParent ensures that this is derived from the given secureClient
|
||||
func (c mockContext) IsParent(other basecoin.Context) bool {
|
||||
_, ok := other.(mockContext)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Reset should clear out all permissions,
|
||||
// but carry on knowledge that this is a child
|
||||
func (c mockContext) Reset() basecoin.Context {
|
||||
return mockContext{
|
||||
Logger: c.Logger,
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue