Move ChainID into context

This commit is contained in:
Ethan Frey
2017-07-03 17:32:01 +02:00
parent ef0ab758ed
commit 159574db89
16 changed files with 170 additions and 124 deletions
+86 -89
View File
@@ -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
}
+4 -2
View File
@@ -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"
+3 -3
View File
@@ -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)