cryptofoundry

الاتصال بـ cryptofoundry

أخبرنا بما تريد بناءه أو أتمتته.

البريد الإلكتروني
[email protected]
ADAMANT Messenger
فتح في ADAMANT
Developers & API

نشر المعاملات، التوحيد، التحقق، والبث على عقد ADAMANT

الوظائف

Transaction.prototype.verify تتحقق من معاملة مسترجعة من كتل أخرى، والتي قد تشمل معاملات قديمة. Transactions.prototype.publish تتحقق من المعاملات الواردة من المستخدمين، وتُستخدم للتحقق من معاملات جديدة غير مؤكدة. وتُستدعى verify أيضًا بعد استلام معاملة جديدة من الواجهة البرمجية API، بعد طرائق publish وobjectNormalize. وتُستدعى publish فقط عند دفع المعاملات عبر الواجهة البرمجية العامة API.

معالجة المعاملات

عندما تتلقى عقدة معاملة جديدة من تطبيق عميل عبر الواجهة البرمجية API كأول عقدة تراها، تقوم Logic->Transaction.prototype.publish بإنشاء معاملة جديدة من البيانات المستلمة، وتتحقق من خصائص معاملة العميل (بما في ذلك timestampMs)، وتُضيف معرّف المعاملة ID، ثم تعالج المعاملة غير المؤكدة كما هو معتاد. إذا تلقت العقدة معاملة جديدة من ند آخر عند الارتفاع الحالي، فإنها تتحقق من صحة المعاملة وتحذف الند في حال كانت غير صالحة، ثم تعالج المعاملة غير المؤكدة. عند جلب معاملة من ند آخر أثناء الارتفاع أو التحقق من السلسلة الكتلية من الارتفاع 0، تقوم العقدة بالتحقق من صحة المعاملة، وتحذف الند في حال كانت غير صالحة، ثم تعالج المعاملة غير المؤكدة أثناء التحقق من عدة معاملات في وقت واحد. يتضمن التحقق استدعاء العقدة لـ objectNormalize() للتحقق من صحة المخطط schema للصفقة المستلمة.

تبدأ عملية معالجة المعاملة غير المؤكدة بـ logic.transaction.process()، والتي تتحقق من معرّف المعاملة وتوحّد معرّف المرسل. بعد ذلك، تُوحّد المعاملة: logic.transaction.objectNormalize() تتحقق من كائن المعاملة مقابل المخطط schema وتُزيل الخصائص غير الضرورية، بما في ذلك timestampMs قبل تفعيل spaceship. أخيرًا، تُستدعى logic.transaction.verify() للتحقق من جميع الخصائص مثل timestamp وtimestampMs وsignature.

إزالة ند تعني حذفه من قائمة الندود حتى يُعاد اكتشافه؛ لا تقوم العقد بحظر الندود، وبالتالي لا يُطبّق أبدًا الحالة BANNED. تقوم العقدة ببث المعاملة إلى العقد الأخرى بعد معالجة المعاملة غير المؤكدة. بالإضافة إلى objectNormalize()، تمتلك العقدة normalize()، والتي تُستخدم فقط لنقطة النهاية POST /transactions/normalize التي ينبغي إيقاف دعمها. تمتلك العقدة كلاً من apply() وapplyUnconfirmed() لأن طرائق “apply” تغيّر أرصدة حسابات المرسل والمستقبل، بينما تغيّر applyUnconfirmed() الرصيد غير المؤكد؛ وينطبق الشيء نفسه على طرائق “undo”. عندما تولّد العقدة كتلة جديدة، تُؤخذ المعاملات من قائمة تم التحقق منها مسبقًا. حاليًا، تتحقق publish() مما إذا كان زمن المعاملة في المستقبل أو أكثر من constants.maxTransactionAgeSec ثانية في الماضي. لا فائدة من إضافة نفس الشروط في publish كما في verify لأن الطريقة الأخيرة يجب أن تُستدعى بعد publish. أيضًا، لا يمكن تضمين شروط publish في verify لأنها تعتمد على الوقت الحالي، مما يجعل من المستحيل التحقق مما إذا كانت معاملة قديمة تقل عن 5 ثوانٍ. سيتلقى تطبيق العميل رسائل خطأ مثل The difference between timestamp and timestampMs is greater than ${maxTimestampMsDelta}ms. أو Invalid transaction timestamp. Timestamp is not in the int32 range إذا لم تكن هذه الشروط في publish() بل في verify().

ملاحظات حول الزمن النقطي

