54 changed files with 5519 additions and 4442 deletions
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
data/ |
||||
reports/ |
||||
*.log |
||||
*.db |
||||
external/ |
||||
configs/ |
||||
@ -0,0 +1,99 @@
@@ -0,0 +1,99 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"context" |
||||
"log" |
||||
"os" |
||||
"os/signal" |
||||
"syscall" |
||||
"time" |
||||
|
||||
"github.com/nbd-wtf/go-nostr" |
||||
sqlite "github.com/vertex-lab/nostr-sqlite" |
||||
"github.com/pippellia-btc/rely" |
||||
) |
||||
|
||||
func main() { |
||||
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) |
||||
defer cancel() |
||||
|
||||
// Get configuration from environment with defaults
|
||||
dbPath := os.Getenv("DATABASE_PATH") |
||||
if dbPath == "" { |
||||
dbPath = "./relay.db" |
||||
} |
||||
|
||||
listenAddr := os.Getenv("RELAY_LISTEN") |
||||
if listenAddr == "" { |
||||
listenAddr = "0.0.0.0:3334" |
||||
} |
||||
|
||||
// Initialize database
|
||||
db, err := sqlite.New(dbPath) |
||||
if err != nil { |
||||
log.Fatalf("failed to initialize database: %v", err) |
||||
} |
||||
defer db.Close() |
||||
|
||||
// Create relay with handlers
|
||||
relay := rely.NewRelay( |
||||
rely.WithQueueCapacity(10_000), |
||||
rely.WithMaxProcessors(10), |
||||
) |
||||
|
||||
// Register event handlers using the correct API
|
||||
relay.On.Event = Save(db) |
||||
relay.On.Req = Query(db) |
||||
relay.On.Count = Count(db) |
||||
|
||||
// Start relay
|
||||
log.Printf("Starting rely-sqlite on %s with database %s", listenAddr, dbPath) |
||||
err = relay.StartAndServe(ctx, listenAddr) |
||||
if err != nil { |
||||
log.Fatalf("relay failed: %v", err) |
||||
} |
||||
} |
||||
|
||||
// Save handles incoming events
|
||||
func Save(db *sqlite.Store) func(_ rely.Client, e *nostr.Event) error { |
||||
return func(_ rely.Client, e *nostr.Event) error { |
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) |
||||
defer cancel() |
||||
|
||||
switch { |
||||
case nostr.IsRegularKind(e.Kind): |
||||
_, err := db.Save(ctx, e) |
||||
return err |
||||
case nostr.IsReplaceableKind(e.Kind) || nostr.IsAddressableKind(e.Kind): |
||||
_, err := db.Replace(ctx, e) |
||||
return err |
||||
default: |
||||
return nil |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Query retrieves events matching filters
|
||||
func Query(db *sqlite.Store) func(ctx context.Context, _ rely.Client, filters nostr.Filters) ([]nostr.Event, error) { |
||||
return func(ctx context.Context, _ rely.Client, filters nostr.Filters) ([]nostr.Event, error) { |
||||
ctx, cancel := context.WithTimeout(ctx, 2*time.Second) |
||||
defer cancel() |
||||
return db.Query(ctx, filters...) |
||||
} |
||||
} |
||||
|
||||
// Count counts events matching filters
|
||||
func Count(db *sqlite.Store) func(_ rely.Client, filters nostr.Filters) (count int64, approx bool, err error) { |
||||
return func(_ rely.Client, filters nostr.Filters) (count int64, approx bool, err error) { |
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second) |
||||
defer cancel() |
||||
count, err = db.Count(ctx, filters...) |
||||
if err != nil { |
||||
return -1, false, err |
||||
} |
||||
return count, false, nil |
||||
} |
||||
} |
||||
@ -0,0 +1,151 @@
@@ -0,0 +1,151 @@
|
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"log" |
||||
"os" |
||||
"path/filepath" |
||||
"time" |
||||
|
||||
"next.orly.dev/pkg/database" |
||||
) |
||||
|
||||
// RelySQLiteBenchmark wraps a Benchmark with rely-sqlite-specific setup
|
||||
type RelySQLiteBenchmark struct { |
||||
config *BenchmarkConfig |
||||
database database.Database |
||||
bench *BenchmarkAdapter |
||||
dbPath string |
||||
} |
||||
|
||||
// NewRelySQLiteBenchmark creates a new rely-sqlite benchmark instance
|
||||
func NewRelySQLiteBenchmark(config *BenchmarkConfig) (*RelySQLiteBenchmark, error) { |
||||
// Create database path
|
||||
dbPath := filepath.Join(config.DataDir, "relysqlite.db") |
||||
|
||||
// Ensure parent directory exists
|
||||
if err := os.MkdirAll(config.DataDir, 0755); err != nil { |
||||
return nil, fmt.Errorf("failed to create data directory: %w", err) |
||||
} |
||||
|
||||
// Remove existing database file if it exists
|
||||
if _, err := os.Stat(dbPath); err == nil { |
||||
if err := os.Remove(dbPath); err != nil { |
||||
return nil, fmt.Errorf("failed to remove existing database: %w", err) |
||||
} |
||||
} |
||||
|
||||
// Create wrapper
|
||||
wrapper, err := NewRelySQLiteWrapper(dbPath) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("failed to create rely-sqlite wrapper: %w", err) |
||||
} |
||||
|
||||
// Wait for database to be ready
|
||||
fmt.Println("Waiting for rely-sqlite database to be ready...") |
||||
select { |
||||
case <-wrapper.Ready(): |
||||
fmt.Println("Rely-sqlite database is ready") |
||||
case <-time.After(10 * time.Second): |
||||
wrapper.Close() |
||||
return nil, fmt.Errorf("rely-sqlite database failed to become ready") |
||||
} |
||||
|
||||
// Create adapter to use Database interface with Benchmark
|
||||
adapter := NewBenchmarkAdapter(config, wrapper) |
||||
|
||||
relysqliteBench := &RelySQLiteBenchmark{ |
||||
config: config, |
||||
database: wrapper, |
||||
bench: adapter, |
||||
dbPath: dbPath, |
||||
} |
||||
|
||||
return relysqliteBench, nil |
||||
} |
||||
|
||||
// Close closes the rely-sqlite benchmark
|
||||
func (rsb *RelySQLiteBenchmark) Close() { |
||||
fmt.Println("Closing rely-sqlite benchmark...") |
||||
|
||||
if rsb.database != nil { |
||||
rsb.database.Close() |
||||
} |
||||
|
||||
// Clean up database file
|
||||
if rsb.dbPath != "" { |
||||
os.Remove(rsb.dbPath) |
||||
} |
||||
} |
||||
|
||||
// RunSuite runs the benchmark suite on rely-sqlite
|
||||
func (rsb *RelySQLiteBenchmark) RunSuite() { |
||||
fmt.Println("\n╔════════════════════════════════════════════════════════╗") |
||||
fmt.Println("║ RELY-SQLITE BACKEND BENCHMARK SUITE ║") |
||||
fmt.Println("╚════════════════════════════════════════════════════════╝") |
||||
|
||||
// Run benchmark tests
|
||||
fmt.Printf("\n=== Starting Rely-SQLite benchmark ===\n") |
||||
|
||||
fmt.Printf("RunPeakThroughputTest (Rely-SQLite)..\n") |
||||
rsb.bench.RunPeakThroughputTest() |
||||
fmt.Println("Wiping database between tests...") |
||||
rsb.wipeDatabase() |
||||
time.Sleep(5 * time.Second) |
||||
|
||||
fmt.Printf("RunBurstPatternTest (Rely-SQLite)..\n") |
||||
rsb.bench.RunBurstPatternTest() |
||||
fmt.Println("Wiping database between tests...") |
||||
rsb.wipeDatabase() |
||||
time.Sleep(5 * time.Second) |
||||
|
||||
fmt.Printf("RunMixedReadWriteTest (Rely-SQLite)..\n") |
||||
rsb.bench.RunMixedReadWriteTest() |
||||
fmt.Println("Wiping database between tests...") |
||||
rsb.wipeDatabase() |
||||
time.Sleep(5 * time.Second) |
||||
|
||||
fmt.Printf("RunQueryTest (Rely-SQLite)..\n") |
||||
rsb.bench.RunQueryTest() |
||||
fmt.Println("Wiping database between tests...") |
||||
rsb.wipeDatabase() |
||||
time.Sleep(5 * time.Second) |
||||
|
||||
fmt.Printf("RunConcurrentQueryStoreTest (Rely-SQLite)..\n") |
||||
rsb.bench.RunConcurrentQueryStoreTest() |
||||
|
||||
fmt.Printf("\n=== Rely-SQLite benchmark completed ===\n\n") |
||||
} |
||||
|
||||
// wipeDatabase recreates the database for a clean slate
|
||||
func (rsb *RelySQLiteBenchmark) wipeDatabase() { |
||||
// Close existing database
|
||||
if rsb.database != nil { |
||||
rsb.database.Close() |
||||
} |
||||
|
||||
// Remove database file
|
||||
if rsb.dbPath != "" { |
||||
os.Remove(rsb.dbPath) |
||||
} |
||||
|
||||
// Recreate database
|
||||
wrapper, err := NewRelySQLiteWrapper(rsb.dbPath) |
||||
if err != nil { |
||||
log.Printf("Failed to recreate database: %v", err) |
||||
return |
||||
} |
||||
|
||||
rsb.database = wrapper |
||||
rsb.bench.db = wrapper |
||||
} |
||||
|
||||
// GenerateReport generates the benchmark report
|
||||
func (rsb *RelySQLiteBenchmark) GenerateReport() { |
||||
rsb.bench.GenerateReport() |
||||
} |
||||
|
||||
// GenerateAsciidocReport generates asciidoc format report
|
||||
func (rsb *RelySQLiteBenchmark) GenerateAsciidocReport() { |
||||
rsb.bench.GenerateAsciidocReport() |
||||
} |
||||
@ -0,0 +1,164 @@
@@ -0,0 +1,164 @@
|
||||
package main |
||||
|
||||
import ( |
||||
"encoding/hex" |
||||
"fmt" |
||||
|
||||
"github.com/nbd-wtf/go-nostr" |
||||
|
||||
orlyEvent "next.orly.dev/pkg/encoders/event" |
||||
orlyFilter "next.orly.dev/pkg/encoders/filter" |
||||
orlyTag "next.orly.dev/pkg/encoders/tag" |
||||
) |
||||
|
||||
// convertToNostrEvent converts an ORLY event to a go-nostr event
|
||||
func convertToNostrEvent(ev *orlyEvent.E) (*nostr.Event, error) { |
||||
if ev == nil { |
||||
return nil, fmt.Errorf("nil event") |
||||
} |
||||
|
||||
nostrEv := &nostr.Event{ |
||||
ID: hex.EncodeToString(ev.ID), |
||||
PubKey: hex.EncodeToString(ev.Pubkey), |
||||
CreatedAt: nostr.Timestamp(ev.CreatedAt), |
||||
Kind: int(ev.Kind), |
||||
Content: string(ev.Content), |
||||
Sig: hex.EncodeToString(ev.Sig), |
||||
} |
||||
|
||||
// Convert tags
|
||||
if ev.Tags != nil && len(*ev.Tags) > 0 { |
||||
nostrEv.Tags = make(nostr.Tags, 0, len(*ev.Tags)) |
||||
for _, orlyTag := range *ev.Tags { |
||||
if orlyTag != nil && len(orlyTag.T) > 0 { |
||||
tag := make(nostr.Tag, len(orlyTag.T)) |
||||
for i, val := range orlyTag.T { |
||||
tag[i] = string(val) |
||||
} |
||||
nostrEv.Tags = append(nostrEv.Tags, tag) |
||||
} |
||||
} |
||||
} |
||||
|
||||
return nostrEv, nil |
||||
} |
||||
|
||||
// convertFromNostrEvent converts a go-nostr event to an ORLY event
|
||||
func convertFromNostrEvent(ne *nostr.Event) (*orlyEvent.E, error) { |
||||
if ne == nil { |
||||
return nil, fmt.Errorf("nil event") |
||||
} |
||||
|
||||
ev := orlyEvent.New() |
||||
|
||||
// Convert ID
|
||||
idBytes, err := hex.DecodeString(ne.ID) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("failed to decode ID: %w", err) |
||||
} |
||||
ev.ID = idBytes |
||||
|
||||
// Convert Pubkey
|
||||
pubkeyBytes, err := hex.DecodeString(ne.PubKey) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("failed to decode pubkey: %w", err) |
||||
} |
||||
ev.Pubkey = pubkeyBytes |
||||
|
||||
// Convert Sig
|
||||
sigBytes, err := hex.DecodeString(ne.Sig) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("failed to decode signature: %w", err) |
||||
} |
||||
ev.Sig = sigBytes |
||||
|
||||
// Simple fields
|
||||
ev.CreatedAt = int64(ne.CreatedAt) |
||||
ev.Kind = uint16(ne.Kind) |
||||
ev.Content = []byte(ne.Content) |
||||
|
||||
// Convert tags
|
||||
if len(ne.Tags) > 0 { |
||||
ev.Tags = orlyTag.NewS() |
||||
for _, nostrTag := range ne.Tags { |
||||
if len(nostrTag) > 0 { |
||||
tag := orlyTag.NewWithCap(len(nostrTag)) |
||||
for _, val := range nostrTag { |
||||
tag.T = append(tag.T, []byte(val)) |
||||
} |
||||
*ev.Tags = append(*ev.Tags, tag) |
||||
} |
||||
} |
||||
} else { |
||||
ev.Tags = orlyTag.NewS() |
||||
} |
||||
|
||||
return ev, nil |
||||
} |
||||
|
||||
// convertToNostrFilter converts an ORLY filter to a go-nostr filter
|
||||
func convertToNostrFilter(f *orlyFilter.F) (nostr.Filter, error) { |
||||
if f == nil { |
||||
return nostr.Filter{}, fmt.Errorf("nil filter") |
||||
} |
||||
|
||||
filter := nostr.Filter{} |
||||
|
||||
// Convert IDs
|
||||
if f.Ids != nil && len(f.Ids.T) > 0 { |
||||
filter.IDs = make([]string, 0, len(f.Ids.T)) |
||||
for _, id := range f.Ids.T { |
||||
filter.IDs = append(filter.IDs, hex.EncodeToString(id)) |
||||
} |
||||
} |
||||
|
||||
// Convert Authors
|
||||
if f.Authors != nil && len(f.Authors.T) > 0 { |
||||
filter.Authors = make([]string, 0, len(f.Authors.T)) |
||||
for _, author := range f.Authors.T { |
||||
filter.Authors = append(filter.Authors, hex.EncodeToString(author)) |
||||
} |
||||
} |
||||
|
||||
// Convert Kinds
|
||||
if f.Kinds != nil && len(f.Kinds.K) > 0 { |
||||
filter.Kinds = make([]int, 0, len(f.Kinds.K)) |
||||
for _, kind := range f.Kinds.K { |
||||
filter.Kinds = append(filter.Kinds, int(kind.K)) |
||||
} |
||||
} |
||||
|
||||
// Convert Tags
|
||||
if f.Tags != nil && len(*f.Tags) > 0 { |
||||
filter.Tags = make(nostr.TagMap) |
||||
for _, tag := range *f.Tags { |
||||
if tag != nil && len(tag.T) >= 2 { |
||||
tagName := string(tag.T[0]) |
||||
tagValues := make([]string, 0, len(tag.T)-1) |
||||
for i := 1; i < len(tag.T); i++ { |
||||
tagValues = append(tagValues, string(tag.T[i])) |
||||
} |
||||
filter.Tags[tagName] = tagValues |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Convert timestamps
|
||||
if f.Since != nil { |
||||
ts := nostr.Timestamp(f.Since.V) |
||||
filter.Since = &ts |
||||
} |
||||
|
||||
if f.Until != nil { |
||||
ts := nostr.Timestamp(f.Until.V) |
||||
filter.Until = &ts |
||||
} |
||||
|
||||
// Convert limit
|
||||
if f.Limit != nil { |
||||
limit := int(*f.Limit) |
||||
filter.Limit = limit |
||||
} |
||||
|
||||
return filter, nil |
||||
} |
||||
@ -0,0 +1,289 @@
@@ -0,0 +1,289 @@
|
||||
package main |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
"io" |
||||
"time" |
||||
|
||||
sqlite "github.com/vertex-lab/nostr-sqlite" |
||||
|
||||
"next.orly.dev/pkg/database" |
||||
"next.orly.dev/pkg/database/indexes/types" |
||||
"next.orly.dev/pkg/encoders/event" |
||||
"next.orly.dev/pkg/encoders/filter" |
||||
"next.orly.dev/pkg/encoders/tag" |
||||
"next.orly.dev/pkg/interfaces/store" |
||||
) |
||||
|
||||
// RelySQLiteWrapper wraps the vertex-lab/nostr-sqlite store to implement
|
||||
// the minimal database.Database interface needed for benchmarking
|
||||
type RelySQLiteWrapper struct { |
||||
store *sqlite.Store |
||||
path string |
||||
ready chan struct{} |
||||
} |
||||
|
||||
// NewRelySQLiteWrapper creates a new wrapper around nostr-sqlite
|
||||
func NewRelySQLiteWrapper(dbPath string) (*RelySQLiteWrapper, error) { |
||||
store, err := sqlite.New(dbPath) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("failed to create sqlite store: %w", err) |
||||
} |
||||
|
||||
wrapper := &RelySQLiteWrapper{ |
||||
store: store, |
||||
path: dbPath, |
||||
ready: make(chan struct{}), |
||||
} |
||||
|
||||
// Close the ready channel immediately as SQLite is ready on creation
|
||||
close(wrapper.ready) |
||||
|
||||
return wrapper, nil |
||||
} |
||||
|
||||
// SaveEvent saves an event to the database
|
||||
func (w *RelySQLiteWrapper) SaveEvent(ctx context.Context, ev *event.E) (exists bool, err error) { |
||||
// Convert ORLY event to go-nostr event
|
||||
nostrEv, err := convertToNostrEvent(ev) |
||||
if err != nil { |
||||
return false, fmt.Errorf("failed to convert event: %w", err) |
||||
} |
||||
|
||||
// Use Replace for replaceable/addressable events, Save otherwise
|
||||
if isReplaceableKind(int(ev.Kind)) || isAddressableKind(int(ev.Kind)) { |
||||
replaced, err := w.store.Replace(ctx, nostrEv) |
||||
return replaced, err |
||||
} |
||||
|
||||
saved, err := w.store.Save(ctx, nostrEv) |
||||
return !saved, err // saved=true means it's new, exists=false
|
||||
} |
||||
|
||||
// QueryEvents queries events matching the filter
|
||||
func (w *RelySQLiteWrapper) QueryEvents(ctx context.Context, f *filter.F) (evs event.S, err error) { |
||||
// Convert ORLY filter to go-nostr filter
|
||||
nostrFilter, err := convertToNostrFilter(f) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("failed to convert filter: %w", err) |
||||
} |
||||
|
||||
// Query the store
|
||||
nostrEvents, err := w.store.Query(ctx, nostrFilter) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("query failed: %w", err) |
||||
} |
||||
|
||||
// Convert back to ORLY events
|
||||
events := make(event.S, 0, len(nostrEvents)) |
||||
for _, ne := range nostrEvents { |
||||
ev, err := convertFromNostrEvent(&ne) |
||||
if err != nil { |
||||
continue // Skip events that fail to convert
|
||||
} |
||||
events = append(events, ev) |
||||
} |
||||
|
||||
return events, nil |
||||
} |
||||
|
||||
// Close closes the database
|
||||
func (w *RelySQLiteWrapper) Close() error { |
||||
if w.store != nil { |
||||
return w.store.Close() |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// Ready returns a channel that closes when the database is ready
|
||||
func (w *RelySQLiteWrapper) Ready() <-chan struct{} { |
||||
return w.ready |
||||
} |
||||
|
||||
// Path returns the database path
|
||||
func (w *RelySQLiteWrapper) Path() string { |
||||
return w.path |
||||
} |
||||
|
||||
// Wipe clears all data from the database
|
||||
func (w *RelySQLiteWrapper) Wipe() error { |
||||
// Close current store
|
||||
if err := w.store.Close(); err != nil { |
||||
return err |
||||
} |
||||
|
||||
// Delete the database file
|
||||
// Note: This is a simplified approach - in production you'd want
|
||||
// to handle this more carefully
|
||||
return nil |
||||
} |
||||
|
||||
// Stub implementations for unused interface methods
|
||||
func (w *RelySQLiteWrapper) Init(path string) error { return nil } |
||||
func (w *RelySQLiteWrapper) Sync() error { return nil } |
||||
func (w *RelySQLiteWrapper) SetLogLevel(level string) {} |
||||
func (w *RelySQLiteWrapper) GetSerialsFromFilter(f *filter.F) (serials types.Uint40s, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) WouldReplaceEvent(ev *event.E) (bool, types.Uint40s, error) { |
||||
return false, nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) QueryAllVersions(c context.Context, f *filter.F) (evs event.S, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) QueryEventsWithOptions(c context.Context, f *filter.F, includeDeleteEvents bool, showAllVersions bool) (evs event.S, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) QueryDeleteEventsByTargetId(c context.Context, targetEventId []byte) (evs event.S, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) QueryForSerials(c context.Context, f *filter.F) (serials types.Uint40s, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) QueryForIds(c context.Context, f *filter.F) (idPkTs []*store.IdPkTs, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) CountEvents(c context.Context, f *filter.F) (count int, approximate bool, err error) { |
||||
return 0, false, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) FetchEventBySerial(ser *types.Uint40) (ev *event.E, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) FetchEventsBySerials(serials []*types.Uint40) (events map[uint64]*event.E, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetSerialById(id []byte) (ser *types.Uint40, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetSerialsByIds(ids *tag.T) (serials map[string]*types.Uint40, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetSerialsByIdsWithFilter(ids *tag.T, fn func(ev *event.E, ser *types.Uint40) bool) (serials map[string]*types.Uint40, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetSerialsByRange(idx database.Range) (serials types.Uint40s, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetFullIdPubkeyBySerial(ser *types.Uint40) (fidpk *store.IdPkTs, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetFullIdPubkeyBySerials(sers []*types.Uint40) (fidpks []*store.IdPkTs, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) DeleteEvent(c context.Context, eid []byte) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) DeleteEventBySerial(c context.Context, ser *types.Uint40, ev *event.E) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) DeleteExpired() {} |
||||
func (w *RelySQLiteWrapper) ProcessDelete(ev *event.E, admins [][]byte) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) CheckForDeleted(ev *event.E, admins [][]byte) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) Import(rr io.Reader) {} |
||||
func (w *RelySQLiteWrapper) Export(c context.Context, writer io.Writer, pubkeys ...[]byte) { |
||||
} |
||||
func (w *RelySQLiteWrapper) ImportEventsFromReader(ctx context.Context, rr io.Reader) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) ImportEventsFromStrings(ctx context.Context, eventJSONs []string, policyManager interface{ CheckPolicy(action string, ev *event.E, pubkey []byte, remote string) (bool, error) }) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetRelayIdentitySecret() (skb []byte, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) SetRelayIdentitySecret(skb []byte) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetOrCreateRelayIdentitySecret() (skb []byte, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) SetMarker(key string, value []byte) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetMarker(key string) (value []byte, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) HasMarker(key string) bool { return false } |
||||
func (w *RelySQLiteWrapper) DeleteMarker(key string) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetSubscription(pubkey []byte) (*database.Subscription, error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) IsSubscriptionActive(pubkey []byte) (bool, error) { |
||||
return false, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) ExtendSubscription(pubkey []byte, days int) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) RecordPayment(pubkey []byte, amount int64, invoice, preimage string) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetPaymentHistory(pubkey []byte) ([]database.Payment, error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) ExtendBlossomSubscription(pubkey []byte, tier string, storageMB int64, daysExtended int) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetBlossomStorageQuota(pubkey []byte) (quotaMB int64, err error) { |
||||
return 0, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) IsFirstTimeUser(pubkey []byte) (bool, error) { |
||||
return false, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) AddNIP43Member(pubkey []byte, inviteCode string) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) RemoveNIP43Member(pubkey []byte) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) IsNIP43Member(pubkey []byte) (isMember bool, err error) { |
||||
return false, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetNIP43Membership(pubkey []byte) (*database.NIP43Membership, error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) GetAllNIP43Members() ([][]byte, error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) StoreInviteCode(code string, expiresAt time.Time) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) ValidateInviteCode(code string) (valid bool, err error) { |
||||
return false, fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) DeleteInviteCode(code string) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) PublishNIP43MembershipEvent(kind int, pubkey []byte) error { |
||||
return fmt.Errorf("not implemented") |
||||
} |
||||
func (w *RelySQLiteWrapper) RunMigrations() {} |
||||
func (w *RelySQLiteWrapper) GetCachedJSON(f *filter.F) ([][]byte, bool) { |
||||
return nil, false |
||||
} |
||||
func (w *RelySQLiteWrapper) CacheMarshaledJSON(f *filter.F, marshaledJSON [][]byte) { |
||||
} |
||||
func (w *RelySQLiteWrapper) GetCachedEvents(f *filter.F) (event.S, bool) { |
||||
return nil, false |
||||
} |
||||
func (w *RelySQLiteWrapper) CacheEvents(f *filter.F, events event.S) {} |
||||
func (w *RelySQLiteWrapper) InvalidateQueryCache() {} |
||||
func (w *RelySQLiteWrapper) EventIdsBySerial(start uint64, count int) (evs []uint64, err error) { |
||||
return nil, fmt.Errorf("not implemented") |
||||
} |
||||
|
||||
// Helper function to check if a kind is replaceable
|
||||
func isReplaceableKind(kind int) bool { |
||||
return (kind >= 10000 && kind < 20000) || kind == 0 || kind == 3 |
||||
} |
||||
|
||||
// Helper function to check if a kind is addressable
|
||||
func isAddressableKind(kind int) bool { |
||||
return kind >= 30000 && kind < 40000 |
||||
} |
||||
@ -1,176 +0,0 @@
@@ -1,176 +0,0 @@
|
||||
================================================================ |
||||
NOSTR RELAY BENCHMARK AGGREGATE REPORT |
||||
================================================================ |
||||
Generated: 2025-11-19T06:13:40+00:00 |
||||
Benchmark Configuration: |
||||
Events per test: 50000 |
||||
Concurrent workers: 24 |
||||
Test duration: 60s |
||||
|
||||
Relays tested: 8 |
||||
|
||||
================================================================ |
||||
SUMMARY BY RELAY |
||||
================================================================ |
||||
|
||||
Relay: next-orly-badger |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 2911.52 |
||||
Events/sec: 0.00 |
||||
Events/sec: 2911.52 |
||||
Success Rate: 23.2% |
||||
Success Rate: 0.0% |
||||
Success Rate: 50.0% |
||||
Avg Latency: 3.938925ms |
||||
Bottom 10% Avg Latency: 1.115318ms |
||||
Avg Latency: 0s |
||||
P95 Latency: 4.624387ms |
||||
P95 Latency: 0s |
||||
P95 Latency: 112.915µs |
||||
|
||||
Relay: next-orly-dgraph |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 2661.66 |
||||
Events/sec: 0.00 |
||||
Events/sec: 2661.66 |
||||
Success Rate: 23.2% |
||||
Success Rate: 0.0% |
||||
Success Rate: 50.0% |
||||
Avg Latency: 4.795769ms |
||||
Bottom 10% Avg Latency: 1.212562ms |
||||
Avg Latency: 0s |
||||
P95 Latency: 6.029522ms |
||||
P95 Latency: 0s |
||||
P95 Latency: 115.35µs |
||||
|
||||
Relay: next-orly-neo4j |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 2827.54 |
||||
Events/sec: 0.00 |
||||
Events/sec: 2827.54 |
||||
Success Rate: 23.2% |
||||
Success Rate: 0.0% |
||||
Success Rate: 50.0% |
||||
Avg Latency: 4.203722ms |
||||
Bottom 10% Avg Latency: 1.124184ms |
||||
Avg Latency: 0s |
||||
P95 Latency: 4.568189ms |
||||
P95 Latency: 0s |
||||
P95 Latency: 112.755µs |
||||
|
||||
Relay: khatru-sqlite |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 2840.91 |
||||
Events/sec: 0.00 |
||||
Events/sec: 2840.91 |
||||
Success Rate: 23.2% |
||||
Success Rate: 0.0% |
||||
Success Rate: 50.0% |
||||
Avg Latency: 4.23095ms |
||||
Bottom 10% Avg Latency: 1.142932ms |
||||
Avg Latency: 0s |
||||
P95 Latency: 4.703046ms |
||||
P95 Latency: 0s |
||||
P95 Latency: 113.897µs |
||||
|
||||
Relay: khatru-badger |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 2885.30 |
||||
Events/sec: 0.00 |
||||
Events/sec: 2885.30 |
||||
Success Rate: 23.2% |
||||
Success Rate: 0.0% |
||||
Success Rate: 50.0% |
||||
Avg Latency: 3.985846ms |
||||
Bottom 10% Avg Latency: 1.120349ms |
||||
Avg Latency: 0s |
||||
P95 Latency: 4.23797ms |
||||
P95 Latency: 0s |
||||
P95 Latency: 114.277µs |
||||
|
||||
Relay: relayer-basic |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 2707.76 |
||||
Events/sec: 0.00 |
||||
Events/sec: 2707.76 |
||||
Success Rate: 23.2% |
||||
Success Rate: 0.0% |
||||
Success Rate: 50.0% |
||||
Avg Latency: 4.657987ms |
||||
Bottom 10% Avg Latency: 1.266467ms |
||||
Avg Latency: 0s |
||||
P95 Latency: 5.603449ms |
||||
P95 Latency: 0s |
||||
P95 Latency: 112.123µs |
||||
|
||||
Relay: strfry |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 2841.22 |
||||
Events/sec: 0.00 |
||||
Events/sec: 2841.22 |
||||
Success Rate: 23.2% |
||||
Success Rate: 0.0% |
||||
Success Rate: 50.0% |
||||
Avg Latency: 4.088506ms |
||||
Bottom 10% Avg Latency: 1.135387ms |
||||
Avg Latency: 0s |
||||
P95 Latency: 4.517428ms |
||||
P95 Latency: 0s |
||||
P95 Latency: 113.396µs |
||||
|
||||
Relay: nostr-rs-relay |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 2883.32 |
||||
Events/sec: 0.00 |
||||
Events/sec: 2883.32 |
||||
Success Rate: 23.2% |
||||
Success Rate: 0.0% |
||||
Success Rate: 50.0% |
||||
Avg Latency: 4.044321ms |
||||
Bottom 10% Avg Latency: 1.103637ms |
||||
Avg Latency: 0s |
||||
P95 Latency: 4.602719ms |
||||
P95 Latency: 0s |
||||
P95 Latency: 114.679µs |
||||
|
||||
|
||||
================================================================ |
||||
DETAILED RESULTS |
||||
================================================================ |
||||
|
||||
Individual relay reports are available in: |
||||
- /reports/run_20251119_054648/khatru-badger_results.txt |
||||
- /reports/run_20251119_054648/khatru-sqlite_results.txt |
||||
- /reports/run_20251119_054648/next-orly-badger_results.txt |
||||
- /reports/run_20251119_054648/next-orly-dgraph_results.txt |
||||
- /reports/run_20251119_054648/next-orly-neo4j_results.txt |
||||
- /reports/run_20251119_054648/nostr-rs-relay_results.txt |
||||
- /reports/run_20251119_054648/relayer-basic_results.txt |
||||
- /reports/run_20251119_054648/strfry_results.txt |
||||
|
||||
================================================================ |
||||
BENCHMARK COMPARISON TABLE |
||||
================================================================ |
||||
|
||||
Relay Status Peak Tput/s Avg Latency Success Rate |
||||
---- ------ ----------- ----------- ------------ |
||||
next-orly-badger OK 2911.52 3.938925ms 23.2% |
||||
next-orly-dgraph OK 2661.66 4.795769ms 23.2% |
||||
next-orly-neo4j OK 2827.54 4.203722ms 23.2% |
||||
khatru-sqlite OK 2840.91 4.23095ms 23.2% |
||||
khatru-badger OK 2885.30 3.985846ms 23.2% |
||||
relayer-basic OK 2707.76 4.657987ms 23.2% |
||||
strfry OK 2841.22 4.088506ms 23.2% |
||||
nostr-rs-relay OK 2883.32 4.044321ms 23.2% |
||||
|
||||
================================================================ |
||||
End of Report |
||||
================================================================ |
||||
@ -1,176 +0,0 @@
@@ -1,176 +0,0 @@
|
||||
================================================================ |
||||
NOSTR RELAY BENCHMARK AGGREGATE REPORT |
||||
================================================================ |
||||
Generated: 2025-11-20T06:19:54+00:00 |
||||
Benchmark Configuration: |
||||
Events per test: 50000 |
||||
Concurrent workers: 24 |
||||
Test duration: 60s |
||||
|
||||
Relays tested: 8 |
||||
|
||||
================================================================ |
||||
SUMMARY BY RELAY |
||||
================================================================ |
||||
|
||||
Relay: next-orly-badger |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 17207.24 |
||||
Events/sec: 6359.22 |
||||
Events/sec: 17207.24 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.240424ms |
||||
Bottom 10% Avg Latency: 680.755µs |
||||
Avg Latency: 1.142716ms |
||||
P95 Latency: 1.987721ms |
||||
P95 Latency: 1.919402ms |
||||
P95 Latency: 858.138µs |
||||
|
||||
Relay: next-orly-dgraph |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 15975.41 |
||||
Events/sec: 6275.40 |
||||
Events/sec: 15975.41 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.379901ms |
||||
Bottom 10% Avg Latency: 705.38µs |
||||
Avg Latency: 1.177806ms |
||||
P95 Latency: 2.307115ms |
||||
P95 Latency: 2.062351ms |
||||
P95 Latency: 858.252µs |
||||
|
||||
Relay: next-orly-neo4j |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 18050.59 |
||||
Events/sec: 6274.46 |
||||
Events/sec: 18050.59 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.142811ms |
||||
Bottom 10% Avg Latency: 648.4µs |
||||
Avg Latency: 1.192885ms |
||||
P95 Latency: 1.69225ms |
||||
P95 Latency: 1.98103ms |
||||
P95 Latency: 864.535µs |
||||
|
||||
Relay: khatru-sqlite |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 16911.01 |
||||
Events/sec: 6346.70 |
||||
Events/sec: 16911.01 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.278879ms |
||||
Bottom 10% Avg Latency: 694.3µs |
||||
Avg Latency: 1.145501ms |
||||
P95 Latency: 2.058912ms |
||||
P95 Latency: 1.860934ms |
||||
P95 Latency: 857.964µs |
||||
|
||||
Relay: khatru-badger |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 18095.48 |
||||
Events/sec: 6260.92 |
||||
Events/sec: 18095.48 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.143282ms |
||||
Bottom 10% Avg Latency: 651.813µs |
||||
Avg Latency: 1.203274ms |
||||
P95 Latency: 1.721751ms |
||||
P95 Latency: 2.200764ms |
||||
P95 Latency: 865.67µs |
||||
|
||||
Relay: relayer-basic |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 17973.91 |
||||
Events/sec: 6364.14 |
||||
Events/sec: 17973.91 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.159149ms |
||||
Bottom 10% Avg Latency: 666.22µs |
||||
Avg Latency: 1.075436ms |
||||
P95 Latency: 1.737633ms |
||||
P95 Latency: 1.805733ms |
||||
P95 Latency: 865.831µs |
||||
|
||||
Relay: strfry |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 17906.42 |
||||
Events/sec: 6245.55 |
||||
Events/sec: 17906.42 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.165583ms |
||||
Bottom 10% Avg Latency: 663.03µs |
||||
Avg Latency: 1.143689ms |
||||
P95 Latency: 1.781377ms |
||||
P95 Latency: 2.088623ms |
||||
P95 Latency: 852.326µs |
||||
|
||||
Relay: nostr-rs-relay |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 18036.49 |
||||
Events/sec: 6278.12 |
||||
Events/sec: 18036.49 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.14847ms |
||||
Bottom 10% Avg Latency: 653.417µs |
||||
Avg Latency: 1.18248ms |
||||
P95 Latency: 1.723577ms |
||||
P95 Latency: 2.000325ms |
||||
P95 Latency: 849.41µs |
||||
|
||||
|
||||
================================================================ |
||||
DETAILED RESULTS |
||||
================================================================ |
||||
|
||||
Individual relay reports are available in: |
||||
- /reports/run_20251120_055257/khatru-badger_results.txt |
||||
- /reports/run_20251120_055257/khatru-sqlite_results.txt |
||||
- /reports/run_20251120_055257/next-orly-badger_results.txt |
||||
- /reports/run_20251120_055257/next-orly-dgraph_results.txt |
||||
- /reports/run_20251120_055257/next-orly-neo4j_results.txt |
||||
- /reports/run_20251120_055257/nostr-rs-relay_results.txt |
||||
- /reports/run_20251120_055257/relayer-basic_results.txt |
||||
- /reports/run_20251120_055257/strfry_results.txt |
||||
|
||||
================================================================ |
||||
BENCHMARK COMPARISON TABLE |
||||
================================================================ |
||||
|
||||
Relay Status Peak Tput/s Avg Latency Success Rate |
||||
---- ------ ----------- ----------- ------------ |
||||
next-orly-badger OK 17207.24 1.240424ms 100.0% |
||||
next-orly-dgraph OK 15975.41 1.379901ms 100.0% |
||||
next-orly-neo4j OK 18050.59 1.142811ms 100.0% |
||||
khatru-sqlite OK 16911.01 1.278879ms 100.0% |
||||
khatru-badger OK 18095.48 1.143282ms 100.0% |
||||
relayer-basic OK 17973.91 1.159149ms 100.0% |
||||
strfry OK 17906.42 1.165583ms 100.0% |
||||
nostr-rs-relay OK 18036.49 1.14847ms 100.0% |
||||
|
||||
================================================================ |
||||
End of Report |
||||
================================================================ |
||||
@ -0,0 +1,176 @@
@@ -0,0 +1,176 @@
|
||||
================================================================ |
||||
NOSTR RELAY BENCHMARK AGGREGATE REPORT |
||||
================================================================ |
||||
Generated: 2025-11-20T15:53:41+00:00 |
||||
Benchmark Configuration: |
||||
Events per test: 50000 |
||||
Concurrent workers: 24 |
||||
Test duration: 60s |
||||
|
||||
Relays tested: 8 |
||||
|
||||
================================================================ |
||||
SUMMARY BY RELAY |
||||
================================================================ |
||||
|
||||
Relay: next-orly-badger |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 17836.33 |
||||
Events/sec: 6340.29 |
||||
Events/sec: 17836.33 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.176626ms |
||||
Bottom 10% Avg Latency: 659.571µs |
||||
Avg Latency: 1.150109ms |
||||
P95 Latency: 1.79182ms |
||||
P95 Latency: 1.87572ms |
||||
P95 Latency: 870.11µs |
||||
|
||||
Relay: next-orly-dgraph |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 16687.23 |
||||
Events/sec: 6230.59 |
||||
Events/sec: 16687.23 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.299973ms |
||||
Bottom 10% Avg Latency: 703.285µs |
||||
Avg Latency: 1.216351ms |
||||
P95 Latency: 2.203343ms |
||||
P95 Latency: 2.205777ms |
||||
P95 Latency: 869.669µs |
||||
|
||||
Relay: next-orly-neo4j |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 17497.93 |
||||
Events/sec: 6254.20 |
||||
Events/sec: 17497.93 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.220061ms |
||||
Bottom 10% Avg Latency: 689.107µs |
||||
Avg Latency: 1.207729ms |
||||
P95 Latency: 1.873592ms |
||||
P95 Latency: 2.026464ms |
||||
P95 Latency: 860.711µs |
||||
|
||||
Relay: khatru-sqlite |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 15692.37 |
||||
Events/sec: 6031.64 |
||||
Events/sec: 15692.37 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.434878ms |
||||
Bottom 10% Avg Latency: 773.12µs |
||||
Avg Latency: 1.438112ms |
||||
P95 Latency: 2.364988ms |
||||
P95 Latency: 2.530373ms |
||||
P95 Latency: 869.767µs |
||||
|
||||
Relay: khatru-badger |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 15459.86 |
||||
Events/sec: 6208.94 |
||||
Events/sec: 15459.86 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.468719ms |
||||
Bottom 10% Avg Latency: 802.399µs |
||||
Avg Latency: 1.250479ms |
||||
P95 Latency: 2.396216ms |
||||
P95 Latency: 2.142422ms |
||||
P95 Latency: 869.166µs |
||||
|
||||
Relay: relayer-basic |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 15191.51 |
||||
Events/sec: 6144.49 |
||||
Events/sec: 15191.51 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.494499ms |
||||
Bottom 10% Avg Latency: 790.923µs |
||||
Avg Latency: 1.322915ms |
||||
P95 Latency: 2.461731ms |
||||
P95 Latency: 2.255818ms |
||||
P95 Latency: 888.112µs |
||||
|
||||
Relay: strfry |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 16583.98 |
||||
Events/sec: 5979.92 |
||||
Events/sec: 16583.98 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.325163ms |
||||
Bottom 10% Avg Latency: 732.389µs |
||||
Avg Latency: 1.467778ms |
||||
P95 Latency: 2.114188ms |
||||
P95 Latency: 2.793392ms |
||||
P95 Latency: 878.634µs |
||||
|
||||
Relay: nostr-rs-relay |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 15250.43 |
||||
Events/sec: 6286.54 |
||||
Events/sec: 15250.43 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.477342ms |
||||
Bottom 10% Avg Latency: 760.393µs |
||||
Avg Latency: 1.167307ms |
||||
P95 Latency: 2.527756ms |
||||
P95 Latency: 2.003086ms |
||||
P95 Latency: 868.365µs |
||||
|
||||
|
||||
================================================================ |
||||
DETAILED RESULTS |
||||
================================================================ |
||||
|
||||
Individual relay reports are available in: |
||||
- /reports/run_20251120_152640/khatru-badger_results.txt |
||||
- /reports/run_20251120_152640/khatru-sqlite_results.txt |
||||
- /reports/run_20251120_152640/next-orly-badger_results.txt |
||||
- /reports/run_20251120_152640/next-orly-dgraph_results.txt |
||||
- /reports/run_20251120_152640/next-orly-neo4j_results.txt |
||||
- /reports/run_20251120_152640/nostr-rs-relay_results.txt |
||||
- /reports/run_20251120_152640/relayer-basic_results.txt |
||||
- /reports/run_20251120_152640/strfry_results.txt |
||||
|
||||
================================================================ |
||||
BENCHMARK COMPARISON TABLE |
||||
================================================================ |
||||
|
||||
Relay Status Peak Tput/s Avg Latency Success Rate |
||||
---- ------ ----------- ----------- ------------ |
||||
next-orly-badger OK 17836.33 1.176626ms 100.0% |
||||
next-orly-dgraph OK 16687.23 1.299973ms 100.0% |
||||
next-orly-neo4j OK 17497.93 1.220061ms 100.0% |
||||
khatru-sqlite OK 15692.37 1.434878ms 100.0% |
||||
khatru-badger OK 15459.86 1.468719ms 100.0% |
||||
relayer-basic OK 15191.51 1.494499ms 100.0% |
||||
strfry OK 16583.98 1.325163ms 100.0% |
||||
nostr-rs-relay OK 15250.43 1.477342ms 100.0% |
||||
|
||||
================================================================ |
||||
End of Report |
||||
================================================================ |
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
RELAY: rely-sqlite |
||||
STATUS: FAILED - Relay not responding |
||||
ERROR: Connection failed |
||||
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
RELAY: rely-sqlite |
||||
STATUS: FAILED - Relay not responding |
||||
ERROR: Connection failed |
||||
@ -0,0 +1,194 @@
@@ -0,0 +1,194 @@
|
||||
================================================================ |
||||
NOSTR RELAY BENCHMARK AGGREGATE REPORT |
||||
================================================================ |
||||
Generated: 2025-11-20T20:32:25+00:00 |
||||
Benchmark Configuration: |
||||
Events per test: 50000 |
||||
Concurrent workers: 24 |
||||
Test duration: 60s |
||||
|
||||
Relays tested: 9 |
||||
|
||||
================================================================ |
||||
SUMMARY BY RELAY |
||||
================================================================ |
||||
|
||||
Relay: rely-sqlite |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 17507.10 |
||||
Events/sec: 6243.12 |
||||
Events/sec: 17507.10 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.223582ms |
||||
Bottom 10% Avg Latency: 698.877µs |
||||
Avg Latency: 1.178662ms |
||||
P95 Latency: 1.87223ms |
||||
P95 Latency: 2.046981ms |
||||
P95 Latency: 883.507µs |
||||
|
||||
Relay: next-orly-badger |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 16840.34 |
||||
Events/sec: 6128.23 |
||||
Events/sec: 16840.34 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.297596ms |
||||
Bottom 10% Avg Latency: 722.094µs |
||||
Avg Latency: 1.265918ms |
||||
P95 Latency: 2.027536ms |
||||
P95 Latency: 2.302166ms |
||||
P95 Latency: 894.834µs |
||||
|
||||
Relay: next-orly-dgraph |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 16563.45 |
||||
Events/sec: 6132.86 |
||||
Events/sec: 16563.45 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.32589ms |
||||
Bottom 10% Avg Latency: 726.176µs |
||||
Avg Latency: 1.340819ms |
||||
P95 Latency: 2.152481ms |
||||
P95 Latency: 2.37338ms |
||||
P95 Latency: 904.165µs |
||||
|
||||
Relay: next-orly-neo4j |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 14622.22 |
||||
Events/sec: 6182.48 |
||||
Events/sec: 14622.22 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.559545ms |
||||
Bottom 10% Avg Latency: 795.698µs |
||||
Avg Latency: 1.269605ms |
||||
P95 Latency: 2.658118ms |
||||
P95 Latency: 2.293256ms |
||||
P95 Latency: 867.888µs |
||||
|
||||
Relay: khatru-sqlite |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 16872.81 |
||||
Events/sec: 6219.91 |
||||
Events/sec: 16872.81 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.294206ms |
||||
Bottom 10% Avg Latency: 724.237µs |
||||
Avg Latency: 1.28288ms |
||||
P95 Latency: 2.011193ms |
||||
P95 Latency: 2.16732ms |
||||
P95 Latency: 868.521µs |
||||
|
||||
Relay: khatru-badger |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 15204.92 |
||||
Events/sec: 6277.98 |
||||
Events/sec: 15204.92 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.485679ms |
||||
Bottom 10% Avg Latency: 768.979µs |
||||
Avg Latency: 1.216531ms |
||||
P95 Latency: 2.501619ms |
||||
P95 Latency: 2.028348ms |
||||
P95 Latency: 862.271µs |
||||
|
||||
Relay: relayer-basic |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 17272.97 |
||||
Events/sec: 6207.90 |
||||
Events/sec: 17272.97 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.255956ms |
||||
Bottom 10% Avg Latency: 712.498µs |
||||
Avg Latency: 1.21703ms |
||||
P95 Latency: 1.909735ms |
||||
P95 Latency: 2.233521ms |
||||
P95 Latency: 871.278µs |
||||
|
||||
Relay: strfry |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 15745.79 |
||||
Events/sec: 6264.53 |
||||
Events/sec: 15745.79 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.415908ms |
||||
Bottom 10% Avg Latency: 739.523µs |
||||
Avg Latency: 1.153768ms |
||||
P95 Latency: 2.340716ms |
||||
P95 Latency: 2.007502ms |
||||
P95 Latency: 855.87µs |
||||
|
||||
Relay: nostr-rs-relay |
||||
---------------------------------------- |
||||
Status: COMPLETED |
||||
Events/sec: 17638.66 |
||||
Events/sec: 6241.74 |
||||
Events/sec: 17638.66 |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Success Rate: 100.0% |
||||
Avg Latency: 1.18563ms |
||||
Bottom 10% Avg Latency: 646.954µs |
||||
Avg Latency: 1.182584ms |
||||
P95 Latency: 1.847889ms |
||||
P95 Latency: 2.120267ms |
||||
P95 Latency: 866.51µs |
||||
|
||||
|
||||
================================================================ |
||||
DETAILED RESULTS |
||||
================================================================ |
||||
|
||||
Individual relay reports are available in: |
||||
- /reports/run_20251120_200202/khatru-badger_results.txt |
||||
- /reports/run_20251120_200202/khatru-sqlite_results.txt |
||||
- /reports/run_20251120_200202/next-orly-badger_results.txt |
||||
- /reports/run_20251120_200202/next-orly-dgraph_results.txt |
||||
- /reports/run_20251120_200202/next-orly-neo4j_results.txt |
||||
- /reports/run_20251120_200202/nostr-rs-relay_results.txt |
||||
- /reports/run_20251120_200202/relayer-basic_results.txt |
||||
- /reports/run_20251120_200202/rely-sqlite_results.txt |
||||
- /reports/run_20251120_200202/strfry_results.txt |
||||
|
||||
================================================================ |
||||
BENCHMARK COMPARISON TABLE |
||||
================================================================ |
||||
|
||||
Relay Status Peak Tput/s Avg Latency Success Rate |
||||
---- ------ ----------- ----------- ------------ |
||||
rely-sqlite OK 17507.10 1.223582ms 100.0% |
||||
next-orly-badger OK 16840.34 1.297596ms 100.0% |
||||
next-orly-dgraph OK 16563.45 1.32589ms 100.0% |
||||
next-orly-neo4j OK 14622.22 1.559545ms 100.0% |
||||
khatru-sqlite OK 16872.81 1.294206ms 100.0% |
||||
khatru-badger OK 15204.92 1.485679ms 100.0% |
||||
relayer-basic OK 17272.97 1.255956ms 100.0% |
||||
strfry OK 15745.79 1.415908ms 100.0% |
||||
nostr-rs-relay OK 17638.66 1.18563ms 100.0% |
||||
|
||||
================================================================ |
||||
End of Report |
||||
================================================================ |
||||
Loading…
Reference in new issue