From af9ce5b5536b16f4f8ccb32d214b8cd55eb66708 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 10 Jul 2017 11:44:40 +0200 Subject: [PATCH] Add expiration field to ChainTx --- modules/base/chain_test.go | 35 +++++++++++++++++++++++++++++++++-- modules/base/tx.go | 27 +++++++++++++++++++++++---- modules/base/tx_test.go | 2 +- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/modules/base/chain_test.go b/modules/base/chain_test.go index 967c0e91b9..9d69d154fd 100644 --- a/modules/base/chain_test.go +++ b/modules/base/chain_test.go @@ -13,6 +13,37 @@ import ( "github.com/tendermint/basecoin/state" ) +func TestChainValidate(t *testing.T) { + assert := assert.New(t) + raw := stack.NewRawTx([]byte{1, 2, 3, 4}) + + cases := []struct { + name string + expires uint64 + valid bool + }{ + {"hello", 0, true}, + {"one-2-three", 123, true}, + {"super!@#$%@", 0, false}, + {"WISH_2_be", 14, true}, + {"öhhh", 54, false}, + } + + for _, tc := range cases { + tx := NewChainTx(tc.name, tc.expires, raw) + err := tx.ValidateBasic() + if tc.valid { + assert.Nil(err, "%s: %+v", tc.name, err) + } else { + assert.NotNil(err, tc.name) + } + } + + empty := NewChainTx("okay", 0, basecoin.Tx{}) + err := empty.ValidateBasic() + assert.NotNil(err) +} + func TestChain(t *testing.T) { assert := assert.New(t) msg := "got it" @@ -24,8 +55,8 @@ func TestChain(t *testing.T) { valid bool errorMsg string }{ - {NewChainTx(chainID, raw), true, ""}, - {NewChainTx("someone-else", raw), false, "someone-else"}, + {NewChainTx(chainID, 0, raw), true, ""}, + {NewChainTx("someone-else", 0, raw), false, "someone-else"}, {raw, false, "No chain id provided"}, } diff --git a/modules/base/tx.go b/modules/base/tx.go index b4f2cd2b78..30320bedcf 100644 --- a/modules/base/tx.go +++ b/modules/base/tx.go @@ -1,6 +1,11 @@ package base -import "github.com/tendermint/basecoin" +import ( + "regexp" + + "github.com/tendermint/basecoin" + "github.com/tendermint/basecoin/errors" +) // nolint const ( @@ -51,20 +56,34 @@ func (mt MultiTx) ValidateBasic() error { // ChainTx locks this tx to one chainTx, wrap with this before signing type ChainTx struct { - Tx basecoin.Tx `json:"tx"` - ChainID string `json:"chain_id"` + ChainID string `json:"chain_id"` // name of chain, must be [A-Za-z0-9_-]+ + ExpiresAt uint64 `json:"expires_at"` // block height at which it is no longer valid + Tx basecoin.Tx `json:"tx"` } var _ basecoin.TxInner = &ChainTx{} +var ( + chainPattern = regexp.MustCompile("^[A-Za-z0-9_-]+$") +) + //nolint - TxInner Functions -func NewChainTx(chainID string, tx basecoin.Tx) basecoin.Tx { +func NewChainTx(chainID string, expires uint64, tx basecoin.Tx) basecoin.Tx { return (ChainTx{Tx: tx, ChainID: chainID}).Wrap() } func (c ChainTx) Wrap() basecoin.Tx { return basecoin.Tx{c} } func (c ChainTx) ValidateBasic() error { + if c.ChainID == "" { + return errors.ErrNoChain() + } + if !chainPattern.MatchString(c.ChainID) { + return errors.ErrWrongChain(c.ChainID) + } + if c.Tx.Empty() { + return errors.ErrUnknownTxType(c.Tx) + } // TODO: more checks? chainID? return c.Tx.ValidateBasic() } diff --git a/modules/base/tx_test.go b/modules/base/tx_test.go index 215256674d..00bd4ea79c 100644 --- a/modules/base/tx_test.go +++ b/modules/base/tx_test.go @@ -25,7 +25,7 @@ func TestEncoding(t *testing.T) { }{ {raw}, {NewMultiTx(raw, raw2)}, - {NewChainTx("foobar", raw)}, + {NewChainTx("foobar", 0, raw)}, } for idx, tc := range cases {