fixed initialization and syncing

This commit is contained in:
Silberengel
2025-10-03 17:51:44 +02:00
parent 4c66eda10e
commit c62fdc96d5
5 changed files with 116 additions and 40 deletions

View File

@@ -9,7 +9,7 @@
docker-compose up -d docker-compose up -d
# View logs # View logs
docker-compose logs -f stella-relay docker-compose logs -f orly-relay
# Stop the relay # Stop the relay
docker-compose down docker-compose down
@@ -136,7 +136,7 @@ go run ./cmd/stresstest -relay ws://localhost:7777
```bash ```bash
# Container debugging # Container debugging
docker ps | grep relay docker ps | grep relay
docker logs stella-relay docker logs orly-relay
curl -I http://127.0.0.1:7777 # Should return HTTP 426 curl -I http://127.0.0.1:7777 # Should return HTTP 426
# WebSocket testing # WebSocket testing
@@ -153,7 +153,7 @@ grep ProxyPass /etc/apache2/plesk.conf.d/vhosts/domain.conf
```bash ```bash
# View relay logs # View relay logs
docker-compose logs -f stella-relay docker-compose logs -f orly-relay
# View nginx logs (if using proxy) # View nginx logs (if using proxy)
docker-compose logs -f nginx docker-compose logs -f nginx

View File

@@ -2,12 +2,12 @@
# Owner: npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx # Owner: npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx
services: services:
stella-relay: orly-relay:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
image: silberengel/next-orly:latest image: silberengel/next-orly:latest
container_name: stella-nostr-relay container_name: orly-nostr-relay
restart: unless-stopped restart: unless-stopped
ports: ports:
- "127.0.0.1:7777:7777" - "127.0.0.1:7777:7777"
@@ -22,14 +22,14 @@ services:
- ORLY_LOG_LEVEL=info - ORLY_LOG_LEVEL=info
- ORLY_DB_LOG_LEVEL=error - ORLY_DB_LOG_LEVEL=error
- ORLY_OWNERS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx - ORLY_OWNERS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx
- ORLY_ADMINS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx - ORLY_ADMINS=npub1v30tsz9vw6ylpz63g0a702nj3xa26t3m7p5us8f2y2sd8v6cnsvq465zjx,npub1m4ny6hjqzepn4rxknuq94c2gpqzr29ufkkw7ttcxyak7v43n6vvsajc2jl,npub1l5sga6xg72phsz5422ykujprejwud075ggrr3z2hwyrfgr7eylqstegx9z
# ACL and Spider Configuration # ACL and Spider Configuration
- ORLY_ACL_MODE=follows - ORLY_ACL_MODE=follows
- ORLY_SPIDER_MODE=follows - ORLY_SPIDER_MODE=follows
# Bootstrap relay URLs for initial sync # Bootstrap relay URLs for initial sync
- ORLY_BOOTSTRAP_RELAYS=wss://profiles.nostr1.com,wss://purplepag.es,wss://relay.damus.io,wss://nostr.wine,wss://relay.nostr.band,wss://freelay.sovbit.host - ORLY_BOOTSTRAP_RELAYS=wss://profiles.nostr1.com,wss://purplepag.es,wss://relay.nostr.band,wss://relay.damus.io
# Subscription Settings (optional) # Subscription Settings (optional)
- ORLY_SUBSCRIPTION_ENABLED=false - ORLY_SUBSCRIPTION_ENABLED=false
@@ -77,7 +77,7 @@ services:
- ./nginx/ssl:/etc/nginx/ssl:ro - ./nginx/ssl:/etc/nginx/ssl:ro
- nginx_logs:/var/log/nginx - nginx_logs:/var/log/nginx
depends_on: depends_on:
- stella-relay - orly-relay
profiles: profiles:
- proxy # Only start with: docker-compose --profile proxy up - proxy # Only start with: docker-compose --profile proxy up
@@ -93,4 +93,4 @@ volumes:
networks: networks:
default: default:
name: stella-relay-network name: orly-relay-network

View File

