ملخص
عمليات فحص وقت التشغيل بعد كل تعليمة: المالك فقط يمكنه خصم lamports أو تعديل البيانات، يمكن للبيانات أن تنمو بحد أقصى 10 كيلوبايت لكل تعليمة، تغييرات المالك تتطلب بيانات مهيأة بالصفر، وعلامة قابل للتنفيذ غير قابلة للإلغاء.
يفرض وقت تشغيل سولانا هذه القواعد بعد تنفيذ كل تعليمة عبر طرق
BorrowedInstructionAccount.
يتم فحص كل قاعدة عند نقطة التعديل، ويتم التراجع عن المعاملة إذا فشل أي فحص.
قواعد lamports
| القاعدة | الإنفاذ | الخطأ |
|---|---|---|
| المالك فقط يمكنه خصم lamports | set_lamports(): يفحص is_owned_by_current_program() عندما lamports < current | ExternalAccountLamportSpend |
| الحسابات للقراءة فقط لا يمكن تغيير lamports الخاصة بها | set_lamports(): يفحص is_writable() | ReadonlyLamportChange |
| أي برنامج يمكنه إضافة lamports إلى حساب قابل للكتابة | set_lamports(): فحص الملكية ينطبق فقط عندما يكون الرصيد الجديد أقل من الرصيد الحالي؛ فحص القابلية للكتابة لا يزال ينطبق | ReadonlyLamportChange |
| يجب أن تتوازن lamports عبر التعليمة | TransactionContext::pop(): يتحقق من get_lamports_delta() == 0 | UnbalancedInstruction |
قواعد البيانات
| القاعدة | الإنفاذ | الخطأ |
|---|---|---|
| المالك فقط يمكنه تعديل البيانات | can_data_be_changed(): يفحص is_owned_by_current_program() | ExternalAccountDataModified |
| الحسابات للقراءة فقط لا يمكن تعديل بياناتها | can_data_be_changed(): يفحص is_writable() | ReadonlyDataModified |
| المالك فقط يمكنه تغيير حجم البيانات | can_data_be_resized(): يفحص is_owned_by_current_program() عندما new_len != old_len | AccountDataSizeChanged |
| الحد الأقصى لحجم البيانات: 10 ميجابايت | TransactionAccounts::can_data_be_resized(): يفحص new_len <= MAX_ACCOUNT_DATA_LEN | InvalidRealloc |
| الحد الأقصى للنمو لكل تعليمة: 10 كيلوبايت | إلغاء التسلسل في deserialize_parameters_aligned(): يفحص post_len - pre_len <= MAX_PERMITTED_DATA_INCREASE | InvalidRealloc |
| الحد الأقصى للنمو لكل معاملة: 20 ميجابايت | TransactionAccounts::can_data_be_resized(): يفحص التراكمي resize_delta <= MAX_ACCOUNT_DATA_GROWTH_PER_TRANSACTION | MaxAccountsDataAllocationsExceeded |
قواعد المالك
| القاعدة | التطبيق | الخطأ |
|---|---|---|
| المالك الحالي فقط يمكنه إعادة تعيين المالك | set_owner(): يتحقق من is_owned_by_current_program() | ModifiedProgramId |
| يجب أن يكون الحساب قابلاً للكتابة | set_owner(): يتحقق من is_writable() | ModifiedProgramId |
| يجب أن تكون البيانات مهيأة بالصفر | set_owner(): يتحقق من is_zeroed(data) | ModifiedProgramId |
قواعد علامة القابلية للتنفيذ
| القاعدة | التطبيق | الخطأ |
|---|---|---|
| يجب أن يكون الحساب معفى من الإيجار | set_executable(): يتحقق من rent.is_exempt(lamports, data_len) | ExecutableAccountNotRentExempt |
| المالك فقط يمكنه تعيين العلامة | set_executable(): يتحقق من is_owned_by_current_program() | ExecutableModified |
| يجب أن يكون الحساب قابلاً للكتابة | set_executable(): يتحقق من is_writable() | ExecutableModified |
تحولات حالة الإيجار
تتواجد الحسابات في واحدة من ثلاث قيم
RentState:
Uninitialized (0 lamports)، RentPaying (أعلى من 0 ولكن أقل من الحد
الأدنى للإعفاء من الإيجار)، و RentExempt (عند الحد الأدنى أو أعلى منه).
التحولات غير المسموح بها تنتج TransactionError::InsufficientFundsForRent.
يطبق وقت التشغيل هذه القواعد عبر
transition_allowed():
- يمكن لأي حساب الانتقال إلى
Uninitialized(إغلاق) أوRentExempt. - لا يمكن لأي حساب الدخول إلى
RentPayingمنUninitializedأوRentExempt. يجب أن تكون جميع الحسابات الجديدة معفاة من الإيجار.
قواعد استعارة الحساب
أثناء تنفيذ التعليمات، يطبق وقت التشغيل دلالات استعارة الكاتب الواحد على
الحسابات. يمكن للبرنامج الحصول على مرجع قابل للتعديل واحد أو عدة مراجع غير قابلة
للتعديل لحساب، ولكن ليس كليهما في نفس الوقت. إذا حاول برنامج استعارة حساب مستعار
بالفعل بشكل قابل للتعديل (أو استعارة حساب بشكل قابل للتعديل مستعار بالفعل بشكل
غير قابل للتعديل)، تفشل التعليمة مع AccountBorrowFailed عبر
try_borrow()
و
try_borrow_mut().
إذا اكتملت تعليمة بينما لا تزال الاستعارة قائمة، يعيد وقت التشغيل
AccountBorrowOutstanding في
TransactionContext::pop().
Is this page helpful?