تشغيل عُقدة OpenFiat
يحافظ مشغّلو العُقد على السوق اللامركزي الذي يجلس فوق سلسلة الكتل. تؤمّن مدقّقات Solana السلسلة وتنفّذ برامج OpenFiat؛ وتحمل العُقد القوائم والسمعة والمراسلة والاكتشاف.
تستخدم الأوامر أدناه النشر المرجعي: خدمة openfiat-node، و/etc/openfiat للإعداد و/var/lib/openfiat للبيانات.
العتاد
الحد الأدنى
4 أنوية CPU · 16 غيغابايت RAM · SSD NVMe سعة 250 غيغابايت · اتصال نطاق عريض مستقر
موصى به للإنتاج
8–16 نواة CPU · 32 غيغابايت RAM أو أكثر · SSD NVMe سعة 1 تيرابايت · شبكة عالية النطاق ومنخفضة الكمون · حماية طاقة UPS · اتصال إنترنت مكرّر
العُقدة ملف Rust ثنائي واحد. libp2p (QUIC، Noise، Yamux) وRocksDB مُجمَّعان داخله — لا شيء يُثبَّت منفصلًا.
أين تشغّلها
تقود AllenHark التطوير الأولي للبروتوكول وتبيع الشيئين اللذين تحتاجهما العُقدة: خادمًا ووصول RPC إلى Solana. يحصل مشغّلو العُقد على خصم 50% على كليهما، كجزء من برنامج OpenFiat.
استضافة الخوادم
تخزين NVMe على وصلات 10 غيغابت/ثانية، في فرانكفورت وأمستردام وشيكاغو. احسب حجمه مقابل العتاد أعلاه — التخزين هو ما تنمو إليه العُقدة الكاملة، فقل ما تشغّله ويمكن تحديده لك.
عرض الأسعارRPC وgRPC لـ Solana
اتصالات مرهونة، بحيث لا تُصفّ المعاملات التي ترسلها عُقدتك خلف معاملات الجميع. يُمنح الوصول بقائمة IP مسموح بها بدلًا من مفتاح API. Yellowstone gRPC متاح لبثّ تحديثات الحسابات والفتحات.
عرض الأسعارالمطالبة بالخصم
لا يوجد كود لإدخاله. اسأل على Discord أو في محادثة allenhark.com، قل إنك تشغّل عُقدة OpenFiat، ويُطبَّق الخصم على طلبك.
اخدم الشبكة، لا نفسك فقط
عُقدة تقرأ فقط هي ضيف. عُقدة يستطيع الجمهور الوصول إليها هي بنية تحتية — المحافظ والمستكشفات وتطبيقات الويب عليها أن تتحدّث إلى *أحد ما*، واليوم يوجد القليل جدًا من هؤلاء. كل مشغّل يضع عُقدته خلف TLS ويضبط --public-rpc-url يوسّع تلك المجموعة، وهو الفرق بين شبكة لها عدة أبواب أمامية مستقلة وأخرى لها نقطة فشل واحدة يعتمد عليها الجميع بصمت. يكلّف شهادة ووكيلًا عكسيًا. وهو مأجور أيضًا: العُقدة القابلة للوصول هي التي يمكن للأنداد تحدّيها ومكافأتها، وستستخدم تطبيقات OpenFiat نفسها عُقدتك إلى جانب كل غيرها.
أمران يجدر معرفتهما قبل ذلك. خدمة الجمهور تعني حركة مرور حقيقية، فاحسب حجم الجهاز لها وراقب نقطة نهاية المقاييس. والعُقدة العامة التزام عام — سيبني الناس على العنوان الذي تنشره، فأنزله عمدًا لا بصمت.
التثبيت
البناء من المصدر — للإنتاج، اليوم
لم يُوسَم أي إصدار بعد، فهذه حاليًا الطريقة الوحيدة للحصول على ملف العُقدة الثنائي. تحتاج toolchain لـ Rust وtoolchain لـ C من أجل RocksDB. ابنِه، وضعه في /usr/local/bin، وشغّله تحت systemd — هذا هو النشر الذي توثّقه هذه الصفحة، والذي تستخدمه لعُقدة يعتمد عليها آخرون.
# Rust toolchain, then build the node binary
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
apt install -y build-essential pkg-config libssl-dev clang cmake
git clone https://github.com/OpenFiat-org/openfiat-core.git
cd openfiat-core
cargo build --release --bin openfiat-node
install -m 0755 target/release/openfiat-node /usr/local/bin/ملف ثنائي جاهز — بمجرد وسم إصدار
دفع وسم v* يشغّل تدفّق الإصدار، الذي يبني openfiat-node على منفّذات أصلية وينشر أرشيفات linux-x86_64 وwindows-x86_64 إلى GitHub Releases. لم يُوسَم شيء بعد، فتلك الصفحة فارغة حاليًا. لاحظ أنها بُنى إصدار عادية، لا ساكنة ولا موقّعة — تحقّق مما تنزّله مقابل التدفّق الذي أنتجه.
إصدارات GitHubuseradd --system --create-home --home-dir /var/lib/openfiat --shell /usr/sbin/nologin openfiat
install -m 755 openfiat-node /usr/local/bin/openfiat-node
mkdir -p /etc/openfiat
chown -R openfiat:openfiat /var/lib/openfiat
systemctl daemon-reload
systemctl enable --now openfiat-node
journalctl -u openfiat-node -fDocker — للاختبار فقط
استخدم الصورة لتجربة عُقدة محليًا أو لرفع عنقود متعدّد العُقد قابل للتخلّص — لا لتشغيل عُقدة تعتمد عليها الشبكة. توجد للاختبار المحلي القابل للتكرار؛ الإنتاج يشغّل الملف الثنائي تحت systemd.
# /opt/openfiat/compose.yaml
# TESTING ONLY. Use this to try a node locally or to bring up a throwaway
# cluster — run a production node from the binary under systemd instead
# (see the unit file further down this page).
services:
node:
image: ghcr.io/openfiat-org/openfiat-node:latest
restart: unless-stopped
# QUIC needs UDP; the same TCP port serves JSON-RPC, WebSocket, REST,
# health, and metrics together — there is no separate metrics port.
ports:
- "4001:4001/udp"
- "7080:7080/tcp"
volumes:
- /var/lib/openfiat:/data
- /etc/openfiat/wallet.json:/data/wallet.json:ro
command:
- --ledger=/data
- --identity=/data/wallet.json
- --rpc-bind-address=0.0.0.0:7080
- --gossip-bind-address=/ip4/0.0.0.0/udp/4001/quic-v1
# Static multiaddr — DNS bootstrap does not resolve (see this
# file's own top comment). Repeat the flag for several.
- --entrypoint=/ip4/84.32.223.111/udp/4001/quic-v1/p2p/12D3KooWK9hQ7TwbfvFiaAxUbRFCkdhS7iEpAJDnewNL1anyREQ1
# Omit to stay GossipOnly, the safe default. Any value opts into
# real Solana devnet connectivity (OFS-4300 §4).
- --solana-rpc-url=https://api.devnet.solana.com
stop_grace_period: 60s
ulimits:
nofile: 65536install -d -m 0750 /var/lib/openfiat
docker compose -f /opt/openfiat/compose.yaml up -d
docker compose -f /opt/openfiat/compose.yaml logs -f nodeالمنافذ
- 4001/UDPحركة بين الأنداد. QUIC هو النقل الأساسي، فيجب أن يكون منفذ UDP هذا قابلًا للوصول — الذي ينساه الناس أكثر.يجب أن يكون قابلًا للوصول
- 7080/TCPJSON-RPC وWebSocket وREST والصحة والمقاييس — منفذ حقيقي واحد يخدمها كلها، لا منفذ منفصل لكل سطح.يجب أن يكون قابلًا للوصول
- 7080/TCPالمنفذ نفسه الخاص بالـ API أعلاه (GET /metrics). قيّده بجدار حماية إلى loopback/شبكة خاصة إن لم ترد أن يكون عامًا.أبقِه خاصًا
إطلاق عُقدة
اعمل عليها بالترتيب. كل خطوة أدناه تحمل الأمر الذي تحتاجه.
- 01
جهّز الجهاز
خادم Debian أو Ubuntu حديث، وجدار حماية، وساعة دقيقة. الساعة أهم مما تبدو: تحمل السجلات طوابع زمنية وأوقات انتهاء، وساعة منحرفة تجعل العُقدة ترفض بيانات صالحة.
shell# Debian 12 / Ubuntu 24.04, as root apt update && apt install -y ca-certificates curl gnupg ufw chrony # Clock drift breaks signature and expiry checks — keep NTP running. systemctl enable --now chrony - 02
ثبّت العُقدة
ابنِ من المصدر وشغّل الناتج تحت systemd — لم يُوسَم أي إصدار بعد، فتلك الطريقة الوحيدة للحصول على ملف ثنائي اليوم، وبقية هذا الدليل يفترضها. لا تلجأ إلى Docker إلا عند الاختبار محليًا أو رفع عنقود قابل للتخلّص.
- 03
ولّد محفظة العُقدة
لا يوجد تنسيق "هوية عُقدة" منفصل — هوية العُقدة هي wallet.json حقيقي من CLI الخاص بـ Solana، الملف نفسه الذي ينتجه solana-keygen. تُعاد بذرته لكلٍّ من هوية gossip/النِدّ للعُقدة ومفتاح توقيع Solana. احتفظ بالملف — إن فقدته تعود العُقدة كغريب وتبدأ بناء السمعة من الصفر.
shell# The node's identity IS a Solana CLI-format wallet.json — the same # file "solana-keygen new" produces (its own seed is reused for the # node's gossip/P2P keypair too, see crates/cli's load_or_generate_wallet). # There is no separate "node identity" format or command. solana-keygen new --outfile /etc/openfiat/wallet.json chmod 600 /etc/openfiat/wallet.json solana-keygen pubkey /etc/openfiat/wallet.json - 04
اضبط البيئة
openfiat-node ليس له ملف إعداد خاص — كل ضبط متغيّر بيئة، يُقرأ مرة عند البدء: أين تعيش البيانات، وأي عنوان للإصغاء، وأي أنداد لطلبهم عند البدء، و(اختياريًا) أي نقطة نهاية RPC لـ Solana يُستخدَم. يجب أن تكون أنداد الإطلاق multiaddr/IP ثابتًا، لا اسم مضيف — إطلاق DNS لا يُحلّ.
shell# There is no config file and no environment variables. Every # setting is a flag on the systemd unit's ExecStart below, so # "systemctl cat openfiat-node" shows exactly what a running node was # given, and "openfiat-node --help" is the whole surface. # # Try it in the foreground first — the node prints the addresses it is # reachable at and whether it reached Solana: openfiat-node \ --ledger /var/lib/openfiat \ --identity /etc/openfiat/wallet.json \ --rpc-bind-address 0.0.0.0:7080 \ --gossip-bind-address /ip4/0.0.0.0/udp/4001/quic-v1 \ --entrypoint /ip4/84.32.223.111/udp/4001/quic-v1/p2p/12D3KooWK9hQ7TwbfvFiaAxUbRFCkdhS7iEpAJDnewNL1anyREQ1 \ --solana-rpc-url https://api.devnet.solana.com # Omit --solana-rpc-url to stay GossipOnly, the safe default: the node # still serves the marketplace, but its on-chain answers come # second-hand from peers. Never put a real endpoint or API key anywhere # version controlled — it belongs in the unit file on the server. # # Add --ipfs-api-url http://127.0.0.1:5001 to pin protocol content and # earn the full reward share, and --retention archival to keep the whole # history instead of a rolling 30 days. - 05
افتح المنافذ الصحيحة
يصل الأنداد إلى العُقدة عبر UDP لأن QUIC هو النقل الأساسي — ذلك المنفذ الذي ينساه الناس أكثر. منفذ TCP واحد يخدم JSON-RPC وWebSocket وREST والصحة والمقاييس معًا؛ أبقِه خاصًا إن لم ترد خدمة العملاء علنًا.
shellufw default deny incoming ufw allow 22/tcp # keep your own access ufw allow 4001/udp # libp2p, QUIC — the port people most often forget ufw allow 443/tcp # once nginx terminates TLS in front (see below) ufw allow 7080/tcp # only if the node is exposed directly, without a proxy ufw enable && ufw status verbose - 06
اخدم الشبكة: اجعل عُقدتك قابلة للوصول
هذه الخطوة التي تحوّل العُقدة من شيء يراقب الشبكة إلى شيء يحملها. ضع nginx في المقدمة واحصل على شهادة، ثم أخبر العُقدة بعنوانها العام عبر --public-rpc-url فتُعلن عن نفسها لتستطيع المحافظ والمستكشفات وتطبيق OpenFiat الخاص استخدامها. الترتيب مهم: nginx على HTTP عادي أولًا، ثم certbot يضيف TLS — إعداد يسمّي شهادة أصلًا لا يستطيع البدء، فيفشل certbot قبل أن يصدر التي كانت ستُصلحه. الشهادة ليست زينة اختيارية: صفحة تُخدَم عبر HTTPS لا تستطيع فتح اتصال HTTP عادي، فعُقدة بلا واحدة غير مرئية لكل متصفّح مهما كانت سليمة.
/etc/nginx/sites-available/openfiat-node# /etc/nginx/sites-available/openfiat-node # # HTTP only at this stage, with NO TLS directives. certbot --nginx works # by running "nginx -t" and editing this file, so a config that already # points at a certificate cannot load, nginx will not start, and certbot # fails before it can issue the certificate that would have fixed it. server { listen 80; listen [::]:80; server_name openfiat.example.com; location / { proxy_pass http://127.0.0.1:7080; proxy_http_version 1.1; # The node serves its WebSocket event stream on the same port; # without these the stream downgrades to a plain request and # subscriptions silently never deliver. proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Do NOT add CORS headers here — the node already sets them, and # two Access-Control-Allow-Origin headers on one response make # browsers reject it while curl sees a clean 200. proxy_read_timeout 300s; } }shell# The A record must already resolve for the world — certbot proves # control of the name over port 80. Check a public resolver, not your # own machine, whose cache can be stale: dig +short @8.8.8.8 openfiat.example.com ln -s /etc/nginx/sites-available/openfiat-node /etc/nginx/sites-enabled/ nginx -t && systemctl reload nginx curl -s http://openfiat.example.com/health # ok, before any certificate apt install -y certbot python3-certbot-nginx certbot --nginx -d openfiat.example.com # certbot edits the server block in place: it adds listen 443 ssl, the # certificate paths, and a redirect from :80. The location block and its # proxy headers carry over. Renewal installs itself as a systemd timer. # Do not hand-write a 443 block afterwards — certbot manages that one. # Then tell the network this node can be reached directly: # openfiat-node --public-rpc-url https://openfiat.example.com - 07
شغّلها كخدمة
تحت systemd تُعاد العُقدة بعد تعطّل أو إعادة تشغيل، وتحصل على فترة سماح إيقاف طويلة كفاية لتفرّغ قاعدة البيانات نظيفة بدلًا من قتلها في منتصف الكتابة.
openfiat-node.service# /etc/systemd/system/openfiat-node.service [Unit] Description=OpenFiat node Documentation=https://docs.openfiat.network After=network-online.target Wants=network-online.target [Service] Type=simple User=openfiat Group=openfiat ExecStart=/usr/local/bin/openfiat-node \ --ledger /var/lib/openfiat \ --identity /etc/openfiat/wallet.json \ --rpc-bind-address 0.0.0.0:7080 \ --gossip-bind-address /ip4/0.0.0.0/udp/4001/quic-v1 \ --entrypoint /ip4/84.32.223.111/udp/4001/quic-v1/p2p/12D3KooWK9hQ7TwbfvFiaAxUbRFCkdhS7iEpAJDnewNL1anyREQ1 \ --solana-rpc-url https://api.devnet.solana.com WorkingDirectory=/var/lib/openfiat Restart=on-failure RestartSec=5s # openfiat-node handles SIGTERM itself (graceful shutdown) rather than # needing systemd to force-kill it; this gives that shutdown path a # reasonable window before systemd escalates to SIGKILL. TimeoutStopSec=30s NoNewPrivileges=true ProtectSystem=strict ProtectHome=true ReadWritePaths=/var/lib/openfiat PrivateTmp=true # AF_NETLINK is required, not optional: binding a wildcard address makes # libp2p enumerate this host's interfaces, and that goes over a netlink # socket. Without it the QUIC listener fails and the gossip actor panics # while the HTTP thread survives — so systemd reports the unit active # and the node looks healthy while serving nothing. RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK [Install] WantedBy=multi-user.targetshelluseradd --system --create-home --home-dir /var/lib/openfiat --shell /usr/sbin/nologin openfiat install -m 755 openfiat-node /usr/local/bin/openfiat-node mkdir -p /etc/openfiat chown -R openfiat:openfiat /var/lib/openfiat systemctl daemon-reload systemctl enable --now openfiat-node journalctl -u openfiat-node -f - 08
دعها تلحق
بدلًا من إعادة تشغيل كل التاريخ، تستطيع عُقدة جديدة اكتشاف واستيراد لقطة معلَنة من نِدّ لحالة السوق الحالية (OFS-1300) — طرق JSON-RPC حقيقية، لا أداة منفصلة: getLatestSnapshot، getCheckpointHeight. التوقيع وإصدار البروتوكول وجذر الحالة كلها عليها أن تتطابق قبل الوثوق بها.
shell# Snapshot sync (OFS-1300) is real JSON-RPC, not a separate CLI — # a new node discovers and imports a peer-announced snapshot instead of # replaying all history: curl -s -X POST http://localhost:7080/rpc -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"getLatestSnapshot","params":{}}' curl -s -X POST http://localhost:7080/rpc -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"getCheckpointHeight","params":{}}' - 09
تحقّق من أنها سليمة
GET /health يؤكّد أن العملية قائمة؛ وgetChainStatus عبر JSON-RPC يخبرك إن كانت GossipOnly أم RpcConnected، وblockhash الحالي إن كانت الأخيرة.
shell# Is it up, and which mode is it in? curl -s http://localhost:7080/health # ok curl -s -X POST http://localhost:7080/rpc -H 'content-type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"getChainStatus","params":{}}' # {"jsonrpc":"2.0","id":1,"result":{"mode":"GossipOnly","blockhash":null,"slot":null,"age_ms":null}} # ("RpcConnected" with a real blockhash once --solana-rpc-url is set) # The addresses your node is reachable at are in its own log — give one # of these to another operator as their --entrypoint: journalctl -u openfiat-node | grep "reachable at a new address" - 10
هي أصلًا جزء من الشبكة
لا خطوة "إعلان" منفصلة — بمجرد أن يكون للعُقدة أنداد إطلاق، تنشر عبر gossip ويُنشَر عنها تلقائيًا؛ لا أحد يوافق عليها. الرهن ونشر بيانات سجل الخدمات والانضمام إلى النزاعات وإلقاء أصوات الحوكمة كلها إجراءات منفصلة يقودها المحفظة يؤدّيها عميل مقابل العُقدة العاملة — راجع دليل المشاركة المناسب لكلٍّ منها.
ترهن العُقدة OPEN لتصبح مشاركًا نشطًا. لكن الرهن لا يشتري سمعة: مشغّل ذو أداء ضعيف لا يستطيع التعويض برهن أكثر. تجمع الأولوية الفعّالة بين السمعة والرهن وأداء الشبكة المُقاس.
- 11
راقبها
الإشارات التي تتنبّأ فعلًا بالمشكلات هي الأنداد المتصلون، ووضع السلسلة (GossipOnly مقابل RpcConnected)، وعمر blockhash. نبّه على هذه فتعرف قبل مستخدميك.
prometheus.yml# /etc/prometheus/prometheus.yml — same port as everything else, # no separate metrics listener to configure on the node's own side. scrape_configs: - job_name: openfiat-node static_configs: - targets: ["127.0.0.1:7080"] - 12
أبقِها محدّثة
أوقف، استبدل الملف الثنائي، ابدأ. تُحدَّث العُقد واحدة تلو الأخرى، فلا تحتاج الشبكة أبدًا إلى انقطاع منسّق، وتُعاد أحداث gossip المفقودة عند البدء.
shellsystemctl stop openfiat-node # SIGTERM, lets RocksDB flush # docker: docker compose pull node && docker compose up -d node install -m 0755 ./openfiat-node /usr/local/bin/ systemctl start openfiat-node # Missed gossip events replay automatically on start. journalctl -u openfiat-node -f - 13
انسخ ما لا يمكن إعادة توليده
يمكن دائمًا إعادة مزامنة حالة السوق من لقطة. المحفظة لا يمكن إعادة توليدها. الأرصدة والضمان تعيش على Solana، لا على قرصك.
shell# Back up what cannot be re-derived. Marketplace state can always be # re-synced from a snapshot; the wallet cannot be regenerated. tar czf openfiat-wallet-$(date +%F).tar.gz /etc/openfiat/wallet.json # Authoritative financial state lives on Solana, not on the node's own # RocksDB volume.
حين يكون هناك خطأ
لا يتصل أي نِدّ
UDP 4001 محجوب، أو --entrypoint يشير إلى عنوان لا يستطيع الأنداد الوصول إليه فعلًا — يجب أن يكون multiaddr/IP ثابتًا، لا اسم مضيف (إطلاق DNS لا يُحلّ). تسجّل عُقدتك العناوين التي هي قابلة للوصول عليها بمجرد أن تصغي.
ss -lunp | grep 4001 && journalctl -u openfiat-node -n 100المزامنة لا تكتمل أبدًا
استيراد اللقطة (OFS-1300) لم ينتهِ، أو لم يُعلن أي نِدّ عن لقطة حديثة كفاية بعد — افحص getLatestSnapshot/getCheckpointHeight.
journalctl -u openfiat-node -n 200 --no-pager | grep -i snapshotاستخدام القرص يستمر في النمو
RocksDB لم يضغط.
du -sh /var/lib/openfiat/*توقيعات أو انتهاءات مرفوضة
انحراف الساعة. تحمل السجلات طوابع زمنية وانتهاءً، فعلى ساعة المضيف أن تكون صحيحة.
chronyc trackingما ينبغي أن تعرضه العُقدة
هذا كل ما تصدّره العُقدة اليوم — عدد الأنداد ووضع السلسلة وتقدّم المزامنة ليست بعد مقاييس Prometheus، بل قيم تستطيع استعلامها عبر JSON-RPC (getChainStatus، getLatestSnapshot، getCheckpointHeight).
البنية التحتية
المعالج · الذاكرة · القرص · معدّل نقل الشبكة
البروتوكول (GET /metrics)
rpc_requests_total · rpc_errors_total
استضافة واجهة المستخدم
يفصل OpenFiat البروتوكول عن واجهاته. لأي شخص أن يستضيف واجهة ويب أو بوابة جوّال أو بوابة مؤسسية أو سوقًا إقليميًا، وكلٌّ منها يصل إلى السوق نفسه.
بغضّ النظر عن الواجهة المستخدمة، يتفاعل كل مشارك مع السوق اللامركزي نفسه.
واجهة الويب الرسمية · واجهات المجتمع · واجهات التجّار · أسواق إقليمية · بوابات مؤسسية
بماذا تتصل الواجهة
لا تتحدّث الواجهات إلى السلسلة مباشرة. تتصل بعُقدة أو أكثر من عُقد OpenFiat القريبة، وتتحوّل إلى عُقدة أخرى إذا أصبحت واحدة غير متاحة.
سطح API الخاص بالعُقدة
- السوقالبحث في الإعلانات · إنشاء الإعلانات · تحديث الإعلانات · إزالة الإعلانات
- التداولحجز الإعلانات · مزامنة جلسات الصفقة · تقديم تأكيدات الدفع
- البنية التحتيةاكتشاف الأنداد · اكتشاف البوابات · معلومات اللقطات · استخبارات المخاطر
- الحوكمةاكتشاف المقترحات · تقديم الأصوات · معلومات الخزينة
تعرض كل عُقدة مطابِقة سطح API نفسه، فواجهة مكتوبة مقابل عُقدة واحدة تعمل مقابلها جميعًا.