Move ChainID into context
This commit is contained in:
+86
-89
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user