Rand Protocol
दस्तावेज़ीकरण
मार्गदर्शिकाएँ

नोड चलाना

बाइनरी बिल्ड करें, कुंजी बनाएँ, chain 20 जेनेसिस से डेटा डायरेक्टरी आरंभ करें, बूटस्ट्रैप नोड से कनेक्ट करें, RPC बाइंड करें, इतिहास प्रून करें, और चेन का सत्यापन करें - ऑब्ज़र्वर या वैलिडेटर के रूप में।

इस पृष्ठ का उपयोग testnet पर अपना स्वयं का rand-node चलाने के लिए करें। वॉलेट को निजी रूप से उपयोग करने का अनुशंसित तरीका भी यही है: आपके द्वारा चलाया गया नोड यह जानकारी आपके अतिरिक्त किसी और से प्राप्त नहीं करता कि आप कौन-सा लीफ़ खर्च करने वाले हैं। एक ऑब्ज़र्वर सिंक करता है, प्रत्येक प्रूफ़ का पुनः सत्यापन करता है और JSON-RPC सेवा प्रदान करता है। वैलिडेटर भी यही सब करता है और जब उसकी कुंजी किसी epoch के सेट में शामिल हो जाती है, तब वह सहमति (consensus) में भी भाग लेता है।

बिल्ड

आवश्यकताएँ: Rust 1.98.1 (rust-toolchain.toml में पिन किया गया; rustup इसे स्वयं इंस्टॉल कर देता है), तथा RocksDB के लिए एक C++ कंपाइलर और cmake। zkVM crate की path निर्भरताएँ प्रूफ़-सिस्टम रिपॉज़िटरी (randprotocol/zkp-circuits) के एक सहोदर circuits/ चेकआउट की ओर जाती हैं। यह चेकआउट fullnode/ के बगल में और उसी कमिट पर होना चाहिए जिससे रिलीज़ vendor की गई थी। यह कमिट crates/randprotocol-zkvm/guests-compiled/PROVENANCE.md की circuits: पंक्ति में दर्ज है (v0.6.8 के लिए aeacf31, वही जो v0.6.7 के लिए था)। पहले बिल्ड में 10 से 20 मिनट लगते हैं।

git clone https://github.com/randprotocol/fullnode
cargo build --release          # target/release/rand-node, target/release/rand, target/release/rand-prover

v0.6.8 चलाएँ (git checkout v0.6.8, कमिट c9c9bd3c, वही रिलीज़ है जिसे फ़्लीट चलाता है; rand_getVersion किसी नोड का sha बताता है)। इसकी GitHub रिलीज़ में rand-node, rand, rand-prover और SHA256SUMS शामिल हैं, जो फ़्लीट के एक होस्ट पर बिल्ड किए गए हैं और हस्ताक्षरित नहीं हैं। Chain 20 के लिए यही संस्करण आवश्यक है। इसके genesis में ऐसे फ़ील्ड हैं जिन्हें कोई पुराना बिल्ड नहीं पढ़ता (testnet, binding_domain, proof_window_blocks, program_state, ब्रिज के rotation और fees समूह, gas की ऊपरी सीमाएँ और मतदान द्वारा स्टेकिंग प्रवेश)। साथ ही v0.6.8 में सहमति से जुड़े ऐसे परिवर्तन हैं जिन्हें पुराना नोड नहीं चलाता। प्रूफ़ अब भी constraint set 8 के अंतर्गत बनाए जाते हैं, जैसा chains 18 और 19 पर होता था। हर बंडल में अब भी अपने बंडल प्रूफ़ के साथ एक प्राधिकरण प्रूफ़ होता है (विभाजित प्राधिकरण, chain 17 से)। इसलिए genesis वही दो guests पिन करता है: बंडल guest v3 (hc_bundle 60af094a…) और auth guest (hc_auth 1e4e347f…)। genesis में एक gas अनुभाग, hardening_v6 और envelope_bytes भी हैं। v0.6.8 बिल्ड chains 14, 15, 16 और 17 के genesis को run और verify दोनों चरणों पर hash के आधार पर अस्वीकार कर देता है, पर chain 19 का genesis अब भी चला सकता है। हर नोड फ़्लीट का ही बिल्ड चलाता है।

Chain 20: एक पूर्ण-विराम हार्ड फ़ोर्क

Chain 20 2026-10-01 को 06:17 UTC पर लाइव हुई। इसे chain 19 के एक स्नैपशॉट से तैयार किया गया और पूर्ण-विराम, पूर्ण-आरंभ विधि से लागू किया गया: chain 19 का हर नोड ऊँचाई 7,700 पर रुका, और हर नोड v0.6.8 के साथ chain 20 पर शुरू हुआ। यह रोलिंग अपडेट नहीं था, और इसके दो कारण थे। पहला, Chain 20 का genesis नया है, इसलिए chain 19 के साथ उसका कोई ब्लॉक साझा नहीं है। दूसरा, v0.6.8 में audit v6 से निकले सहमति-संबंधी ऐसे परिवर्तन हैं जिन्हें कभी भी एक-एक नोड करके लागू नहीं किया जाना चाहिए: CON-4 वैलिडेटर के लॉक की स्वचालित रिलीज़ हटाता है, और CH-1 एक timeout-certificate pacemaker जोड़ता है। सभी 26 वैलिडेटर अपनी कुंजियों, peer ids और bootstraps सहित आगे ले जाए गए; कोरम अब भी 26 में से 18 है। Chains 19 और 18 सेवानिवृत्त कर दी गई हैं।

