eyes example compiles - but doesnt work

This commit is contained in:
Ethan Frey 2017-10-24 22:23:43 +02:00
parent 5efbbc3237
commit 850796bad5
9 changed files with 40 additions and 251 deletions

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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)

View File

@ -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"))

92
tx.go
View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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 ***/