From b130d586ca6aef22b35dc37721921d8b75d7c488 Mon Sep 17 00:00:00 2001 From: Victor Farazdagi Date: Tue, 28 Mar 2017 12:04:52 +0300 Subject: [PATCH] cmd/statusd: expose LES, SHH, Swarm. Closes #128 --- Makefile | 23 ++- cmd/status/main.go | 26 ---- cmd/{status => statusd}/library.go | 0 cmd/{status => statusd}/library_test.go | 0 cmd/statusd/main.go | 183 +++++++++++++++++++++++ cmd/{status => statusd}/utils.go | 0 geth/node.go | 16 ++ geth/node_manager.go | 23 ++- geth/params/config.go | 30 ++-- geth/params/defaults.go | 3 + geth/params/testdata/config.testnet.json | 9 +- 11 files changed, 256 insertions(+), 57 deletions(-) delete mode 100644 cmd/status/main.go rename cmd/{status => statusd}/library.go (100%) rename cmd/{status => statusd}/library_test.go (100%) create mode 100644 cmd/statusd/main.go rename cmd/{status => statusd}/utils.go (100%) diff --git a/Makefile b/Makefile index 7616d8f0f..fd9de4d88 100644 --- a/Makefile +++ b/Makefile @@ -5,25 +5,24 @@ GOBIN = build/bin GO ?= latest statusgo: - build/env.sh go build -i -o $(GOBIN)/statusgo -v $(shell build/testnet-flags.sh) ./cmd/status - @echo "status go compilation done." - @echo "Run \"build/bin/statusgo\" to view available commands" + build/env.sh go build -i -o $(GOBIN)/statusd -v $(shell build/testnet-flags.sh) ./cmd/statusd + @echo "\nCompilation done.\nRun \"build/bin/statusd help\" to view available commands." statusgo-cross: statusgo-android statusgo-ios @echo "Full cross compilation done." @ls -ld $(GOBIN)/statusgo-* statusgo-android: xgo - build/env.sh $(GOBIN)/xgo --image farazdagi/xgo --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=android-16/aar -v $(shell build/testnet-flags.sh) ./cmd/status + build/env.sh $(GOBIN)/xgo --image farazdagi/xgo --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=android-16/aar -v $(shell build/testnet-flags.sh) ./cmd/statusd @echo "Android cross compilation done." statusgo-ios: xgo - build/env.sh $(GOBIN)/xgo --image farazdagi/xgo --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v $(shell build/testnet-flags.sh) ./cmd/status + build/env.sh $(GOBIN)/xgo --image farazdagi/xgo --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v $(shell build/testnet-flags.sh) ./cmd/statusd @echo "iOS framework cross compilation done." statusgo-ios-simulator: xgo @build/env.sh docker pull farazdagi/xgo-ios-simulator - build/env.sh $(GOBIN)/xgo --image farazdagi/xgo-ios-simulator --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v $(shell build/testnet-flags.sh) ./cmd/status + build/env.sh $(GOBIN)/xgo --image farazdagi/xgo-ios-simulator --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v $(shell build/testnet-flags.sh) ./cmd/statusd @echo "iOS framework cross compilation done." xgo: @@ -31,20 +30,20 @@ xgo: build/env.sh go get github.com/karalabe/xgo statusgo-mainnet: - build/env.sh go build -i -o $(GOBIN)/statusgo -v $(shell build/mainnet-flags.sh) ./cmd/status + build/env.sh go build -i -o $(GOBIN)/statusgo -v $(shell build/mainnet-flags.sh) ./cmd/statusd @echo "status go compilation done (mainnet)." @echo "Run \"build/bin/statusgo\" to view available commands" statusgo-android-mainnet: xgo - build/env.sh $(GOBIN)/xgo --image farazdagi/xgo --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=android-16/aar -v $(shell build/mainnet-flags.sh) ./cmd/status + build/env.sh $(GOBIN)/xgo --image farazdagi/xgo --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=android-16/aar -v $(shell build/mainnet-flags.sh) ./cmd/statusd @echo "Android cross compilation done (mainnet)." statusgo-ios-mainnet: xgo - build/env.sh $(GOBIN)/xgo --image farazdagi/xgo --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v $(shell build/mainnet-flags.sh) ./cmd/status + build/env.sh $(GOBIN)/xgo --image farazdagi/xgo --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v $(shell build/mainnet-flags.sh) ./cmd/statusd @echo "iOS framework cross compilation done (mainnet)." statusgo-ios-simulator-mainnet: xgo - build/env.sh $(GOBIN)/xgo --image farazdagi/xgo-ios-simulator --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v $(shell build/mainnet-flags.sh) ./cmd/status + build/env.sh $(GOBIN)/xgo --image farazdagi/xgo-ios-simulator --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v $(shell build/mainnet-flags.sh) ./cmd/statusd @echo "iOS framework cross compilation done (mainnet)." ci: @@ -63,7 +62,7 @@ test: @build/env.sh tail -n +2 coverage.out >> coverage-all.out build/env.sh go test -coverprofile=coverage.out -covermode=set ./extkeys @build/env.sh tail -n +2 coverage.out >> coverage-all.out - build/env.sh go test -coverprofile=coverage.out -covermode=set ./cmd/status + build/env.sh go test -coverprofile=coverage.out -covermode=set ./cmd/statusd @build/env.sh tail -n +2 coverage.out >> coverage-all.out @build/env.sh go tool cover -html=coverage-all.out -o coverage.html @build/env.sh go tool cover -func=coverage-all.out @@ -89,7 +88,7 @@ test-extkeys: @build/env.sh go tool cover -func=coverage.out test-cmd: - build/env.sh go test -v -coverprofile=coverage.out ./cmd/status + build/env.sh go test -v -coverprofile=coverage.out ./cmd/statusd @build/env.sh go tool cover -html=coverage.out -o coverage.html @build/env.sh go tool cover -func=coverage.out diff --git a/cmd/status/main.go b/cmd/status/main.go deleted file mode 100644 index f21321ea0..000000000 --- a/cmd/status/main.go +++ /dev/null @@ -1,26 +0,0 @@ -package main - -import ( - "fmt" - "github.com/status-im/status-go/geth/params" -) - -var ( - gitCommit = "rely on linker: -ldflags -X main.GitCommit" - buildStamp = "rely on linker: -ldflags -X main.buildStamp" -) - -func main() { - nodeConfig, err := params.NewNodeConfig(".ethereumcmd", params.TestNetworkId) - if err != nil { - panic(err) - } - - netVersion := "mainnet" - if nodeConfig.TestNet { - netVersion = "testnet" - } - - fmt.Printf("%s\nVersion: %s\nGit Commit: %s\nBuild Date: %s\nNetwork: %s\n", - nodeConfig.Name, params.Version, gitCommit, buildStamp, netVersion) -} diff --git a/cmd/status/library.go b/cmd/statusd/library.go similarity index 100% rename from cmd/status/library.go rename to cmd/statusd/library.go diff --git a/cmd/status/library_test.go b/cmd/statusd/library_test.go similarity index 100% rename from cmd/status/library_test.go rename to cmd/statusd/library_test.go diff --git a/cmd/statusd/main.go b/cmd/statusd/main.go new file mode 100644 index 000000000..525ea0a71 --- /dev/null +++ b/cmd/statusd/main.go @@ -0,0 +1,183 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + "runtime" + "strings" + + "github.com/status-im/status-go/geth" + "github.com/status-im/status-go/geth/params" + "gopkg.in/urfave/cli.v1" +) + +var ( + gitCommit = "rely on linker: -ldflags -X main.GitCommit" + buildStamp = "rely on linker: -ldflags -X main.buildStamp" + app = makeApp(gitCommit) +) + +var ( + DataDirFlag = cli.StringFlag{ + Name: "datadir", + Usage: "Data directory for the databases and keystore", + Value: params.DefaultDataDir, + } + NetworkIdFlag = cli.IntFlag{ + Name: "networkid", + Usage: "Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten)", + Value: params.TestNetworkId, + } + LightEthEnabledFlag = cli.BoolFlag{ + Name: "les", + Usage: "LES protocol enabled", + } + WhisperEnabledFlag = cli.BoolFlag{ + Name: "shh", + Usage: "SHH protocol enabled", + } + SwarmEnabledFlag = cli.BoolFlag{ + Name: "swarm", + Usage: "Swarm protocol enabled", + } + HTTPEnabledFlag = cli.BoolFlag{ + Name: "http", + Usage: "HTTP RPC enpoint enabled", + } + HTTPPortFlag = cli.IntFlag{ + Name: "httpport", + Usage: "HTTP RPC server's listening port", + Value: params.DefaultHTTPPort, + } + IPCEnabledFlag = cli.BoolFlag{ + Name: "ipc", + Usage: "IPC RPC enpoint enabled", + } + LogLevelFlag = cli.StringFlag{ + Name: "log", + Usage: `Log level, one of: ""ERROR", "WARNING", "INFO", "DEBUG", and "DETAIL"`, + 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() { + // setup the app + app.Action = statusd + app.HideVersion = true // separate command prints version + app.Commands = []cli.Command{ + { + Action: version, + Name: "version", + Usage: "Print app version", + }, + } + + app.Flags = []cli.Flag{ + DataDirFlag, + NetworkIdFlag, + LightEthEnabledFlag, + WhisperEnabledFlag, + SwarmEnabledFlag, + HTTPEnabledFlag, + HTTPPortFlag, + IPCEnabledFlag, + LogLevelFlag, + } + app.Before = func(ctx *cli.Context) error { + runtime.GOMAXPROCS(runtime.NumCPU()) + return nil + } + app.After = func(ctx *cli.Context) error { + return nil + } +} + +func main() { + if err := app.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +// statusd runs Status node +func statusd(ctx *cli.Context) error { + config, err := makeNodeConfig(ctx) + if err != nil { + fmt.Fprintf(os.Stderr, "can not parse config: %v", err) + return err + } + + if err := geth.CreateAndRunNode(config); err != nil { + return err + } + + // wait till node has been stopped + geth.NodeManagerInstance().Node().GethStack().Wait() + + return nil +} + +// makeNodeConfig parses incoming CLI options and returns node configuration object +func makeNodeConfig(ctx *cli.Context) (*params.NodeConfig, error) { + nodeConfig, err := params.NewNodeConfig(ctx.GlobalString(DataDirFlag.Name), ctx.GlobalInt(NetworkIdFlag.Name)) + if err != nil { + return nil, err + } + + if !ctx.GlobalBool(HTTPEnabledFlag.Name) { + nodeConfig.HTTPHost = "" // HTTP RPC is disabled + } + nodeConfig.IPCEnabled = ctx.GlobalBool(IPCEnabledFlag.Name) + nodeConfig.LightEthConfig.Enabled = ctx.GlobalBool(LightEthEnabledFlag.Name) + nodeConfig.WhisperConfig.Enabled = ctx.GlobalBool(WhisperEnabledFlag.Name) + nodeConfig.SwarmConfig.Enabled = ctx.GlobalBool(SwarmEnabledFlag.Name) + nodeConfig.HTTPPort = ctx.GlobalInt(HTTPPortFlag.Name) + + if logLevel := ctx.GlobalString(LogLevelFlag.Name); len(logLevel) > 0 { + nodeConfig.LogEnabled = true + nodeConfig.LogLevel = logLevel + } + + 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. +func makeApp(gitCommit string) *cli.App { + app := cli.NewApp() + app.Name = filepath.Base(os.Args[0]) + app.Author = "" + //app.Authors = nil + app.Email = "" + app.Version = params.Version + if gitCommit != "" { + app.Version += "-" + gitCommit[:8] + } + app.Usage = "Status CLI" + return app +} diff --git a/cmd/status/utils.go b/cmd/statusd/utils.go similarity index 100% rename from cmd/status/utils.go rename to cmd/statusd/utils.go diff --git a/geth/node.go b/geth/node.go index b2f8b478b..dee29cc6e 100644 --- a/geth/node.go +++ b/geth/node.go @@ -6,6 +6,7 @@ import ( "io" "os" "path" + "path/filepath" "reflect" "runtime" "runtime/debug" @@ -15,6 +16,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/les" + "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p/discover" @@ -57,6 +59,11 @@ func (n *Node) GethStack() *node.Node { // MakeNode create a geth node entity func MakeNode(config *params.NodeConfig) *Node { + // make sure data directory exists + if err := os.MkdirAll(filepath.Join(config.DataDir), os.ModePerm); err != nil { + Fatalf(err) + } + // setup logging glog.CopyStandardLogTo("INFO") glog.SetToStderr(true) @@ -115,6 +122,11 @@ func MakeNode(config *params.NodeConfig) *Node { // activateEthService configures and registers the eth.Ethereum service with a given node. func activateEthService(stack *node.Node, config *params.NodeConfig) error { + if !config.LightEthConfig.Enabled { + glog.V(logger.Info).Infoln("LES protocol is disabled") + return nil + } + ethConf := ð.Config{ Etherbase: common.Address{}, ChainConfig: makeChainConfig(config), @@ -148,6 +160,10 @@ func activateEthService(stack *node.Node, config *params.NodeConfig) error { // activateShhService configures Whisper and adds it to the given node. func activateShhService(stack *node.Node, config *params.NodeConfig) error { + if !config.WhisperConfig.Enabled { + glog.V(logger.Info).Infoln("SHH protocol is disabled") + return nil + } serviceConstructor := func(*node.ServiceContext) (node.Service, error) { return whisper.New(), nil } diff --git a/geth/node_manager.go b/geth/node_manager.go index cbb4a887a..f3d0f799e 100644 --- a/geth/node_manager.go +++ b/geth/node_manager.go @@ -115,15 +115,13 @@ func (m *NodeManager) RunNode() { } // setup handlers - lightEthereum, err := m.LightEthereumService() - if err != nil { - panic("service stack misses LES") + if lightEthereum, err := m.LightEthereumService(); err == nil { + lightEthereum.StatusBackend.SetTransactionQueueHandler(onSendTransactionRequest) + lightEthereum.StatusBackend.SetAccountsFilterHandler(onAccountsListRequest) + lightEthereum.StatusBackend.SetTransactionReturnHandler(onSendTransactionReturn) } - lightEthereum.StatusBackend.SetTransactionQueueHandler(onSendTransactionRequest) - lightEthereum.StatusBackend.SetAccountsFilterHandler(onAccountsListRequest) - lightEthereum.StatusBackend.SetTransactionReturnHandler(onSendTransactionReturn) - + var err error m.services.rpcClient, err = m.node.geth.Attach() if err != nil { glog.V(logger.Warn).Infoln("cannot get RPC client service:", ErrInvalidClient) @@ -264,7 +262,7 @@ func (m *NodeManager) StopNodeRPCServer() (bool, error) { return m.api.StopRPC() } -// HasNode checks whether manager has initialized node attached +// NodeInited checks whether manager has initialized node attached func (m *NodeManager) NodeInited() bool { if m == nil || !m.node.Inited() { return false @@ -273,6 +271,15 @@ func (m *NodeManager) NodeInited() bool { return true } +// Node returns attached node if it has been initialized +func (m *NodeManager) Node() *Node { + if !m.NodeInited() { + return nil + } + + return m.node +} + // AccountManager exposes reference to accounts manager func (m *NodeManager) AccountManager() (*accounts.Manager, error) { if m == nil || !m.NodeInited() { diff --git a/geth/params/config.go b/geth/params/config.go index 228762e9b..cb517bdee 100644 --- a/geth/params/config.go +++ b/geth/params/config.go @@ -63,6 +63,9 @@ type ChainConfig struct { // LightEthConfig holds LES-related configuration // Status nodes are always lightweight clients (due to mobile platform constraints) type LightEthConfig struct { + // Enabled flag specifies whether protocol is enabled + Enabled bool + // Genesis is JSON to seed the chain database with Genesis string @@ -71,10 +74,16 @@ type LightEthConfig struct { } // WhisperConfig holds SHH-related configuration -type WhisperConfig struct{} +type WhisperConfig struct { + // Enabled flag specifies whether protocol is enabled + Enabled bool +} // SwarmConfig holds Swarm-related configuration -type SwarmConfig struct{} +type SwarmConfig struct { + // Enabled flag specifies whether protocol is enabled + Enabled bool +} // NodeConfig stores configuration options for a node type NodeConfig struct { @@ -143,13 +152,13 @@ type NodeConfig struct { *ChainConfig `json:"ChainConfig,"` // LightEthConfig extra configuration for LES - *LightEthConfig `json:"LightEthConfig,"` + LightEthConfig *LightEthConfig `json:"LightEthConfig,"` // WhisperConfig extra configuration for SHH - *WhisperConfig `json:"WhisperConfig,"` + WhisperConfig *WhisperConfig `json:"WhisperConfig,"` // SwarmConfig extra configuration for Swarm and ENS - *SwarmConfig `json:"SwarmConfig,"` + SwarmConfig *SwarmConfig `json:"SwarmConfig,"` } // NewNodeConfig creates new node configuration object @@ -171,10 +180,13 @@ func NewNodeConfig(dataDir string, networkId int) (*NodeConfig, error) { LogLevel: DefaultLogLevel, ChainConfig: &ChainConfig{}, LightEthConfig: &LightEthConfig{ + Enabled: true, DatabaseCache: DefaultDatabaseCache, }, - WhisperConfig: &WhisperConfig{}, - SwarmConfig: &SwarmConfig{}, + WhisperConfig: &WhisperConfig{ + Enabled: true, + }, + SwarmConfig: &SwarmConfig{}, } nodeConfig.populateChainConfig() @@ -206,7 +218,7 @@ func (c *NodeConfig) populateChainConfig() { c.ChainConfig.EIP158Block = params.TestnetChainConfig.EIP158Block c.ChainConfig.ChainId = params.TestnetChainConfig.ChainId - c.Genesis = core.DefaultTestnetGenesisBlock() + c.LightEthConfig.Genesis = core.DefaultTestnetGenesisBlock() } else { // Homestead fork c.ChainConfig.HomesteadBlock = params.MainNetHomesteadBlock @@ -223,7 +235,7 @@ func (c *NodeConfig) populateChainConfig() { c.ChainConfig.EIP158Block = params.MainNetSpuriousDragon c.ChainConfig.ChainId = params.MainNetChainID - c.Genesis = core.DefaultGenesisBlock() + c.LightEthConfig.Genesis = core.DefaultGenesisBlock() } } diff --git a/geth/params/defaults.go b/geth/params/defaults.go index 81e57f040..0ba28a285 100644 --- a/geth/params/defaults.go +++ b/geth/params/defaults.go @@ -10,6 +10,9 @@ const ( // DefaultClientIdentifier is client identifier to advertise over the network DefaultClientIdentifier = "StatusIM" + // DefaultDataDir is default data directory used by statusd executable + DefaultDataDir = "statusd-data" + // DefaultIPCFile is filename of exposed IPC RPC Server DefaultIPCFile = "geth.ipc" diff --git a/geth/params/testdata/config.testnet.json b/geth/params/testdata/config.testnet.json index 28278c918..8682d1441 100755 --- a/geth/params/testdata/config.testnet.json +++ b/geth/params/testdata/config.testnet.json @@ -29,9 +29,14 @@ "EIP158Block": 10 }, "LightEthConfig": { + "Enabled": true, "Genesis": "{\n \"config\": {\n \"chainId\": 3,\n \"homesteadBlock\":0,\n \"eip150Block\":0,\n \"eip155Block\":10,\n \"eip158Block\":10,\n \"eip160Block\":10\n },\n \"nonce\": \"0x0000000000000042\", \n \"alloc\": {\n \"0x0000000000000000000000000000000000000011\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000010\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000013\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000012\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000015\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000014\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000017\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000016\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000019\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000018\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000c1\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000c0\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000c7\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000c6\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000c5\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000c4\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000002d\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000002e\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000002f\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000c8\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000002a\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000002b\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000002c\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000091\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000090\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000093\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000092\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000095\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000094\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000097\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000096\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000076\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000000c\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000c3\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000c2\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000081\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000000a\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000024\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000025\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000026\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000027\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000020\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000021\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000022\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000023\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000009a\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000d7\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000009c\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000009b\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000028\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000029\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000d0\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000009f\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000001a\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000001c\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000001b\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000001e\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000001d\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000001f\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000cc\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000cb\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ca\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000cf\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ce\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000cd\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000099\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000098\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ac\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000aa\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000e9\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000e8\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000e5\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000e4\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000e7\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000e6\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000e1\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000e0\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000e3\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000e2\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000df\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000fb\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000fc\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000fd\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000fe\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ff\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ae\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000dd\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ad\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000de\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000009e\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000004f\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000db\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000004d\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000004e\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000004b\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000004c\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000004a\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000039\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000038\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000000e\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000033\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000032\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000031\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000030\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000037\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000036\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000035\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000034\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000f0\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000f1\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000f2\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000f3\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000f4\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000f5\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000f6\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000f7\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000f8\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000f9\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ee\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000c9\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ef\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ea\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ec\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000eb\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000003c\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000003b\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000003a\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000003f\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000003e\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000003d\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000089\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000048\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000049\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000046\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000047\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000044\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000045\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000042\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000043\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000040\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000041\": {\n \"balance\": \"0\"\n }, \n \"0x874b54a8bd152966d63f706bae1ffeb0411921e5\": {\n \"balance\": \"1000000000000000000000000000000\"\n }, \n \"0x00000000000000000000000000000000000000af\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000088\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000000d\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ed\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000006a\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000006b\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000006c\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000006d\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000006e\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000006f\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000086\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000087\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000059\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000058\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000055\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000054\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000057\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000056\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000051\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000050\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000053\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000052\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000009d\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000dc\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000000b\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000fa\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000005e\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000005d\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000005f\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000005a\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000005c\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000005b\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000060\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000061\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000062\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000063\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000064\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000065\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000066\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000067\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000068\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000069\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000bd\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000be\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000bf\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ba\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000bb\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000bc\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000008b\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000008c\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000008a\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000008f\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000008d\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000008e\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000a1\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000a0\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000a3\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000a2\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000a5\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000a4\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000a7\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000a6\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000a9\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000a8\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000ab\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000d8\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000d9\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000077\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000d6\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000075\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000074\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000073\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000072\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000071\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000070\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000d4\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000079\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000078\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000002\": {\n \"balance\": \"1\"\n }, \n \"0x0000000000000000000000000000000000000003\": {\n \"balance\": \"1\"\n }, \n \"0x0000000000000000000000000000000000000000\": {\n \"balance\": \"1\"\n }, \n \"0x0000000000000000000000000000000000000001\": {\n \"balance\": \"1\"\n }, \n \"0x0000000000000000000000000000000000000006\": {\n \"balance\": \"1\"\n }, \n \"0x0000000000000000000000000000000000000007\": {\n \"balance\": \"1\"\n }, \n \"0x0000000000000000000000000000000000000004\": {\n \"balance\": \"1\"\n }, \n \"0x0000000000000000000000000000000000000005\": {\n \"balance\": \"1\"\n }, \n \"0x00000000000000000000000000000000000000d2\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000008\": {\n \"balance\": \"1\"\n }, \n \"0x0000000000000000000000000000000000000009\": {\n \"balance\": \"1\"\n }, \n \"0x00000000000000000000000000000000000000d3\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000b4\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000b5\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000b6\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000b7\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000b0\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000b1\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000b2\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000b3\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000082\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000083\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000080\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000d1\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000b8\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000b9\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000084\": {\n \"balance\": \"0\"\n }, \n \"0x0000000000000000000000000000000000000085\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000007f\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000007e\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000007d\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000007c\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000007b\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000007a\": {\n \"balance\": \"0\"\n }, \n \"0x000000000000000000000000000000000000000f\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000d5\": {\n \"balance\": \"0\"\n }, \n \"0x00000000000000000000000000000000000000da\": {\n \"balance\": \"0\"\n }\n }, \n \"timestamp\": \"0x00\", \n \"parentHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\", \n \"extraData\": \"0x3535353535353535353535353535353535353535353535353535353535353535\", \n \"gasLimit\": \"0x1000000\", \n \"difficulty\": \"0x100000\", \n \"mixhash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\", \n \"coinbase\": \"0x0000000000000000000000000000000000000000\"\n}\n", "DatabaseCache": 128 }, - "WhisperConfig": {}, - "SwarmConfig": {} + "WhisperConfig": { + "Enabled": true + }, + "SwarmConfig": { + "Enabled": false + } } \ No newline at end of file