mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
go list ./... returned nothing, so no package here could be built or tested and the failure was invisible: one directory held a Go test beside fifteen .cpp files, which makes it a Go package the toolchain then refuses. The generator moves to the golden/ subdirectory the other two C++ chains already use. That silence was hiding a package that does not compile. host/ calls EnsureIdentity and identity.go defines LoadIdentity — a rename that happened on one side — and it has no importers, because the Go host is cmd/luxd now. Deleted rather than repaired: the thing it was a stand-in for arrived. The operator tools came across too (backup, blscheck, ceremony, config, genesishash, keytoaddr, pqkeygen, repair-proposervm, wire) plus benchmarks and examples, so the package set now differs from the retired repo by exactly one name: main/ is cmd/luxd. Two tests were right and are now satisfied rather than silenced. The purity test looked for ./main; it looks where the daemon lives. The chain-address test found conformance/dex spelling /v1/chain by hand — but that is its own module on purpose, since it links an EVM ABI and a signer the node must not carry, so it cannot call Chain. The rule is about this module, and the walk now says so.
272 lines
5.4 KiB
Go
272 lines
5.4 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package benchmarks
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/luxfi/crypto/hash"
|
|
"github.com/luxfi/ids"
|
|
"github.com/luxfi/log"
|
|
)
|
|
|
|
// BenchmarkHashingComputeHash256 benchmarks SHA256 hashing performance
|
|
func BenchmarkHashingComputeHash256(b *testing.B) {
|
|
data := make([]byte, 1024) // 1KB of data
|
|
for i := range data {
|
|
data[i] = byte(i % 256)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
_ = hash.ComputeHash256(data)
|
|
}
|
|
|
|
b.SetBytes(int64(len(data)))
|
|
}
|
|
|
|
// BenchmarkHashingComputeHash256Array benchmarks SHA256 array hashing
|
|
func BenchmarkHashingComputeHash256Array(b *testing.B) {
|
|
data := make([]byte, 32) // 32 bytes (common hash size)
|
|
for i := range data {
|
|
data[i] = byte(i)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
_ = hash.ComputeHash256Array(data)
|
|
}
|
|
|
|
b.SetBytes(int64(len(data)))
|
|
}
|
|
|
|
// BenchmarkIDGeneration benchmarks ID generation performance
|
|
func BenchmarkIDGeneration(b *testing.B) {
|
|
data := []byte("test data for ID generation")
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
_ = ids.ID(hash.ComputeHash256(data))
|
|
}
|
|
}
|
|
|
|
// BenchmarkIDComparison benchmarks ID comparison operations
|
|
func BenchmarkIDComparison(b *testing.B) {
|
|
id1 := ids.GenerateTestID()
|
|
id2 := ids.GenerateTestID()
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
_ = id1.Compare(id2)
|
|
}
|
|
}
|
|
|
|
// BenchmarkIDString benchmarks ID string conversion
|
|
func BenchmarkIDString(b *testing.B) {
|
|
id := ids.GenerateTestID()
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
_ = id.String()
|
|
}
|
|
}
|
|
|
|
// BenchmarkIDFromString benchmarks parsing ID from string
|
|
func BenchmarkIDFromString(b *testing.B) {
|
|
idStr := ids.GenerateTestID().String()
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
_, _ = ids.FromString(idStr)
|
|
}
|
|
}
|
|
|
|
// BenchmarkVerifySignature times the loop around a signature verification, not
|
|
// the verification: the body below does arithmetic on the operand lengths and
|
|
// calls no crypto at all, so the number it reports is the harness floor.
|
|
func BenchmarkVerifySignature(b *testing.B) {
|
|
message := []byte("message to sign")
|
|
signature := make([]byte, 65) // typical signature size
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
// Simulate signature verification
|
|
_ = len(message) + len(signature)
|
|
}
|
|
}
|
|
|
|
// BenchmarkContextWithTimeout benchmarks context creation with timeout
|
|
func BenchmarkContextWithTimeout(b *testing.B) {
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
cancel()
|
|
_ = ctx
|
|
}
|
|
}
|
|
|
|
// BenchmarkLoggerCreation benchmarks logger creation
|
|
func BenchmarkLoggerCreation(b *testing.B) {
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
_ = log.New()
|
|
}
|
|
}
|
|
|
|
// BenchmarkMapOperations benchmarks map operations commonly used in consensus
|
|
func BenchmarkMapOperations(b *testing.B) {
|
|
b.Run("Insert", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
m := make(map[ids.ID]bool)
|
|
for j := 0; j < 100; j++ {
|
|
m[ids.GenerateTestID()] = true
|
|
}
|
|
}
|
|
})
|
|
|
|
b.Run("Lookup", func(b *testing.B) {
|
|
m := make(map[ids.ID]bool)
|
|
keys := make([]ids.ID, 100)
|
|
for i := 0; i < 100; i++ {
|
|
id := ids.GenerateTestID()
|
|
keys[i] = id
|
|
m[id] = true
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
_ = m[keys[i%100]]
|
|
}
|
|
})
|
|
|
|
b.Run("Delete", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
m := make(map[ids.ID]bool)
|
|
id := ids.GenerateTestID()
|
|
m[id] = true
|
|
delete(m, id)
|
|
}
|
|
})
|
|
}
|
|
|
|
// BenchmarkSliceOperations benchmarks slice operations
|
|
func BenchmarkSliceOperations(b *testing.B) {
|
|
b.Run("Append", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
s := make([]ids.ID, 0, 100)
|
|
for j := 0; j < 100; j++ {
|
|
s = append(s, ids.GenerateTestID())
|
|
}
|
|
}
|
|
})
|
|
|
|
b.Run("Copy", func(b *testing.B) {
|
|
src := make([]ids.ID, 100)
|
|
for i := range src {
|
|
src[i] = ids.GenerateTestID()
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
dst := make([]ids.ID, len(src))
|
|
copy(dst, src)
|
|
}
|
|
})
|
|
}
|
|
|
|
// BenchmarkChannelOperations benchmarks channel operations
|
|
func BenchmarkChannelOperations(b *testing.B) {
|
|
b.Run("Send", func(b *testing.B) {
|
|
ch := make(chan ids.ID, 100)
|
|
id := ids.GenerateTestID()
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
select {
|
|
case ch <- id:
|
|
default:
|
|
// Channel full, drain it
|
|
<-ch
|
|
ch <- id
|
|
}
|
|
}
|
|
})
|
|
|
|
b.Run("Receive", func(b *testing.B) {
|
|
ch := make(chan ids.ID, 100)
|
|
id := ids.GenerateTestID()
|
|
for i := 0; i < 100; i++ {
|
|
ch <- id
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
select {
|
|
case <-ch:
|
|
ch <- id // Put it back
|
|
default:
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
// BenchmarkMessageSerialization benchmarks message serialization
|
|
func BenchmarkMessageSerialization(b *testing.B) {
|
|
type testMessage struct {
|
|
ID ids.ID
|
|
Height uint64
|
|
Timestamp time.Time
|
|
Data []byte
|
|
}
|
|
|
|
msg := testMessage{
|
|
ID: ids.GenerateTestID(),
|
|
Height: 1000000,
|
|
Timestamp: time.Now(),
|
|
Data: make([]byte, 256),
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
// Simulate serialization by accessing all fields
|
|
_ = msg.ID
|
|
_ = msg.Height
|
|
_ = msg.Timestamp
|
|
_ = msg.Data
|
|
}
|
|
}
|