nonce testing
This commit is contained in:
parent
16b039534d
commit
6e07dbe7c3
|
@ -90,7 +90,7 @@ func doSendTx(cmd *cobra.Command, args []string) error {
|
|||
if seq < 0 {
|
||||
return fmt.Errorf("sequence must be greater than 0")
|
||||
}
|
||||
tx = nonce.NewTx(tx, uint32(seq), nonceAccount) // XXX - what is the nonceAccount here!!!
|
||||
tx = nonce.NewTx(uint32(seq), nonceAccount, tx)
|
||||
|
||||
// Note: this is single sig (no multi sig yet)
|
||||
stx := auth.NewSig(tx)
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
|
||||
var (
|
||||
errDecoding = fmt.Errorf("Error decoding input")
|
||||
errNoAccount = fmt.Errorf("No such account")
|
||||
errUnauthorized = fmt.Errorf("Unauthorized")
|
||||
errInvalidSignature = fmt.Errorf("Invalid Signature")
|
||||
errTooLarge = fmt.Errorf("Input size too large")
|
||||
|
@ -139,17 +138,13 @@ func IsNoChainErr(err error) bool {
|
|||
func ErrNoNonce() TMError {
|
||||
return WithCode(errNoNonce, unauthorized)
|
||||
}
|
||||
func ErrBadNonce() TMError {
|
||||
return WithCode(errBadNonce, unauthorized)
|
||||
func ErrBadNonce(got, expected uint32) TMError {
|
||||
return WithCode(fmt.Errorf("Bad nonce seqence, got %d, expected %d", got, expected), unauthorized)
|
||||
}
|
||||
func ErrNotMember() TMError {
|
||||
return WithCode(errBadNonce, unauthorized)
|
||||
}
|
||||
|
||||
func ErrNoAccount() TMError {
|
||||
return WithCode(errNoAccount, unknownAddress)
|
||||
}
|
||||
|
||||
func ErrWrongChain(chain string) TMError {
|
||||
msg := errors.Wrap(errWrongChain, chain)
|
||||
return WithCode(msg, unauthorized)
|
||||
|
|
|
@ -10,10 +10,10 @@ import (
|
|||
)
|
||||
|
||||
func getSeq(store state.KVStore, key []byte) (seq uint32, err error) {
|
||||
// fmt.Printf("load: %X\n", key)
|
||||
data := store.Get(key)
|
||||
if len(data) == 0 {
|
||||
return seq, errors.ErrNoAccount()
|
||||
//if the key is not stored, its a new key with a sequence of zero!
|
||||
return 0, nil
|
||||
}
|
||||
err = wire.ReadBinaryBytes(data, &seq)
|
||||
if err != nil {
|
||||
|
|
|
@ -20,31 +20,24 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
basecoin.TxMapper.RegisterImplementation(&Tx{}, TypeNonce, ByteNonce)
|
||||
basecoin.TxMapper.RegisterImplementation(Tx{}, TypeNonce, ByteNonce)
|
||||
}
|
||||
|
||||
// Tx - XXX fill in
|
||||
type Tx struct {
|
||||
Tx basecoin.Tx `json:p"tx"`
|
||||
Sequence uint32
|
||||
Signers []basecoin.Actor // or simple []data.Bytes (they are only pubkeys...)
|
||||
seqKey []byte //key to store the sequence number
|
||||
Sequence uint32 `json:"sequence"`
|
||||
Signers []basecoin.Actor `json:"signers"`
|
||||
Tx basecoin.Tx `json:"tx"`
|
||||
}
|
||||
|
||||
var _ basecoin.TxInner = &Tx{}
|
||||
|
||||
// NewTx wraps the tx with a signable nonce
|
||||
func NewTx(tx basecoin.Tx, sequence uint32, signers []basecoin.Actor) basecoin.Tx {
|
||||
|
||||
//Generate the sequence key as the hash of the list of signers, sorted by address
|
||||
sort.Sort(basecoin.ByAddress(signers))
|
||||
seqKey := merkle.SimpleHashFromBinary(signers)
|
||||
|
||||
func NewTx(sequence uint32, signers []basecoin.Actor, tx basecoin.Tx) basecoin.Tx {
|
||||
return (Tx{
|
||||
Tx: tx,
|
||||
Sequence: sequence,
|
||||
Signers: signers,
|
||||
seqKey: seqKey,
|
||||
Tx: tx,
|
||||
}).Wrap()
|
||||
}
|
||||
|
||||
|
@ -59,13 +52,17 @@ func (n Tx) ValidateBasic() error {
|
|||
// CheckIncrementSeq - XXX fill in
|
||||
func (n Tx) CheckIncrementSeq(ctx basecoin.Context, store state.KVStore) error {
|
||||
|
||||
//Generate the sequence key as the hash of the list of signers, sorted by address
|
||||
sort.Sort(basecoin.ByAddress(n.Signers))
|
||||
seqKey := merkle.SimpleHashFromBinary(n.Signers)
|
||||
|
||||
// check the current state
|
||||
cur, err := getSeq(store, n.seqKey)
|
||||
cur, err := getSeq(store, seqKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n.Sequence != cur+1 {
|
||||
return errors.ErrBadNonce()
|
||||
return errors.ErrBadNonce(n.Sequence, cur+1)
|
||||
}
|
||||
|
||||
// make sure they all signed
|
||||
|
@ -76,7 +73,7 @@ func (n Tx) CheckIncrementSeq(ctx basecoin.Context, store state.KVStore) error {
|
|||
}
|
||||
|
||||
//finally increment the sequence by 1
|
||||
err = setSeq(store, n.seqKey, cur+1)
|
||||
err = setSeq(store, seqKey, cur+1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package nonce
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/tendermint/basecoin"
|
||||
"github.com/tendermint/basecoin/stack"
|
||||
"github.com/tendermint/basecoin/state"
|
||||
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
)
|
||||
|
||||
func TestNonce(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
// generic args here...
|
||||
chainID := "my-chain"
|
||||
height := uint64(100)
|
||||
ctx := stack.NewContext(chainID, height, log.NewNopLogger())
|
||||
store := state.NewMemKVStore()
|
||||
|
||||
act1 := basecoin.Actor{ChainID: chainID, App: "fooz", Address: []byte{1, 2, 3, 4}}
|
||||
act2 := basecoin.Actor{ChainID: chainID, App: "fooz", Address: []byte{1, 1, 1, 1}}
|
||||
act3 := basecoin.Actor{ChainID: chainID, App: "fooz", Address: []byte{3, 3, 3, 3}}
|
||||
|
||||
testList := []struct {
|
||||
valid bool
|
||||
seq uint32
|
||||
actors []basecoin.Actor
|
||||
}{
|
||||
{false, 0, []basecoin.Actor{act1}},
|
||||
{true, 1, []basecoin.Actor{act1}},
|
||||
{false, 777, []basecoin.Actor{act1}},
|
||||
{true, 2, []basecoin.Actor{act1}},
|
||||
{false, 0, []basecoin.Actor{act1, act2}},
|
||||
{true, 1, []basecoin.Actor{act1, act2}},
|
||||
{true, 2, []basecoin.Actor{act1, act2}},
|
||||
{true, 3, []basecoin.Actor{act1, act2}},
|
||||
{false, 2, []basecoin.Actor{act1, act2}},
|
||||
{false, 2, []basecoin.Actor{act1, act2, act3}},
|
||||
{true, 1, []basecoin.Actor{act1, act2, act3}},
|
||||
}
|
||||
|
||||
for _, test := range testList {
|
||||
|
||||
tx := NewTx(test.seq, test.actors, basecoin.Tx{})
|
||||
nonceTx, ok := tx.Unwrap().(Tx)
|
||||
require.True(ok)
|
||||
err := nonceTx.CheckIncrementSeq(ctx, store)
|
||||
if test.valid {
|
||||
assert.Nil(err, "%v,%v: %+v", test.seq, test.actors, err)
|
||||
} else {
|
||||
assert.NotNil(err, "%v,%v", test.seq, test.actors)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue