cosmos-sdk/modules/coin/handler_test.go

220 lines
5.7 KiB
Go
Raw Normal View History

2017-06-30 11:26:17 -07:00
package coin
import (
2017-07-03 09:58:28 -07:00
"encoding/json"
2017-06-30 11:26:17 -07:00
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2017-07-03 09:58:28 -07:00
crypto "github.com/tendermint/go-crypto"
"github.com/tendermint/tmlibs/log"
2017-06-30 11:26:17 -07:00
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/modules/auth"
2017-06-30 11:26:17 -07:00
"github.com/tendermint/basecoin/stack"
2017-07-06 05:23:38 -07:00
"github.com/tendermint/basecoin/state"
2017-06-30 11:26:17 -07:00
)
// this makes sure that txs are rejected with invalid data or permissions
func TestHandlerValidation(t *testing.T) {
2017-06-30 11:26:17 -07:00
assert := assert.New(t)
// 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}}
2017-07-06 05:59:45 -07:00
someCoins := Coins{{"atom", 123}}
doubleCoins := Coins{{"atom", 246}}
minusCoins := Coins{{"eth", -34}}
2017-06-30 11:26:17 -07:00
cases := []struct {
valid bool
tx basecoin.Tx
2017-06-30 11:26:17 -07:00
perms []basecoin.Actor
}{
// auth works with different apps
{true,
NewSendTx(
2017-07-12 09:54:07 -07:00
[]TxInput{NewTxInput(addr1, someCoins)},
[]TxOutput{NewTxOutput(addr2, someCoins)}),
2017-06-30 11:26:17 -07:00
[]basecoin.Actor{addr1}},
{true,
NewSendTx(
2017-07-12 09:54:07 -07:00
[]TxInput{NewTxInput(addr2, someCoins)},
[]TxOutput{NewTxOutput(addr1, someCoins)}),
[]basecoin.Actor{addr1, addr2}},
// check multi-input with both sigs
{true,
NewSendTx(
2017-07-12 09:54:07 -07:00
[]TxInput{NewTxInput(addr1, someCoins), NewTxInput(addr2, someCoins)},
[]TxOutput{NewTxOutput(addr1, doubleCoins)}),
2017-06-30 11:26:17 -07:00
[]basecoin.Actor{addr1, addr2}},
// wrong permissions fail
{false,
NewSendTx(
2017-07-12 09:54:07 -07:00
[]TxInput{NewTxInput(addr1, someCoins)},
[]TxOutput{NewTxOutput(addr2, someCoins)}),
2017-06-30 11:26:17 -07:00
[]basecoin.Actor{}},
{false,
NewSendTx(
2017-07-12 09:54:07 -07:00
[]TxInput{NewTxInput(addr1, someCoins)},
[]TxOutput{NewTxOutput(addr2, someCoins)}),
2017-06-30 11:26:17 -07:00
[]basecoin.Actor{addr2}},
{false,
NewSendTx(
2017-07-12 09:54:07 -07:00
[]TxInput{NewTxInput(addr1, someCoins), NewTxInput(addr2, someCoins)},
[]TxOutput{NewTxOutput(addr1, doubleCoins)}),
[]basecoin.Actor{addr1}},
2017-06-30 11:26:17 -07:00
// invalid input fails
{false,
NewSendTx(
2017-07-12 09:54:07 -07:00
[]TxInput{NewTxInput(addr1, minusCoins)},
[]TxOutput{NewTxOutput(addr2, minusCoins)}),
2017-06-30 11:26:17 -07:00
[]basecoin.Actor{addr2}},
}
for i, tc := range cases {
ctx := stack.MockContext("base-chain", 100).WithPermissions(tc.perms...)
_, err := checkTx(ctx, tc.tx)
2017-06-30 11:26:17 -07:00
if tc.valid {
assert.Nil(err, "%d: %+v", i, err)
} else {
assert.NotNil(err, "%d", i)
}
}
}
2017-06-30 11:26:17 -07:00
func TestDeliverTx(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
// some sample settings
addr1 := basecoin.Actor{App: "coin", Address: []byte{1, 2}}
addr2 := basecoin.Actor{App: "role", Address: []byte{7, 8}}
addr3 := basecoin.Actor{App: "coin", Address: []byte{6, 5, 4, 3}}
2017-07-06 05:59:45 -07:00
someCoins := Coins{{"atom", 123}}
moreCoins := Coins{{"atom", 6487}}
diffCoins := moreCoins.Minus(someCoins)
2017-07-06 05:59:45 -07:00
otherCoins := Coins{{"eth", 11}}
mixedCoins := someCoins.Plus(otherCoins)
type money struct {
addr basecoin.Actor
2017-07-06 05:59:45 -07:00
coins Coins
}
cases := []struct {
init []money
tx basecoin.Tx
perms []basecoin.Actor
final []money // nil for error
}{
{
[]money{{addr1, moreCoins}},
NewSendTx(
2017-07-12 09:54:07 -07:00
[]TxInput{NewTxInput(addr1, someCoins)},
[]TxOutput{NewTxOutput(addr2, someCoins)}),
[]basecoin.Actor{addr1},
[]money{{addr1, diffCoins}, {addr2, someCoins}},
},
// simple multi-sig 2 accounts to 1
{
[]money{{addr1, mixedCoins}, {addr2, moreCoins}},
NewSendTx(
2017-07-12 09:54:07 -07:00
[]TxInput{NewTxInput(addr1, otherCoins), NewTxInput(addr2, someCoins)},
[]TxOutput{NewTxOutput(addr3, mixedCoins)}),
[]basecoin.Actor{addr1, addr2},
[]money{{addr1, someCoins}, {addr2, diffCoins}, {addr3, mixedCoins}},
},
// multi-sig with one account sending many times
{
[]money{{addr1, moreCoins.Plus(otherCoins)}},
NewSendTx(
2017-07-12 09:54:07 -07:00
[]TxInput{NewTxInput(addr1, otherCoins), NewTxInput(addr1, someCoins)},
[]TxOutput{NewTxOutput(addr2, mixedCoins)}),
[]basecoin.Actor{addr1},
[]money{{addr1, diffCoins}, {addr2, mixedCoins}},
},
}
h := NewHandler()
for i, tc := range cases {
// setup the cases....
2017-07-06 05:23:38 -07:00
store := state.NewMemKVStore()
for _, m := range tc.init {
acct := Account{Coins: m.coins}
err := storeAccount(store, m.addr.Bytes(), acct)
require.Nil(err, "%d: %+v", i, err)
}
ctx := stack.MockContext("base-chain", 100).WithPermissions(tc.perms...)
_, err := h.DeliverTx(ctx, store, tc.tx)
if len(tc.final) > 0 { // valid
2017-06-30 11:26:17 -07:00
assert.Nil(err, "%d: %+v", i, err)
// make sure the final balances are correct
for _, f := range tc.final {
acct, err := loadAccount(store, f.addr.Bytes())
assert.Nil(err, "%d: %+v", i, err)
assert.Equal(f.coins, acct.Coins)
}
2017-06-30 11:26:17 -07:00
} else {
assert.NotNil(err, "%d", i)
// TODO: make sure balances unchanged!
2017-06-30 11:26:17 -07:00
}
}
2017-07-03 09:58:28 -07:00
}
func TestSetOption(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
// some sample settings
pk := crypto.GenPrivKeySecp256k1().Wrap()
addr := pk.PubKey().Address()
actor := auth.SigPerm(addr)
2017-07-03 09:58:28 -07:00
2017-07-06 05:59:45 -07:00
someCoins := Coins{{"atom", 123}}
otherCoins := Coins{{"eth", 11}}
2017-07-03 09:58:28 -07:00
mixedCoins := someCoins.Plus(otherCoins)
type money struct {
addr basecoin.Actor
2017-07-06 05:59:45 -07:00
coins Coins
2017-07-03 09:58:28 -07:00
}
cases := []struct {
init []GenesisAccount
expected []money
}{
{
[]GenesisAccount{{Address: addr, Balance: mixedCoins}},
[]money{{actor, mixedCoins}},
},
}
h := NewHandler()
l := log.NewNopLogger()
for i, tc := range cases {
2017-07-06 05:23:38 -07:00
store := state.NewMemKVStore()
key := "account"
2017-07-03 09:58:28 -07:00
// set the options
for j, gen := range tc.init {
value, err := json.Marshal(gen)
require.Nil(err, "%d,%d: %+v", i, j, err)
_, err = h.SetOption(l, store, NameCoin, key, string(value))
2017-07-03 09:58:28 -07:00
require.Nil(err)
}
// check state is proper
for _, f := range tc.expected {
acct, err := loadAccount(store, f.addr.Bytes())
2017-07-03 09:58:28 -07:00
assert.Nil(err, "%d: %+v", i, err)
assert.Equal(f.coins, acct.Coins)
}
}
2017-06-30 11:26:17 -07:00
}