الزمن النقطي timestamp للصفقة هو زمن حقبة ADAMANT بالثواني، وليس زمن Unix. يجب أن يكون الزمن النقطي timestampMs زمن حقبة ADAMANT بالميللي ثانية، وليس زمن Unix؛ يمكن اشتقاق زمن Unix بالميللي ثانية عبر constants.epochTime.getTime() + timestampMs. لا يُعد حقل timestampMs جزءًا من بايتات المعاملة، أو التوقيعات، أو معرّفات المعاملات، أو الهاشات، حتى بعد تفعيل spaceship. بعد spaceship، يجب أن تتطلب التحقق الحساس للإجماع أن يكون timestampMs في نفس ثانية حقبة ADAMANT كما timestamp: 0 <= timestampMs - timestamp * 1000 < 1000. هذه القاعدة الأشد (نفس الثانية) مقصودة: يجب أن يُحسّن timestampMs نفس الثانية الدقيقة من حقبة ADAMANT المخزنة في timestamp، وينبغي للعملاء حساب timestamp = Math.floor(timestampMs / 1000). إن استخدام Math.round() أو Math.ceil() قرب حدود الثانية يُنتج زوجًا غير متسق ويجب رفضه. أظهرت مراجعة العملاء الحاليين والمصادر أن adamant-api-jsclient، وPWA، وadamant-console (عبر [email protected])، وiOS، وأمثلة الوثائق تستخدم جميعها Math.floor أو اختزالًا مكافئًا، ولا توجد أي مسار لإنشاء زمن معاملة ADM صادرة يستخدم round أو ceil. قبل spaceship، يجب أن يزيل التوحيد الحساس للإجماع timestampMs ليبقى السلوك قبل التفعيل متوافقًا مع العقد الأقدم. يُسمح بوجود معاملات متعددة من نفس المرسل خلال ثانية واحدة طالما أنها معاملات مختلفة؛ يساعد timestampMs العملاء على ترتيب رسائل الدردشة السريعة، لكنه لا يجب أن يصبح رقمًا تسلسليًا للمعاملة أو مدخلًا للتوقيع.

الشروط عند القبول

تحتوي الطريقة publish() على شروط قبول للواجهة البرمجية العامة API للمعاملات المقدمة حديثًا، والتي قد تعتمد على ساعة العقدة الحالية. إذا نجحت المعاملة في publish()، فإنها ما زالت تُعالج عبر verify()، التي لا تحتوي عمداً على شرط زمني حالي، ويجب أن تحتفظ فقط بالشروط الحتمية مثل المخطط، والمعرّف، والتوقيعات، والأرصدة، وقاعدة نفس الثانية لـ timestampMs. لا يجب نقل الشروط الزمنية الحالية من publish() إلى verify() لأن verify() تُستخدم في إعادة التشغيل، والتزامن، والمعاملات التاريخية. الشرط الحالي للتحقق من المستقبل يعتمد على الفتحات: مع فتحات 5 ثوانٍ، فإن عميلًا يسبق بحوالي 400 مللي ثانية فقط يسبب خطأ Transaction timestamp is in the future عندما يتقاطع الزمن بالثواني المدوّر إلى الفتحة التالية. maxTransactionFutureMs هو تسامح غير حاسم في قبول الواجهة البرمجية العامة API يُطبّق فقط في publish()، وليس في إعادة التشغيل، أو التحقق من الند/الكتلة، أو منطق تفعيل الإجماع. الشرط المقصود يحافظ على سياسة القبول القديمة المعتمدة على الفتحات مع تليين الحالة الحدية عن طريق رفض المعاملة فقط عندما يكون transactionSlotNumber > currentSlotNumber ويكون زمن المعاملة متقدمًا أكثر من maxTransactionFutureMs على زمن العقدة الحالي. لحساب هذا، استخدم timestampMs إذا قدمه العميل؛ وإلا عد إلى timestamp * 1000. يمكن أن تحسّن مهلة صغيرة غير حاسمة في publish() (مثلاً، 500 مللي ثانية للفتحة التالية) تجربة المستخدم لأجهزة العميل السريعة قليلاً دون تغيير التحقق من إعادة التشغيل، رغم أنه ينبغي للتطبيقات العميلة أن تحتفظ بمهلة زمنية صغيرة للتوافق مع العقد الأقدم. يمكن تضمين معاملة زمنها timestamp متقدمًا بثانية واحدة عن الكتلة الحالية ضمن تلك الكتلة دون إتلاف السلسلة الكتلية، لأن timestamp المعاملة هو بيانات وصفية موقعة، وليس مصدرًا لصلاحية الفتحة أو الكتلة، ولا يتطلب الإجماع tx.timestamp <= block.timestamp. أثناء إعادة التشغيل، لا تقوم العقد بمقارنة الأزمنة النقطية للمعاملات مع الزمن المحلي الفعلي، وبالتالي لا يمكن أن تسبب مهلة القبول تباينًا في إعادة التشغيل.

نقطة النهاية Status

قد تُرجع نقطة النهاية /api/node/status حقول زمن إضافية مثل nodeTimestampMs (ميللي ثواني حقبة ADAMANT) وunixTimestampMs دون تأثير على الإجماع. يبقى nodeTimestamp زمن حقبة ADAMANT بالثواني.

ارتفاعات التفعيل

ينبغي أن تكون ارتفاعات التفعيل الحاسمة قابلة للتكوين على شبكة الاختبار وعلى السلاسل المستندة إلى ADAMANT، مع الحفاظ على الإعدادات الافتراضية للشبكة الرئيسية في الكود أو التهيئة. استخدم الفحص التاريخي fairSystemActivateBlock: 4359464 الشرط height > fairSystemActivateBlock، وبالتالي فإن الارتفاع النشط الأول المكافئ لتفعيل fairSystem المسمّى هو 4,359,465. ينبغي أن يُفعّل spaceship فقط السلوك الحساس للإجماع مثل قبول، وتوحيد، وتخزين، والتحقق من timestampMs أثناء معالجة الكتلة، والند، وإعادة التشغيل. الشروط النسبية للساعة في publish() هي سياسة قبول ويجب أن تبقى خارج تفعيل الإجماع.