Added ValidateBasic() to all Tx for easy stateless pre-filtering

This commit is contained in:
Ethan Frey 2017-06-01 14:59:19 +02:00
parent 2c9123224e
commit 9db18750be
4 changed files with 58 additions and 0 deletions

View File

@ -14,6 +14,7 @@ const (
msgInvalidSequence = "Invalid Sequence" msgInvalidSequence = "Invalid Sequence"
msgNoInputs = "No Input Coins" msgNoInputs = "No Input Coins"
msgNoOutputs = "No Output Coins" msgNoOutputs = "No Output Coins"
msgTooLarge = "Input size too large"
) )
func DecodingError() TMError { func DecodingError() TMError {
@ -43,3 +44,7 @@ func NoInputs() TMError {
func NoOutputs() TMError { func NoOutputs() TMError {
return New(msgNoOutputs, abci.CodeType_BaseInvalidOutput) return New(msgNoOutputs, abci.CodeType_BaseInvalidOutput)
} }
func TooLarge() TMError {
return New(msgTooLarge, abci.CodeType_EncodingError)
}

1
tx.go
View File

@ -4,6 +4,7 @@ package basecoin
// +gen wrapper:"Tx" // +gen wrapper:"Tx"
type TxInner interface { type TxInner interface {
Wrap() Tx Wrap() Tx
ValidateBasic() error
} }
// TxLayer provides a standard way to deal with "middleware" tx, // TxLayer provides a standard way to deal with "middleware" tx,

View File

@ -2,6 +2,7 @@ package txs
import ( import (
"github.com/tendermint/basecoin" "github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/errors"
"github.com/tendermint/basecoin/types" "github.com/tendermint/basecoin/types"
"github.com/tendermint/go-wire/data" "github.com/tendermint/go-wire/data"
) )
@ -30,6 +31,10 @@ const (
TypeMultiSig = "multisig" TypeMultiSig = "multisig"
) )
const (
rawMaxSize = 2000 * 1000
)
func init() { func init() {
basecoin.TxMapper. basecoin.TxMapper.
RegisterImplementation(Raw{}, TypeRaw, ByteRaw). RegisterImplementation(Raw{}, TypeRaw, ByteRaw).
@ -47,6 +52,13 @@ func (r Raw) Wrap() basecoin.Tx {
return basecoin.Tx{r} return basecoin.Tx{r}
} }
func (r Raw) ValidateBasic() error {
if len(r.Bytes) > rawMaxSize {
return errors.TooLarge()
}
return nil
}
func NewRaw(d []byte) Raw { func NewRaw(d []byte) Raw {
return Raw{data.Bytes(d)} 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} 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 { func (f *Fee) Wrap() basecoin.Tx {
return basecoin.Tx{f} return basecoin.Tx{f}
} }
@ -82,6 +99,16 @@ func (mt *MultiTx) Wrap() basecoin.Tx {
return basecoin.Tx{mt} 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 ****/
// Chain locks this tx to one chain, wrap with this before signing // 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 { func (c *Chain) Wrap() basecoin.Tx {
return basecoin.Tx{c} return basecoin.Tx{c}
} }
func (c *Chain) ValidateBasic() error {
// TODO: more checks? chainID?
return c.Tx.ValidateBasic()
}

View File

@ -14,6 +14,7 @@ a basecoin.Tx.
package txs package txs
import ( import (
// TODO: merge in usage of pkg/errors into basecoin/errors and remove this
"github.com/pkg/errors" "github.com/pkg/errors"
crypto "github.com/tendermint/go-crypto" crypto "github.com/tendermint/go-crypto"
@ -21,6 +22,7 @@ import (
"github.com/tendermint/go-wire/data" "github.com/tendermint/go-wire/data"
"github.com/tendermint/basecoin" "github.com/tendermint/basecoin"
berrs "github.com/tendermint/basecoin/errors"
) )
// Signed holds one signature of the data // Signed holds one signature of the data
@ -59,6 +61,14 @@ func (s *OneSig) Wrap() basecoin.Tx {
return basecoin.Tx{s} 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 // TxBytes returns the full data with signatures
func (s *OneSig) TxBytes() ([]byte, error) { func (s *OneSig) TxBytes() ([]byte, error) {
return data.ToWire(s) return data.ToWire(s)
@ -121,6 +131,16 @@ func (s *MultiSig) Wrap() basecoin.Tx {
return basecoin.Tx{s} 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 // TxBytes returns the full data with signatures
func (s *MultiSig) TxBytes() ([]byte, error) { func (s *MultiSig) TxBytes() ([]byte, error) {
return data.ToWire(s) return data.ToWire(s)