From 784784e196b1624aab2af3a4bac55adf01422430 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Mon, 24 Aug 2020 00:59:29 +0500 Subject: [PATCH 1/7] Add pprof support --- debug.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 debug.go diff --git a/debug.go b/debug.go new file mode 100644 index 0000000..f10ac30 --- /dev/null +++ b/debug.go @@ -0,0 +1,23 @@ +// +build debug + +package main + +import ( + "log" + "net/http" + _ "net/http/pprof" + "os" +) + +func init() { + listen := os.Getenv("SYGGO_HTTP") + if listen == "" { + listen = "[::]:8082" + } + log.Printf("profiling is enabled, HTTP server is attached to %s\n", listen) + go func() { + if err := http.ListenAndServe(listen, nil); err != nil { + log.Fatalf("http failed: %v\n", err) + } + }() +} From 80643460d12806a29e3d297919c49e035286a7a6 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Mon, 24 Aug 2020 01:02:49 +0500 Subject: [PATCH 2/7] Update README --- README.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d68615b..d7ab608 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # SimpleYggGen-Go -This program reimplements [SimpleYggGen](https://notabug.org/acetone/SimpleYggGen-Bash) in Go, importing the original Yggdrasil -code for generating keys and utilizing multiple CPU threads for mining. +This program reimplements +[SimpleYggGen](https://notabug.org/acetone/SimpleYggGen-Bash) in Go, importing +the original Yggdrasil code for generating keys and utilizing multiple CPU +threads for mining. ### Installation @@ -16,9 +18,13 @@ his implementation was that it ran grep and yggdrasil as separate processes, making mining very slow. Even though @acetone later made a C++ implementation, it still relied on running Yggdrasil as a separate process. -As of now (2020-08-12) @acetone reworked his C++ miner implementation, and -[SYG-C++](https://notabug.org/acetone/SimpleYggGen-CPP) is even more performant -than this program (making, like, 15% more iterations within the same time). +As of now (2020-08-24) @acetone reworked his C++ miner implementation, and +[SYG-C++](https://notabug.org/acetone/SimpleYggGen-CPP) is a lot more performant +than this program, making 4 times more iterations in the same time. If you're +using Windows, it might be feasible to use his program instead. + +There's also a CUDA miner by @frodo_baggins available +[here](https://notabug.org/frodo_buggins/ygg-brute). ### Performance @@ -58,6 +64,12 @@ Usage of syg_go: display version ``` +### Development + +`go tool pprof` support is available when building with `-tags debug`. The +program will launch an HTTP server attachable by pprof, listening on the address +specified by the `SYGGO_HTTP` environment variable. + ### License See [LICENSE](LICENSE). From 79a835265142c9a61f7e634e6ebe49ac7458f9e8 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Mon, 24 Aug 2020 01:37:34 +0500 Subject: [PATCH 3/7] Link AUR package in README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index d7ab608..67b6a99 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ threads for mining. `% go get -u -v git.tdem.in/tdemin/syg_go` +If you're an Arch Linux user, you can install it from +[AUR](https://aur.archlinux.org/packages/syg_go/): + +`% yay -S syg_go` + ### History [SimpleYggGen](https://notabug.org/acetone/SimpleYggGen-Bash) is originally a From 27f25333cb764d5d7b4b93075c20a25853ffe6c1 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Mon, 31 Aug 2020 01:44:10 +0500 Subject: [PATCH 4/7] Be honest with what our upstream is --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 94e3f6f..92d4b23 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,7 @@ package main /* -Parts of this program are taken from yggdrasil-go, located at +This program is largely based on cmd/genkeys from yggdrasil-go, located at https://github.com/yggdrasil-network/yggdrasil-go See cmd/genkeys/main.go@78b5f88e4bb734d0dd6a138ff08d34ca39dcaea3 From c3b29059568f2f2bde77243b064b2da5f8f13be9 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Mon, 31 Aug 2020 01:50:05 +0500 Subject: [PATCH 5/7] Fix logic of highaddr mining --- README.md | 2 +- main.go | 106 +++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 82 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 67b6a99..14c10ec 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ flag. % syg_go -help Usage of syg_go: -highaddr - high address mining mode (2xx::), excludes regex + high address mining mode, excludes regex -iter uint per how many iterations to output status (default 100000) -original diff --git a/main.go b/main.go index 92d4b23..9a41d7b 100644 --- a/main.go +++ b/main.go @@ -28,7 +28,7 @@ func main() { iterationsPerOutput := flag.Uint("iter", 100000, "per how many iterations to output status") displayVersion := flag.Bool("version", false, "display version") origCode := flag.Bool("original", false, "use original Yggdrasil code") - highAddressMode := flag.Bool("highaddr", false, "high address mining mode (2xx::), excludes regex") + highAddressMode := flag.Bool("highaddr", false, "high address mining mode, excludes regex") flag.Parse() if *displayVersion { println("syg_go", version) @@ -43,40 +43,55 @@ func main() { addrForNodeID = AddrForNodeID } + regex, err := regexp.Compile(*rxflag) + if err != nil { + log.Printf("%v\n", err) + os.Exit(1) + } + + newKeys := make(chan keySet, *threads) var ( - regex *regexp.Regexp - err error + threadChannels []chan []byte + currentBest []byte ) if !*highAddressMode { - regex, err = regexp.Compile(*rxflag) - if err != nil { - log.Printf("%v\n", err) - os.Exit(1) + log.Printf("starting mining for %v with %v threads\n", regex, *threads) + for i := 0; i < *threads; i++ { + go doBoxKeys(newKeys) } } else { - regex = regexp.MustCompile("^2..::$") - } - - newKeys := make(chan keySet, *threads) - log.Printf("starting mining for %v with %v threads\n", regex, *threads) - for i := 0; i < *threads; i++ { - go doBoxKeys(newKeys) + log.Printf("starting mining higher addresses with %v threads\n", *threads) + for i := 0; i < *threads; i++ { + threadChannels = append(threadChannels, make(chan []byte, *threads)) + go doBoxKeysHighAddr(newKeys, threadChannels[i]) + } } counter := uint64(0) i := uint64(*iterationsPerOutput) - for { - newKey := <-newKeys - if regex.MatchString(newKey.ip) { - log.Printf("priv: %s | pub: %s | nodeid: %s | ip: %s\n", - hex.EncodeToString(newKey.priv[:]), - hex.EncodeToString(newKey.pub[:]), - hex.EncodeToString(newKey.id[:]), - newKey.ip) + if !*highAddressMode { + for { + newKey := <-newKeys + if regex.MatchString(newKey.ip) { + newKey.print() + } + counter++ + if counter%i == 0 { + log.Printf("reached %v iterations\n", counter) + } } - counter++ - if counter%i == 0 { - log.Printf("reached %v iterations\n", counter) + } else { + for { + newKey := <-newKeys + if isBetter(currentBest[:], newKey.id) || len(currentBest) == 0 { + currentBest = newKey.id + for _, channel := range threadChannels { + select { + case channel <- newKey.id: + } + } + newKey.print() + } } } } @@ -88,6 +103,14 @@ type keySet struct { ip string } +func (k *keySet) print() { + log.Printf("priv: %s | pub: %s | nodeid: %s | ip: %s\n", + hex.EncodeToString(k.priv[:]), + hex.EncodeToString(k.pub[:]), + hex.EncodeToString(k.id[:]), + k.ip) +} + func doBoxKeys(out chan<- keySet) { for { pub, priv := crypto.NewBoxKeys() @@ -96,3 +119,36 @@ func doBoxKeys(out chan<- keySet) { out <- keySet{priv[:], pub[:], id[:], ip} } } + +func isBetter(oldID, newID []byte) bool { + for i := range oldID { + if newID[i] > oldID[i] { + return true + } + if newID[i] < oldID[i] { + return false + } + } + return false +} + +func doBoxKeysHighAddr(out chan<- keySet, in <-chan []byte) { + var bestID crypto.NodeID + for { + select { + case newBestID := <-in: + if isBetter(bestID[:], newBestID) { + copy(bestID[:], newBestID) + } + default: + pub, priv := crypto.NewBoxKeys() + id := crypto.GetNodeID(pub) + if !isBetter(bestID[:], id[:]) { + continue + } + bestID = *id + ip := net.IP(address.AddrForNodeID(id)[:]).String() + out <- keySet{priv[:], pub[:], id[:], ip} + } + } +} From 6a0dacdcf4836d0d5bff21a5ded93e6a0265fcbc Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Mon, 31 Aug 2020 02:01:30 +0500 Subject: [PATCH 6/7] Remove extraneous optimizations from genkeys cmd/genkeys tries to save time on converting IPs to strings, but this time appears to be lost on doing Go scheduling stuff instead. We remove the optimization. --- main.go | 46 +++++++++------------------------------------- 1 file changed, 9 insertions(+), 37 deletions(-) diff --git a/main.go b/main.go index 9a41d7b..720e866 100644 --- a/main.go +++ b/main.go @@ -50,21 +50,15 @@ func main() { } newKeys := make(chan keySet, *threads) - var ( - threadChannels []chan []byte - currentBest []byte - ) + var currentBest []byte + if !*highAddressMode { log.Printf("starting mining for %v with %v threads\n", regex, *threads) - for i := 0; i < *threads; i++ { - go doBoxKeys(newKeys) - } } else { log.Printf("starting mining higher addresses with %v threads\n", *threads) - for i := 0; i < *threads; i++ { - threadChannels = append(threadChannels, make(chan []byte, *threads)) - go doBoxKeysHighAddr(newKeys, threadChannels[i]) - } + } + for i := 0; i < *threads; i++ { + go doBoxKeys(newKeys) } counter := uint64(0) @@ -85,13 +79,12 @@ func main() { newKey := <-newKeys if isBetter(currentBest[:], newKey.id) || len(currentBest) == 0 { currentBest = newKey.id - for _, channel := range threadChannels { - select { - case channel <- newKey.id: - } - } newKey.print() } + counter++ + if counter%i == 0 { + log.Printf("reached %v iterations\n", counter) + } } } } @@ -131,24 +124,3 @@ func isBetter(oldID, newID []byte) bool { } return false } - -func doBoxKeysHighAddr(out chan<- keySet, in <-chan []byte) { - var bestID crypto.NodeID - for { - select { - case newBestID := <-in: - if isBetter(bestID[:], newBestID) { - copy(bestID[:], newBestID) - } - default: - pub, priv := crypto.NewBoxKeys() - id := crypto.GetNodeID(pub) - if !isBetter(bestID[:], id[:]) { - continue - } - bestID = *id - ip := net.IP(address.AddrForNodeID(id)[:]).String() - out <- keySet{priv[:], pub[:], id[:], ip} - } - } -} From ef12b071a8765cb46f451cd6938f8541ef00b349 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Mon, 31 Aug 2020 02:01:48 +0500 Subject: [PATCH 7/7] Bump v0.1.3 --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 720e866..8e2f929 100644 --- a/main.go +++ b/main.go @@ -20,7 +20,7 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/crypto" ) -var version = "v0.1.2" +var version = "v0.1.3" func main() { rxflag := flag.String("regex", "::", "regex to match addresses against")