cosmos-sdk/app/app.go

201 lines
5.0 KiB
Go
Raw Normal View History

package app
2016-02-05 23:16:33 -08:00
import (
"strings"
2016-03-22 13:07:03 -07:00
"github.com/tendermint/basecoin/state"
2016-02-16 12:29:54 -08:00
"github.com/tendermint/basecoin/types"
2016-03-15 15:01:53 -07:00
. "github.com/tendermint/go-common"
2016-02-05 23:16:33 -08:00
"github.com/tendermint/go-wire"
2016-03-22 13:07:03 -07:00
"github.com/tendermint/governmint/gov"
2016-02-05 23:16:33 -08:00
eyes "github.com/tendermint/merkleeyes/client"
tmsp "github.com/tendermint/tmsp/types"
)
2016-03-27 12:47:50 -07:00
const (
version = "0.1"
maxTxSize = 10240
2016-04-18 08:09:19 -07:00
PluginTypeByteBase = 0x01
PluginTypeByteEyes = 0x02
PluginTypeByteGov = 0x03
2016-03-27 12:47:50 -07:00
2016-04-18 08:09:19 -07:00
PluginNameBase = "base"
PluginNameEyes = "eyes"
PluginNameGov = "gov"
2016-03-27 12:47:50 -07:00
)
2016-02-05 23:16:33 -08:00
2016-02-16 12:29:54 -08:00
type Basecoin struct {
2016-02-21 15:09:47 -08:00
eyesCli *eyes.Client
2016-03-15 15:01:53 -07:00
govMint *gov.Governmint
2016-03-22 13:07:03 -07:00
state *state.State
2016-03-27 12:47:50 -07:00
plugins *types.Plugins
2016-02-05 23:16:33 -08:00
}
2016-02-21 15:09:47 -08:00
func NewBasecoin(eyesCli *eyes.Client) *Basecoin {
2016-03-22 13:07:03 -07:00
govMint := gov.NewGovernmint(eyesCli)
2016-03-27 12:47:50 -07:00
state_ := state.NewState(eyesCli)
plugins := types.NewPlugins()
2016-04-18 08:09:19 -07:00
plugins.RegisterPlugin(PluginTypeByteGov, PluginNameGov, govMint)
2016-02-16 12:29:54 -08:00
return &Basecoin{
2016-02-05 23:16:33 -08:00
eyesCli: eyesCli,
2016-03-22 13:07:03 -07:00
govMint: govMint,
2016-03-24 12:17:26 -07:00
state: state_,
2016-03-27 12:47:50 -07:00
plugins: plugins,
2016-02-05 23:16:33 -08:00
}
}
2016-02-08 18:08:55 -08:00
// TMSP::Info
2016-02-16 12:29:54 -08:00
func (app *Basecoin) Info() string {
2016-03-22 13:07:03 -07:00
return Fmt("Basecoin v%v", version)
2016-02-05 23:16:33 -08:00
}
2016-02-08 18:08:55 -08:00
// TMSP::SetOption
2016-02-16 12:29:54 -08:00
func (app *Basecoin) SetOption(key string, value string) (log string) {
2016-04-18 08:09:19 -07:00
PluginName, key := splitKey(key)
if PluginName != PluginNameBase {
// Set option on plugin
2016-04-18 08:09:19 -07:00
plugin := app.plugins.GetByName(PluginName)
if plugin == nil {
2016-04-18 08:09:19 -07:00
return "Invalid plugin name: " + PluginName
2016-02-05 23:16:33 -08:00
}
return plugin.SetOption(key, value)
} else {
// Set option on basecoin
switch key {
case "chainID":
app.state.SetChainID(value)
return "Success"
case "account":
var err error
2016-03-27 23:04:58 -07:00
var acc *types.Account
wire.ReadJSONPtr(&acc, []byte(value), &err)
if err != nil {
2016-03-27 23:04:58 -07:00
return "Error decoding acc message: " + err.Error()
}
2016-03-27 23:04:58 -07:00
app.state.SetAccount(acc.PubKey.Address(), acc)
return "Success"
2016-02-05 23:16:33 -08:00
}
return "Unrecognized option key " + key
2016-02-05 23:16:33 -08:00
}
}
2016-02-08 18:08:55 -08:00
// TMSP::AppendTx
2016-03-20 03:00:43 -07:00
func (app *Basecoin) AppendTx(txBytes []byte) (res tmsp.Result) {
2016-02-05 23:16:33 -08:00
if len(txBytes) > maxTxSize {
return tmsp.ErrBaseEncodingError.AppendLog("Tx size exceeds maximum")
2016-02-05 23:16:33 -08:00
}
// Decode tx
var tx types.Tx
err := wire.ReadBinaryBytes(txBytes, &tx)
if err != nil {
return tmsp.ErrBaseEncodingError.AppendLog("Error decoding tx: " + err.Error())
2016-02-05 23:16:33 -08:00
}
2016-03-22 13:07:03 -07:00
// Validate and exec tx
2016-03-27 12:47:50 -07:00
res = state.ExecTx(app.state, app.plugins, tx, false, nil)
if res.IsErr() {
2016-03-22 13:07:03 -07:00
return res.PrependLog("Error in AppendTx")
2016-02-05 23:16:33 -08:00
}
return tmsp.OK
2016-02-05 23:16:33 -08:00
}
2016-02-08 18:08:55 -08:00
// TMSP::CheckTx
2016-03-20 03:00:43 -07:00
func (app *Basecoin) CheckTx(txBytes []byte) (res tmsp.Result) {
2016-02-05 23:16:33 -08:00
if len(txBytes) > maxTxSize {
return tmsp.ErrBaseEncodingError.AppendLog("Tx size exceeds maximum")
2016-02-05 23:16:33 -08:00
}
// Decode tx
var tx types.Tx
err := wire.ReadBinaryBytes(txBytes, &tx)
if err != nil {
return tmsp.ErrBaseEncodingError.AppendLog("Error decoding tx: " + err.Error())
2016-02-05 23:16:33 -08:00
}
// Validate tx
2016-03-27 12:47:50 -07:00
res = state.ExecTx(app.state, app.plugins, tx, true, nil)
if res.IsErr() {
2016-03-22 13:07:03 -07:00
return res.PrependLog("Error in CheckTx")
2016-02-05 23:16:33 -08:00
}
return tmsp.OK
2016-02-05 23:16:33 -08:00
}
2016-02-08 18:08:55 -08:00
// TMSP::Query
2016-03-20 03:00:43 -07:00
func (app *Basecoin) Query(query []byte) (res tmsp.Result) {
2016-03-27 21:51:04 -07:00
if len(query) == 0 {
return tmsp.ErrEncodingError.SetLog("Query cannot be zero length")
}
typeByte := query[0]
query = query[1:]
switch typeByte {
2016-04-18 08:09:19 -07:00
case PluginTypeByteBase:
2016-03-27 21:51:04 -07:00
return tmsp.OK.SetLog("This type of query not yet supported")
2016-04-18 08:09:19 -07:00
case PluginTypeByteEyes:
2016-03-27 21:51:04 -07:00
return app.eyesCli.QuerySync(query)
2016-04-18 08:09:19 -07:00
case PluginTypeByteGov:
2016-03-27 21:51:04 -07:00
return app.govMint.Query(query)
2016-02-05 23:16:33 -08:00
}
2016-03-27 21:51:04 -07:00
return tmsp.ErrBaseUnknownPlugin.SetLog(
Fmt("Unknown plugin with type byte %X", typeByte))
2016-02-05 23:16:33 -08:00
}
2016-02-14 13:12:38 -08:00
// TMSP::Commit
func (app *Basecoin) Commit() (res tmsp.Result) {
// First, commit all the plugins
2016-03-27 12:47:50 -07:00
for _, plugin := range app.plugins.GetList() {
res = plugin.Commit()
if res.IsErr() {
PanicSanity(Fmt("Error committing plugin %v", plugin.Name))
}
}
// Then, commit eyes.
res = app.eyesCli.CommitSync()
if res.IsErr() {
PanicSanity("Error getting hash: " + res.Error())
2016-02-05 23:16:33 -08:00
}
return res
2016-02-05 23:16:33 -08:00
}
2016-03-15 15:01:53 -07:00
// TMSP::InitChain
func (app *Basecoin) InitChain(validators []*tmsp.Validator) {
2016-04-18 08:09:19 -07:00
for _, plugin := range app.plugins.GetList() {
if _, ok := plugin.Plugin.(tmsp.BlockchainAware); ok {
plugin.Plugin.(tmsp.BlockchainAware).InitChain(validators)
}
}
2016-03-15 15:01:53 -07:00
}
2016-03-29 14:25:17 -07:00
// TMSP::BeginBlock
func (app *Basecoin) BeginBlock(height uint64) {
2016-04-18 08:09:19 -07:00
app.state.ResetCacheState()
for _, plugin := range app.plugins.GetList() {
if _, ok := plugin.Plugin.(tmsp.BlockchainAware); ok {
plugin.Plugin.(tmsp.BlockchainAware).BeginBlock(height)
}
}
2016-03-29 14:25:17 -07:00
}
2016-03-15 15:01:53 -07:00
// TMSP::EndBlock
2016-04-18 08:09:19 -07:00
func (app *Basecoin) EndBlock(height uint64) (vals []*tmsp.Validator) {
for _, plugin := range app.plugins.GetList() {
if plugin.Plugin == app.govMint {
vals = plugin.Plugin.(tmsp.BlockchainAware).EndBlock(height)
} else {
if _, ok := plugin.Plugin.(tmsp.BlockchainAware); ok {
plugin.Plugin.(tmsp.BlockchainAware).EndBlock(height)
}
}
}
return
2016-03-15 15:01:53 -07:00
}
//----------------------------------------
2016-04-17 12:41:26 -07:00
// Splits the string at the first '/'.
// if there are none, the second string is nil.
2016-04-17 12:41:26 -07:00
func splitKey(key string) (prefix string, suffix string) {
2016-03-27 12:47:50 -07:00
if strings.Contains(key, "/") {
keyParts := strings.SplitN(key, "/", 2)
return keyParts[0], keyParts[1]
}
return key, ""
}