mirror of
https://github.com/bitvora/wot-relay.git
synced 2025-06-06 18:31:05 +00:00
performance optimization, sexyness upgrade
This commit is contained in:
parent
55bae27490
commit
dd9763e967
208
main.go
208
main.go
@ -28,19 +28,33 @@ type Config struct {
|
|||||||
StaticPath string
|
StaticPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
var archivePool *nostr.SimplePool
|
var pool *nostr.SimplePool
|
||||||
var fetchingPool *nostr.SimplePool
|
|
||||||
|
|
||||||
var relays []string
|
var relays []string
|
||||||
var config Config
|
var config Config
|
||||||
var trustNetwork []string
|
var trustNetwork []string
|
||||||
var mu sync.Mutex
|
var mu sync.Mutex
|
||||||
|
var trustNetworkFilter *blobloom.Filter
|
||||||
|
var trustNetworkFilterMu sync.Mutex
|
||||||
|
var seedRelays []string
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("starting")
|
green := "\033[32m"
|
||||||
|
reset := "\033[0m"
|
||||||
|
|
||||||
|
art := `
|
||||||
|
__ __ ___. _____ ___________ __
|
||||||
|
/ \ / \ ____\_ |__ _____/ ____\ \__ ___/______ __ __ _______/ |_
|
||||||
|
\ \/\/ // __ \| __ \ / _ \ __\ | | \_ __ \ | \/ ___/\ __\
|
||||||
|
\ /\ ___/| \_\ \ ( <_> ) | | | | | \/ | /\___ \ | |
|
||||||
|
\__/\ / \___ >___ / \____/|__| |____| |__| |____//____ > |__|
|
||||||
|
\/ \/ \/ \/
|
||||||
|
`
|
||||||
|
|
||||||
|
fmt.Println(green + art + reset)
|
||||||
|
log.Println("🚀 booting up web of trust relay")
|
||||||
relay := khatru.NewRelay()
|
relay := khatru.NewRelay()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
pool = nostr.NewSimplePool(ctx)
|
||||||
config = LoadConfig()
|
config = LoadConfig()
|
||||||
|
|
||||||
relay.Info.Name = config.RelayName
|
relay.Info.Name = config.RelayName
|
||||||
@ -49,7 +63,7 @@ func main() {
|
|||||||
appendPubkey(config.RelayPubkey)
|
appendPubkey(config.RelayPubkey)
|
||||||
|
|
||||||
db := lmdb.LMDBBackend{
|
db := lmdb.LMDBBackend{
|
||||||
Path: getEnv("DB_PATH"),
|
Path: config.DBPath,
|
||||||
}
|
}
|
||||||
if err := db.Init(); err != nil {
|
if err := db.Init(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -57,6 +71,7 @@ func main() {
|
|||||||
|
|
||||||
relay.StoreEvent = append(relay.StoreEvent, db.SaveEvent)
|
relay.StoreEvent = append(relay.StoreEvent, db.SaveEvent)
|
||||||
relay.QueryEvents = append(relay.QueryEvents, db.QueryEvents)
|
relay.QueryEvents = append(relay.QueryEvents, db.QueryEvents)
|
||||||
|
relay.DeleteEvent = append(relay.DeleteEvent, db.DeleteEvent)
|
||||||
relay.RejectEvent = append(relay.RejectEvent, func(ctx context.Context, event *nostr.Event) (bool, string) {
|
relay.RejectEvent = append(relay.RejectEvent, func(ctx context.Context, event *nostr.Event) (bool, string) {
|
||||||
for _, pk := range trustNetwork {
|
for _, pk := range trustNetwork {
|
||||||
if pk == event.PubKey {
|
if pk == event.PubKey {
|
||||||
@ -67,7 +82,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
relays = []string{
|
seedRelays = []string{
|
||||||
"wss://nos.lol",
|
"wss://nos.lol",
|
||||||
"wss://nostr.mom",
|
"wss://nostr.mom",
|
||||||
"wss://purplepag.es",
|
"wss://purplepag.es",
|
||||||
@ -113,7 +128,7 @@ func main() {
|
|||||||
|
|
||||||
mux.Handle("/favicon.ico", http.StripPrefix("/", http.FileServer(http.Dir(config.StaticPath))))
|
mux.Handle("/favicon.ico", http.StripPrefix("/", http.FileServer(http.Dir(config.StaticPath))))
|
||||||
|
|
||||||
fmt.Println("running on :3334")
|
log.Println("🎉 relay running on port :3334")
|
||||||
err := http.ListenAndServe(":3334", relay)
|
err := http.ListenAndServe(":3334", relay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -144,10 +159,23 @@ func getEnv(key string) string {
|
|||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshTrustNetwork(relay *khatru.Relay, ctx context.Context) []string {
|
func updateTrustNetworkFilter() {
|
||||||
fetchingPool = nostr.NewSimplePool(ctx)
|
trustNetworkFilterMu.Lock()
|
||||||
|
defer trustNetworkFilterMu.Unlock()
|
||||||
|
|
||||||
|
nKeys := uint64(len(trustNetwork))
|
||||||
|
log.Println("🌐 updating trust network filter with", nKeys, "keys")
|
||||||
|
trustNetworkFilter = blobloom.NewOptimized(blobloom.Config{
|
||||||
|
Capacity: nKeys,
|
||||||
|
FPRate: 1e-4,
|
||||||
|
})
|
||||||
|
for _, trustedPubkey := range trustNetwork {
|
||||||
|
trustNetworkFilter.Add(xxhash.Sum64([]byte(trustedPubkey)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func refreshTrustNetwork(relay *khatru.Relay, ctx context.Context) []string {
|
||||||
|
|
||||||
// Function to refresh the trust network
|
|
||||||
runTrustNetworkRefresh := func() {
|
runTrustNetworkRefresh := func() {
|
||||||
timeoutCtx, cancel := context.WithTimeout(ctx, 3*time.Second)
|
timeoutCtx, cancel := context.WithTimeout(ctx, 3*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -157,82 +185,76 @@ func refreshTrustNetwork(relay *khatru.Relay, ctx context.Context) []string {
|
|||||||
Kinds: []int{nostr.KindContactList},
|
Kinds: []int{nostr.KindContactList},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for ev := range fetchingPool.SubManyEose(timeoutCtx, relays, filters) {
|
log.Println("🔍 fetching owner's follows")
|
||||||
|
for ev := range pool.SubManyEose(timeoutCtx, seedRelays, filters) {
|
||||||
for _, contact := range ev.Event.Tags.GetAll([]string{"p"}) {
|
for _, contact := range ev.Event.Tags.GetAll([]string{"p"}) {
|
||||||
appendPubkey(contact[1])
|
appendPubkey(contact[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chunks := make([][]string, 0)
|
follows := make([]string, len(trustNetwork))
|
||||||
for i := 0; i < len(trustNetwork); i += 100 {
|
copy(follows, trustNetwork)
|
||||||
end := i + 100
|
|
||||||
if end > len(trustNetwork) {
|
|
||||||
end = len(trustNetwork)
|
|
||||||
}
|
|
||||||
chunks = append(chunks, trustNetwork[i:end])
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, chunk := range chunks {
|
log.Println("🌐 building web of trust graph")
|
||||||
threeTimeoutCtx, tenCancel := context.WithTimeout(ctx, 10*time.Second)
|
for i := 0; i < len(follows); i += 200 {
|
||||||
defer tenCancel()
|
timeout, cancel := context.WithTimeout(ctx, 3*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
end := i + 200
|
||||||
|
if end > len(follows) {
|
||||||
|
end = len(follows)
|
||||||
|
}
|
||||||
|
|
||||||
filters = []nostr.Filter{{
|
filters = []nostr.Filter{{
|
||||||
Authors: chunk,
|
Authors: follows[i:end],
|
||||||
Kinds: []int{nostr.KindContactList},
|
Kinds: []int{nostr.KindContactList, nostr.KindRelayListMetadata, nostr.KindProfileMetadata},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for ev := range fetchingPool.SubManyEose(threeTimeoutCtx, relays, filters) {
|
for ev := range pool.SubManyEose(timeout, seedRelays, filters) {
|
||||||
for _, contact := range ev.Event.Tags.GetAll([]string{"p"}) {
|
for _, contact := range ev.Event.Tags.GetAll([]string{"p"}) {
|
||||||
if len(contact) > 1 {
|
if len(contact) > 1 {
|
||||||
appendPubkey(contact[1])
|
appendPubkey(contact[1])
|
||||||
} else {
|
|
||||||
fmt.Println("Skipping malformed tag: ", contact)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getTrustNetworkProfileMetadata(relay, ctx)
|
for _, relay := range ev.Event.Tags.GetAll([]string{"r"}) {
|
||||||
|
appendRelay(relay[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
if ev.Event.Kind == nostr.KindProfileMetadata {
|
||||||
|
relay.AddEvent(ctx, ev.Event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
log.Println("🫂 network size:", len(trustNetwork))
|
||||||
|
log.Println("🔗 relays discovered:", len(relays))
|
||||||
}
|
}
|
||||||
|
|
||||||
runTrustNetworkRefresh()
|
runTrustNetworkRefresh()
|
||||||
|
updateTrustNetworkFilter()
|
||||||
|
|
||||||
ticker := time.NewTicker(10 * time.Minute)
|
ticker := time.NewTicker(24 * time.Hour)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
runTrustNetworkRefresh()
|
runTrustNetworkRefresh()
|
||||||
|
updateTrustNetworkFilter()
|
||||||
}
|
}
|
||||||
|
|
||||||
return trustNetwork
|
return trustNetwork
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTrustNetworkProfileMetadata(relay *khatru.Relay, ctx context.Context) {
|
func appendRelay(relay string) {
|
||||||
chunks := make([][]string, 0)
|
mu.Lock()
|
||||||
for i := 0; i < len(trustNetwork); i += 100 {
|
defer mu.Unlock()
|
||||||
end := i + 100
|
|
||||||
if end > len(trustNetwork) {
|
for _, r := range relays {
|
||||||
end = len(trustNetwork)
|
if r == relay {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
chunks = append(chunks, trustNetwork[i:end])
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, chunk := range chunks {
|
|
||||||
if len(chunk) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
timeoutCtx, cancel := context.WithTimeout(ctx, 3*time.Second)
|
|
||||||
filters := []nostr.Filter{{
|
|
||||||
Authors: chunk,
|
|
||||||
Kinds: []int{nostr.KindProfileMetadata},
|
|
||||||
}}
|
|
||||||
|
|
||||||
for ev := range fetchingPool.SubManyEose(timeoutCtx, relays, filters) {
|
|
||||||
relay.AddEvent(ctx, ev.Event)
|
|
||||||
}
|
|
||||||
cancel()
|
|
||||||
}
|
}
|
||||||
|
relays = append(relays, relay)
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendPubkey(pubkey string) {
|
func appendPubkey(pubkey string) {
|
||||||
@ -244,52 +266,48 @@ func appendPubkey(pubkey string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(pubkey) != 64 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
trustNetwork = append(trustNetwork, pubkey)
|
trustNetwork = append(trustNetwork, pubkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func archiveTrustedNotes(relay *khatru.Relay, ctx context.Context) {
|
func archiveTrustedNotes(relay *khatru.Relay, ctx context.Context) {
|
||||||
ticker := time.NewTicker(1 * time.Minute)
|
log.Println("⏳ waiting for trust network to be populated")
|
||||||
archivePool = nostr.NewSimplePool(ctx)
|
time.Sleep(1 * time.Minute)
|
||||||
defer ticker.Stop()
|
timeout, cancel := context.WithTimeout(ctx, 24*time.Hour)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
for range ticker.C {
|
filters := []nostr.Filter{{
|
||||||
timeout, cancel := context.WithTimeout(ctx, 50*time.Second)
|
Kinds: []int{
|
||||||
filters := []nostr.Filter{{
|
nostr.KindArticle,
|
||||||
Kinds: []int{
|
nostr.KindDeletion,
|
||||||
nostr.KindArticle,
|
nostr.KindContactList,
|
||||||
nostr.KindDeletion,
|
nostr.KindEncryptedDirectMessage,
|
||||||
nostr.KindContactList,
|
nostr.KindMuteList,
|
||||||
nostr.KindEncryptedDirectMessage,
|
nostr.KindReaction,
|
||||||
nostr.KindMuteList,
|
nostr.KindRelayListMetadata,
|
||||||
nostr.KindReaction,
|
nostr.KindRepost,
|
||||||
nostr.KindRelayListMetadata,
|
nostr.KindZapRequest,
|
||||||
nostr.KindRepost,
|
nostr.KindZap,
|
||||||
nostr.KindZapRequest,
|
nostr.KindTextNote,
|
||||||
nostr.KindZap,
|
},
|
||||||
nostr.KindTextNote,
|
}}
|
||||||
},
|
|
||||||
}}
|
|
||||||
|
|
||||||
nKeys := uint64(len(trustNetwork))
|
|
||||||
fmt.Println("trust network size:", nKeys)
|
|
||||||
bloomFilter := blobloom.NewOptimized(blobloom.Config{
|
|
||||||
Capacity: nKeys,
|
|
||||||
FPRate: 1e-4,
|
|
||||||
})
|
|
||||||
for _, trustedPubkey := range trustNetwork {
|
|
||||||
bloomFilter.Add(xxhash.Sum64([]byte(trustedPubkey)))
|
|
||||||
}
|
|
||||||
|
|
||||||
for ev := range archivePool.SubMany(timeout, relays, filters) {
|
|
||||||
|
|
||||||
if bloomFilter.Has(xxhash.Sum64([]byte(ev.Event.PubKey))) {
|
|
||||||
if len(ev.Event.Tags) > 2000 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
relay.AddEvent(ctx, ev.Event)
|
|
||||||
|
|
||||||
|
log.Println("📦 archiving trusted notes...")
|
||||||
|
var i int64
|
||||||
|
trustNetworkFilterMu.Lock()
|
||||||
|
for ev := range pool.SubMany(timeout, seedRelays, filters) {
|
||||||
|
if trustNetworkFilter.Has(xxhash.Sum64([]byte(ev.Event.PubKey))) {
|
||||||
|
if len(ev.Event.Tags) > 2000 {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
relay.AddEvent(ctx, ev.Event)
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
cancel()
|
|
||||||
}
|
}
|
||||||
|
trustNetworkFilterMu.Unlock()
|
||||||
|
fmt.Println("📦 archived", i, "trusted notes")
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user