Rand Protocol
دستاویزات
بنیادی تصورات

میم پول

ایک نوڈ کسی ٹرانزیکشن کو موصول کرنے سے لے کر اسے بلاک میں شامل کرنے تک اس کے ساتھ کیا کرتا ہے - داخلے کی ترتیب، نانس کی جگہ تنازعات کا سراغ، چار تصدیقی ورکرز، پیئر میٹر اور فیصلوں کا کیش، تجویز کنندہ بلاک کیسے منتخب کرتا ہے، اور ہارنے والا دوہرا خرچ خود بخود کیوں غائب ہو جاتا ہے۔

اس صفحے سے یہ سمجھا جا سکتا ہے کہ rand_sendTransaction کسی ٹرانزیکشن کو قبول کرنے کے بعد اور کسی بلاک میں شامل ہونے سے پہلے اس کے ساتھ کیا ہوتا ہے: اگر اسے رد کیا گیا تو کیوں، وہ کبھی ناکام ہوئے بغیر پول سے کیوں غائب ہو سکتی ہے، بلاک کس ترتیب سے بھرا جاتا ہے، اور غلط پروفس کی بھرمار کسی ویلیڈیٹر کا کیا بگاڑ سکتی ہے اور کیا نہیں۔ میم پول crates/randprotocol-node/src/mempool.rs ہے؛ اس کے آگے کے محافظ admission.rs میں ہیں۔

بھیجنے والے نہیں، اس لیے نانس بھی نہیں

