config: allow to specify keystore directory, closes #147

This commit is contained in:
Victor Farazdagi 2017-04-28 11:49:15 +03:00
parent 9a68fd211f
commit eab1458ba2
7 changed files with 90 additions and 26 deletions

View File

@ -1307,29 +1307,9 @@ func startTestNode(t *testing.T) <-chan struct{} {
syncRequired = true syncRequired = true
} }
// prepare node directory // inject test accounts
if err := os.MkdirAll(filepath.Join(geth.TestDataDir, "testnet", "keystore"), os.ModePerm); err != nil { geth.ImportTestAccount(filepath.Join(geth.TestDataDir, "keystore"), "test-account1.pk")
panic(err) geth.ImportTestAccount(filepath.Join(geth.TestDataDir, "keystore"), "test-account2.pk")
}
// import test account (with test ether on it)
importTestAccount := func(accountFile string) error {
dst := filepath.Join(geth.TestDataDir, "keystore", accountFile)
if _, err := os.Stat(dst); os.IsNotExist(err) {
err = geth.CopyFile(dst, filepath.Join(geth.RootDir, "data", accountFile))
if err != nil {
panic(err)
}
}
return nil
}
if err := importTestAccount("test-account1.pk"); err != nil {
panic(err)
}
if err := importTestAccount("test-account2.pk"); err != nil {
panic(err)
}
waitForNodeStart := make(chan struct{}, 1) waitForNodeStart := make(chan struct{}, 1)
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) { geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {

View File

@ -63,6 +63,10 @@ func MakeNode(config *params.NodeConfig) *Node {
if err := os.MkdirAll(filepath.Join(config.DataDir), os.ModePerm); err != nil { if err := os.MkdirAll(filepath.Join(config.DataDir), os.ModePerm); err != nil {
Fatalf(err) Fatalf(err)
} }
// make sure keys directory exists
if err := os.MkdirAll(filepath.Join(config.KeyStoreDir), os.ModePerm); err != nil {
Fatalf(err)
}
// setup logging // setup logging
glog.CopyStandardLogTo("INFO") glog.CopyStandardLogTo("INFO")
@ -74,6 +78,7 @@ func MakeNode(config *params.NodeConfig) *Node {
// configure required node (should you need to update node's config, e.g. add bootstrap nodes, see node.Config) // configure required node (should you need to update node's config, e.g. add bootstrap nodes, see node.Config)
stackConfig := &node.Config{ stackConfig := &node.Config{
DataDir: config.DataDir, DataDir: config.DataDir,
KeyStoreDir: config.KeyStoreDir,
UseLightweightKDF: true, UseLightweightKDF: true,
Name: config.Name, Name: config.Name,
Version: config.Version, Version: config.Version,

View File

@ -129,6 +129,10 @@ type NodeConfig struct {
// DataDir is the file system folder the node should use for any data storage needs. // DataDir is the file system folder the node should use for any data storage needs.
DataDir string DataDir string
// KeyStoreDir is the file system folder that contains private keys.
// If KeyStoreDir is empty, the default location is the "keystore" subdirectory of DataDir.
KeyStoreDir string
// PrivateKeyFile is a filename with node ID (private key) // PrivateKeyFile is a filename with node ID (private key)
// This file should contain a valid secp256k1 private key that will be used for both // This file should contain a valid secp256k1 private key that will be used for both
// remote peer identification as well as network traffic encryption. // remote peer identification as well as network traffic encryption.
@ -223,7 +227,6 @@ func NewNodeConfig(dataDir string, networkId int) (*NodeConfig, error) {
}, },
WhisperConfig: &WhisperConfig{ WhisperConfig: &WhisperConfig{
Enabled: true, Enabled: true,
DataDir: filepath.Join(dataDir, "wnode"),
Port: WhisperPort, Port: WhisperPort,
MinimumPoW: WhisperMinimumPoW, MinimumPoW: WhisperMinimumPoW,
TTL: WhisperTTL, TTL: WhisperTTL,
@ -231,12 +234,32 @@ func NewNodeConfig(dataDir string, networkId int) (*NodeConfig, error) {
SwarmConfig: &SwarmConfig{}, SwarmConfig: &SwarmConfig{},
} }
// auto-populate some dependent values
nodeConfig.populateChainConfig() nodeConfig.populateChainConfig()
nodeConfig.populateDirs()
return nodeConfig, nil return nodeConfig, nil
} }
// populateChainConfig does necessary adjustments to config object (depending on network node will be runnin on) // populateDirs updates directories that should be wrt to DataDir
func (c *NodeConfig) populateDirs() {
makeSubDirPath := func(baseDir, subDir string) string {
if len(baseDir) == 0 {
return ""
}
return filepath.Join(baseDir, subDir)
}
if len(c.KeyStoreDir) == 0 {
c.KeyStoreDir = makeSubDirPath(c.DataDir, KeyStoreDir)
}
if len(c.WhisperConfig.DataDir) == 0 {
c.WhisperConfig.DataDir = makeSubDirPath(c.DataDir, WhisperDataDir)
}
}
// populateChainConfig does necessary adjustments to config object (depending on network node will be running on)
func (c *NodeConfig) populateChainConfig() { func (c *NodeConfig) populateChainConfig() {
c.TestNet = false c.TestNet = false
if c.NetworkId == TestNetworkId { if c.NetworkId == TestNetworkId {
@ -298,6 +321,7 @@ func LoadNodeConfig(configJSON string) (*NodeConfig, error) {
// repopulate // repopulate
nodeConfig.populateChainConfig() nodeConfig.populateChainConfig()
nodeConfig.populateDirs()
if len(nodeConfig.DataDir) == 0 { if len(nodeConfig.DataDir) == 0 {
return nil, ErrMissingDataDir return nil, ErrMissingDataDir

View File

@ -75,6 +75,53 @@ var loadConfigTestCases = []struct {
} }
}, },
}, },
{
`use default KeyStoreDir`,
`{
"NetworkId": 3,
"DataDir": "$TMPDIR"
}`,
func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if _, err := os.Stat(dataDir); os.IsNotExist(err) {
t.Fatalf("data directory doesn't exist: %s", dataDir)
}
expectedDataDir := dataDir
if nodeConfig.DataDir != expectedDataDir {
t.Fatalf("incorrect DataDir used, expected: %v, got: %v", expectedDataDir, nodeConfig.DataDir)
}
expectedKeyStoreDir := filepath.Join(dataDir, params.KeyStoreDir)
if nodeConfig.KeyStoreDir != expectedKeyStoreDir {
t.Fatalf("incorrect KeyStoreDir used, expected: %v, got: %v", expectedKeyStoreDir, nodeConfig.KeyStoreDir)
}
},
},
{
`use non-default KeyStoreDir`,
`{
"NetworkId": 3,
"DataDir": "$TMPDIR",
"KeyStoreDir": "/foo/bar"
}`,
func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expectedDataDir := dataDir
if nodeConfig.DataDir != expectedDataDir {
t.Fatalf("incorrect DataDir used, expected: %v, got: %v", expectedDataDir, nodeConfig.DataDir)
}
expectedKeyStoreDir := "/foo/bar"
if nodeConfig.KeyStoreDir != expectedKeyStoreDir {
t.Fatalf("incorrect KeyStoreDir used, expected: %v, got: %v", expectedKeyStoreDir, nodeConfig.KeyStoreDir)
}
},
},
{ {
`test parameter overriding`, `test parameter overriding`,
`{ `{

View File

@ -13,6 +13,9 @@ const (
// DataDir is default data directory used by statusd executable // DataDir is default data directory used by statusd executable
DataDir = "statusd-data" DataDir = "statusd-data"
// KeyStoreDir is default directory where private keys are stored, relative to DataDir
KeyStoreDir = "keystore"
// IPCFile is filename of exposed IPC RPC Server // IPCFile is filename of exposed IPC RPC Server
IPCFile = "geth.ipc" IPCFile = "geth.ipc"
@ -54,6 +57,9 @@ const (
// LogLevel defines the minimum log level to report // LogLevel defines the minimum log level to report
LogLevel = "INFO" LogLevel = "INFO"
// WhisperDataDir is directory where Whisper data is stored, relative to DataDir
WhisperDataDir = "wnode"
// WhisperPort is Whisper node listening port // WhisperPort is Whisper node listening port
WhisperPort = 30379 WhisperPort = 30379

View File

@ -2,6 +2,7 @@
"TestNet": true, "TestNet": true,
"NetworkId": 3, "NetworkId": 3,
"DataDir": "$TMPDIR", "DataDir": "$TMPDIR",
"KeyStoreDir": "$TMPDIR/keystore",
"NodeKeyFile": "", "NodeKeyFile": "",
"Name": "StatusIM", "Name": "StatusIM",
"Version": "$VERSION", "Version": "$VERSION",

View File

@ -177,10 +177,11 @@ func PrepareTestNode() (err error) {
} }
// start geth node and wait for it to initialize // start geth node and wait for it to initialize
config, err := params.NewNodeConfig(TestDataDir, params.TestNetworkId) config, err := params.NewNodeConfig(filepath.Join(TestDataDir, "data"), params.TestNetworkId)
if err != nil { if err != nil {
return err return err
} }
config.KeyStoreDir = filepath.Join(TestDataDir, "keystore")
config.HTTPPort = testConfig.Node.HTTPPort // to avoid conflicts with running app, using different port in tests config.HTTPPort = testConfig.Node.HTTPPort // to avoid conflicts with running app, using different port in tests
config.WSPort = testConfig.Node.WSPort // ditto config.WSPort = testConfig.Node.WSPort // ditto
config.LogEnabled = true config.LogEnabled = true