इसलिए किसी नोड को chain 19 से chain 20 पर ले जाने के लिए नई बाइनरी, नई genesis फ़ाइल और एक नई डेटा डायरेक्टरी चाहिए, जैसा नीचे बताया गया है। chain 20 पर भेजने के लिए वॉलेट को v0.6.8 चाहिए: इसका genesis हर प्रूफ़ और हर हस्ताक्षरित संदेश को अपने hash से बाँधता है (binding_domain: 1), और पुराना वॉलेट ऐसा नहीं करता।

कुंजियाँ

rand-node keygen --out node.key.json      # prints the address
rand-node address --key node.key.json     # address, public key, libp2p peer id

फ़ाइल का रूप { "seed", "address", "public_key" } है और उसका मोड 0600 है; इनमें केवल seed गोपनीय है। ऑब्ज़र्वर को भी एक कुंजी चाहिए, क्योंकि वही उसकी p2p पहचान है। नोड कुंजी वॉलेट कुंजी नहीं होती: वॉलेट के लिए rand keygen का उपयोग करें।

अपनी कुंजी स्वयं बनाएँ और उसे चेकआउट से बाहर रखें। fullnode रिपॉज़िटरी अब कोई कुंजी ट्रैक नहीं करती (audit v3, OPS-1)। chains 8 से 13 के लिए कमिट की गई deploy/node-*.key.json और deploy/payout/*.key.json फ़ाइलों के seeds सार्वजनिक हो चुके हैं, इसलिए उनका उपयोग नहीं किया जाना चाहिए। Chain 20 की वैलिडेटर कुंजियाँ रिपॉज़िटरी से बाहर बनाई गईं और कभी रिपॉज़िटरी में नहीं रहीं। इसके 26 genesis वैलिडेटर chain 14 के लिए बनाई गई अठारह कुंजियों और chain 15 पर बॉन्ड की गई आठ कुंजियों से बने हैं, जो तब से हर कट में आगे ले जाई गई हैं।

v0.6.8 से rand-node keygen किसी ऐसी --out फ़ाइल को अस्वीकार कर देता है जो पहले से मौजूद हो; v0.6.7 उसे बिना पूछे अधिलेखित कर देता था। यह फ़ाइल seed की एकमात्र प्रति है। कोई बॉन्ड इस पर निर्भर हो, उससे पहले इसका बैकअप ले लें।

genesis से आरंभ करना

किसी chain के हर नोड को बाइट-दर-बाइट एक जैसी genesis फ़ाइल चाहिए। rand-node init इसे डेटा डायरेक्टरी में कॉपी करता है और इसका hash प्रिंट करता है। chain 20 के लिए यह hash 6210cf071a390d7ac61d8cbea5dd9d139d1a493a862b54a45a498f36af2d5135 होना चाहिए। फ़ाइल deploy/genesis-chain20.json है (sha256 0020247a…3a21)। इसे टैग के बाद लॉन्च रिकॉर्ड के साथ fullnode के main में कमिट किया गया था (कमिट 74cfaca0), इसलिए v0.6.8 के चेकआउट में यह नहीं होती: इसे main से प्राप्त करें।

git -C fullnode show origin/main:deploy/genesis-chain20.json > genesis-chain20.json
rand-node init --datadir ./data-6210cf07 --genesis genesis-chain20.json

इससे <datadir>/db (RocksDB) बनता है, जिसमें ये होते हैं: ब्लॉक 0; tree के पहले लीफ़ के रूप में नौ genesis नोट; और वैलिडेटर रजिस्टर। इन नौ नोटों में सात RAND नोट हैं, जिनमें chain 19 के ऑपरेटर वॉलेटों के 5,184.243719258 RAND हैं। बाकी दो 10 और 89 zUSD के zUSD नोट हैं, यानी ब्रिज की अभिरक्षा में लॉक 99 zUSD। उसी genesis के साथ दोबारा चलाने पर कुछ नहीं होता; भिन्न genesis अस्वीकार कर दिया जाता है (already initialized with a different genesis का अर्थ है कि datadir किसी दूसरी chain की है)। फ़्लीट की तरह डेटा डायरेक्टरी का नाम genesis hash के पहले आठ अक्षरों पर रखें (data-<name>-6210cf07), ताकि यह chain 19 की डायरेक्टरी (-a3defc93) से कभी न टकराए।

genesis फ़ाइल की संरचना:

{
  "chain_id": 20,
  "timestamp_ms": 1790835251661,
  "validators": [ { "public_key": "<hex>", "stake": 1000000000000, "payout": "rand1…" } ],
  "alloc": [ { "cm": "<64 hex>", "envelope": { "kem_ct": "…", "to_receiver": "…", "to_sender": "…", "body": "…" }, "amount": 1000000000000,
               "opening": { "pk": "<64 hex>", "time": 0, "r": "<64 hex>" } },
             { "cm": "…", "envelope": { … }, "amount": 1000000000,
               "opening": { "pk": "<64 hex>", "time": 0, "r": "<64 hex>", "asset": 1 } } ],
  "faucet": true,
  "confidential": true,
  "fri_profile": "production",
  "hc_bundle": "60af094acfe65d85fdb18fb3d06cf9085dcf28c96e59e87f1ee527226e6e3fce",
  "bridge": { "emitter": "<64 hex>", "guardians": [ "<40 hex>" ], "emitters": { "2": "<64 hex>", "3": "…", "4": "…", "5": "…" },
              "pq_guardians": [ "<hex>" ], "pause_key": "<hex>",
              "rules_v2": { "global_mint_cap_per_window": 400000000000, "cap_window_secs": 86400 },
              "guardian_set_index": 1, "burn_sequence": 13,
              "min_inbound_sequence": { "2": 3, "3": 3, "4": 3, "5": 7 },
              "rotation": { "delay_secs": 86400, "needs_possession": true },
              "fees": { "mint_bps": 10, "burn_bps": 10, "recipient": "rand1…" } },
  "tokens": { "registration_fee": 1000000000, "mint_cap_per_day": 10000000000000,
              "tokens": [ { "name": "Shielded USD", "symbol": "zUSD", "salt": "<64 hex>",
                            "backings": [ { "chain": 2, "token": "<64 hex>", "decimals": 6 }, … ] } ],
              "max_tokens": 4096, "burn_registration_fee": true, "bound_note_value": true },
  "consensus_domain": 1,
  "staking": { "faucet_budget_per_epoch": "10000000000000", "bond_activation_epochs": 2,
               "max_weight_bps": 3333, "registration_v2": true,
               "faucet_recipients": [ "rand1…" ], "faucet_minters": [ "<validator address>" ],
               "max_stake_entry_bps_per_epoch": 2500, "admission_by_vote": true },
  "epoch_blocks": 1000,
  "max_program_words": 65535,
  "max_proof_bytes": 4194304,
  "max_block_bytes": 20971520,
  "max_call_envelope_bytes": 65536,
  "max_program_public_words": 32768,
  "envelope_bytes": 1860,
  "hardening_v6": true,
  "hc_auth": "1e4e347f44cf86750b30a9a4bdf9ec9256efe353d4ff8017451eca7d195639c1",
  "gas": { "gas_price": "100", "byte_price": "800", "bundle_gas_limit": 20479, "metering": "circuit",
           "dynamic": { "target_block_bytes": 10485760, "target_block_gas": 262144,
                        "adjust_bps": 1250, "min_gas_price": "100", "min_byte_price": "800",
                        "max_gas_price": "10000", "max_byte_price": "80000", "byte_load": "paying" } },
  "testnet": true,
  "binding_domain": 1,
  "proof_window_blocks": 1024,
  "program_state": { "cell_fee": 10000000 }
}

हर फ़ील्ड genesis hash में शामिल है। hc_bundle उस बंडल guest को पिन करता है जिसके विरुद्ध हर बंडल प्रूफ़ जाँचा जाता है, और hc_auth उस auth guest को जिसके विरुद्ध हर प्राधिकरण प्रूफ़ जाँचा जाता है। जिस नोड का बिल्ड कोई भिन्न guest असेंबल करता है, वह शुरू होने से इनकार कर देता है और दोनों digests बताता है। पाँचों max_* फ़ील्ड वैकल्पिक हैं और केवल मौजूद होने पर ही hash में बँधते हैं; chain 20 पाँचों को सेट करती है। max_proof_bytes 4 MiB है, जबकि chains 13 से 16 में यह 8 MiB था। chain 17 से एक लेन-देन में तीन प्रूफ़ हो सकते हैं (बंडल, प्राधिकरण, कॉल), और hc_auth वाले genesis में max_block_bytes कम से कम max_proof_bytes का तीन गुना और उसके ऊपर 1 MiB होना चाहिए। हर alloc नोट अपना opening साथ रखता है (pk, time, r, और टोकन नोट के लिए asset), इसलिए genesis नोट का स्वामी और राशि डिज़ाइन से ही सार्वजनिक होते हैं। Chain 20 में ये हैं:

  • एक bridge अनुभाग। इसमें ये शामिल हैं: index 1 पर आठ guardians वाला guardian set 1; स्रोत chains 2, 3, 4 और 5 के emitters (chain 19 वाले); आठ Dilithium2 pq_guardians; एक pause_key; burn_sequence 13; स्रोत chains 2, 3 और 4 के लिए 3 और स्रोत chain 5 के लिए 7 का min_inbound_sequence; और rules_v2 (प्रति 24 h विंडो 4,000 zUSD की वैश्विक मिंट सीमा)। chain 20 पर नए हैं rotation और fees। rotation के अंतर्गत PQ-guardian या pause-key के रोटेशन के लिए नई कुंजियों के स्वामित्व का प्रमाण चाहिए, और रोटेशन कमिट होने के 86,400 s बाद प्रभावी होता है। fees के अंतर्गत chain हर जमा और हर burn का 10 bps एक zUSD नोट के रूप में treasury पते पर रख लेती है, इसलिए जमा पर सकल राशि में से शुल्क घटाकर क्रेडिट होता है और burn अपनी राशि में से शुल्क घटाकर जारी करता है;
  • एक tokens अनुभाग। इसमें ये शामिल हैं: 1 RAND का पंजीकरण शुल्क, जो proposer को देने के बजाय burn किया जाता है; आठ दशमलव पर प्रति backing 100,000 टोकन का mint_cap_per_day; 4,096 टोकन की रजिस्ट्री सीमा; 2^63 की नोट-मूल्य सीमा; और genesis पर सूचीबद्ध zUSD, उसकी सात backings के साथ। दो genesis zUSD नोटों के सापेक्ष 99 zUSD लॉक हैं (Ethereum USDT 22, BSC USDT 22, Tron USDT 30, Solana USDT 25);
  • consensus_domain: 1: सहमति का हर हस्ताक्षर इसी genesis से बँधा है (सहमति);
  • एक staking अनुभाग। chain 19 की तरह इसमें faucet को 16 वॉलेटों और 18 मिंटिंग वैलिडेटर कुंजियों तक allowlist किया गया है। साथ में प्रति epoch 10,000 RAND का बजट, दो epoch की बॉन्ड विलंब अवधि, 3,333 bps की भार सीमा और v2 पंजीकरण हैं। chain 20 पर नए हैं admission_by_vote (नई वैलिडेटर कुंजी तभी पंजीकृत होती है जब वैलिडेटर सेट मतदान से उसे स्वीकार कर ले) और प्रति epoch सीमा पर सक्रिय भार के 2,500 bps का प्रवेश बजट, जबकि chain 19 में यह 10,000 RAND पर निश्चित था (स्टेकिंग)। कोई slashing नहीं है;
  • एक gas अनुभाग। कॉल अपने प्रूफ़ में घोषित gas सीमा और अपने बाइट्स के लिए भुगतान करती है। मूल्य 100 इकाई प्रति gas और 800 इकाई प्रति KiB से शुरू होते हैं और हर ब्लॉक के बाद उसकी भराव-मात्रा के अनुसार बदलते हैं, जिसका लक्ष्य 10,485,760 बाइट और 262,144 gas है। एक ब्लॉक में बदलाव अधिकतम 1,250 bps होता है, और मूल्य कभी शुरुआती मूल्यों से नीचे नहीं जाते। chain 20 पर नया यह है कि वे कभी 10,000 और 80,000 से ऊपर भी नहीं जाते। बाइट मूल्य के भार में केवल वे बाइट गिने जाते हैं जो बाइट मूल्य चुकाते हैं, यानी कॉल का प्रूफ़ और इनपुट envelope (byte_load: "paying")। हर बंडल प्रूफ़ एक ही सीमा घोषित करता है, 20,479 (शुल्क);
  • envelope_bytes: 1860: हर नोट envelope ठीक 1,860 बाइट का होता है और उसमें एक एन्क्रिप्टेड memo फ़ील्ड होता है;
  • hardening_v6: true, v0.6 का hardening स्विच, जिसे chain 16 से हर chain ने सेट किया है;
  • testnet: true, वह चिह्न जिसके कारण faucet एक bridge अनुभाग के साथ रह सकता है;
  • binding_domain: 1: हर लेन-देन के प्रूफ़ और हर हस्ताक्षरित action संदेश में genesis hash शामिल होता है, इसलिए एक chain के लिए प्रमाणित या हस्ताक्षरित कुछ भी दूसरी chain पर सत्यापित नहीं होता;
  • proof_window_blocks: 1024: बंडल का anchor अंतिम 1,024 block-end roots में से कोई भी हो सकता है, और उसका time ऊँचाई से 1,024 ब्लॉक तक पीछे हो सकता है (chain 19 पर यह 256 था)। इससे धीमे या प्रत्यायोजित prover को लगभग बीस मिनट मिलते हैं;
  • program_state, RPL-2: प्रोग्राम cells, प्रोग्राम vaults और Invoke action। किसी invoke द्वारा बनाई गई हर cell पर 0.1 RAND का cell शुल्क लगता है (सीमाएँ JSON-RPC में दी गई हैं)।

इसमें कोई aggregation अनुभाग नहीं है, और जिस genesis में यह अनुभाग हो, उस पर बिल्ड शुरू होने से इनकार कर देता है।

timestamp_ms चेन की घड़ी का शून्य बिंदु है। जब आप अपना स्वयं का जेनेसिस बनाएँ, तो इसे वास्तविक लॉन्च समय के निकट रखें और उससे आगे कभी न रखें। यदि यह बहुत पहले का हो, तो ब्लॉक समय दीवार-घड़ी के समय से पीछे रहता है, जब तक कि प्रति ब्लॉक 60 s की चरण-सीमा उसे बराबरी पर न ले आए। यदि यह 15 सेकंड से अधिक भविष्य में हो, तो ब्लॉक 1 कमिट ही नहीं होता: प्रत्येक वोट, लीडर का वोट भी, तब तक रोका जाता है जब तक दीवार-घड़ी का समय जेनेसिस टाइमस्टैम्प तक नहीं पहुँच जाता। इसे उस मशीन की घड़ी से जाँचें जो फ़्लीट को लॉन्च करती है, न कि उस मशीन की जिसने फ़ाइल बनाई।

चलाएँ

rand-node run --datadir ./data --key node.key.json \
    --listen /ip4/0.0.0.0/tcp/30303 --rpc 127.0.0.1:8545 --no-mdns \
    --bootstrap /ip4/164.90.239.200/tcp/30303/p2p/12D3KooWEQEbUwZRgqhDPXhW7vNBmcRcnhUDGUADe81VFdv3ALYe \
    --bootstrap /ip4/165.245.173.74/tcp/30303/p2p/12D3KooWJyc5oDHggAr89e9QrRFBy9Tg8TxXh18yzrb1SM6KKLYw \
    --bootstrap /ip4/188.166.235.187/tcp/30303/p2p/12D3KooWSyX84P1DAbWByLHpRBMLRWD53r3Jj4aqVt6tHoF8B2ZQ
तर्कडिफ़ॉल्टअर्थ
--datadirआवश्यकआरंभ की गई डेटा डायरेक्टरी
--keyआवश्यककी फ़ाइल: वैलिडेटर पहचान, p2p पहचान, शुल्क प्राप्तकर्ता
--listen/ip4/0.0.0.0/tcp/30303libp2p लिसन multiaddr, दोहराया जा सकता है
--bootstrapकोई नहींवह पीयर जिसे आरंभ में और संपर्क टूटे रहने पर हर 30 s पर डायल किया जाता है, दोहराया जा सकता है
--rpc127.0.0.1:8545ऑपरेटर का JSON-RPC और WebSocket लिसनर: सभी मेथड, और यह लूपबैक पर भरोसा करता है। इसे लूपबैक पर ही रखें, और किसी सार्वजनिक एंडपॉइंट को कभी इस पर फ़ॉरवर्ड न करें
--public-rpc <ADDR>बंदv0.6.8: रिवर्स प्रॉक्सी या SSH फ़ॉरवर्ड के लिए एक दूसरा, सार्वजनिक लिसनर: एक निश्चित मेथड-समूह, जिसमें व्यूइंग-की मेथड, rand_mint या rand_getPeers नहीं हैं, कोई बैच नहीं, कोई WebSocket नहीं, सभी कॉल करने वालों के लिए एक ही मीटर (JSON-RPC)
--rpc-viewing-token-file <PATH>बंदv0.6.8: --rpc के व्यूइंग-की मेथड पर एक बेयरर टोकन (फ़ाइल की पहली पंक्ति, 32 या अधिक वर्ण) अनिवार्य करें
--reserved-peer <PEER_ID>कोई नहींv0.6.8, दोहराया जा सकता है: वह पीयर जिसे इनबाउंड कनेक्शन सीमा के बावजूद प्रवेश मिलता है; देखें आरक्षित पीयर
--strict-gossipबंदv0.6.8: केवल वैध लेखक हस्ताक्षर, अनुक्रम संख्या और स्रोत वाला गॉसिप स्वीकार करें; यह एक-एक नोड पर क्रमशः लागू होता है
--validatorबंदयह नोड एक वैलिडेटर की रखता है और जब इसकी की वर्तमान समूह में हो, तब सहमति में भाग लेता है
--no-mdnsबंदLAN खोज बंद करें; सर्वरों पर अनुशंसित
--block-interval-ms1000प्रस्तावों के बीच न्यूनतम अंतराल
--view-timeout-ms3000आधार व्यू टाइमआउट, प्रत्येक लगातार टाइमआउट पर दोगुना होकर अधिकतम 8× तक
--verify-chainquickआरंभ पर अखंडता जाँच: off, quick (संरचना और लेजर रीप्ले), full (साथ में प्रत्येक हस्ताक्षर और QC भी)
--keep-raw-proofsबंदब्लॉक एकत्रीकरण के लिए आर्काइव मोड; चेन 20 पर कोई प्रभाव नहीं
--prune-historyबंद (सब कुछ रखें)लेजर रखें और ब्लॉक इतिहास केवल इतना: <n>m, <n>h या <n>d, कम से कम 1h। testnet के वैलिडेटर 24h चलाते हैं, दोनों आर्काइव को छोड़कर; देखें इतिहास प्रूनिंग
--min-free-disk-mb1024डेटा डायरेक्टरी की फ़ाइल-सिस्टम पर इससे कम खाली स्थान होने पर आरंभ करने से इनकार करें; इसके चार गुने से कम होने पर rand_getHealth disk_low उत्तर देता है। 0 इस सुरक्षा को बंद कर देता है
--prover <ADDR>बंदइस पते पर एक प्रत्यायोजित प्रूवर होस्ट करें, जो अपना अलग लिसनर है और कभी RPC नहीं; देखें नीचे
--gas-price, --byte-price100, 800बिना gas खंड वाली चेन पर किसी कॉल के लिए पूल का न्यूनतम मूल्य। चेन 20 का जेनेसिस अपने मूल्य स्वयं निर्धारित करता है, इसलिए वहाँ नोड दोनों फ़्लैग को अनदेखा करता है और एक चेतावनी लॉग करता है

--prover-accept-spend-key अब हटा दिया गया है: यह दिए जाने पर v0.6.8 नोड आरंभ होने से इनकार करता है, इसलिए v0.6.7 से लाई गई किसी भी यूनिट फ़ाइल से इसे निकाल दें।

ऊपर दिए गए तीन बूटस्ट्रैप वैलिडेटर C, D और E हैं, जो चेन 19 से अपरिवर्तित हैं। चेन 20 उन वैलिडेटर कीज़ पर चलती है जो चेन 14 के लिए बनाई गई थीं, इसलिए उनके पीयर id वही हैं जो चेन 14 में थे; p2p पहचान वैलिडेटर की से व्युत्पन्न होती है। अधिकांश वैलिडेटर केवल एक दिन के ब्लॉक रखते हैं, इसलिए जेनेसिस से सिंक करने वाले, या एक दिन से अधिक पीछे चल रहे नोड को एक पूर्ण-इतिहास पीयर की भी आवश्यकता होती है। दोनों आर्काइव में से एक जोड़ें:

    --bootstrap /ip4/168.144.46.203/tcp/30303/p2p/12D3KooWS5usdMPvsbaWSaT2xtKndHvDYurwmueoNvaRRarb2wRf    # obs1
    --bootstrap /ip4/206.81.29.236/tcp/30303/p2p/12D3KooWPocyZGcNB9Vp68VSfgVvNXhSzBBoJa4h9R1yMkp71XHh    # rand-archive-2

ऑब्ज़र्वर चलाने के लिए --validator छोड़ दें। आरंभ का क्रम: स्टोरेज खोलना, इस बिल्ड के गेस्ट को जेनेसिस के hc_bundle और hc_auth से जाँचना, अखंडता जाँच चलाना (क्षतिग्रस्त अंतिम भाग को काटते हुए और वोट-सुरक्षा स्थिति को बनाए रखते हुए), सहेजे गए हेड से सहमति फिर से शुरू करना, नेटवर्किंग और RPC आरंभ करना, फिर आगे चल रहे किसी भी पीयर से सिंक करना। RUST_LOG का डिफ़ॉल्ट info,libp2p=warn,libp2p_mdns=off है; Ctrl-C या SIGTERM, जो systemd का स्टॉप सिग्नल है, नोड को सुव्यवस्थित ढंग से बंद करता है। उसी --datadir से पुनः आरंभ करने पर नोड सहेजे गए हेड से आगे चलता है।

फ़ुलनोड के टोपोलॉजी नियम: NAT के पीछे के नोड सार्वजनिक पते वाले नोड को डायल करते हैं; सार्वजनिक नोड पर इनबाउंड TCP 30303 खोलें; RPC को 127.0.0.1 पर बाइंड करें, जब तक कि वह फ़ायरवॉल के पीछे न हो — यह हर उस व्यक्ति से लेनदेन स्वीकार करता है जो इस तक पहुँच सकता है, और एक बार इसमें व्यूइंग की इम्पोर्ट हो जाने पर उस पोर्ट को की-धारक मानें। --block-interval-ms को 1000 या उससे धीमा रखें: एक बंडल प्रूफ़ में लगभग दो मिनट लगते हैं और उसका एंकर चेन 20 पर 1,024 ब्लॉक तक वैध रहता है (चेन 19 पर 256)।

वैलिडेटर को सिंक्रनाइज़ की हुई घड़ी चाहिए। चेन 14 से दीवार-घड़ी का समय सहमति का भाग है (ब्रिज हार्डनिंग B2)। जिस ब्लॉक का टाइमस्टैम्प उसके पैरेंट से 60 s से अधिक आगे हो, वह अवैध है, और वैलिडेटर उस ब्लॉक पर अपना वोट रोक लेता है जिसका टाइमस्टैम्प उसकी अपनी घड़ी से 15 s से अधिक आगे हो। इसलिए जिस वैलिडेटर की घड़ी धीमी चलती है, वह कोई त्रुटि लॉग किए बिना वोट देना बंद कर देता है, और चेन 20 पर कमिट के लिए छब्बीस में से अठारह का वोट आवश्यक है। प्रत्येक वैलिडेटर पर NTP चलाएँ और नोड आरंभ करने से पहले उसे जाँचें:

timedatectl                     # want "System clock synchronized: yes" and "NTP service: active"
chronyc tracking
apt-get install -y chrony && systemctl enable --now chrony    # if it is not synchronised

आरक्षित पीयर

v0.6.8 से एक नोड अधिकतम 256 स्थापित और 64 अर्ध-खुले इनबाउंड कनेक्शन स्वीकार करता है, और libp2p पहचान बनाने में कोई लागत नहीं लगती, इसलिए अजनबी सभी स्लॉट घेर सकते हैं। तीन प्रकार के पीयर आरक्षित होते हैं, जिन्हें सीमा के बावजूद प्रवेश मिलता है और सिंक बजट के वैलिडेटर-अंश से सेवा दी जाती है: प्रत्येक --bootstrap पीयर, प्रत्येक --reserved-peer, और हस्ताक्षरित पीयर बाइंडिंग से ज्ञात प्रत्येक वैलिडेटर पहचान। प्रत्येक --validator नोड अपनी libp2p पहचान पर अपनी वैलिडेटर की से हस्ताक्षर करता है और उसे गॉसिप करता है; जो नोड उस की को किसी वैलिडेटर समूह से जानता है, वह उस पीयर को आरक्षित करता है और पुनः आरंभ के बाद भी उस रिकॉर्ड को बनाए रखता है। नई बनाई गई चेन के स्टोर में कोई बाइंडिंग नहीं होती, इसलिए पहली घोषणाएँ आने तक केवल पहले दो प्रकार आरक्षित होते हैं: नई चेन बनाते समय फ़्लीट के वैलिडेटर पीयर id --reserved-peer के साथ दें या उन्हें बूटस्ट्रैप सूची में रखें (rand-node address --key <file> किसी की का पीयर id दिखाता है)। rand_status.reserved_peers उनकी गिनती बताता है; फ़्लीट नोड पर यह आरंभ के एक मिनट के भीतर वैलिडेटर संख्या तक पहुँच जानी चाहिए।

जाँचें

rand-node status                # rand_status verbatim
rand --rpc http://127.0.0.1:8545 status
rand peers

rand_status ये सूचित करता है: height, view, syncing, sync_target, peer_count, connected_peers, reserved_peers, mempool_size, is_validator, active_validator, faucet, confidential, testnet, fri_profile, programs, notes, nullifiers, tree_root, hc_bundle, hc_auth, binding_domain, gas_prices, नोड का address और peer_id, सिंक निदान (sync_inflight_age_ms, sync_failures, sync_late_batches), डिस्क (disk_free_bytes, disk_low), और प्रतिधारण सीमा (prune_floor, सब कुछ रखने वाले नोड पर 0; prune_history_secs, सेट न होने पर null)। चेन 20 पर अपेक्षित मान हैं hc_bundle 60af094a…, hc_auth 1e4e347f…, faucet true, confidential true, testnet true, binding_domain 1, fri_profile "production", और gas_prices प्रति गैस 100 से 10,000 के बीच तथा प्रति KiB 800 से 80,000 के बीच। rand_getGenesisHash का उत्तर 6210cf07…5135 और rand_getVersion का उत्तर 0.6.8 होना चाहिए।

जब खाली स्थान --min-free-disk-mb के चार गुने से कम हो, तो rand_getHealth ok, syncing या behind के स्थान पर पहले disk_low (free_bytes के साथ) उत्तर देता है।

इतिहास प्रूनिंग

--prune-history 24h के साथ आरंभ किया गया नोड लेजर (नोट, नलिफ़ायर, एंकर, वैलिडेटर रजिस्टर, प्रोग्राम) को पूरा रखता है और पुराने ब्लॉक, उनके प्रमाणपत्र, लेनदेन और रसीदें हटा देता है। एक पास हर 16वें कमिट किए गए ब्लॉक पर चलता है और हेड के टाइमस्टैम्प में से विंडो घटाने पर प्राप्त समय से पुराने अधिकतम 512 ब्लॉक हटाता है; जेनेसिस, हेड और उसका पैरेंट कभी नहीं हटाए जाते, और सीमा केवल ऊपर बढ़ती है। डिस्क स्थान RocksDB के कॉम्पैक्शन के बाद वापस मिलता है। चेन 20 पर, चेन 19 की तरह, 26 में से 24 वैलिडेटर 24h चलाते हैं और लगभग एक दिन के ब्लॉक रखते हैं। जब चेन 14 के लिए प्रूनिंग चालू की गई (2026-09-25), तो बैकलॉग साफ़ होने पर प्रत्येक वैलिडेटर की ब्लॉक तालिकाएँ 19 GB से घटकर 3.3–4.4 GB रह गईं; शेष दो, obs1 और rand-archive-2, जो 2026-09-27 से वैलिडेटर भी हैं, इस फ़्लैग के बिना चलते हैं और सब कुछ रखते हैं। mainnet नोड यह फ़्लैग कभी नहीं देता।

प्रून किए गए नोड पर, सीमा से नीचे ऊँचाई के आधार पर किया गया लुकअप (rand_getBlockByHeight, ऊँचाई के आधार पर rand_getFinality, उस सीमा तक पहुँचने वाली rand_getBlocks या rand_getCompactBlocks रेंज) data.floor के साथ त्रुटि -32010 उत्तर देता है: किसी आर्काइव से पूछें। हैश के आधार पर किया गया लुकअप उस ब्लॉक के लिए null उत्तर देता है जो अब नोड के पास नहीं है, ठीक वैसे ही जैसे कभी अस्तित्व में न रहे ब्लॉक के लिए। वॉलेट स्कैनिंग अप्रभावित रहती है, क्योंकि नोट और नलिफ़ायर कभी प्रून नहीं किए जाते।

प्रून किए गए नोड की आरंभिक जाँच संरचनात्मक होती है (ब्लॉक 0 और रखे गए ब्लॉक, उनके QC, पैरेंट लिंक और लीडर), जेनेसिस से रीप्ले नहीं, और यह स्वयं की मरम्मत नहीं करती: यदि यह विफल हो, तो किसी आर्काइव से फिर से सिंक करें। किसी प्रून की गई डेटा डायरेक्टरी को v0.5.7 से पुराने बिल्ड से तब तक न खोलें जब तक वह --verify-chain off के साथ न चल रहा हो: उसकी डिफ़ॉल्ट जाँच जेनेसिस से रीप्ले करती है, ब्लॉक 1 को अनुपस्थित पाती है, और लेजर को काटकर जेनेसिस तक छोटा कर देती है।

प्रूवर होस्ट करना

चेन 20 पर एक वॉलेट हर बंडल के लिए दो प्रूफ़ बनाता है, और उनमें से बड़े प्रूफ़ के लिए लगभग 6 GB मेमोरी चाहिए। जो वॉलेट इसे वहन नहीं कर सकता, वह यह प्रूफ़ अपने साथ युग्मित किसी प्रत्यायोजित प्रूवर को सौंप सकता है: अलग rand-prover बाइनरी, या किसी नोड द्वारा होस्ट की गई वही सेवा।

rand-prover --home /root/prover keygen
rand-prover --home /root/prover pair --name laptop --url https://prover.example.net
rand-node run --datadir ./data --key node.key.json --prover 127.0.0.1:8600 --prover-home /root/prover

pair एक randprover: लिंक प्रिंट करता है। वॉलेट इसे rand prover pair <link> से ग्रहण करता है और फिर वैश्विक --prover विकल्प के साथ इसी के माध्यम से प्रूफ़ बनवाता है। prover का listener उसका अपना होता है, वह RPC की कोई method कभी नहीं होता: --rpc के समान पता अस्वीकार कर दिया जाता है। --prover के साथ नोड तभी आरंभ होता है जब <prover-home>/prover.key.json मौजूद हो (डिफ़ॉल्ट <datadir>/prover) और प्रति proving slot 5.74 GB तथा अतिरिक्त 1 GiB मेमोरी उपलब्ध हो, अन्यथा वह आरंभ होने से इनकार कर देता है; --prover-max-parallel slots की संख्या निर्धारित करता है, डिफ़ॉल्ट रूप से एक।

chain 20 पर prover को वॉलेट की viewing key और एक नया salt भेजा जाता है, spend key नहीं। वॉलेट spend key पर authorisation proof स्वयं बनाता है, इसलिए paired prover उस वॉलेट का पूरा इतिहास पढ़ सकता है, पर ख़र्च नहीं कर सकता। listener को loopback पर ही रखें, जब तक कि उसके आगे कोई TLS-terminating proxy न हो, और उसे ऐसी मशीन पर होस्ट न करें जो सार्वजनिक RPC प्रदान करती हो। रोकने पर नोड चल रहे प्रूफ़ के पूरा होने की प्रतीक्षा करता है, इसलिए systemd unit को TimeoutStopSec=180 दें।

सत्यापन और मरम्मत

rand-node verify --datadir ./data                  # full: hashes, QCs, signatures, proofs, ledger replay, the supply counters
rand-node verify --datadir ./data --mode quick     # structure and ledger replay
rand-node verify --datadir ./data --repair         # truncate a damaged tail; peers resync the rest

पहले नोड को रोकें। सुसंगत होने पर exit code 0, और कोई समस्या मिलने पर तथा --repair न दिए जाने पर 2। Replay हर bundle proof को पुनः सत्यापित करता है, इसलिए जिस build का constraint set चेन बनाने वाले build से भिन्न है, वह पहले ही bundle पर रुक जाता है।

validator बनना

कोई validator किसी चल रही चेन से नए genesis के माध्यम से नहीं, बल्कि bonding के माध्यम से जुड़ता है: नोड को --validator के साथ आरंभ करें, rand-node register --key node.key.json --payout <rand1…> --v2 से एक registration प्रिंट करें (chain 20 v1 registration अस्वीकार करती है), किसी वॉलेट से rand bond <address> 1000 --registration <hex> द्वारा कम से कम 1,000 RAND bond करवाएँ, और bond सक्रिय होते ही नोड प्रस्ताव देने लगता है: chain 20 पर, bond के बाद सबसे जल्दी तीन 1,000-block epoch सीमाओं के पश्चात। chain 20 पर bond दूसरे क्रम पर आता है। इसका genesis staking.admission_by_vote निर्धारित करता है, इसलिए नई key पंजीकृत करने वाला bond तब तक अस्वीकार किया जाता है जब तक voting weight के दो-तिहाई से अधिक भाग वाले validators उस key के पक्ष में मत न दे दें: प्रत्येक validator rand-node admit sign --candidate <key or registration> --key <validator key> --genesis-hash 6210cf071a390d7ac61d8cbea5dd9d139d1a493a862b54a45a498f36af2d5135 से हस्ताक्षर करता है, और उनमें से एक rand-node admit submit से मत जमा करता है (कमांड लाइन)। rand_getAdmitted उन keys की सूची देता है जिनके पक्ष में मत दिए जा चुके हैं पर जो अभी पंजीकृत नहीं हुई हैं। किसी एक epoch सीमा पर सक्रिय weight के 2,500 bps से अधिक नया weight नहीं बनता। Staking इसे चरणबद्ध रूप से समझाता है। निजी परीक्षण चेन के लिए rand-node genesis एक genesis तैयार करता है:

rand-node genesis --chain-id 88 \
    --validator a.key.json,1000,rand1<a's payout address> \
    --validator <hex public key of b>,1000,rand1<b's payout address> \
    --alloc rand1<address>=1000 \
    --epoch-blocks 1000 --faucet --fri-profile production \
    --out genesis.json

और scripts/local-testnet.sh एक ही मशीन पर दो validators चलाता है, जिनका RPC 8545 और 8546 पर होता है। अतिरिक्त flags के बिना genesis में न hc_auth होता है, न gas अनुभाग और न कोई memo। chain 20 को इनके ऊपर --hardening-v6 --bundle-guest v3 --auth-guest --gas-price 100 --byte-price 800 --bundle-gas-limit 20479 --gas-dynamic 10485760,262144,1250 --max-gas-price 10000 --max-byte-price 80000 --gas-byte-load paying --envelope-bytes 1860 --testnet --binding-domain 1 --proof-window-blocks 1024 --program-state-cell-fee 10000000 के साथ तैयार किया गया था (chains 18 और 19 में --envelope-bytes तक के flags थे), और इसके bridge और staking अनुभाग तथा consensus_domain cut script द्वारा जोड़े गए थे। आपकी अपनी नई चेन को --binding-domain 1 देना चाहिए: v0.6.8 वॉलेट 14 से 19 के बाहर की हर chain id पर genesis-bound रूप में प्रूफ़ बनाता है।

सर्वर पर डिप्लॉय करना

रिपॉज़िटरी की deploy/ डायरेक्टरी में वे scripts हैं जिनका उपयोग fleet करता है: deploy/push-to-vps.sh <ip> <letter> "<bootstraps>" [validator|observer] एक Linux सर्वर तैयार करता है (source को rsync करना, build करना, /usr/local/bin/{rand-node,rand} इंस्टॉल करना, genesis hash पर आधारित datadir आरंभ करना, rand-node systemd service इंस्टॉल करना), और deploy/rebuild-vps.sh <ip> नए commit पर पुनः build करता है और डेटा सुरक्षित रखते हुए पुनः आरंभ करता है। दो सावधानियाँ। provisioning script deploy/genesis.json से आरंभ करता है, जो chain 20 की फ़ाइल नहीं है, इसलिए testnet के लिए नोड deploy/genesis-chain20.json से हाथ से सेट किया जाता है (main पर, ऊपर देखें)। और दोनों scripts /root/fullnode को --delete के साथ rsync करती हैं, इसलिए उस tree के भीतर रखी key अगले rebuild में हट जाती है: उसे /root/keys में रखें, जैसा fleet करता है और जैसा v0.6.8 provisioning script अब डिफ़ॉल्ट रूप से करता है (v0.6.7 वाला script key को /root/fullnode/deploy/ के अंतर्गत लिखता था)। service प्रबंधन systemctl status rand-node, journalctl -u rand-node -f से होता है। सर्वर को build-essential clang cmake pkg-config libssl-dev और एक Rust toolchain की आवश्यकता होती है। 1-vCPU, 2 GB वाला सर्वर binaries build नहीं कर सकता; उन्हें कहीं और build करके सर्वर पर कॉपी करें। validator और aggregator चलाना में आकार और चरण-दर-चरण सेटअप दिए गए हैं।

एक्सप्लोरर

randscan.org validator E के साथ चलता है और chain 20 को index करता है; इसका REST API और WebSocket feed नोड के बिना चेन पढ़ने का सबसे आसान तरीका है (Explorer API)। एक्सप्लोरर ओपन सोर्स है (randprotocol/randscan) और इसके indexer को केवल किसी नोड के rand_* JSON-RPC और एक PostgreSQL डेटाबेस की आवश्यकता होती है, इसलिए इसे आपके अपने नोड पर भी चलाया जा सकता है।

2026-10-12 को fullnode कमिट c0878c3f (चेन 21) के विरुद्ध अंतिम बार सत्यापित। जहाँ कोड और यह पृष्ठ असहमत हों, वहाँ कोड सही है; हमें बताएँ।