From 50e4d31149a2155ee205622ce67b39eb48c26d20 Mon Sep 17 00:00:00 2001 From: rigel rozanski Date: Tue, 11 Jul 2017 20:00:39 -0400 Subject: [PATCH] working nonce module --- app/app.go | 2 ++ cmd/basecli/commands/cmds.go | 4 +++ modules/nonce/replaycheck.go | 45 +++++++++++++++++++++++ modules/nonce/tx.go | 69 ++++++++++++++++++++++++++++++++++++ 4 files changed, 120 insertions(+) create mode 100644 modules/nonce/replaycheck.go create mode 100644 modules/nonce/tx.go diff --git a/app/app.go b/app/app.go index 836e8c66f..313c71933 100644 --- a/app/app.go +++ b/app/app.go @@ -15,6 +15,7 @@ import ( "github.com/tendermint/basecoin/modules/base" "github.com/tendermint/basecoin/modules/coin" "github.com/tendermint/basecoin/modules/fee" + "github.com/tendermint/basecoin/modules/nonce" "github.com/tendermint/basecoin/stack" sm "github.com/tendermint/basecoin/state" "github.com/tendermint/basecoin/version" @@ -61,6 +62,7 @@ func DefaultHandler(feeDenom string) basecoin.Handler { base.Logger{}, stack.Recovery{}, auth.Signatures{}, + nonce.ReplayCheck{}, base.Chain{}, fee.NewSimpleFeeMiddleware(coin.Coin{feeDenom, 0}, fee.Bank), ).Use(d) diff --git a/cmd/basecli/commands/cmds.go b/cmd/basecli/commands/cmds.go index 631c371d6..d069a838a 100644 --- a/cmd/basecli/commands/cmds.go +++ b/cmd/basecli/commands/cmds.go @@ -17,6 +17,7 @@ import ( "github.com/tendermint/basecoin/modules/base" "github.com/tendermint/basecoin/modules/coin" "github.com/tendermint/basecoin/modules/fee" + "github.com/tendermint/basecoin/modules/nonce" ) //------------------------- @@ -74,6 +75,9 @@ func doSendTx(cmd *cobra.Command, args []string) error { return err } + // XXX - what is the nonceAccount here!!! + tx = nonce.NewTx(tx, viper.GetInt(FlagSequence), nonceAccount) + // Note: this is single sig (no multi sig yet) stx := auth.NewSig(tx) diff --git a/modules/nonce/replaycheck.go b/modules/nonce/replaycheck.go new file mode 100644 index 000000000..9e75f0b18 --- /dev/null +++ b/modules/nonce/replaycheck.go @@ -0,0 +1,45 @@ +package nonce + +import ( + "github.com/tendermint/basecoin" + "github.com/tendermint/basecoin/stack" + "github.com/tendermint/basecoin/state" +) + +//nolint +const ( + NameNonce = "nonce" +) + +// ReplayCheck parses out go-crypto signatures and adds permissions to the +// context for use inside the application +type ReplayCheck struct { + stack.PassOption +} + +// Name of the module - fulfills Middleware interface +func (ReplayCheck) Name() string { + return NameNonce +} + +var _ stack.Middleware = ReplayCheck{} + +// CheckTx verifies the signatures are correct - fulfills Middlware interface +func (ReplayCheck) CheckTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx, next basecoin.Checker) (res basecoin.Result, err error) { + sigs, tnext, err := getSigners(tx) + if err != nil { + return res, err + } + ctx2 := addSigners(ctx, sigs) + return next.CheckTx(ctx2, store, tnext) +} + +// DeliverTx verifies the signatures are correct - fulfills Middlware interface +func (ReplayCheck) DeliverTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx, next basecoin.Deliver) (res basecoin.Result, err error) { + sigs, tnext, err := getSigners(tx) + if err != nil { + return res, err + } + ctx2 := addSigners(ctx, sigs) + return next.DeliverTx(ctx2, store, tnext) +} diff --git a/modules/nonce/tx.go b/modules/nonce/tx.go new file mode 100644 index 000000000..741340cfd --- /dev/null +++ b/modules/nonce/tx.go @@ -0,0 +1,69 @@ +/* +Package nonce XXX +*/ +package nonce + +import ( + "github.com/tendermint/basecoin/state" + + "github.com/tendermint/basecoin" +) + +// nolint +const ( + // for signatures + ByteSingleTx = 0x16 + ByteMultiSig = 0x17 +) + +/**** Registration ****/ + +//func init() { +//basecoin.TxMapper.RegisterImplementation(&Tx{}, TypeSingleTx, ByteSingleTx) +//} + +// 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...) +} + +var _ basecoin.TxInner = &Tx{} + +// NewTx wraps the tx with a signable nonce +func NewTx(tx basecoin.Tx, sequence uint32, signers []basecoin.Actor) *Tx { + return &Tx{ + Tx: tx, + Sequence: sequence, + Signers: signers, + } +} + +//nolint +func (n *Tx) Wrap() basecoin.Tx { + return basecoin.Tx{s} +} +func (n *Tx) ValidateBasic() error { + return s.Tx.ValidateBasic() +} + +// CheckSequence - XXX fill in +func (n *Tx) CheckSequence(ctx basecoin.Context, store state.KVStore) error { + + // check the current state + h := hash(Sort(n.Signers)) + cur := loadSeq(store, h) + if n.Sequence != cur+1 { + return ErrBadNonce() + } + + // make sure they all signed + for _, s := range n.Signers { + if !ctx.HasPermission(s) { + return ErrNotMember() + } + } + + return nil +}