From 31b8abf58aa9d20a0248e04bf59042e8b922cdb7 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 23 Oct 2017 22:17:09 +0200 Subject: [PATCH] module eyes works --- handler.go | 13 ++++++ modules/eyes/_gen.go | 6 +++ modules/eyes/eyestxinner_wrapper.go | 62 +++++++++++++++++++++++++++++ modules/eyes/handler.go | 46 ++++++++++----------- modules/eyes/handler_test.go | 15 ++++--- modules/eyes/tx.go | 39 ++++++------------ 6 files changed, 126 insertions(+), 55 deletions(-) create mode 100644 modules/eyes/_gen.go create mode 100644 modules/eyes/eyestxinner_wrapper.go diff --git a/handler.go b/handler.go index a9dd5404a..ae7906029 100644 --- a/handler.go +++ b/handler.go @@ -90,3 +90,16 @@ func MustGetTx(msg interface{}) interface{} { m := msg.(Msg) return m.GetTx() } + +// WrapTx embeds the tx into a Msg interface, with no decorator info +func WrapTx(tx interface{}) Msg { + return msg{tx} +} + +type msg struct { + tx interface{} +} + +func (m msg) GetTx() interface{} { + return m.tx +} diff --git a/modules/eyes/_gen.go b/modules/eyes/_gen.go new file mode 100644 index 000000000..a98feaf4e --- /dev/null +++ b/modules/eyes/_gen.go @@ -0,0 +1,6 @@ +package main + +import ( + _ "github.com/tendermint/go-wire/gen" + _ "github.com/clipperhouse/stringer" +) diff --git a/modules/eyes/eyestxinner_wrapper.go b/modules/eyes/eyestxinner_wrapper.go new file mode 100644 index 000000000..f93704ab8 --- /dev/null +++ b/modules/eyes/eyestxinner_wrapper.go @@ -0,0 +1,62 @@ +// Generated by: main +// TypeWriter: wrapper +// Directive: +gen on EyesTxInner + +package eyes + +import ( + "github.com/tendermint/go-wire/data" +) + +// Auto-generated adapters for happily unmarshaling interfaces +// Apache License 2.0 +// Copyright (c) 2017 Ethan Frey (ethan.frey@tendermint.com) + +type EyesTx struct { + EyesTxInner "json:\"unwrap\"" +} + +var EyesTxMapper = data.NewMapper(EyesTx{}) + +func (h EyesTx) MarshalJSON() ([]byte, error) { + return EyesTxMapper.ToJSON(h.EyesTxInner) +} + +func (h *EyesTx) UnmarshalJSON(data []byte) (err error) { + parsed, err := EyesTxMapper.FromJSON(data) + if err == nil && parsed != nil { + h.EyesTxInner = parsed.(EyesTxInner) + } + return err +} + +// Unwrap recovers the concrete interface safely (regardless of levels of embeds) +func (h EyesTx) Unwrap() EyesTxInner { + hi := h.EyesTxInner + for wrap, ok := hi.(EyesTx); ok; wrap, ok = hi.(EyesTx) { + hi = wrap.EyesTxInner + } + return hi +} + +func (h EyesTx) Empty() bool { + return h.EyesTxInner == nil +} + +/*** below are bindings for each implementation ***/ + +func init() { + EyesTxMapper.RegisterImplementation(SetTx{}, "set", 0x1) +} + +func (hi SetTx) Wrap() EyesTx { + return EyesTx{hi} +} + +func init() { + EyesTxMapper.RegisterImplementation(RemoveTx{}, "remove", 0x2) +} + +func (hi RemoveTx) Wrap() EyesTx { + return EyesTx{hi} +} diff --git a/modules/eyes/handler.go b/modules/eyes/handler.go index 34a54877e..4b8ab3f91 100644 --- a/modules/eyes/handler.go +++ b/modules/eyes/handler.go @@ -6,13 +6,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk" "github.com/cosmos/cosmos-sdk/errors" - "github.com/cosmos/cosmos-sdk/state" ) const ( - // Name of the module for registering it + // Name is used to register this module Name = "eyes" - // CostSet is the gas needed for the set operation CostSet uint64 = 10 // CostRemove is the gas needed for the remove operation @@ -20,9 +18,7 @@ const ( ) // Handler allows us to set and remove data -type Handler struct { - sdk.NopInitValidate -} +type Handler struct{} var _ sdk.Handler = Handler{} @@ -31,14 +27,10 @@ func NewHandler() Handler { return Handler{} } -// Name - return name space -func (Handler) Name() string { - return Name -} - -// InitState - sets the genesis state -func (h Handler) InitState(l log.Logger, store state.SimpleDB, +// InitState - sets the genesis state - implements InitStater +func (h Handler) InitState(l log.Logger, store sdk.SimpleDB, module, key, value string) (log string, err error) { + if module != Name { return "", errors.ErrUnknownModule(module) } @@ -47,10 +39,12 @@ func (h Handler) InitState(l log.Logger, store state.SimpleDB, } // CheckTx verifies if the transaction is properly formated -func (h Handler) CheckTx(ctx sdk.Context, store state.SimpleDB, tx sdk.Tx) (res sdk.CheckResult, err error) { - err = tx.ValidateBasic() - if err != nil { - return +func (h Handler) CheckTx(ctx sdk.Context, store sdk.SimpleDB, + msg interface{}) (res sdk.CheckResult, err error) { + + tx := sdk.MustGetTx(msg).(EyesTx) + if err := tx.ValidateBasic(); err != nil { + return res, err } switch tx.Unwrap().(type) { @@ -67,10 +61,12 @@ func (h Handler) CheckTx(ctx sdk.Context, store state.SimpleDB, tx sdk.Tx) (res // DeliverTx tries to create a new role. // // Returns an error if the role already exists -func (h Handler) DeliverTx(ctx sdk.Context, store state.SimpleDB, tx sdk.Tx) (res sdk.DeliverResult, err error) { - err = tx.ValidateBasic() - if err != nil { - return +func (h Handler) DeliverTx(ctx sdk.Context, store sdk.SimpleDB, + msg interface{}) (res sdk.DeliverResult, err error) { + + tx := sdk.MustGetTx(msg).(EyesTx) + if err := tx.ValidateBasic(); err != nil { + return res, err } switch t := tx.Unwrap().(type) { @@ -86,7 +82,9 @@ func (h Handler) DeliverTx(ctx sdk.Context, store state.SimpleDB, tx sdk.Tx) (re // doSetTx writes to the store, overwriting any previous value // note that an empty response in DeliverTx is OK with no log or data returned -func (h Handler) doSetTx(ctx sdk.Context, store state.SimpleDB, tx SetTx) (res sdk.DeliverResult, err error) { +func (h Handler) doSetTx(ctx sdk.Context, store sdk.SimpleDB, + tx SetTx) (res sdk.DeliverResult, err error) { + data := NewData(tx.Value, ctx.BlockHeight()) store.Set(tx.Key, wire.BinaryBytes(data)) return @@ -94,7 +92,9 @@ func (h Handler) doSetTx(ctx sdk.Context, store state.SimpleDB, tx SetTx) (res s // doRemoveTx deletes the value from the store and returns the last value // here we let res.Data to return the value over abci -func (h Handler) doRemoveTx(ctx sdk.Context, store state.SimpleDB, tx RemoveTx) (res sdk.DeliverResult, err error) { +func (h Handler) doRemoveTx(ctx sdk.Context, store sdk.SimpleDB, + tx RemoveTx) (res sdk.DeliverResult, err error) { + // we set res.Data so it gets returned to the client over the abci interface res.Data = store.Get(tx.Key) if len(res.Data) != 0 { diff --git a/modules/eyes/handler_test.go b/modules/eyes/handler_test.go index 1e44ae438..0cc688a2b 100644 --- a/modules/eyes/handler_test.go +++ b/modules/eyes/handler_test.go @@ -5,9 +5,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/stack" - "github.com/cosmos/cosmos-sdk/state" + wire "github.com/tendermint/go-wire" + + sdk "github.com/cosmos/cosmos-sdk" + "github.com/cosmos/cosmos-sdk/state" + "github.com/cosmos/cosmos-sdk/util" ) func TestHandler(t *testing.T) { @@ -18,12 +21,12 @@ func TestHandler(t *testing.T) { var height uint64 = 123 h := NewHandler() - ctx := stack.MockContext("role-chain", height) + ctx := util.MockContext("role-chain", height) store := state.NewMemKVStore() - set := SetTx{Key: key, Value: val}.Wrap() - remove := RemoveTx{Key: key}.Wrap() - invalid := SetTx{}.Wrap() + set := sdk.WrapTx(NewSetTx(key, val)) + remove := sdk.WrapTx(NewRemoveTx(key)) + invalid := sdk.WrapTx(NewSetTx(nil, nil)) // make sure pricing makes sense cres, err := h.CheckTx(ctx, store, set) diff --git a/modules/eyes/tx.go b/modules/eyes/tx.go index 8fe25c2ea..db83ad295 100644 --- a/modules/eyes/tx.go +++ b/modules/eyes/tx.go @@ -1,40 +1,32 @@ package eyes import ( - sdk "github.com/cosmos/cosmos-sdk" "github.com/tendermint/go-wire/data" ) -// nolint -const ( - TypeSet = Name + "/set" - TypeRemove = Name + "/remove" - - ByteSet = 0xF4 - ByteRemove = 0xF5 -) - -func init() { - sdk.TxMapper. - RegisterImplementation(SetTx{}, TypeSet, ByteSet). - RegisterImplementation(RemoveTx{}, TypeRemove, ByteRemove) +// DO NOT USE THIS INTERFACE. +// You probably want to use EyesTx +// +gen wrapper:"EyesTx,Impl[SetTx,RemoveTx],set,remove" +type EyesTxInner interface { + ValidateBasic() error } +// func init() { +// sdk.TxMapper. +// RegisterImplementation(SetTx{}, TypeSet, ByteSet). +// RegisterImplementation(RemoveTx{}, TypeRemove, ByteRemove) +// } + // SetTx sets a key-value pair type SetTx struct { Key data.Bytes `json:"key"` Value data.Bytes `json:"value"` } -func NewSetTx(key, value []byte) sdk.Tx { +func NewSetTx(key, value []byte) EyesTx { return SetTx{Key: key, Value: value}.Wrap() } -// Wrap - fulfills TxInner interface -func (t SetTx) Wrap() sdk.Tx { - return sdk.Tx{t} -} - // ValidateBasic makes sure it is valid func (t SetTx) ValidateBasic() error { if len(t.Key) == 0 || len(t.Value) == 0 { @@ -48,15 +40,10 @@ type RemoveTx struct { Key data.Bytes `json:"key"` } -func NewRemoveTx(key []byte) sdk.Tx { +func NewRemoveTx(key []byte) EyesTx { return RemoveTx{Key: key}.Wrap() } -// Wrap - fulfills TxInner interface -func (t RemoveTx) Wrap() sdk.Tx { - return sdk.Tx{t} -} - // ValidateBasic makes sure it is valid func (t RemoveTx) ValidateBasic() error { if len(t.Key) == 0 {