From 5f5d0aa4ff3988d81406f2e79e45a32610894c7b Mon Sep 17 00:00:00 2001 From: zelig Date: Sat, 10 Dec 2016 18:45:52 +0100 Subject: [PATCH 1/8] cmd/swarm: subsume cmd/bzz* as subcommands under swarm cmd/swarm: subsume cmd/bzz* under cmd/swarm as subcommands --- cmd/{bzzhash/main.go => swarm/hash.go} | 19 ++++--- cmd/{bzzd => swarm}/main.go | 71 ++++++++++++++++++++++++-- cmd/{bzzup/main.go => swarm/upload.go} | 27 +++++----- 3 files changed, 90 insertions(+), 27 deletions(-) rename cmd/{bzzhash/main.go => swarm/hash.go} (80%) rename cmd/{bzzd => swarm}/main.go (79%) rename cmd/{bzzup/main.go => swarm/upload.go} (89%) diff --git a/cmd/bzzhash/main.go b/cmd/swarm/hash.go similarity index 80% rename from cmd/bzzhash/main.go rename to cmd/swarm/hash.go index 0ae99acc0..0a20bea82 100644 --- a/cmd/bzzhash/main.go +++ b/cmd/swarm/hash.go @@ -19,22 +19,21 @@ package main import ( "fmt" + "log" "os" - "runtime" "github.com/ethereum/go-ethereum/swarm/storage" + "gopkg.in/urfave/cli.v1" ) -func main() { - runtime.GOMAXPROCS(runtime.NumCPU()) - - if len(os.Args) < 2 { - fmt.Println("Usage: bzzhash ") - os.Exit(0) +func hash(ctx *cli.Context) { + args := ctx.Args() + if len(args) < 1 { + log.Fatal("Usage: swarm hash ") } - f, err := os.Open(os.Args[1]) + f, err := os.Open(args[0]) if err != nil { - fmt.Println("Error opening file " + os.Args[1]) + fmt.Println("Error opening file " + args[1]) os.Exit(1) } @@ -42,7 +41,7 @@ func main() { chunker := storage.NewTreeChunker(storage.NewChunkerParams()) key, err := chunker.Split(f, stat.Size(), nil, nil, nil) if err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) + log.Fatalf("%v\n", err) } else { fmt.Printf("%v\n", key) } diff --git a/cmd/bzzd/main.go b/cmd/swarm/main.go similarity index 79% rename from cmd/bzzd/main.go rename to cmd/swarm/main.go index 4bb2ca04a..a76e29c3b 100644 --- a/cmd/bzzd/main.go +++ b/cmd/swarm/main.go @@ -43,11 +43,14 @@ import ( "gopkg.in/urfave/cli.v1" ) -const clientIdentifier = "bzzd" +const ( + clientIdentifier = "swarm" + versionString = "0.2" +) var ( gitCommit string // Git SHA1 commit hash of the release (set via linker flags) - app = utils.NewApp(gitCommit, "Ethereum Swarm server daemon") + app = utils.NewApp(gitCommit, "Ethereum Swarm") ) var ( @@ -85,6 +88,19 @@ var ( Usage: "URL of the Ethereum API provider", Value: node.DefaultIPCEndpoint("geth"), } + SwarmApiFlag = cli.StringFlag{ + Name: "bzzapi", + Usage: "Swarm HTTP endpoint", + Value: "http://127.0.0.1:8500", + } + SwarmRecursiveUploadFlag = cli.BoolFlag{ + Name: "recursive", + Usage: "Upload directories recursively", + } + SwarmWantManifestFlag = cli.BoolTFlag{ + Name: "manifest", + Usage: "Automatic manifest upload", + } ) var defaultBootnodes = []string{} @@ -96,8 +112,39 @@ func init() { utils.IPCApiFlag.Value = "admin, bzz, chequebook, debug, rpc, web3" // Set up the cli app. - app.Commands = nil app.Action = bzzd + app.HideVersion = true // we have a command to print the version + app.Copyright = "Copyright 2013-2016 The go-ethereum Authors" + app.Commands = []cli.Command{ + cli.Command{ + Action: version, + Name: "version", + Usage: "Print version numbers", + ArgsUsage: " ", + Description: ` +The output of this command is supposed to be machine-readable. +`, + }, + cli.Command{ + Action: upload, + Name: "up", + Usage: "upload a file or directory to swarm using the HTTP API", + ArgsUsage: " ", + Description: ` +"upload a file or directory to swarm using the HTTP API and prints the root hash", +`, + }, + cli.Command{ + Action: hash, + Name: "hash", + Usage: "print the swarm hash of a file or directory", + ArgsUsage: " ", + Description: ` +Prints the swarm hash of file or directory. +`, + }, + } + app.Flags = []cli.Flag{ utils.IdentityFlag, utils.DataDirFlag, @@ -123,6 +170,10 @@ func init() { SwarmAccountFlag, SwarmNetworkIdFlag, ChequebookAddrFlag, + // upload flags + SwarmApiFlag, + SwarmRecursiveUploadFlag, + SwarmWantManifestFlag, } app.Flags = append(app.Flags, debug.Flags...) app.Before = func(ctx *cli.Context) error { @@ -142,6 +193,20 @@ func main() { } } +func version(ctx *cli.Context) error { + fmt.Println(strings.Title(clientIdentifier)) + fmt.Println("Version:", versionString) + if gitCommit != "" { + fmt.Println("Git Commit:", gitCommit) + } + fmt.Println("Network Id:", ctx.GlobalInt(utils.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 +} + func bzzd(ctx *cli.Context) error { stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) registerBzzService(ctx, stack) diff --git a/cmd/bzzup/main.go b/cmd/swarm/upload.go similarity index 89% rename from cmd/bzzup/main.go rename to cmd/swarm/upload.go index 7d251aadb..0aceef20b 100644 --- a/cmd/bzzup/main.go +++ b/cmd/swarm/upload.go @@ -20,7 +20,6 @@ package main import ( "bytes" "encoding/json" - "flag" "fmt" "io" "io/ioutil" @@ -30,24 +29,24 @@ import ( "os" "path/filepath" "strings" + + "gopkg.in/urfave/cli.v1" ) -func main() { +func upload(ctx *cli.Context) { + args := ctx.Args() var ( - bzzapiFlag = flag.String("bzzapi", "http://127.0.0.1:8500", "Swarm HTTP endpoint") - recursiveFlag = flag.Bool("recursive", false, "Upload directories recursively") - manifestFlag = flag.Bool("manifest", true, "Skip automatic manifest upload") + bzzapi = ctx.GlobalString(SwarmApiFlag.Name) + recursive = ctx.GlobalBool(SwarmRecursiveUploadFlag.Name) + wantManifest = ctx.GlobalBoolT(SwarmWantManifestFlag.Name) ) - log.SetOutput(os.Stderr) - log.SetFlags(0) - flag.Parse() - if flag.NArg() != 1 { + if len(args) != 1 { log.Fatal("need filename as the first and only argument") } var ( - file = flag.Arg(0) - client = &client{api: *bzzapiFlag} + file = args[0] + client = &client{api: bzzapi} mroot manifest ) fi, err := os.Stat(file) @@ -55,13 +54,13 @@ func main() { log.Fatal(err) } if fi.IsDir() { - if !*recursiveFlag { + if !recursive { log.Fatal("argument is a directory and recursive upload is disabled") } mroot, err = client.uploadDirectory(file) } else { mroot, err = client.uploadFile(file, fi) - if *manifestFlag { + if wantManifest { // Wrap the raw file entry in a proper manifest so both hashes get printed. mroot = manifest{Entries: []manifest{mroot}} } @@ -69,7 +68,7 @@ func main() { if err != nil { log.Fatalln("upload failed:", err) } - if *manifestFlag { + if wantManifest { hash, err := client.uploadManifest(mroot) if err != nil { log.Fatalln("manifest upload failed:", err) From d7c398b638115ad724e9a1ce363ae78fe25968b7 Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 13 Dec 2016 09:18:18 +0100 Subject: [PATCH 2/8] build: add swarm command to binary packages, update README --- README.md | 4 +--- build/ci.go | 16 +++------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 770546010..66f59470f 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,7 @@ The go-ethereum project comes with several wrappers/executables found in the `cm | `evm` | Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode. Its purpose is to allow insolated, fine-grained debugging of EVM opcodes (e.g. `evm --code 60ff60ff --debug`). | | `gethrpctest` | Developer utility tool to support our [ethereum/rpc-test](https://github.com/ethereum/rpc-tests) test suite which validates baseline conformity to the [Ethereum JSON RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) specs. Please see the [test suite's readme](https://github.com/ethereum/rpc-tests/blob/master/README.md) for details. | | `rlpdump` | Developer utility tool to convert binary RLP ([Recursive Length Prefix](https://github.com/ethereum/wiki/wiki/RLP)) dumps (data encoding used by the Ethereum protocol both network as well as consensus wise) to user friendlier hierarchical representation (e.g. `rlpdump --hex CE0183FFFFFFC4C304050583616263`). | -| `bzzd` | swarm daemon. This is the entrypoint for the swarm network. `bzzd --help` for command line options. See https://swarm-guide.readthedocs.io for swarm documentation. | -| `bzzup` | swarm command line file uploader. `bzzup --help` for command line options | -| `bzzhash` | command to calculate the swarm hash of a file or directory. `bzzhash --help` for command line options | +| `swarm` | swarm daemon and tools. This is the entrypoint for the swarm network. `swarm --help` for command line options and subcommands. See https://swarm-guide.readthedocs.io for swarm documentation. | ## Running geth diff --git a/build/ci.go b/build/ci.go index 602eb8239..6f1978cf7 100644 --- a/build/ci.go +++ b/build/ci.go @@ -72,9 +72,7 @@ var ( executablePath("abigen"), executablePath("evm"), executablePath("geth"), - executablePath("bzzd"), - executablePath("bzzhash"), - executablePath("bzzup"), + executablePath("swarm"), executablePath("rlpdump"), } @@ -93,16 +91,8 @@ var ( Description: "Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode.", }, { - Name: "bzzd", - Description: "Ethereum Swarm daemon", - }, - { - Name: "bzzup", - Description: "Ethereum Swarm command line file/directory uploader", - }, - { - Name: "bzzhash", - Description: "Ethereum Swarm file/directory hash calculator", + Name: "swarm", + Description: "Ethereum Swarm daemon and tools", }, { Name: "abigen", From 418104648894c2a96e08a1666010a0b43d3a400b Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 13 Dec 2016 09:24:33 +0100 Subject: [PATCH 3/8] swarm/network, cmd/swarm: swarm default network id is 3 (to match Ropsten) --- cmd/swarm/main.go | 2 +- swarm/network/protocol.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index a76e29c3b..fb2ae8da3 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -68,7 +68,7 @@ var ( } SwarmNetworkIdFlag = cli.IntFlag{ Name: "bzznetworkid", - Usage: "Network identifier (integer, default 322=swarm testnet)", + Usage: "Network identifier (integer, default 3=swarm testnet)", Value: network.NetworkId, } SwarmConfigPathFlag = cli.StringFlag{ diff --git a/swarm/network/protocol.go b/swarm/network/protocol.go index a3ffd338f..4fffaac6d 100644 --- a/swarm/network/protocol.go +++ b/swarm/network/protocol.go @@ -51,7 +51,7 @@ const ( Version = 0 ProtocolLength = uint64(8) ProtocolMaxMsgSize = 10 * 1024 * 1024 - NetworkId = 322 + NetworkId = 3 ) const ( From d44f1a77eeb208a929add38ca4234d9f2a865a26 Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 13 Dec 2016 09:49:02 +0100 Subject: [PATCH 4/8] cmd/swarm: add default bootnodes for testnet 3 --- cmd/swarm/main.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index fb2ae8da3..e968ad4c2 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -49,8 +49,15 @@ const ( ) var ( - gitCommit string // Git SHA1 commit hash of the release (set via linker flags) - app = utils.NewApp(gitCommit, "Ethereum Swarm") + gitCommit string // Git SHA1 commit hash of the release (set via linker flags) + app = utils.NewApp(gitCommit, "Ethereum Swarm") + testbetBootNodes = []string{ + "enode://330dce4992f5ec50a4a6f9e16bf35b9d8ee739236b6530e7846fcb058ed24b666e6027513a4b921fd2ec40ff22f6ddec0937bcbc697a8937d9cde83d8fde8a06@13.79.165.39:30403", + "enode://7ea1cc1723b4d51f08f76f6380f5f9faa92232313c6568e79ab1e1a98148f7549a3f8d05b2e6f94c10796e015a224ed2e46df7033077d63a888eeec52fae6fd2@13.79.165.39:30404", + "enode://4363f21af9e94e32b3ad22d88ed04f6e5bcf9407b7cb38a61216c57bbdcb9d5c5beb4f9aac1b78049e8d3a516097f5b92fc116928e35c92e48fc9b68086b78f5@13.79.165.39:30405", + "enode://79b616c70d309b27319461219032ff7f5901c3e522bb5d5b084e4372666f7f006803387e81563bd1bb06937a4adb8efa16c0ea86e921edf49a09e58ac3a90845@13.79.165.39:30406", + "enode://83b4df39d90720193717ccd5476feca81a962a31090fc440a9085941fcbfcd765285edb00c549286be33703d9bfb2723576dc85d705c9bfe1a74ee454d61f2cc@13.79.165.39:30407", + } ) var ( @@ -103,8 +110,6 @@ var ( } ) -var defaultBootnodes = []string{} - func init() { // Override flag defaults so bzzd can run alongside geth. utils.ListenPortFlag.Value = 30399 @@ -211,13 +216,15 @@ func bzzd(ctx *cli.Context) error { stack := utils.MakeNode(ctx, clientIdentifier, gitCommit) registerBzzService(ctx, stack) utils.StartNode(stack) - + networkId := ctx.GlobalUint64(SwarmNetworkIdFlag.Name) // Add bootnodes as initial peers. if ctx.GlobalIsSet(utils.BootnodesFlag.Name) { bootnodes := strings.Split(ctx.GlobalString(utils.BootnodesFlag.Name), ",") injectBootnodes(stack.Server(), bootnodes) } else { - injectBootnodes(stack.Server(), defaultBootnodes) + if networkId == 3 { + injectBootnodes(stack.Server(), testbetBootNodes) + } } stack.Wait() From 8e35f54931a0c5036d82f7b7db756d70290cf118 Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 13 Dec 2016 09:51:42 +0100 Subject: [PATCH 5/8] cmd/swarm: trim trailing slash from bzzapi url --- cmd/swarm/upload.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/swarm/upload.go b/cmd/swarm/upload.go index 0aceef20b..5393d4ef6 100644 --- a/cmd/swarm/upload.go +++ b/cmd/swarm/upload.go @@ -36,7 +36,7 @@ import ( func upload(ctx *cli.Context) { args := ctx.Args() var ( - bzzapi = ctx.GlobalString(SwarmApiFlag.Name) + bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") recursive = ctx.GlobalBool(SwarmRecursiveUploadFlag.Name) wantManifest = ctx.GlobalBoolT(SwarmWantManifestFlag.Name) ) From 080699f7df86f472a99d181c46605391dfd99967 Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 13 Dec 2016 10:52:22 +0100 Subject: [PATCH 6/8] cmd/swarm: ethapi not required --- cmd/swarm/main.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index e968ad4c2..144dcc80c 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -254,13 +254,11 @@ func registerBzzService(ctx *cli.Context, stack *node.Node) { boot := func(ctx *node.ServiceContext) (node.Service, error) { var client *ethclient.Client - if ethapi == "" { - err = fmt.Errorf("use ethapi flag to connect to a an eth client and talk to the blockchain") - } else { + if len(ethapi) > 0 { client, err = ethclient.Dial(ethapi) - } - if err != nil { - utils.Fatalf("Can't connect: %v", err) + if err != nil { + utils.Fatalf("Can't connect: %v", err) + } } return swarm.NewSwarm(ctx, client, bzzconfig, swapEnabled, syncEnabled) } From 485748c4161f558bd1aa01c2e064c335208c9482 Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 13 Dec 2016 12:48:30 +0100 Subject: [PATCH 7/8] cmd/swarm: improve uploader output and add defaultpath option --- cmd/swarm/main.go | 5 +++ cmd/swarm/upload.go | 89 +++++++++++++++++++++++++++++++++------------ 2 files changed, 70 insertions(+), 24 deletions(-) diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index 144dcc80c..1c8da43ae 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -108,6 +108,10 @@ var ( Name: "manifest", Usage: "Automatic manifest upload", } + SwarmUploadDefaultPath = cli.StringFlag{ + Name: "defaultpath", + Usage: "path to file served for empty url path (none)", + } ) func init() { @@ -179,6 +183,7 @@ Prints the swarm hash of file or directory. SwarmApiFlag, SwarmRecursiveUploadFlag, SwarmWantManifestFlag, + SwarmUploadDefaultPath, } app.Flags = append(app.Flags, debug.Flags...) app.Before = func(ctx *cli.Context) error { diff --git a/cmd/swarm/upload.go b/cmd/swarm/upload.go index 5393d4ef6..d048bbc40 100644 --- a/cmd/swarm/upload.go +++ b/cmd/swarm/upload.go @@ -27,6 +27,8 @@ import ( "mime" "net/http" "os" + "os/user" + "path" "path/filepath" "strings" @@ -39,6 +41,7 @@ func upload(ctx *cli.Context) { bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") recursive = ctx.GlobalBool(SwarmRecursiveUploadFlag.Name) wantManifest = ctx.GlobalBoolT(SwarmWantManifestFlag.Name) + defaultPath = ctx.GlobalString(SwarmUploadDefaultPath.Name) ) if len(args) != 1 { log.Fatal("need filename as the first and only argument") @@ -48,8 +51,9 @@ func upload(ctx *cli.Context) { file = args[0] client = &client{api: bzzapi} mroot manifest + entry manifestEntry ) - fi, err := os.Stat(file) + fi, err := os.Stat(expandPath(file)) if err != nil { log.Fatal(err) } @@ -57,28 +61,49 @@ func upload(ctx *cli.Context) { if !recursive { log.Fatal("argument is a directory and recursive upload is disabled") } - mroot, err = client.uploadDirectory(file) + mroot, err = client.uploadDirectory(file, defaultPath) } else { - mroot, err = client.uploadFile(file, fi) - if wantManifest { - // Wrap the raw file entry in a proper manifest so both hashes get printed. - mroot = manifest{Entries: []manifest{mroot}} - } + entry, err = client.uploadFile(file, fi) + mroot = manifest{[]manifestEntry{entry}} } if err != nil { log.Fatalln("upload failed:", err) } - if wantManifest { - hash, err := client.uploadManifest(mroot) - if err != nil { - log.Fatalln("manifest upload failed:", err) - } - mroot.Hash = hash + if !wantManifest { + // Print the manifest. This is the only output to stdout. + mrootJSON, _ := json.MarshalIndent(mroot, "", " ") + fmt.Println(string(mrootJSON)) + return } + hash, err := client.uploadManifest(mroot) + if err != nil { + log.Fatalln("manifest upload failed:", err) + } + fmt.Println(hash) +} - // Print the manifest. This is the only output to stdout. - mrootJSON, _ := json.MarshalIndent(mroot, "", " ") - fmt.Println(string(mrootJSON)) +// Expands a file path +// 1. replace tilde with users home dir +// 2. expands embedded environment variables +// 3. cleans the path, e.g. /a/b/../c -> /a/c +// Note, it has limitations, e.g. ~someuser/tmp will not be expanded +func expandPath(p string) string { + if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") { + if home := homeDir(); home != "" { + p = home + p[1:] + } + } + return path.Clean(os.ExpandEnv(p)) +} + +func homeDir() string { + if home := os.Getenv("HOME"); home != "" { + return home + } + if usr, err := user.Current(); err == nil { + return usr.HomeDir + } + return "" } // client wraps interaction with the swarm HTTP gateway. @@ -87,24 +112,40 @@ type client struct { } // manifest is the JSON representation of a swarm manifest. -type manifest struct { - Hash string `json:"hash,omitempty"` - ContentType string `json:"contentType,omitempty"` - Path string `json:"path,omitempty"` - Entries []manifest `json:"entries,omitempty"` +type manifestEntry struct { + Hash string `json:"hash,omitempty"` + ContentType string `json:"contentType,omitempty"` + Path string `json:"path,omitempty"` } -func (c *client) uploadFile(file string, fi os.FileInfo) (manifest, error) { +// manifest is the JSON representation of a swarm manifest. +type manifest struct { + Entries []manifestEntry `json:"entries,omitempty"` +} + +func (c *client) uploadFile(file string, fi os.FileInfo) (manifestEntry, error) { hash, err := c.uploadFileContent(file, fi) - m := manifest{ + m := manifestEntry{ Hash: hash, ContentType: mime.TypeByExtension(filepath.Ext(fi.Name())), } return m, err } -func (c *client) uploadDirectory(dir string) (manifest, error) { +func (c *client) uploadDirectory(dir string, defaultPath string) (manifest, error) { dirm := manifest{} + if len(defaultPath) > 0 { + fi, err := os.Stat(defaultPath) + if err != nil { + log.Fatal(err) + } + entry, err := c.uploadFile(defaultPath, fi) + if err != nil { + log.Fatal(err) + } + entry.Path = "" + dirm.Entries = append(dirm.Entries, entry) + } prefix := filepath.ToSlash(filepath.Clean(dir)) + "/" err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error { if err != nil || fi.IsDir() { From 92224d27b124bda3748128a140d50ddf0fa295c1 Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 13 Dec 2016 13:08:41 +0100 Subject: [PATCH 8/8] cmd/swarm: testnet bootnodes IP address change --- cmd/swarm/main.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index 1c8da43ae..04930760e 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -52,11 +52,11 @@ var ( gitCommit string // Git SHA1 commit hash of the release (set via linker flags) app = utils.NewApp(gitCommit, "Ethereum Swarm") testbetBootNodes = []string{ - "enode://330dce4992f5ec50a4a6f9e16bf35b9d8ee739236b6530e7846fcb058ed24b666e6027513a4b921fd2ec40ff22f6ddec0937bcbc697a8937d9cde83d8fde8a06@13.79.165.39:30403", - "enode://7ea1cc1723b4d51f08f76f6380f5f9faa92232313c6568e79ab1e1a98148f7549a3f8d05b2e6f94c10796e015a224ed2e46df7033077d63a888eeec52fae6fd2@13.79.165.39:30404", - "enode://4363f21af9e94e32b3ad22d88ed04f6e5bcf9407b7cb38a61216c57bbdcb9d5c5beb4f9aac1b78049e8d3a516097f5b92fc116928e35c92e48fc9b68086b78f5@13.79.165.39:30405", - "enode://79b616c70d309b27319461219032ff7f5901c3e522bb5d5b084e4372666f7f006803387e81563bd1bb06937a4adb8efa16c0ea86e921edf49a09e58ac3a90845@13.79.165.39:30406", - "enode://83b4df39d90720193717ccd5476feca81a962a31090fc440a9085941fcbfcd765285edb00c549286be33703d9bfb2723576dc85d705c9bfe1a74ee454d61f2cc@13.79.165.39:30407", + "enode://ec8ae764f7cb0417bdfb009b9d0f18ab3818a3a4e8e7c67dd5f18971a93510a2e6f43cd0b69a27e439a9629457ea804104f37c85e41eed057d3faabbf7744cdf@13.74.157.139:30429", + "enode://c2e1fceb3bf3be19dff71eec6cccf19f2dbf7567ee017d130240c670be8594bc9163353ca55dd8df7a4f161dd94b36d0615c17418b5a3cdcbb4e9d99dfa4de37@13.74.157.139:30430", + "enode://fe29b82319b734ce1ec68b84657d57145fee237387e63273989d354486731e59f78858e452ef800a020559da22dcca759536e6aa5517c53930d29ce0b1029286@13.74.157.139:30431", + "enode://1d7187e7bde45cf0bee489ce9852dd6d1a0d9aa67a33a6b8e6db8a4fbc6fcfa6f0f1a5419343671521b863b187d1c73bad3603bae66421d157ffef357669ddb8@13.74.157.139:30432", + "enode://0e4cba800f7b1ee73673afa6a4acead4018f0149d2e3216be3f133318fd165b324cd71b81fbe1e80deac8dbf56e57a49db7be67f8b9bc81bd2b7ee496434fb5d@13.74.157.139:30433", } )