From 9db18750be9ae286e03bc9ddcde2663a4e70bab4 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 1 Jun 2017 14:59:19 +0200 Subject: [PATCH] Added ValidateBasic() to all Tx for easy stateless pre-filtering --- errors/common.go | 5 +++++ tx.go | 1 + txs/base.go | 32 ++++++++++++++++++++++++++++++++ txs/sigs.go | 20 ++++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/errors/common.go b/errors/common.go index 3ea5a409e..eedaf8057 100644 --- a/errors/common.go +++ b/errors/common.go @@ -14,6 +14,7 @@ const ( msgInvalidSequence = "Invalid Sequence" msgNoInputs = "No Input Coins" msgNoOutputs = "No Output Coins" + msgTooLarge = "Input size too large" ) func DecodingError() TMError { @@ -43,3 +44,7 @@ func NoInputs() TMError { func NoOutputs() TMError { return New(msgNoOutputs, abci.CodeType_BaseInvalidOutput) } + +func TooLarge() TMError { + return New(msgTooLarge, abci.CodeType_EncodingError) +} diff --git a/tx.go b/tx.go index 5a74a7f90..23e262b90 100644 --- a/tx.go +++ b/tx.go @@ -4,6 +4,7 @@ package basecoin // +gen wrapper:"Tx" type TxInner interface { Wrap() Tx + ValidateBasic() error } // TxLayer provides a standard way to deal with "middleware" tx, diff --git a/txs/base.go b/txs/base.go index f67f09db1..d7ecdb349 100644 --- a/txs/base.go +++ b/txs/base.go @@ -2,6 +2,7 @@ package txs import ( "github.com/tendermint/basecoin" + "github.com/tendermint/basecoin/errors" "github.com/tendermint/basecoin/types" "github.com/tendermint/go-wire/data" ) @@ -30,6 +31,10 @@ const ( TypeMultiSig = "multisig" ) +const ( + rawMaxSize = 2000 * 1000 +) + func init() { basecoin.TxMapper. RegisterImplementation(Raw{}, TypeRaw, ByteRaw). @@ -47,6 +52,13 @@ func (r Raw) Wrap() basecoin.Tx { return basecoin.Tx{r} } +func (r Raw) ValidateBasic() error { + if len(r.Bytes) > rawMaxSize { + return errors.TooLarge() + } + return nil +} + func NewRaw(d []byte) Raw { return Raw{data.Bytes(d)} } @@ -65,6 +77,11 @@ func NewFee(tx basecoin.Tx, fee types.Coin, addr []byte) *Fee { return &Fee{Tx: tx, Fee: fee, Payer: addr} } +func (f *Fee) ValidateBasic() error { + // TODO: more checks + return f.Tx.ValidateBasic() +} + func (f *Fee) Wrap() basecoin.Tx { return basecoin.Tx{f} } @@ -82,6 +99,16 @@ func (mt *MultiTx) Wrap() basecoin.Tx { return basecoin.Tx{mt} } +func (mt *MultiTx) ValidateBasic() error { + for _, t := range mt.Txs { + err := t.ValidateBasic() + if err != nil { + return err + } + } + return nil +} + /*** Chain ****/ // Chain locks this tx to one chain, wrap with this before signing @@ -97,3 +124,8 @@ func NewChain(tx basecoin.Tx, chainID string) *Chain { func (c *Chain) Wrap() basecoin.Tx { return basecoin.Tx{c} } + +func (c *Chain) ValidateBasic() error { + // TODO: more checks? chainID? + return c.Tx.ValidateBasic() +} diff --git a/txs/sigs.go b/txs/sigs.go index c8ed07ac0..8336bb7c0 100644 --- a/txs/sigs.go +++ b/txs/sigs.go @@ -14,6 +14,7 @@ a basecoin.Tx. package txs import ( + // TODO: merge in usage of pkg/errors into basecoin/errors and remove this "github.com/pkg/errors" crypto "github.com/tendermint/go-crypto" @@ -21,6 +22,7 @@ import ( "github.com/tendermint/go-wire/data" "github.com/tendermint/basecoin" + berrs "github.com/tendermint/basecoin/errors" ) // Signed holds one signature of the data @@ -59,6 +61,14 @@ func (s *OneSig) Wrap() basecoin.Tx { return basecoin.Tx{s} } +func (s *OneSig) ValidateBasic() error { + // TODO: VerifyBytes here, we do it in Signers? + if s.Empty() || !s.Pubkey.VerifyBytes(s.SignBytes(), s.Sig) { + return berrs.Unauthorized() + } + return s.Tx.ValidateBasic() +} + // TxBytes returns the full data with signatures func (s *OneSig) TxBytes() ([]byte, error) { return data.ToWire(s) @@ -121,6 +131,16 @@ func (s *MultiSig) Wrap() basecoin.Tx { return basecoin.Tx{s} } +func (s *MultiSig) ValidateBasic() error { + // TODO: more efficient + _, err := s.Signers() + if err != nil { + // TODO: better return value + return berrs.Unauthorized() + } + return s.Tx.ValidateBasic() +} + // TxBytes returns the full data with signatures func (s *MultiSig) TxBytes() ([]byte, error) { return data.ToWire(s)