وقت تشغيل الحساب

ملخص

قبل التنفيذ، يقوم وقت التشغيل بتحميل الحسابات، والتحقق من صحة دافع الرسوم، وفحص الإعفاء من الإيجار، وتسلسل بيانات الحساب في تخطيط ذاكرة يمكن للبرامج الوصول إليه.

تغطي هذه الصفحة التفاصيل الداخلية لوقت التشغيل. معظم المطورين لا يحتاجون هذه المعلومات لبناء البرامج. راجع بنية الحساب للحصول على العرض الموجه للمطورين.

تحميل الحساب

قبل تنفيذ المعاملة، يقوم وقت التشغيل بتحميل جميع الحسابات المشار إليها عبر load_transaction_accounts(). تقوم هذه العملية بإجراء عدة عمليات تحقق:

  1. التحقق من صحة دافع الرسوم: يجب أن يكون دافع الرسوم (الحساب الأول) موجودًا، وأن يكون حساب نظام أو حساب nonce، وأن يحتوي على ما يكفي من lamports لتغطية الرسوم (validate_fee_payer()). بعد دفع الرسوم، يجب أن يظل الحساب معفى من الإيجار أو ينتقل إلى 0 lamports بالضبط. لا يمكن أن ينتهي بين 0 والحد الأدنى للإعفاء من الإيجار. يجب أن تحتفظ حسابات nonce دائمًا بما يكفي من lamports لتظل معفاة من الإيجار. إذا لم يكن الدافع حساب نظام ولا حساب nonce، تفشل المعاملة مع TransactionError::InvalidAccountForFee.

  2. حد حجم البيانات المحملة: يجب ألا يتجاوز الحجم الإجمالي لجميع الحسابات المحملة (بما في ذلك TRANSACTION_ACCOUNT_BASE_SIZE بمقدار 64 بايت لكل حساب) MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES (64 ميجابايت). يؤدي تجاوز هذا الحد إلى TransactionError::MaxLoadedAccountsDataSizeExceeded.

  3. التحقق من صحة حساب البرنامج: يجب أن يكون كل برنامج يتم استدعاؤه بواسطة تعليمة موجودًا ومملوكًا لمحمل صالح: أحد PROGRAM_OWNERS (BPF Loader Upgradeable، BPF Loader، BPF Loader Deprecated، Loader V4) أو المحمل الأصلي. إذا لم يكن حساب البرنامج موجودًا، تفشل المعاملة مع TransactionError::ProgramAccountNotFound. إذا كان موجودًا ولكن لديه مالك غير صالح، تفشل المعاملة مع TransactionError::InvalidProgramForExecution.

  4. الحسابات غير الموجودة: يتم تحميل الحسابات التي لا توجد على السلسلة كحسابات افتراضية (0 لامبورت، بيانات فارغة، مملوكة لبرنامج النظام) مع تعيين rent_epoch إلى u64::MAX.

تنسيق تسلسل BPF

عند استدعاء برنامج، يقوم وقت التشغيل بتسلسل الحسابات في مخزن ذاكرة متجاور ويمرره إلى BPF VM. يتم تعريف تنسيق التسلسل (للتنسيق المحاذي القياسي المستخدم من قبل جميع المحملات باستثناء loader-v1 المهمل) في serialize_parameters_aligned().

يبدأ المخزن بـ u64 (8 بايتات، little-endian) يحتوي على عدد الحسابات. ثم، لكل حساب في التعليمة، يحتوي المخزن على:

الإزاحةالحجمالحقلالنوع
01علامة التكرارu8 (0xFF = فريد، الفهرس = نسخة من ذلك الحساب)
11is_signeru8 (0 أو 1)
21is_writableu8 (0 أو 1)
31executableu8 (0 أو 1)
44original_data_len (محجوز، دائماً 0)[0u8; 4]
832keyPubkey
4032ownerPubkey
728lamportsu64 (little-endian)
808data_lenu64 (little-endian)
88data_lendata[u8]
88 + data_len10240 + paddingمساحة إعادة التخصيص + المحاذاةمملوء بالأصفار إلى MAX_PERMITTED_DATA_INCREASE (10 كيلوبايت) + حشو للمحاذاة إلى BPF_ALIGN_OF_U128 (8 بايتات)
...8rent_epochu64 (little-endian)

بعد جميع الحسابات، يضيف المخزن المؤقت:

الحجمالحقل
8instruction_data_len (u64، little-endian)
instruction_data_leninstruction_data
32program_id (Pubkey)

بالنسبة للحسابات المكررة، يتم كتابة بايت واحد فقط (علامة التكرار مع فهرس الحساب الأصلي) بالإضافة إلى 7 بايتات من الحشو.

إلغاء تكرار الحسابات

عندما يظهر نفس المفتاح العام للحساب عدة مرات في مصفوفة accounts الخاصة بالتعليمة، يقوم وقت التشغيل بإلغاء تكرارها. يحصل كل إدخال في قائمة حسابات التعليمة على بنية InstructionAccount خاصة به، لكن الإدخالات التي تشير إلى نفس الحساب على مستوى المعاملة تشير إلى نفس البيانات الأساسية.

تحدد طريقة is_instruction_account_duplicate ما إذا كان فهرس حساب التعليمة المحدد هو الظهور الأول أم مكرر من خلال البحث عن فهرس الحساب على مستوى المعاملة وإيجاد أول فهرس على مستوى التعليمة يرتبط به:

  • إذا كان فهرس حساب التعليمة الحالي يساوي الفهرس المرتبط الأول، فهو ليس مكرراً (يُرجع None).
  • وإلا، يُرجع Some(first_index)، حيث first_index هو فهرس الظهور الأول.

نظراً لأن جميع المراجع لنفس الحساب تشترك في نفس AccountSharedData الأساسي، فإن التعديلات من خلال أي مرجع تكون مرئية فوراً من خلال جميع المراجع الأخرى. ومع ذلك، يمكن الاحتفاظ باستعارة قابلة للتعديل واحدة فقط في كل مرة. محاولة استعارة نفس الحساب بشكل قابل للتعديل من خلال فهرسين مختلفين لحساب التعليمة في وقت واحد تُرجع InstructionError::AccountBorrowFailed. يجب على البرامج إسقاط استعارة واحدة قبل الحصول على أخرى على نفس الحساب الأساسي.

بعد تنفيذ البرنامج، يقوم وقت التشغيل بإلغاء تسلسل المخزن المؤقت (deserialize_parameters_aligned()) ويطبق أي تغييرات على lamports و data (بما في ذلك تغييرات الطول حتى MAX_PERMITTED_DATA_INCREASE) و owner.

Is this page helpful?

جدول المحتويات

تعديل الصفحة

تدار بواسطة

© 2026 مؤسسة سولانا.
جميع الحقوق محفوظة.
تواصل معنا