@@ -9,8 +9,8 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$SCRIPT_DIR" PROJECT_DIR="$SCRIPT_DIR"
# Configuration from docker-compose.yml # Configuration from docker-compose.yml
RELAY_SERVICE="stella-relay" RELAY_SERVICE="orly-relay"
CONTAINER_NAME="stella-nostr-relay" CONTAINER_NAME="orly-nostr-relay"
RELAY_URL="ws://127.0.0.1:7777" RELAY_URL="ws://127.0.0.1:7777"
HTTP_URL="http://127.0.0.1:7777" HTTP_URL="http://127.0.0.1:7777"
RELAY_DATA_DIR="/home/madmin/.local/share/orly-relay" RELAY_DATA_DIR="/home/madmin/.local/share/orly-relay"
@@ -21,7 +21,7 @@ cd "$PROJECT_DIR"
case "${1:-}" in case "${1:-}" in
"start") "start")
echo "🚀 Starting Stella's Orly Relay..." echo "🚀 Starting Stella's Orly Relay..."
docker compose up -d stella-relay docker compose up -d orly-relay
echo "✅ Relay started!" echo "✅ Relay started!"
;; ;;
"stop") "stop")
@@ -31,16 +31,16 @@ case "${1:-}" in
;; ;;
"restart") "restart")
echo "🔄 Restarting Stella's Orly Relay..." echo "🔄 Restarting Stella's Orly Relay..."
docker compose restart stella-relay docker compose restart orly-relay
echo "✅ Relay restarted!" echo "✅ Relay restarted!"
;; ;;
"status") "status")
echo "📊 Stella's Orly Relay Status:" echo "📊 Stella's Orly Relay Status:"
docker compose ps stella-relay docker compose ps orly-relay
;; ;;
"logs") "logs")
echo "📜 Stella's Orly Relay Logs:" echo "📜 Stella's Orly Relay Logs:"
docker compose logs -f stella-relay docker compose logs -f orly-relay
;; ;;
"test") "test")
echo "🧪 Testing relay connection..." echo "🧪 Testing relay connection..."
@@ -77,7 +77,7 @@ case "${1:-}" in
echo "🐳 Docker Information:" echo "🐳 Docker Information:"
echo " Compose File: $PROJECT_DIR/docker-compose.yml" echo " Compose File: $PROJECT_DIR/docker-compose.yml"
echo " Container Status:" echo " Container Status:"
docker compose ps stella-relay 2>/dev/null || echo " Not running" docker compose ps orly-relay 2>/dev/null || echo " Not running"
echo "" echo ""
echo "💡 Configuration:" echo "💡 Configuration:"
echo " All settings are defined in docker-compose.yml" echo " All settings are defined in docker-compose.yml"
@@ -85,26 +85,26 @@ case "${1:-}" in
;; ;;
"docker-logs") "docker-logs")
echo "🐳 Docker Container Logs:" echo "🐳 Docker Container Logs:"
docker compose logs -f stella-relay 2>/dev/null || echo "❌ Container not found or not running" docker compose logs -f orly-relay 2>/dev/null || echo "❌ Container not found or not running"
;; ;;
"docker-status") "docker-status")
echo "🐳 Docker Container Status:" echo "🐳 Docker Container Status:"
docker compose ps stella-relay docker compose ps orly-relay
;; ;;
"docker-restart") "docker-restart")
echo "🔄 Restarting Docker Container..." echo "🔄 Restarting Docker Container..."
docker compose restart stella-relay docker compose restart orly-relay
echo "✅ Container restarted!" echo "✅ Container restarted!"
;; ;;
"docker-update") "docker-update")
echo "🔄 Updating and restarting Docker Container..." echo "🔄 Updating and restarting Docker Container..."
docker compose pull stella-relay docker compose pull orly-relay
docker compose up -d stella-relay docker compose up -d orly-relay
echo "✅ Container updated and restarted!" echo "✅ Container updated and restarted!"
;; ;;
"docker-build") "docker-build")
echo "🔨 Building Docker Container..." echo "🔨 Building Docker Container..."
docker compose build stella-relay docker compose build orly-relay
echo "✅ Container built!" echo "✅ Container built!"
;; ;;
"docker-down") "docker-down")

View File

