|
| 1 | +# Runtime Spec Version 25 Changes |
| 2 | + |
| 3 | +This document outlines all interface changes between runtime spec version 24 and 25, focusing on structural refactoring of the permission system to move instance management into individual permission scopes. |
| 4 | + |
| 5 | +## Extrinsics |
| 6 | + |
| 7 | +No extrinsic signatures were changed in this version. The permission0 pallet maintains the same external interface with internal restructuring only. |
| 8 | + |
| 9 | +## Events |
| 10 | + |
| 11 | +No event changes were made in this version. |
| 12 | + |
| 13 | +## Storage Items |
| 14 | + |
| 15 | +No storage item changes were made in this version. A migration (v7) handles the internal restructuring of existing data. |
| 16 | + |
| 17 | +## Structs & Enums |
| 18 | + |
| 19 | +### `permission0::PermissionContract<T>` |
| 20 | + |
| 21 | +```diff |
| 22 | + pub struct PermissionContract<T: Config> { |
| 23 | + pub delegator: T::AccountId, |
| 24 | + pub scope: PermissionScope<T>, |
| 25 | + pub duration: PermissionDuration<T>, |
| 26 | + pub revocation: RevocationTerms<T>, |
| 27 | + pub enforcement: EnforcementAuthority<T>, |
| 28 | + pub last_update: BlockNumberFor<T>, |
| 29 | + pub last_execution: Option<BlockNumberFor<T>>, |
| 30 | + pub execution_count: u32, |
| 31 | +- pub max_instances: u32, |
| 32 | +- pub children: BoundedBTreeSet<PermissionId, T::MaxChildrenPerPermission>, |
| 33 | + pub created_at: BlockNumberFor<T>, |
| 34 | + } |
| 35 | +``` |
| 36 | + |
| 37 | +The `max_instances` and `children` fields have been removed from the main contract structure and moved into the individual permission scope types that require them (CuratorScope and NamespaceScope). This architectural change better encapsulates scope-specific functionality and eliminates unnecessary fields for stream permissions which don't use instance management. See [Instance Management Refactoring](#instance-management-refactoring). |
| 38 | + |
| 39 | +### `permission0::CuratorScope<T>` |
| 40 | + |
| 41 | +```diff |
| 42 | + pub struct CuratorScope<T: Config> { |
| 43 | + pub recipient: T::AccountId, |
| 44 | + pub flags: BoundedBTreeMap< |
| 45 | + Option<PermissionId>, |
| 46 | + CuratorPermissions, |
| 47 | + T::MaxCuratorSubpermissionsPerPermission, |
| 48 | + >, |
| 49 | + pub cooldown: Option<BlockNumberFor<T>>, |
| 50 | ++ pub max_instances: u32, |
| 51 | ++ pub children: BoundedBTreeSet<PermissionId, T::MaxChildrenPerPermission>, |
| 52 | + } |
| 53 | +``` |
| 54 | + |
| 55 | +The curator scope now directly contains instance management fields, allowing curator permissions to manage their own hierarchical relationships and instance limits independently. See [Scope-Specific Instance Management](#scope-specific-instance-management). |
| 56 | + |
| 57 | +### `permission0::NamespaceScope<T>` |
| 58 | + |
| 59 | +```diff |
| 60 | + pub struct NamespaceScope<T: Config> { |
| 61 | + pub recipient: T::AccountId, |
| 62 | + pub paths: BoundedBTreeMap< |
| 63 | + Option<PermissionId>, |
| 64 | + BoundedBTreeSet<NamespacePath, T::MaxNamespacesPerPermission>, |
| 65 | + T::MaxNamespacesPerPermission, |
| 66 | + >, |
| 67 | ++ pub max_instances: u32, |
| 68 | ++ pub children: BoundedBTreeSet<PermissionId, T::MaxChildrenPerPermission>, |
| 69 | + } |
| 70 | +``` |
| 71 | + |
| 72 | +Similar to curator permissions, namespace permissions now maintain their own instance tracking and children collections, enabling proper encapsulation of hierarchical permission structures. See [Scope-Specific Instance Management](#scope-specific-instance-management). |
| 73 | + |
| 74 | +### `permission0::PermissionContract<T>::new()` signature |
| 75 | + |
| 76 | +```diff |
| 77 | + pub(crate) fn new( |
| 78 | + delegator: T::AccountId, |
| 79 | + scope: PermissionScope<T>, |
| 80 | + duration: PermissionDuration<T>, |
| 81 | + revocation: RevocationTerms<T>, |
| 82 | + enforcement: EnforcementAuthority<T>, |
| 83 | +- max_instances: u32, |
| 84 | + ) -> Self |
| 85 | +``` |
| 86 | + |
| 87 | +The constructor no longer accepts `max_instances` as a parameter since this is now managed within the individual scope structures, simplifying permission creation for stream permissions which don't require instance management. |
| 88 | + |
| 89 | +## Behavior Changes |
| 90 | + |
| 91 | +### Instance Management Refactoring |
| 92 | + |
| 93 | +**What changed**: Instance management (max_instances and children tracking) has been moved from the PermissionContract level into the specific permission scopes that require it (CuratorScope and NamespaceScope). The PermissionContract methods `max_instances()`, `available_instances()`, `used_instances()`, `children()`, and `children_mut()` now return `Option` types and delegate to the underlying scope implementations. |
| 94 | + |
| 95 | +**Why it matters**: This refactoring improves the architecture by eliminating unnecessary fields for stream permissions, which don't use instance management. It creates better separation of concerns where each permission type manages only the data it needs, reducing storage overhead for stream permissions and making the codebase more maintainable. |
| 96 | + |
| 97 | +**Migration needed**: The v7 migration automatically restructures existing permissions by moving the max_instances and children fields from the contract level into the appropriate scope structures. No manual intervention is required. |
| 98 | + |
| 99 | +*Tests*: Migration validated through comprehensive tests in `pallets/permission0/src/migrations.rs::v7` ensuring all permission types are correctly transformed. |
| 100 | + |
| 101 | +*Cross-pallet impact*: None. The external API remains unchanged, and other pallets interact with permissions through the same interface. |
| 102 | + |
| 103 | +### Scope-Specific Instance Management |
| 104 | + |
| 105 | +**What changed**: CuratorScope and NamespaceScope now directly manage their instance limits and children collections. The cleanup logic for removing children from parent permissions when a permission is revoked has been updated to use the new `children_mut()` method that safely accesses the children collection only when present in the scope. |
| 106 | + |
| 107 | +**Why it matters**: This change creates a cleaner separation where only permission types that support hierarchical delegation (curator and namespace) carry the overhead of tracking instances and children. Stream permissions, which are flat structures, no longer carry unnecessary instance-related data. |
| 108 | + |
| 109 | +**Migration needed**: Handled automatically by the v7 migration. Existing permissions are restructured to move instance data into the appropriate scope types. |
| 110 | + |
| 111 | +*Tests*: Instance management behavior is validated through existing permission delegation and revocation tests. |
| 112 | + |
| 113 | +*Cross-pallet impact*: None. The changes are internal to the permission0 pallet structure. |
| 114 | + |
| 115 | +### Dynamic Instance Updates for Namespace Permissions |
| 116 | + |
| 117 | +**What changed**: The `update_namespace_permission` function now correctly updates the max_instances field within the NamespaceScope rather than at the PermissionContract level. The validation logic checks parent permissions' available instances and ensures that reducing instances doesn't invalidate existing child permissions. |
| 118 | + |
| 119 | +**Why it matters**: This ensures that instance management for namespace permissions works correctly with the new structure where instances are tracked at the scope level. The change maintains the same external behavior while operating on the restructured internal data. |
| 120 | + |
| 121 | +**Migration needed**: None. This is an internal implementation change that maintains the same external behavior. |
| 122 | + |
| 123 | +*Tests*: Instance update validation tested through namespace permission update tests ensuring proper parent-child instance tracking. |
| 124 | + |
| 125 | +*Cross-pallet impact*: None. The external behavior of updating namespace permissions remains unchanged. |
| 126 | + |
| 127 | +### Optional Instance Methods |
| 128 | + |
| 129 | +**What changed**: The methods `max_instances()`, `available_instances()`, and `children()` on PermissionContract now return `Option` types instead of direct values. These methods return `Some(value)` for curator and namespace permissions that support instances, and `None` for stream permissions that don't. |
| 130 | + |
| 131 | +**Why it matters**: This change makes the API more explicit about which permission types support instance management, preventing incorrect assumptions about stream permissions having instance limits. It provides compile-time safety for code that works with instance management. |
| 132 | + |
| 133 | +**Migration needed**: None. Internal implementation detail. |
| 134 | + |
| 135 | +*Tests*: Method behavior validated through permission contract unit tests. |
| 136 | + |
| 137 | +*Cross-pallet impact*: None. These are internal methods not exposed through the pallet's external API. |
0 commit comments