mirror of
https://github.com/status-im/status-go.git
synced 2025-01-27 15:05:56 +00:00
Merge pull request #148 from farazdagi/feature/keystore-config
Config: keystore directory settings
This commit is contained in:
commit
b388271774
3
Makefile
3
Makefile
@ -52,6 +52,9 @@ ci:
|
|||||||
build/env.sh go test -v -cover ./geth/jail
|
build/env.sh go test -v -cover ./geth/jail
|
||||||
build/env.sh go test -v -cover ./extkeys
|
build/env.sh go test -v -cover ./extkeys
|
||||||
|
|
||||||
|
generate:
|
||||||
|
build/env.sh go generate ./static
|
||||||
|
|
||||||
test:
|
test:
|
||||||
@build/env.sh echo "mode: set" > coverage-all.out
|
@build/env.sh echo "mode: set" > coverage-all.out
|
||||||
build/env.sh go test -coverprofile=coverage.out -covermode=set ./geth
|
build/env.sh go test -coverprofile=coverage.out -covermode=set ./geth
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/status-im/status-go/geth"
|
"github.com/status-im/status-go/geth"
|
||||||
"github.com/status-im/status-go/geth/params"
|
"github.com/status-im/status-go/geth/params"
|
||||||
@ -19,10 +18,14 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
NodeKeyFileFlag = cli.StringFlag{
|
||||||
|
Name: "nodekey",
|
||||||
|
Usage: "P2P node key file (private key)",
|
||||||
|
}
|
||||||
DataDirFlag = cli.StringFlag{
|
DataDirFlag = cli.StringFlag{
|
||||||
Name: "datadir",
|
Name: "datadir",
|
||||||
Usage: "Data directory for the databases and keystore",
|
Usage: "Data directory for the databases and keystore",
|
||||||
Value: params.DefaultDataDir,
|
Value: params.DataDir,
|
||||||
}
|
}
|
||||||
NetworkIdFlag = cli.IntFlag{
|
NetworkIdFlag = cli.IntFlag{
|
||||||
Name: "networkid",
|
Name: "networkid",
|
||||||
@ -48,7 +51,7 @@ var (
|
|||||||
HTTPPortFlag = cli.IntFlag{
|
HTTPPortFlag = cli.IntFlag{
|
||||||
Name: "httpport",
|
Name: "httpport",
|
||||||
Usage: "HTTP RPC server's listening port",
|
Usage: "HTTP RPC server's listening port",
|
||||||
Value: params.DefaultHTTPPort,
|
Value: params.HTTPPort,
|
||||||
}
|
}
|
||||||
IPCEnabledFlag = cli.BoolFlag{
|
IPCEnabledFlag = cli.BoolFlag{
|
||||||
Name: "ipc",
|
Name: "ipc",
|
||||||
@ -59,14 +62,6 @@ var (
|
|||||||
Usage: `Log level, one of: ""ERROR", "WARNING", "INFO", "DEBUG", and "DETAIL"`,
|
Usage: `Log level, one of: ""ERROR", "WARNING", "INFO", "DEBUG", and "DETAIL"`,
|
||||||
Value: "INFO",
|
Value: "INFO",
|
||||||
}
|
}
|
||||||
TestAccountKey = cli.StringFlag{
|
|
||||||
Name: "accountkey",
|
|
||||||
Usage: "Test account PK (will be loaded into accounts cache, and injected to Whisper)",
|
|
||||||
}
|
|
||||||
TestAccountPasswd = cli.StringFlag{
|
|
||||||
Name: "accountpasswd",
|
|
||||||
Usage: "Test account password",
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -74,14 +69,12 @@ func init() {
|
|||||||
app.Action = statusd
|
app.Action = statusd
|
||||||
app.HideVersion = true // separate command prints version
|
app.HideVersion = true // separate command prints version
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
{
|
versionCommand,
|
||||||
Action: version,
|
wnodeCommand,
|
||||||
Name: "version",
|
|
||||||
Usage: "Print app version",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Flags = []cli.Flag{
|
app.Flags = []cli.Flag{
|
||||||
|
NodeKeyFileFlag,
|
||||||
DataDirFlag,
|
DataDirFlag,
|
||||||
NetworkIdFlag,
|
NetworkIdFlag,
|
||||||
LightEthEnabledFlag,
|
LightEthEnabledFlag,
|
||||||
@ -133,6 +126,7 @@ func makeNodeConfig(ctx *cli.Context) (*params.NodeConfig, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodeConfig.NodeKeyFile = ctx.GlobalString(NodeKeyFileFlag.Name)
|
||||||
if !ctx.GlobalBool(HTTPEnabledFlag.Name) {
|
if !ctx.GlobalBool(HTTPEnabledFlag.Name) {
|
||||||
nodeConfig.HTTPHost = "" // HTTP RPC is disabled
|
nodeConfig.HTTPHost = "" // HTTP RPC is disabled
|
||||||
}
|
}
|
||||||
@ -150,23 +144,6 @@ func makeNodeConfig(ctx *cli.Context) (*params.NodeConfig, error) {
|
|||||||
return nodeConfig, nil
|
return nodeConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// version displays app version
|
|
||||||
func version(ctx *cli.Context) error {
|
|
||||||
fmt.Println(strings.Title(params.DefaultClientIdentifier))
|
|
||||||
fmt.Println("Version:", params.Version)
|
|
||||||
if gitCommit != "" {
|
|
||||||
fmt.Println("Git Commit:", gitCommit)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Network Id:", ctx.GlobalInt(NetworkIdFlag.Name))
|
|
||||||
fmt.Println("Go Version:", runtime.Version())
|
|
||||||
fmt.Println("OS:", runtime.GOOS)
|
|
||||||
fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH"))
|
|
||||||
fmt.Printf("GOROOT=%s\n", runtime.GOROOT())
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// makeApp creates an app with sane defaults.
|
// makeApp creates an app with sane defaults.
|
||||||
func makeApp(gitCommit string) *cli.App {
|
func makeApp(gitCommit string) *cli.App {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
|
36
cmd/statusd/misccmd.go
Normal file
36
cmd/statusd/misccmd.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/status-im/status-go/geth/params"
|
||||||
|
"gopkg.in/urfave/cli.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
versionCommand = cli.Command{
|
||||||
|
Action: version,
|
||||||
|
Name: "version",
|
||||||
|
Usage: "Print app version",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// version displays app version
|
||||||
|
func version(ctx *cli.Context) error {
|
||||||
|
fmt.Println(strings.Title(params.ClientIdentifier))
|
||||||
|
fmt.Println("Version:", params.Version)
|
||||||
|
if gitCommit != "" {
|
||||||
|
fmt.Println("Git Commit:", gitCommit)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Network Id:", ctx.GlobalInt(NetworkIdFlag.Name))
|
||||||
|
fmt.Println("Go Version:", runtime.Version())
|
||||||
|
fmt.Println("OS:", runtime.GOOS)
|
||||||
|
fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH"))
|
||||||
|
fmt.Printf("GOROOT=%s\n", runtime.GOROOT())
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -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) {
|
||||||
|
138
cmd/statusd/wnodecmd.go
Normal file
138
cmd/statusd/wnodecmd.go
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/status-im/status-go/geth"
|
||||||
|
"github.com/status-im/status-go/geth/params"
|
||||||
|
"gopkg.in/urfave/cli.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
WhisperEchoModeFlag = cli.BoolTFlag{
|
||||||
|
Name: "echo",
|
||||||
|
Usage: "Echo mode, prints some arguments for diagnostics (default: true)",
|
||||||
|
}
|
||||||
|
WhisperBootstrapNodeFlag = cli.BoolTFlag{
|
||||||
|
Name: "bootstrap",
|
||||||
|
Usage: "Don't actively connect to peers, wait for incoming connections (default: true)",
|
||||||
|
}
|
||||||
|
WhisperNotificationServerNodeFlag = cli.BoolFlag{
|
||||||
|
Name: "notify",
|
||||||
|
Usage: "Node is capable of sending Push Notifications",
|
||||||
|
}
|
||||||
|
WhisperForwarderNodeFlag = cli.BoolFlag{
|
||||||
|
Name: "forward",
|
||||||
|
Usage: "Only forward messages, neither send nor decrypt messages",
|
||||||
|
}
|
||||||
|
WhisperMailserverNodeFlag = cli.BoolFlag{
|
||||||
|
Name: "mailserver",
|
||||||
|
Usage: "Delivers expired messages on demand",
|
||||||
|
}
|
||||||
|
WhisperPassword = cli.StringFlag{
|
||||||
|
Name: "password",
|
||||||
|
Usage: "Password, will be used for topic keys, as Mail & Notification Server password",
|
||||||
|
}
|
||||||
|
WhisperPortFlag = cli.IntFlag{
|
||||||
|
Name: "port",
|
||||||
|
Usage: "Whisper node's listening port",
|
||||||
|
Value: params.WhisperPort,
|
||||||
|
}
|
||||||
|
WhisperPoWFlag = cli.Float64Flag{
|
||||||
|
Name: "pow",
|
||||||
|
Usage: "PoW for messages to be added to queue, in float format",
|
||||||
|
Value: params.WhisperMinimumPoW,
|
||||||
|
}
|
||||||
|
WhisperTTLFlag = cli.IntFlag{
|
||||||
|
Name: "ttl",
|
||||||
|
Usage: "Time to live for messages, in seconds",
|
||||||
|
Value: params.WhisperTTL,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
wnodeCommand = cli.Command{
|
||||||
|
Action: wnode,
|
||||||
|
Name: "wnode",
|
||||||
|
Usage: "Starts Whisper/5 node",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
WhisperEchoModeFlag,
|
||||||
|
WhisperBootstrapNodeFlag,
|
||||||
|
WhisperNotificationServerNodeFlag,
|
||||||
|
WhisperForwarderNodeFlag,
|
||||||
|
WhisperMailserverNodeFlag,
|
||||||
|
WhisperPassword,
|
||||||
|
WhisperPoWFlag,
|
||||||
|
WhisperPortFlag,
|
||||||
|
WhisperTTLFlag,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// version displays app version
|
||||||
|
func wnode(ctx *cli.Context) error {
|
||||||
|
config, err := makeWhisperNodeConfig(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can not parse config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
wnodePrintHeader(config)
|
||||||
|
|
||||||
|
// inject test accounts
|
||||||
|
geth.ImportTestAccount(filepath.Join(config.DataDir, "keystore"), "test-account1.pk")
|
||||||
|
geth.ImportTestAccount(filepath.Join(config.DataDir, "keystore"), "test-account2.pk")
|
||||||
|
|
||||||
|
if err := geth.CreateAndRunNode(config); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait till node has been stopped
|
||||||
|
geth.NodeManagerInstance().Node().GethStack().Wait()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func wnodePrintHeader(nodeConfig *params.NodeConfig) {
|
||||||
|
fmt.Println("Starting Whisper/5 node..")
|
||||||
|
|
||||||
|
whisperConfig := nodeConfig.WhisperConfig
|
||||||
|
|
||||||
|
if whisperConfig.EchoMode {
|
||||||
|
fmt.Printf("Whisper Config: %s\n", whisperConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeWhisperNodeConfig parses incoming CLI options and returns node configuration object
|
||||||
|
func makeWhisperNodeConfig(ctx *cli.Context) (*params.NodeConfig, error) {
|
||||||
|
nodeConfig, err := makeNodeConfig(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
whisperConfig := nodeConfig.WhisperConfig
|
||||||
|
|
||||||
|
whisperConfig.Enabled = true
|
||||||
|
whisperConfig.EchoMode = ctx.BoolT(WhisperEchoModeFlag.Name)
|
||||||
|
whisperConfig.BootstrapNode = ctx.BoolT(WhisperBootstrapNodeFlag.Name)
|
||||||
|
whisperConfig.ForwarderNode = ctx.Bool(WhisperForwarderNodeFlag.Name)
|
||||||
|
whisperConfig.NotificationServerNode = ctx.Bool(WhisperNotificationServerNodeFlag.Name)
|
||||||
|
whisperConfig.MailServerNode = ctx.Bool(WhisperMailserverNodeFlag.Name)
|
||||||
|
whisperConfig.MailServerPassword = ctx.String(WhisperPassword.Name)
|
||||||
|
whisperConfig.NotificationServerPassword = ctx.String(WhisperPassword.Name) // the same for both mail and notification servers
|
||||||
|
|
||||||
|
whisperConfig.Port = ctx.Int(WhisperPortFlag.Name)
|
||||||
|
whisperConfig.TTL = ctx.Int(WhisperTTLFlag.Name)
|
||||||
|
whisperConfig.MinimumPoW = ctx.Float64(WhisperPoWFlag.Name)
|
||||||
|
|
||||||
|
if whisperConfig.MailServerNode && len(whisperConfig.MailServerPassword) == 0 {
|
||||||
|
return nil, errors.New("mail server requires --password to be specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
if whisperConfig.NotificationServerNode && len(whisperConfig.NotificationServerPassword) == 0 {
|
||||||
|
return nil, errors.New("notification server requires --password to be specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeConfig, nil
|
||||||
|
}
|
@ -1,21 +0,0 @@
|
|||||||
#cloud-config
|
|
||||||
|
|
||||||
coreos:
|
|
||||||
etcd2:
|
|
||||||
# generate a new token for each unique cluster from https://discovery.etcd.io/new:
|
|
||||||
discovery: https://discovery.etcd.io/d2df3f02e6129624ad96f1bdb4a5ba05
|
|
||||||
# multi-region deployments, multi-cloud deployments, and Droplets without
|
|
||||||
# private networking need to use $public_ipv4:
|
|
||||||
advertise-client-urls: http://$private_ipv4:2379,http://$private_ipv4:4001
|
|
||||||
initial-advertise-peer-urls: http://$private_ipv4:2380
|
|
||||||
# listen on the official ports 2379, 2380 and one legacy port 4001:
|
|
||||||
listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
|
|
||||||
listen-peer-urls: http://$private_ipv4:2380
|
|
||||||
fleet:
|
|
||||||
public-ip: $private_ipv4 # used for fleetctl ssh command
|
|
||||||
metadata: "region=sgp,size=2048"
|
|
||||||
units:
|
|
||||||
- name: etcd2.service
|
|
||||||
command: start
|
|
||||||
- name: fleet.service
|
|
||||||
command: start
|
|
@ -1,19 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=GetNode
|
|
||||||
After=docker.service
|
|
||||||
Requires=docker.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
TimeoutStartSec=0
|
|
||||||
ExecStartPre=-/usr/bin/docker kill geth
|
|
||||||
ExecStartPre=-/usr/bin/docker rm geth
|
|
||||||
ExecStartPre=/usr/bin/docker pull farazdagi/geth
|
|
||||||
ExecStart=/usr/bin/docker run --name geth -v /home/core/data:/root/.ethereum -p 30303:30303 farazdagi/geth --lightkdf --shh
|
|
||||||
ExecStop=/usr/bin/docker stop geth
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
|
|
||||||
[X-Fleet]
|
|
||||||
Global=true
|
|
||||||
MachineMetadata=size=2048
|
|
@ -1 +0,0 @@
|
|||||||
{"address":"89b50b2b26947ccad43accaef76c21d175ad85f4","crypto":{"cipher":"aes-128-ctr","ciphertext":"cc8f600a59f8c5ac3d6ab849722a6602f61de0adc5c9617a1cd014d3d9638a95","cipherparams":{"iv":"836bb6b5df64c29a84f95e7628510e71"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"4cc1f86eaa707ee37dc3b686712f09be49b7175a2046c63cfd1d7a3e7ebee8ab"},"mac":"164f2e53c67b5c85267b79e4fc8b2f9117a66b5e0546933403d85d52fffa1f52"},"id":"3ade037d-722b-467a-ad8e-2bcae28b9642","version":3,"whisperenabled":true}
|
|
@ -1,13 +0,0 @@
|
|||||||
[
|
|
||||||
"enode://8e4440f36e97b12f320dd3312c6b21c78ba72afd36d4b3202cf363f3b82311dd2c2c883ffadf3374941486db82c45f975dff491f639da39f9e3eec4f142a4f53@139.59.147.137:30303",
|
|
||||||
"enode://d29febbcd9ac8b163a2b5b080aa16497faec2cf115cdc57cea2e5a8055fecda702ebfe1b3118b88e24efd7a2e6ff865f5d088553ab69b1c88e3cd5344e069ff4@139.59.208.103:30303",
|
|
||||||
"enode://1263b51754fc03be5800469078218318c43a07dfa53405794d12f77ee72a0ff49b48c86ebae501ef239d4a9253cc8dc6a889acdbb33176bc3e1bd4a499d4bc48@139.59.214.200:30303",
|
|
||||||
"enode://47df3738d17e7d6d1ae059cf73ee3deade7436d7c33e2547d1524a6afd9735dd90dfe505e08ad26cd2d0473d0c62a34b3d317da92be3ac4ddb9faa8bd28dc660@139.59.209.169:30303",
|
|
||||||
"enode://5f00ae7bc7191550e523069c87dbd0e1d7ac4771b98dc7663f55eed22d5fc9b0b108c7962694a1e7827a4747a10e1fe3706fb46ea5e26851b3f384bcfe5ca533@139.59.209.170:30303",
|
|
||||||
|
|
||||||
"enode://57a9b08555e0dee42b6cbe9b7817782703d4923a7214f6549ae799ec060c8205a4784c0e46c36ddee4ffbaeea31f8d8368860760753895157f224321202d7747@188.166.212.8:30303",
|
|
||||||
"enode://a63de242582d75060d0b2300e70558fe2fbbba99a1e6a5cadbead6af0e651d86e4db69f171a75e9f67d6e434a73c89360693d354b46d8563a419821d257c14c0@188.166.212.238:30303",
|
|
||||||
"enode://f98a1e0ee1507ed4b9e222bf0f1a995633ac8e36ea47e642e7f73a5f88422497e16b207bb399a64415a3472dd69ec0b2a0f9d58a7bc70542db34c8f2bb782c7a@188.166.220.39:30303",
|
|
||||||
"enode://6337e9c29693525466fa240831d0e92e6b627111794cef3b4fb710f3c2bbb870767a39d50553491072f3b2459911b981d036237234f9cf6f8ee9a6ffe1a2b4f2@188.166.220.183:30303",
|
|
||||||
"enode://9eb901eb9c96a5a56ac5d493d5cd9522edac067e9c7549608056f5ffdb5453e77848c445d07b9b806ab9880e7d595e62705f4dcf3e7fc2af64a0c33bde961031@188.166.210.253:30303"
|
|
||||||
]
|
|
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/robertkrimen/otto"
|
"github.com/robertkrimen/otto"
|
||||||
"github.com/status-im/status-go/geth"
|
"github.com/status-im/status-go/geth"
|
||||||
|
"github.com/status-im/status-go/static"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -37,6 +38,7 @@ type JailedRuntime struct {
|
|||||||
sem *semaphore.Semaphore
|
sem *semaphore.Semaphore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var Web3_JS = static.MustAsset("scripts/web3.js")
|
||||||
var jailInstance *Jail
|
var jailInstance *Jail
|
||||||
var once sync.Once
|
var once sync.Once
|
||||||
|
|
||||||
@ -95,7 +97,7 @@ func (jail *Jail) Parse(chatId string, js string) string {
|
|||||||
localStorage, _ := vm.Get("localStorage")
|
localStorage, _ := vm.Get("localStorage")
|
||||||
localStorage.Object().Set("set", makeLocalStorageSetHandler(chatId))
|
localStorage.Object().Set("set", makeLocalStorageSetHandler(chatId))
|
||||||
|
|
||||||
jjs := Web3_JS + `
|
jjs := string(Web3_JS) + `
|
||||||
var Web3 = require('web3');
|
var Web3 = require('web3');
|
||||||
var web3 = new Web3(jeth);
|
var web3 = new Web3(jeth);
|
||||||
var Bignumber = require("bignumber.js");
|
var Bignumber = require("bignumber.js");
|
||||||
|
15977
geth/jail/web3.go
15977
geth/jail/web3.go
File diff suppressed because it is too large
Load Diff
@ -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,
|
||||||
|
@ -77,6 +77,39 @@ type LightEthConfig struct {
|
|||||||
type WhisperConfig struct {
|
type WhisperConfig struct {
|
||||||
// Enabled flag specifies whether protocol is enabled
|
// Enabled flag specifies whether protocol is enabled
|
||||||
Enabled bool
|
Enabled bool
|
||||||
|
|
||||||
|
// EchoMode if mode is on, prints some arguments for diagnostics
|
||||||
|
EchoMode bool
|
||||||
|
|
||||||
|
// BootstrapNode whether node doesn't actively connect to peers, and waits for incoming connections
|
||||||
|
BootstrapNode bool
|
||||||
|
|
||||||
|
// ForwarderNode is mode when node only forwards messages, neither sends nor decrypts messages
|
||||||
|
ForwarderNode bool
|
||||||
|
|
||||||
|
// MailServerNode is mode when node is capable of delivering expired messages on demand
|
||||||
|
MailServerNode bool
|
||||||
|
|
||||||
|
// MailServerPassword is password for MailServer's symmetric key
|
||||||
|
MailServerPassword string
|
||||||
|
|
||||||
|
// NotificationServerNode is mode when node is capable of sending Push (and probably other kinds) Notifications
|
||||||
|
NotificationServerNode bool
|
||||||
|
|
||||||
|
// NotificationServerPassword is password for NotificationServer's symmetric key (used in discovery)
|
||||||
|
NotificationServerPassword string
|
||||||
|
|
||||||
|
// DataDir is the file system folder Whisper should use for any data storage needs.
|
||||||
|
DataDir string
|
||||||
|
|
||||||
|
// Port Whisper node's listening port
|
||||||
|
Port int
|
||||||
|
|
||||||
|
// MinimumPoW minimum PoW for Whisper messages
|
||||||
|
MinimumPoW float64
|
||||||
|
|
||||||
|
// TTL time to live for messages, in seconds
|
||||||
|
TTL int
|
||||||
}
|
}
|
||||||
|
|
||||||
// SwarmConfig holds Swarm-related configuration
|
// SwarmConfig holds Swarm-related configuration
|
||||||
@ -96,6 +129,15 @@ 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)
|
||||||
|
// This file should contain a valid secp256k1 private key that will be used for both
|
||||||
|
// remote peer identification as well as network traffic encryption.
|
||||||
|
NodeKeyFile string
|
||||||
|
|
||||||
// Name sets the instance name of the node. It must not contain the / character.
|
// Name sets the instance name of the node. It must not contain the / character.
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@ -166,35 +208,58 @@ func NewNodeConfig(dataDir string, networkId int) (*NodeConfig, error) {
|
|||||||
nodeConfig := &NodeConfig{
|
nodeConfig := &NodeConfig{
|
||||||
NetworkId: networkId,
|
NetworkId: networkId,
|
||||||
DataDir: dataDir,
|
DataDir: dataDir,
|
||||||
Name: DefaultClientIdentifier,
|
Name: ClientIdentifier,
|
||||||
Version: Version,
|
Version: Version,
|
||||||
HTTPHost: DefaultHTTPHost,
|
HTTPHost: HTTPHost,
|
||||||
HTTPPort: DefaultHTTPPort,
|
HTTPPort: HTTPPort,
|
||||||
APIModules: DefaultAPIModules,
|
APIModules: APIModules,
|
||||||
WSHost: DefaultWSHost,
|
WSHost: WSHost,
|
||||||
WSPort: DefaultWSPort,
|
WSPort: WSPort,
|
||||||
MaxPeers: DefaultMaxPeers,
|
MaxPeers: MaxPeers,
|
||||||
MaxPendingPeers: DefaultMaxPendingPeers,
|
MaxPendingPeers: MaxPendingPeers,
|
||||||
IPCFile: DefaultIPCFile,
|
IPCFile: IPCFile,
|
||||||
LogFile: DefaultLogFile,
|
LogFile: LogFile,
|
||||||
LogLevel: DefaultLogLevel,
|
LogLevel: LogLevel,
|
||||||
ChainConfig: &ChainConfig{},
|
ChainConfig: &ChainConfig{},
|
||||||
LightEthConfig: &LightEthConfig{
|
LightEthConfig: &LightEthConfig{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
DatabaseCache: DefaultDatabaseCache,
|
DatabaseCache: DatabaseCache,
|
||||||
},
|
},
|
||||||
WhisperConfig: &WhisperConfig{
|
WhisperConfig: &WhisperConfig{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
Port: WhisperPort,
|
||||||
|
MinimumPoW: WhisperMinimumPoW,
|
||||||
|
TTL: WhisperTTL,
|
||||||
},
|
},
|
||||||
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 {
|
||||||
@ -256,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
|
||||||
@ -293,3 +359,15 @@ func (c *NodeConfig) String() string {
|
|||||||
data, _ := json.MarshalIndent(c, "", " ")
|
data, _ := json.MarshalIndent(c, "", " ")
|
||||||
return string(data)
|
return string(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String dumps config object as nicely indented JSON
|
||||||
|
func (c *WhisperConfig) String() string {
|
||||||
|
data, _ := json.MarshalIndent(c, "", " ")
|
||||||
|
return string(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String dumps config object as nicely indented JSON
|
||||||
|
func (c *SwarmConfig) String() string {
|
||||||
|
data, _ := json.MarshalIndent(c, "", " ")
|
||||||
|
return string(data)
|
||||||
|
}
|
||||||
|
@ -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`,
|
||||||
`{
|
`{
|
||||||
@ -101,11 +148,11 @@ var loadConfigTestCases = []struct {
|
|||||||
t.Fatal("wrong Name")
|
t.Fatal("wrong Name")
|
||||||
}
|
}
|
||||||
|
|
||||||
if nodeConfig.HTTPPort != params.DefaultHTTPPort {
|
if nodeConfig.HTTPPort != params.HTTPPort {
|
||||||
t.Fatal("wrong HTTPPort")
|
t.Fatal("wrong HTTPPort")
|
||||||
}
|
}
|
||||||
|
|
||||||
if nodeConfig.HTTPHost != params.DefaultHTTPHost {
|
if nodeConfig.HTTPHost != params.HTTPHost {
|
||||||
t.Fatal("wrong HTTPHost")
|
t.Fatal("wrong HTTPHost")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,37 +7,40 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DefaultClientIdentifier is client identifier to advertise over the network
|
// ClientIdentifier is client identifier to advertise over the network
|
||||||
DefaultClientIdentifier = "StatusIM"
|
ClientIdentifier = "StatusIM"
|
||||||
|
|
||||||
// DefaultDataDir is default data directory used by statusd executable
|
// DataDir is default data directory used by statusd executable
|
||||||
DefaultDataDir = "statusd-data"
|
DataDir = "statusd-data"
|
||||||
|
|
||||||
// DefaultIPCFile is filename of exposed IPC RPC Server
|
// KeyStoreDir is default directory where private keys are stored, relative to DataDir
|
||||||
DefaultIPCFile = "geth.ipc"
|
KeyStoreDir = "keystore"
|
||||||
|
|
||||||
// DefaultHTTPHost is host interface for the HTTP RPC server
|
// IPCFile is filename of exposed IPC RPC Server
|
||||||
DefaultHTTPHost = "localhost"
|
IPCFile = "geth.ipc"
|
||||||
|
|
||||||
// DefaultHTTPPort is HTTP-RPC port (replaced in unit tests)
|
// HTTPHost is host interface for the HTTP RPC server
|
||||||
DefaultHTTPPort = 8545
|
HTTPHost = "localhost"
|
||||||
|
|
||||||
// DefaultAPIModules is a list of modules to expose vie HTTP RPC
|
// HTTPPort is HTTP-RPC port (replaced in unit tests)
|
||||||
|
HTTPPort = 8545
|
||||||
|
|
||||||
|
// APIModules is a list of modules to expose vie HTTP RPC
|
||||||
// TODO remove "admin" on main net
|
// TODO remove "admin" on main net
|
||||||
DefaultAPIModules = "db,eth,net,web3,shh,personal,admin"
|
APIModules = "db,eth,net,web3,shh,personal,admin"
|
||||||
|
|
||||||
// DefaultWSHost is a host interface for the websocket RPC server
|
// WSHost is a host interface for the websocket RPC server
|
||||||
DefaultWSHost = "localhost"
|
WSHost = "localhost"
|
||||||
|
|
||||||
// DefaultWSPort is a WS-RPC port (replaced in unit tests)
|
// WSPort is a WS-RPC port (replaced in unit tests)
|
||||||
DefaultWSPort = 8546
|
WSPort = 8546
|
||||||
|
|
||||||
// DefaultMaxPeers is the maximum number of global peers
|
// MaxPeers is the maximum number of global peers
|
||||||
DefaultMaxPeers = 25
|
MaxPeers = 25
|
||||||
|
|
||||||
// DefaultMaxPendingPeers is the maximum number of peers that can be pending in the
|
// MaxPendingPeers is the maximum number of peers that can be pending in the
|
||||||
// handshake phase, counted separately for inbound and outbound connections.
|
// handshake phase, counted separately for inbound and outbound connections.
|
||||||
DefaultMaxPendingPeers = 0
|
MaxPendingPeers = 0
|
||||||
|
|
||||||
// DefaultGas default amount of gas used for transactions
|
// DefaultGas default amount of gas used for transactions
|
||||||
DefaultGas = 180000
|
DefaultGas = 180000
|
||||||
@ -45,14 +48,26 @@ const (
|
|||||||
// DefaultFileDescriptorLimit is fd limit that database can use
|
// DefaultFileDescriptorLimit is fd limit that database can use
|
||||||
DefaultFileDescriptorLimit = uint64(2048)
|
DefaultFileDescriptorLimit = uint64(2048)
|
||||||
|
|
||||||
// DefaultDatabaseCache is memory (in MBs) allocated to internal caching (min 16MB / database forced)
|
// DatabaseCache is memory (in MBs) allocated to internal caching (min 16MB / database forced)
|
||||||
DefaultDatabaseCache = 128
|
DatabaseCache = 128
|
||||||
|
|
||||||
// DefaultLogFile defines where to write logs to
|
// LogFile defines where to write logs to
|
||||||
DefaultLogFile = "geth.log"
|
LogFile = "geth.log"
|
||||||
|
|
||||||
// DefaultLogLevel defines the minimum log level to report
|
// LogLevel defines the minimum log level to report
|
||||||
DefaultLogLevel = "INFO"
|
LogLevel = "INFO"
|
||||||
|
|
||||||
|
// WhisperDataDir is directory where Whisper data is stored, relative to DataDir
|
||||||
|
WhisperDataDir = "wnode"
|
||||||
|
|
||||||
|
// WhisperPort is Whisper node listening port
|
||||||
|
WhisperPort = 30379
|
||||||
|
|
||||||
|
// WhisperMinimumPoW amount of work for Whisper message to be added to sending queue
|
||||||
|
WhisperMinimumPoW = 0.001
|
||||||
|
|
||||||
|
// WhisperTTL is time to live for messages, in seconds
|
||||||
|
WhisperTTL = 120
|
||||||
|
|
||||||
// TestNetworkId is id of a test network
|
// TestNetworkId is id of a test network
|
||||||
TestNetworkId = 3
|
TestNetworkId = 3
|
||||||
|
15
geth/params/testdata/config.testnet.json
vendored
15
geth/params/testdata/config.testnet.json
vendored
@ -2,6 +2,8 @@
|
|||||||
"TestNet": true,
|
"TestNet": true,
|
||||||
"NetworkId": 3,
|
"NetworkId": 3,
|
||||||
"DataDir": "$TMPDIR",
|
"DataDir": "$TMPDIR",
|
||||||
|
"KeyStoreDir": "$TMPDIR/keystore",
|
||||||
|
"NodeKeyFile": "",
|
||||||
"Name": "StatusIM",
|
"Name": "StatusIM",
|
||||||
"Version": "$VERSION",
|
"Version": "$VERSION",
|
||||||
"APIModules": "db,eth,net,web3,shh,personal,admin",
|
"APIModules": "db,eth,net,web3,shh,personal,admin",
|
||||||
@ -34,7 +36,18 @@
|
|||||||
"DatabaseCache": 128
|
"DatabaseCache": 128
|
||||||
},
|
},
|
||||||
"WhisperConfig": {
|
"WhisperConfig": {
|
||||||
"Enabled": true
|
"Enabled": true,
|
||||||
|
"EchoMode": false,
|
||||||
|
"BootstrapNode": false,
|
||||||
|
"ForwarderNode": false,
|
||||||
|
"MailServerNode": false,
|
||||||
|
"MailServerPassword": "",
|
||||||
|
"NotificationServerNode": false,
|
||||||
|
"NotificationServerPassword": "",
|
||||||
|
"DataDir": "$TMPDIR/wnode",
|
||||||
|
"Port": 30379,
|
||||||
|
"MinimumPoW": 0.001,
|
||||||
|
"TTL": 120
|
||||||
},
|
},
|
||||||
"SwarmConfig": {
|
"SwarmConfig": {
|
||||||
"Enabled": false
|
"Enabled": false
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -22,12 +23,12 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/status-im/status-go/geth/params"
|
"github.com/status-im/status-go/geth/params"
|
||||||
|
"github.com/status-im/status-go/static"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
muPrepareTestNode sync.Mutex
|
muPrepareTestNode sync.Mutex
|
||||||
RootDir string
|
RootDir string
|
||||||
DataDir string
|
|
||||||
TestDataDir string
|
TestDataDir string
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -44,7 +45,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setup auxiliary directories
|
// setup auxiliary directories
|
||||||
DataDir = filepath.Join(RootDir, "data")
|
|
||||||
TestDataDir = filepath.Join(RootDir, ".ethereumtest")
|
TestDataDir = filepath.Join(RootDir, ".ethereumtest")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ type TestConfig struct {
|
|||||||
func LoadTestConfig() (*TestConfig, error) {
|
func LoadTestConfig() (*TestConfig, error) {
|
||||||
var testConfig TestConfig
|
var testConfig TestConfig
|
||||||
|
|
||||||
configData := LoadFromFile(filepath.Join(DataDir, "test-data.json"))
|
configData := string(static.MustAsset("config/test-data.json"))
|
||||||
if err := json.Unmarshal([]byte(configData), &testConfig); err != nil {
|
if err := json.Unmarshal([]byte(configData), &testConfig); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -168,31 +168,20 @@ func PrepareTestNode() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// import test account (with test ether on it)
|
// import test accounts (with test ether on it)
|
||||||
importTestAccount := func(accountFile string) error {
|
if err := ImportTestAccount(filepath.Join(TestDataDir, "keystore"), "test-account1.pk"); err != nil {
|
||||||
dst := filepath.Join(TestDataDir, "keystore", accountFile)
|
|
||||||
if _, err := os.Stat(dst); os.IsNotExist(err) {
|
|
||||||
err = CopyFile(dst, filepath.Join(RootDir, "data", accountFile))
|
|
||||||
if err != nil {
|
|
||||||
glog.V(logger.Warn).Infof("cannot copy test account PK: %v", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if err := importTestAccount("test-account1.pk"); err != nil {
|
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if err := importTestAccount("test-account2.pk"); err != nil {
|
if err := ImportTestAccount(filepath.Join(TestDataDir, "keystore"), "test-account2.pk"); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
@ -286,3 +275,23 @@ func AddressToDecryptedAccount(address, password string) (accounts.Account, *key
|
|||||||
|
|
||||||
return keyStore.AccountDecryptedKey(account, password)
|
return keyStore.AccountDecryptedKey(account, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImportTestAccount checks if test account exists in keystore, and if not
|
||||||
|
// tries to import it (from static resources, see "static/keys" folder)
|
||||||
|
func ImportTestAccount(keystoreDir, accountFile string) error {
|
||||||
|
// make sure that keystore folder exists
|
||||||
|
if _, err := os.Stat(keystoreDir); os.IsNotExist(err) {
|
||||||
|
os.MkdirAll(keystoreDir, os.ModePerm)
|
||||||
|
}
|
||||||
|
|
||||||
|
dst := filepath.Join(keystoreDir, accountFile)
|
||||||
|
if _, err := os.Stat(dst); os.IsNotExist(err) {
|
||||||
|
err = ioutil.WriteFile(dst, static.MustAsset("keys/"+accountFile), 0644)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(logger.Warn).Infof("cannot copy test account PK: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
333
static/bindata.go
Normal file
333
static/bindata.go
Normal file
File diff suppressed because one or more lines are too long
4
static/static.go
Normal file
4
static/static.go
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// Package static embeds static (JS, HTML) resources right into the binaries
|
||||||
|
package static
|
||||||
|
|
||||||
|
//go:generate go-bindata -pkg static -o bindata.go scripts/ config/ keys/
|
Loading…
x
Reference in New Issue
Block a user