Move ChainID into context
This commit is contained in:
parent
ef0ab758ed
commit
159574db89
175
app/app.go
175
app/app.go
|
@ -1,23 +1,22 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/basecoin"
|
||||
eyes "github.com/tendermint/merkleeyes/client"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
||||
"github.com/tendermint/basecoin/errors"
|
||||
"github.com/tendermint/basecoin/modules/coin"
|
||||
"github.com/tendermint/basecoin/stack"
|
||||
sm "github.com/tendermint/basecoin/state"
|
||||
"github.com/tendermint/basecoin/types"
|
||||
"github.com/tendermint/basecoin/version"
|
||||
)
|
||||
|
||||
const (
|
||||
maxTxSize = 10240
|
||||
PluginNameBase = "base"
|
||||
)
|
||||
|
||||
|
@ -25,23 +24,29 @@ type Basecoin struct {
|
|||
eyesCli *eyes.Client
|
||||
state *sm.State
|
||||
cacheState *sm.State
|
||||
plugins *types.Plugins
|
||||
handler basecoin.Handler
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
func NewBasecoin(eyesCli *eyes.Client, l log.Logger) *Basecoin {
|
||||
func NewBasecoin(h basecoin.Handler, eyesCli *eyes.Client, l log.Logger) *Basecoin {
|
||||
state := sm.NewState(eyesCli, l.With("module", "state"))
|
||||
|
||||
plugins := types.NewPlugins()
|
||||
return &Basecoin{
|
||||
handler: h,
|
||||
eyesCli: eyesCli,
|
||||
state: state,
|
||||
cacheState: nil,
|
||||
plugins: plugins,
|
||||
logger: l,
|
||||
}
|
||||
}
|
||||
|
||||
// placeholder to just handle sendtx
|
||||
func DefaultHandler() basecoin.Handler {
|
||||
// use the default stack
|
||||
h := coin.NewHandler()
|
||||
return stack.NewDefault().Use(h)
|
||||
}
|
||||
|
||||
// XXX For testing, not thread safe!
|
||||
func (app *Basecoin) GetState() *sm.State {
|
||||
return app.state.CacheWrap()
|
||||
|
@ -60,87 +65,85 @@ func (app *Basecoin) Info() abci.ResponseInfo {
|
|||
}
|
||||
}
|
||||
|
||||
func (app *Basecoin) RegisterPlugin(plugin types.Plugin) {
|
||||
app.plugins.RegisterPlugin(plugin)
|
||||
}
|
||||
|
||||
// ABCI::SetOption
|
||||
func (app *Basecoin) SetOption(key string, value string) string {
|
||||
pluginName, key := splitKey(key)
|
||||
if pluginName != PluginNameBase {
|
||||
// Set option on plugin
|
||||
plugin := app.plugins.GetByName(pluginName)
|
||||
if plugin == nil {
|
||||
return "Invalid plugin name: " + pluginName
|
||||
}
|
||||
app.logger.Info("SetOption on plugin", "plugin", pluginName, "key", key, "value", value)
|
||||
return plugin.SetOption(app.state, key, value)
|
||||
} else {
|
||||
// Set option on basecoin
|
||||
switch key {
|
||||
case "chain_id":
|
||||
app.state.SetChainID(value)
|
||||
return "Success"
|
||||
case "account":
|
||||
var acc GenesisAccount
|
||||
err := json.Unmarshal([]byte(value), &acc)
|
||||
if err != nil {
|
||||
return "Error decoding acc message: " + err.Error()
|
||||
}
|
||||
acc.Balance.Sort()
|
||||
addr, err := acc.GetAddr()
|
||||
if err != nil {
|
||||
return "Invalid address: " + err.Error()
|
||||
}
|
||||
app.state.SetAccount(addr, acc.ToAccount())
|
||||
app.logger.Info("SetAccount", "addr", hex.EncodeToString(addr), "acc", acc)
|
||||
// TODO
|
||||
return "todo"
|
||||
// pluginName, key := splitKey(key)
|
||||
// if pluginName != PluginNameBase {
|
||||
// // Set option on plugin
|
||||
// plugin := app.plugins.GetByName(pluginName)
|
||||
// if plugin == nil {
|
||||
// return "Invalid plugin name: " + pluginName
|
||||
// }
|
||||
// app.logger.Info("SetOption on plugin", "plugin", pluginName, "key", key, "value", value)
|
||||
// return plugin.SetOption(app.state, key, value)
|
||||
// } else {
|
||||
// // Set option on basecoin
|
||||
// switch key {
|
||||
// case "chain_id":
|
||||
// app.state.SetChainID(value)
|
||||
// return "Success"
|
||||
// case "account":
|
||||
// var acc GenesisAccount
|
||||
// err := json.Unmarshal([]byte(value), &acc)
|
||||
// if err != nil {
|
||||
// return "Error decoding acc message: " + err.Error()
|
||||
// }
|
||||
// acc.Balance.Sort()
|
||||
// addr, err := acc.GetAddr()
|
||||
// if err != nil {
|
||||
// return "Invalid address: " + err.Error()
|
||||
// }
|
||||
// app.state.SetAccount(addr, acc.ToAccount())
|
||||
// app.logger.Info("SetAccount", "addr", hex.EncodeToString(addr), "acc", acc)
|
||||
|
||||
return "Success"
|
||||
}
|
||||
return "Unrecognized option key " + key
|
||||
}
|
||||
// return "Success"
|
||||
// }
|
||||
// return "Unrecognized option key " + key
|
||||
// }
|
||||
}
|
||||
|
||||
// ABCI::DeliverTx
|
||||
func (app *Basecoin) DeliverTx(txBytes []byte) (res abci.Result) {
|
||||
if len(txBytes) > maxTxSize {
|
||||
return abci.ErrBaseEncodingError.AppendLog("Tx size exceeds maximum")
|
||||
}
|
||||
|
||||
// Decode tx
|
||||
var tx types.Tx
|
||||
err := wire.ReadBinaryBytes(txBytes, &tx)
|
||||
func (app *Basecoin) DeliverTx(txBytes []byte) abci.Result {
|
||||
tx, err := basecoin.LoadTx(txBytes)
|
||||
if err != nil {
|
||||
return abci.ErrBaseEncodingError.AppendLog("Error decoding tx: " + err.Error())
|
||||
return errors.Result(err)
|
||||
}
|
||||
|
||||
// Validate and exec tx
|
||||
res = sm.ExecTx(app.state, app.plugins, tx, false, nil)
|
||||
if res.IsErr() {
|
||||
return res.PrependLog("Error in DeliverTx")
|
||||
// TODO: can we abstract this setup and commit logic??
|
||||
cache := app.state.CacheWrap()
|
||||
ctx := stack.NewContext(app.state.GetChainID(),
|
||||
app.logger.With("call", "delivertx"))
|
||||
res, err := app.handler.DeliverTx(ctx, cache, tx)
|
||||
|
||||
if err != nil {
|
||||
// discard the cache...
|
||||
return errors.Result(err)
|
||||
}
|
||||
return res
|
||||
// commit the cache and return result
|
||||
cache.CacheSync()
|
||||
return res.ToABCI()
|
||||
}
|
||||
|
||||
// ABCI::CheckTx
|
||||
func (app *Basecoin) CheckTx(txBytes []byte) (res abci.Result) {
|
||||
if len(txBytes) > maxTxSize {
|
||||
return abci.ErrBaseEncodingError.AppendLog("Tx size exceeds maximum")
|
||||
}
|
||||
|
||||
// Decode tx
|
||||
var tx types.Tx
|
||||
err := wire.ReadBinaryBytes(txBytes, &tx)
|
||||
func (app *Basecoin) CheckTx(txBytes []byte) abci.Result {
|
||||
tx, err := basecoin.LoadTx(txBytes)
|
||||
if err != nil {
|
||||
return abci.ErrBaseEncodingError.AppendLog("Error decoding tx: " + err.Error())
|
||||
return errors.Result(err)
|
||||
}
|
||||
|
||||
// Validate tx
|
||||
res = sm.ExecTx(app.cacheState, app.plugins, tx, true, nil)
|
||||
if res.IsErr() {
|
||||
return res.PrependLog("Error in CheckTx")
|
||||
// TODO: can we abstract this setup and commit logic??
|
||||
ctx := stack.NewContext(app.state.GetChainID(),
|
||||
app.logger.With("call", "checktx"))
|
||||
// checktx generally shouldn't touch the state, but we don't care
|
||||
// here on the framework level, since the cacheState is thrown away next block
|
||||
res, err := app.handler.CheckTx(ctx, app.cacheState, tx)
|
||||
|
||||
if err != nil {
|
||||
return errors.Result(err)
|
||||
}
|
||||
return abci.OK
|
||||
return res.ToABCI()
|
||||
}
|
||||
|
||||
// ABCI::Query
|
||||
|
@ -151,12 +154,6 @@ func (app *Basecoin) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQu
|
|||
return
|
||||
}
|
||||
|
||||
// handle special path for account info
|
||||
if reqQuery.Path == "/account" {
|
||||
reqQuery.Path = "/key"
|
||||
reqQuery.Data = types.AccountKey(reqQuery.Data)
|
||||
}
|
||||
|
||||
resQuery, err := app.eyesCli.QuerySync(reqQuery)
|
||||
if err != nil {
|
||||
resQuery.Log = "Failed to query MerkleEyes: " + err.Error()
|
||||
|
@ -183,24 +180,24 @@ func (app *Basecoin) Commit() (res abci.Result) {
|
|||
|
||||
// ABCI::InitChain
|
||||
func (app *Basecoin) InitChain(validators []*abci.Validator) {
|
||||
for _, plugin := range app.plugins.GetList() {
|
||||
plugin.InitChain(app.state, validators)
|
||||
}
|
||||
// for _, plugin := range app.plugins.GetList() {
|
||||
// plugin.InitChain(app.state, validators)
|
||||
// }
|
||||
}
|
||||
|
||||
// ABCI::BeginBlock
|
||||
func (app *Basecoin) BeginBlock(hash []byte, header *abci.Header) {
|
||||
for _, plugin := range app.plugins.GetList() {
|
||||
plugin.BeginBlock(app.state, hash, header)
|
||||
}
|
||||
// for _, plugin := range app.plugins.GetList() {
|
||||
// plugin.BeginBlock(app.state, hash, header)
|
||||
// }
|
||||
}
|
||||
|
||||
// ABCI::EndBlock
|
||||
func (app *Basecoin) EndBlock(height uint64) (res abci.ResponseEndBlock) {
|
||||
for _, plugin := range app.plugins.GetList() {
|
||||
pluginRes := plugin.EndBlock(app.state, height)
|
||||
res.Diffs = append(res.Diffs, pluginRes.Diffs...)
|
||||
}
|
||||
// for _, plugin := range app.plugins.GetList() {
|
||||
// pluginRes := plugin.EndBlock(app.state, height)
|
||||
// res.Diffs = append(res.Diffs, pluginRes.Diffs...)
|
||||
// }
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,8 @@ func (at *appTest) reset() {
|
|||
at.accOut = types.MakeAcc("output0")
|
||||
|
||||
eyesCli := eyes.NewLocalClient("", 0)
|
||||
at.app = NewBasecoin(eyesCli, log.TestingLogger().With("module", "app"))
|
||||
at.app = NewBasecoin(DefaultHandler(), eyesCli,
|
||||
log.TestingLogger().With("module", "app"))
|
||||
|
||||
res := at.app.SetOption("base/chain_id", at.chainID)
|
||||
require.EqualValues(at.t, res, "Success")
|
||||
|
@ -105,7 +106,8 @@ func TestSetOption(t *testing.T) {
|
|||
require := require.New(t)
|
||||
|
||||
eyesCli := eyes.NewLocalClient("", 0)
|
||||
app := NewBasecoin(eyesCli, log.TestingLogger().With("module", "app"))
|
||||
app := NewBasecoin(DefaultHandler(), eyesCli,
|
||||
log.TestingLogger().With("module", "app"))
|
||||
|
||||
//testing ChainID
|
||||
chainID := "testChain"
|
||||
|
|
|
@ -19,7 +19,7 @@ const genesisAcctFilepath = "./testdata/genesis2.json"
|
|||
|
||||
func TestLoadGenesisDoNotFailIfAppOptionsAreMissing(t *testing.T) {
|
||||
eyesCli := eyescli.NewLocalClient("", 0)
|
||||
app := NewBasecoin(eyesCli, log.TestingLogger())
|
||||
app := NewBasecoin(DefaultHandler(), eyesCli, log.TestingLogger())
|
||||
err := app.LoadGenesis("./testdata/genesis3.json")
|
||||
require.Nil(t, err, "%+v", err)
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ func TestLoadGenesis(t *testing.T) {
|
|||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
eyesCli := eyescli.NewLocalClient("", 0)
|
||||
app := NewBasecoin(eyesCli, log.TestingLogger())
|
||||
app := NewBasecoin(DefaultHandler(), eyesCli, log.TestingLogger())
|
||||
err := app.LoadGenesis(genesisFilepath)
|
||||
require.Nil(err, "%+v", err)
|
||||
|
||||
|
@ -65,7 +65,7 @@ func TestLoadGenesisAccountAddress(t *testing.T) {
|
|||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
eyesCli := eyescli.NewLocalClient("", 0)
|
||||
app := NewBasecoin(eyesCli, log.TestingLogger())
|
||||
app := NewBasecoin(DefaultHandler(), eyesCli, log.TestingLogger())
|
||||
err := app.LoadGenesis(genesisAcctFilepath)
|
||||
require.Nil(err, "%+v", err)
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/tendermint/abci/server"
|
||||
"github.com/tendermint/basecoin"
|
||||
eyesApp "github.com/tendermint/merkleeyes/app"
|
||||
eyes "github.com/tendermint/merkleeyes/client"
|
||||
"github.com/tendermint/tmlibs/cli"
|
||||
|
@ -21,6 +22,8 @@ import (
|
|||
"github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/tendermint/basecoin/app"
|
||||
"github.com/tendermint/basecoin/modules/coin"
|
||||
"github.com/tendermint/basecoin/stack"
|
||||
)
|
||||
|
||||
var StartCmd = &cobra.Command{
|
||||
|
@ -48,6 +51,22 @@ func init() {
|
|||
tcmd.AddNodeFlags(StartCmd)
|
||||
}
|
||||
|
||||
// TODO: setup handler instead of Plugins
|
||||
func getHandler() basecoin.Handler {
|
||||
// use the default stack
|
||||
h := coin.NewHandler()
|
||||
app := stack.NewDefault("change-this").Use(h)
|
||||
return app
|
||||
|
||||
// register IBC plugn
|
||||
// basecoinApp.RegisterPlugin(NewIBCPlugin())
|
||||
|
||||
// register all other plugins
|
||||
// for _, p := range plugins {
|
||||
// basecoinApp.RegisterPlugin(p.newPlugin())
|
||||
// }
|
||||
}
|
||||
|
||||
func startCmd(cmd *cobra.Command, args []string) error {
|
||||
rootDir := viper.GetString(cli.HomeFlag)
|
||||
meyes := viper.GetString(FlagEyes)
|
||||
|
@ -66,15 +85,8 @@ func startCmd(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
// Create Basecoin app
|
||||
basecoinApp := app.NewBasecoin(eyesCli, logger.With("module", "app"))
|
||||
|
||||
// register IBC plugn
|
||||
// basecoinApp.RegisterPlugin(NewIBCPlugin())
|
||||
|
||||
// register all other plugins
|
||||
for _, p := range plugins {
|
||||
basecoinApp.RegisterPlugin(p.newPlugin())
|
||||
}
|
||||
h := app.DefaultHandler()
|
||||
basecoinApp := app.NewBasecoin(h, eyesCli, logger.With("module", "app"))
|
||||
|
||||
// if chain_id has not been set yet, load the genesis.
|
||||
// else, assume it's been loaded
|
||||
|
|
|
@ -34,4 +34,5 @@ type Context interface {
|
|||
HasPermission(perm Actor) bool
|
||||
IsParent(ctx Context) bool
|
||||
Reset() Context
|
||||
ChainID() string
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ func TestHandlerValidation(t *testing.T) {
|
|||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
ctx := stack.MockContext().WithPermissions(tc.perms...)
|
||||
ctx := stack.MockContext("base-chain").WithPermissions(tc.perms...)
|
||||
_, err := checkTx(ctx, tc.tx)
|
||||
if tc.valid {
|
||||
assert.Nil(err, "%d: %+v", i, err)
|
||||
|
@ -142,7 +142,7 @@ func TestDeliverTx(t *testing.T) {
|
|||
require.Nil(err, "%d: %+v", i, err)
|
||||
}
|
||||
|
||||
ctx := stack.MockContext().WithPermissions(tc.perms...)
|
||||
ctx := stack.MockContext("base-chain").WithPermissions(tc.perms...)
|
||||
_, err := h.DeliverTx(ctx, store, tc.tx)
|
||||
if len(tc.final) > 0 { // valid
|
||||
assert.Nil(err, "%d: %+v", i, err)
|
||||
|
|
|
@ -12,9 +12,7 @@ const (
|
|||
)
|
||||
|
||||
// Chain enforces that this tx was bound to the named chain
|
||||
type Chain struct {
|
||||
ChainID string
|
||||
}
|
||||
type Chain struct{}
|
||||
|
||||
func (_ Chain) Name() string {
|
||||
return NameRecovery
|
||||
|
@ -23,7 +21,7 @@ func (_ Chain) Name() string {
|
|||
var _ Middleware = Chain{}
|
||||
|
||||
func (c Chain) CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Checker) (res basecoin.Result, err error) {
|
||||
stx, err := c.checkChain(tx)
|
||||
stx, err := c.checkChain(ctx.ChainID(), tx)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
@ -31,7 +29,7 @@ func (c Chain) CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx
|
|||
}
|
||||
|
||||
func (c Chain) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Deliver) (res basecoin.Result, err error) {
|
||||
stx, err := c.checkChain(tx)
|
||||
stx, err := c.checkChain(ctx.ChainID(), tx)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
@ -39,12 +37,12 @@ func (c Chain) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.
|
|||
}
|
||||
|
||||
// checkChain makes sure the tx is a txs.Chain and
|
||||
func (c Chain) checkChain(tx basecoin.Tx) (basecoin.Tx, error) {
|
||||
func (c Chain) checkChain(chainID string, tx basecoin.Tx) (basecoin.Tx, error) {
|
||||
ctx, ok := tx.Unwrap().(*txs.Chain)
|
||||
if !ok {
|
||||
return tx, errors.ErrNoChain()
|
||||
}
|
||||
if ctx.ChainID != c.ChainID {
|
||||
if ctx.ChainID != chainID {
|
||||
return tx, errors.ErrWrongChain(ctx.ChainID)
|
||||
}
|
||||
return ctx.Tx, nil
|
||||
|
|
|
@ -30,12 +30,12 @@ func TestChain(t *testing.T) {
|
|||
}
|
||||
|
||||
// generic args here...
|
||||
ctx := NewContext(log.NewNopLogger())
|
||||
ctx := NewContext(chainID, log.NewNopLogger())
|
||||
store := types.NewMemKVStore()
|
||||
|
||||
// build the stack
|
||||
ok := OKHandler{msg}
|
||||
app := New(Chain{chainID}).Use(ok)
|
||||
app := New(Chain{}).Use(ok)
|
||||
|
||||
for idx, tc := range cases {
|
||||
i := strconv.Itoa(idx)
|
||||
|
|
|
@ -17,20 +17,26 @@ type nonce int64
|
|||
|
||||
type secureContext struct {
|
||||
id nonce
|
||||
chain string
|
||||
app string
|
||||
perms []basecoin.Actor
|
||||
log.Logger
|
||||
}
|
||||
|
||||
func NewContext(logger log.Logger) basecoin.Context {
|
||||
func NewContext(chain string, logger log.Logger) basecoin.Context {
|
||||
return secureContext{
|
||||
id: nonce(rand.Int63()),
|
||||
chain: chain,
|
||||
Logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
var _ basecoin.Context = secureContext{}
|
||||
|
||||
func (c secureContext) ChainID() string {
|
||||
return c.chain
|
||||
}
|
||||
|
||||
// WithPermissions will panic if they try to set permission without the proper app
|
||||
func (c secureContext) WithPermissions(perms ...basecoin.Actor) basecoin.Context {
|
||||
// the guard makes sure you only set permissions for the app you are inside
|
||||
|
@ -44,6 +50,7 @@ func (c secureContext) WithPermissions(perms ...basecoin.Actor) basecoin.Context
|
|||
|
||||
return secureContext{
|
||||
id: c.id,
|
||||
chain: c.chain,
|
||||
app: c.app,
|
||||
perms: append(c.perms, perms...),
|
||||
Logger: c.Logger,
|
||||
|
@ -73,6 +80,7 @@ func (c secureContext) IsParent(other basecoin.Context) bool {
|
|||
func (c secureContext) Reset() basecoin.Context {
|
||||
return secureContext{
|
||||
id: c.id,
|
||||
chain: c.chain,
|
||||
app: c.app,
|
||||
perms: nil,
|
||||
Logger: c.Logger,
|
||||
|
@ -88,6 +96,7 @@ func withApp(ctx basecoin.Context, app string) basecoin.Context {
|
|||
}
|
||||
return secureContext{
|
||||
id: sc.id,
|
||||
chain: sc.chain,
|
||||
app: app,
|
||||
perms: sc.perms,
|
||||
Logger: sc.Logger,
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
func TestOK(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
ctx := NewContext(log.NewNopLogger())
|
||||
ctx := NewContext("test-chain", log.NewNopLogger())
|
||||
store := types.NewMemKVStore()
|
||||
data := "this looks okay"
|
||||
tx := basecoin.Tx{}
|
||||
|
@ -33,7 +33,7 @@ func TestOK(t *testing.T) {
|
|||
func TestFail(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
ctx := NewContext(log.NewNopLogger())
|
||||
ctx := NewContext("test-chain", log.NewNopLogger())
|
||||
store := types.NewMemKVStore()
|
||||
msg := "big problem"
|
||||
tx := basecoin.Tx{}
|
||||
|
@ -53,7 +53,7 @@ func TestFail(t *testing.T) {
|
|||
func TestPanic(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
ctx := NewContext(log.NewNopLogger())
|
||||
ctx := NewContext("test-chain", log.NewNopLogger())
|
||||
store := types.NewMemKVStore()
|
||||
msg := "system crash!"
|
||||
tx := basecoin.Tx{}
|
||||
|
|
|
@ -57,12 +57,12 @@ func New(middlewares ...Middleware) *Stack {
|
|||
// NewDefault sets up the common middlewares before your custom stack.
|
||||
//
|
||||
// This is logger, recovery, signature, and chain
|
||||
func NewDefault(chainID string, middlewares ...Middleware) *Stack {
|
||||
func NewDefault(middlewares ...Middleware) *Stack {
|
||||
mids := []Middleware{
|
||||
Logger{},
|
||||
Recovery{},
|
||||
Signatures{},
|
||||
Chain{chainID},
|
||||
Chain{},
|
||||
}
|
||||
mids = append(mids, middlewares...)
|
||||
return New(mids...)
|
||||
|
|
|
@ -17,7 +17,7 @@ func TestPermissionSandbox(t *testing.T) {
|
|||
require := require.New(t)
|
||||
|
||||
// generic args
|
||||
ctx := NewContext(log.NewNopLogger())
|
||||
ctx := NewContext("test-chain", log.NewNopLogger())
|
||||
store := types.NewMemKVStore()
|
||||
raw := txs.NewRaw([]byte{1, 2, 3, 4})
|
||||
rawBytes, err := data.ToWire(raw)
|
||||
|
|
|
@ -10,17 +10,23 @@ import (
|
|||
|
||||
type mockContext struct {
|
||||
perms []basecoin.Actor
|
||||
chain string
|
||||
log.Logger
|
||||
}
|
||||
|
||||
func MockContext() basecoin.Context {
|
||||
func MockContext(chain string) basecoin.Context {
|
||||
return mockContext{
|
||||
chain: chain,
|
||||
Logger: log.NewNopLogger(),
|
||||
}
|
||||
}
|
||||
|
||||
var _ basecoin.Context = mockContext{}
|
||||
|
||||
func (c mockContext) ChainID() string {
|
||||
return c.chain
|
||||
}
|
||||
|
||||
// WithPermissions will panic if they try to set permission without the proper app
|
||||
func (c mockContext) WithPermissions(perms ...basecoin.Actor) basecoin.Context {
|
||||
return mockContext{
|
||||
|
|
|
@ -15,7 +15,7 @@ func TestRecovery(t *testing.T) {
|
|||
assert := assert.New(t)
|
||||
|
||||
// generic args here...
|
||||
ctx := NewContext(log.NewNopLogger())
|
||||
ctx := NewContext("test-chain", log.NewNopLogger())
|
||||
store := types.NewMemKVStore()
|
||||
tx := basecoin.Tx{}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ func TestSignatureChecks(t *testing.T) {
|
|||
assert := assert.New(t)
|
||||
|
||||
// generic args
|
||||
ctx := NewContext(log.NewNopLogger())
|
||||
ctx := NewContext("test-chain", log.NewNopLogger())
|
||||
store := types.NewMemKVStore()
|
||||
raw := txs.NewRaw([]byte{1, 2, 3, 4})
|
||||
|
||||
|
|
21
tx.go
21
tx.go
|
@ -1,5 +1,12 @@
|
|||
package basecoin
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
)
|
||||
|
||||
const maxTxSize = 10240
|
||||
|
||||
// TxInner is the interface all concrete transactions should implement.
|
||||
//
|
||||
// It adds bindings for clean un/marhsaling of the various implementations
|
||||
|
@ -15,6 +22,20 @@ type TxInner interface {
|
|||
ValidateBasic() error
|
||||
}
|
||||
|
||||
// LoadTx parses a tx from data
|
||||
//
|
||||
// TODO: label both errors with abci.CodeType_EncodingError
|
||||
// need to move errors to avoid import cycle
|
||||
func LoadTx(bin []byte) (tx Tx, err error) {
|
||||
if len(bin) > maxTxSize {
|
||||
return tx, errors.New("Tx size exceeds maximum")
|
||||
}
|
||||
|
||||
// Decode tx
|
||||
err = data.FromWire(bin, &tx)
|
||||
return tx, err
|
||||
}
|
||||
|
||||
// TODO: do we need this abstraction? TxLayer???
|
||||
// please review again after implementing "middleware"
|
||||
|
||||
|
|
Loading…
Reference in New Issue