From 850796bad5c706e14af30abc240446f0532e7bdc Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 24 Oct 2017 22:23:43 +0200 Subject: [PATCH] eyes example compiles - but doesnt work --- app/base.go | 17 +++---- client/commands/query/tx.go | 5 +- client/commands/txs/helpers.go | 22 ++++---- client/commands/txs/root.go | 4 +- client/commands/txs/wrapper.go | 6 +-- server/commands/start.go | 32 ++++++------ tx.go | 92 ---------------------------------- tx_test.go | 67 ------------------------- txinner_wrapper.go | 46 ----------------- 9 files changed, 40 insertions(+), 251 deletions(-) delete mode 100644 tx.go delete mode 100644 tx_test.go delete mode 100644 txinner_wrapper.go diff --git a/app/base.go b/app/base.go index 6740853c20..f3f7c391e6 100644 --- a/app/base.go +++ b/app/base.go @@ -29,16 +29,14 @@ func NewBaseApp(store *StoreApp, handler sdk.Handler, clock sdk.Ticker) *BaseApp // DeliverTx - ABCI - dispatches to the handler func (app *BaseApp) DeliverTx(txBytes []byte) abci.Result { - tx, err := sdk.LoadTx(txBytes) - if err != nil { - return errors.Result(err) - } + // TODO: use real context on refactor ctx := util.MockContext( app.GetChainID(), app.WorkingHeight(), ) - res, err := app.handler.DeliverTx(ctx, app.Append(), tx) + // Note: first decorator must parse bytes + res, err := app.handler.DeliverTx(ctx, app.Append(), txBytes) if err != nil { return errors.Result(err) @@ -49,16 +47,13 @@ func (app *BaseApp) DeliverTx(txBytes []byte) abci.Result { // CheckTx - ABCI - dispatches to the handler func (app *BaseApp) CheckTx(txBytes []byte) abci.Result { - tx, err := sdk.LoadTx(txBytes) - if err != nil { - return errors.Result(err) - } - + // TODO: use real context on refactor ctx := util.MockContext( app.GetChainID(), app.WorkingHeight(), ) - res, err := app.handler.CheckTx(ctx, app.Check(), tx) + // Note: first decorator must parse bytes + res, err := app.handler.CheckTx(ctx, app.Check(), txBytes) if err != nil { return errors.Result(err) diff --git a/client/commands/query/tx.go b/client/commands/query/tx.go index 8f86c09bb1..24087b768f 100644 --- a/client/commands/query/tx.go +++ b/client/commands/query/tx.go @@ -4,7 +4,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - sdk "github.com/cosmos/cosmos-sdk" wire "github.com/tendermint/go-wire" "github.com/tendermint/tendermint/types" @@ -66,9 +65,9 @@ func txQueryCmd(cmd *cobra.Command, args []string) error { return showTx(res.Height, res.Proof.Data) } -// showTx parses anything that was previously registered as sdk.Tx +// showTx parses anything that was previously registered as interface{} func showTx(h int, tx types.Tx) error { - var info sdk.Tx + var info interface{} err := wire.ReadBinaryBytes(tx, &info) if err != nil { return err diff --git a/client/commands/txs/helpers.go b/client/commands/txs/helpers.go index 013b15d24b..716c430980 100644 --- a/client/commands/txs/helpers.go +++ b/client/commands/txs/helpers.go @@ -61,7 +61,7 @@ func GetSignerAct() (res sdk.Actor) { // If you want a non-standard flow, just call the various functions directly. // eg. if you already set the middleware layers in your code, or want to // output in another format. -func DoTx(tx sdk.Tx) (err error) { +func DoTx(tx interface{}) (err error) { tx, err = Middleware.Wrap(tx) if err != nil { return err @@ -85,12 +85,12 @@ func DoTx(tx sdk.Tx) (err error) { // SignTx will validate the tx, and signs it if it is wrapping a Signable. // Modifies tx in place, and returns an error if it should sign but couldn't -func SignTx(tx sdk.Tx) error { - // validate tx client-side - err := tx.ValidateBasic() - if err != nil { - return err - } +func SignTx(tx interface{}) (err error) { + // TODO: validate tx client-side + // err := tx.ValidateBasic() + // if err != nil { + // return err + // } // abort early if we don't want to sign if viper.GetBool(FlagNoSign) { @@ -100,7 +100,7 @@ func SignTx(tx sdk.Tx) error { name := viper.GetString(FlagName) manager := keycmd.GetKeyManager() - if sign, ok := tx.Unwrap().(keys.Signable); ok { + if sign, ok := tx.(keys.Signable); ok { // TODO: allow us not to sign? if so then what use? if name == "" { return errors.New("--name is required to sign tx") @@ -114,7 +114,7 @@ func SignTx(tx sdk.Tx) error { // multisig, or to post it to the node. Returns error on any failure. // If no error and the result is nil, it means it already wrote to file, // no post, no need to do more. -func PrepareOrPostTx(tx sdk.Tx) (*ctypes.ResultBroadcastTxCommit, error) { +func PrepareOrPostTx(tx interface{}) (*ctypes.ResultBroadcastTxCommit, error) { wrote, err := PrepareTx(tx) // error in prep if err != nil { @@ -132,7 +132,7 @@ func PrepareOrPostTx(tx sdk.Tx) (*ctypes.ResultBroadcastTxCommit, error) { // to the specified location for later multi-sig. Returns true if it // handled the tx (no futher work required), false if it did nothing // (and we should post the tx) -func PrepareTx(tx sdk.Tx) (bool, error) { +func PrepareTx(tx interface{}) (bool, error) { prep := viper.GetString(FlagPrepare) if prep == "" { return false, nil @@ -152,7 +152,7 @@ func PrepareTx(tx sdk.Tx) (bool, error) { // PostTx does all work once we construct a proper struct // it validates the data, signs if needed, transforms to bytes, // and posts to the node. -func PostTx(tx sdk.Tx) (*ctypes.ResultBroadcastTxCommit, error) { +func PostTx(tx interface{}) (*ctypes.ResultBroadcastTxCommit, error) { packet := wire.BinaryBytes(tx) // post the bytes node := commands.GetNode() diff --git a/client/commands/txs/root.go b/client/commands/txs/root.go index 0a6317027b..fca14f2e46 100644 --- a/client/commands/txs/root.go +++ b/client/commands/txs/root.go @@ -6,8 +6,6 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/viper" - - sdk "github.com/cosmos/cosmos-sdk" ) // nolint @@ -39,7 +37,7 @@ func doRawTx(cmd *cobra.Command, args []string) error { } // parse the input - var tx sdk.Tx + var tx interface{} err = json.Unmarshal(raw, &tx) if err != nil { return errors.WithStack(err) diff --git a/client/commands/txs/wrapper.go b/client/commands/txs/wrapper.go index 4265eff8d7..fcfd994004 100644 --- a/client/commands/txs/wrapper.go +++ b/client/commands/txs/wrapper.go @@ -2,8 +2,6 @@ package txs import ( "github.com/spf13/pflag" - - sdk "github.com/cosmos/cosmos-sdk" ) var ( @@ -14,7 +12,7 @@ var ( // Wrapper defines the information needed for each middleware package that // wraps the data. They should read all configuration out of bounds via viper. type Wrapper interface { - Wrap(sdk.Tx) (sdk.Tx, error) + Wrap(interface{}) (interface{}, error) Register(*pflag.FlagSet) } @@ -26,7 +24,7 @@ var _ Wrapper = Wrappers{} // Wrap applies the wrappers to the passed in tx in order, // aborting on the first error -func (ws Wrappers) Wrap(tx sdk.Tx) (sdk.Tx, error) { +func (ws Wrappers) Wrap(tx interface{}) (interface{}, error) { var err error for _, w := range ws { tx, err = w.Wrap(tx) diff --git a/server/commands/start.go b/server/commands/start.go index 5580ce3036..20f772f529 100644 --- a/server/commands/start.go +++ b/server/commands/start.go @@ -57,6 +57,8 @@ var ( // Handler - use a global to store the handler, so we can set it in main. // TODO: figure out a cleaner way to register plugins Handler sdk.Handler + // InitState registers handlers for genesis file options + InitState sdk.InitStater ) func init() { @@ -88,8 +90,9 @@ func tickStartCmd(clock sdk.Ticker) func(cmd *cobra.Command, args []string) erro } // Create Basecoin app - basecoinApp := app.NewBaseApp(storeApp, Handler, clock) - return start(rootDir, basecoinApp) + baseApp := app.NewBaseApp(storeApp, Handler, clock) + app := app.NewInitApp(baseApp, InitState, nil) // TODO: support validators + return start(rootDir, app) } } @@ -108,19 +111,20 @@ func startCmd(cmd *cobra.Command, args []string) error { } // Create Basecoin app - basecoinApp := app.NewBaseApp(storeApp, Handler, nil) - return start(rootDir, basecoinApp) + baseApp := app.NewBaseApp(storeApp, Handler, nil) + app := app.NewInitApp(baseApp, InitState, nil) // TODO: support validators + return start(rootDir, app) } -func start(rootDir string, basecoinApp *app.BaseApp) error { +func start(rootDir string, app *app.InitApp) error { // if chain_id has not been set yet, load the genesis. // else, assume it's been loaded - if basecoinApp.GetChainID() == "" { + if app.GetChainID() == "" { // If genesis file exists, set key-value options genesisFile := path.Join(rootDir, "genesis.json") if _, err := os.Stat(genesisFile); err == nil { - err = genesis.Load(basecoinApp, genesisFile) + err = genesis.Load(app, genesisFile) if err != nil { return errors.Errorf("Error in LoadGenesis: %v\n", err) } @@ -129,21 +133,21 @@ func start(rootDir string, basecoinApp *app.BaseApp) error { } } - chainID := basecoinApp.GetChainID() + chainID := app.GetChainID() if viper.GetBool(FlagWithoutTendermint) { logger.Info("Starting Basecoin without Tendermint", "chain_id", chainID) // run just the abci app/server - return startBasecoinABCI(basecoinApp) + return startBasecoinABCI(app) } logger.Info("Starting Basecoin with Tendermint", "chain_id", chainID) // start the app with tendermint in-process - return startTendermint(rootDir, basecoinApp) + return startTendermint(rootDir, app) } -func startBasecoinABCI(basecoinApp abci.Application) error { +func startBasecoinABCI(app abci.Application) error { // Start the ABCI listener addr := viper.GetString(FlagAddress) - svr, err := server.NewServer(addr, "socket", basecoinApp) + svr, err := server.NewServer(addr, "socket", app) if err != nil { return errors.Errorf("Error creating listener: %v\n", err) } @@ -158,7 +162,7 @@ func startBasecoinABCI(basecoinApp abci.Application) error { return nil } -func startTendermint(dir string, basecoinApp abci.Application) error { +func startTendermint(dir string, app abci.Application) error { cfg, err := tcmd.ParseConfig() if err != nil { return err @@ -167,7 +171,7 @@ func startTendermint(dir string, basecoinApp abci.Application) error { // Create & start tendermint node n, err := node.NewNode(cfg, types.LoadOrGenPrivValidatorFS(cfg.PrivValidatorFile()), - proxy.NewLocalClientCreator(basecoinApp), + proxy.NewLocalClientCreator(app), node.DefaultGenesisDocProviderFunc(cfg), node.DefaultDBProvider, logger.With("module", "node")) diff --git a/tx.go b/tx.go deleted file mode 100644 index 81dd1dc0b0..0000000000 --- a/tx.go +++ /dev/null @@ -1,92 +0,0 @@ -package sdk - -import ( - "strings" - - "github.com/tendermint/go-wire/data" - - "github.com/cosmos/cosmos-sdk/errors" -) - -const maxTxSize = 10240 - -// TxInner is the interface all concrete transactions should implement. -// -// It adds bindings for clean un/marhsaling of the various implementations -// both as json and binary, as well as some common functionality to move them. -// -// +gen wrapper:"Tx" -type TxInner interface { - Wrap() Tx - - // ValidateBasic should be a stateless check and just verify that the - // tx is properly formated (required strings not blank, signatures exist, etc.) - // this can also be run on the client-side for better debugging before posting a tx - ValidateBasic() error -} - -// LoadTx parses a tx from data -func LoadTx(bin []byte) (tx Tx, err error) { - if len(bin) > maxTxSize { - return tx, errors.ErrTooLarge() - } - - // Decode tx - err = data.FromWire(bin, &tx) - return tx, err -} - -// TODO: do we need this abstraction? TxLayer??? -// please review again after implementing "middleware" - -// TxLayer provides a standard way to deal with "middleware" tx, -// That add context to an embedded tx. -type TxLayer interface { - TxInner - Next() Tx -} - -func (t Tx) IsLayer() bool { - _, ok := t.Unwrap().(TxLayer) - return ok -} - -func (t Tx) GetLayer() TxLayer { - l, _ := t.Unwrap().(TxLayer) - return l -} - -// env lets us parse an envelope and just grab the type -type env struct { - Kind string `json:"type"` -} - -// TODO: put this functionality into go-data in a cleaner and more efficient way -func (t Tx) GetKind() (string, error) { - // render as json - d, err := data.ToJSON(t) - if err != nil { - return "", err - } - // parse json - text := env{} - err = data.FromJSON(d, &text) - if err != nil { - return "", err - } - // grab the type we used in json - return text.Kind, nil -} - -func (t Tx) GetMod() (string, error) { - kind, err := t.GetKind() - if err != nil { - return "", err - } - parts := strings.SplitN(kind, "/", 2) - if len(parts) != 2 { - // TODO: return "base"? - return "", errors.ErrUnknownTxType(t) - } - return parts[0], nil -} diff --git a/tx_test.go b/tx_test.go deleted file mode 100644 index c3ddfc819a..0000000000 --- a/tx_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package sdk - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func init() { - TxMapper. - RegisterImplementation(Demo{}, TypeDemo, ByteDemo). - RegisterImplementation(Fake{}, TypeFake, ByteFake) -} - -const ( - ByteDemo = 0xF0 - TypeDemo = "test/demo" - ByteFake = 0xF1 - TypeFake = "test/fake" -) - -// define a Demo struct that implements TxLayer -type Demo struct{} - -var _ TxLayer = Demo{} - -func (d Demo) Next() Tx { return Tx{} } -func (d Demo) Wrap() Tx { return Tx{d} } -func (d Demo) ValidateBasic() error { return nil } - -// define a Fake struct that doesn't implement TxLayer -type Fake struct{} - -func (f Fake) Wrap() Tx { return Tx{f} } -func (f Fake) ValidateBasic() error { return nil } - -// Make sure the layer -func TestLayer(t *testing.T) { - assert := assert.New(t) - - // a fake tx, just don't use it... - nl := Fake{}.Wrap() - assert.False(nl.IsLayer()) - assert.Nil(nl.GetLayer()) - - // a tx containing a TxLayer should respond properly - l := Demo{}.Wrap() - assert.True(l.IsLayer()) - assert.NotNil(l.GetLayer()) -} - -func TestKind(t *testing.T) { - cases := []struct { - tx Tx - kind string - }{ - {Demo{}.Wrap(), TypeDemo}, - {Fake{}.Wrap(), TypeFake}, - } - - for _, tc := range cases { - kind, err := tc.tx.GetKind() - require.Nil(t, err, "%+v", err) - assert.Equal(t, tc.kind, kind) - } -} diff --git a/txinner_wrapper.go b/txinner_wrapper.go deleted file mode 100644 index c3cf36ebe0..0000000000 --- a/txinner_wrapper.go +++ /dev/null @@ -1,46 +0,0 @@ -// Generated by: main -// TypeWriter: wrapper -// Directive: +gen on TxInner - -package sdk - -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 Tx struct { - TxInner "json:\"unwrap\"" -} - -var TxMapper = data.NewMapper(Tx{}) - -func (h Tx) MarshalJSON() ([]byte, error) { - return TxMapper.ToJSON(h.TxInner) -} - -func (h *Tx) UnmarshalJSON(data []byte) (err error) { - parsed, err := TxMapper.FromJSON(data) - if err == nil && parsed != nil { - h.TxInner = parsed.(TxInner) - } - return err -} - -// Unwrap recovers the concrete interface safely (regardless of levels of embeds) -func (h Tx) Unwrap() TxInner { - hi := h.TxInner - for wrap, ok := hi.(Tx); ok; wrap, ok = hi.(Tx) { - hi = wrap.TxInner - } - return hi -} - -func (h Tx) Empty() bool { - return h.TxInner == nil -} - -/*** below are bindings for each implementation ***/