diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 94a26ec..3e446d3 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -143,6 +143,16 @@ services: - redis network_mode: service:tor + strfry: + build: ./strfry + container_name: strfry${SUFFIX} + restart: always + volumes: + - ${STRFRY_URLS}:/app/onion_urls.txt:ro + - ${STRFRY_CONF}:/etc/strfry.conf:ro + - ${STRFRY_DATA}/db:/app/strfry-db:rw + network_mode: service:tor + # Example simple backup service (copy/paste to attached storage locations) # backup: # build: ./backup diff --git a/compose/env-sample/clntn/robosats.env b/compose/env-sample/clntn/robosats.env index 0ad1c66..92a85cc 100644 --- a/compose/env-sample/clntn/robosats.env +++ b/compose/env-sample/clntn/robosats.env @@ -174,4 +174,7 @@ MINIMUM_TARGET_CONF = 24 SLASHED_BOND_REWARD_SPLIT = 0.5 # Username for HTLCs escrows -ESCROW_USERNAME = 'admin' \ No newline at end of file +ESCROW_USERNAME = 'admin' + +#Social +NOSTR_NSEC = 'nsec1vxhs2zc4kqe0dhz4z2gfrdyjsrwf8pg3neeqx6w4nl8djfzdp0dqwd6rxh' diff --git a/compose/env-sample/lndtn/compose.env b/compose/env-sample/lndtn/compose.env index 329279b..802227b 100644 --- a/compose/env-sample/lndtn/compose.env +++ b/compose/env-sample/lndtn/compose.env @@ -28,6 +28,10 @@ POSTGRES_PASSWORD='example' NGINX_CONFD='./nginx/tn.conf.d' WELLKNOWN='./nginx/tn.well-known' +STRFRY_CONF='./env-sample/lndtn/strfry.conf' +STRFRY_URLS='./strfry/tn.onion_urls.txt' +STRFRY_DATA='/custom_path/testnet/strfry' + # Port and number of HTTP server workers for the robosats backend WEB_LOCAL_PORT=8001 GUNICORN_WORKERS=2 diff --git a/compose/env-sample/lndtn/robosats.env b/compose/env-sample/lndtn/robosats.env index aa1474b..130ccfe 100644 --- a/compose/env-sample/lndtn/robosats.env +++ b/compose/env-sample/lndtn/robosats.env @@ -178,3 +178,6 @@ SLASHED_BOND_REWARD_SPLIT = 0.5 # Username for HTLCs escrows ESCROW_USERNAME = 'admin' + +#Social +NOSTR_NSEC = 'nsec1vxhs2zc4kqe0dhz4z2gfrdyjsrwf8pg3neeqx6w4nl8djfzdp0dqwd6rxh' diff --git a/compose/env-sample/lndtn/strfry.conf b/compose/env-sample/lndtn/strfry.conf new file mode 100644 index 0000000..8b8341d --- /dev/null +++ b/compose/env-sample/lndtn/strfry.conf @@ -0,0 +1,138 @@ +## +## Default strfry config +## + +# Directory that contains the strfry LMDB database (restart required) +db = "/app/strfry-db/" + +dbParams { + # Maximum number of threads/processes that can simultaneously have LMDB transactions open (restart required) + maxreaders = 256 + + # Size of mmap() to use when loading LMDB (default is 10TB, does *not* correspond to disk-space used) (restart required) + mapsize = 10995116277760 + + # Disables read-ahead when accessing the LMDB mapping. Reduces IO activity when DB size is larger than RAM. (restart required) + noReadAhead = false +} + +events { + # Maximum size of normalised JSON, in bytes + maxEventSize = 65536 + + # Events newer than this will be rejected + rejectEventsNewerThanSeconds = 900 + + # Events older than this will be rejected + rejectEventsOlderThanSeconds = 94608000 + + # Ephemeral events older than this will be rejected + rejectEphemeralEventsOlderThanSeconds = 60 + + # Ephemeral events will be deleted from the DB when older than this + ephemeralEventsLifetimeSeconds = 300 + + # Maximum number of tags allowed + maxNumTags = 2000 + + # Maximum size for tag values, in bytes + maxTagValSize = 1024 +} + +relay { + # Interface to listen on. Use 0.0.0.0 to listen on all interfaces (restart required) + bind = "0.0.0.0" + + # Port to open for the nostr websocket protocol (restart required) + port = 7777 + + # Set OS-limit on maximum number of open files/sockets (if 0, don't attempt to set) (restart required) + nofiles = 524288 + + # HTTP header that contains the client's real IP, before reverse proxying (ie x-real-ip) (MUST be all lower-case) + realIpHeader = "" + + info { + # NIP-11: Name of this server. Short/descriptive (< 30 characters) + name = "Robosats" + + # NIP-11: Detailed information about relay, free-form + description = "Federation cache system." + + # NIP-11: Administrative nostr pubkey, for contact purposes + pubkey = "" + + # NIP-11: Alternative administrative contact (email, website, etc) + contact = "" + } + + # Maximum accepted incoming websocket frame size (should be larger than max event) (restart required) + maxWebsocketPayloadSize = 131072 + + # Websocket-level PING message frequency (should be less than any reverse proxy idle timeouts) (restart required) + autoPingSeconds = 55 + + # If TCP keep-alive should be enabled (detect dropped connections to upstream reverse proxy) + enableTcpKeepalive = false + + # How much uninterrupted CPU time a REQ query should get during its DB scan + queryTimesliceBudgetMicroseconds = 10000 + + # Maximum records that can be returned per filter + maxFilterLimit = 500 + + # Maximum number of subscriptions (concurrent REQs) a connection can have open at any time + maxSubsPerConnection = 3 + + writePolicy { + # If non-empty, path to an executable script that implements the writePolicy plugin logic + plugin = "" + } + + compression { + # Use permessage-deflate compression if supported by client. Reduces bandwidth, but slight increase in CPU (restart required) + enabled = true + + # Maintain a sliding window buffer for each connection. Improves compression, but uses more memory (restart required) + slidingWindow = false + } + + logging { + # Dump all incoming messages + dumpInAll = false + + # Dump all incoming EVENT messages + dumpInEvents = false + + # Dump all incoming REQ/CLOSE messages + dumpInReqs = false + + # Log performance metrics for initial REQ database scans + dbScanPerf = false + + # Log reason for invalid event rejection? Can be disabled to silence excessive logging + invalidEvents = true + } + + numThreads { + # Ingester threads: route incoming requests, validate events/sigs (restart required) + ingester = 3 + + # reqWorker threads: Handle initial DB scan for events (restart required) + reqWorker = 3 + + # reqMonitor threads: Handle filtering of new events (restart required) + reqMonitor = 3 + + # negentropy threads: Handle negentropy protocol messages (restart required) + negentropy = 2 + } + + negentropy { + # Support negentropy protocol messages + enabled = true + + # Maximum records that sync will process before returning an error + maxSyncEvents = 1000000 + } +} diff --git a/compose/nginx/mn.conf.d/local.conf b/compose/nginx/mn.conf.d/local.conf index c4bd962..6598124 100644 --- a/compose/nginx/mn.conf.d/local.conf +++ b/compose/nginx/mn.conf.d/local.conf @@ -66,6 +66,14 @@ server { limit_req zone=tenpersec burst=10; } + location /nostr { + proxy_pass http://127.0.0.1:7777; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + } + location = /favicon.ico { access_log off; log_not_found off; } } diff --git a/compose/nginx/tn.conf.d/local.conf b/compose/nginx/tn.conf.d/local.conf index e2114db..7c1fcb0 100644 --- a/compose/nginx/tn.conf.d/local.conf +++ b/compose/nginx/tn.conf.d/local.conf @@ -64,6 +64,14 @@ server { proxy_set_header Host $host; } + location /nostr { + proxy_pass http://127.0.0.1:7777; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + } + location = /favicon.ico { access_log off; log_not_found off; } } diff --git a/compose/strfry/Dockerfile b/compose/strfry/Dockerfile new file mode 100644 index 0000000..86a2b08 --- /dev/null +++ b/compose/strfry/Dockerfile @@ -0,0 +1,41 @@ +FROM ubuntu:jammy +ENV TZ=Europe/London + +RUN apt update && apt install -y --no-install-recommends \ + git g++ make pkg-config libtool ca-certificates \ + libssl-dev zlib1g-dev liblmdb-dev libflatbuffers-dev \ + libsecp256k1-dev libzstd-dev + +# setup app +RUN git clone https://github.com/KoalaSat/strfry /app + +WORKDIR /app + +RUN git submodule update --init +RUN make setup-golpe +RUN make clean +RUN make -j4 + +RUN apt update && apt install -y --no-install-recommends \ + liblmdb0 libflatbuffers1 libsecp256k1-0 libb2-1 libzstd1 torsocks cron\ + && rm -rf /var/lib/apt/lists/* + +RUN echo "TorAddress 127.0.0.1" >> /etc/tor/torsocks.conf +RUN echo "TorPort 9050" >> /etc/tor/torsocks.conf + +# Setting up crontab +COPY crontab /etc/cron.d/crontab +RUN chmod 0644 /etc/cron.d/crontab +RUN crontab /etc/cron.d/crontab + +# Setting up entrypoints +COPY sync.sh /etc/strfry/sync.sh +COPY entrypoint.sh /etc/strfry/entrypoint.sh + +RUN chmod +x /etc/strfry/entrypoint.sh +RUN chmod +x /etc/strfry/sync.sh + +#Setting up logs +RUN touch /var/log/cron.log && chmod 0644 /var/log/cron.log + +ENTRYPOINT ["/etc/strfry/entrypoint.sh"] diff --git a/compose/strfry/crontab b/compose/strfry/crontab new file mode 100644 index 0000000..fb04c49 --- /dev/null +++ b/compose/strfry/crontab @@ -0,0 +1,24 @@ +# Edit this file to introduce tasks to be run by cron. +# +# Each task to run has to be defined through a single line +# indicating with different fields when the task will be run +# and what command to run for the task +# +# To define the time you can provide concrete values for +# minute (m), hour (h), day of month (dom), month (mon), +# and day of week (dow) or use '*' in these fields (for 'any'). +# +# Notice that tasks will be started based on the cron's system +# daemon's notion of time and timezones. +# +# Output of the crontab jobs (including errors) is sent through +# email to the user the crontab file belongs to (unless redirected). +# +# For example, you can run a backup of all your user accounts +# at 5 a.m every week with: +# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ +# +# For more information see the manual pages of crontab(5) and cron(8) +# +# m h dom mon dow command +*/1 * * * * torsocks /etc/strfry/sync.sh >> /var/log/cron.log 2>&1 diff --git a/compose/strfry/entrypoint.sh b/compose/strfry/entrypoint.sh new file mode 100644 index 0000000..efb3062 --- /dev/null +++ b/compose/strfry/entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +cron -f -l 8 & tail -f /var/log/cron.log & /app/strfry relay diff --git a/compose/strfry/mn.onion_urls.txt b/compose/strfry/mn.onion_urls.txt new file mode 100644 index 0000000..6f593e0 --- /dev/null +++ b/compose/strfry/mn.onion_urls.txt @@ -0,0 +1,4 @@ +ws://ngdk7ocdzmz5kzsysa3om6du7ycj2evxp2f2olfkyq37htx3gllwp2yd.onion/nostr +ws://satstraoq35jffvkgpfoqld32nzw2siuvowanruindbfojowpwsjdgad.onion/nostr +ws://4t4jxmivv6uqej6xzx2jx3fxh75gtt65v3szjoqmc4ugdlhipzdat6yd.onion/nostr +ws://mmhaqzuirth5rx7gl24d4773lknltjhik57k7ahec5iefktezv4b3uid.onion/nostr \ No newline at end of file diff --git a/compose/strfry/sync.sh b/compose/strfry/sync.sh new file mode 100644 index 0000000..8c47617 --- /dev/null +++ b/compose/strfry/sync.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +filters='{"kinds":[38383]}' + +while IFS= read -r line; do + /app/strfry --config /etc/strfry.conf sync ${line} --filter "$filters" --dir both +done < /app/onion_urls.txt diff --git a/compose/strfry/tn.onion_urls.txt b/compose/strfry/tn.onion_urls.txt new file mode 100644 index 0000000..92abf18 --- /dev/null +++ b/compose/strfry/tn.onion_urls.txt @@ -0,0 +1,4 @@ +ws://testraliar7xkhos2gipv2k65obykofb4jqzl5l4danfryacifi4t7qd.onion/nostr +ws://jpp3w5tpxtyg6lifonisdszpriiapszzem4wod2zsdweyfenlsxeoxid.onion/nostr +ws://ghbtv7lhoyhomyir4xvxaeyqgx4ylxksia343jaat3njqqlkqpdjqcyd.onion/nostr +ws://wsjyhbashc4zrrex6vijpryujggbka5plry2o62dxqoz3pxinblnj4ad.onion/nostr \ No newline at end of file