यह पेज बताता है कि rand_sendTransaction द्वारा स्वीकार किए जाने के बाद और किसी ब्लॉक में शामिल होने से पहले किसी ट्रांज़ैक्शन के साथ क्या होता है: यदि वह अस्वीकार हुआ तो क्यों, वह कभी विफल हुए बिना पूल से क्यों ग़ायब हो सकता है, ब्लॉक किस क्रम में भरा जाता है, और ख़राब प्रूफ़ की बाढ़ किसी वैलिडेटर का क्या बिगाड़ सकती है और क्या नहीं। मेमपूल crates/randprotocol-node/src/mempool.rs है; उसके आगे के गार्ड admission.rs हैं।
प्रेषक नहीं, इसलिए नॉन्स नहीं
अकाउंट-आधारित चेन पर मेमपूल हर प्रेषक के ट्रांज़ैक्शनों को नॉन्स के क्रम में रखता है। शील्डेड चेन पर कोई प्रेषक नहीं होता: बंडल में न कोई पता होता है, न कोई हस्ताक्षर, और दो बंडल आपस में तभी संबंधित होते हैं जब वे एक ही नोट को छूते हैं। इसलिए प्रति-प्रेषक क्रम तय करने का काम बचता ही नहीं। नॉन्स के लेखे-जोखे की जगह टकराव ट्रैकिंग (conflict tracking) लेती है: पूल हर लंबित ट्रांज़ैक्शन के न्यूलिफ़ायर और कमिटमेंट को इंडेक्स करता है, और ऐसे नए ट्रांज़ैक्शन को अस्वीकार करता है जो उनमें से किसी पर दावा करे। यही बात उन कुछ काउंटरों पर भी लागू होती है जिनके हर मान पर लेजर ठीक एक ट्रांज़ैक्शन स्वीकार करता है: किसी वैलिडेटर का रजिस्टर नॉन्स (Unbond या Withdraw), किसी टोकन का mint_nonce (TokenMint और SetAuthority द्वारा साझा), वह रजिस्ट्री इंडेक्स जिससे कोई RegisterToken बँधा होता है, और ब्रिज के pause_nonce और list_nonce। इनमें से हर एक ऐसा स्लॉट है जिसे पूल का अधिक से अधिक एक ट्रांज़ैक्शन धारण कर सकता है। ऐसे दो ट्रांज़ैक्शनों में से अधिक से अधिक एक ही कभी शामिल हो सकता है, और दूसरे को ढोने की क़ीमत प्रस्तावक को ब्लॉक स्पेस से और हर नोड को हर गॉसिप राउंड में एक प्रूफ़ सत्यापन से चुकानी पड़ती।
पूल में अधिक से अधिक 10,000 ट्रांज़ैक्शन रहते हैं (node.rs में Mempool::new(10_000)) और, v0.6.8 से, अधिक से अधिक आठ ब्लॉकों जितने बाइट: MAX_POOL_BLOCKS = चेन के max_block_bytes का 8 गुना, यानी chain 20 पर 160 MiB (audit v6, CH-7)। इससे पहले केवल संख्या पर सीमा थी, जबकि प्रूफ़ वाला एक ट्रांज़ैक्शन लगभग 1.3 MB से लेकर 12 MB से अधिक तक का होता है। हर ट्रांज़ैक्शन का सत्यापन अंतिम कमिट हुए ब्लॉक के बजाय कंसेंसस ट्री के शीर्ष (tip) पर मौजूद लेजर के विरुद्ध होता है: वही स्थिति जिस पर कोई प्रस्तावक वास्तव में ब्लॉक बनाएगा।
प्रवेश: सस्ती जाँच पहले, महँगी बाद में
RPC या गॉसिप से आने वाला ट्रांज़ैक्शन क्रम से इन चरणों से गुज़रता है, और पहली अस्वीकृति ही वह त्रुटि होती है जो आपको दिखती है:
- डुप्लिकेट। हैश पहले से पूल में है:
already in mempool। - टकराव। कोई न्यूलिफ़ायर, कोई कमिटमेंट या ऊपर बताए गए नॉन्स और इंडेक्स स्लॉट में से कोई एक पहले से किसी लंबित ट्रांज़ैक्शन द्वारा दावा किया जा चुका है:
conflicts with a pending transaction over <hex>। टोकन स्लॉट के लिए hex एक प्रदर्शन कुंजी होती है: एक टैग शब्द (mint_nonceके लिएtokn, पंजीकरण इंडेक्स के लिएtidx), फिर इंडेक्स और नॉन्स। जिस ब्रिज अटेस्टेशन के लिए दो रिलेयर होड़ में थे, उसे उसके डाइजेस्ट से पहचाना जाता है:conflicts with a pending transaction over bridge attestation <hash>। - भरा हुआ।
mempool full। क्षमता की जाँच इन तीनों में अंतिम है। बाइट सीमा पर पहुँचने पर नया ट्रांज़ैक्शन पूल की उन प्रविष्टियों की जगह ले सकता है जो उससे सख़्ती से नीचे रैंक करती हैं — पहले हर एक के वर्तमान प्रति-KiB न्यूनतम से ऊपर के शुल्क के आधार पर, फिर शुल्क के आधार पर — और जगह बनने तक सबसे सस्ती प्रविष्टियों को पहले निकाला जाता है; यदि वे पर्याप्त न हों, या वह केवल बराबरी पर हो, तो अस्वीकार वही होता है। गवर्नेंस क्रियाएँ दोनों सीमाओं से बाहर हैं और कभी निकाली नहीं जातीं: चार ब्रिज गवर्नेंस क्रियाएँPauseMints,UnpauseMints,RegisterBridgedToken,ListBacking, और v0.6.8 सेRotatePqGuardians,RotatePauseKey, उनके…V2रूप,CancelRotation,AdmitValidatorऔरSlashEquivocation। उनके बाइट और प्रविष्टियाँ फिर भी सीमाओं में गिनी जाती हैं।PauseMintsगार्जियन-कुंजी के समझौते (compromise) की स्थिति में ब्रेक है: बंडल-रहित, शुल्क-रहित, और वही एक ट्रांज़ैक्शन जिसे हमलावर के मिंट करते रहने के दौरान ब्लॉक तक पहुँचना ही चाहिए, इसलिए भरा हुआ पूल उसे बाहर नहीं रख सकता। यह छूट टकराव वाले चरण से सीमित है:pause_nonceऔरlist_nonceमें से हर एक एक समय में पूल के एक ही ट्रांज़ैक्शन को प्रवेश देता है, इसलिए चार ब्रिज क्रियाएँ सीमा के पार अधिक से अधिक दो प्रविष्टियाँ जोड़ सकती हैं; बाक़ी क्रियाओं में से हर एक अपना ख़ुद का नॉन्स या कोरम ख़र्च करती है। Ledger::validateका सस्ता आधा हिस्सा। वह सब कुछ जो प्रवेश और समावेशन के बीच बासी हो सकता है और जिसमें कोई प्रूफ़ नहीं लगता: एंकर chain 20 पर अंतिम 1,024 रूट में से एक है (जेनेसिसproof_window_blocks; उसके बिना 256),timeविंडो के भीतर है, न्यूलिफ़ायर ख़र्च नहीं हुए हैं, कमिटमेंट मौजूद नहीं हैं, अटेस्टेशन का डाइजेस्ट दावा-रहित है, स्टेकिंग क्रिया का रजिस्टर नॉन्स वर्तमान है, टोकन क्रिया काmint_nonceया पंजीकरण इंडेक्स वही है जिस पर रजिस्ट्री है (चेन के उससे आगे बढ़ जाने परwrong mint nonce,wrong token index), और पॉज़ या लिस्टिंग का नॉन्स ब्रिज का वर्तमान नॉन्स है। ट्रांज़ैक्शन जो कमिटमेंट बनाता है उनकी गणना भी यहीं होती है, जिसमें वह नोट भी शामिल है जिसे लेजर स्वयं किसीWithdraw,BridgeAttestया एग्रीगेटर भुगतान के लिए व्युत्पन्न करता है; वह वायर पर नहीं होता, पर उसका भी टकराना वर्जित है। कुछ भी डिकोड करने से पहले आकार सीमाएँ जाँची जाती हैं: चेन केmax_proof_bytesसे बड़ा प्रूफ़ (डिफ़ॉल्ट रूप से 2 MiB, chain 20 पर 4 MiB), 16 KiB से बड़ा अटेस्टेशन, या ब्लॉक से बड़ा ट्रांज़ैक्शन (max_block_bytes: डिफ़ॉल्ट रूप से 4 MiB, chain 20 पर 20 MiB) सीधे अस्वीकार कर दिया जाता है, ताकि अति-आकार का ब्लॉब कोई काम न करवा सके। सील किए गए (प्रून किए गए) मार्कर रूप वाला बंडल प्रूफ़ सील-रूप सिंक के बाहर इसी चरण मेंPrunedFormOutsideSyncके रूप में अस्वीकार होता है। फिर, अब भी कुछ सत्यापित किए बिना, पूल प्रूफ़ हेडर पढ़ता है। तीन नीतियाँ पहले आती हैं: ऐसा कॉल पूल में नहीं लिया जाता जिसकी इनपुट, keccak या sha256 तालिका 2^7 पंक्तियों से कम हो (CallRevealsPrivateInputs), न ही ऐसा डिप्लॉय जिसे कोई कॉल समा न सके (ProgramUncallable), न ही ऐसा ट्रांज़ैक्शन जिसके बंडल या कॉल प्रूफ़ में कोई ऐसा हेडर फ़ील्ड हो जिसे ईमानदार प्रूवर नहीं लिखता (NonCanonicalProof)। अंतिम दो chain 20 परhardening_v6के अंतर्गत लेजर नियम भी हैं। v0.6.8 से, जिस हेडर की घोषित डिग्री सबसे ऊँची तालिका की अधिकतम सीमा से आगे हो, उसे जाँच द्वारा उस पर चलने से पहले हीNonCanonicalProofके रूप में अस्वीकार कर दिया जाता है (audit v6, ZKV-4), और इस प्रारंभिक जाँच में कहीं भी panic होने का अर्थ उस ट्रांज़ैक्शन की अस्वीकृति है (VerifierPanicked), न कि नोड का बंद हो जाना। फिर न्यूनतम शुल्क: chain 20 पर पूल किसी कॉल या इनवोक प्रूफ़ द्वारा घोषित गैस सीमा को डिकोड करता है और शीर्ष की क़ीमतों परBUNDLE_BASE + gas_price × limit + byte_price × ⌈bytes/1024⌉, साथ में इनवोक के सेल शुल्क, से कम शुल्क कोFeeTooLowके रूप में अस्वीकार करता है (शुल्क)। यह ब्लॉक का अपना नियम है, इसलिए पूल ठीक उतना ही माँगता है जितना ब्लॉक माँगता है।- महँगा आधा हिस्सा, कंसेंसस लूप से बाहर। ट्रांज़ैक्शन को चार सत्यापन वर्करों में से किसी एक के लिए, अधिकतम 64 की गहराई वाली कतार में रखा जाता है। वर्कर
Ledger::validateका शेष भाग एक ब्लॉकिंग टास्क पर चलाता है: बंडल डाइजेस्ट, बंडल प्रूफ़ द्वारा घोषित गैस सीमा (chain 20 पर ठीक 20,479, अन्यथाBundleGasLimit), बंडल प्रूफ़ और, chain 17 से, ट्रांज़ैक्शन के बाइंडिंग के विरुद्ध उसका प्राधिकरण प्रूफ़, और कॉल के लिए उसका अपना प्रूफ़ और उसका न्यूनतम शुल्क। यह सत्यापन शीर्ष के एक स्नैपशॉट के विरुद्ध होता है जिसे आलस्यपूर्वक (lazily) क्लोन किया जाता है, शीर्ष बदलने पर अधिक से अधिक एक बार और केवल तब जब कुछ प्रतीक्षा में हो। जो गॉसिप किया गया ट्रांज़ैक्शन कतार को भरा पाता है, उसे मतदान करने वाले लूप को रोकने के बजाय छोड़ दिया जाता है, न सत्यापित किया जाता है न आगे भेजा जाता है; पीयर का अगला गॉसिप राउंड उसे फिर ले आता है। - पुनः जाँच और पूल में प्रवेश।
insert_verifiedचरण 4 को उस शीर्ष के विरुद्ध फिर से चलाता है जिस पर ट्रांज़ैक्शन वास्तव में पूल में रखा जाता है, क्योंकि प्रूफ़ के सत्यापन के दौरान शीर्ष आगे बढ़ चुका हो सकता है, फिर उसे प्रवेश देता है और, गॉसिप से आए ट्रैफ़िक के लिए, उसे आगे भेजता है।
चरण 1 से 4 Mempool::precheck हैं; चरण 5 ही एकमात्र चरण है जो STARK का सत्यापन करता है। चूँकि यह लागत एक वर्कर पर चुकाई जाती है, ख़राब प्रूफ़ की बाढ़ चार थ्रेड घेरती है, कंसेंसस लूप को कभी नहीं। ट्रांज़ैक्शन और क्रियाएँ लेजर का अपना प्रवेश क्रम सूचीबद्ध करता है, जिसे चरण 4 और 5 मिलकर चलाते हैं।
गॉसिप के लिए दो गार्ड और एक कैश
प्रवेश से पहले, दो चीज़ें केवल पीयर से आने वाले ट्रांज़ैक्शनों पर लागू होती हैं; RPC से भेजे गए ट्रांज़ैक्शन इन्हें छोड़ देते हैं, क्योंकि वह पोर्ट ऑपरेटर का अपना है और पहले से ही अनुरोध-बॉडी की सीमा से बँधा है। RPC का एकमात्र मार्ग जिसकी खपत मापी जाती है, फ़ॉसेट है, जिसका वर्णन नीचे है।
- प्रति-पीयर बाइट मीटर। v0.6.8 से हर गॉसिप फ़्रेम को डिकोड किए जाने से पहले ही उसे अग्रेषित करने वाले पीयर के बाइट बजट से घटा दिया जाता है। इस बजट में अधिकतम ट्रांसमिट आकार के आठ फ़्रेम का बर्स्ट मिलता है, और यह प्रति सेकंड दो फ़्रेम की दर से फिर भरता है। बजट से आगे का फ़्रेम बिना डिकोड किए छोड़ दिया जाता है (audit v6, GOSSIP-1)। ट्रांज़ैक्शन id पूरे प्रूफ़ का हैश लेती है, इसलिए उसकी गणना केवल अग्रेषक के बजट के भीतर ही होती है।
- प्रति-पीयर ट्रांज़ैक्शन मीटर। हर अग्रेषित करने वाले पीयर के लिए एक टोकन बकेट है, जिसमें 16 का बर्स्ट मिलता है और यह प्रति सेकंड 4 की दर से फिर भरता है (
PEER_TX_BURST,PEER_TX_PER_SEC)। यह उस पीयर को मापता है जिसने ट्रांज़ैक्शन अग्रेषित किया, उसके लेखक को नहीं, क्योंकि शील्डेड चेन लेखक की पहचान नहीं बता सकती। - निर्णय कैश। कुछ ट्रांज़ैक्शन यह नोड ऐसे कारण से पहले ही अस्वीकार कर चुका होता है जो केवल उनके बाइट्स पर निर्भर है, जैसे अमान्य प्रूफ़, अमान्य हस्ताक्षर या सीमा से बड़ा कोई भाग। ऐसे ट्रांज़ैक्शन को दोबारा सत्यापित नहीं किया जाता, उसे 8,192 प्रविष्टियों वाले FIFO कैश (
REFUSED_CACHE_ENTRIES) से फिर अस्वीकार कर दिया जाता है। जो निर्णय इस नोड की स्थिति के बारे में कुछ कहता है, जैसे अज्ञात एंकर या पहले से व्यय हुआ नलिफ़ायर, वह कभी कैश नहीं होता। ऐसा न हो तो एक ब्लॉक पीछे चल रहा नोड उन ट्रांज़ैक्शनों के विरुद्ध ख़ुद को दूषित कर लेगा जो बस वैध होने वाले हैं। यह सूची एक अनुमति-सूची है, इसलिए कोई नई त्रुटि तब तक स्थिति मानी जाती है जब तक कोई अन्यथा तय न करे। नीचे की प्रविष्टियाँ दिखाती हैं कि यह रेखा कहाँ से गुज़रती है:- v0.6.8 से
BadPauseSignature(the pause signature does not verify) स्थायी नहीं है (audit v6, BRG-18)। यह हस्ताक्षर को चेन की वर्तमान पॉज़ कुंजी के अंतर्गत जाँचता है। bridge rules v2 इस कुंजी को बदल सकते हैं, इसलिए यह स्थिति है। अन्यथा कुंजी-परिवर्तन से एक ब्लॉक पीछे चल रहा नोड पुनःआरंभ तक नए धारक केPauseMintsको अस्वीकार करता रहेगा। इसी कारण सीमा से बाहर का PQ सह-हस्ताक्षर सूचकांक भी कैश से हटा दिया गया। v0.6.7 तक, चेन 18 और 19 पर, दोनों स्थायी के रूप में कैश होते थे। अब बार-बार भेजे गए अमान्य पॉज़ की लागत हर डिलीवरी पर एक Dilithium2 सत्यापन है, जिसकी सीमा प्रति-पीयर मीटर तय करता है। PrunedFormOutsideSyncजानबूझकर स्थायी नहीं है। सील किए गए बंडल के मार्कर रूप का हैश मूल ट्रांज़ैक्शन की अपनी id के बराबर होता है, और कैश उसी id को कुंजी बनाता है। इसलिए इस अस्वीकृति को कैश करने से कोई भी गॉसिप पीयर ईमानदार ट्रांज़ैक्शन को पूरे नेटवर्क में सेंसर कर सकेगा।- किसी प्रूफ़ की घोषित गैस सीमा उसके अपने बाइट्स और एक जेनेसिस स्थिरांक की तुलना है, इसलिए
BundleGasLimitऔरAuthGasLimitस्थायी हैं।FeeTooLowस्थायी नहीं है, क्योंकि चेन 20 पर न्यूनतम शुल्क कीमतों के साथ बदलता है। चरण 4 की तीन हेडर नीतियाँ भी कभी कैश नहीं होतीं: हर एक इस बिल्ड की जानकारी है, जिसे कोई बाद का बिल्ड बदल सकता है। - फ़ॉसेट अनुमति-सूची वाली चेन (चेन 20) पर
FaucetRecipientNotAllowedस्थायी है, क्योंकि यह मिंट के अपने प्राप्तकर्ता की तुलना एक जेनेसिस स्थिरांक से करता है।FaucetBudgetExhaustedस्थायी नहीं है: यह स्थिति है, और वही मिंट अगले एपॉक में फिर स्वीकार हो जाता है। - स्टेकिंग क्रिया के विपरीत, टोकन क्रिया का
BadSignatureभी स्थायी नहीं है। टोकन का मिंट अधिकार स्थिति है, औरSetAuthorityउसे किसी दूसरी कुंजी को सौंप सकता है। इसलिए वही बाइट्स उस परिवर्तन के कमिट होने से पहले अस्वीकार और बाद में स्वीकार हो सकते हैं। बाइट-स्तर की टोकन अस्वीकृतियाँ कैश होती हैं, जैसे अमान्य नाम या प्रतीक, बहुत अधिक दशमलव स्थान, शून्य राशि, या टोकन सूचकांक 0। ये भी कैश होती हैं: बर्न का ऐसा फ़ील्ड जिसे क्रिया सेट नहीं कर सकती, ऐसा मिंट जिसका कमिटमेंट उसकी राशि पर नहीं खुलता, और ऐसा ब्रिज डिपॉज़िट जिसकी ब्लाइंडिंग व्युत्पन्न ब्लाइंडिंग नहीं है।
- v0.6.8 से
फ़ॉसेट सीमा
rand_mint पर कोई शुल्क नहीं लगता और हर कॉल पूल में एक ट्रांज़ैक्शन जोड़ती है। चेन 20 पर फ़ॉसेट चालू है और उसके पीछे मूल्य रखने वाला एक ब्रिज है। जेनेसिस तय करता है कि फ़ॉसेट क्या कर सकता है। कोई मिंट केवल अनुमति-सूची के 16 वॉलेट को भुगतान करता है, और 1,000 ब्लॉक के हर एपॉक में अधिकतम 10,000 RAND (Staking)। मिंट पर हस्ताक्षर केवल जेनेसिस की staking.faucet_minters सूची की 18 कुंजियों में से कोई एक कर सकती है (MinterNotAllowed, जो कभी कैश नहीं होता)। चेन 16 से यह लेजर नियम है। चेन 15 पर यह नोड नीति थी, और वहाँ यह सूची जेनेसिस वैलिडेटर ही थे। इसके ऊपर हर नोड अपने फ़ॉसेट को ख़ुद मापता है: लगातार आठ मिंट, जिसके बाद प्रति सेकंड एक की दर से बजट फिर भरता है (FAUCET_MINT_BURST, FAUCET_MINT_PER_SEC)। इससे आगे कॉल का उत्तर होता है faucet is rate limited on this node (8 mints back to back, refilling at 1/s); try again shortly। यह सीमा प्रति नोड प्रक्रिया है, प्रति कॉलर नहीं, क्योंकि RPC पोर्ट पर मापने के लिए कोई पीयर पहचान नहीं होती और संरक्षित संसाधन इसी नोड का पूल है। ऊपर बताई गई क्षमता-छूट के साथ मिलकर इसका अर्थ है कि फ़ॉसेट की बाढ़ किसी PauseMints से पहले पूल को नहीं भर सकती।
Gossipsub एप्लिकेशन-स्तरीय सत्यापन के साथ चलता है, इसलिए कोई ट्रांज़ैक्शन दूसरे पीयरों को तभी अग्रेषित होता है जब वह यहाँ सत्यापित हो चुका हो। जो पीयर अमान्य ट्रांज़ैक्शनों की बाढ़ भेजता है, उसे मीटर धीमा कर देता है और कैश उत्तर देता है। सर्वसम्मति लूप पर उसकी कोई लागत नहीं पड़ती।
ब्लॉक बनाना
जब कोई वैलिडेटर किसी व्यू का नेतृत्व करता है, तो वह पूल से उम्मीदवार ट्रांज़ैक्शन माँगता है। candidates_within केवल वे ट्रांज़ैक्शन रखता है जो उस लेजर पर, जिस पर ब्लॉक बन रहा है, अब भी लागू होते हैं। इसके लिए वह प्रवेश-जाँच का सस्ता आधा हिस्सा फिर चलाता है: एंकर अब भी विंडो में है, time अब भी विंडो में है, नलिफ़ायर अभी व्यय नहीं हुए हैं, और कमिटमेंट अभी मौजूद नहीं हैं। वह ऐसी टोकन क्रिया भी हटा देता है जिसके mint_nonce या पंजीकरण सूचकांक से चेन आगे निकल चुकी है, और पुराने nonce वाला पॉज़ या लिस्टिंग भी।
v0.6.8 से वह हर कॉल और इनवोक का मूल्य फिर से लगाता है। इसके लिए वह उस टिप पर लागू कीमतें लेता है जिस पर ब्लॉक बन रहा है, और प्रवेश के समय याद रखी गई गैस सीमा। जिसका शुल्क अब न्यूनतम से कम है, उसे वह ब्लॉक से बाहर रखता है। वह ट्रांज़ैक्शन पूल में बना रहता है और कीमतें गिरने पर फिर प्रस्तुत होता है (audit v6, CH-9)।
चेन 20 पर इसके बाद शेष ट्रांज़ैक्शन इस क्रम में लगते हैं: पहले गवर्नेंस, फिर वर्तमान न्यूनतम से ऊपर के शुल्क के अनुसार प्रति KiB ट्रांज़ैक्शन, फिर शुल्क के अनुसार, सबसे ऊँचा पहले, और बराबरी पर हैश से निर्णय। इससे एक ही पूल पर ब्लॉक बनाने वाला हर ईमानदार प्रस्तावक वही ब्लॉक चुनता है। ब्लॉक 2,000 ट्रांज़ैक्शन और चेन की ब्लॉक सीमा तक भरा जाता है (MAX_BLOCK_TXS; max_block_bytes, डिफ़ॉल्ट रूप से 4 MiB और चेन 20 पर 20 MiB)। ब्लॉक में कमी बाइट्स की होती है, इसीलिए अतिरिक्त शुल्क प्रति KiB लिया जाता है। जिस चेन में gas अनुभाग नहीं है और जिस नोड में गैस नीति नहीं है, वे यह कुंजी छोड़ देते हैं और गवर्नेंस, शुल्क और हैश से क्रम लगाते हैं, जैसा चेन 15 ने किया।
पहले गवर्नेंस रखना पॉज़ की गारंटी का दूसरा आधा हिस्सा है। PauseMints डिज़ाइन के अनुसार कोई शुल्क नहीं देता, क्योंकि उसे ऐसे वॉलेट से भी काम करना है जिसमें कोई RAND नहीं है। केवल शुल्क के क्रम में यह आपातकालीन ब्रेक शुल्क देने वाले हर ट्रांज़ैक्शन के पीछे चला जाता।
जब कोई कॉल या इनवोक तैयार हो, तब एक और नियम लागू होता है (audit v6, POOL-2)। यह हर चेन पर नोड नीति है, वैधता नियम नहीं। बाइट मूल्य केवल कॉल और इनवोक देते हैं। अपने निश्चित आधार शुल्क से थोड़ा अधिक देने वाला ट्रांसफ़र प्रति KiB उनसे ऊँचा स्थान पाता है, इसलिए ट्रांसफ़रों की एक धारा किसी तैयार कॉल को हर ब्लॉक से बाहर रख सकती थी। इसलिए पहले चरण में निश्चित शुल्क वाले ट्रांज़ैक्शन ब्लॉक के बाइट्स का अधिकतम तीन-चौथाई लेते हैं। कॉल रखे जाने के बाद जो जगह बचती है, उसे रोके गए ट्रांसफ़रों से उनके क्रम में भर दिया जाता है। ब्लॉक की कोई जगह व्यर्थ नहीं जाती, और कोई कॉल तैयार न हो तो कुछ नहीं बदलता (Fees)।
जो ट्रांज़ैक्शन बची हुई जगह के लिए बहुत बड़ा है, उसे छोड़ दिया जाता है, पर ब्लॉक वहीं समाप्त नहीं होता: उसके पीछे का कोई छोटा ट्रांज़ैक्शन फिर भी शामिल हो जाता है। चेन 18 का एक ट्रांसफ़र लगभग 2.85 MB का होता है: 1.49 MB का बंडल प्रूफ़ और 1.36 MB का प्राधिकरण प्रूफ़। इसलिए उसके 20 MiB के ब्लॉक में लगभग सात ट्रांसफ़र आते हैं, और डिफ़ॉल्ट 4 MiB के ब्लॉक में एक। चेन 15 पर, लगभग 1.43 MB प्रति ट्रांसफ़र के साथ, उसी 20 MiB में चौदह आते थे। लोड के समय शुल्क ही तय करता है कि कौन से ट्रांज़ैक्शन शामिल होंगे (Fees)।
छँटाई
हर कमिट के बाद prune पूल से ठीक वही हटाता है जिसे candidates_within छोड़ देता। ये वे ट्रांज़ैक्शन हैं जिनका नोट किसी और ने व्यय कर दिया, जिनका कमिटमेंट अब मौजूद है, जिनके nonce या पंजीकरण सूचकांक से चेन आगे निकल चुकी है, या जिनका एंकर या time विंडो से बाहर चला गया है (चेन 20 पर 1,024 ब्लॉक, चेन 19 तक 256)। इसलिए डबल-स्पेंड की होड़ हारने वाला बंडल अपने आप ग़ायब हो जाता है, और किसी को कोई त्रुटि नहीं मिलती। rand_sendTransaction द्वारा स्वीकृति कमिटमेंट नहीं है। rand_getTransaction को तब तक पोल करें जब तक वह कोई ब्लॉक न लौटाए। यदि ब्लॉक मिलने से पहले एंकर विंडो बीत जाए, तो नए एंकर पर बंडल फिर से बनाएँ और दोबारा जमा करें।
इस पर नज़र रखना
rand_status तीन मान बताता है: mempool_size, verify_queue (वर्कर की प्रतीक्षा कर रहे ट्रांज़ैक्शन) और refused_cache (निर्णय कैश की प्रविष्टियाँ)। यदि verify_queue 64 पर टिका रहे, तो प्रूफ़ उससे तेज़ आ रहे हैं जितना चार वर्कर उन्हें सत्यापित कर पाते हैं। वार्म कुंजी के साथ हर सत्यापन लगभग 16 ms लेता है। यदि ब्लॉक भरे रहने के बावजूद mempool_size बढ़ता रहे, तो शामिल होने का निर्णय आगमन का क्रम नहीं, शुल्क कर रहा है।
जो अभी नहीं है
- कोई प्रतिस्थापन नहीं। चेन 20 पर गैस और बाइट की कीमतें हर ब्लॉक में किसी कॉल की न्यूनतम फ़ीस बदलती हैं, अपनी अधिकतम सीमाओं तक; किसी ट्रांसफ़र की न्यूनतम फ़ीस स्थिर रहती है। पूल में रखे किसी ट्रांज़ैक्शन को उन्हीं नोट्स पर अधिक फ़ीस वाले ट्रांज़ैक्शन से बदला नहीं जा सकता, क्योंकि टकराव का नियम इसे अस्वीकार कर देता है। जो कॉल कीमतें बढ़ने से बाहर हो जाती है, वह पूल में प्रतीक्षा करती है और तब तक प्रस्तावित नहीं की जाती जब तक कीमतें घट न जाएँ या उसकी एंकर विंडो बीत न जाए। v0.6.7 (चेन 18 और 19) पर पूल में रखी कॉल अपनी वही न्यूनतम फ़ीस रखती थी जिस पर उसे स्वीकार किया गया था। कीमतें बढ़ने के बाद भी वह प्रस्तावित की जाती थी, और प्रस्तावक के परीक्षण-अनुप्रयोग में
FeeTooLowके रूप में विफल हो जाती थी। fullnode का ब्लॉक-स्पेस दस्तावेज़ फ़ीस-क्रमित मेमपूल को बड़े ब्लॉक से पहले का चरण बताता है, और ब्लॉक-स्तरीय एकत्रीकरण को वह उपाय बताता है जो प्रति-ब्लॉक अधिकतम सीमा बढ़ाता है। - आयु के आधार पर कोई समाप्ति नहीं। पूल में रखा ट्रांज़ैक्शन केवल तीन तरह से हटता है: ब्लॉक में शामिल होने से, बाइट सीमा पर निष्कासन से, या एंकर और समय विंडो बीतने से। चेन 20 पर ये विंडो 1,024 ब्लॉक की हैं। एक्सप्लोरर ने वहाँ प्रति ब्लॉक 1.34 s का समय दर्ज किया, जिस हिसाब से यह लगभग 23 मिनट है। चेन 19 तक ये विंडो 256 ब्लॉक की थीं, यानी लगभग पाँच मिनट।
- कोई मेमपूल RPC नहीं। लंबित ट्रांज़ैक्शनों की सूची देने वाली कोई मेथड नहीं है। मेमपूल देखने के केवल दो तरीके हैं:
rand_statusमेंmempool_size, औरrand_getMempoolInfoमें संख्या, बाइट और सबसे पुराने ट्रांज़ैक्शन की आयु। एक्सप्लोरर केवल कमिट हो चुके ब्लॉकों को इंडेक्स करता है।