commit
f6513738cf
24
app/app.go
24
app/app.go
|
@ -28,12 +28,16 @@ type Basecoin struct {
|
|||
state *Store
|
||||
|
||||
handler sdk.Handler
|
||||
tick Ticker
|
||||
|
||||
pending []*abci.Validator
|
||||
height uint64
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
// Ticker - tick function
|
||||
type Ticker func(sm.SimpleDB) ([]*abci.Validator, error)
|
||||
|
||||
var _ abci.Application = &Basecoin{}
|
||||
|
||||
// NewBasecoin - create a new instance of the basecoin application
|
||||
|
@ -46,6 +50,17 @@ func NewBasecoin(handler sdk.Handler, store *Store, logger log.Logger) *Basecoin
|
|||
}
|
||||
}
|
||||
|
||||
// NewBasecoinTick - create a new instance of the basecoin application with tick functionality
|
||||
func NewBasecoinTick(handler sdk.Handler, store *Store, logger log.Logger, tick Ticker) *Basecoin {
|
||||
return &Basecoin{
|
||||
handler: handler,
|
||||
info: sm.NewChainState(),
|
||||
state: store,
|
||||
logger: logger,
|
||||
tick: tick,
|
||||
}
|
||||
}
|
||||
|
||||
// GetChainID returns the currently stored chain
|
||||
func (app *Basecoin) GetChainID() string {
|
||||
return app.info.GetChainID(app.state.Committed())
|
||||
|
@ -168,9 +183,18 @@ func (app *Basecoin) InitChain(req abci.RequestInitChain) {
|
|||
// BeginBlock - ABCI
|
||||
func (app *Basecoin) BeginBlock(req abci.RequestBeginBlock) {
|
||||
app.height++
|
||||
|
||||
// for _, plugin := range app.plugins.GetList() {
|
||||
// plugin.BeginBlock(app.state, hash, header)
|
||||
// }
|
||||
|
||||
if app.tick != nil {
|
||||
diff, err := app.tick(app.state.Append())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
app.addValChange(diff)
|
||||
}
|
||||
}
|
||||
|
||||
// EndBlock - ABCI
|
||||
|
|
|
@ -35,7 +35,7 @@ func initCmd(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
genesis := getGenesisJSON(viper.GetString(commands.FlagChainID))
|
||||
return commands.CreateGenesisValidatorFiles(cfg, genesis, cmd.Root().Name())
|
||||
return commands.CreateGenesisValidatorFiles(cfg, genesis, commands.StaticPrivValJSON, cmd.Root().Name())
|
||||
}
|
||||
|
||||
// TODO: better, auto-generate validator...
|
||||
|
|
|
@ -2,6 +2,7 @@ package commands
|
|||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
@ -13,25 +14,33 @@ import (
|
|||
|
||||
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
||||
"github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
// InitCmd - node initialization command
|
||||
var InitCmd = &cobra.Command{
|
||||
Use: "init [address]",
|
||||
Short: "Initialize genesis files for a blockchain",
|
||||
RunE: initCmd,
|
||||
}
|
||||
|
||||
//nolint - flags
|
||||
var (
|
||||
// InitCmd - node initialization command
|
||||
InitCmd = GetInitCmd("mycoin")
|
||||
|
||||
//nolint - flags
|
||||
FlagChainID = "chain-id" //TODO group with other flags or remove? is this already a flag here?
|
||||
FlagDenom = "denom" //TODO group with other flags or remove? is this already a flag here?
|
||||
FlagOption = "option"
|
||||
FlagStatic = "static"
|
||||
)
|
||||
|
||||
func init() {
|
||||
InitCmd.Flags().String(FlagChainID, "test_chain_id", "Chain ID")
|
||||
InitCmd.Flags().StringSliceP(FlagOption, "p", []string{}, "Genesis option in the format <app>/<option>/<value>")
|
||||
// GetInitCmd - get the node initialization command, with a custom genesis account denom
|
||||
func GetInitCmd(defaultDenom string) *cobra.Command {
|
||||
initCmd := &cobra.Command{
|
||||
Use: "init [address]",
|
||||
Short: "Initialize genesis files for a blockchain",
|
||||
RunE: initCmd,
|
||||
}
|
||||
initCmd.Flags().String(FlagChainID, "test_chain_id", "Chain ID")
|
||||
initCmd.Flags().String(FlagDenom, defaultDenom, "Coin denomination for genesis account")
|
||||
initCmd.Flags().StringSliceP(FlagOption, "p", []string{}, "Genesis option in the format <app>/<option>/<value>")
|
||||
initCmd.Flags().Bool(FlagStatic, false, "use a static private validator")
|
||||
return initCmd
|
||||
}
|
||||
|
||||
// returns 1 iff it set a file, otherwise 0 (so we can add them)
|
||||
|
@ -91,37 +100,31 @@ func initCmd(cmd *cobra.Command, args []string) error {
|
|||
optionsStr = sep + strings.Join(options[:], sep)
|
||||
}
|
||||
|
||||
genesis := GetGenesisJSON(viper.GetString(FlagChainID), userAddr, optionsStr)
|
||||
return CreateGenesisValidatorFiles(cfg, genesis, cmd.Root().Name())
|
||||
}
|
||||
|
||||
// CreateGenesisValidatorFiles creates a genesis file with these
|
||||
// contents and a private validator file
|
||||
func CreateGenesisValidatorFiles(cfg *config.Config, genesis, appName string) error {
|
||||
genesisFile := cfg.GenesisFile()
|
||||
privValFile := cfg.PrivValidatorFile()
|
||||
|
||||
mod1, err := setupFile(genesisFile, genesis, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mod2, err := setupFile(privValFile, PrivValJSON, 0400)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if (mod1 + mod2) > 0 {
|
||||
msg := fmt.Sprintf("Initialized %s", appName)
|
||||
logger.Info(msg, "genesis", genesisFile, "priv_validator", privValFile)
|
||||
var privValJSON, pubkey string
|
||||
if viper.GetBool(FlagStatic) {
|
||||
privValJSON = StaticPrivValJSON
|
||||
pubkey = StaticPK
|
||||
} else {
|
||||
logger.Info("Already initialized", "priv_validator", privValFile)
|
||||
|
||||
privVal := types.GenPrivValidatorFS("")
|
||||
pubkey = strings.ToUpper(hex.EncodeToString(privVal.PubKey.Bytes()[1:]))
|
||||
pvBytes, err := json.Marshal(privVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
privValJSON = string(pvBytes)
|
||||
}
|
||||
|
||||
return nil
|
||||
genesis := GetGenesisJSON(pubkey, viper.GetString(FlagChainID), viper.GetString(FlagDenom),
|
||||
userAddr, optionsStr)
|
||||
return CreateGenesisValidatorFiles(cfg, genesis, privValJSON, cmd.Root().Name())
|
||||
}
|
||||
|
||||
// PrivValJSON - validator private key file contents in json
|
||||
var PrivValJSON = `{
|
||||
// StaticPK - static public key for test cases
|
||||
var StaticPK = "7B90EA87E7DC0C7145C8C48C08992BE271C7234134343E8A8E8008E617DE7B30"
|
||||
|
||||
// StaticPrivValJSON - static validator private key file contents in json
|
||||
var StaticPrivValJSON = `{
|
||||
"address": "7A956FADD20D3A5B2375042B2959F8AB172A058F",
|
||||
"last_height": 0,
|
||||
"last_round": 0,
|
||||
|
@ -138,10 +141,35 @@ var PrivValJSON = `{
|
|||
}
|
||||
}`
|
||||
|
||||
// CreateGenesisValidatorFiles creates a genesis file with these
|
||||
// contents and a private validator file
|
||||
func CreateGenesisValidatorFiles(cfg *config.Config, genesis, privVal, appName string) error {
|
||||
privValFile := cfg.PrivValidatorFile()
|
||||
genesisFile := cfg.GenesisFile()
|
||||
|
||||
mod1, err := setupFile(genesisFile, genesis, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mod2, err := setupFile(privValFile, privVal, 0400)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if (mod1 + mod2) > 0 {
|
||||
msg := fmt.Sprintf("Initialized %s", appName)
|
||||
logger.Info(msg, "genesis", genesisFile, "priv_validator", privValFile)
|
||||
} else {
|
||||
logger.Info("Already initialized", "priv_validator", privValFile)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetGenesisJSON returns a new tendermint genesis with Basecoin app_options
|
||||
// that grant a large amount of "mycoin" to a single address
|
||||
// TODO: A better UX for generating genesis files
|
||||
func GetGenesisJSON(chainID, addr string, options string) string {
|
||||
func GetGenesisJSON(pubkey, chainID, denom, addr string, options string) string {
|
||||
return fmt.Sprintf(`{
|
||||
"app_hash": "",
|
||||
"chain_id": "%s",
|
||||
|
@ -152,7 +180,7 @@ func GetGenesisJSON(chainID, addr string, options string) string {
|
|||
"name": "",
|
||||
"pub_key": {
|
||||
"type": "ed25519",
|
||||
"data": "7B90EA87E7DC0C7145C8C48C08992BE271C7234134343E8A8E8008E617DE7B30"
|
||||
"data": "%s"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -161,7 +189,7 @@ func GetGenesisJSON(chainID, addr string, options string) string {
|
|||
"address": "%s",
|
||||
"coins": [
|
||||
{
|
||||
"denom": "mycoin",
|
||||
"denom": "%s",
|
||||
"amount": 9007199254740992
|
||||
}
|
||||
]
|
||||
|
@ -170,5 +198,5 @@ func GetGenesisJSON(chainID, addr string, options string) string {
|
|||
"coin/issuer", {"app": "sigs", "addr": "%s"}%s
|
||||
]
|
||||
}
|
||||
}`, chainID, addr, addr, options)
|
||||
}`, chainID, pubkey, addr, denom, addr, options)
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
"github.com/tendermint/abci/server"
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/tmlibs/cli"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
|
||||
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/tendermint/tendermint/proxy"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
"github.com/cosmos/cosmos-sdk/app"
|
||||
)
|
||||
|
||||
|
@ -29,6 +30,18 @@ var StartCmd = &cobra.Command{
|
|||
RunE: startCmd,
|
||||
}
|
||||
|
||||
// GetTickStartCmd - initialize a command as the start command with tick
|
||||
func GetTickStartCmd(tick app.Ticker) *cobra.Command {
|
||||
startCmd := &cobra.Command{
|
||||
Use: "start",
|
||||
Short: "Start this full node",
|
||||
RunE: startCmd,
|
||||
}
|
||||
startCmd.RunE = tickStartCmd(tick)
|
||||
addStartFlag(startCmd)
|
||||
return startCmd
|
||||
}
|
||||
|
||||
// nolint TODO: move to config file
|
||||
const EyesCacheSize = 10000
|
||||
|
||||
|
@ -45,11 +58,35 @@ var (
|
|||
)
|
||||
|
||||
func init() {
|
||||
flags := StartCmd.Flags()
|
||||
addStartFlag(StartCmd)
|
||||
}
|
||||
|
||||
func addStartFlag(startCmd *cobra.Command) {
|
||||
flags := startCmd.Flags()
|
||||
flags.String(FlagAddress, "tcp://0.0.0.0:46658", "Listen address")
|
||||
flags.Bool(FlagWithoutTendermint, false, "Only run abci app, assume external tendermint process")
|
||||
// add all standard 'tendermint node' flags
|
||||
tcmd.AddNodeFlags(StartCmd)
|
||||
tcmd.AddNodeFlags(startCmd)
|
||||
}
|
||||
|
||||
//returns the start command which uses the tick
|
||||
func tickStartCmd(tick app.Ticker) func(cmd *cobra.Command, args []string) error {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
rootDir := viper.GetString(cli.HomeFlag)
|
||||
|
||||
store, err := app.NewStore(
|
||||
path.Join(rootDir, "data", "merkleeyes.db"),
|
||||
EyesCacheSize,
|
||||
logger.With("module", "store"),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create Basecoin app
|
||||
basecoinApp := app.NewBasecoinTick(Handler, store, logger.With("module", "app"), tick)
|
||||
return start(rootDir, store, basecoinApp)
|
||||
}
|
||||
}
|
||||
|
||||
func startCmd(cmd *cobra.Command, args []string) error {
|
||||
|
@ -63,9 +100,12 @@ func startCmd(cmd *cobra.Command, args []string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create Basecoin app
|
||||
basecoinApp := app.NewBasecoin(Handler, store, logger.With("module", "app"))
|
||||
return start(rootDir, store, basecoinApp)
|
||||
}
|
||||
|
||||
func start(rootDir string, store *app.Store, basecoinApp *app.Basecoin) error {
|
||||
|
||||
// if chain_id has not been set yet, load the genesis.
|
||||
// else, assume it's been loaded
|
||||
|
@ -93,7 +133,7 @@ func startCmd(cmd *cobra.Command, args []string) error {
|
|||
return startTendermint(rootDir, basecoinApp)
|
||||
}
|
||||
|
||||
func startBasecoinABCI(basecoinApp *app.Basecoin) error {
|
||||
func startBasecoinABCI(basecoinApp abci.Application) error {
|
||||
// Start the ABCI listener
|
||||
addr := viper.GetString(FlagAddress)
|
||||
svr, err := server.NewServer(addr, "socket", basecoinApp)
|
||||
|
@ -111,7 +151,7 @@ func startBasecoinABCI(basecoinApp *app.Basecoin) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func startTendermint(dir string, basecoinApp *app.Basecoin) error {
|
||||
func startTendermint(dir string, basecoinApp abci.Application) error {
|
||||
cfg, err := tcmd.ParseConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -34,7 +34,7 @@ var _ sdk.Context = secureContext{}
|
|||
func (c secureContext) WithPermissions(perms ...sdk.Actor) sdk.Context {
|
||||
// the guard makes sure you only set permissions for the app you are inside
|
||||
for _, p := range perms {
|
||||
if !c.validPermisison(p) {
|
||||
if !c.validPermission(p) {
|
||||
err := errors.Errorf("Cannot set permission for %s/%s on (app=%s, ibc=%b)",
|
||||
p.ChainID, p.App, c.app, c.ibc)
|
||||
panic(err)
|
||||
|
@ -48,7 +48,7 @@ func (c secureContext) WithPermissions(perms ...sdk.Actor) sdk.Context {
|
|||
}
|
||||
}
|
||||
|
||||
func (c secureContext) validPermisison(p sdk.Actor) bool {
|
||||
func (c secureContext) validPermission(p sdk.Actor) bool {
|
||||
// if app is set, then it must match
|
||||
if c.app != "" && c.app != p.App {
|
||||
return false
|
||||
|
|
|
@ -65,7 +65,7 @@ initServer() {
|
|||
SERVER_LOG=$1/${SERVER_EXE}.log
|
||||
|
||||
GENKEY=$(${CLIENT_EXE} keys get ${RICH} | awk '{print $2}')
|
||||
${SERVER_EXE} init --chain-id $CHAIN $GENKEY --home=$SERVE_DIR >>$SERVER_LOG
|
||||
${SERVER_EXE} init --static --chain-id $CHAIN $GENKEY --home=$SERVE_DIR >>$SERVER_LOG
|
||||
|
||||
# optionally set the port
|
||||
if [ -n "$3" ]; then
|
||||
|
|
Loading…
Reference in New Issue