آخر مرة أضفت إيداعًا إلى البورصة، نسخت العنوان ثم راجعت memo مرتين أيضًا، خشيةً أن تصل العملات لكن لا تستطيع البورصة التعرف أنها تخصني. لاحقًا، بعد قراءة وثائق تكامل البورصة الخاصة بـ @Dusk ، اكتشفت أن متطلبات Dusk لواجهة الإيداع في الخلفية أدق من مجرد “إدخال الملاحظة الصحيحة”. أولًا تختار نموذج الحساب العام Moonlight، ثم تقرر هل يكون لكل شخص حسابه الخاص، أو حساب مشترك مع memo.
إذا كان الحساب مشتركًا، فـ memo مهم فقط لإخبار النظام “من يجب أن تُنسب له هذه الأموال”، لكنه غير مناسب ليكون الدليل الوحيد لمنع الإدخالات المكررة. قد يخطئ مستخدمان في إدخال نفس memo، وقد تُعاد معالجة نفس البيانات إذا تمت إعادة تشغيل الخلفية. لذلك توصي الوثائق الرسمية باستخدام معرّف معاملة Dusk كـ idempotency key. وبعبارة بسيطة: هذه هي “قفل يُسجل كل إيداع مرة واحدة فقط”. #dusk
وهناك حالة حدودية يسهل تجاهلها: لا ينبغي للبورصة أن ترى زيادة رصيد Moonlight ثم تُضيف الرصيد للمستخدم فورًا. يجب عليها أن تفحص من سجل الإحالات المحفوظ (المؤرشف) الذي أصبح نهائيًا، وتحوّل التحويلات المباشرة فقط، ثم—إذا كانت memo مفقودة أو بصيغتها غير صحيحة أو غير معروفة أو كانت مكررة—يجب وضع الإيداعات في منطقة عزل بدلًا من افتراض أنها تلقائيًا تُضاف للحساب.
والتفصيل الأعمق: كتابة سجل الإيداع في الخلفية والتقدم في فحص “نقطة التحقق” لِـ بلوكات يجب أن يتم في نفس معاملة قاعدة البيانات. إذا تقدمت بنقطة التحقق قبل الإيداع ثم تعطلّت الخدمة، فقد تتجاوز أموال المستخدم. وإذا تم تسجيل الإيداع بدون حفظ التقدم، فقد يُعاد فحص نفس الأشياء عند إعادة المسح فتتم معالجتها مرتين. كذلك تحويل Phoenix، ودفع العقود، وسحب الرهن يجب أن تُضبط لها قواعد أحداث منفصلة، ولا ينبغي خلطها مع “الإيداع العادي”.
هذه المنطق يشبه مستودع الشحن: memo مثل ملصق المستلم، ومعرّف المعاملة هو رقم بوليصة الشحن غير المكرر، وfinalized يعني أن الطرد أصبح مؤكدًا بالفعل وتم إدخاله في المستودع. النظر إلى واحد فقط قد يسبب فقد طرد أو تسليمًا مكررًا.
لذلك عندما راجعت تكيف البورصة لِـ $DUSK ، لم أنظر فقط إلى “هل يمكن الإيداع/السحب”، بل أيضًا: هل يمكن للخلفية أن تنفّذ بعد التحقق النهائي الإدخال في الحساب، ومنع تكرار transaction ID، وتزامن نقطة التحقق والدفتر (账本) معًا في معاملة واحدة. التجربة المالية الحقيقية ليست أن واجهة المستخدم تدور بسرعة كبيرة، بل أن إعادة تشغيل الخلفية وإعادة المسح لن تمنح المستخدم أبدًا أكثر أو أقل من سنت واحد. #dusk
إذا كان الحساب مشتركًا، فـ memo مهم فقط لإخبار النظام “من يجب أن تُنسب له هذه الأموال”، لكنه غير مناسب ليكون الدليل الوحيد لمنع الإدخالات المكررة. قد يخطئ مستخدمان في إدخال نفس memo، وقد تُعاد معالجة نفس البيانات إذا تمت إعادة تشغيل الخلفية. لذلك توصي الوثائق الرسمية باستخدام معرّف معاملة Dusk كـ idempotency key. وبعبارة بسيطة: هذه هي “قفل يُسجل كل إيداع مرة واحدة فقط”. #dusk
وهناك حالة حدودية يسهل تجاهلها: لا ينبغي للبورصة أن ترى زيادة رصيد Moonlight ثم تُضيف الرصيد للمستخدم فورًا. يجب عليها أن تفحص من سجل الإحالات المحفوظ (المؤرشف) الذي أصبح نهائيًا، وتحوّل التحويلات المباشرة فقط، ثم—إذا كانت memo مفقودة أو بصيغتها غير صحيحة أو غير معروفة أو كانت مكررة—يجب وضع الإيداعات في منطقة عزل بدلًا من افتراض أنها تلقائيًا تُضاف للحساب.
والتفصيل الأعمق: كتابة سجل الإيداع في الخلفية والتقدم في فحص “نقطة التحقق” لِـ بلوكات يجب أن يتم في نفس معاملة قاعدة البيانات. إذا تقدمت بنقطة التحقق قبل الإيداع ثم تعطلّت الخدمة، فقد تتجاوز أموال المستخدم. وإذا تم تسجيل الإيداع بدون حفظ التقدم، فقد يُعاد فحص نفس الأشياء عند إعادة المسح فتتم معالجتها مرتين. كذلك تحويل Phoenix، ودفع العقود، وسحب الرهن يجب أن تُضبط لها قواعد أحداث منفصلة، ولا ينبغي خلطها مع “الإيداع العادي”.
هذه المنطق يشبه مستودع الشحن: memo مثل ملصق المستلم، ومعرّف المعاملة هو رقم بوليصة الشحن غير المكرر، وfinalized يعني أن الطرد أصبح مؤكدًا بالفعل وتم إدخاله في المستودع. النظر إلى واحد فقط قد يسبب فقد طرد أو تسليمًا مكررًا.
لذلك عندما راجعت تكيف البورصة لِـ $DUSK ، لم أنظر فقط إلى “هل يمكن الإيداع/السحب”، بل أيضًا: هل يمكن للخلفية أن تنفّذ بعد التحقق النهائي الإدخال في الحساب، ومنع تكرار transaction ID، وتزامن نقطة التحقق والدفتر (账本) معًا في معاملة واحدة. التجربة المالية الحقيقية ليست أن واجهة المستخدم تدور بسرعة كبيرة، بل أن إعادة تشغيل الخلفية وإعادة المسح لن تمنح المستخدم أبدًا أكثر أو أقل من سنت واحد. #dusk

