Setup custom tendermint node

By exporting all of the commands, we allow users to setup their own
tendermint node cli. This enables users to provide a different
pivValidator without the need to fork tendermint.
This commit is contained in:
Adrian Brink
2017-08-31 10:34:45 +02:00
committed by Ethan Buchman
parent 2c129447fd
commit 83f7d5c95a
3 changed files with 62 additions and 6 deletions

View File

@ -3,10 +3,17 @@ package main
import ( import (
"os" "os"
tc "github.com/tendermint/tendermint/cmd/tendermint/commands"
"github.com/tendermint/tmlibs/cli" "github.com/tendermint/tmlibs/cli"
"github.com/tendermint/tmlibs/log"
"github.com/tendermint/tendermint/cmd/hsm/commands" tc "github.com/tendermint/tendermint/cmd/tendermint/commands"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/types"
)
var (
config = cfg.DefaultConfig()
logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "main")
) )
func main() { func main() {
@ -28,7 +35,9 @@ func main() {
rootCmd.AddCommand(tc.TestnetFilesCmd) rootCmd.AddCommand(tc.TestnetFilesCmd)
rootCmd.AddCommand(tc.VersionCmd) rootCmd.AddCommand(tc.VersionCmd)
rootCmd.AddCommand(commands.RunNodeCmd) privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile(), logger)
privValidator.SetSigner(types.NewDefaultSigner(privValidator.PrivKey))
rootCmd.AddCommand(tc.NewRunNodeCmd(privValidator))
cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv("$HOME/.tendermint")) cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv("$HOME/.tendermint"))
cmd.Execute() cmd.Execute()

View File

@ -5,16 +5,59 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
cmn "github.com/tendermint/tmlibs/common"
"github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/node"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
) )
// RunNodeCmd creates and starts a tendermint node.
var RunNodeCmd = &cobra.Command{ var RunNodeCmd = &cobra.Command{
Use: "node", Use: "node",
Short: "Run the tendermint node", Short: "Run the tendermint node",
RunE: runNode, RunE: runNode,
} }
// NewRunNodeCmd creates and starts a tendermint node. It allows the user to
// use a custom PrivValidator.
func NewRunNodeCmd(privVal *types.PrivValidator) *cobra.Command {
return &cobra.Command{
Use: "node",
Short: "Run the tendermint node",
RunE: func(cmd *cobra.Command, args []string) error {
// Wait until the genesis doc becomes available
// This is for Mintnet compatibility.
// TODO: If Mintnet gets deprecated or genesis_file is
// always available, remove.
genDocFile := config.GenesisFile()
for !cmn.FileExists(genDocFile) {
logger.Info(cmn.Fmt("Waiting for genesis file %v...", genDocFile))
time.Sleep(time.Second)
}
genDoc, err := types.GenesisDocFromFile(genDocFile)
if err != nil {
return err
}
config.ChainID = genDoc.ChainID
// Create & start node
n := node.NewNode(config, privVal, proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), logger)
if _, err := n.Start(); err != nil {
return fmt.Errorf("Failed to start node: %v", err)
} else {
logger.Info("Started node", "nodeInfo", n.Switch().NodeInfo())
}
// Trap signal, run forever.
n.RunForever()
return nil
},
}
}
func init() { func init() {
AddNodeFlags(RunNodeCmd) AddNodeFlags(RunNodeCmd)
} }

View File

@ -35,6 +35,7 @@ func voteToStep(vote *Vote) int8 {
} }
} }
// PrivValidator implements the functionality for signing blocks.
type PrivValidator struct { type PrivValidator struct {
Address data.Bytes `json:"address"` Address data.Bytes `json:"address"`
PubKey crypto.PubKey `json:"pub_key"` PubKey crypto.PubKey `json:"pub_key"`
@ -58,26 +59,29 @@ type PrivValidator struct {
// It is the caller's duty to verify the msg before calling Sign, // It is the caller's duty to verify the msg before calling Sign,
// eg. to avoid double signing. // eg. to avoid double signing.
// Currently, the only callers are SignVote and SignProposal // Currently, the only callers are SignVote and SignProposal
// Signer is an interface that describes how to sign votes.
type Signer interface { type Signer interface {
PubKey() crypto.PubKey PubKey() crypto.PubKey
Sign(msg []byte) (crypto.Signature, error) Sign(msg []byte) (crypto.Signature, error)
} }
// Implements Signer // DefaultSigner implements Signer.
type DefaultSigner struct { type DefaultSigner struct {
priv crypto.PrivKey priv crypto.PrivKey
} }
// NewDefaultSigner returns an instance of DefaultSigner.
func NewDefaultSigner(priv crypto.PrivKey) *DefaultSigner { func NewDefaultSigner(priv crypto.PrivKey) *DefaultSigner {
return &DefaultSigner{priv: priv} return &DefaultSigner{priv: priv}
} }
// Implements Signer // Sign implements Signer. It signs the byte slice with a private key.
func (ds *DefaultSigner) Sign(msg []byte) (crypto.Signature, error) { func (ds *DefaultSigner) Sign(msg []byte) (crypto.Signature, error) {
return ds.priv.Sign(msg), nil return ds.priv.Sign(msg), nil
} }
// Implements Signer // PubKey implements Signer. It should return the public key that corresponds
// to the private key used for signing.
func (ds *DefaultSigner) PubKey() crypto.PubKey { func (ds *DefaultSigner) PubKey() crypto.PubKey {
return ds.priv.PubKey() return ds.priv.PubKey()
} }