diff --git a/README.md b/README.md index d68615b..14c10ec 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,19 @@ # 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 `% 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 @@ -16,9 +23,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 @@ -45,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 @@ -58,6 +69,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). 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) + } + }() +} diff --git a/main.go b/main.go index 94e3f6f..8e2f929 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 @@ -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") @@ -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,48 @@ func main() { addrForNodeID = AddrForNodeID } - var ( - regex *regexp.Regexp - err error - ) - if !*highAddressMode { - regex, err = regexp.Compile(*rxflag) - if err != nil { - log.Printf("%v\n", err) - os.Exit(1) - } - } else { - regex = regexp.MustCompile("^2..::$") + regex, err := regexp.Compile(*rxflag) + if err != nil { + log.Printf("%v\n", err) + os.Exit(1) } newKeys := make(chan keySet, *threads) - log.Printf("starting mining for %v with %v threads\n", regex, *threads) + var currentBest []byte + + if !*highAddressMode { + log.Printf("starting mining for %v with %v threads\n", regex, *threads) + } else { + log.Printf("starting mining higher addresses with %v threads\n", *threads) + } for i := 0; i < *threads; i++ { go doBoxKeys(newKeys) } 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 + newKey.print() + } + counter++ + if counter%i == 0 { + log.Printf("reached %v iterations\n", counter) + } } } } @@ -88,6 +96,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 +112,15 @@ 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 +}