This repository has been archived by the owner on Mar 21, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
Showing
6 changed files
with
166 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
builds: | ||
- main: main.go | ||
- main: . | ||
env: | ||
- CGO_ENABLED=0 | ||
goos: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters