cosmos-sdk/modules/nonce/tx.go

95 lines
2.3 KiB
Go
Raw Normal View History

2017-07-11 17:00:39 -07:00
/*
Package nonce XXX
*/
package nonce
import (
2017-07-12 02:02:16 -07:00
"sort"
2017-07-11 17:00:39 -07:00
"github.com/tendermint/basecoin"
2017-07-12 02:02:16 -07:00
"github.com/tendermint/basecoin/errors"
"github.com/tendermint/basecoin/state"
"github.com/tendermint/tmlibs/merkle"
2017-07-11 17:00:39 -07:00
)
// nolint
const (
2017-07-12 02:02:16 -07:00
ByteNonce = 0x69 //TODO overhaul byte assign system don't make no sense!
TypeNonce = "nonce"
2017-07-11 17:00:39 -07:00
)
2017-07-12 02:02:16 -07:00
func init() {
2017-07-12 03:10:17 -07:00
basecoin.TxMapper.RegisterImplementation(Tx{}, TypeNonce, ByteNonce)
2017-07-12 02:02:16 -07:00
}
2017-07-11 17:00:39 -07:00
// Tx - XXX fill in
type Tx struct {
2017-07-12 03:10:17 -07:00
Sequence uint32 `json:"sequence"`
Signers []basecoin.Actor `json:"signers"`
Tx basecoin.Tx `json:"tx"`
2017-07-11 17:00:39 -07:00
}
var _ basecoin.TxInner = &Tx{}
// NewTx wraps the tx with a signable nonce
2017-07-12 03:10:17 -07:00
func NewTx(sequence uint32, signers []basecoin.Actor, tx basecoin.Tx) basecoin.Tx {
2017-07-12 02:02:16 -07:00
return (Tx{
2017-07-11 17:00:39 -07:00
Sequence: sequence,
Signers: signers,
2017-07-12 03:10:17 -07:00
Tx: tx,
2017-07-12 02:02:16 -07:00
}).Wrap()
2017-07-11 17:00:39 -07:00
}
//nolint
2017-07-12 02:02:16 -07:00
func (n Tx) Wrap() basecoin.Tx {
return basecoin.Tx{n}
2017-07-11 17:00:39 -07:00
}
2017-07-12 02:02:16 -07:00
func (n Tx) ValidateBasic() error {
2017-07-12 06:19:37 -07:00
// rigel: check if Sequence == 0, len(Signers) == 0, or Tx.Empty()
// these are all invalid, regardless of the state
// (also add max sequence number to prevent overflow?)
2017-07-12 02:02:16 -07:00
return n.Tx.ValidateBasic()
2017-07-11 17:00:39 -07:00
}
2017-07-12 02:02:16 -07:00
// CheckIncrementSeq - XXX fill in
func (n Tx) CheckIncrementSeq(ctx basecoin.Context, store state.KVStore) error {
2017-07-11 17:00:39 -07:00
2017-07-12 06:19:37 -07:00
// rigel: nice with the sort, problem is this modifies the TX in place...
// if we reserialize the tx after this function, it will be a different
// representations... copy n.Signers before sorting them please
2017-07-12 03:10:17 -07:00
//Generate the sequence key as the hash of the list of signers, sorted by address
sort.Sort(basecoin.ByAddress(n.Signers))
2017-07-12 06:19:37 -07:00
// rigel: nice sort, no need for a merkle hash... something simpler also works
2017-07-12 03:10:17 -07:00
seqKey := merkle.SimpleHashFromBinary(n.Signers)
2017-07-11 17:00:39 -07:00
// check the current state
2017-07-12 03:10:17 -07:00
cur, err := getSeq(store, seqKey)
2017-07-12 02:02:16 -07:00
if err != nil {
return err
}
2017-07-11 17:00:39 -07:00
if n.Sequence != cur+1 {
2017-07-12 03:10:17 -07:00
return errors.ErrBadNonce(n.Sequence, cur+1)
2017-07-11 17:00:39 -07:00
}
// make sure they all signed
for _, s := range n.Signers {
if !ctx.HasPermission(s) {
2017-07-12 02:02:16 -07:00
return errors.ErrNotMember()
2017-07-11 17:00:39 -07:00
}
}
2017-07-12 06:19:37 -07:00
// rigel: this should be separate. we check the sequence on CheckTx and DeliverTx
// BEFORE we execute the wrapped tx.
// we increment the sequence in DeliverTx AFTER it returns success (not on error)
2017-07-12 02:02:16 -07:00
//finally increment the sequence by 1
2017-07-12 03:10:17 -07:00
err = setSeq(store, seqKey, cur+1)
2017-07-12 02:02:16 -07:00
if err != nil {
return err
}
2017-07-11 17:00:39 -07:00
return nil
}