init append functionality complete

This commit is contained in:
rigelrozanski 2018-04-23 15:15:50 -04:00
parent 556896679a
commit c8f5fcb27b
5 changed files with 92 additions and 10 deletions

View File

@ -27,7 +27,7 @@ import (
// TODO flag to retrieve genesis file / config file from a URL?
// get cmd to initialize all files for tendermint and application
func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState AppendAppState) *cobra.Command {
flagOverwrite, flagAppendFile := "overwrite", "piece-file"
flagOverwrite, flagPieceFile := "overwrite", "piece-file"
cmd := &cobra.Command{
Use: "init",
Short: "Initialize genesis config, priv-validator file, and p2p-node file",
@ -56,15 +56,17 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState Append
if err != nil {
return err
}
nodeID := string(nodeKey.ID())
// print out some key information
toPrint := struct {
ChainID string `json:"chain_id"`
NodeID string `json:"node_id"`
AppMessage json.RawMessage `json:"app_message"`
}{
chainID,
string(nodeKey.ID()),
nodeID,
cliPrint,
}
out, err := wire.MarshalJSONIndent(cdc, toPrint)
@ -72,12 +74,35 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState Append
return err
}
fmt.Println(string(out))
// write the piece file is path specified
pieceFile := viper.GetString(flagPieceFile)
if len(pieceFile) > 0 {
//create the piece
ip, err := externalIP()
if err != nil {
return err
}
piece := GenesisPiece{
ChainID: chainID,
NodeID: nodeID,
IP: ip,
AppState: appState,
Validators: validators,
}
bz, err := cdc.MarshalJSON(piece)
if err != nil {
return err
}
return cmn.WriteFile(pieceFile, bz, 0644)
}
return nil
},
}
if appendState != nil {
cmd.AddCommand(FromPiecesCmd(ctx, cdc, appendState))
cmd.Flags().BoolP(flagAppendFile, "a", false, "create an append file for others to import")
cmd.Flags().StringP(flagPieceFile, "a", "", "create an append file for others to import")
}
cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the config file")
return cmd
@ -87,6 +112,7 @@ func InitCmd(ctx *Context, cdc *wire.Codec, gen GenAppParams, appendState Append
type GenesisPiece struct {
ChainID string `json:"chain_id"`
NodeID string `json:"node_id"`
IP string `json:"ip"`
AppState json.RawMessage `json:"app_state"`
Validators []tmtypes.GenesisValidator `json:"validators"`
}
@ -116,7 +142,7 @@ func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appendState AppendAppState) *c
os.Remove(genFile)
// deterministically walk the directory for genesis-piece files to import
filepath.Walk(pieceDir, appendPiece(cdc, appendState, nodeKeyFile, genFile))
filepath.Walk(pieceDir, appendPiece(ctx, cdc, appendState, nodeKeyFile, genFile))
return nil
},
@ -124,7 +150,7 @@ func FromPiecesCmd(ctx *Context, cdc *wire.Codec, appendState AppendAppState) *c
}
// append a genesis-piece
func appendPiece(cdc *wire.Codec, appendState AppendAppState, nodeKeyFile, genFile string) filepath.WalkFunc {
func appendPiece(ctx *Context, cdc *wire.Codec, appendState AppendAppState, nodeKeyFile, genFile string) filepath.WalkFunc {
return func(pieceFile string, _ os.FileInfo, err error) error {
if err != nil {
return err
@ -185,7 +211,17 @@ func appendPiece(cdc *wire.Codec, appendState AppendAppState, nodeKeyFile, genFi
// write the appended genesis file
return WriteGenesisFile(cdc, genFile, piece.ChainID, validators, appState)
// XXX XXX XXX read in configTOMBL and combine new nodeID file
// Add a persistent peer if the config (if it's not me)
myIP, err := externalIP()
if err != nil {
return err
}
if myIP == piece.IP {
return nil
}
ctx.Config.P2P.PersistentPeers += fmt.Sprintf(",%s@%s", piece.NodeID, piece.IP)
configFilePath := filepath.Join(viper.GetString("home"), "config", "config.toml") //TODO this is annoying should be easier to get
cfg.WriteConfigFile(configFilePath, ctx.Config)
return nil
}

View File

@ -8,6 +8,7 @@ import (
"github.com/tendermint/tmlibs/log"
"github.com/cosmos/cosmos-sdk/mock"
"github.com/cosmos/cosmos-sdk/wire"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
)
@ -18,7 +19,8 @@ func TestInit(t *testing.T) {
cfg, err := tcmd.ParseConfig()
require.Nil(t, err)
ctx := NewContext(cfg, logger)
cmd := InitCmd(ctx, cdc, mock.GenAppParams)
cdc := wire.NewCodec()
cmd := InitCmd(ctx, cdc, mock.GenAppParams, nil)
err = cmd.RunE(nil, nil)
require.NoError(t, err)
}

View File

@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/mock"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/tendermint/abci/server"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
"github.com/tendermint/tmlibs/log"
@ -25,7 +26,8 @@ func TestStartStandAlone(t *testing.T) {
cfg, err := tcmd.ParseConfig()
require.Nil(t, err)
ctx := NewContext(cfg, logger)
initCmd := InitCmd(ctx, cdc, mock.GenAppParams)
cdc := wire.NewCodec()
initCmd := InitCmd(ctx, cdc, mock.GenAppParams, nil)
err = initCmd.RunE(nil, nil)
require.NoError(t, err)
@ -51,7 +53,8 @@ func TestStartWithTendermint(t *testing.T) {
cfg, err := tcmd.ParseConfig()
require.Nil(t, err)
ctx := NewContext(cfg, logger)
initCmd := InitCmd(ctx, cdc, mock.GenAppParams)
cdc := wire.NewCodec()
initCmd := InitCmd(ctx, cdc, mock.GenAppParams, nil)
err = initCmd.RunE(nil, nil)
require.NoError(t, err)

View File

@ -2,8 +2,10 @@ package server
import (
"encoding/json"
"net"
"os"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
@ -93,3 +95,42 @@ func AppendJSON(cdc *wire.Codec, baseJSON []byte, key string, value json.RawMess
bz, err := wire.MarshalJSONIndent(cdc, jsonMap)
return json.RawMessage(bz), err
}
// https://stackoverflow.com/questions/23558425/how-do-i-get-the-local-ip-address-in-go
// TODO there must be a better way to get external IP
func externalIP() (string, error) {
ifaces, err := net.Interfaces()
if err != nil {
return "", err
}
for _, iface := range ifaces {
if iface.Flags&net.FlagUp == 0 {
continue // interface down
}
if iface.Flags&net.FlagLoopback != 0 {
continue // loopback interface
}
addrs, err := iface.Addrs()
if err != nil {
return "", err
}
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
if ip == nil || ip.IsLoopback() {
continue
}
ip = ip.To4()
if ip == nil {
continue // not an ipv4 address
}
return ip.String(), nil
}
}
return "", errors.New("are you connected to the network?")
}

View File

@ -12,6 +12,7 @@ import (
//func AppendJSON(cdc *wire.Codec, baseJSON []byte, key string, value json.RawMessage) (appended []byte, err error) {
func TestAppendJSON(t *testing.T) {
cdc := wire.NewCodec()
foo := map[string]string{"foo": "foofoo"}
bar := map[string]string{"barInner": "barbar"}
@ -26,7 +27,6 @@ func TestAppendJSON(t *testing.T) {
barRaw := json.RawMessage(bz)
// make the append
cdc := wire.NewCodec()
appBz, err := AppendJSON(cdc, fooRaw, "barOuter", barRaw)
require.NoError(t, err)