أحداث WebSocket للعملاء للكتل والأرصدة في ADAMANT Node
نظرة عامة
يدعم ADAMANT Node الآن إمكانيَّتي WebSocket اختياريتين للعملاء: أحداث newBlock للكتل المُطبَّقة والمحفوظة بنجاح، وأحداث balances/change لتحديثات balance و unconfirmedBalance المؤكَّدة. يستخدم التنفيذ Socket.IO بدلاً من اتصال WebSocket مجرَّد. الاشتراكات محدَّدة بنطاق مقبس واحد ويجب استعادتها بعد إعادة الاتصال.
يتناول التنفيذ Node issue #256 وNode issue #217، مع توثيق في Adamant-im/docs#35 وعقد مرافق بصيغة OpenAPI في Adamant-im/adamant-schema#48.
أحداث الكتل الجديدة
يُفعِّل العملاء إشعارات الكتل صراحةً عن طريق إرسال blocks: true. تحتوي حمولة newBlock على رأس عام مدمج: معرِّف الكتلة، والارتفاع، والطابع الزمني، والمفتاح العام للمولِّد، وعدد المعاملات، والمبلغ الإجمالي، والرسوم الإجمالية، والمكافأة. تتعمَّد حذف قائمة المعاملات والتواقيع وتجزئة الحمولة؛ ويمكن للعملاء طلب الكتلة الكاملة عبر REST عند الحاجة.
connection.emit('blocks', true);
connection.on('newBlock', (block) => {
console.log('Applied block:', block);
});
لا تُصدر العقدة هذا الحدث إلا بعد نجاح خط أنابيب تطبيق الكتلة بالكامل وحفظ الكتلة. لا تُنتج إعادة التشغيل التاريخية وإعادة بناء جداول الذاكرة أحداث كتل حية.
أحداث تغيُّر الأرصدة
يتطلَّب تسليم الرصيد اشتراكاً في العنوان واشتراكاً صريحاً في الحقل. تحتوي الحمولة فقط على الحقول المشترَك فيها التي تغيَّرت، مع قيم كسلاسل عشرية بوحدات 1/10^8 ADM.
connection.emit('address', ['U1234567890123456']);
connection.emit('balances', ['balance', 'unconfirmedBalance']);
connection.on('balances/change', (account) => {
console.log('Balance changed:', account);
});
يمثِّل balance حالة سلسلة الكتل المؤكَّدة. ويعكس unconfirmedBalance أيضاً مجموعة المعاملات غير المؤكَّدة الحالية في العقدة، وقد يتغيَّر عند قبول المعاملات أو تأكيدها أو انتهائها أو التراجع عنها أو إعادة التحقق منها.
تصميم التسليم والأداء
كان الهدف الرئيسي إضافة أحداث مفيدة دون تحويل كل تغيير في الحساب إلى مسح لكل مقبس متصل أو قراءة قاعدة بيانات غير ضرورية. تختار الفهارس المخصَّصة للكتل والأرصدة لكل عنوان فقط المقابس المهتمة، وتتخطى العقدة قراءات الحساب عندما لا يحتاج أي مشترك إلى العنوان والحقل المتغيِّر. تُجمِّع عملية تطبيق الكتلة والتراجع عنها تغييرات الأرصدة الداخلية وتُجري قراءة حساب نهائية واحدة لكل عنوان متغيِّر. يُثبَّت كبت الدُفعات المتداخلة حتى يُغلق الدفعة الخارجية، مما يمنع النشر الجزئي بعد فشل داخلي. تُثبِّط عملية تطبيق الكتلة الفاشلة، والتراجع الفاشل، وإعادة التشغيل، وإعادة البناء، واقتطاع اللقطة المكتمل، جميعها إشعارات الأرصدة غير الدائمة. تُعزل مطابقة المقابس، والبحث عن الحساب، وحالات فشل الإرسال لكل مقبس عن معالجة الكتل والجولات والحسابات. لا تُنشر تغييرات مكافآت الجولات إلا بعد اكتمال عملية جولة دائمة.
لا تُعدِّل هذه التغييرات قواعد الإجماع، أو تسلسل الكتل والمعاملات، أو التواقيع، أو المعرِّفات، أو مخططات قاعدة البيانات، أو المكافآت، أو الرسوم، أو سلوك بروتوكول الأقران.
دلالات الأحداث بأفضل جهد
هذه الأحداث إشعارات منخفضة الكمون، وليست سجل أحداث دائم. قد يفوت العملاء أحداث أثناء انقطاع الاتصال ويجب عليهم التوفيق بين الحالات المهمة عبر REST. لا ترسل اشتراكات الأرصدة لقطة أولية، وقد تكتمل قراءات الأرصدة غير المتزامنة بترتيب مختلف أثناء التحديثات المستقلة السريعة. تُكبَت معرِّفات المعاملات والكتل المكرَّرة لمدة 60 ثانية على الأقل، مع تنظيف دوري يوسِّع النافذة الفعَّالة إلى دقيقتين تقريباً. إذا تراجعت كتلة وأُعيد تطبيق نفس المعرِّف داخل تلك النافذة، فقد يُكبَت الإشعار الثاني.
يتطابق تمثيل سلسلة الرصيد الحالية عمداً مع سلوك REST؛ والقيم الدقيقة خارج نطاق الأعداد الصحيحة الآمنة في JavaScript تتطلَّب تغييراً منسَّقاً على مستوى واجهة برمجة التطبيقات بدلاً من تباعد خاص بـ WebSocket فقط. لم يُدخل سقف اشتراك صامت تعسُّفي لكل مقبس. لا تحتوي واجهة برمجة التطبيقات الحالية على آلية إقرار للرفض الجزئي، لذا يجب أن يكون حد الموارد عقداً منفصلاً قابلاً للتهيئة والتوثيق مع تغذية راجعة صريحة من العميل.
التحقق
تضمَّن التحقق 226 اختبار عقدة ناجحاً موجَّهاً للميزات يغطِّي مسارات WebSocket والحساب والمعاملة والكتلة والجولة، بالإضافة إلى اختبارات تراجع متابعة مركَّزة لكبت اللقطات والتخلُّص من الدُفعات المتداخلة. اجتازت مجموعة اختبارات الوحدة السريعة الأوسع 940 اختباراً. غطَّت الفحوصات الإضافية ESLint، وبناء توثيق VitePress للإنتاج، وتنسيق OpenAPI والتحقق من الحزمة، وتغطية تكامل Socket.IO الفعلية لتسليم الكتل والأرصدة. تُركَت مجموعات الاختبارات طويلة التشغيل غير المرتبطة عمداً لأن هذه الميزة لا تُغيِّر التحقق من الإجماع، أو التسلسل، أو SQL، أو نقل الأقران، أو نقاط نهاية REST.