Skip to content
This repository has been archived by the owner on Mar 21, 2022. It is now read-only.

Commit

Permalink
Release v0.1.1
Browse files Browse the repository at this point in the history
The program now vendors some more Yggdrasil code to improve performance;
as of now it's just the IP address calculation function with a simple
tweak that nonetheless speeds it up by 10% (preallocating the slice for
`temp`).

Vendored code can be turned off at any time by using `-original` flag
when running syg_go.

Vendored code is also covered with tests so that vendored implementation
stays compatible with Yggdrasil.
  • Loading branch information
tdemin committed Aug 8, 2020
2 parents 487fce5 + 23263b4 commit b177f71
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 5 deletions.
14 changes: 12 additions & 2 deletions .drone.yml
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .goreleaser.yml
@@ -1,5 +1,5 @@
builds:
- main: main.go
- main: .
env:
- CGO_ENABLED=0
goos:
Expand Down
21 changes: 21 additions & 0 deletions README.md
Expand Up @@ -34,6 +34,27 @@ 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

```
% syg_go -help
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
how many threads to use for mining (default 16)
-version
display version
```

### License

See [LICENSE](LICENSE).
52 changes: 52 additions & 0 deletions crypto.go
@@ -0,0 +1,52 @@
package main

import (
"github.com/yggdrasil-network/yggdrasil-go/src/address"
"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.
//
// 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
}
69 changes: 69 additions & 0 deletions 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)
}
}
13 changes: 11 additions & 2 deletions main.go
Expand Up @@ -20,19 +20,28 @@ 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")
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)
Expand Down Expand Up @@ -74,7 +83,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}
}
}

0 comments on commit b177f71

Please sign in to comment.