اکاؤنٹ پر مبنی چین میں میم پول ہر بھیجنے والے کی ٹرانزیکشنز کو نانس کے مطابق ترتیب دیتا ہے۔ شیلڈڈ چین میں بھیجنے والے ہوتے ہی نہیں: بنڈل میں نہ کوئی ایڈریس ہوتا ہے نہ دستخط، اور دو بنڈلز میں تعلق صرف تب ہوتا ہے جب وہ ایک ہی نوٹ کو چھوتے ہوں۔ چنانچہ ہر بھیجنے والے کے لحاظ سے ترتیب دینے کا کوئی کام باقی نہیں رہتا۔ نانس کے حساب کتاب کی جگہ تصادم کی نگرانی لیتی ہے: پول ہر زیرِ التوا ٹرانزیکشن کے نلیفائرز اور کمٹمنٹس کا اشاریہ رکھتا ہے، اور کسی ایسی نئی ٹرانزیکشن کو رد کر دیتا ہے جو ان میں سے کسی پر دعویٰ کرے۔ یہی اصول ان چند کاؤنٹرز پر بھی لاگو ہے جن کی ہر قدر کے لیے لیجر ٹھیک ایک ٹرانزیکشن قبول کرتا ہے: ویلیڈیٹر کا رجسٹر نانس (ایک 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 گنا، یعنی چین 20 پر 160 MiB (آڈٹ v6، CH-7)۔ اس سے پہلے صرف تعداد کی حد مقرر تھی، جبکہ پروف رکھنے والی ایک ٹرانزیکشن کا حجم تقریباً 1.3 MB سے 12 MB سے زائد تک ہوتا ہے۔ ہر ٹرانزیکشن کی توثیق لیجر کی اس حالت کے مقابل ہوتی ہے جو کنسینسس ٹری کے سرے پر ہے، نہ کہ آخری کمٹ شدہ بلاک پر: یعنی وہ حالت جس پر تجویز کنندہ درحقیقت بلاک بنائے گا۔

داخلہ: سستا کام مہنگے سے پہلے

RPC یا گوسپ کے ذریعے آنے والی ٹرانزیکشن ترتیب وار ان مراحل سے گزرتی ہے، اور پہلا انکار ہی وہ خرابی ہے جو آپ کو نظر آتی ہے:

  1. دہرائی ہوئی۔ ہیش پہلے سے پول میں ہے: already in mempool۔
  2. تصادم۔ کوئی نلیفائر، کوئی کمٹمنٹ یا اوپر بیان کردہ نانس اور انڈیکس کی جگہوں میں سے کوئی ایک پہلے ہی کسی زیرِ التوا ٹرانزیکشن کے دعوے میں ہے: conflicts with a pending transaction over <hex>۔ ٹوکن کی جگہ کے لیے hex ایک نمائشی کلید ہوتی ہے: ایک ٹیگ لفظ (mint_nonce کے لیے tokn، رجسٹریشن انڈیکس کے لیے tidx)، پھر انڈیکس اور نانس۔ برج کی ایسی تصدیق جس پر دو ریلیئرز میں دوڑ لگی ہو، اپنے ڈائجسٹ سے پہچانی جاتی ہے: conflicts with a pending transaction over bridge attestation <hash>۔
  3. بھرا ہوا۔ mempool full۔ گنجائش کی جانچ ان تینوں میں آخری ہے۔ بائٹ کی حد پر پہنچ کر نئی ٹرانزیکشن پول کی ان اندراجات کی جگہ لے سکتی ہے جو درجے میں اس سے سختی سے نیچے ہوں — پہلے ہر ایک کی موجودہ فی KiB کم از کم حد سے زائد فیس کے لحاظ سے، پھر فیس کے لحاظ سے — اور سب سے سستی کو پہلے نکالتی جاتی ہے یہاں تک کہ اس کی جگہ بن جائے؛ اگر یہ کافی نہ ہوں، یا وہ صرف برابر ہو، تو رد اسی کو کیا جاتا ہے۔ گورننس کے اقدامات دونوں حدود سے باہر ہیں اور کبھی نکالے نہیں جاتے: برج گورننس کے چار اقدامات PauseMints، UnpauseMints، RegisterBridgedToken، ListBacking، اور v0.6.8 سے RotatePqGuardians، RotatePauseKey، ان کی …V2 صورتیں، CancelRotation، AdmitValidator اور SlashEquivocation۔ ان کی بائٹس اور اندراجات پھر بھی حدود میں شمار ہوتے ہیں۔ PauseMints گارڈین کلید کے افشا ہونے کی صورت میں بریک ہے: بنڈل کے بغیر، فیس کے بغیر، اور وہ واحد ٹرانزیکشن جسے اس وقت بلاک تک پہنچنا لازم ہے جب کوئی حملہ آور منٹ کر رہا ہو، اس لیے بھرا ہوا پول اسے باہر نہیں رکھ سکتا۔ یہ استثنا تصادم کے مرحلے سے محدود ہے: pause_nonce اور list_nonce میں سے ہر ایک ایک وقت میں پول کی ایک ہی ٹرانزیکشن کو داخلہ دیتا ہے، اس لیے برج کے چار اقدامات حد سے زیادہ سے زیادہ دو اندراجات ہی بڑھا سکتے ہیں؛ باقی اقدامات میں سے ہر ایک اپنا الگ نانس یا کورم صرف کرتا ہے۔
  4. Ledger::validate کا سستا نصف۔ ہر وہ چیز جو داخلے اور شمولیت کے درمیان پرانی ہو سکتی ہے اور جس پر کسی پروف کا خرچ نہیں آتا: اینکر چین 20 پر آخری 1,024 روٹس میں سے ایک ہو (جینیسس کا proof_window_blocks؛ اس کے بغیر 256)، time ونڈو کے اندر ہو، نلیفائرز خرچ نہ ہوئے ہوں، کمٹمنٹس موجود نہ ہوں، تصدیق کے ڈائجسٹ پر دعویٰ نہ ہوا ہو، اسٹیکنگ اقدام کا رجسٹر نانس موجودہ ہو، ٹوکن اقدام کا mint_nonce یا رجسٹریشن انڈیکس وہی ہو جس پر رجسٹری ہے (چین کے آگے بڑھ جانے کے بعد wrong mint nonce، wrong token index)، اور پاز یا لسٹنگ کا نانس برج کا موجودہ نانس ہو۔ ٹرانزیکشن جو کمٹمنٹس بناتی ہے ان کا حساب بھی یہیں ہوتا ہے، بشمول اس نوٹ کے جو لیجر خود کسی Withdraw، کسی BridgeAttest یا ایگریگیٹر کی ادائیگی کے لیے اخذ کرتا ہے، جو وائر پر موجود نہیں ہوتا مگر اس کا بھی ٹکرانا ممنوع ہے۔ حجم کی حدود کسی بھی چیز کو ڈی کوڈ کرنے سے پہلے جانچی جاتی ہیں: چین کے max_proof_bytes (بطورِ طے شدہ 2 MiB، چین 20 پر 4 MiB) سے بڑا پروف، 16 KiB سے بڑی تصدیق، یا بلاک سے بڑی ٹرانزیکشن (max_block_bytes: بطورِ طے شدہ 4 MiB، چین 20 پر 20 MiB) سیدھے رد کر دی جاتی ہے، تاکہ کوئی حد سے بڑا بلاب کوئی کام نہ کروا سکے۔ سیلڈ (پرون شدہ) مارکر صورت میں بنڈل پروف بھی اسی مرحلے پر، سیلڈ صورت کی ہم آہنگی کے باہر، PrunedFormOutsideSync کے طور پر رد کیا جاتا ہے۔ پھر، اب بھی کسی چیز کی تصدیق کیے بغیر، پول پروف کے ہیڈرز پڑھتا ہے۔ تین پالیسیاں پہلے آتی ہیں: ایسی کال جس کا input، keccak یا sha256 ٹیبل 2^7 قطاروں سے کم ہو پول میں نہیں لی جاتی (CallRevealsPrivateInputs)، نہ ایسا ڈپلائے جسے کوئی کال سما نہ سکے (ProgramUncallable)، نہ ایسی ٹرانزیکشن جس کے بنڈل یا کال پروف کے ہیڈر میں کوئی ایسا فیلڈ ہو جو دیانت دار پروور نہ لکھتا (NonCanonicalProof)۔ آخری دو چین 20 پر hardening_v6 کے تحت لیجر کے قواعد بھی ہیں۔ v0.6.8 سے ایسا ہیڈر جس کا اعلان کردہ درجہ سب سے لمبے ٹیبل کی بالائی حد سے آگے ہو، جانچ کے اس پر چلنے سے پہلے ہی NonCanonicalProof کے طور پر رد ہو جاتا ہے (آڈٹ v6، ZKV-4)، اور اس ابتدائی چھان بین میں کہیں بھی panic ہو تو وہ اس ٹرانزیکشن کا انکار ہے (VerifierPanicked)، نوڈ کی موت نہیں۔ پھر کم از کم فیس: چین 20 پر پول وہ گیس حد ڈی کوڈ کرتا ہے جس کا اعلان کوئی کال یا invoke پروف کرتا ہے، اور سرے کی قیمتوں پر BUNDLE_BASE + gas_price × limit + byte_price × ⌈bytes/1024⌉، جمع invoke کی سیل فیس، سے کم فیس کو FeeTooLow کے طور پر رد کرتا ہے (فیسیں)۔ یہ بلاک کا اپنا قاعدہ ہے، اس لیے پول ٹھیک وہی مانگتا ہے جو بلاک مانگتا ہے۔
  5. مہنگا نصف، کنسینسس لوپ سے باہر۔ ٹرانزیکشن چار تصدیقی ورکرز میں سے کسی ایک کے لیے قطار میں ڈالی جاتی ہے، جس کی گہرائی زیادہ سے زیادہ 64 ہے۔ ورکر ایک بلاکنگ ٹاسک پر Ledger::validate کا باقی حصہ چلاتا ہے: بنڈل ڈائجسٹ، وہ گیس حد جس کا اعلان بنڈل پروف کرتا ہے (چین 20 پر ٹھیک 20,479، ورنہ BundleGasLimit)، بنڈل پروف اور، چین 17 سے، ٹرانزیکشن کی بائنڈنگ کے مقابل اس کا اجازتی پروف، اور کال کی صورت میں اس کا اپنا پروف اور اس کی کم از کم فیس۔ یہ توثیق سرے کی ایک ایسی نقل کے مقابل ہوتی ہے جو تاخیر سے، ہر سرے کی تبدیلی پر زیادہ سے زیادہ ایک بار اور صرف تب بنائی جاتی ہے جب کچھ انتظار میں ہو۔ گوسپ سے آئی ہوئی ٹرانزیکشن جسے قطار بھری ہوئی ملے، ووٹ دینے والے لوپ کو روکنے کے بجائے چھوڑ دی جاتی ہے، نہ اس کی تصدیق ہوتی ہے نہ اسے آگے بھیجا جاتا ہے؛ پیئر کا اگلا گوسپ دور اسے پھر لے آتا ہے۔
  6. دوبارہ جانچ اور پول میں شمولیت۔ insert_verified مرحلہ 4 کو اس سرے کے مقابل دوبارہ چلاتا ہے جس پر ٹرانزیکشن درحقیقت پول میں رکھی جا رہی ہے، کیونکہ پروف کی تصدیق کے دوران سرا آگے بڑھ چکا ہو سکتا ہے، پھر اسے داخلہ دیتا ہے اور، گوسپ سے آنے والی ٹریفک کی صورت میں، آگے بھیج دیتا ہے۔

مراحل 1 تا 4 Mempool::precheck ہیں؛ مرحلہ 5 واحد مرحلہ ہے جو کسی STARK کی تصدیق کرتا ہے۔ چونکہ یہ خرچ ایک ورکر پر ادا ہوتا ہے، اس لیے غلط پروفس کی بھرمار چار تھریڈز کو مصروف رکھتی ہے اور کنسینسس لوپ کو کبھی نہیں۔ ٹرانزیکشنز اور اقدامات میں لیجر کی اپنی داخلے کی ترتیب درج ہے، جسے مراحل 4 اور 5 مل کر چلاتے ہیں۔

گوسپ کے لیے دو محافظ اور ایک کیش

داخلے سے پہلے، دو چیزیں صرف پیئرز سے آنے والی ٹرانزیکشنز پر لاگو ہوتی ہیں؛ RPC کے ذریعے جمع کرائی گئی ٹرانزیکشنز انہیں چھوڑ دیتی ہیں، کیونکہ وہ پورٹ آپریٹر کا اپنا ہے اور درخواست کے باڈی کی حد سے پہلے ہی محدود ہے۔ RPC کا واحد راستہ جس پر پیمائش ہوتی ہے فوسیٹ ہے، جو نیچے بیان ہے۔

  • فی پیئر بائٹ میٹر۔ v0.6.8 سے ہر گوسپ فریم ڈی کوڈ ہونے سے پہلے ہی اسے آگے بھیجنے والے پیئر کے بائٹ بجٹ میں شمار کر لیا جاتا ہے۔ ہر پیئر زیادہ سے زیادہ ترسیلی سائز کے آٹھ فریم ایک ساتھ بھیج سکتا ہے، اور یہ گنجائش فی سیکنڈ دو فریموں کی شرح سے بحال ہوتی ہے۔ اس حد سے آگے فریم ڈی کوڈ کیے بغیر رد کر دیا جاتا ہے (آڈٹ v6، GOSSIP-1)۔ ٹرانزیکشن کی شناخت پورے ثبوت کا ہیش ہے، اس لیے اس کا حساب صرف آگے بھیجنے والے کی مقررہ گنجائش کے اندر ہی کیا جاتا ہے۔
  • فی پیئر ٹرانزیکشن میٹر۔ آگے بھیجنے والے ہر پیئر کے لیے ایک ٹوکن بکٹ ہے، برسٹ 16، اور فی سیکنڈ 4 کی شرح سے بحالی (PEER_TX_BURST, PEER_TX_PER_SEC)۔ یہ اس پیئر کو ناپتا ہے جس نے ٹرانزیکشن آگے بھیجی، اس کے مصنف کو نہیں، کیونکہ پوشیدہ چین مصنف کی شناخت نہیں کر سکتی۔
  • فیصلوں کا کیش۔ بعض ٹرانزیکشنز کو یہ نوڈ پہلے ہی کسی ایسی وجہ سے رد کر چکا ہوتا ہے جو صرف ان کے بائٹس پر منحصر ہو، جیسے غلط ثبوت، غلط دستخط یا حد سے بڑا کوئی حصہ۔ ایسی ٹرانزیکشن کی دوبارہ تصدیق نہیں کی جاتی، بلکہ اسے 8,192 اندراجات والے FIFO کیش (REFUSED_CACHE_ENTRIES) کی بنیاد پر دوبارہ رد کر دیا جاتا ہے۔ جو فیصلہ اس نوڈ کی حالت سے متعلق ہو، جیسے نامعلوم اینکر یا خرچ شدہ نلیفائر، وہ کبھی کیش نہیں کیا جاتا۔ ورنہ ایک بلاک پیچھے چلنے والا نوڈ ان ٹرانزیکشنز کو مستقل طور پر رد کرنے لگتا جو چند لمحوں میں درست ہونے والی ہیں۔ یہ فہرست اجازتی فہرست ہے، یعنی کوئی بھی نئی خرابی اس وقت تک حالت ہی شمار ہوتی ہے جب تک کوئی اس کے برعکس فیصلہ نہ کرے۔ درج ذیل اندراجات سے واضح ہوتا ہے کہ یہ حد کہاں سے گزرتی ہے:
    • BadPauseSignature (the pause signature does not verify) v0.6.8 سے مستقل نہیں ہے (آڈٹ v6، BRG-18)۔ یہ دستخط کو چین کی موجودہ توقف کلید کے تحت جانچتا ہے، اور برج قواعد v2 اس کلید کو بدل سکتے ہیں، اس لیے یہ حالت ہے۔ ورنہ کلید کی تبدیلی سے ایک بلاک پیچھے چلنے والا نوڈ نئے حامل کا PauseMints اس وقت تک رد کرتا رہتا جب تک اسے دوبارہ شروع نہ کیا جائے۔ اسی وجہ سے حد سے باہر PQ شریک دستخط کا اشاریہ بھی کیش سے نکال دیا گیا۔ v0.6.7 تک، یعنی چین 18 اور 19 پر، یہ دونوں مستقل کے طور پر کیش ہوتے تھے۔ اب غلط توقف کا ہر بار بار آنے والا پیغام ہر ترسیل پر ایک Dilithium2 تصدیق کی لاگت رکھتا ہے، اور اس لاگت کی حد فی پیئر میٹر طے کرتا ہے۔
    • PrunedFormOutsideSync جان بوجھ کر مستقل نہیں رکھا گیا۔ مہر بند بنڈل کی نشان شکل کا ہیش وہی ہوتا ہے جو خام ٹرانزیکشن کی اپنی شناخت ہے، اور کیش اسی شناخت کو کلید کے طور پر استعمال کرتا ہے۔ اس لیے اگر یہ رد کیش ہوتا تو کوئی بھی گوسپ پیئر دیانت دار ٹرانزیکشن کو پورے نیٹ ورک میں روک سکتا۔
    • کسی ثبوت کی اعلان کردہ گیس حد کا فیصلہ اس کے اپنے بائٹس کو جینیسس کی ایک مستقل قدر سے ملا کر ہوتا ہے، اس لیے BundleGasLimit اور AuthGasLimit مستقل ہیں۔ FeeTooLow مستقل نہیں، کیونکہ چین 20 پر فیس کی نچلی حد قیمتوں کے ساتھ بدلتی ہے۔ مرحلہ 4 کی تینوں ہیڈر پالیسیاں بھی کبھی کیش نہیں کی جاتیں، کیونکہ ہر ایک اس بلڈ کا علم ہے جسے بعد کا کوئی بلڈ بدل سکتا ہے۔
    • جس چین پر فاسیٹ کی اجازتی فہرست ہو (چین 20)، وہاں FaucetRecipientNotAllowed مستقل ہے، کیونکہ یہ اجرا کے اپنے وصول کنندہ کا موازنہ جینیسس کی ایک مستقل قدر سے کرتا ہے۔ FaucetBudgetExhausted مستقل نہیں: یہ حالت ہے، اور وہی اجرا اگلے ایپوک میں دوبارہ قبول ہو جاتا ہے۔
    • اسٹیکنگ عمل کے برعکس، ٹوکن عمل کا BadSignature بھی مستقل نہیں ہے۔ ٹوکن کا اجرائی اختیار حالت ہے، اور ایک SetAuthority اسے کسی دوسری کلید کے حوالے کر سکتا ہے۔ یوں وہی بائٹس اس تبدیلی کے کمٹ ہونے سے پہلے رد اور بعد میں قبول ہو سکتے ہیں۔ بائٹ کی سطح پر ٹوکن کے رد کیش کیے جاتے ہیں: غلط نام یا علامت، حد سے زیادہ اعشاری مقامات، صفر رقم، اور ٹوکن اشاریہ 0۔ اسی طرح یہ صورتیں بھی کیش ہوتی ہیں: ایسی برن فیلڈ جسے یہ عمل مقرر نہیں کر سکتا، ایسا اجرا جس کا کمٹمنٹ اس کی رقم پر نہیں کھلتا، اور ایسا برج ڈپازٹ جس کی بلائنڈنگ ماخوذ قدر نہیں ہے۔

فاسیٹ کی حد

rand_mint پر کوئی فیس نہیں لگتی اور ہر کال پول میں ایک ٹرانزیکشن کی جگہ لیتی ہے۔ چین 20 پر فاسیٹ فعال ہے اور اس کے پیچھے ایک برج میں قدر رکھی ہوئی ہے۔ جینیسس اس کے اختیارات کو محدود کرتا ہے۔ اجرا صرف اجازتی فہرست کے 16 والٹس کو ادائیگی کر سکتا ہے، اور ہر 1,000 بلاک کے ایپوک میں زیادہ سے زیادہ 10,000 RAND (اسٹیکنگ)۔ اس پر صرف جینیسس کی 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 یا رجسٹریشن اشاریہ چین پیچھے چھوڑ چکی ہو، اور پرانے نانس والا توقف یا لسٹنگ بھی۔ v0.6.8 سے یہ ہر کال اور انووک کی فیس ان قیمتوں پر دوبارہ جانچتا ہے جو اس سرے پر نافذ ہیں جس پر بلاک بن رہا ہے۔ اس کے لیے داخلے کے وقت محفوظ کی گئی گیس حد استعمال ہوتی ہے، اور جس ٹرانزیکشن کی فیس اب اپنی نچلی حد سے کم ہو اسے بلاک سے باہر رکھا جاتا ہے۔ ایسی ٹرانزیکشن پول میں رہتی ہے اور قیمتیں گرنے پر دوبارہ پیش کی جاتی ہے (آڈٹ v6، CH-9)۔ چین 20 پر باقی ٹرانزیکشنز کی ترتیب یہ ہے: پہلے گورننس، پھر ٹرانزیکشن کے فی KiB موجودہ نچلی حد سے اوپر کی فیس، پھر فیس، سب سے زیادہ پہلے، اور برابری کی صورت میں فیصلہ ہیش سے۔ یوں ایک ہی پول پر بلاک بنانے والا ہر دیانت دار تجویز کنندہ ایک ہی بلاک چنتا ہے۔ بلاک 2,000 ٹرانزیکشنز اور چین کی بلاک حد کے بجٹ تک بھرا جاتا ہے (MAX_BLOCK_TXS؛ max_block_bytes، جو بطور طے شدہ 4 MiB اور چین 20 پر 20 MiB ہے)۔ بلاک میں کمی بائٹس ہی کی ہوتی ہے، اسی لیے اضافی فیس کا حساب فی KiB کیا جاتا ہے۔ جس چین میں gas سیکشن نہ ہو، یا جس نوڈ کی کوئی گیس پالیسی نہ ہو، وہ اس معیار کو چھوڑ کر گورننس، فیس اور ہیش کے لحاظ سے ترتیب دیتا ہے، جیسا کہ چین 15 پر ہوتا تھا۔ گورننس کو پہلے رکھنا توقف کی ضمانت کا دوسرا نصف ہے۔ PauseMints ڈیزائن کے تحت کوئی فیس ادا نہیں کرتا، کیونکہ اسے ایسے والٹ سے بھی کام کرنا ہوتا ہے جس میں کوئی RAND نہ ہو۔ اس لیے سادہ فیس کی ترتیب اس ہنگامی بریک کو ہر فیس ادا کرنے والی ٹرانزیکشن کے پیچھے دھکیل دیتی۔

جب کوئی کال یا انووک تیار ہو تو ایک اور قاعدہ لاگو ہوتا ہے (آڈٹ v6، POOL-2؛ یہ ہر چین پر نوڈ کی پالیسی ہے، درستی کا قاعدہ نہیں)۔ بائٹ کی قیمت صرف یہی ادا کرتے ہیں، جبکہ اپنی مقررہ بنیادی فیس سے تھوڑا زیادہ ادا کرنے والی منتقلی فی KiB درجہ بندی میں ان سے آگے نکل جاتی ہے۔ یوں منتقلیوں کا مسلسل سلسلہ کسی تیار کال کو ہر بلاک سے باہر رکھ سکتا تھا۔ اس لیے پہلے مرحلے میں مقررہ فیس والی ٹرانزیکشنز بلاک کے زیادہ سے زیادہ تین چوتھائی بائٹس لیتی ہیں۔ کالز رکھ دیے جانے کے بعد جو جگہ بچے، اسے روکی گئی منتقلیوں سے ان کی ترتیب کے مطابق بھر دیا جاتا ہے۔ بلاک کی کوئی جگہ ضائع نہیں ہوتی، اور اگر کوئی کال تیار نہ ہو تو کچھ نہیں بدلتا (فیس)۔

جو ٹرانزیکشن باقی جگہ کے لیے بہت بڑی ہو، اسے چھوڑ دیا جاتا ہے، لیکن اس سے بلاک کی تشکیل ختم نہیں ہوتی: اس کے پیچھے کوئی چھوٹی ٹرانزیکشن پھر بھی شامل ہو سکتی ہے۔ چین 18 کی ایک منتقلی تقریباً 2.85 MB کی ہوتی ہے، یعنی 1.49 MB کا بنڈل ثبوت اور 1.36 MB کا اجازتی ثبوت۔ اس لیے اس کے 20 MiB بلاک میں تقریباً سات منتقلیوں کی گنجائش ہے اور طے شدہ 4 MiB بلاک میں ایک کی۔ چین 15 پر فی منتقلی تقریباً 1.43 MB تھی، اس لیے انہی 20 MiB میں چودہ منتقلیاں سماتی تھیں۔ بوجھ کے وقت فیس ہی طے کرتی ہے کہ کون سی ٹرانزیکشنز شامل ہوں گی (فیس)۔

چھانٹی

ہر کمٹ کے بعد prune پول سے ٹھیک وہی ٹرانزیکشنز نکال دیتا ہے جنہیں candidates_within چھوڑ دیتا۔ ان میں وہ ٹرانزیکشنز شامل ہیں جن کا نوٹ کوئی اور خرچ کر چکا ہو، جن کا کمٹمنٹ اب موجود ہو، جن کا نانس یا رجسٹریشن اشاریہ چین پیچھے چھوڑ چکی ہو، یا جن کا اینکر یا 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 میں تعداد، بائٹس اور سب سے پرانی ٹرانزیکشن کی عمر ہی واحد ذرائع ہیں، اور ایکسپلورر صرف کمٹ شدہ بلاکس کو انڈیکس کرتا ہے۔

آخری بار 2026-10-12 کو fullnode کمٹ c0878c3f (چین 21)، اور fullnode v0.6.8 `c9c9bd3c` (chain 20): `crates/randprotocol-node/src/mempool.rs` (`MAX_POOL_BLOCKS`, `make_room`, `is_governance`, the call reservation in `candidates_within`), the commits for CH-7, CH-9, POOL-2, BRG-18, GOSSIP-1 and ZKV-4, and `rand_getLimits` on chain 20, fullnode v0.6.7 `86941a1`: `crates/randprotocol-node/src/mempool.rs`, `admission.rs`, `crates/randprotocol-core/src/ledger/mod.rs` (the gas floor), fullnode `90e7716`: `docs/architecture.md` §8, `docs/rpc.md` (changelog, the 2026-09-28 gas entries), fullnode `ed88241`: `docs/confidential.md` (transaction binding) کے مقابل تصدیق کی گئی۔ جہاں کوڈ اور یہ صفحہ ایک دوسرے سے مختلف ہوں، وہاں کوڈ درست ہے؛ ہمیں مطلع کریں۔