From 525f8e9e1ea537bf7e49ae3fcb412a365830a246 Mon Sep 17 00:00:00 2001
From: zramsay <zach@monax.io>
Date: Mon, 14 Nov 2016 14:43:39 -0500
Subject: [PATCH] gut GenesisKnown & use go-crypto

---
 client/cmd/genesis.go        |  40 +++++-----
 genesis/make_genesis_file.go | 141 +++++++++--------------------------
 2 files changed, 55 insertions(+), 126 deletions(-)

diff --git a/client/cmd/genesis.go b/client/cmd/genesis.go
index 31f2e7c9..d0aa5e26 100644
--- a/client/cmd/genesis.go
+++ b/client/cmd/genesis.go
@@ -6,6 +6,18 @@ import (
 	"github.com/spf13/cobra"
 )
 
+// TODO refactor these vars into a struct?
+var (
+	//DirFlag string
+	//AddrsFlag  string
+	AccountsPathFlag   string
+	ValidatorsPathFlag string
+	//CsvPathFlag        string
+	//PubkeyFlag         string
+	//RootFlag           string
+	//NoValAccountsFlag  bool
+)
+
 var GenesisGenCmd = &cobra.Command{
 	Use:   "genesis",
 	Short: "eris-client genesis creates a genesis.json with known inputs",
@@ -13,32 +25,16 @@ var GenesisGenCmd = &cobra.Command{
 
 	Run: func(cmd *cobra.Command, args []string) {
 
-		genesis.GenerateKnown("thisIsChainID", "", "114234767676")
+		genesis.GenerateKnown(args[0], AccountsPathFlag, ValidatorsPathFlag)
 
 	},
 }
 
 func buildGenesisGenCommand() {
-	//addTransactionPersistentFlags()
+	addGenesisPersistentFlags()
 }
 
-var (
-	DirFlag string
-	//AddrsFlag  string
-	CsvPathFlag       string
-	PubkeyFlag        string
-	RootFlag          string
-	NoValAccountsFlag bool
-)
-
-//var knownCmd = &cobra.Command{
-//	Use:   "known",
-//	Short: "mintgen known <chain_id> [flags] ",
-//	Long:  "Create a genesis.json with --pub <pub_1> <pub_2> <pub_N> or with --csv <path_to_file>, or pass a priv_validator.json on stdin. Two csv file names can be passed (comma separated) to distinguish validators and accounts.",
-//	//Run:   cliKnown,
-//}
-//
-//
-//knownCmd.Flags().StringVarP(&PubkeyFlag, "pub", "", "", "pubkeys to include when generating genesis.json. flag is req'd")
-//knownCmd.Flags().StringVarP(&CsvPathFlag, "csv", "", "", "path to .csv with the following params: (pubkey, starting balance, name, permissions, setbit")
-//
+func addGenesisPersistentFlags() {
+	GenesisGenCmd.Flags().StringVarP(&AccountsPathFlag, "accounts", "", "", "path to accounts.csv with the following params: (pubkey, starting balance, name, permissions, setbit")
+	GenesisGenCmd.Flags().StringVarP(&ValidatorsPathFlag, "validators", "", "", "path to validators.csv with the following params: (pubkey, starting balance, name, permissions, setbit")
+}
diff --git a/genesis/make_genesis_file.go b/genesis/make_genesis_file.go
index fc9043e0..fe2ceacd 100644
--- a/genesis/make_genesis_file.go
+++ b/genesis/make_genesis_file.go
@@ -6,75 +6,46 @@ import (
 	"encoding/hex"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"strconv"
-	"strings"
-	"time"
 
 	"github.com/eris-ltd/common/go/common"
 	stypes "github.com/eris-ltd/eris-db/manager/eris-mint/state/types"
 	ptypes "github.com/eris-ltd/eris-db/permission/types"
-	wire "github.com/tendermint/go-wire"
-
-	// TODO
-	"github.com/eris-ltd/mint-client/Godeps/_workspace/src/github.com/eris-ltd/tendermint/types"
 
-	// TODO
-	"github.com/eris-ltd/mint-client/Godeps/_workspace/src/github.com/eris-ltd/tendermint/account"
-	//"github.com/eris-ltd/eris-db/account"
+	"github.com/tendermint/go-crypto"
+	wire "github.com/tendermint/go-wire"
 )
 
 //------------------------------------------------------------------------------------
 // core functions
 
-func GenerateKnown(chainID, csvFile, pubKeys string) ([]byte, error) {
+func GenerateKnown(chainID, accountsPathCSV, validatorsPathCSV string) ([]byte, error) {
 	var genDoc *stypes.GenesisDoc
 	var err error
-	// either we pass the name of a csv file or we read a priv_validator over stdin
-	// TODO eliminate reading priv_val
-	if csvFile != "" {
-		var csvValidators, csvAccounts string
-		csvFiles := strings.Split(csvFile, ",")
-		csvValidators = csvFiles[0]
-		if len(csvFiles) > 1 {
-			csvAccounts = csvFiles[1]
-		}
-		pubkeys, amts, names, perms, setbits, err := parseCsv(csvValidators)
-		if err != nil {
-			return nil, err
-		}
 
-		if csvAccounts == "" {
-			genDoc = newGenDoc(chainID, len(pubkeys), len(pubkeys))
-			for i, pk := range pubkeys {
-				genDocAddAccountAndValidator(genDoc, pk, amts[i], names[i], perms[i], setbits[i], i)
-			}
-		} else {
-			pubkeysA, amtsA, namesA, permsA, setbitsA, err := parseCsv(csvAccounts)
-			if err != nil {
-				return nil, err
-			}
-			genDoc = newGenDoc(chainID, len(pubkeys), len(pubkeysA))
-			for i, pk := range pubkeys {
-				genDocAddValidator(genDoc, pk, amts[i], names[i], perms[i], setbits[i], i)
-			}
-			for i, pk := range pubkeysA {
-				genDocAddAccount(genDoc, pk, amtsA[i], namesA[i], permsA[i], setbitsA[i], i)
-			}
-		}
-	} else if pubKeys != "" {
-		pubkeys := strings.Split(pubKeys, ",")
-		amt := int64(1) << 50
-		pubKeys := pubKeyStringsToPubKeys(pubkeys)
-		genDoc = newGenDoc(chainID, len(pubkeys), len(pubkeys))
+	// TODO [eb] eliminate reading priv_val ... [zr] where?
+	if accountsPathCSV == "" || validatorsPathCSV == "" {
+		return []byte{}, fmt.Errorf("both accounts.csv and validators.csv is required")
 
-		for i, pk := range pubKeys {
-			genDocAddAccountAndValidator(genDoc, pk, amt, "", ptypes.DefaultPermFlags, ptypes.DefaultPermFlags, i)
-		}
-	} else {
-		privJSON := readStdinTimeout()
-		genDoc = genesisFromPrivValBytes(chainID, privJSON)
+	}
+
+	pubkeys, amts, names, perms, setbits, err := parseCsv(validatorsPathCSV)
+	if err != nil {
+		return nil, err
+	}
+
+	pubkeysA, amtsA, namesA, permsA, setbitsA, err := parseCsv(accountsPathCSV)
+	if err != nil {
+		return nil, err
+	}
+
+	genDoc = newGenDoc(chainID, len(pubkeys), len(pubkeysA))
+	for i, pk := range pubkeys {
+		genDocAddValidator(genDoc, pk, amts[i], names[i], perms[i], setbits[i], i)
+	}
+	for i, pk := range pubkeysA {
+		genDocAddAccount(genDoc, pk, amtsA[i], namesA[i], permsA[i], setbitsA[i], i)
 	}
 
 	buf, buf2, n := new(bytes.Buffer), new(bytes.Buffer), new(int)
@@ -103,24 +74,7 @@ func newGenDoc(chainID string, nVal, nAcc int) *stypes.GenesisDoc {
 	return &genDoc
 }
 
-// genesis file with only one validator, using priv_validator.json
-func genesisFromPrivValBytes(chainID string, privJSON []byte) *stypes.GenesisDoc {
-	var err error
-	privVal := wire.ReadJSON(&types.PrivValidator{}, privJSON, &err).(*types.PrivValidator)
-	if err != nil {
-		common.Exit(fmt.Errorf("Error reading PrivValidator on stdin: %v\n", err))
-	}
-	pubKey := privVal.PubKey
-	amt := int64(1) << 50
-
-	genDoc := newGenDoc(chainID, 1, 1)
-
-	genDocAddAccountAndValidator(genDoc, pubKey, amt, "", ptypes.DefaultPermFlags, ptypes.DefaultPermFlags, 0)
-
-	return genDoc
-}
-
-func genDocAddAccount(genDoc *stypes.GenesisDoc, pubKey account.PubKeyEd25519, amt int64, name string, perm, setbit ptypes.PermFlag, index int) {
+func genDocAddAccount(genDoc *stypes.GenesisDoc, pubKey crypto.PubKeyEd25519, amt int64, name string, perm, setbit ptypes.PermFlag, index int) {
 	addr := pubKey.Address()
 	acc := stypes.GenesisAccount{
 		Address: addr,
@@ -140,7 +94,7 @@ func genDocAddAccount(genDoc *stypes.GenesisDoc, pubKey account.PubKeyEd25519, a
 	}
 }
 
-func genDocAddValidator(genDoc *stypes.GenesisDoc, pubKey account.PubKeyEd25519, amt int64, name string, perm, setbit ptypes.PermFlag, index int) {
+func genDocAddValidator(genDoc *stypes.GenesisDoc, pubKey crypto.PubKeyEd25519, amt int64, name string, perm, setbit ptypes.PermFlag, index int) {
 	addr := pubKey.Address()
 	genDoc.Validators[index] = stypes.GenesisValidator{
 		PubKey: pubKey,
@@ -153,27 +107,23 @@ func genDocAddValidator(genDoc *stypes.GenesisDoc, pubKey account.PubKeyEd25519,
 			},
 		},
 	}
-}
-
-func genDocAddAccountAndValidator(genDoc *stypes.GenesisDoc, pubKey account.PubKeyEd25519, amt int64, name string, perm, setbit ptypes.PermFlag, index int) {
-	genDocAddAccount(genDoc, pubKey, amt, name, perm, setbit, index)
-	genDocAddValidator(genDoc, pubKey, amt, name, perm, setbit, index)
+	// [zr] why no index < 0 like in genDocAddAccount?
 }
 
 //-----------------------------------------------------------------------------
 // util functions
 
 // convert hex strings to ed25519 pubkeys
-func pubKeyStringsToPubKeys(pubkeys []string) []account.PubKeyEd25519 {
-	pubKeys := make([]account.PubKeyEd25519, len(pubkeys))
+func pubKeyStringsToPubKeys(pubkeys []string) ([]crypto.PubKeyEd25519, error) {
+	pubKeys := make([]crypto.PubKeyEd25519, len(pubkeys))
 	for i, k := range pubkeys {
 		pubBytes, err := hex.DecodeString(k)
 		if err != nil {
-			common.Exit(fmt.Errorf("Pubkey (%s) is invalid hex: %v", k, err))
+			return pubKeys, err
 		}
 		copy(pubKeys[i][:], pubBytes)
 	}
-	return pubKeys
+	return pubKeys, nil
 }
 
 // empty is over written
@@ -186,8 +136,8 @@ func ifExistsElse(list []string, index int, defaultValue string) string {
 	return defaultValue
 }
 
-//takes a csv in the format defined [here]
-func parseCsv(filePath string) (pubKeys []account.PubKeyEd25519, amts []int64, names []string, perms, setbits []ptypes.PermFlag, err error) {
+// takes a csv in the following format: pubkey, starting balance, name, permissions, setbit
+func parseCsv(filePath string) (pubKeys []crypto.PubKeyEd25519, amts []int64, names []string, perms, setbits []ptypes.PermFlag, err error) {
 
 	csvFile, err := os.Open(filePath)
 	if err != nil {
@@ -244,27 +194,10 @@ func parseCsv(filePath string) (pubKeys []account.PubKeyEd25519, amts []int64, n
 	}
 
 	// convert pubkey hex strings to struct
-	pubKeys = pubKeyStringsToPubKeys(pubkeys)
+	pubKeys, err = pubKeyStringsToPubKeys(pubkeys)
+	if err != nil {
+		return
+	}
 
 	return pubKeys, amts, names, perms, setbits, nil
 }
-
-const stdinTimeoutSeconds = 1
-
-// read the priv validator json off stdin or timeout and fail
-func readStdinTimeout() []byte {
-	ch := make(chan []byte, 1)
-	go func() {
-		privJSON, err := ioutil.ReadAll(os.Stdin)
-		common.IfExit(err)
-		ch <- privJSON
-	}()
-	ticker := time.Tick(time.Second * stdinTimeoutSeconds)
-	select {
-	case <-ticker:
-		common.Exit(fmt.Errorf("Please pass a priv_validator.json on stdin, or specify either a pubkey with --pub or csv file with --csv"))
-	case privJSON := <-ch:
-		return privJSON
-	}
-	return nil
-}
-- 
GitLab