أعتقد أننا غالبًا ما نطرح السؤال الخاطئ عندما تفشل معاملة “Dusk”.
مجرد الحصول على 202 Accepted فقط يعني أن العقدة قبلت الطلب للتوجيه. ولا يعني ذلك أن المعاملة موجودة بالفعل في mempool أو ضمن كتلة. مثال وجدته مثيرًا للاهتمام هو nonce مستقبلي. إذا وصلت معاملة Moonlight بــ nonce مستقبلي بينما كان nonce سابق لا يزال مفقودًا، يمكن لـ Dusk إبقاؤها خارج الـ real mempool والانتظار حتى يُغلق فجوة الـ nonce بدلًا من رفضها فورًا. تحصل عندها على حالة مؤجلة.
هذا جزء واحد فقط من القصة. بعد اجتياز المعاملة لمرحلة القبول، تدخل الـ mempool المحلية لتلك العقدة. تحتفظ العقد الأخرى بمراكز mempool الخاصة بها وتجري أيضًا فحوصات القبول الخاصة بها. لاحقًا، يمكن اختيار المعاملة لكتلة، وتنفيذها، وفي النهاية يتم إتمامها (finalized). كما يمكنها مغادرة الـ mempool المحلية دون أن يعني ذلك تلقائيًا أنها فشلت. يمكن أن تؤدي الإتاحة (Expiry) والاستبدال (replacement) وحدود السعة والتعارضات جميعها إلى الإزالة.
وهنا أرى أن الفرق يهم للـ wallets و exchanges. توجيه التكامل الخاص بـ Dusk يقول للاحتفاظ بالمعاملة الموقعة نفسها حرفيًا، ومعاملة 202 Accepted على أنها نجاح توجيه فقط، ثم إعادة بثّ نفس البايتات الموقعة بعد مهلة انتهاء النقل (transport timeout) بدلًا من إنشاء معاملة جديدة بشكل أعمى. يجب اعتبار عملية السحب مكتملة فقط بعد التحقق من تنفيذها وأن الكتلة قد اكتملت.
كلما نظرت أكثر، قلّ شعوري بأن عبارة “transaction submitted” تبدو حالة مفيدة بذاتها. يمكن أن تكون المعاملة تنتظر nonce، أو تكون موجودة في الـ mempool لإحدى العقد، أو تُنفَّذ مع خطأ، أو تكون متواجدة في كتلة غير مكتملة بعد. هذه حالات مختلفة جدًا، حتى لو كانت جميعها قد تبدو من الخارج وكأنها “لا تزال معلّقة”.
بالنسبة لي، هذه هي الخلاصة المفيدة من تدفق معاملات Dusk: submitted هو البداية فقط. الأهم هو حالة يمكنك إثباتها فعليًا أن المعاملة وصلت إليها.
$DUSK @Dusk #dusk
مجرد الحصول على 202 Accepted فقط يعني أن العقدة قبلت الطلب للتوجيه. ولا يعني ذلك أن المعاملة موجودة بالفعل في mempool أو ضمن كتلة. مثال وجدته مثيرًا للاهتمام هو nonce مستقبلي. إذا وصلت معاملة Moonlight بــ nonce مستقبلي بينما كان nonce سابق لا يزال مفقودًا، يمكن لـ Dusk إبقاؤها خارج الـ real mempool والانتظار حتى يُغلق فجوة الـ nonce بدلًا من رفضها فورًا. تحصل عندها على حالة مؤجلة.
هذا جزء واحد فقط من القصة. بعد اجتياز المعاملة لمرحلة القبول، تدخل الـ mempool المحلية لتلك العقدة. تحتفظ العقد الأخرى بمراكز mempool الخاصة بها وتجري أيضًا فحوصات القبول الخاصة بها. لاحقًا، يمكن اختيار المعاملة لكتلة، وتنفيذها، وفي النهاية يتم إتمامها (finalized). كما يمكنها مغادرة الـ mempool المحلية دون أن يعني ذلك تلقائيًا أنها فشلت. يمكن أن تؤدي الإتاحة (Expiry) والاستبدال (replacement) وحدود السعة والتعارضات جميعها إلى الإزالة.
وهنا أرى أن الفرق يهم للـ wallets و exchanges. توجيه التكامل الخاص بـ Dusk يقول للاحتفاظ بالمعاملة الموقعة نفسها حرفيًا، ومعاملة 202 Accepted على أنها نجاح توجيه فقط، ثم إعادة بثّ نفس البايتات الموقعة بعد مهلة انتهاء النقل (transport timeout) بدلًا من إنشاء معاملة جديدة بشكل أعمى. يجب اعتبار عملية السحب مكتملة فقط بعد التحقق من تنفيذها وأن الكتلة قد اكتملت.
كلما نظرت أكثر، قلّ شعوري بأن عبارة “transaction submitted” تبدو حالة مفيدة بذاتها. يمكن أن تكون المعاملة تنتظر nonce، أو تكون موجودة في الـ mempool لإحدى العقد، أو تُنفَّذ مع خطأ، أو تكون متواجدة في كتلة غير مكتملة بعد. هذه حالات مختلفة جدًا، حتى لو كانت جميعها قد تبدو من الخارج وكأنها “لا تزال معلّقة”.
بالنسبة لي، هذه هي الخلاصة المفيدة من تدفق معاملات Dusk: submitted هو البداية فقط. الأهم هو حالة يمكنك إثباتها فعليًا أن المعاملة وصلت إليها.
$DUSK @Dusk #dusk