Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hamdi/config #157

Merged
merged 8 commits into from
Jul 6, 2019
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func SetPlasmaOptionsFromConfig(conf config.PlasmaConfig) func(*PlasmaMVPChain)
var blockFinality uint64

if conf.IsOperator {
d, err := hex.DecodeString(conf.EthOperatorPrivateKey)
d, err := hex.DecodeString(conf.OperatorPrivateKey)

if err != nil {
errMsg := fmt.Sprintf("Could not parse private key: %v", err)
Expand Down
4 changes: 2 additions & 2 deletions cmd/plasmacli/config/cobra.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import (
)

func AddPersistentTMFlags(cmd *cobra.Command) {
cmd.PersistentFlags().String(client.FlagNode, "tcp://localhost:26657", "<host>:<port> to tendermint rpc interface for this chain")
cmd.PersistentFlags().String(client.FlagNode, "", "<host>:<port> to tendermint rpc interface for this chain")
cmd.PersistentFlags().Bool(client.FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)")
cmd.PersistentFlags().String(client.FlagChainID, "", "id of the chain. Required if --trust-node=false")
viper.BindPFlag(client.FlagNode, cmd.PersistentFlags().Lookup(client.FlagNode))
viper.BindPFlag(client.FlagTrustNode, cmd.PersistentFlags().Lookup(client.FlagTrustNode))
viper.BindPFlag(client.FlagChainID, cmd.PersistentFlags().Lookup(client.FlagChainID))
viper.BindPFlag(client.FlagNode, cmd.PersistentFlags().Lookup(client.FlagNode))
}
87 changes: 71 additions & 16 deletions cmd/plasmacli/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,121 @@ package config
import (
"bytes"
"fmt"
"github.com/cosmos/cosmos-sdk/client"
"github.com/spf13/viper"
cmn "github.com/tendermint/tendermint/libs/common"
"os"
"path/filepath"
"strings"
"text/template"
)

const defaultConfigTemplate = `# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml

##### ethereum config options #####
##### ethereum configuration #####

# Ethereum plasma contract address
ethereum_plasma_contract_address = "{{ .EthPlasmaContractAddr }}"
ethereum_contract_address = "{{ .EthPlasmaContractAddr }}"

# Node URL for eth client
ethereum_nodeurl = "{{ .EthNodeURL }}"

# Number of Ethereum blocks until a transaction is considered final
ethereum_finality = "{{ .EthBlockFinality }}"`

##### plasamd configuration #####

# Node URL for plasmad
node = "{{ .PlasmadNodeURL }}"

# Trust the connected plasmad node (don't verify proofs for responses)
trust_node = {{ .PlasmadTrustNode }}

# Chain identifier. Must be set if trust-node == false
chain_id = "{{ .PlasmadChainID }}"`

// Must match the above defaultConfigTemplate
type PlasmaConfig struct {
EthPlasmaContractAddr string `mapstructure:"ethereum_plasma_contract_address"`
type Config struct {
// Ethereum config
EthPlasmaContractAddr string `mapstructure:"ethereum_contract_address"`
EthNodeURL string `mapstructure:"ethereum_nodeurl"`
EthBlockFinality string `mapstructure:"ethereum_finality"`
hamdiallam marked this conversation as resolved.
Show resolved Hide resolved

// Plasmad config
PlasmadNodeURL string `mapstructure:"node"`
PlasmadTrustNode bool `mapstructure:"trust_node"`
PlasmadChainID string `mapstructure:"chain_id"`
}

var configTemplate *template.Template

func init() {
var err error
tmpl := template.New("plasmaConfigFileTemplate")
tmpl := template.New("configFileTemplate")
if configTemplate, err = tmpl.Parse(defaultConfigTemplate); err != nil {
panic(err)
}

// ensure that none of the cosmos-cli flags have changed
var changed bool
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
if client.FlagNode != "node" {
changed = true
} else if client.FlagTrustNode != "trust-node" {
changed = true
} else if client.FlagChainID != "chain-id" {
changed = true
}

if changed {
panic("cosmos client flags have changed. adjust the config file")
}

}

func DefaultPlasmaConfig() PlasmaConfig {
return PlasmaConfig{"", "http://localhost:8545", "0"}
func DefaultConfig() Config {
return Config{
EthPlasmaContractAddr: "",
EthNodeURL: "http://localhost:8545",
PlasmadNodeURL: "tcp://localhost:26657",
PlasmadTrustNode: false,
PlasmadChainID: "",
}
}

// RegisterViper will match client flags with config and register env
func RegisterViperAndEnv() {
viper.SetEnvPrefix("PCLI")
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
viper.AutomaticEnv()

// The configuration files use underscores while the Cosmos SDK uses
// hypens. These aliases align `Viper.Get(..)` for both
// the SDK and the configuration file
viper.RegisterAlias("trust_node", "trust-node")
viper.RegisterAlias("chain_id", "chain-id")
}

// parses the plasma.toml file and unmarshals it into a Config struct
func ParsePlasmaConfigFromViper() (PlasmaConfig, error) {
config := DefaultPlasmaConfig()
func ParseConfigFromViper() (Config, error) {
config := Config{}
err := viper.Unmarshal(&config)
return config, err
}

// WriteConfigFile renders config using the template and writes it to configFilePath.
func WritePlasmaConfigFile(configFilePath string, config PlasmaConfig) {
func WriteConfigFile(configFilePath string, config Config) error {
var buffer bytes.Buffer

if err := configTemplate.Execute(&buffer, &config); err != nil {
panic(err)
return fmt.Errorf("template: %s", err)
}

if err := cmn.EnsureDir(filepath.Dir(configFilePath), os.ModePerm); err != nil {
fmt.Printf("ERROR: failed to create directory: %s, recieved error: { %s }", filepath.Dir(configFilePath), err)
return fmt.Errorf("ensuredir: %s", err)
}

// 0666 allows for read and write for any user
cmn.MustWriteFile(configFilePath, buffer.Bytes(), 0666)
if err := cmn.WriteFile(configFilePath, buffer.Bytes(), 0666); err != nil {
return fmt.Errorf("writefile: %s", err)
}

return nil
}
36 changes: 9 additions & 27 deletions cmd/plasmacli/config/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ package config

import (
"fmt"
"github.com/FourthState/plasma-mvp-sidechain/cmd/plasmacli/store"
"github.com/FourthState/plasma-mvp-sidechain/cmd/plasmacli/flags"
"github.com/FourthState/plasma-mvp-sidechain/eth"
ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/spf13/viper"
"os"
"path/filepath"
"strconv"
)

var plasmaContract *eth.Plasma
Expand All @@ -28,42 +25,27 @@ func GetContractConn() (*eth.Plasma, error) {
}

func setupContractConn() (*eth.Plasma, error) {
// Parse plasma.toml before every call to the eth command
// Update ethereum client connection if params have changed
plasmaConfigFilePath := filepath.Join(viper.GetString(store.DirFlag), "plasma.toml")

if _, err := os.Stat(plasmaConfigFilePath); os.IsNotExist(err) {
plasmaConfig := DefaultPlasmaConfig()
WritePlasmaConfigFile(plasmaConfigFilePath, plasmaConfig)
}

viper.SetConfigName("plasma")
if err := viper.MergeInConfig(); err != nil {
conf, err := ParseConfigFromViper()
if err != nil {
return nil, err
}

conf, err := ParsePlasmaConfigFromViper()
if err != nil {
return nil, err
dir := viper.GetString(flags.Home)
if dir[len(dir)-1] != '/' {
dir = dir + "/"
}

// Check to see if the eth connection params have changed
dir := viper.GetString(store.DirFlag)
if conf.EthNodeURL == "" {
return nil, fmt.Errorf("please specify a node url for eth connection in %s/plasma.toml", dir)
return nil, fmt.Errorf("please specify a node url for eth connection in %sconfig.toml", dir)
} else if conf.EthPlasmaContractAddr == "" || !ethcmn.IsHexAddress(conf.EthPlasmaContractAddr) {
return nil, fmt.Errorf("please specic a valid contract address in %s/plasma.toml", dir)
return nil, fmt.Errorf("please specify a valid contract address in %sconfig.toml", dir)
}

ethClient, err := eth.InitEthConn(conf.EthNodeURL)
if err != nil {
return nil, err
}
blockFinality, err := strconv.ParseUint(conf.EthBlockFinality, 10, 64)
if err != nil {
return nil, err
}
plasma, err := eth.InitPlasma(ethcmn.HexToAddress(conf.EthPlasmaContractAddr), ethClient, blockFinality)
plasma, err := eth.InitPlasma(ethcmn.HexToAddress(conf.EthPlasmaContractAddr), ethClient, 0)
hamdiallam marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}
Expand Down
9 changes: 9 additions & 0 deletions cmd/plasmacli/flags/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package flags
colin-axner marked this conversation as resolved.
Show resolved Hide resolved

import (
tmcli "github.com/tendermint/tendermint/libs/cli"
)

const (
Home = tmcli.HomeFlag
)
37 changes: 17 additions & 20 deletions cmd/plasmacli/store/keystore.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/spf13/viper"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/iterator"
"io/ioutil"
"os"
"path/filepath"
)

Expand All @@ -23,16 +21,19 @@ const (

PassphrasePrompt = "Enter passphrase:"

accountDir = "data/accounts.ldb"
keysDir = "keys"

DirFlag = "directory"
accountsDir = "data/accounts.ldb"
keysDir = "keys"
)

var ks *keystore.KeyStore
var (
home string
ks *keystore.KeyStore
)

// initialize a keystore in the specified directory
func InitKeystore() {
func InitKeystore(homeDir string) {
home = homeDir

dir := getDir(keysDir)
if ks == nil {
ks = keystore.NewKeyStore(dir, keystore.StandardScryptN, keystore.StandardScryptP)
Expand All @@ -42,7 +43,7 @@ func InitKeystore() {
// Return iterator over accounts
// returns db so db.close can be called
func AccountIterator() (iterator.Iterator, *leveldb.DB) {
dir := getDir(accountDir)
dir := getDir(accountsDir)
db, err := leveldb.OpenFile(dir, nil)
if err != nil {
fmt.Printf("leveldb: %s", err)
Expand All @@ -55,7 +56,7 @@ func AccountIterator() (iterator.Iterator, *leveldb.DB) {
// Add a new account to the keystore
// Add account name and address to leveldb
func AddAccount(name string) (ethcmn.Address, error) {
dir := getDir(accountDir)
dir := getDir(accountsDir)
db, err := leveldb.OpenFile(dir, nil)
if err != nil {
return ethcmn.Address{}, fmt.Errorf("leveldb: %s", err)
Expand Down Expand Up @@ -87,7 +88,7 @@ func AddAccount(name string) (ethcmn.Address, error) {

// Retrieve the address of an account
func GetAccount(name string) (ethcmn.Address, error) {
dir := getDir(accountDir)
dir := getDir(accountsDir)
db, err := leveldb.OpenFile(dir, nil)
if err != nil {
return ethcmn.Address{}, fmt.Errorf("leveldb: %s", err)
Expand All @@ -107,7 +108,7 @@ func GetAccount(name string) (ethcmn.Address, error) {
// Remove an account from the local keystore
// and the leveldb
func DeleteAccount(name string) error {
dir := getDir(accountDir)
dir := getDir(accountsDir)
db, err := leveldb.OpenFile(dir, nil)
if err != nil {
return fmt.Errorf("leveldb: %s", err)
Expand Down Expand Up @@ -140,7 +141,7 @@ func DeleteAccount(name string) error {

// Update either the name of an account or the passphrase for an account
func UpdateAccount(name string, updatedName string) (msg string, err error) {
dir := getDir(accountDir)
dir := getDir(accountsDir)
db, err := leveldb.OpenFile(dir, nil)
if err != nil {
return msg, fmt.Errorf("leveldb: %s", err)
Expand Down Expand Up @@ -188,7 +189,7 @@ func UpdateAccount(name string, updatedName string) (msg string, err error) {

// Import a private key with an account name
func ImportECDSA(name string, pk *ecdsa.PrivateKey) (ethcmn.Address, error) {
dir := getDir(accountDir)
dir := getDir(accountsDir)
db, err := leveldb.OpenFile(dir, nil)
if err != nil {
return ethcmn.Address{}, fmt.Errorf("leveldb: %s", err)
Expand Down Expand Up @@ -240,7 +241,7 @@ func SignHashWithPassphrase(signer string, hash []byte) ([]byte, error) {
}

func GetKey(name string) (*ecdsa.PrivateKey, error) {
dir := getDir(accountDir)
dir := getDir(accountsDir)
db, err := leveldb.OpenFile(dir, nil)
if err != nil {
return nil, fmt.Errorf("leveldb: %s", err)
Expand Down Expand Up @@ -284,9 +285,5 @@ func GetKey(name string) (*ecdsa.PrivateKey, error) {
// Return the directory specified by the --directory flag
// with the passed in string appended to the end
func getDir(location string) string {
dir := viper.GetString(DirFlag)
if dir[len(dir)-1] != '/' {
dir = filepath.Join(dir, "/")
}
return os.ExpandEnv(filepath.Join(dir, location))
return filepath.Join(home, location)
}
4 changes: 1 addition & 3 deletions cmd/plasmacli/store/keystore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,14 @@ import (
func TestAccounts(t *testing.T) {
// setup testing env
os.Mkdir("testing", os.ModePerm)
viper.Set(DirFlag, os.ExpandEnv("./testing"))
InitKeystore("./testing")

// cleanup
defer func() {
viper.Reset()
os.RemoveAll("testing")
}()

InitKeystore()

cases := []string{
"mykey",
"another-key",
Expand Down
Loading