@@ -3,6 +3,8 @@ package acl
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/hex"
"net/http"
"reflect" "reflect"
"strings" "strings"
"sync" "sync"
@@ -22,9 +24,9 @@ import (
"next.orly.dev/pkg/encoders/envelopes/reqenvelope" "next.orly.dev/pkg/encoders/envelopes/reqenvelope"
"next.orly.dev/pkg/encoders/event" "next.orly.dev/pkg/encoders/event"
"next.orly.dev/pkg/encoders/filter" "next.orly.dev/pkg/encoders/filter"
"next.orly.dev/pkg/encoders/hex"
"next.orly.dev/pkg/encoders/kind" "next.orly.dev/pkg/encoders/kind"
"next.orly.dev/pkg/encoders/tag" "next.orly.dev/pkg/encoders/tag"
"next.orly.dev/pkg/encoders/timestamp"
"next.orly.dev/pkg/protocol/publish" "next.orly.dev/pkg/protocol/publish"
"next.orly.dev/pkg/utils" "next.orly.dev/pkg/utils"
"next.orly.dev/pkg/utils/normalize" "next.orly.dev/pkg/utils/normalize"
@@ -108,7 +110,7 @@ func (f *Follows) Configure(cfg ...any) (err error) {
for _, v := range ev.Tags.GetAll([]byte("p")) { for _, v := range ev.Tags.GetAll([]byte("p")) {
// log.I.F("adding follow: %s", v.Value()) // log.I.F("adding follow: %s", v.Value())
var a []byte var a []byte
if b, e := hex.Dec(string(v.Value())); chk.E(e) { if b, e := hex.DecodeString(string(v.Value())); chk.E(e) {
continue continue
} else { } else {
a = b a = b
@@ -253,18 +255,45 @@ func (f *Follows) startSubscriptions(ctx context.Context) {
return return
default: default:
} }
c, _, err := websocket.Dial(ctx, u, nil) // Create a timeout context for the connection
connCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
// Create proper headers for the WebSocket connection
headers := http.Header{}
headers.Set("User-Agent", "ORLY-Relay/0.9.2")
headers.Set("Origin", "https://orly.dev")
// Use proper WebSocket dial options
dialOptions := &websocket.DialOptions{
HTTPHeader: headers,
}
c, _, err := websocket.Dial(connCtx, u, dialOptions)
cancel()
if err != nil { if err != nil {
log.W.F("follows syncer: dial %s failed: %v", u, err) log.W.F("follows syncer: dial %s failed: %v", u, err)
if strings.Contains(
err.Error(), "response status code 101 but got 403", // Handle different types of errors
) { if strings.Contains(err.Error(), "response status code 101 but got 403") {
// 403 means the relay is not accepting connections from // 403 means the relay is not accepting connections from us
// us. Forbidden is the meaning, usually used to // Forbidden is the meaning, usually used to indicate either the IP or user is blocked
// indicate either the IP or user is blocked. so stop // But we should still retry after a longer delay
// trying this one. log.W.F("follows syncer: relay %s returned 403, will retry after longer delay", u)
return timer := time.NewTimer(5 * time.Minute) // Wait 5 minutes before retrying 403 errors
select {
case <-ctx.Done():
return
case <-timer.C:
}
continue
} else if strings.Contains(err.Error(), "timeout") || strings.Contains(err.Error(), "connection refused") {
// Network issues, retry with normal backoff
log.W.F("follows syncer: network issue with %s, retrying in %v", u, backoff)
} else {
// Other errors, retry with normal backoff
log.W.F("follows syncer: connection error with %s, retrying in %v", u, backoff)
} }
timer := time.NewTimer(backoff) timer := time.NewTimer(backoff)
select { select {
case <-ctx.Done(): case <-ctx.Done():
@@ -277,22 +306,37 @@ func (f *Follows) startSubscriptions(ctx context.Context) {
continue continue
} }
backoff = time.Second backoff = time.Second
// send REQ log.I.F("follows syncer: successfully connected to %s", u)
// send REQ for kind 3 (follow lists), kind 10002 (relay lists), and all events from follows
ff := &filter.S{} ff := &filter.S{}
f1 := &filter.F{ f1 := &filter.F{
Authors: tag.NewFromBytesSlice(authors...), Authors: tag.NewFromBytesSlice(authors...),
Kinds: kind.NewS(kind.New(kind.RelayListMetadata.K)), Kinds: kind.NewS(kind.New(kind.FollowList.K)),
Limit: values.ToUintPointer(0), Limit: values.ToUintPointer(100),
} }
*ff = append(*ff, f1) f2 := &filter.F{
Authors: tag.NewFromBytesSlice(authors...),
Kinds: kind.NewS(kind.New(kind.RelayListMetadata.K)),
Limit: values.ToUintPointer(100),
}
// Add filter for all events from follows (last 30 days)
oneMonthAgo := timestamp.FromUnix(time.Now().Add(-30 * 24 * time.Hour).Unix())
f3 := &filter.F{
Authors: tag.NewFromBytesSlice(authors...),
Since: oneMonthAgo,
Limit: values.ToUintPointer(1000),
}
*ff = append(*ff, f1, f2, f3)
req := reqenvelope.NewFrom([]byte("follows-sync"), ff) req := reqenvelope.NewFrom([]byte("follows-sync"), ff)
if err = c.Write( if err = c.Write(
ctx, websocket.MessageText, req.Marshal(nil), ctx, websocket.MessageText, req.Marshal(nil),
); chk.E(err) { ); chk.E(err) {
log.W.F("follows syncer: failed to send REQ to %s: %v", u, err)
_ = c.Close(websocket.StatusInternalError, "write failed") _ = c.Close(websocket.StatusInternalError, "write failed")
continue continue
} }
log.T.F("sent REQ to %s for follows subscription", u) log.I.F("follows syncer: sent REQ to %s for kind 3, 10002, and all events (last 30 days) from followed users", u)
// read loop // read loop
for { for {
select { select {
@@ -320,6 +364,23 @@ func (f *Follows) startSubscriptions(ctx context.Context) {
if ok, err := res.Event.Verify(); chk.T(err) || !ok { if ok, err := res.Event.Verify(); chk.T(err) || !ok {
continue continue
} }
// Process events based on kind
switch res.Event.Kind {
case kind.FollowList.K:
log.I.F("follows syncer: received kind 3 (follow list) event from %s on relay %s",
hex.EncodeToString(res.Event.Pubkey), u)
// Extract followed pubkeys from 'p' tags in kind 3 events
f.extractFollowedPubkeys(res.Event)
case kind.RelayListMetadata.K:
log.I.F("follows syncer: received kind 10002 (relay list) event from %s on relay %s",
hex.EncodeToString(res.Event.Pubkey), u)
default:
// Log all other events from followed users
log.I.F("follows syncer: received kind %d event from %s on relay %s",
res.Event.Kind, hex.EncodeToString(res.Event.Pubkey), u)
}
if _, _, err = f.D.SaveEvent( if _, _, err = f.D.SaveEvent(
ctx, res.Event, ctx, res.Event,
); err != nil { ); err != nil {
@@ -397,6 +458,20 @@ func (f *Follows) GetFollowedPubkeys() [][]byte {
return followedPubkeys return followedPubkeys
} }
// extractFollowedPubkeys extracts followed pubkeys from 'p' tags in kind 3 events
func (f *Follows) extractFollowedPubkeys(event *event.E) {
if event.Kind != kind.FollowList.K {
return
}
// Extract all 'p' tags (followed pubkeys) from the kind 3 event
for _, tag := range event.Tags.GetAll([]byte("p")) {
if len(tag.Value()) == 32 { // Valid pubkey length
f.AddFollow(tag.Value())
}
}
}
// AddFollow appends a pubkey to the in-memory follows list if not already present // AddFollow appends a pubkey to the in-memory follows list if not already present
// and signals the syncer to refresh subscriptions. // and signals the syncer to refresh subscriptions.
func (f *Follows) AddFollow(pub []byte) { func (f *Follows) AddFollow(pub []byte) {
@@ -413,6 +488,7 @@ func (f *Follows) AddFollow(pub []byte) {
b := make([]byte, len(pub)) b := make([]byte, len(pub))
copy(b, pub) copy(b, pub)
f.follows = append(f.follows, b) f.follows = append(f.follows, b)
log.I.F("follows syncer: added new followed pubkey: %s", hex.EncodeToString(pub))
// notify syncer if initialized // notify syncer if initialized
if f.updated != nil { if f.updated != nil {
select { select {

View File

@@ -13,13 +13,13 @@ Group=madmin
WorkingDirectory=/home/madmin/Projects/GitCitadel/next.orly.dev WorkingDirectory=/home/madmin/Projects/GitCitadel/next.orly.dev
# Start the relay using docker compose # Start the relay using docker compose
ExecStart=/usr/bin/docker compose up -d stella-relay ExecStart=/usr/bin/docker compose up -d orly-relay
# Stop the relay # Stop the relay
ExecStop=/usr/bin/docker compose down ExecStop=/usr/bin/docker compose down
# Reload configuration (restart containers) # Reload configuration (restart containers)
ExecReload=/usr/bin/docker compose restart stella-relay ExecReload=/usr/bin/docker compose restart orly-relay
# Security settings # Security settings
NoNewPrivileges=true NoNewPrivileges=true