From d53753ff72f4953d71fb5c85b34fb94fe609cd34 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Wed, 29 Jul 2020 00:32:04 +0500 Subject: [PATCH 1/8] Add usage to README --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index be2304d..ae401b3 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,21 @@ With 8 threads on Ryzen 1700X while searching for `::` this program reaches: * 100 000 000 iterations in 25 minutes, 58 seconds * 500 000 000 iterations in 2 hours, 10 minutes +### Usage + +``` +% syg_go -help +Usage of syg_go: + -iter uint + per how many iterations to output status (default 100000) + -regex string + regex to match addresses against (default "::") + -threads int + how many threads to use for mining (default 16) + -version + display version +``` + ### License See [LICENSE](LICENSE). From ca280954f4f0e85b4b3ee7b6780c8b8273d23634 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Sat, 8 Aug 2020 20:57:23 +0500 Subject: [PATCH 2/8] Vendor IP address calculation function The version of AddrForNodeID we vendor preallocates memory during IP address calculation, and has a slight performance win. --- crypto.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ main.go | 3 +-- 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 crypto.go diff --git a/crypto.go b/crypto.go new file mode 100644 index 0000000..35a8af1 --- /dev/null +++ b/crypto.go @@ -0,0 +1,47 @@ +package main + +import ( + "github.com/yggdrasil-network/yggdrasil-go/src/address" + "github.com/yggdrasil-network/yggdrasil-go/src/crypto" +) + +// AddrForNodeID is a variant of Yggdrasil's src/address.AddrForNodeID that +// might be slightly optimized for performance. +// +// This function is a modded variant of address.AddrForNodeID from Yggdrasil. +// See src/address/address.go@78b5f88e4bb734d0dd6a138ff08d34ca39dcaea3 +func AddrForNodeID(nid *crypto.NodeID) *address.Address { + // 128 bit address, begins with GetPrefix(), with last bit set to 0 + // (indicates an address). Next 7 bits, interpreted as a uint, are the count + // of leading 1s in the NodeID. Leading 1s and first leading 0 of the NodeID + // are truncated off. The rest is appended to the IPv6 address (truncated to + // 128 bits total). + var addr address.Address + temp := make([]byte, 0, len(nid)) + done := false + ones := byte(0) + bits := byte(0) + nBits := 0 + for idx := 0; idx < 8*len(nid); idx++ { + bit := (nid[idx/8] & (0x80 >> byte(idx%8))) >> byte(7-(idx%8)) + if !done && bit != 0 { + ones++ + continue + } + if !done && bit == 0 { + done = true + continue + } + bits = (bits << 1) | bit + nBits++ + if nBits == 8 { + nBits = 0 + temp = append(temp, bits) + } + } + prefix := address.GetPrefix() + copy(addr[:], prefix[:]) + addr[len(prefix)] = ones + copy(addr[len(prefix)+1:], temp) + return &addr +} diff --git a/main.go b/main.go index d0519ed..da94066 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,6 @@ import ( "regexp" "runtime" - "github.com/yggdrasil-network/yggdrasil-go/src/address" "github.com/yggdrasil-network/yggdrasil-go/src/crypto" ) @@ -74,7 +73,7 @@ func doBoxKeys(out chan<- keySet) { for { pub, priv := crypto.NewBoxKeys() id := crypto.GetNodeID(pub) - ip := net.IP(address.AddrForNodeID(id)[:]).String() + ip := net.IP(AddrForNodeID(id)[:]).String() out <- keySet{priv[:], pub[:], id[:], ip} } } From 1361c3e981c2a5eb958956ca7eeda5b2183b406e Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Sat, 8 Aug 2020 20:57:56 +0500 Subject: [PATCH 3/8] Add tests and benchmarks for vendored code --- crypto_test.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 crypto_test.go diff --git a/crypto_test.go b/crypto_test.go new file mode 100644 index 0000000..90aa4a0 --- /dev/null +++ b/crypto_test.go @@ -0,0 +1,69 @@ +package main + +import ( + "net" + "os" + "regexp" + "testing" + + "github.com/yggdrasil-network/yggdrasil-go/src/address" + "github.com/yggdrasil-network/yggdrasil-go/src/crypto" +) + +var ( + testAddr *address.Address + testPub *crypto.BoxPubKey + testNodeID *crypto.NodeID + testRegex *regexp.Regexp +) + +func TestAddrForNodeID(t *testing.T) { + for i := 20; i > 0; i-- { + pub, _ := crypto.NewBoxKeys() + id := crypto.GetNodeID(pub) + origIP := net.IP(address.AddrForNodeID(id)[:]) + modIP := net.IP(AddrForNodeID(id)[:]) + if !origIP.Equal(modIP) { + t.Errorf("got %s, expected %s", modIP, origIP) + } + } +} + +func TestMain(m *testing.M) { + testPub, _ = crypto.NewBoxKeys() + testNodeID = crypto.GetNodeID(testPub) + testRegex = regexp.MustCompile("::") + os.Exit(m.Run()) +} + +func BenchmarkOrigAddrForNodeID(b *testing.B) { + for i := 0; i < b.N; i++ { + testAddr = address.AddrForNodeID(testNodeID) + } +} + +func BenchmarkModdedAddrForNodeID(b *testing.B) { + for i := 0; i < b.N; i++ { + testAddr = AddrForNodeID(testNodeID) + } +} + +// measures overall performance of code from cmd/genkeys +func BenchmarkOrigLoop(b *testing.B) { + for i := 0; i < b.N; i++ { + pub, _ := crypto.NewBoxKeys() + id := crypto.GetNodeID(pub) + ip := net.IP(address.AddrForNodeID(id)[:]).String() + testRegex.MatchString(ip) + } +} + +// measures overall performance of functions we vendor +func BenchmarkModdedLoop(b *testing.B) { + for i := 0; i < b.N; i++ { + pub, _ := crypto.NewBoxKeys() + id := crypto.GetNodeID(pub) + ip := net.IP(AddrForNodeID(id)[:]).String() + testRegex.MatchString(ip) + } +} From e6c3e3884e29689ec2e3f673b66931f4516a3a65 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Sat, 8 Aug 2020 20:58:14 +0500 Subject: [PATCH 4/8] Add testing to Drone pipeline --- .drone.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.drone.yml b/.drone.yml index 0905067..6f757f6 100644 --- a/.drone.yml +++ b/.drone.yml @@ -2,12 +2,22 @@ kind: pipeline name: build & release steps: -- name: fetch +- name: fetch tags image: docker:git commands: - git fetch --tags + when: + event: tag +- name: test + image: golang:1.14-alpine + commands: + - go test -v . + when: + event: + exclude: + - tag - name: release - image: golang + image: golang:1.14-alpine environment: GITEA_TOKEN: from_secret: goreleaser_gitea_token From 5c1dd7aff274ca0992579b0055349fcc6c688c97 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Sat, 8 Aug 2020 21:21:49 +0500 Subject: [PATCH 5/8] Make vendoring tunable with build tags --- README.md | 4 ++++ crypto.go | 5 +++++ crypto_original.go | 14 ++++++++++++++ crypto_vendor.go | 10 ++++++++++ main.go | 2 +- 5 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 crypto_original.go create mode 100644 crypto_vendor.go diff --git a/README.md b/README.md index ae401b3..e3a792b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ code for generating keys and utilizing multiple CPU threads for mining. `% go get -u -v git.tdem.in/tdemin/syg_go` +This program contains some modded code from Yggdrasil that aims to improve +performance. If you prefer to use original Yggdrasil code, set `-tags original` +flag in the command above. + ### History SimpleYggGen is originally a project by [@acetone](https://notabug.org/acetone), diff --git a/crypto.go b/crypto.go index 35a8af1..bf40398 100644 --- a/crypto.go +++ b/crypto.go @@ -5,6 +5,11 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/crypto" ) +// custom function selectors, see crypto_xxx.go +var ( + addrForNodeID func(*crypto.NodeID) *address.Address +) + // AddrForNodeID is a variant of Yggdrasil's src/address.AddrForNodeID that // might be slightly optimized for performance. // diff --git a/crypto_original.go b/crypto_original.go new file mode 100644 index 0000000..a0ed3dc --- /dev/null +++ b/crypto_original.go @@ -0,0 +1,14 @@ +// +build original + +package main + +import ( + "log" + + "github.com/yggdrasil-network/yggdrasil-go/src/address" +) + +func init() { + log.Println("using unmodified Yggdrasil code") + addrForNodeID = address.AddrForNodeID +} diff --git a/crypto_vendor.go b/crypto_vendor.go new file mode 100644 index 0000000..5909965 --- /dev/null +++ b/crypto_vendor.go @@ -0,0 +1,10 @@ +// +build !original + +package main + +import "log" + +func init() { + log.Println("using vendored syg_go code") + addrForNodeID = AddrForNodeID +} diff --git a/main.go b/main.go index da94066..8e81de3 100644 --- a/main.go +++ b/main.go @@ -73,7 +73,7 @@ func doBoxKeys(out chan<- keySet) { for { pub, priv := crypto.NewBoxKeys() id := crypto.GetNodeID(pub) - ip := net.IP(AddrForNodeID(id)[:]).String() + ip := net.IP(addrForNodeID(id)[:]).String() out <- keySet{priv[:], pub[:], id[:], ip} } } From 9a25e69d3a93e2744db0024fee77670f60177605 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Sat, 8 Aug 2020 21:28:24 +0500 Subject: [PATCH 6/8] Update goreleaser config for multiple files --- .goreleaser.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index d6eead2..ecd0dac 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,5 +1,5 @@ builds: -- main: main.go +- main: . env: - CGO_ENABLED=0 goos: From 5bd373be6118f74c975dd2bf3effd909196b6f9f Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Sat, 8 Aug 2020 21:38:37 +0500 Subject: [PATCH 7/8] Make crypto implementation switchable with cmdline flags --- README.md | 10 ++++++---- crypto_original.go | 14 -------------- crypto_vendor.go | 10 ---------- main.go | 10 ++++++++++ 4 files changed, 16 insertions(+), 28 deletions(-) delete mode 100644 crypto_original.go delete mode 100644 crypto_vendor.go diff --git a/README.md b/README.md index e3a792b..6baa191 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,6 @@ code for generating keys and utilizing multiple CPU threads for mining. `% go get -u -v git.tdem.in/tdemin/syg_go` -This program contains some modded code from Yggdrasil that aims to improve -performance. If you prefer to use original Yggdrasil code, set `-tags original` -flag in the command above. - ### History SimpleYggGen is originally a project by [@acetone](https://notabug.org/acetone), @@ -38,6 +34,10 @@ With 8 threads on Ryzen 1700X while searching for `::` this program reaches: * 100 000 000 iterations in 25 minutes, 58 seconds * 500 000 000 iterations in 2 hours, 10 minutes +This program contains some modded code from Yggdrasil that aims to improve +performance. If you prefer to use original Yggdrasil code, set `-original` +flag. + ### Usage ``` @@ -45,6 +45,8 @@ With 8 threads on Ryzen 1700X while searching for `::` this program reaches: Usage of syg_go: -iter uint per how many iterations to output status (default 100000) + -original + use original Yggdrasil code -regex string regex to match addresses against (default "::") -threads int diff --git a/crypto_original.go b/crypto_original.go deleted file mode 100644 index a0ed3dc..0000000 --- a/crypto_original.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build original - -package main - -import ( - "log" - - "github.com/yggdrasil-network/yggdrasil-go/src/address" -) - -func init() { - log.Println("using unmodified Yggdrasil code") - addrForNodeID = address.AddrForNodeID -} diff --git a/crypto_vendor.go b/crypto_vendor.go deleted file mode 100644 index 5909965..0000000 --- a/crypto_vendor.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build !original - -package main - -import "log" - -func init() { - log.Println("using vendored syg_go code") - addrForNodeID = AddrForNodeID -} diff --git a/main.go b/main.go index 8e81de3..e8c24e6 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ import ( "regexp" "runtime" + "github.com/yggdrasil-network/yggdrasil-go/src/address" "github.com/yggdrasil-network/yggdrasil-go/src/crypto" ) @@ -26,12 +27,21 @@ func main() { threads := flag.Int("threads", runtime.GOMAXPROCS(0), "how many threads to use for mining") 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") flag.Parse() if *displayVersion { println("syg_go", version) return } + if *origCode { + log.Println("using unmodified Yggdrasil code") + addrForNodeID = address.AddrForNodeID + } else { + log.Println("using syg_go vendored code") + addrForNodeID = AddrForNodeID + } + regex, err := regexp.Compile(*rxflag) if err != nil { log.Printf("%v\n", err) From 23263b4540e0a52312ed6e5f48a216724295e383 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Sat, 8 Aug 2020 21:47:19 +0500 Subject: [PATCH 8/8] Bump v0.1.1 --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index e8c24e6..54b96be 100644 --- a/main.go +++ b/main.go @@ -20,7 +20,7 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/crypto" ) -var version = "v0.1.0" +var version = "v0.1.1" func main() { rxflag := flag.String("regex", "::", "regex to match addresses against")