From 2c2d8b5119cb9e64d591fffd7f74efb907be61b0 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 8 Jul 2021 16:50:14 +0200 Subject: [PATCH 01/49] feat: initial commit --- .../delegation/src/delegation_hierarchy.rs | 100 +++------ pallets/delegation/src/lib.rs | 202 +++++++----------- 2 files changed, 116 insertions(+), 186 deletions(-) diff --git a/pallets/delegation/src/delegation_hierarchy.rs b/pallets/delegation/src/delegation_hierarchy.rs index 3de5d465f5..1a02be1b2a 100644 --- a/pallets/delegation/src/delegation_hierarchy.rs +++ b/pallets/delegation/src/delegation_hierarchy.rs @@ -18,6 +18,8 @@ use bitflags::bitflags; use codec::{Decode, Encode}; +use ctype::CtypeHashOf; +use sp_std::collections::btree_set::BTreeSet; use crate::*; @@ -52,87 +54,51 @@ impl Default for Permissions { } } -/// A node representing a delegation hierarchy root. #[derive(Clone, Debug, Encode, Decode, PartialEq)] -pub struct DelegationRoot { - /// The hash of the CTYPE that delegated attesters within this trust - /// hierarchy can attest. - pub ctype_hash: CtypeHashOf, - /// The identifier of the root owner. - pub owner: DelegatorIdOf, - /// The flag indicating whether the root has been revoked or not. - pub revoked: bool, -} - -impl DelegationRoot { - pub fn new(ctype_hash: CtypeHashOf, owner: DelegatorIdOf) -> Self { - DelegationRoot { - ctype_hash, - owner, - revoked: false, - } - } +pub struct DelegationNode { + pub hierarchy_id: DelegationHierarchyIdOf, + pub parent: Option>, + pub children: BTreeSet>, + pub details: DelegationDetails, } -/// A node representing a node in the delegation hierarchy. #[derive(Clone, Debug, Encode, Decode, PartialEq)] -pub struct DelegationNode { - /// The ID of the delegation hierarchy root. - pub root_id: DelegationNodeIdOf, - /// \[OPTIONAL\] The ID of the parent node. If None, the node is - /// considered a direct child of the root node. - pub parent: Option>, - /// The identifier of the owner of the delegation node, i.e., the delegate. +pub struct DelegationDetails { pub owner: DelegatorIdOf, - /// The permission flags for the operations the delegate is allowed to - /// perform. - pub permissions: Permissions, - /// The flag indicating whether the delegation has been revoked or not. pub revoked: bool, + pub permissions: Permissions, } impl DelegationNode { - /// Create a new delegation node that is a direct descendent of the - /// given root. - /// - /// * root_id: the root node ID this node will be a child of - /// * owner: the identifier of the owner of the new delegation, i.e., the - /// new delegate - /// * permissions: the permission flags for the operations the delegate is - /// allowed to perform - pub fn new_root_child(root_id: DelegationNodeIdOf, owner: DelegatorIdOf, permissions: Permissions) -> Self { - DelegationNode { - root_id, - owner, - permissions, - revoked: false, + pub fn new_root_node(hierarchy_id: DelegationHierarchyIdOf, owner: DelegatorIdOf) -> Self { + Self { + hierarchy_id, parent: None, + children: BTreeSet::new(), + details: DelegationDetails { + owner, + revoked: false, + permissions: Permissions::all(), + }, } } - /// Creates a new delegation node that is a direct descendent of the - /// given node. - /// - /// * root_id: the root node ID this node will be a child of - /// * parent - the parent node ID this node will be a child of - /// * owner: the identifier of the owner of the new delegation, i.e., the - /// new delegate - /// * permissions: the permission flags for the operations the delegate is - /// allowed to perform - pub fn new_node_child( - root_id: DelegationNodeIdOf, - parent: DelegationNodeIdOf, - owner: DelegatorIdOf, - permissions: Permissions, - ) -> Self { - DelegationNode { - root_id, - parent: Some(parent), - owner, - permissions, - revoked: false, - } + pub fn new_node(hierarchy_id: DelegationHierarchyIdOf, parent: DelegationNodeIdOf, owner: DelegatorIdOf, permissions: Permissions) -> Self { + let mut new_node = Self::new_root_node(hierarchy_id, owner); + new_node.parent = Some(parent); + new_node.details.permissions = permissions; + + new_node } + + pub fn add_child(&mut self, child_id: DelegationNodeIdOf) { + self.children.insert(child_id); + } +} + +#[derive(Clone, Debug, Encode, Decode, Eq, PartialEq, Ord, PartialOrd)] +pub struct DelegationHierarchyInfo { + pub ctype_hash: CtypeHashOf, } /// The result that the delegation pallet expects from the implementer of the diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 467326a062..a4b0623feb 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -49,6 +49,11 @@ pub mod pallet { /// Type of a delegation node identifier. pub type DelegationNodeIdOf = ::DelegationNodeId; + /// Type of a delegation hierarchy identifier. + /// + /// Currently, it is just equivalent to the ID of the root node of a given hierarchy. + pub type DelegationHierarchyIdOf = DelegationNodeIdOf; + /// Type of a delegator or a delegate. pub type DelegatorIdOf = ::DelegationEntityId; @@ -70,7 +75,7 @@ pub mod pallet { Signature = Vec, >; type DelegationEntityId: Parameter; - type DelegationNodeId: Parameter + Copy + AsRef<[u8]>; + type DelegationNodeId: Parameter + Copy + AsRef<[u8]> + Eq + PartialEq + Ord + PartialOrd; type EnsureOrigin: EnsureOrigin, ::Origin>; type Event: From> + IsType<::Event>; #[pallet::constant] @@ -89,45 +94,37 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet {} - /// Delegation root nodes stored on chain. - /// - /// It maps from a root node ID to the full root node. - #[pallet::storage] - #[pallet::getter(fn roots)] - pub type Roots = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, DelegationRoot>; - /// Delegation nodes stored on chain. /// - /// It maps from a node ID to the full delegation node. + /// It maps from a node ID to the node details. #[pallet::storage] - #[pallet::getter(fn delegations)] - pub type Delegations = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, DelegationNode>; + #[pallet::getter(fn delegation_nodes)] + pub type DelegationNodes = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, DelegationNode>; - /// Children delegation nodes. + /// Delegation hierarchies stored on chain. /// - /// It maps from a delegation node ID, including the root node, to the list - /// of children nodes, sorted by time of creation. + /// It maps from a hierarchy ID to the hierarchy details. #[pallet::storage] - #[pallet::getter(fn children)] - pub type Children = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, Vec>>; + #[pallet::getter(fn delegation_hierarchies)] + pub type DelegationHierarchies = StorageMap<_, Blake2_128Concat, DelegationHierarchyIdOf, DelegationHierarchyInfo>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - /// A new root has been created. - /// \[creator ID, root node ID, CTYPE hash\] - RootCreated(DelegatorIdOf, DelegationNodeIdOf, CtypeHashOf), - /// A root has been revoked. - /// \[revoker ID, root node ID\] - RootRevoked(DelegatorIdOf, DelegationNodeIdOf), + /// A new hierarchy has been created. + /// \[creator ID, hierarchy ID, CTYPE hash\] + HierarchyCreated(DelegatorIdOf, DelegationHierarchyIdOf, CtypeHashOf), + /// A hierarchy has been revoked. + /// \[revoker ID, hierarchy ID\] + HierarchyRevoked(DelegatorIdOf, DelegationHierarchyIdOf), /// A new delegation has been created. - /// \[creator ID, root node ID, delegation node ID, parent node ID, + /// \[creator ID, hierarchy ID, delegation node ID, parent node ID, /// delegate ID, permissions\] DelegationCreated( DelegatorIdOf, + DelegationHierarchyIdOf, DelegationNodeIdOf, DelegationNodeIdOf, - Option>, DelegatorIdOf, Permissions, ), @@ -147,17 +144,17 @@ pub mod pallet { DelegationNotFound, /// No delegate with the given ID stored on chain. DelegateNotFound, - /// There is already a root node with the same ID stored on chain. - RootAlreadyExists, - /// No root delegation with the given ID stored on chain. - RootNotFound, + /// There is already a hierarchy with the same ID stored on chain. + HierarchyAlreadyExists, + /// No hierarchy with the given ID stored on chain. + HierarchyNotFound, /// Max number of nodes checked without verifying the given condition. MaxSearchDepthReached, /// Max number of nodes checked without verifying the given condition. NotOwnerOfParentDelegation, /// The delegation creator is not allowed to write the delegation /// because he is not the owner of the delegation root node. - NotOwnerOfRootDelegation, + NotOwnerOfDelegationHierarchy, /// No parent delegation with the given ID stored on chain. ParentDelegationNotFound, /// The delegation revoker is not allowed to revoke the delegation. @@ -186,14 +183,14 @@ pub mod pallet { /// * root_id: the ID of the root node. It has to be unique /// * ctype_hash: the CTYPE hash that delegates can use for attestations #[pallet::weight(::WeightInfo::create_root())] - pub fn create_root( + pub fn create_hierarchy( origin: OriginFor, - root_id: DelegationNodeIdOf, + hierarchy_id: DelegationHierarchyIdOf, ctype_hash: CtypeHashOf, ) -> DispatchResult { let creator = ::EnsureOrigin::ensure_origin(origin)?; - ensure!(!>::contains_key(&root_id), Error::::RootAlreadyExists); + ensure!(!>::contains_key(&hierarchy_id), Error::::HierarchyAlreadyExists); ensure!( >::contains_key(&ctype_hash), @@ -201,9 +198,12 @@ pub mod pallet { ); log::debug!("insert Delegation Root"); - >::insert(&root_id, DelegationRoot::new(ctype_hash, creator.clone())); + let root_node = DelegationNode::new_root_node(hierarchy_id, creator.clone()); + let hierarchy_info = DelegationHierarchyInfo:: { ctype_hash }; + >::insert(&hierarchy_id, root_node); + >::insert(&hierarchy_id, hierarchy_info); - Self::deposit_event(Event::RootCreated(creator, root_id, ctype_hash)); + Self::deposit_event(Event::HierarchyCreated(creator, hierarchy_id, ctype_hash)); Ok(()) } @@ -231,8 +231,8 @@ pub mod pallet { pub fn add_delegation( origin: OriginFor, delegation_id: DelegationNodeIdOf, - root_id: DelegationNodeIdOf, - parent_id: Option>, + hierarchy_id: DelegationHierarchyIdOf, + parent_id: DelegationNodeIdOf, delegate: DelegatorIdOf, permissions: Permissions, delegate_signature: DelegateSignatureTypeOf, @@ -240,7 +240,7 @@ pub mod pallet { let delegator = ::EnsureOrigin::ensure_origin(origin)?; // Calculate the hash root - let hash_root = Self::calculate_hash(&delegation_id, &root_id, &parent_id, &permissions); + let hash_root = Self::calculate_hash(&delegation_id, &hierarchy_id, &Some(parent_id), &permissions); // Verify that the hash root signature is correct. DelegationSignatureVerificationOf::::verify(&delegate, &hash_root.encode(), &delegate_signature) @@ -250,56 +250,36 @@ pub mod pallet { })?; ensure!( - !>::contains_key(&delegation_id), + !>::contains_key(&delegation_id), Error::::DelegationAlreadyExists ); - let root = >::get(&root_id).ok_or(Error::::RootNotFound)?; - - // Computes the delegation parent. Either the given parent (if allowed) or the - // root node. - let parent = if let Some(parent_id) = parent_id { - let parent_node = >::get(&parent_id).ok_or(Error::::ParentDelegationNotFound)?; - - // Check if the parent's delegate is the creator of this delegation node... - ensure!(parent_node.owner == delegator, Error::::NotOwnerOfParentDelegation); - // ... and has permission to delegate - ensure!( - (parent_node.permissions & Permissions::DELEGATE) == Permissions::DELEGATE, - Error::::UnauthorizedDelegation - ); - - log::debug!("insert Delegation with parent"); - >::insert( - &delegation_id, - DelegationNode::::new_node_child(root_id, parent_id, delegate.clone(), permissions), - ); - - // Return parent_id as the result of this if branch - parent_id - } else { - // Check if the creator of this delegation node is the creator of the root node - // (as no parent is given) - ensure!(root.owner == delegator, Error::::NotOwnerOfRootDelegation); - - log::debug!("insert Delegation without parent"); - >::insert( - &delegation_id, - DelegationNode::::new_root_child(root_id, delegate.clone(), permissions), - ); - - // Return node_id as the result of this if branch - root_id - }; + let mut parent_node = >::get(&parent_id).ok_or(Error::::ParentDelegationNotFound)?; - // Regardless of the node returned as parent, add the new node as a child of - // that node - Self::add_child(delegation_id, parent); + // Check if the parent's delegate is the creator of this delegation node... + ensure!(parent_node.details.owner == delegator, Error::::NotOwnerOfParentDelegation); + // ... and has permission to delegate + ensure!( + (parent_node.details.permissions & Permissions::DELEGATE) == Permissions::DELEGATE, + Error::::UnauthorizedDelegation + ); + + log::debug!("insert Delegation with parent"); + >::insert( + &delegation_id, + DelegationNode::new_node(hierarchy_id, parent_id, delegate.clone(), permissions) + ); + // Add the new node as a child of that node + parent_node.add_child(delegation_id); + >::insert( + &parent_id, + parent_node + ); Self::deposit_event(Event::DelegationCreated( delegator, delegation_id, - root_id, + hierarchy_id, parent_id, delegate, permissions, @@ -322,37 +302,38 @@ pub mod pallet { /// * max_children: the maximum number of nodes descending from the root /// to revoke as a consequence of the root revocation #[pallet::weight(::WeightInfo::revoke_root(*max_children))] - pub fn revoke_root( + pub fn revoke_hierarchy( origin: OriginFor, - root_id: DelegationNodeIdOf, + hierarchy_id: DelegationHierarchyIdOf, max_children: u32, ) -> DispatchResultWithPostInfo { let invoker = ::EnsureOrigin::ensure_origin(origin)?; - let mut root = >::get(&root_id).ok_or(Error::::RootNotFound)?; + let mut hierarchy_root = >::get(&hierarchy_id).ok_or(Error::::HierarchyNotFound)?; - ensure!(root.owner == invoker, Error::::UnauthorizedRevocation); + ensure!(hierarchy_root.details.owner == invoker, Error::::UnauthorizedRevocation); ensure!( max_children <= T::MaxRevocations::get(), Error::::MaxRevocationsTooLarge ); - let consumed_weight: Weight = if !root.revoked { + let consumed_weight: Weight = if !hierarchy_root.details.revoked { // Recursively revoke all children - let (_, post_weight) = Self::revoke_children(&root_id, &invoker, max_children)?; + let (_, post_weight) = Self::revoke_children(&hierarchy_id, &invoker, max_children)?; // If we didn't return an ExceededRevocationBounds error, we can revoke the root // too. - root.revoked = true; - >::insert(&root_id, root); + hierarchy_root.details.revoked = true; + >::insert(&hierarchy_id, hierarchy_root); + // We don't cancel the delegation_hierarchy from storage. post_weight.saturating_add(T::DbWeight::get().writes(1)) } else { 0 }; - Self::deposit_event(Event::RootRevoked(invoker, root_id)); + Self::deposit_event(Event::HierarchyRevoked(invoker, hierarchy_id)); Ok(Some(consumed_weight.saturating_add(T::DbWeight::get().reads(1))).into()) } @@ -389,7 +370,7 @@ pub mod pallet { let invoker = ::EnsureOrigin::ensure_origin(origin)?; ensure!( - >::contains_key(&delegation_id), + >::contains_key(&delegation_id), Error::::DelegationNotFound ); @@ -451,12 +432,12 @@ impl Pallet { delegation: &DelegationNodeIdOf, max_parent_checks: u32, ) -> Result<(bool, u32), DispatchError> { - let delegation_node = >::get(delegation).ok_or(Error::::DelegationNotFound)?; + let delegation_node = >::get(delegation).ok_or(Error::::DelegationNotFound)?; // Check if the given account is the owner of the delegation and that the // delegation has not been removed - if &delegation_node.owner == identity { - Ok((!delegation_node.revoked, 0u32)) + if &delegation_node.details.owner == identity { + Ok((!delegation_node.details.revoked, 0u32)) } else { // Counter is decreased regardless of whether we are checking the parent node // next of the root node, as the root node is as a matter of fact the top node's @@ -467,16 +448,10 @@ impl Pallet { if let Some(parent) = delegation_node.parent { // Recursively check upwards in hierarchy - Self::is_delegating(identity, &parent, remaining_lookups) + return Self::is_delegating(identity, &parent, remaining_lookups); } else { - // Return whether the given account is the owner of the root and the root has - // not been revoked - let root = >::get(delegation_node.root_id).ok_or(Error::::RootNotFound)?; - Ok(( - (&root.owner == identity) && !root.revoked, - // safe because remaining lookups is at most max_parent_checks - max_parent_checks - remaining_lookups, - )) + // Safe because remaining lookups is at most max_parent_checks + return Ok((false, max_parent_checks - remaining_lookups)); } } } @@ -490,11 +465,11 @@ impl Pallet { let mut revocations: u32 = 0; let mut consumed_weight: Weight = 0; // Retrieve delegation node from storage - let mut delegation_node = >::get(*delegation).ok_or(Error::::DelegationNotFound)?; + let mut delegation_node = >::get(*delegation).ok_or(Error::::DelegationNotFound)?; consumed_weight = consumed_weight.saturating_add(T::DbWeight::get().reads(1)); // Check if already revoked - if !delegation_node.revoked { + if !delegation_node.details.revoked { // First revoke all children recursively let remaining_revocations = max_revocations .checked_sub(1) @@ -509,8 +484,8 @@ impl Pallet { ensure!(revocations < max_revocations, Error::::ExceededRevocationBounds); // Set revoked flag and store delegation node - delegation_node.revoked = true; - >::insert(*delegation, delegation_node); + delegation_node.details.revoked = true; + >::insert(*delegation, delegation_node); consumed_weight = consumed_weight.saturating_add(T::DbWeight::get().writes(1)); // Deposit event that the delegation has been revoked Self::deposit_event(Event::DelegationRevoked(sender.clone(), *delegation)); @@ -528,12 +503,9 @@ impl Pallet { ) -> Result<(u32, Weight), DispatchError> { let mut revocations: u32 = 0; let mut consumed_weight: Weight = 0; - // Check if there's a child vector in the storage - if let Some(children) = >::get(delegation) { - consumed_weight = consumed_weight.saturating_add(T::DbWeight::get().reads(1)); - - // Iterate child vector and revoke all nodes - for child in children { + if let Some(delegation_node) = >::get(delegation) { + // Iterate children and revoke all nodes + for child in delegation_node.children.iter() { let remaining_revocations = max_revocations .checked_sub(revocations) .ok_or(Error::::ExceededRevocationBounds)?; @@ -549,12 +521,4 @@ impl Pallet { } Ok((revocations, consumed_weight.saturating_add(T::DbWeight::get().reads(1)))) } - - // Add a child node into the delegation hierarchy - fn add_child(child: DelegationNodeIdOf, parent: DelegationNodeIdOf) { - // Get the children vector or initialize an empty one if none - let mut children = >::get(parent).unwrap_or_default(); - children.push(child); - >::insert(parent, children); - } } From b07bf96c24a808ab38ef9e69bc51ae3f0aea7e8a Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 9 Jul 2021 09:59:00 +0200 Subject: [PATCH 02/49] feat: pallet compiling --- pallets/delegation/src/lib.rs | 64 ++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index a4b0623feb..6b029db595 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -52,7 +52,7 @@ pub mod pallet { /// Type of a delegation hierarchy identifier. /// /// Currently, it is just equivalent to the ID of the root node of a given hierarchy. - pub type DelegationHierarchyIdOf = DelegationNodeIdOf; + pub type DelegationHierarchyIdOf = ::DelegationHierarchyId; /// Type of a delegator or a delegate. pub type DelegatorIdOf = ::DelegationEntityId; @@ -76,6 +76,7 @@ pub mod pallet { >; type DelegationEntityId: Parameter; type DelegationNodeId: Parameter + Copy + AsRef<[u8]> + Eq + PartialEq + Ord + PartialOrd; + type DelegationHierarchyId: Parameter + Copy + Into; type EnsureOrigin: EnsureOrigin, ::Origin>; type Event: From> + IsType<::Event>; #[pallet::constant] @@ -197,11 +198,7 @@ pub mod pallet { >::CTypeNotFound ); - log::debug!("insert Delegation Root"); - let root_node = DelegationNode::new_root_node(hierarchy_id, creator.clone()); - let hierarchy_info = DelegationHierarchyInfo:: { ctype_hash }; - >::insert(&hierarchy_id, root_node); - >::insert(&hierarchy_id, hierarchy_info); + Self::create_and_store_hierarchy_root(hierarchy_id, DelegationHierarchyInfo:: { ctype_hash }, creator.clone()); Self::deposit_event(Event::HierarchyCreated(creator, hierarchy_id, ctype_hash)); @@ -240,7 +237,7 @@ pub mod pallet { let delegator = ::EnsureOrigin::ensure_origin(origin)?; // Calculate the hash root - let hash_root = Self::calculate_hash(&delegation_id, &hierarchy_id, &Some(parent_id), &permissions); + let hash_root = Self::calculate_hash_root(&delegation_id, &hierarchy_id.into(), &Some(parent_id), &permissions); // Verify that the hash root signature is correct. DelegationSignatureVerificationOf::::verify(&delegate, &hash_root.encode(), &delegate_signature) @@ -254,7 +251,7 @@ pub mod pallet { Error::::DelegationAlreadyExists ); - let mut parent_node = >::get(&parent_id).ok_or(Error::::ParentDelegationNotFound)?; + let parent_node = >::get(&parent_id).ok_or(Error::::ParentDelegationNotFound)?; // Check if the parent's delegate is the creator of this delegation node... ensure!(parent_node.details.owner == delegator, Error::::NotOwnerOfParentDelegation); @@ -264,22 +261,12 @@ pub mod pallet { Error::::UnauthorizedDelegation ); - log::debug!("insert Delegation with parent"); - >::insert( - &delegation_id, - DelegationNode::new_node(hierarchy_id, parent_id, delegate.clone(), permissions) - ); - // Add the new node as a child of that node - parent_node.add_child(delegation_id); - >::insert( - &parent_id, - parent_node - ); + Self::store_delegation_under_parent(&delegation_id, DelegationNode::new_node(hierarchy_id, parent_id, delegate.clone(), permissions), &parent_id, parent_node); Self::deposit_event(Event::DelegationCreated( delegator, - delegation_id, hierarchy_id, + delegation_id, parent_id, delegate, permissions, @@ -309,23 +296,22 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let invoker = ::EnsureOrigin::ensure_origin(origin)?; - let mut hierarchy_root = >::get(&hierarchy_id).ok_or(Error::::HierarchyNotFound)?; + let hierarchy_root_node = >::get(&hierarchy_id.into()).ok_or(Error::::HierarchyNotFound)?; - ensure!(hierarchy_root.details.owner == invoker, Error::::UnauthorizedRevocation); + ensure!(hierarchy_root_node.details.owner == invoker, Error::::UnauthorizedRevocation); ensure!( max_children <= T::MaxRevocations::get(), Error::::MaxRevocationsTooLarge ); - let consumed_weight: Weight = if !hierarchy_root.details.revoked { + let consumed_weight: Weight = if !hierarchy_root_node.details.revoked { // Recursively revoke all children - let (_, post_weight) = Self::revoke_children(&hierarchy_id, &invoker, max_children)?; + let (_, post_weight) = Self::revoke_children(&hierarchy_id.into(), &invoker, max_children)?; // If we didn't return an ExceededRevocationBounds error, we can revoke the root // too. - hierarchy_root.details.revoked = true; - >::insert(&hierarchy_id, hierarchy_root); + Self::revoke_and_store_hierarchy_root(hierarchy_id, hierarchy_root_node); // We don't cancel the delegation_hierarchy from storage. post_weight.saturating_add(T::DbWeight::get().writes(1)) @@ -403,7 +389,7 @@ pub mod pallet { impl Pallet { // Calculate the hash of all values of a delegation transaction - fn calculate_hash( + fn calculate_hash_root( delegation_id: &DelegationNodeIdOf, root_id: &DelegationNodeIdOf, parent_id: &Option>, @@ -420,6 +406,30 @@ impl Pallet { T::Hashing::hash(&hashed_values) } + fn create_and_store_hierarchy_root(hierarchy_id: DelegationHierarchyIdOf, hierarchy_info: DelegationHierarchyInfo, hierarchy_owner: DelegatorIdOf) { + let root_node = DelegationNode::new_root_node(hierarchy_id, hierarchy_owner); + >::insert(hierarchy_id.into(), root_node); + >::insert(hierarchy_id, hierarchy_info); + } + + fn store_delegation_under_parent(delegation_id: &DelegationNodeIdOf, delegation_node: DelegationNode, parent_id: &DelegationNodeIdOf, mut parent_node: DelegationNode) { + >::insert( + delegation_id, + delegation_node + ); + // Add the new node as a child of that node + parent_node.add_child(*delegation_id); + >::insert( + parent_id, + parent_node + ); + } + + fn revoke_and_store_hierarchy_root(hierarchy_id: DelegationHierarchyIdOf, mut root_node: DelegationNode) { + root_node.details.revoked = true; + >::insert(hierarchy_id.into(), root_node); + } + /// Check if an identity is the owner of the given delegation node or any /// node up the hierarchy, and if the delegation has not been yet revoked. /// From fde4a99507f85ac08b0883694430b6b2d712eddb Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 9 Jul 2021 16:16:31 +0200 Subject: [PATCH 03/49] wip: fixing test cases --- Cargo.lock | 609 +++-- pallets/attestation/src/tests.rs | 48 +- pallets/delegation/src/benchmarking.rs | 10 +- pallets/delegation/src/lib.rs | 64 +- pallets/delegation/src/mock.rs | 116 +- pallets/delegation/src/tests.rs | 3274 ++++++++++++------------ 6 files changed, 2050 insertions(+), 2071 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0fd9b8ac16..c68aed92f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03345e98af8f3d786b6d9f656ccfa6ac316d954e92bc4841f0bba20789d5fb5a" +checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a" dependencies = [ "gimli", ] @@ -88,23 +88,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" [[package]] -name = "aho-corasick" -version = "0.7.18" +name = "ahash" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98" dependencies = [ - "memchr", + "getrandom 0.2.3", + "once_cell", + "version_check", ] [[package]] -name = "alga" -version = "0.9.3" +name = "aho-corasick" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ - "approx 0.3.2", - "num-complex 0.2.4", - "num-traits", + "memchr", ] [[package]] @@ -133,24 +133,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" - -[[package]] -name = "approx" -version = "0.3.2" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" -dependencies = [ - "num-traits", -] +checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" [[package]] name = "approx" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" +checksum = "072df7202e63b127ab55acfe16ce97013d5b97bf160489336d3f1840fd78e99e" dependencies = [ "num-traits", ] @@ -178,9 +169,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "arrayvec" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a2f58b0bb10c380af2b26e57212856b8c9a59e0925b4c20f4a174a49734eaf7" +checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd" [[package]] name = "asn1_der" @@ -261,12 +252,11 @@ dependencies = [ [[package]] name = "async-io" -version = "1.4.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bbfd5cf2794b1e908ea8457e6c45f8f8f1f6ec5f74617bf4662623f47503c3b" +checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" dependencies = [ "concurrent-queue", - "fastrand", "futures-lite", "libc", "log", @@ -326,7 +316,7 @@ dependencies = [ "async-io", "async-lock", "async-process", - "crossbeam-utils 0.8.4", + "crossbeam-utils 0.8.5", "futures-channel", "futures-core", "futures-io", @@ -337,7 +327,7 @@ dependencies = [ "memchr", "num_cpus", "once_cell", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", "pin-utils", "slab", "wasm-bindgen-futures", @@ -384,7 +374,7 @@ dependencies = [ "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", ] [[package]] @@ -397,7 +387,7 @@ dependencies = [ "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", ] [[package]] @@ -461,16 +451,16 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "backtrace" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4717cfcbfaa661a0fd48f8453951837ae7e8f81e481fbb136e3202d72805a744" +checksum = "b7815ea54e4d821e791162e078acbebfd6d8c8939cd559c9335dceb1c8ca7282" dependencies = [ "addr2line", "cc", "cfg-if 1.0.0", "libc", "miniz_oxide", - "object", + "object 0.25.3", "rustc-demangle", ] @@ -867,9 +857,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.6.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" [[package]] name = "byte-slice-cast" @@ -1164,9 +1154,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" dependencies = [ "libc", ] @@ -1263,7 +1253,7 @@ dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", - "itertools 0.10.0", + "itertools 0.10.1", "log", "serde", "smallvec 1.6.1", @@ -1287,7 +1277,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.4", + "crossbeam-utils 0.8.5", ] [[package]] @@ -1308,8 +1298,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" dependencies = [ "cfg-if 1.0.0", - "crossbeam-epoch 0.9.4", - "crossbeam-utils 0.8.4", + "crossbeam-epoch 0.9.5", + "crossbeam-utils 0.8.5", ] [[package]] @@ -1329,14 +1319,14 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52fb27eab85b17fbb9f6fd667089e07d6a2eb8743d02639ee7f6a7a7729c9c94" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.4", + "crossbeam-utils 0.8.5", "lazy_static", - "memoffset 0.6.3", + "memoffset 0.6.4", "scopeguard 1.1.0", ] @@ -1364,11 +1354,10 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "autocfg 1.0.1", "cfg-if 1.0.0", "lazy_static", ] @@ -1565,7 +1554,7 @@ name = "cumulus-client-network" version = "0.1.0" source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.7#c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "futures-timer 3.0.2", "parity-scale-codec", @@ -1597,7 +1586,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-overseer", "polkadot-primitives", - "rand 0.8.3", + "rand 0.8.4", "sc-client-api", "sp-api", "sp-consensus", @@ -1701,8 +1690,8 @@ dependencies = [ "frame-system", "log", "parity-scale-codec", - "rand 0.8.3", - "rand_chacha 0.3.0", + "rand 0.8.4", + "rand_chacha 0.3.1", "sp-runtime", "sp-std", "xcm", @@ -1792,9 +1781,9 @@ checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" [[package]] name = "data-encoding-macro" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3920ab0ba823e4fe0fe4c358f105a7e36643f2155f409b13df03e67965d296f" +checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029aca" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -1802,9 +1791,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f83e699727abca3c56e187945f303389590305ab2f0185ea445aa66e8d5f2a" +checksum = "a5bbed42daaa95e780b60a50546aa345b8413a1e46f9a40a12907d3598f038db" dependencies = [ "data-encoding", "syn 1.0.73", @@ -1858,13 +1847,14 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.14" +version = "0.99.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc7b9cef1e351660e5443924e4f43ab25fbbed3e9a5f052df3677deb4d6b320" +checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" dependencies = [ "convert_case", "proc-macro2 1.0.27", "quote 1.0.9", + "rustc_version 0.3.3", "syn 1.0.73", ] @@ -1873,7 +1863,7 @@ name = "did" version = "0.24.0" dependencies = [ "ctype", - "env_logger 0.8.3", + "env_logger 0.8.4", "frame-benchmarking", "frame-support", "frame-system", @@ -2092,9 +2082,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" dependencies = [ "atty", "humantime 2.1.0", @@ -2111,9 +2101,9 @@ checksum = "68b91989ae21441195d7d9b9993a2f9295c7e1a8c96255d8b729accddc124797" [[package]] name = "erased-serde" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5b36e6f2295f393f44894c6031f67df4d185b984cd54d08f768ce678007efcd" +checksum = "3de9ad4541d99dc22b59134e7ff8dc3d6c988c89ecd7324bf10a8362b07a2afa" dependencies = [ "serde", ] @@ -2267,9 +2257,9 @@ dependencies = [ [[package]] name = "finality-grandpa" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6447e2f8178843749e8c8003206def83ec124a7859475395777a28b5338647c" +checksum = "74a1bfdcc776e63e49f741c7ce6116fa1b887e8ac2e3ccb14dd4aa113e54feb9" dependencies = [ "either", "futures 0.3.15", @@ -2287,7 +2277,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" dependencies = [ "byteorder", - "rand 0.8.3", + "rand 0.8.4", "rustc-hex", "static_assertions", ] @@ -2652,16 +2642,16 @@ checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1" [[package]] name = "futures-lite" -version = "1.11.3" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4481d0cd0de1d204a4fa55e7d45f07b1d958abcb06714b3446438e2eff695fb" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" dependencies = [ "fastrand", "futures-core", "futures-io", "memchr", "parking", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", "waker-fn", ] @@ -2728,7 +2718,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -2750,15 +2740,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "generic-array" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.4" @@ -2820,9 +2801,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" +checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" dependencies = [ "aho-corasick", "bstr", @@ -2917,23 +2898,32 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" dependencies = [ - "ahash", + "ahash 0.4.7", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.4", ] [[package]] name = "heck" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ "unicode-segmentation", ] [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -2956,9 +2946,9 @@ dependencies = [ [[package]] name = "hex-literal" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8" +checksum = "76505e26b6ca3bbdbbb360b68472abbb80998c5fa5dc43672eca34f28258e138" [[package]] name = "hex-literal-impl" @@ -3069,7 +3059,7 @@ checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9" dependencies = [ "bytes 1.0.1", "http 0.2.4", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", ] [[package]] @@ -3161,9 +3151,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.9" +version = "0.14.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83" +checksum = "7728a72c4c7d72665fde02204bcbd93b247721025b222ef78606f14513e0fd03" dependencies = [ "bytes 1.0.1", "futures-channel", @@ -3174,8 +3164,8 @@ dependencies = [ "httparse", "httpdate 1.0.1", "itoa", - "pin-project-lite 0.2.6", - "tokio 1.7.0", + "pin-project-lite 0.2.7", + "tokio 1.8.1", "tower-service", "tracing", "want 0.3.0", @@ -3260,9 +3250,9 @@ dependencies = [ [[package]] name = "impl-codec" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df170efa359aebdd5cb7fe78edcc67107748e4737bdca8a8fb40d15ea7a877ed" +checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" dependencies = [ "parity-scale-codec", ] @@ -3298,12 +3288,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg 1.0.1", - "hashbrown", + "hashbrown 0.11.2", "serde", ] @@ -3370,9 +3360,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" +checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" [[package]] name = "itertools" @@ -3385,9 +3375,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" dependencies = [ "either", ] @@ -3561,7 +3551,7 @@ dependencies = [ "beef", "futures-channel", "futures-util", - "hyper 0.14.9", + "hyper 0.14.10", "log", "serde", "serde_json", @@ -3790,9 +3780,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "libc" -version = "0.2.95" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "libloading" @@ -4019,7 +4009,7 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log", - "rand 0.8.3", + "rand 0.8.4", "smallvec 1.6.1", "socket2 0.4.0", "void", @@ -4310,11 +4300,11 @@ dependencies = [ [[package]] name = "linregress" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b36162d2e1dcbdeb61223cb788f029f8ac9f2ab19969b89c5a8f4517aad4d940" +checksum = "1e6e407dadb4ca4b31bc69c27aff00e7ca4534fdcee855159b039a7cebb5f395" dependencies = [ - "nalgebra 0.25.4", + "nalgebra", "statrs", ] @@ -4362,7 +4352,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f374d42cdfc1d7dbf3d3dec28afab2eb97ffbf43a3234d795b5986dbf4b90ba" dependencies = [ - "hashbrown", + "hashbrown 0.9.1", ] [[package]] @@ -4453,7 +4443,7 @@ dependencies = [ "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", - "hex-literal 0.3.1", + "hex-literal 0.3.2", "kilt-launch", "kilt-primitives", "log", @@ -4509,15 +4499,6 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -[[package]] -name = "matrixmultiply" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916806ba0031cd542105d916a97c8572e1fa6dd79c9c51e7eb43a09ec2dd84c1" -dependencies = [ - "rawpointer", -] - [[package]] name = "matrixmultiply" version = "0.3.1" @@ -4581,9 +4562,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" dependencies = [ "autocfg 1.0.1", ] @@ -4595,7 +4576,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "814bbecfc0451fc314eeea34f05bbcd5b98a7ad7af37faee088b86a1e633f1d4" dependencies = [ "hash-db", - "hashbrown", + "hashbrown 0.9.1", "parity-util-mem", ] @@ -4631,7 +4612,7 @@ name = "metered-channel" version = "0.1.0" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "futures-timer 3.0.2", ] @@ -4822,37 +4803,31 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.19.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0abb021006c01b126a936a8dd1351e0720d83995f4fc942d0d426c654f990745" +checksum = "462fffe4002f4f2e1f6a9dcf12cc1a6fc0e15989014efc02a941d3e0f5dc2120" dependencies = [ - "alga", - "approx 0.3.2", - "generic-array 0.13.3", - "matrixmultiply 0.2.4", - "num-complex 0.2.4", - "num-rational 0.2.4", + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational 0.4.0", "num-traits", - "rand 0.7.3", + "rand 0.8.4", "rand_distr", + "simba", "typenum", ] [[package]] -name = "nalgebra" -version = "0.25.4" +name = "nalgebra-macros" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c70c9e8c5f213c8e93fc8c112ade4edd3ee62062fb897776c23dcebac7932900" +checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" dependencies = [ - "approx 0.4.0", - "generic-array 0.14.4", - "matrixmultiply 0.3.1", - "num-complex 0.3.1", - "num-rational 0.3.2", - "num-traits", - "serde", - "simba", - "typenum", + "proc-macro2 1.0.27", + "quote 1.0.9", + "syn 1.0.73", ] [[package]] @@ -5029,19 +5004,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" -dependencies = [ - "autocfg 1.0.1", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" +checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" dependencies = [ "num-traits", ] @@ -5070,9 +5035,9 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" dependencies = [ "autocfg 1.0.1", "num-integer", @@ -5109,11 +5074,20 @@ dependencies = [ "indexmap", ] +[[package]] +name = "object" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a38f2be3697a57b4060074ff41b44c16870d916ad7877c17696e063257482bc7" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" dependencies = [ "parking_lot 0.11.1", ] @@ -5986,7 +5960,7 @@ dependencies = [ "log", "memmap2", "parking_lot 0.11.1", - "rand 0.8.3", + "rand 0.8.4", ] [[package]] @@ -6009,24 +5983,25 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f518afaa5a47d0d6386229b0a6e01e86427291d643aa4cabb4992219f504f8" +checksum = "8975095a2a03bbbdc70a74ab11a4f76a6d0b84680d87c68d722531b0ac28e8a9" dependencies = [ - "arrayvec 0.7.0", + "arrayvec 0.7.1", "bitvec", "byte-slice-cast", + "impl-trait-for-tuples", "parity-scale-codec-derive", "serde", ] [[package]] name = "parity-scale-codec-derive" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f44c5f94427bd0b5076e8f7e15ca3f60a4d8ac0077e4793884e6fdfd8915344e" +checksum = "40dbbfef7f0a1143c5b06e0d76a6278e25dac0bc1af4be51a0fbb73f07e7ad09" dependencies = [ - "proc-macro-crate 0.1.5", + "proc-macro-crate 1.0.0", "proc-macro2 1.0.27", "quote 1.0.9", "syn 1.0.73", @@ -6065,7 +6040,7 @@ checksum = "664a8c6b8e62d8f9f2f937e391982eb433ab285b4cd9545b342441e04a906e42" dependencies = [ "cfg-if 1.0.0", "ethereum-types", - "hashbrown", + "hashbrown 0.9.1", "impl-trait-for-tuples", "lru", "parity-util-mem-derive", @@ -6103,9 +6078,9 @@ checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" [[package]] name = "parity-ws" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e02a625dd75084c2a7024f07c575b61b782f729d18702dabb3cdbf31911dc61" +checksum = "322d72dfe461b8b9e367d057ceace105379d64d5b03907d23c481ccf3fbf8aa4" dependencies = [ "byteorder", "bytes 0.4.12", @@ -6218,7 +6193,7 @@ dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall 0.2.8", + "redox_syscall 0.2.9", "smallvec 1.6.1", "winapi 0.3.9", ] @@ -6293,7 +6268,7 @@ dependencies = [ "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", - "hex-literal 0.3.1", + "hex-literal 0.3.2", "kilt-launch", "kilt-primitives", "log", @@ -6444,9 +6419,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" [[package]] name = "pin-utils" @@ -6508,7 +6483,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.3", + "rand 0.8.4", "sp-application-crypto", "sp-core", "sp-keystore", @@ -6530,7 +6505,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.3", + "rand 0.8.4", "thiserror", "tracing", ] @@ -6689,7 +6664,7 @@ version = "0.1.0" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa" dependencies = [ "bitvec", - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "futures-timer 3.0.2", "kvdb", @@ -6845,7 +6820,7 @@ dependencies = [ "pin-project 1.0.7", "polkadot-core-primitives", "polkadot-parachain", - "rand 0.8.3", + "rand 0.8.4", "sc-executor", "sc-executor-common", "sc-executor-wasmtime", @@ -6938,7 +6913,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35b dependencies = [ "async-std", "async-trait", - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "futures-timer 3.0.2", "lazy_static", @@ -6978,7 +6953,7 @@ dependencies = [ "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-primitives", - "rand 0.8.3", + "rand 0.8.4", "sc-network", "sp-application-crypto", "sp-core", @@ -7013,7 +6988,7 @@ name = "polkadot-parachain" version = "0.9.7" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "parity-scale-codec", "parity-util-mem", "polkadot-core-primitives", @@ -7030,7 +7005,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35b dependencies = [ "bitvec", "frame-system", - "hex-literal 0.3.1", + "hex-literal 0.3.2", "parity-scale-codec", "parity-util-mem", "polkadot-core-primitives", @@ -7230,7 +7205,7 @@ version = "0.9.7" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.7#5d35bac7408a4cb12a578764217d06f3920b36aa" dependencies = [ "bitvec", - "derive_more 0.99.14", + "derive_more 0.99.16", "frame-benchmarking", "frame-support", "frame-system", @@ -7246,8 +7221,8 @@ dependencies = [ "pallet-vesting", "parity-scale-codec", "polkadot-primitives", - "rand 0.8.3", - "rand_chacha 0.3.0", + "rand 0.8.4", + "rand_chacha 0.3.1", "rustc-hex", "serde", "sp-api", @@ -7272,7 +7247,7 @@ dependencies = [ "beefy-primitives", "frame-system-rpc-runtime-api", "futures 0.3.15", - "hex-literal 0.3.1", + "hex-literal 0.3.2", "kvdb", "kvdb-rocksdb", "pallet-babe", @@ -7487,7 +7462,7 @@ dependencies = [ "polkadot-runtime-parachains", "polkadot-service", "polkadot-test-runtime", - "rand 0.8.3", + "rand 0.8.4", "sc-authority-discovery", "sc-chain-spec", "sc-cli", @@ -7518,14 +7493,14 @@ dependencies = [ [[package]] name = "polling" -version = "2.0.3" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fc12d774e799ee9ebae13f4076ca003b40d18a11ac0f3641e6f899618580b7b" +checksum = "92341d779fa34ea8437ef4d82d440d5e1ce3f3ff7f824aa64424cd481f9a1f25" dependencies = [ "cfg-if 1.0.0", "libc", "log", - "wepoll-sys", + "wepoll-ffi", "winapi 0.3.9", ] @@ -7584,9 +7559,9 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2415937401cb030a2a0a4d922483f945fa068f52a7dbb22ce0fe5f2b6f6adace" +checksum = "06345ee39fbccfb06ab45f3a1a5798d9dafa04cb8921a76d227040003a234b0e" dependencies = [ "fixed-hash", "impl-codec", @@ -7744,9 +7719,9 @@ dependencies = [ [[package]] name = "pwasm-utils" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0e517f47d9964362883182404b68d0b6949382c0baa40aa5ffca94f5f1e3481" +checksum = "f0c1a2f10b47d446372a4f397c58b329aaea72b2daf9395a623a411cb8ccb54f" dependencies = [ "byteorder", "log", @@ -7858,14 +7833,14 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", - "rand_chacha 0.3.0", - "rand_core 0.6.2", - "rand_hc 0.3.0", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", ] [[package]] @@ -7890,12 +7865,12 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.2", + "rand_core 0.6.3", ] [[package]] @@ -7924,20 +7899,21 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ "getrandom 0.2.3", ] [[package]] name = "rand_distr" -version = "0.2.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2" +checksum = "051b398806e42b9cd04ad9ec8f81e355d0a382c543ac6672c62f5a5b452ef142" dependencies = [ - "rand 0.7.3", + "num-traits", + "rand 0.8.4", ] [[package]] @@ -7960,11 +7936,11 @@ dependencies = [ [[package]] name = "rand_hc" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ - "rand_core 0.6.2", + "rand_core 0.6.3", ] [[package]] @@ -8055,7 +8031,7 @@ checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" dependencies = [ "crossbeam-channel", "crossbeam-deque 0.8.0", - "crossbeam-utils 0.8.4", + "crossbeam-utils 0.8.5", "lazy_static", "num_cpus", ] @@ -8077,9 +8053,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" +checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" dependencies = [ "bitflags", ] @@ -8091,7 +8067,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ "getrandom 0.2.3", - "redox_syscall 0.2.8", + "redox_syscall 0.2.9", ] [[package]] @@ -8100,9 +8076,9 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bd8f48b2066e9f69ab192797d66da804d1935bf22763204ed3675740cb0f221" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "fs-err", - "itertools 0.10.0", + "itertools 0.10.1", "static_init", "thiserror", ] @@ -8152,11 +8128,10 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "byteorder", "regex-syntax", ] @@ -8183,7 +8158,7 @@ name = "remote-externalities" version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ - "env_logger 0.8.3", + "env_logger 0.8.4", "hex", "jsonrpsee-proc-macros", "jsonrpsee-ws-client", @@ -8268,7 +8243,7 @@ dependencies = [ "frame-support", "frame-system", "frame-system-rpc-runtime-api", - "hex-literal 0.3.1", + "hex-literal 0.3.2", "log", "max-encoded-len", "pallet-authority-discovery", @@ -8335,9 +8310,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce" +checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" [[package]] name = "rustc-hash" @@ -8369,6 +8344,15 @@ dependencies = [ "semver 0.11.0", ] +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.3", +] + [[package]] name = "rustls" version = "0.18.1" @@ -8421,9 +8405,9 @@ dependencies = [ [[package]] name = "ruzstd" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d425143485a37727c7a46e689bbe3b883a00f42b4a52c4ac0f44855c1009b00" +checksum = "8cada0ef59efa6a5f4dc5e491f93d9f31e3fc7758df421ff1de8a706338e1100" dependencies = [ "byteorder", "twox-hash", @@ -8479,7 +8463,7 @@ version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ "async-trait", - "derive_more 0.99.14", + "derive_more 0.99.16", "either", "futures 0.3.15", "futures-timer 3.0.2", @@ -8616,7 +8600,7 @@ name = "sc-client-api" version = "3.0.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "fnv", "futures 0.3.15", "hash-db", @@ -8693,7 +8677,7 @@ version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ "async-trait", - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "futures-timer 3.0.2", "log", @@ -8724,7 +8708,7 @@ version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ "async-trait", - "derive_more 0.99.14", + "derive_more 0.99.16", "fork-tree", "futures 0.3.15", "futures-timer 3.0.2", @@ -8769,7 +8753,7 @@ name = "sc-consensus-babe-rpc" version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "jsonrpc-core", "jsonrpc-core-client", @@ -8845,7 +8829,7 @@ name = "sc-executor" version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "lazy_static", "libsecp256k1", "log", @@ -8874,7 +8858,7 @@ name = "sc-executor-common" version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "parity-scale-codec", "pwasm-utils", "sp-allocator", @@ -8924,7 +8908,7 @@ version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ "async-trait", - "derive_more 0.99.14", + "derive_more 0.99.16", "dyn-clone", "finality-grandpa", "fork-tree", @@ -8964,7 +8948,7 @@ name = "sc-finality-grandpa-rpc" version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "finality-grandpa", "futures 0.3.15", "jsonrpc-core", @@ -8988,7 +8972,7 @@ name = "sc-finality-grandpa-warp-sync" version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "log", "num-traits", @@ -9028,7 +9012,7 @@ version = "3.0.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ "async-trait", - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "futures-util", "hex", @@ -9073,7 +9057,7 @@ dependencies = [ "bs58", "bytes 1.0.1", "cid", - "derive_more 0.99.14", + "derive_more 0.99.16", "either", "erased-serde", "fnv", @@ -9221,7 +9205,7 @@ name = "sc-rpc-api" version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "jsonrpc-core", "jsonrpc-core-client", @@ -9432,7 +9416,7 @@ name = "sc-transaction-graph" version = "3.0.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "linked-hash-map", "log", @@ -9633,6 +9617,12 @@ dependencies = [ "serde", ] +[[package]] +name = "semver" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f3aac57ee7f3272d8395c6e4f502f434f0e289fcd62876f70daa008c20dcabe" + [[package]] name = "semver-parser" version = "0.7.0" @@ -9758,9 +9748,9 @@ checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" [[package]] name = "signal-hook" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef33d6d0cd06e0840fba9985aab098c147e67e05cee14d412d3345ed14ff30ac" +checksum = "470c5a6397076fae0094aaf06a08e6ba6f37acb77d3b1b91ea92b4d6c8650c39" dependencies = [ "libc", "signal-hook-registry", @@ -9768,27 +9758,27 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" dependencies = [ "libc", ] [[package]] name = "signature" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0242b8e50dd9accdd56170e94ca1ebd223b098eb9c83539a6e367d0f36ae68" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" [[package]] name = "simba" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5132a955559188f3d13c9ba831e77c802ddc8782783f050ed0c52f5988b95f4c" +checksum = "8e82063457853d00243beda9952e910b82593e4b07ae9f721b9278a99a0d3d5c" dependencies = [ - "approx 0.4.0", - "num-complex 0.3.1", + "approx", + "num-complex", "num-traits", "paste", ] @@ -9822,9 +9812,9 @@ dependencies = [ [[package]] name = "slotmap" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585cd5dffe4e9e06f6dfdf66708b70aca3f781bed561f4f667b2d9c0d4559e36" +checksum = "a952280edbecfb1d4bd3cf2dbc309dc6ab523e53487c438ae21a6df09fe84bc4" dependencies = [ "version_check", ] @@ -9910,7 +9900,7 @@ dependencies = [ "futures 0.3.15", "httparse", "log", - "rand 0.8.3", + "rand 0.8.4", "sha-1 0.9.6", ] @@ -10281,7 +10271,7 @@ version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ "async-trait", - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "merlin", "parity-scale-codec", @@ -10544,7 +10534,7 @@ name = "sp-transaction-pool" version = "3.0.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ - "derive_more 0.99.14", + "derive_more 0.99.16", "futures 0.3.15", "log", "parity-scale-codec", @@ -10654,7 +10644,7 @@ dependencies = [ "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", - "hex-literal 0.3.1", + "hex-literal 0.3.2", "kilt-launch", "kilt-primitives", "log", @@ -10736,12 +10726,15 @@ dependencies = [ [[package]] name = "statrs" -version = "0.13.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e34b58a8f9b7462b6922e0b4e3c83d1b3c2075f7f996a56d6c66afa81590064" +checksum = "05bdbb8e4e78216a85785a85d3ec3183144f98d0097b9281802c019bb07a6f05" dependencies = [ - "nalgebra 0.19.0", - "rand 0.7.3", + "approx", + "lazy_static", + "nalgebra", + "num-traits", + "rand 0.8.4", ] [[package]] @@ -10783,9 +10776,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c" +checksum = "69b041cdcb67226aca307e6e7be44c8806423d83e018bd662360a93dabce4d71" dependencies = [ "clap", "lazy_static", @@ -10794,9 +10787,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" +checksum = "7813934aecf5f51a54775e00068c237de98489463968231a51746bbbc03f9c10" dependencies = [ "heck", "proc-macro-error", @@ -10876,7 +10869,7 @@ version = "0.9.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.7#9c572625f6557dfdb19f47474369a0327d51dfbc" dependencies = [ "async-std", - "derive_more 0.99.14", + "derive_more 0.99.16", "futures-util", "hyper 0.13.10", "log", @@ -11085,8 +11078,8 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if 1.0.0", "libc", - "rand 0.8.3", - "redox_syscall 0.2.8", + "rand 0.8.4", + "redox_syscall 0.2.9", "remove_dir_all", "winapi 0.3.9", ] @@ -11111,18 +11104,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" dependencies = [ "proc-macro2 1.0.27", "quote 1.0.9", @@ -11262,12 +11255,12 @@ dependencies = [ [[package]] name = "tokio" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c79ba603c337335df6ba6dd6afc38c38a7d5e1b0c871678439ea973cd62a118e" +checksum = "98c8b05dc14c75ea83d63dd391100353789f5f24b8b3866542a5e85c8be8e985" dependencies = [ "autocfg 1.0.1", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", ] [[package]] @@ -11534,7 +11527,7 @@ checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" dependencies = [ "cfg-if 1.0.0", "log", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", "tracing-attributes", "tracing-core", ] @@ -11592,9 +11585,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa5553bf0883ba7c9cbe493b085c29926bd41b66afc31ff72cf17ff4fb60dcd5" +checksum = "ab69019741fca4d98be3c62d2b75254528b5432233fd8a4d2739fec20278de48" dependencies = [ "ansi_term 0.12.1", "chrono", @@ -11620,12 +11613,12 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" [[package]] name = "trie-db" -version = "0.22.5" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd81fe0c8bc2b528a51c9d2c31dae4483367a26a723a3c9a4a8120311d7774e3" +checksum = "9eac131e334e81b6b3be07399482042838adcd7957aa0010231d0813e39e02fa" dependencies = [ "hash-db", - "hashbrown", + "hashbrown 0.11.2", "log", "rustc-hex", "smallvec 1.6.1", @@ -11666,7 +11659,7 @@ dependencies = [ "ipnet", "lazy_static", "log", - "rand 0.8.3", + "rand 0.8.4", "smallvec 1.6.1", "thiserror", "tinyvec", @@ -11748,9 +11741,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" [[package]] name = "uint" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e11fe9a9348741cf134085ad57c249508345fe16411b3d7fb4ff2da2f1d6382e" +checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" dependencies = [ "byteorder", "crunchy", @@ -11778,18 +11771,18 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" @@ -11890,9 +11883,9 @@ dependencies = [ [[package]] name = "vcpkg" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025ce40a007e1907e58d5bc1a594def78e5573bb0b1160bc389634e8f12e4faa" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vec_map" @@ -11908,7 +11901,7 @@ checksum = "e7141e445af09c8919f1d5f8a20dae0b20c3b57a45dee0d5823c6ed5d237f15a" dependencies = [ "bitflags", "chrono", - "rustc_version 0.3.3", + "rustc_version 0.4.0", ] [[package]] @@ -12182,7 +12175,7 @@ dependencies = [ "anyhow", "gimli", "more-asserts", - "object", + "object 0.24.0", "target-lexicon", "thiserror", "wasmparser", @@ -12236,7 +12229,7 @@ dependencies = [ "gimli", "log", "more-asserts", - "object", + "object 0.24.0", "rayon", "region", "serde", @@ -12260,7 +12253,7 @@ checksum = "8e1a8ff85246d091828e2225af521a6208ed28c997bb5c39eb697366dc2e2f2b" dependencies = [ "anyhow", "more-asserts", - "object", + "object 0.24.0", "target-lexicon", "wasmtime-debug", "wasmtime-environ", @@ -12277,7 +12270,7 @@ dependencies = [ "gimli", "lazy_static", "libc", - "object", + "object 0.24.0", "scroll", "serde", "target-lexicon", @@ -12300,9 +12293,9 @@ dependencies = [ "libc", "log", "mach", - "memoffset 0.6.3", + "memoffset 0.6.4", "more-asserts", - "rand 0.8.3", + "rand 0.8.4", "region", "thiserror", "wasmtime-environ", @@ -12312,18 +12305,18 @@ dependencies = [ [[package]] name = "wast" -version = "35.0.2" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ef140f1b49946586078353a453a1d28ba90adfc54dde75710bc1931de204d68" +checksum = "8b5d7ba374a364571da1cb0a379a3dc302582a2d9937a183bfe35b68ad5bb9c4" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ec280a739b69173e0ffd12c1658507996836ba4e992ed9bc1e5385a0bd72a02" +checksum = "16383df7f0e3901484c2dda6294ed6895caa3627ce4f6584141dcf30a33a23e6" dependencies = [ "wast", ] @@ -12358,10 +12351,10 @@ dependencies = [ ] [[package]] -name = "wepoll-sys" -version = "3.0.1" +name = "wepoll-ffi" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" dependencies = [ "cc", ] @@ -12517,7 +12510,7 @@ dependencies = [ "log", "nohash-hasher", "parking_lot 0.11.1", - "rand 0.8.3", + "rand 0.8.4", "static_assertions", ] diff --git a/pallets/attestation/src/tests.rs b/pallets/attestation/src/tests.rs index 300c124ed2..9d84703145 100644 --- a/pallets/attestation/src/tests.rs +++ b/pallets/attestation/src/tests.rs @@ -63,7 +63,7 @@ fn attest_with_delegation_successful() { let claim_hash = get_claim_hash(true); let (root_id, root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(attester.clone()), + delegation_mock::generate_base_delegation_hierarchy(attester.clone()), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -79,7 +79,7 @@ fn attest_with_delegation_successful() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) + .with_delegation_hierarchies(vec![(root_id, root_node)]) .with_delegations(vec![(delegation_id, delegation_node)]) .with_children(vec![(root_id, vec![delegation_id])]) .build(Some(ext)); @@ -198,7 +198,7 @@ fn delegation_revoked_attest_error() { let claim_hash = get_claim_hash(true); let (root_id, root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(attester.clone()), + delegation_mock::generate_base_delegation_hierarchy(attester.clone()), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -215,7 +215,7 @@ fn delegation_revoked_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) + .with_delegation_hierarchies(vec![(root_id, root_node)]) .with_delegations(vec![(delegation_id, delegation_node)]) .with_children(vec![(root_id, vec![delegation_id])]) .build(Some(ext)); @@ -242,7 +242,7 @@ fn not_delegation_owner_attest_error() { let claim_hash = get_claim_hash(true); let (root_id, root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(alternative_owner.clone()), + delegation_mock::generate_base_delegation_hierarchy(alternative_owner.clone()), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -258,7 +258,7 @@ fn not_delegation_owner_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) + .with_delegation_hierarchies(vec![(root_id, root_node)]) .with_delegations(vec![(delegation_id, delegation_node)]) .with_children(vec![(root_id, vec![delegation_id])]) .build(Some(ext)); @@ -283,7 +283,7 @@ fn unauthorised_permissions_attest_error() { let claim_hash = get_claim_hash(true); let (root_id, root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(attester.clone()), + delegation_mock::generate_base_delegation_hierarchy(attester.clone()), ); let (delegation_id, delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -298,7 +298,7 @@ fn unauthorised_permissions_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) + .with_delegation_hierarchies(vec![(root_id, root_node)]) .with_delegations(vec![(delegation_id, delegation_node)]) .with_children(vec![(root_id, vec![delegation_id])]) .build(Some(ext)); @@ -323,7 +323,7 @@ fn root_not_present_attest_error() { let claim_hash = get_claim_hash(true); let (root_id, root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(attester.clone()), + delegation_mock::generate_base_delegation_hierarchy(attester.clone()), ); let alternative_root_id = delegation_mock::get_delegation_root_id(false); let (delegation_id, mut delegation_node) = ( @@ -340,7 +340,7 @@ fn root_not_present_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(alternative_root_id, root_node)]) + .with_delegation_hierarchies(vec![(alternative_root_id, root_node)]) .with_delegations(vec![(delegation_id, delegation_node)]) .with_children(vec![(alternative_root_id, vec![delegation_id])]) .build(Some(ext)); @@ -366,7 +366,7 @@ fn root_ctype_mismatch_attest_error() { let alternative_ctype_hash = ctype_mock::get_ctype_hash(false); let (root_id, mut root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(attester.clone()), + delegation_mock::generate_base_delegation_hierarchy(attester.clone()), ); root_node.ctype_hash = alternative_ctype_hash; let (delegation_id, mut delegation_node) = ( @@ -383,7 +383,7 @@ fn root_ctype_mismatch_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) + .with_delegation_hierarchies(vec![(root_id, root_node)]) .with_delegations(vec![(delegation_id, delegation_node)]) .with_children(vec![(root_id, vec![delegation_id])]) .build(Some(ext)); @@ -444,7 +444,7 @@ fn revoke_with_delegation_successful() { let (root_id, root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(revoker.clone()), + delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -464,7 +464,7 @@ fn revoke_with_delegation_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) + .with_delegation_hierarchies(vec![(root_id, root_node)]) .with_delegations(vec![(delegation_id, delegation_node)]) .with_children(vec![(root_id, vec![delegation_id])]) .build(Some(ext)); @@ -497,7 +497,7 @@ fn revoke_with_parent_delegation_successful() { let (root_id, root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(revoker.clone()), + delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), @@ -520,7 +520,7 @@ fn revoke_with_parent_delegation_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) + .with_delegation_hierarchies(vec![(root_id, root_node)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .with_children(vec![(root_id, vec![parent_id]), (parent_id, vec![delegation_id])]) .build(Some(ext)); @@ -552,7 +552,7 @@ fn revoke_parent_delegation_no_attestation_permissions_successful() { let (root_id, root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(revoker.clone()), + delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), @@ -575,7 +575,7 @@ fn revoke_parent_delegation_no_attestation_permissions_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) + .with_delegation_hierarchies(vec![(root_id, root_node)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .with_children(vec![(root_id, vec![parent_id]), (parent_id, vec![delegation_id])]) .build(Some(ext)); @@ -607,7 +607,7 @@ fn revoke_parent_delegation_with_direct_delegation_revoked_successful() { let (root_id, root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(revoker.clone()), + delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), @@ -631,7 +631,7 @@ fn revoke_parent_delegation_with_direct_delegation_revoked_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) + .with_delegation_hierarchies(vec![(root_id, root_node)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .with_children(vec![(root_id, vec![parent_id]), (parent_id, vec![delegation_id])]) .build(Some(ext)); @@ -754,7 +754,7 @@ fn max_parent_lookups_revoke_error() { let (root_id, root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(revoker.clone()), + delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), ); let (parent_delegation_id, parent_delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -776,7 +776,7 @@ fn max_parent_lookups_revoke_error() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) + .with_delegation_hierarchies(vec![(root_id, root_node)]) .with_delegations(vec![ (parent_delegation_id, parent_delegation_node), (delegation_id, delegation_node), @@ -812,7 +812,7 @@ fn revoked_delegation_revoke_error() { let (root_id, root_node) = ( delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_root(revoker.clone()), + delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -829,7 +829,7 @@ fn revoked_delegation_revoke_error() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) + .with_delegation_hierarchies(vec![(root_id, root_node)]) .with_delegations(vec![(delegation_id, delegation_node)]) .with_children(vec![(root_id, vec![delegation_id])]) .build(Some(ext)); diff --git a/pallets/delegation/src/benchmarking.rs b/pallets/delegation/src/benchmarking.rs index 1836759089..72fc175363 100644 --- a/pallets/delegation/src/benchmarking.rs +++ b/pallets/delegation/src/benchmarking.rs @@ -281,8 +281,8 @@ benchmarks! { // TODO: Might want to add variant iterating over children instead of depth at some later point } -impl_benchmark_test_suite! { - Pallet, - crate::mock::ExtBuilder::default().build_with_keystore(None), - crate::mock::Test -} +// impl_benchmark_test_suite! { +// Pallet, +// crate::mock::ExtBuilder::default().build_with_keystore(None), +// crate::mock::Test +// } diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 6b029db595..38cc40967e 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -49,11 +49,6 @@ pub mod pallet { /// Type of a delegation node identifier. pub type DelegationNodeIdOf = ::DelegationNodeId; - /// Type of a delegation hierarchy identifier. - /// - /// Currently, it is just equivalent to the ID of the root node of a given hierarchy. - pub type DelegationHierarchyIdOf = ::DelegationHierarchyId; - /// Type of a delegator or a delegate. pub type DelegatorIdOf = ::DelegationEntityId; @@ -76,7 +71,6 @@ pub mod pallet { >; type DelegationEntityId: Parameter; type DelegationNodeId: Parameter + Copy + AsRef<[u8]> + Eq + PartialEq + Ord + PartialOrd; - type DelegationHierarchyId: Parameter + Copy + Into; type EnsureOrigin: EnsureOrigin, ::Origin>; type Event: From> + IsType<::Event>; #[pallet::constant] @@ -104,26 +98,26 @@ pub mod pallet { /// Delegation hierarchies stored on chain. /// - /// It maps from a hierarchy ID to the hierarchy details. + /// It maps for a (root) node ID to the hierarchy details. #[pallet::storage] #[pallet::getter(fn delegation_hierarchies)] - pub type DelegationHierarchies = StorageMap<_, Blake2_128Concat, DelegationHierarchyIdOf, DelegationHierarchyInfo>; + pub type DelegationHierarchies = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, DelegationHierarchyInfo>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// A new hierarchy has been created. - /// \[creator ID, hierarchy ID, CTYPE hash\] - HierarchyCreated(DelegatorIdOf, DelegationHierarchyIdOf, CtypeHashOf), + /// \[creator ID, root node ID, CTYPE hash\] + HierarchyCreated(DelegatorIdOf, DelegationNodeIdOf, CtypeHashOf), /// A hierarchy has been revoked. - /// \[revoker ID, hierarchy ID\] - HierarchyRevoked(DelegatorIdOf, DelegationHierarchyIdOf), + /// \[revoker ID, root node ID\] + HierarchyRevoked(DelegatorIdOf, DelegationNodeIdOf), /// A new delegation has been created. - /// \[creator ID, hierarchy ID, delegation node ID, parent node ID, + /// \[creator ID, root node ID, delegation node ID, parent node ID, /// delegate ID, permissions\] DelegationCreated( DelegatorIdOf, - DelegationHierarchyIdOf, + DelegationNodeIdOf, DelegationNodeIdOf, DelegationNodeIdOf, DelegatorIdOf, @@ -186,21 +180,21 @@ pub mod pallet { #[pallet::weight(::WeightInfo::create_root())] pub fn create_hierarchy( origin: OriginFor, - hierarchy_id: DelegationHierarchyIdOf, + root_node_id: DelegationNodeIdOf, ctype_hash: CtypeHashOf, ) -> DispatchResult { let creator = ::EnsureOrigin::ensure_origin(origin)?; - ensure!(!>::contains_key(&hierarchy_id), Error::::HierarchyAlreadyExists); + ensure!(!>::contains_key(&root_node_id), Error::::HierarchyAlreadyExists); ensure!( >::contains_key(&ctype_hash), >::CTypeNotFound ); - Self::create_and_store_hierarchy_root(hierarchy_id, DelegationHierarchyInfo:: { ctype_hash }, creator.clone()); + Self::create_and_store_hierarchy_root(root_node_id, DelegationHierarchyInfo:: { ctype_hash }, creator.clone()); - Self::deposit_event(Event::HierarchyCreated(creator, hierarchy_id, ctype_hash)); + Self::deposit_event(Event::HierarchyCreated(creator, root_node_id, ctype_hash)); Ok(()) } @@ -228,7 +222,7 @@ pub mod pallet { pub fn add_delegation( origin: OriginFor, delegation_id: DelegationNodeIdOf, - hierarchy_id: DelegationHierarchyIdOf, + root_node_id: DelegationNodeIdOf, parent_id: DelegationNodeIdOf, delegate: DelegatorIdOf, permissions: Permissions, @@ -237,7 +231,7 @@ pub mod pallet { let delegator = ::EnsureOrigin::ensure_origin(origin)?; // Calculate the hash root - let hash_root = Self::calculate_hash_root(&delegation_id, &hierarchy_id.into(), &Some(parent_id), &permissions); + let hash_root = Self::calculate_hash_root(&delegation_id, &root_node_id.into(), &Some(parent_id), &permissions); // Verify that the hash root signature is correct. DelegationSignatureVerificationOf::::verify(&delegate, &hash_root.encode(), &delegate_signature) @@ -261,11 +255,11 @@ pub mod pallet { Error::::UnauthorizedDelegation ); - Self::store_delegation_under_parent(&delegation_id, DelegationNode::new_node(hierarchy_id, parent_id, delegate.clone(), permissions), &parent_id, parent_node); + Self::store_delegation_under_parent(delegation_id, DelegationNode::new_node(root_node_id, parent_id, delegate.clone(), permissions), parent_id, parent_node); Self::deposit_event(Event::DelegationCreated( delegator, - hierarchy_id, + root_node_id, delegation_id, parent_id, delegate, @@ -291,12 +285,12 @@ pub mod pallet { #[pallet::weight(::WeightInfo::revoke_root(*max_children))] pub fn revoke_hierarchy( origin: OriginFor, - hierarchy_id: DelegationHierarchyIdOf, + root_node_id: DelegationNodeIdOf, max_children: u32, ) -> DispatchResultWithPostInfo { let invoker = ::EnsureOrigin::ensure_origin(origin)?; - let hierarchy_root_node = >::get(&hierarchy_id.into()).ok_or(Error::::HierarchyNotFound)?; + let hierarchy_root_node = >::get(&root_node_id).ok_or(Error::::HierarchyNotFound)?; ensure!(hierarchy_root_node.details.owner == invoker, Error::::UnauthorizedRevocation); @@ -307,11 +301,11 @@ pub mod pallet { let consumed_weight: Weight = if !hierarchy_root_node.details.revoked { // Recursively revoke all children - let (_, post_weight) = Self::revoke_children(&hierarchy_id.into(), &invoker, max_children)?; + let (_, post_weight) = Self::revoke_children(&root_node_id.into(), &invoker, max_children)?; // If we didn't return an ExceededRevocationBounds error, we can revoke the root // too. - Self::revoke_and_store_hierarchy_root(hierarchy_id, hierarchy_root_node); + Self::revoke_and_store_hierarchy_root(root_node_id, hierarchy_root_node); // We don't cancel the delegation_hierarchy from storage. post_weight.saturating_add(T::DbWeight::get().writes(1)) @@ -319,7 +313,7 @@ pub mod pallet { 0 }; - Self::deposit_event(Event::HierarchyRevoked(invoker, hierarchy_id)); + Self::deposit_event(Event::HierarchyRevoked(invoker, root_node_id)); Ok(Some(consumed_weight.saturating_add(T::DbWeight::get().reads(1))).into()) } @@ -406,28 +400,28 @@ impl Pallet { T::Hashing::hash(&hashed_values) } - fn create_and_store_hierarchy_root(hierarchy_id: DelegationHierarchyIdOf, hierarchy_info: DelegationHierarchyInfo, hierarchy_owner: DelegatorIdOf) { - let root_node = DelegationNode::new_root_node(hierarchy_id, hierarchy_owner); - >::insert(hierarchy_id.into(), root_node); - >::insert(hierarchy_id, hierarchy_info); + fn create_and_store_hierarchy_root(root_id: DelegationNodeIdOf, hierarchy_info: DelegationHierarchyInfo, hierarchy_owner: DelegatorIdOf) { + let root_node = DelegationNode::new_root_node(root_id, hierarchy_owner); + >::insert(root_id.into(), root_node); + >::insert(root_id, hierarchy_info); } - fn store_delegation_under_parent(delegation_id: &DelegationNodeIdOf, delegation_node: DelegationNode, parent_id: &DelegationNodeIdOf, mut parent_node: DelegationNode) { + fn store_delegation_under_parent(delegation_id: DelegationNodeIdOf, delegation_node: DelegationNode, parent_id: DelegationNodeIdOf, mut parent_node: DelegationNode) { >::insert( delegation_id, delegation_node ); // Add the new node as a child of that node - parent_node.add_child(*delegation_id); + parent_node.add_child(delegation_id); >::insert( parent_id, parent_node ); } - fn revoke_and_store_hierarchy_root(hierarchy_id: DelegationHierarchyIdOf, mut root_node: DelegationNode) { + fn revoke_and_store_hierarchy_root(root_id: DelegationNodeIdOf, mut root_node: DelegationNode) { root_node.details.revoked = true; - >::insert(hierarchy_id.into(), root_node); + >::insert(root_id, root_node); } /// Check if an identity is the owner of the given delegation node or any diff --git a/pallets/delegation/src/mock.rs b/pallets/delegation/src/mock.rs index 36410c3d56..3ec4cff2fa 100644 --- a/pallets/delegation/src/mock.rs +++ b/pallets/delegation/src/mock.rs @@ -28,7 +28,7 @@ use sp_runtime::{ traits::{BlakeTwo256, IdentifyAccount, IdentityLookup, Verify}, MultiSignature, MultiSigner, }; -use sp_std::sync::Arc; +use sp_std::{collections::btree_set::BTreeSet, sync::Arc}; #[cfg(test)] use codec::Encode; @@ -43,6 +43,7 @@ pub type Block = frame_system::mocking::MockBlock; pub type TestCtypeOwner = kilt_primitives::AccountId; pub type TestCtypeHash = kilt_primitives::Hash; pub type TestDelegationNodeId = kilt_primitives::Hash; +pub type TestDelegationHierarchyId = TestDelegationNodeId; pub type TestDelegatorId = TestCtypeOwner; pub type TestDelegateSignature = MultiSignature; @@ -107,6 +108,7 @@ impl Config for Test { type DelegationSignatureVerification = Self; type DelegationEntityId = TestDelegatorId; type DelegationNodeId = TestDelegationNodeId; + type DelegationHierarchyId = TestDelegationHierarchyId; type EnsureOrigin = EnsureSigned; type Event = (); type MaxSignatureByteLength = MaxSignatureByteLength; @@ -143,8 +145,8 @@ const ALICE_SEED: [u8; 32] = [0u8; 32]; const BOB_SEED: [u8; 32] = [1u8; 32]; const CHARLIE_SEED: [u8; 32] = [2u8; 32]; -const DEFAULT_ROOT_ID_SEED: u64 = 1u64; -const ALTERNATIVE_ROOT_ID_SEED: u64 = 2u64; +const DEFAULT_HIERARCHY_ID_SEED: u64 = 1u64; +const ALTERNATIVE_HIERARCHY_ID_SEED: u64 = 2u64; const DEFAULT_DELEGATION_ID_SEED: u64 = 3u64; const ALTERNATIVE_DELEGATION_ID_SEED: u64 = 4u64; const DEFAULT_DELEGATION_ID_2_SEED: u64 = 3u64; @@ -186,27 +188,27 @@ pub fn get_charlie_sr25519() -> sr25519::Pair { sr25519::Pair::from_seed(&CHARLIE_SEED) } -pub fn get_delegation_root_id(default: bool) -> TestDelegationNodeId { +pub fn get_delegation_hierarchy_id(default: bool) -> TestDelegationHierarchyId { if default { - TestCtypeHash::from_low_u64_be(DEFAULT_ROOT_ID_SEED) + TestDelegationHierarchyId::from_low_u64_be(DEFAULT_HIERARCHY_ID_SEED) } else { - TestCtypeHash::from_low_u64_be(ALTERNATIVE_ROOT_ID_SEED) + TestDelegationHierarchyId::from_low_u64_be(ALTERNATIVE_HIERARCHY_ID_SEED) } } pub fn get_delegation_id(default: bool) -> TestDelegationNodeId { if default { - TestCtypeHash::from_low_u64_be(DEFAULT_DELEGATION_ID_SEED) + TestDelegationNodeId::from_low_u64_be(DEFAULT_DELEGATION_ID_SEED) } else { - TestCtypeHash::from_low_u64_be(ALTERNATIVE_DELEGATION_ID_SEED) + TestDelegationNodeId::from_low_u64_be(ALTERNATIVE_DELEGATION_ID_SEED) } } pub fn get_delegation_id_2(default: bool) -> TestDelegationNodeId { if default { - TestCtypeHash::from_low_u64_be(DEFAULT_DELEGATION_ID_2_SEED) + TestDelegationNodeId::from_low_u64_be(DEFAULT_DELEGATION_ID_2_SEED) } else { - TestCtypeHash::from_low_u64_be(ALTERNATIVE_DELEGATION_ID_2_SEED) + TestDelegationNodeId::from_low_u64_be(ALTERNATIVE_DELEGATION_ID_2_SEED) } } @@ -215,24 +217,23 @@ pub(crate) fn hash_to_u8(hash: T) -> Vec { hash.encode() } -pub struct DelegationRootCreationDetails { - pub root_id: TestDelegationNodeId, +pub struct DelegationHierarchyCreationDetails { + pub id: TestDelegationHierarchyId, pub ctype_hash: TestCtypeHash, } -pub fn generate_base_delegation_root_creation_details( - root_id: TestDelegationNodeId, - root_node: DelegationRoot, -) -> DelegationRootCreationDetails { - DelegationRootCreationDetails { - ctype_hash: root_node.ctype_hash, - root_id, +pub fn generate_base_delegation_hierarchy_creation_details( + id: TestDelegationHierarchyId +) -> DelegationHierarchyCreationDetails { + DelegationHierarchyCreationDetails { + id, + ctype_hash: ctype_mock::get_ctype_hash(true) } } pub struct DelegationCreationDetails { pub delegation_id: TestDelegationNodeId, - pub root_id: TestDelegationNodeId, + pub hierarchy_id: TestDelegationHierarchyId, pub parent_id: Option, pub delegate: TestDelegatorId, pub permissions: Permissions, @@ -247,23 +248,23 @@ pub fn generate_base_delegation_creation_details( DelegationCreationDetails { delegation_id, parent_id: delegation_node.parent, - root_id: delegation_node.root_id, - delegate: delegation_node.owner, + hierarchy_id: delegation_node.hierarchy_id, + delegate: delegation_node.details.owner, delegate_signature, - permissions: delegation_node.permissions, + permissions: delegation_node.details.permissions, } } -pub struct DelegationRootRevocationDetails { - pub root_id: TestDelegationNodeId, +pub struct DelegationHierarchyRevocationDetails { + pub id: TestDelegationHierarchyId, pub max_children: u32, } -pub fn generate_base_delegation_root_revocation_details( - root_id: TestDelegationNodeId, -) -> DelegationRootRevocationDetails { - DelegationRootRevocationDetails { - root_id, +pub fn generate_base_delegation_hierarchy_revocation_details( + id: TestDelegationHierarchyId, +) -> DelegationHierarchyRevocationDetails { + DelegationHierarchyRevocationDetails { + id, max_children: 0u32, } } @@ -282,49 +283,48 @@ pub fn generate_base_delegation_revocation_details(delegation_id: TestDelegation } } -pub fn generate_base_delegation_root(owner: TestDelegatorId) -> DelegationRoot { - DelegationRoot { - owner, +pub fn generate_base_delegation_hierarchy(owner: TestDelegatorId) -> DelegationHierarchyInfo { + DelegationHierarchyInfo { ctype_hash: ctype_mock::get_ctype_hash(true), - revoked: false, } } -pub fn generate_base_delegation_node(root_id: TestDelegationNodeId, owner: TestDelegatorId) -> DelegationNode { +pub fn generate_base_delegation_node(hierarchy_id: TestDelegationHierarchyId, owner: TestDelegatorId) -> DelegationNode { DelegationNode { - owner, + details: DelegationDetails { + owner, + permissions: Permissions::DELEGATE, + revoked: false, + }, + children: BTreeSet::new(), + hierarchy_id, parent: None, - root_id, - permissions: Permissions::DELEGATE, - revoked: false, } } #[derive(Clone)] pub struct ExtBuilder { ctype_builder: Option, - root_delegations_stored: Vec<(TestDelegationNodeId, DelegationRoot)>, + delegation_hierarchies_stored: Vec<(TestDelegationHierarchyId, DelegationHierarchyInfo, DelegationDetails)>, delegations_stored: Vec<(TestDelegationNodeId, DelegationNode)>, - children_stored: Vec<(TestDelegationNodeId, Vec)>, } impl Default for ExtBuilder { fn default() -> Self { Self { ctype_builder: None, - root_delegations_stored: vec![], + delegation_hierarchies_stored: vec![], delegations_stored: vec![], - children_stored: vec![], } } } impl ExtBuilder { - pub fn with_root_delegations( + pub fn with_delegation_hierarchies( mut self, - root_delegations: Vec<(TestDelegationNodeId, DelegationRoot)>, + delegation_hierarchies: Vec<(TestDelegationHierarchyId, DelegationHierarchyInfo, DelegationDetails)>, ) -> Self { - self.root_delegations_stored = root_delegations; + self.delegation_hierarchies_stored = delegation_hierarchies; self } @@ -333,11 +333,6 @@ impl ExtBuilder { self } - pub fn with_children(mut self, children: Vec<(TestDelegationNodeId, Vec)>) -> Self { - self.children_stored = children; - self - } - pub fn build(self, ext: Option) -> sp_io::TestExternalities { let mut ext = if let Some(ext) = ext { ext @@ -346,10 +341,10 @@ impl ExtBuilder { sp_io::TestExternalities::new(storage) }; - if !self.root_delegations_stored.is_empty() { + if !self.delegation_hierarchies_stored.is_empty() { ext.execute_with(|| { - self.root_delegations_stored.iter().for_each(|root_delegation| { - delegation::Roots::::insert(root_delegation.0, root_delegation.1.clone()); + self.delegation_hierarchies_stored.iter().for_each(|delegation_hierarchy| { + delegation::Pallet::create_and_store_hierarchy_root(delegation_hierarchy.0, delegation_hierarchy.1.clone(), delegation_hierarchy.2.owner.clone()); }) }); } @@ -357,15 +352,10 @@ impl ExtBuilder { if !self.delegations_stored.is_empty() { ext.execute_with(|| { self.delegations_stored.iter().for_each(|del| { - delegation::Delegations::::insert(del.0, del.1.clone()); - }) - }); - } - - if !self.children_stored.is_empty() { - ext.execute_with(|| { - self.children_stored.iter().for_each(|child| { - delegation::Children::::insert(child.0, child.1.clone()); + if let Some(parent_node_id) = del.1.parent { + let mut parent_node = delegation::DelegationNodes::::get(&parent_node_id).unwrap(); + delegation::Pallet::store_delegation_under_parent(del.0, del.1.clone(), parent_node_id, parent_node); + } }) }); } diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index 69c37f943f..7f278689a1 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -20,7 +20,7 @@ use codec::Encode; use frame_support::{assert_err, assert_noop, assert_ok}; use sp_core::Pair; -use crate::{self as delegation, mock::*}; +use crate::{self as delegation, DelegationHierarchyInfo, mock::*}; use ctype::mock as ctype_mock; // submit_delegation_root_creation_operation() @@ -30,1654 +30,1656 @@ fn create_root_delegation_successful() { let creator_keypair = get_alice_ed25519(); let creator = get_ed25519_account(creator_keypair.public()); - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(creator.clone()), - ); + let hierarchy_id = get_delegation_hierarchy_id(true); - let operation = generate_base_delegation_root_creation_details(root_id, root_node.clone()); + let operation = generate_base_delegation_hierarchy_creation_details(hierarchy_id); let mut ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) + .with_ctypes(vec![(operation.ctype_hash.clone(), creator.clone())]) .build(None); ext.execute_with(|| { - assert_ok!(Delegation::create_root( + assert_ok!(Delegation::create_hierarchy( get_origin(creator.clone()), - operation.root_id, + operation.id, operation.ctype_hash )); }); - let stored_delegation_root = ext - .execute_with(|| Delegation::roots(&operation.root_id).expect("Delegation root should be present on chain.")); + let stored_hierarchy_details = ext.execute_with(|| Delegation::delegation_hierarchies(&hierarchy_id).expect("Delegation hierarchy should be present on chain.")); + assert_eq!(stored_hierarchy_details.ctype_hash, operation.ctype_hash); - assert_eq!(stored_delegation_root.owner, creator); - assert_eq!(stored_delegation_root.ctype_hash, operation.ctype_hash); - assert!(!stored_delegation_root.revoked); -} - -#[test] -fn duplicate_create_root_delegation_error() { - let creator_keypair = get_alice_ed25519(); - let creator = get_ed25519_account(creator_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(creator.clone()), - ); - - let operation = generate_base_delegation_root_creation_details(root_id, root_node.clone()); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_err!( - Delegation::create_root(get_origin(creator.clone()), operation.root_id, operation.ctype_hash), - delegation::Error::::RootAlreadyExists - ); - }); -} - -#[test] -fn ctype_not_found_create_root_delegation_error() { - let creator_keypair = get_alice_ed25519(); - let creator = get_ed25519_account(creator_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(creator.clone()), - ); - - let operation = generate_base_delegation_root_creation_details(root_id, root_node); - - // No CTYPE stored, - let mut ext = ExtBuilder::default().build(None); - - ext.execute_with(|| { - assert_err!( - Delegation::create_root(get_origin(creator.clone()), operation.root_id, operation.ctype_hash), - ctype::Error::::CTypeNotFound - ); - }); -} - -// submit_delegation_creation_operation() - -#[test] -fn create_delegation_no_parent_successful() { - let creator_keypair = get_alice_ed25519(); - let creator = get_ed25519_account(creator_keypair.public()); - let delegate_keypair = get_bob_sr25519(); - let delegate = get_sr25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(creator.clone()), - ); - let (delegation_id, delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, delegate), - ); - - let delegation_info = Delegation::calculate_hash( - &delegation_id, - &delegation_node.root_id, - &delegation_node.parent, - &delegation_node.permissions, - ); - - let delegate_signature = delegate_keypair.sign(&hash_to_u8(delegation_info)); - - let operation = - generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_ok!(Delegation::add_delegation( - get_origin(creator.clone()), - operation.delegation_id, - operation.root_id, - operation.parent_id, - operation.delegate.clone(), - operation.permissions, - operation.delegate_signature.clone().encode(), - )); - }); - - let stored_delegation = ext.execute_with(|| { - Delegation::delegations(&operation.delegation_id).expect("Delegation should be present on chain.") - }); - - assert_eq!(stored_delegation.root_id, operation.root_id); - assert_eq!(stored_delegation.parent, operation.parent_id); - assert_eq!(stored_delegation.owner, operation.delegate); - assert_eq!(stored_delegation.permissions, operation.permissions); - assert!(!stored_delegation.revoked); - - // Verify that the root has the new delegation among its children - let stored_root_children = ext.execute_with(|| { - Delegation::children(&operation.root_id).expect("Delegation root children should be present on chain.") - }); - - assert_eq!(stored_root_children, vec![operation.delegation_id]); -} - -#[test] -fn create_delegation_with_parent_successful() { - let creator_keypair = get_alice_ed25519(); - let creator = get_ed25519_account(creator_keypair.public()); - let delegate_keypair = get_bob_sr25519(); - let delegate = get_sr25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(creator.clone()), - ); - let (parent_delegation_id, parent_delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, creator.clone()), - ); - let (delegation_id, mut delegation_node) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate.clone()), - ); - delegation_node.parent = Some(parent_delegation_id); - - let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( - &delegation_id, - &delegation_node.root_id, - &delegation_node.parent, - &delegation_node.permissions, - ))); - - let operation = - generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![(parent_delegation_id, parent_delegation_node)]) - .with_children(vec![(root_id, vec![(parent_delegation_id)])]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_ok!(Delegation::add_delegation( - get_origin(creator.clone()), - operation.delegation_id, - operation.root_id, - operation.parent_id, - delegate.clone(), - operation.permissions, - operation.delegate_signature.clone().encode(), - )); - }); - - let stored_delegation = ext.execute_with(|| { - Delegation::delegations(&operation.delegation_id).expect("Delegation should be present on chain.") - }); - - assert_eq!(stored_delegation.root_id, operation.root_id); - assert_eq!(stored_delegation.parent, operation.parent_id); - assert_eq!(stored_delegation.owner, operation.delegate); - assert_eq!(stored_delegation.permissions, operation.permissions); - assert!(!stored_delegation.revoked); - - // Verify that the parent has the new delegation among its children - let stored_parent_children = ext.execute_with(|| { - Delegation::children(&operation.parent_id.unwrap()) - .expect("Delegation parent children should be present on chain.") - }); - - assert_eq!(stored_parent_children, vec![delegation_id]); -} - -#[test] -fn invalid_delegate_signature_create_delegation_error() { - let creator_keypair = get_alice_ed25519(); - let creator = get_ed25519_account(creator_keypair.public()); - let alternative_keypair = get_alice_sr25519(); - let delegate_keypair = get_bob_sr25519(); - let delegate = get_sr25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(creator.clone()), - ); - let (delegation_id, delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, delegate.clone()), - ); - - let delegate_signature = alternative_keypair.sign(&hash_to_u8(Delegation::calculate_hash( - &delegation_id, - &delegation_node.root_id, - &delegation_node.parent, - &delegation_node.permissions, - ))); - - let operation = - generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_err!( - Delegation::add_delegation( - get_origin(creator.clone()), - operation.delegation_id, - operation.root_id, - operation.parent_id, - delegate.clone(), - operation.permissions, - operation.delegate_signature.clone().encode(), - ), - delegation::Error::::InvalidDelegateSignature - ); - }); -} - -#[test] -fn duplicate_delegation_create_delegation_error() { - let creator_keypair = get_alice_ed25519(); - let creator = get_ed25519_account(creator_keypair.public()); - let delegate_keypair = get_bob_sr25519(); - let delegate = get_sr25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(creator.clone()), - ); - let (delegation_id, delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, delegate.clone()), - ); - - let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( - &delegation_id, - &delegation_node.root_id, - &delegation_node.parent, - &delegation_node.permissions, - ))); - - let operation = - generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node.clone()); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![delegation_id])]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_err!( - Delegation::add_delegation( - get_origin(creator.clone()), - operation.delegation_id, - operation.root_id, - operation.parent_id, - delegate.clone(), - operation.permissions, - operation.delegate_signature.clone().encode(), - ), - delegation::Error::::DelegationAlreadyExists - ); - }); -} - -#[test] -fn root_not_existing_create_delegation_error() { - let creator_keypair = get_alice_ed25519(); - let creator = get_ed25519_account(creator_keypair.public()); - let delegate_keypair = get_bob_sr25519(); - let delegate = get_sr25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(creator.clone()), - ); - let (delegation_id, delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, delegate.clone()), - ); - - let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( - &delegation_id, - &delegation_node.root_id, - &delegation_node.parent, - &delegation_node.permissions, - ))); - - let operation = - generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) - .build(None); - // No delegations added to the pallet storage - let mut ext = ExtBuilder::default().build(Some(ext)); - - ext.execute_with(|| { - assert_err!( - Delegation::add_delegation( - get_origin(creator.clone()), - operation.delegation_id, - operation.root_id, - operation.parent_id, - delegate.clone(), - operation.permissions, - operation.delegate_signature.clone().encode(), - ), - delegation::Error::::RootNotFound - ); - }); -} - -#[test] -fn parent_not_existing_create_delegation_error() { - let creator_keypair = get_alice_ed25519(); - let creator = get_ed25519_account(creator_keypair.public()); - let delegate_keypair = get_bob_sr25519(); - let delegate = get_sr25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(creator.clone()), - ); - let alternative_parent_id = get_delegation_id(false); - let (delegation_id, mut delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, delegate.clone()), - ); - delegation_node.parent = Some(alternative_parent_id); - - let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( - &delegation_id, - &delegation_node.root_id, - &delegation_node.parent, - &delegation_node.permissions, - ))); - - let operation = - generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_err!( - Delegation::add_delegation( - get_origin(creator.clone()), - operation.delegation_id, - operation.root_id, - operation.parent_id, - delegate.clone(), - operation.permissions, - operation.delegate_signature.clone().encode(), - ), - delegation::Error::::ParentDelegationNotFound - ); - }); -} - -#[test] -fn not_owner_of_parent_create_delegation_error() { - let creator_keypair = get_alice_ed25519(); - let creator = get_ed25519_account(creator_keypair.public()); - let alternative_owner_keypair = get_charlie_ed25519(); - let alternative_owner = get_ed25519_account(alternative_owner_keypair.public()); - let delegate_keypair = get_bob_sr25519(); - let delegate = get_sr25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(creator.clone()), - ); - let (parent_delegation_id, parent_delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, alternative_owner), - ); - let (delegation_id, mut delegation_node) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate.clone()), - ); - delegation_node.parent = Some(parent_delegation_id); - - let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( - &delegation_id, - &delegation_node.root_id, - &delegation_node.parent, - &delegation_node.permissions, - ))); - - let operation = - generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![(parent_delegation_id, parent_delegation_node)]) - .with_children(vec![(root_id, vec![parent_delegation_id])]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_err!( - Delegation::add_delegation( - get_origin(creator.clone()), - operation.delegation_id, - operation.root_id, - operation.parent_id, - delegate.clone(), - operation.permissions, - operation.delegate_signature.clone().encode(), - ), - delegation::Error::::NotOwnerOfParentDelegation - ); - }); -} - -#[test] -fn unauthorised_delegation_create_delegation_error() { - let creator_keypair = get_alice_ed25519(); - let creator = get_ed25519_account(creator_keypair.public()); - let delegate_keypair = get_bob_sr25519(); - let delegate = get_sr25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(creator.clone()), - ); - let (parent_delegation_id, mut parent_delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, creator.clone()), - ); - parent_delegation_node.permissions = delegation::Permissions::ATTEST; - let (delegation_id, mut delegation_node) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate.clone()), - ); - delegation_node.parent = Some(parent_delegation_id); - - let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( - &delegation_id, - &delegation_node.root_id, - &delegation_node.parent, - &delegation_node.permissions, - ))); - - let operation = - generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![(parent_delegation_id, parent_delegation_node)]) - .with_children(vec![(root_id, vec![parent_delegation_id])]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_err!( - Delegation::add_delegation( - get_origin(creator.clone()), - operation.delegation_id, - operation.root_id, - operation.parent_id, - delegate.clone(), - operation.permissions, - operation.delegate_signature.clone().encode(), - ), - delegation::Error::::UnauthorizedDelegation - ); - }); -} - -#[test] -fn not_owner_of_root_create_delegation_error() { - let creator_keypair = get_alice_ed25519(); - let creator = get_ed25519_account(creator_keypair.public()); - let alternative_owner_keypair = get_charlie_ed25519(); - let alternative_owner = get_ed25519_account(alternative_owner_keypair.public()); - let delegate_keypair = get_bob_sr25519(); - let delegate = get_sr25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(alternative_owner), - ); - let (delegation_id, delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, delegate.clone()), - ); - - let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( - &delegation_id, - &delegation_node.root_id, - &delegation_node.parent, - &delegation_node.permissions, - ))); - - let operation = - generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_noop!( - Delegation::add_delegation( - get_origin(creator.clone()), - operation.delegation_id, - operation.root_id, - operation.parent_id, - delegate.clone(), - operation.permissions, - operation.delegate_signature.clone().encode(), - ), - delegation::Error::::NotOwnerOfRootDelegation - ); - }); -} - -// submit_delegation_root_revocation_operation() -#[test] -fn empty_revoke_root_successful() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(revoker.clone()), - ); - - let mut operation = generate_base_delegation_root_revocation_details(root_id); - operation.max_children = 2u32; - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_ok!(Delegation::revoke_root( - get_origin(revoker.clone()), - operation.root_id, - operation.max_children - )); - }); - - let stored_delegation_root = ext - .execute_with(|| Delegation::roots(&operation.root_id).expect("Delegation root should be present on chain.")); - assert!(stored_delegation_root.revoked); -} - -#[test] -fn list_hierarchy_revoke_root_successful() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - let delegate_keypair = get_bob_ed25519(); - let delegate = get_ed25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(revoker.clone()), - ); - let (parent_delegation_id, parent_delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, revoker.clone()), - ); - let (delegation_id, mut delegation_node) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate), - ); - delegation_node.parent = Some(parent_delegation_id); - - let mut operation = generate_base_delegation_root_revocation_details(root_id); - operation.max_children = 2u32; - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (parent_delegation_id, parent_delegation_node), - (delegation_id, delegation_node), - ]) - .with_children(vec![ - // Root -> Parent -> Delegation - (root_id, vec![parent_delegation_id]), - (parent_delegation_id, vec![delegation_id]), - ]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_ok!(Delegation::revoke_root( - get_origin(revoker.clone()), - operation.root_id, - operation.max_children - )); - }); - - let stored_delegation_root = ext - .execute_with(|| Delegation::roots(&operation.root_id).expect("Delegation root should be present on chain.")); - assert!(stored_delegation_root.revoked); - - let stored_parent_delegation = ext.execute_with(|| { - Delegation::delegations(&parent_delegation_id).expect("Parent delegation should be present on chain.") - }); - assert!(stored_parent_delegation.revoked); - - let stored_delegation = - ext.execute_with(|| Delegation::delegations(&delegation_id).expect("Delegation should be present on chain.")); - assert!(stored_delegation.revoked); -} - -#[test] -fn tree_hierarchy_revoke_root_successful() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - let delegate_keypair = get_bob_ed25519(); - let delegate = get_ed25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(revoker.clone()), - ); - let (delegation_id_1, delegation_node_1) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, revoker.clone()), - ); - let (delegation_id_2, delegation_node_2) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate), - ); - - let mut operation = generate_base_delegation_root_revocation_details(root_id); - operation.max_children = 2u32; - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (delegation_id_1, delegation_node_1), - (delegation_id_2, delegation_node_2), - ]) - .with_children(vec![ - // Root -> Delegation 1 && Delegation 2 - (root_id, vec![delegation_id_1, delegation_id_2]), - ]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_ok!(Delegation::revoke_root( - get_origin(revoker.clone()), - operation.root_id, - operation.max_children - )); - }); - - let stored_delegation_root = ext - .execute_with(|| Delegation::roots(&operation.root_id).expect("Delegation root should be present on chain.")); - assert!(stored_delegation_root.revoked); - - let stored_delegation_1 = ext - .execute_with(|| Delegation::delegations(&delegation_id_1).expect("Delegation 1 should be present on chain.")); - assert!(stored_delegation_1.revoked); - - let stored_delegation_2 = ext - .execute_with(|| Delegation::delegations(&delegation_id_2).expect("Delegation 2 should be present on chain.")); - assert!(stored_delegation_2.revoked); -} - -#[test] -fn greater_max_revocations_revoke_root_successful() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - let delegate_keypair = get_alice_ed25519(); - let delegate = get_ed25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(revoker.clone()), - ); - let (delegation_id, delegation_node) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate), - ); - - let mut operation = generate_base_delegation_root_revocation_details(root_id); - operation.max_children = MaxRevocations::get(); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![ - // Root -> Delegation - (root_id, vec![delegation_id]), - ]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_ok!(Delegation::revoke_root( - get_origin(revoker.clone()), - operation.root_id, - operation.max_children - )); - }); - - let stored_delegation_root = ext - .execute_with(|| Delegation::roots(&operation.root_id).expect("Delegation root should be present on chain.")); - assert!(stored_delegation_root.revoked); + let stored_delegation_root = ext.execute_with(|| Delegation::delegation_nodes(&hierarchy_id).expect("Delegation root should be present on chain.")); - let stored_delegation = - ext.execute_with(|| Delegation::delegations(&delegation_id).expect("Delegation should be present on chain.")); - assert!(stored_delegation.revoked); -} - -#[test] -fn root_not_found_revoke_root_error() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - - let root_id = get_delegation_root_id(true); - - let operation = generate_base_delegation_root_revocation_details(root_id); - - let mut ext = ExtBuilder::default().build(None); - - ext.execute_with(|| { - assert_noop!( - Delegation::revoke_root(get_origin(revoker.clone()), operation.root_id, operation.max_children), - delegation::Error::::RootNotFound - ); - }); -} - -#[test] -fn different_root_creator_revoke_root_error() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - let alternative_revoker_keypair = get_charlie_ed25519(); - let alternative_revoker = get_ed25519_account(alternative_revoker_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(alternative_revoker), - ); - - let operation = generate_base_delegation_root_revocation_details(root_id); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_noop!( - Delegation::revoke_root(get_origin(revoker.clone()), operation.root_id, operation.max_children), - delegation::Error::::UnauthorizedRevocation - ); - }); -} - -#[test] -fn too_small_max_revocations_revoke_root_error() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - let delegate_keypair = get_alice_ed25519(); - let delegate = get_ed25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(revoker.clone()), - ); - let (delegation_id, delegation_node) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate), - ); - - let mut operation = generate_base_delegation_root_revocation_details(root_id); - operation.max_children = 0u32; - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![ - // Root -> Delegation - (root_id, vec![delegation_id]), - ]) - .build(Some(ext)); - ext.execute_with(|| { - assert_noop!( - Delegation::revoke_root(get_origin(revoker.clone()), operation.root_id, operation.max_children), - delegation::Error::::ExceededRevocationBounds - ); - }); + assert_eq!(stored_delegation_root.hierarchy_id, hierarchy_id); + assert_eq!(stored_delegation_root.parent, None); + assert_eq!(stored_delegation_root.children.len(), 0); + assert_eq!(stored_delegation_root.details.owner, creator); + assert!(!stored_delegation_root.details.revoked); } -#[test] -fn exact_children_max_revocations_revoke_root_error() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - let delegate_keypair = get_alice_ed25519(); - let delegate = get_ed25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(revoker.clone()), - ); - let (delegation_id_1, delegation_node_1) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, delegate.clone()), - ); - let (delegation_id_2, mut delegation_node_2) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate.clone()), - ); - delegation_node_2.parent = Some(delegation_id_1); - let (delegation_id_3, mut delegation_node_3) = ( - get_delegation_root_id(false), - generate_base_delegation_node(root_id, delegate), - ); - delegation_node_3.parent = Some(delegation_id_1); - - let mut operation = generate_base_delegation_root_revocation_details(root_id); - operation.max_children = 2u32; - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (delegation_id_1, delegation_node_1), - (delegation_id_2, delegation_node_2), - (delegation_id_3, delegation_node_3), - ]) - .with_children(vec![ - // Root -> Delegation 1 -> Delegation 2 && Delegation 3 - (root_id, vec![delegation_id_1]), - (delegation_id_1, vec![delegation_id_2, delegation_id_3]), - ]) - .build(Some(ext)); - - ext.execute_with(|| { - // assert_err and not asser_noop becase the storage is indeed changed, even tho - // partially - assert_err!( - Delegation::revoke_root(get_origin(revoker.clone()), operation.root_id, operation.max_children), - delegation::Error::::ExceededRevocationBounds - ); - }); - - let stored_delegation_root = ext - .execute_with(|| Delegation::roots(&operation.root_id).expect("Delegation root should be present on chain.")); - assert!(!stored_delegation_root.revoked); - - let stored_delegation_1 = ext - .execute_with(|| Delegation::delegations(&delegation_id_1).expect("Delegation 1 should be present on chain.")); - assert!(!stored_delegation_1.revoked); - - // Only this leaf should have been revoked as it is the first child of - // delegation_1 - let stored_delegation_2 = ext - .execute_with(|| Delegation::delegations(&delegation_id_2).expect("Delegation 2 should be present on chain.")); - assert!(stored_delegation_2.revoked); - - let stored_delegation_3 = ext - .execute_with(|| Delegation::delegations(&delegation_id_3).expect("Delegation 3 should be present on chain.")); - assert!(!stored_delegation_3.revoked); -} - -// submit_delegation_revocation_operation() - -#[test] -fn direct_owner_revoke_delegation_successful() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - let delegate_keypair = get_alice_ed25519(); - let delegate = get_ed25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(revoker.clone()), - ); - let (parent_delegation_id, parent_delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, revoker.clone()), - ); - let (delegation_id, mut delegation_node) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate), - ); - delegation_node.parent = Some(parent_delegation_id); - - let mut operation = generate_base_delegation_revocation_details(parent_delegation_id); - operation.max_revocations = 2u32; - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - // Root -> Parent -> Child - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (parent_delegation_id, parent_delegation_node), - (delegation_id, delegation_node), - ]) - .with_children(vec![ - (root_id, vec![parent_delegation_id]), - (parent_delegation_id, vec![delegation_id]), - ]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_ok!(Delegation::revoke_delegation( - get_origin(revoker.clone()), - operation.delegation_id, - operation.max_parent_checks, - operation.max_revocations - )); - }); - - let stored_parent_delegation = ext.execute_with(|| { - Delegation::delegations(&parent_delegation_id).expect("Parent delegation should be present on chain.") - }); - assert!(stored_parent_delegation.revoked); - - let stored_child_delegation = ext.execute_with(|| { - Delegation::delegations(&delegation_id).expect("Child delegation should be present on chain.") - }); - assert!(stored_child_delegation.revoked); -} - -#[test] -fn parent_owner_revoke_delegation_successful() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - let delegate_keypair = get_alice_ed25519(); - let delegate = get_ed25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(revoker.clone()), - ); - let (parent_delegation_id, parent_delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, revoker.clone()), - ); - let (delegation_id, mut delegation_node) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate), - ); - delegation_node.parent = Some(parent_delegation_id); - - let mut operation = generate_base_delegation_revocation_details(delegation_id); - operation.max_parent_checks = 1u32; - operation.max_revocations = 1u32; - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (parent_delegation_id, parent_delegation_node), - (delegation_id, delegation_node), - ]) - .with_children(vec![ - (root_id, vec![parent_delegation_id]), - (parent_delegation_id, vec![delegation_id]), - ]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_ok!(Delegation::revoke_delegation( - get_origin(revoker.clone()), - operation.delegation_id, - operation.max_parent_checks, - operation.max_revocations - )); - }); - - let stored_parent_delegation = ext.execute_with(|| { - Delegation::delegations(&parent_delegation_id).expect("Parent delegation should be present on chain.") - }); - assert!(!stored_parent_delegation.revoked); - - let stored_child_delegation = ext.execute_with(|| { - Delegation::delegations(&delegation_id).expect("Child delegation should be present on chain.") - }); - assert!(stored_child_delegation.revoked); -} - -#[test] -fn delegation_not_found_revoke_delegation_error() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(revoker.clone()), - ); - let delegation_id = get_delegation_id(true); - - let operation = generate_base_delegation_revocation_details(delegation_id); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_noop!( - Delegation::revoke_delegation( - get_origin(revoker.clone()), - operation.delegation_id, - operation.max_parent_checks, - operation.max_revocations - ), - delegation::Error::::DelegationNotFound - ); - }); -} - -#[test] -fn not_delegating_revoke_delegation_error() { - let owner_keypair = get_alice_ed25519(); - let owner = get_ed25519_account(owner_keypair.public()); - let revoker_keypair = get_bob_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(owner.clone()), - ); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(root_id, owner)); - - let mut operation = generate_base_delegation_revocation_details(delegation_id); - operation.max_parent_checks = MaxParentChecks::get(); - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![delegation_id])]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_noop!( - Delegation::revoke_delegation( - get_origin(revoker.clone()), - operation.delegation_id, - operation.max_parent_checks, - operation.max_revocations - ), - delegation::Error::::UnauthorizedRevocation - ); - }); -} - -#[test] -fn parent_too_far_revoke_delegation_error() { - let owner_keypair = get_alice_ed25519(); - let owner = get_ed25519_account(owner_keypair.public()); - let intermediate_keypair = get_charlie_ed25519(); - let intermediate = get_ed25519_account(intermediate_keypair.public()); - let delegate_keypair = get_bob_ed25519(); - let delegate = get_ed25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(owner.clone()), - ); - let (parent_delegation_id, parent_delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, intermediate.clone()), - ); - let (delegation_id, mut delegation_node) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate), - ); - delegation_node.parent = Some(parent_delegation_id); - - let mut operation = generate_base_delegation_revocation_details(delegation_id); - operation.max_parent_checks = 0u32; - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, owner)]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (parent_delegation_id, parent_delegation_node), - (delegation_id, delegation_node), - ]) - .with_children(vec![ - (root_id, vec![parent_delegation_id]), - (parent_delegation_id, vec![delegation_id]), - ]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_noop!( - Delegation::revoke_delegation( - get_origin(intermediate.clone()), - operation.delegation_id, - operation.max_parent_checks, - operation.max_revocations - ), - delegation::Error::::MaxSearchDepthReached - ); - }); -} - -#[test] -fn too_many_revocations_revoke_delegation_error() { - let revoker_keypair = get_alice_ed25519(); - let revoker = get_ed25519_account(revoker_keypair.public()); - let delegate_keypair = get_bob_ed25519(); - let delegate = get_ed25519_account(delegate_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(revoker.clone()), - ); - let (parent_delegation_id, parent_delegation_node) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, revoker.clone()), - ); - let (delegation_id, mut delegation_node) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, delegate), - ); - delegation_node.parent = Some(parent_delegation_id); - - let mut operation = generate_base_delegation_revocation_details(delegation_id); - operation.max_parent_checks = 1u32; - - let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) - .build(None); - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (parent_delegation_id, parent_delegation_node), - (delegation_id, delegation_node), - ]) - .with_children(vec![ - (root_id, vec![parent_delegation_id]), - (parent_delegation_id, vec![delegation_id]), - ]) - .build(Some(ext)); - - ext.execute_with(|| { - assert_noop!( - Delegation::revoke_delegation( - get_origin(revoker.clone()), - operation.delegation_id, - operation.max_parent_checks, - operation.max_revocations - ), - delegation::Error::::ExceededRevocationBounds - ); - }); -} - -// Internal function: is_delegating() - -#[test] -fn is_delegating_direct_not_revoked() { - let user_1_keypair = get_alice_ed25519(); - let user_1 = get_ed25519_account(user_1_keypair.public()); - let user_2_keypair = get_bob_ed25519(); - let user_2 = get_ed25519_account(user_2_keypair.public()); - let user_3_keypair = get_charlie_ed25519(); - let user_3 = get_ed25519_account(user_3_keypair.public()); - - let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_root(user_1)); - let (delegation_id_1, delegation_node_1) = - (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); - let (delegation_id_2, mut delegation_node_2) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, user_3.clone()), - ); - delegation_node_2.parent = Some(delegation_id_1); - - let max_parent_checks = 0u32; - - // Root -> Delegation 1 -> Delegation 2 - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (delegation_id_1, delegation_node_1), - (delegation_id_2, delegation_node_2), - ]) - .with_children(vec![ - (root_id, vec![delegation_id_1]), - (delegation_id_1, vec![delegation_id_2]), - ]) - .build(None); - - ext.execute_with(|| { - assert_eq!( - Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), - Ok((true, max_parent_checks)) - ); - }); -} - -#[test] -fn is_delegating_direct_not_revoked_max_parent_checks_value() { - let user_1_keypair = get_alice_ed25519(); - let user_1 = get_ed25519_account(user_1_keypair.public()); - let user_2_keypair = get_bob_ed25519(); - let user_2 = get_ed25519_account(user_2_keypair.public()); - let user_3_keypair = get_charlie_ed25519(); - let user_3 = get_ed25519_account(user_3_keypair.public()); - - let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_root(user_1)); - let (delegation_id_1, delegation_node_1) = - (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); - let (delegation_id_2, mut delegation_node_2) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, user_3.clone()), - ); - delegation_node_2.parent = Some(delegation_id_1); - - let max_parent_checks = u32::MAX; - - // Root -> Delegation 1 -> Delegation 2 - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (delegation_id_1, delegation_node_1), - (delegation_id_2, delegation_node_2), - ]) - .with_children(vec![ - (root_id, vec![delegation_id_1]), - (delegation_id_1, vec![delegation_id_2]), - ]) - .build(None); - - ext.execute_with(|| { - assert_eq!( - Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), - Ok((true, 0u32)) - ); - }); -} - -#[test] -fn is_delegating_direct_revoked() { - let user_1_keypair = get_alice_ed25519(); - let user_1 = get_ed25519_account(user_1_keypair.public()); - let user_2_keypair = get_bob_ed25519(); - let user_2 = get_ed25519_account(user_2_keypair.public()); - let user_3_keypair = get_charlie_ed25519(); - let user_3 = get_ed25519_account(user_3_keypair.public()); - - let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_root(user_1)); - let (delegation_id_1, delegation_node_1) = - (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); - let (delegation_id_2, mut delegation_node_2) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, user_3.clone()), - ); - delegation_node_2.parent = Some(delegation_id_1); - delegation_node_2.revoked = true; - - let max_parent_checks = 0u32; - - // Root -> Delegation 1 -> Delegation 2 - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (delegation_id_1, delegation_node_1), - (delegation_id_2, delegation_node_2), - ]) - .with_children(vec![ - (root_id, vec![delegation_id_1]), - (delegation_id_1, vec![delegation_id_2]), - ]) - .build(None); - - ext.execute_with(|| { - assert_eq!( - Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), - Ok((false, max_parent_checks)) - ); - }); -} - -#[test] -fn is_delegating_direct_revoked_max_parent_checks_value() { - let user_1_keypair = get_alice_ed25519(); - let user_1 = get_ed25519_account(user_1_keypair.public()); - let user_2_keypair = get_bob_ed25519(); - let user_2 = get_ed25519_account(user_2_keypair.public()); - let user_3_keypair = get_charlie_ed25519(); - let user_3 = get_ed25519_account(user_3_keypair.public()); - - let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_root(user_1)); - let (delegation_id_1, delegation_node_1) = - (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); - let (delegation_id_2, mut delegation_node_2) = ( - get_delegation_id(false), - generate_base_delegation_node(root_id, user_3.clone()), - ); - delegation_node_2.parent = Some(delegation_id_1); - delegation_node_2.revoked = true; - - let max_parent_checks = u32::MAX; - - // Root -> Delegation 1 -> Delegation 2 - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (delegation_id_1, delegation_node_1), - (delegation_id_2, delegation_node_2), - ]) - .with_children(vec![ - (root_id, vec![delegation_id_1]), - (delegation_id_1, vec![delegation_id_2]), - ]) - .build(None); - - ext.execute_with(|| { - assert_eq!( - Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), - Ok((false, 0u32)) - ); - }); -} - -#[test] -fn is_delegating_max_parent_not_revoked() { - let user_1_keypair = get_alice_ed25519(); - let user_1 = get_ed25519_account(user_1_keypair.public()); - let user_2_keypair = get_bob_ed25519(); - let user_2 = get_ed25519_account(user_2_keypair.public()); - let user_3_keypair = get_charlie_ed25519(); - let user_3 = get_ed25519_account(user_3_keypair.public()); - - let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_root(user_1)); - let (delegation_id_1, delegation_node_1) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, user_2.clone()), - ); - let (delegation_id_2, mut delegation_node_2) = - (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); - delegation_node_2.parent = Some(delegation_id_1); - - let max_parent_checks = 1u32; - - // Root -> Delegation 1 -> Delegation 2 - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (delegation_id_1, delegation_node_1), - (delegation_id_2, delegation_node_2), - ]) - .with_children(vec![ - (root_id, vec![delegation_id_1]), - (delegation_id_1, vec![delegation_id_2]), - ]) - .build(None); - - ext.execute_with(|| { - assert_eq!( - Delegation::is_delegating(&user_2, &delegation_id_2, max_parent_checks), - Ok((true, max_parent_checks - 1)) - ); - }); -} - -#[test] -fn is_delegating_max_parent_revoked() { - let user_1_keypair = get_alice_ed25519(); - let user_1 = get_ed25519_account(user_1_keypair.public()); - let user_2_keypair = get_bob_ed25519(); - let user_2 = get_ed25519_account(user_2_keypair.public()); - let user_3_keypair = get_charlie_ed25519(); - let user_3 = get_ed25519_account(user_3_keypair.public()); - - let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_root(user_1)); - let (delegation_id_1, mut delegation_node_1) = ( - get_delegation_id(true), - generate_base_delegation_node(root_id, user_2.clone()), - ); - delegation_node_1.revoked = true; - let (delegation_id_2, mut delegation_node_2) = - (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); - delegation_node_2.parent = Some(delegation_id_1); - - let max_parent_checks = 2u32; - - // Root -> Delegation 1 -> Delegation 2 - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (delegation_id_1, delegation_node_1), - (delegation_id_2, delegation_node_2), - ]) - .with_children(vec![ - (root_id, vec![delegation_id_1]), - (delegation_id_1, vec![delegation_id_2]), - ]) - .build(None); - - ext.execute_with(|| { - assert_eq!( - Delegation::is_delegating(&user_2, &delegation_id_2, max_parent_checks), - Ok((false, max_parent_checks - 2)) - ); - }); -} - -#[test] -fn is_delegating_root_owner_not_revoked() { - let user_1_keypair = get_alice_ed25519(); - let user_1 = get_ed25519_account(user_1_keypair.public()); - let user_2_keypair = get_bob_ed25519(); - let user_2 = get_ed25519_account(user_2_keypair.public()); - let user_3_keypair = get_charlie_ed25519(); - let user_3 = get_ed25519_account(user_3_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(user_1.clone()), - ); - let (delegation_id_1, delegation_node_1) = - (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); - let (delegation_id_2, mut delegation_node_2) = - (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); - delegation_node_2.parent = Some(delegation_id_1); - - let max_parent_checks = 2u32; - - // Root -> Delegation 1 -> Delegation 2 - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (delegation_id_1, delegation_node_1), - (delegation_id_2, delegation_node_2), - ]) - .with_children(vec![ - (root_id, vec![delegation_id_1]), - (delegation_id_1, vec![delegation_id_2]), - ]) - .build(None); - - ext.execute_with(|| { - assert_eq!( - Delegation::is_delegating(&user_1, &delegation_id_2, max_parent_checks), - Ok((true, max_parent_checks - 1)) - ); - }); -} - -#[test] -fn is_delegating_root_owner_revoked() { - let user_1_keypair = get_alice_ed25519(); - let user_1 = get_ed25519_account(user_1_keypair.public()); - let user_2_keypair = get_bob_ed25519(); - let user_2 = get_ed25519_account(user_2_keypair.public()); - let user_3_keypair = get_charlie_ed25519(); - let user_3 = get_ed25519_account(user_3_keypair.public()); - - let (root_id, mut root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(user_1.clone()), - ); - root_node.revoked = true; - let (delegation_id_1, mut delegation_node_1) = - (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); - delegation_node_1.revoked = true; - let (delegation_id_2, mut delegation_node_2) = - (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); - delegation_node_2.parent = Some(delegation_id_1); - - let max_parent_checks = u32::MAX; - - // Root -> Delegation 1 -> Delegation 2 - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (delegation_id_1, delegation_node_1), - (delegation_id_2, delegation_node_2), - ]) - .with_children(vec![ - (root_id, vec![delegation_id_1]), - (delegation_id_1, vec![delegation_id_2]), - ]) - .build(None); - - ext.execute_with(|| { - assert_eq!( - Delegation::is_delegating(&user_1, &delegation_id_2, max_parent_checks), - Ok((false, 1u32)) - ); - }); -} - -#[test] -fn is_delegating_delegation_not_found() { - let user_1_keypair = get_alice_ed25519(); - let user_1 = get_ed25519_account(user_1_keypair.public()); - - let (root_id, root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(user_1.clone()), - ); - let delegation_id = get_delegation_id(true); - - let max_parent_checks = 2u32; - - // Root -> Delegation 1 - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .build(None); - - ext.execute_with(|| { - assert_noop!( - Delegation::is_delegating(&user_1, &delegation_id, max_parent_checks), - delegation::Error::::DelegationNotFound - ); - }); -} - -#[test] -fn is_delegating_root_after_max_limit() { - let user_1_keypair = get_alice_ed25519(); - let user_1 = get_ed25519_account(user_1_keypair.public()); - let user_2_keypair = get_bob_ed25519(); - let user_2 = get_ed25519_account(user_2_keypair.public()); - let user_3_keypair = get_charlie_ed25519(); - let user_3 = get_ed25519_account(user_3_keypair.public()); - - let (root_id, mut root_node) = ( - get_delegation_root_id(true), - generate_base_delegation_root(user_1.clone()), - ); - root_node.revoked = true; - let (delegation_id_1, mut delegation_node_1) = - (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); - delegation_node_1.revoked = true; - let (delegation_id_2, mut delegation_node_2) = - (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); - delegation_node_2.parent = Some(delegation_id_1); - - // 1 less than needed - let max_parent_checks = 1u32; - - // Root -> Delegation 1 -> Delegation 2 - let mut ext = ExtBuilder::default() - .with_root_delegations(vec![(root_id, root_node)]) - .with_delegations(vec![ - (delegation_id_1, delegation_node_1), - (delegation_id_2, delegation_node_2), - ]) - .with_children(vec![ - (root_id, vec![delegation_id_1]), - (delegation_id_1, vec![delegation_id_2]), - ]) - .build(None); - - ext.execute_with(|| { - assert_noop!( - Delegation::is_delegating(&user_1, &delegation_id_2, max_parent_checks), - delegation::Error::::MaxSearchDepthReached - ); - }); -} +// #[test] +// fn duplicate_create_root_delegation_error() { +// let creator_keypair = get_alice_ed25519(); +// let creator = get_ed25519_account(creator_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(creator.clone()), +// ); + +// let operation = generate_base_delegation_hierarchy_creation_details(root_id, root_node.clone()); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_err!( +// Delegation::create_root(get_origin(creator.clone()), operation.id, operation.ctype_hash), +// delegation::Error::::RootAlreadyExists +// ); +// }); +// } + +// #[test] +// fn ctype_not_found_create_root_delegation_error() { +// let creator_keypair = get_alice_ed25519(); +// let creator = get_ed25519_account(creator_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(creator.clone()), +// ); + +// let operation = generate_base_delegation_hierarchy_creation_details(root_id, root_node); + +// // No CTYPE stored, +// let mut ext = ExtBuilder::default().build(None); + +// ext.execute_with(|| { +// assert_err!( +// Delegation::create_root(get_origin(creator.clone()), operation.id, operation.ctype_hash), +// ctype::Error::::CTypeNotFound +// ); +// }); +// } + +// // submit_delegation_creation_operation() + +// #[test] +// fn create_delegation_no_parent_successful() { +// let creator_keypair = get_alice_ed25519(); +// let creator = get_ed25519_account(creator_keypair.public()); +// let delegate_keypair = get_bob_sr25519(); +// let delegate = get_sr25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(creator.clone()), +// ); +// let (delegation_id, delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, delegate), +// ); + +// let delegation_info = Delegation::calculate_hash( +// &delegation_id, +// &delegation_node.root_id, +// &delegation_node.parent, +// &delegation_node.permissions, +// ); + +// let delegate_signature = delegate_keypair.sign(&hash_to_u8(delegation_info)); + +// let operation = +// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_ok!(Delegation::add_delegation( +// get_origin(creator.clone()), +// operation.delegation_id, +// operation.hierarchy_id, +// operation.parent_id, +// operation.delegate.clone(), +// operation.permissions, +// operation.delegate_signature.clone().encode(), +// )); +// }); + +// let stored_delegation = ext.execute_with(|| { +// Delegation::delegations(&operation.delegation_id).expect("Delegation should be present on chain.") +// }); + +// assert_eq!(stored_delegation.root_id, operation.hierarchy_id); +// assert_eq!(stored_delegation.parent, operation.parent_id); +// assert_eq!(stored_delegation.owner, operation.delegate); +// assert_eq!(stored_delegation.permissions, operation.permissions); +// assert!(!stored_delegation.revoked); + +// // Verify that the root has the new delegation among its children +// let stored_root_children = ext.execute_with(|| { +// Delegation::children(&operation.hierarchy_id).expect("Delegation root children should be present on chain.") +// }); + +// assert_eq!(stored_root_children, vec![operation.delegation_id]); +// } + +// #[test] +// fn create_delegation_with_parent_successful() { +// let creator_keypair = get_alice_ed25519(); +// let creator = get_ed25519_account(creator_keypair.public()); +// let delegate_keypair = get_bob_sr25519(); +// let delegate = get_sr25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(creator.clone()), +// ); +// let (parent_delegation_id, parent_delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, creator.clone()), +// ); +// let (delegation_id, mut delegation_node) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate.clone()), +// ); +// delegation_node.parent = Some(parent_delegation_id); + +// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( +// &delegation_id, +// &delegation_node.root_id, +// &delegation_node.parent, +// &delegation_node.permissions, +// ))); + +// let operation = +// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![(parent_delegation_id, parent_delegation_node)]) +// .with_children(vec![(root_id, vec![(parent_delegation_id)])]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_ok!(Delegation::add_delegation( +// get_origin(creator.clone()), +// operation.delegation_id, +// operation.hierarchy_id, +// operation.parent_id, +// delegate.clone(), +// operation.permissions, +// operation.delegate_signature.clone().encode(), +// )); +// }); + +// let stored_delegation = ext.execute_with(|| { +// Delegation::delegations(&operation.delegation_id).expect("Delegation should be present on chain.") +// }); + +// assert_eq!(stored_delegation.root_id, operation.hierarchy_id); +// assert_eq!(stored_delegation.parent, operation.parent_id); +// assert_eq!(stored_delegation.owner, operation.delegate); +// assert_eq!(stored_delegation.permissions, operation.permissions); +// assert!(!stored_delegation.revoked); + +// // Verify that the parent has the new delegation among its children +// let stored_parent_children = ext.execute_with(|| { +// Delegation::children(&operation.parent_id.unwrap()) +// .expect("Delegation parent children should be present on chain.") +// }); + +// assert_eq!(stored_parent_children, vec![delegation_id]); +// } + +// #[test] +// fn invalid_delegate_signature_create_delegation_error() { +// let creator_keypair = get_alice_ed25519(); +// let creator = get_ed25519_account(creator_keypair.public()); +// let alternative_keypair = get_alice_sr25519(); +// let delegate_keypair = get_bob_sr25519(); +// let delegate = get_sr25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(creator.clone()), +// ); +// let (delegation_id, delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, delegate.clone()), +// ); + +// let delegate_signature = alternative_keypair.sign(&hash_to_u8(Delegation::calculate_hash( +// &delegation_id, +// &delegation_node.root_id, +// &delegation_node.parent, +// &delegation_node.permissions, +// ))); + +// let operation = +// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_err!( +// Delegation::add_delegation( +// get_origin(creator.clone()), +// operation.delegation_id, +// operation.hierarchy_id, +// operation.parent_id, +// delegate.clone(), +// operation.permissions, +// operation.delegate_signature.clone().encode(), +// ), +// delegation::Error::::InvalidDelegateSignature +// ); +// }); +// } + +// #[test] +// fn duplicate_delegation_create_delegation_error() { +// let creator_keypair = get_alice_ed25519(); +// let creator = get_ed25519_account(creator_keypair.public()); +// let delegate_keypair = get_bob_sr25519(); +// let delegate = get_sr25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(creator.clone()), +// ); +// let (delegation_id, delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, delegate.clone()), +// ); + +// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( +// &delegation_id, +// &delegation_node.root_id, +// &delegation_node.parent, +// &delegation_node.permissions, +// ))); + +// let operation = +// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node.clone()); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![(delegation_id, delegation_node)]) +// .with_children(vec![(root_id, vec![delegation_id])]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_err!( +// Delegation::add_delegation( +// get_origin(creator.clone()), +// operation.delegation_id, +// operation.hierarchy_id, +// operation.parent_id, +// delegate.clone(), +// operation.permissions, +// operation.delegate_signature.clone().encode(), +// ), +// delegation::Error::::DelegationAlreadyExists +// ); +// }); +// } + +// #[test] +// fn root_not_existing_create_delegation_error() { +// let creator_keypair = get_alice_ed25519(); +// let creator = get_ed25519_account(creator_keypair.public()); +// let delegate_keypair = get_bob_sr25519(); +// let delegate = get_sr25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(creator.clone()), +// ); +// let (delegation_id, delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, delegate.clone()), +// ); + +// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( +// &delegation_id, +// &delegation_node.root_id, +// &delegation_node.parent, +// &delegation_node.permissions, +// ))); + +// let operation = +// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) +// .build(None); +// // No delegations added to the pallet storage +// let mut ext = ExtBuilder::default().build(Some(ext)); + +// ext.execute_with(|| { +// assert_err!( +// Delegation::add_delegation( +// get_origin(creator.clone()), +// operation.delegation_id, +// operation.hierarchy_id, +// operation.parent_id, +// delegate.clone(), +// operation.permissions, +// operation.delegate_signature.clone().encode(), +// ), +// delegation::Error::::RootNotFound +// ); +// }); +// } + +// #[test] +// fn parent_not_existing_create_delegation_error() { +// let creator_keypair = get_alice_ed25519(); +// let creator = get_ed25519_account(creator_keypair.public()); +// let delegate_keypair = get_bob_sr25519(); +// let delegate = get_sr25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(creator.clone()), +// ); +// let alternative_parent_id = get_delegation_id(false); +// let (delegation_id, mut delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, delegate.clone()), +// ); +// delegation_node.parent = Some(alternative_parent_id); + +// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( +// &delegation_id, +// &delegation_node.root_id, +// &delegation_node.parent, +// &delegation_node.permissions, +// ))); + +// let operation = +// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_err!( +// Delegation::add_delegation( +// get_origin(creator.clone()), +// operation.delegation_id, +// operation.hierarchy_id, +// operation.parent_id, +// delegate.clone(), +// operation.permissions, +// operation.delegate_signature.clone().encode(), +// ), +// delegation::Error::::ParentDelegationNotFound +// ); +// }); +// } + +// #[test] +// fn not_owner_of_parent_create_delegation_error() { +// let creator_keypair = get_alice_ed25519(); +// let creator = get_ed25519_account(creator_keypair.public()); +// let alternative_owner_keypair = get_charlie_ed25519(); +// let alternative_owner = get_ed25519_account(alternative_owner_keypair.public()); +// let delegate_keypair = get_bob_sr25519(); +// let delegate = get_sr25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(creator.clone()), +// ); +// let (parent_delegation_id, parent_delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, alternative_owner), +// ); +// let (delegation_id, mut delegation_node) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate.clone()), +// ); +// delegation_node.parent = Some(parent_delegation_id); + +// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( +// &delegation_id, +// &delegation_node.root_id, +// &delegation_node.parent, +// &delegation_node.permissions, +// ))); + +// let operation = +// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![(parent_delegation_id, parent_delegation_node)]) +// .with_children(vec![(root_id, vec![parent_delegation_id])]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_err!( +// Delegation::add_delegation( +// get_origin(creator.clone()), +// operation.delegation_id, +// operation.hierarchy_id, +// operation.parent_id, +// delegate.clone(), +// operation.permissions, +// operation.delegate_signature.clone().encode(), +// ), +// delegation::Error::::NotOwnerOfParentDelegation +// ); +// }); +// } + +// #[test] +// fn unauthorised_delegation_create_delegation_error() { +// let creator_keypair = get_alice_ed25519(); +// let creator = get_ed25519_account(creator_keypair.public()); +// let delegate_keypair = get_bob_sr25519(); +// let delegate = get_sr25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(creator.clone()), +// ); +// let (parent_delegation_id, mut parent_delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, creator.clone()), +// ); +// parent_delegation_node.permissions = delegation::Permissions::ATTEST; +// let (delegation_id, mut delegation_node) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate.clone()), +// ); +// delegation_node.parent = Some(parent_delegation_id); + +// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( +// &delegation_id, +// &delegation_node.root_id, +// &delegation_node.parent, +// &delegation_node.permissions, +// ))); + +// let operation = +// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![(parent_delegation_id, parent_delegation_node)]) +// .with_children(vec![(root_id, vec![parent_delegation_id])]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_err!( +// Delegation::add_delegation( +// get_origin(creator.clone()), +// operation.delegation_id, +// operation.hierarchy_id, +// operation.parent_id, +// delegate.clone(), +// operation.permissions, +// operation.delegate_signature.clone().encode(), +// ), +// delegation::Error::::UnauthorizedDelegation +// ); +// }); +// } + +// #[test] +// fn not_owner_of_root_create_delegation_error() { +// let creator_keypair = get_alice_ed25519(); +// let creator = get_ed25519_account(creator_keypair.public()); +// let alternative_owner_keypair = get_charlie_ed25519(); +// let alternative_owner = get_ed25519_account(alternative_owner_keypair.public()); +// let delegate_keypair = get_bob_sr25519(); +// let delegate = get_sr25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(alternative_owner), +// ); +// let (delegation_id, delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, delegate.clone()), +// ); + +// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( +// &delegation_id, +// &delegation_node.root_id, +// &delegation_node.parent, +// &delegation_node.permissions, +// ))); + +// let operation = +// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_noop!( +// Delegation::add_delegation( +// get_origin(creator.clone()), +// operation.delegation_id, +// operation.hierarchy_id, +// operation.parent_id, +// delegate.clone(), +// operation.permissions, +// operation.delegate_signature.clone().encode(), +// ), +// delegation::Error::::NotOwnerOfRootDelegation +// ); +// }); +// } + +// // submit_delegation_root_revocation_operation() +// #[test] +// fn empty_revoke_root_successful() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(revoker.clone()), +// ); + +// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); +// operation.max_children = 2u32; + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_ok!(Delegation::revoke_root( +// get_origin(revoker.clone()), +// operation.id, +// operation.max_children +// )); +// }); + +// let stored_delegation_root = ext +// .execute_with(|| Delegation::roots(&operation.id).expect("Delegation root should be present on chain.")); +// assert!(stored_delegation_root.revoked); +// } + +// #[test] +// fn list_hierarchy_revoke_root_successful() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); +// let delegate_keypair = get_bob_ed25519(); +// let delegate = get_ed25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(revoker.clone()), +// ); +// let (parent_delegation_id, parent_delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, revoker.clone()), +// ); +// let (delegation_id, mut delegation_node) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate), +// ); +// delegation_node.parent = Some(parent_delegation_id); + +// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); +// operation.max_children = 2u32; + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (parent_delegation_id, parent_delegation_node), +// (delegation_id, delegation_node), +// ]) +// .with_children(vec![ +// // Root -> Parent -> Delegation +// (root_id, vec![parent_delegation_id]), +// (parent_delegation_id, vec![delegation_id]), +// ]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_ok!(Delegation::revoke_root( +// get_origin(revoker.clone()), +// operation.id, +// operation.max_children +// )); +// }); + +// let stored_delegation_root = ext +// .execute_with(|| Delegation::roots(&operation.id).expect("Delegation root should be present on chain.")); +// assert!(stored_delegation_root.revoked); + +// let stored_parent_delegation = ext.execute_with(|| { +// Delegation::delegations(&parent_delegation_id).expect("Parent delegation should be present on chain.") +// }); +// assert!(stored_parent_delegation.revoked); + +// let stored_delegation = +// ext.execute_with(|| Delegation::delegations(&delegation_id).expect("Delegation should be present on chain.")); +// assert!(stored_delegation.revoked); +// } + +// #[test] +// fn tree_hierarchy_revoke_root_successful() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); +// let delegate_keypair = get_bob_ed25519(); +// let delegate = get_ed25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(revoker.clone()), +// ); +// let (delegation_id_1, delegation_node_1) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, revoker.clone()), +// ); +// let (delegation_id_2, delegation_node_2) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate), +// ); + +// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); +// operation.max_children = 2u32; + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (delegation_id_1, delegation_node_1), +// (delegation_id_2, delegation_node_2), +// ]) +// .with_children(vec![ +// // Root -> Delegation 1 && Delegation 2 +// (root_id, vec![delegation_id_1, delegation_id_2]), +// ]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_ok!(Delegation::revoke_root( +// get_origin(revoker.clone()), +// operation.id, +// operation.max_children +// )); +// }); + +// let stored_delegation_root = ext +// .execute_with(|| Delegation::roots(&operation.id).expect("Delegation root should be present on chain.")); +// assert!(stored_delegation_root.revoked); + +// let stored_delegation_1 = ext +// .execute_with(|| Delegation::delegations(&delegation_id_1).expect("Delegation 1 should be present on chain.")); +// assert!(stored_delegation_1.revoked); + +// let stored_delegation_2 = ext +// .execute_with(|| Delegation::delegations(&delegation_id_2).expect("Delegation 2 should be present on chain.")); +// assert!(stored_delegation_2.revoked); +// } + +// #[test] +// fn greater_max_revocations_revoke_root_successful() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); +// let delegate_keypair = get_alice_ed25519(); +// let delegate = get_ed25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(revoker.clone()), +// ); +// let (delegation_id, delegation_node) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate), +// ); + +// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); +// operation.max_children = MaxRevocations::get(); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![(delegation_id, delegation_node)]) +// .with_children(vec![ +// // Root -> Delegation +// (root_id, vec![delegation_id]), +// ]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_ok!(Delegation::revoke_root( +// get_origin(revoker.clone()), +// operation.id, +// operation.max_children +// )); +// }); + +// let stored_delegation_root = ext +// .execute_with(|| Delegation::roots(&operation.id).expect("Delegation root should be present on chain.")); +// assert!(stored_delegation_root.revoked); + +// let stored_delegation = +// ext.execute_with(|| Delegation::delegations(&delegation_id).expect("Delegation should be present on chain.")); +// assert!(stored_delegation.revoked); +// } + +// #[test] +// fn root_not_found_revoke_root_error() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); + +// let root_id = get_delegation_root_id(true); + +// let operation = generate_base_delegation_hierarchy_revocation_details(root_id); + +// let mut ext = ExtBuilder::default().build(None); + +// ext.execute_with(|| { +// assert_noop!( +// Delegation::revoke_root(get_origin(revoker.clone()), operation.id, operation.max_children), +// delegation::Error::::RootNotFound +// ); +// }); +// } + +// #[test] +// fn different_root_creator_revoke_root_error() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); +// let alternative_revoker_keypair = get_charlie_ed25519(); +// let alternative_revoker = get_ed25519_account(alternative_revoker_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(alternative_revoker), +// ); + +// let operation = generate_base_delegation_hierarchy_revocation_details(root_id); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_noop!( +// Delegation::revoke_root(get_origin(revoker.clone()), operation.id, operation.max_children), +// delegation::Error::::UnauthorizedRevocation +// ); +// }); +// } + +// #[test] +// fn too_small_max_revocations_revoke_root_error() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); +// let delegate_keypair = get_alice_ed25519(); +// let delegate = get_ed25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(revoker.clone()), +// ); +// let (delegation_id, delegation_node) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate), +// ); + +// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); +// operation.max_children = 0u32; + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![(delegation_id, delegation_node)]) +// .with_children(vec![ +// // Root -> Delegation +// (root_id, vec![delegation_id]), +// ]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_noop!( +// Delegation::revoke_root(get_origin(revoker.clone()), operation.id, operation.max_children), +// delegation::Error::::ExceededRevocationBounds +// ); +// }); +// } + +// #[test] +// fn exact_children_max_revocations_revoke_root_error() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); +// let delegate_keypair = get_alice_ed25519(); +// let delegate = get_ed25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(revoker.clone()), +// ); +// let (delegation_id_1, delegation_node_1) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, delegate.clone()), +// ); +// let (delegation_id_2, mut delegation_node_2) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate.clone()), +// ); +// delegation_node_2.parent = Some(delegation_id_1); +// let (delegation_id_3, mut delegation_node_3) = ( +// get_delegation_root_id(false), +// generate_base_delegation_node(root_id, delegate), +// ); +// delegation_node_3.parent = Some(delegation_id_1); + +// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); +// operation.max_children = 2u32; + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (delegation_id_1, delegation_node_1), +// (delegation_id_2, delegation_node_2), +// (delegation_id_3, delegation_node_3), +// ]) +// .with_children(vec![ +// // Root -> Delegation 1 -> Delegation 2 && Delegation 3 +// (root_id, vec![delegation_id_1]), +// (delegation_id_1, vec![delegation_id_2, delegation_id_3]), +// ]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// // assert_err and not asser_noop becase the storage is indeed changed, even tho +// // partially +// assert_err!( +// Delegation::revoke_root(get_origin(revoker.clone()), operation.id, operation.max_children), +// delegation::Error::::ExceededRevocationBounds +// ); +// }); + +// let stored_delegation_root = ext +// .execute_with(|| Delegation::roots(&operation.id).expect("Delegation root should be present on chain.")); +// assert!(!stored_delegation_root.revoked); + +// let stored_delegation_1 = ext +// .execute_with(|| Delegation::delegations(&delegation_id_1).expect("Delegation 1 should be present on chain.")); +// assert!(!stored_delegation_1.revoked); + +// // Only this leaf should have been revoked as it is the first child of +// // delegation_1 +// let stored_delegation_2 = ext +// .execute_with(|| Delegation::delegations(&delegation_id_2).expect("Delegation 2 should be present on chain.")); +// assert!(stored_delegation_2.revoked); + +// let stored_delegation_3 = ext +// .execute_with(|| Delegation::delegations(&delegation_id_3).expect("Delegation 3 should be present on chain.")); +// assert!(!stored_delegation_3.revoked); +// } + +// // submit_delegation_revocation_operation() + +// #[test] +// fn direct_owner_revoke_delegation_successful() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); +// let delegate_keypair = get_alice_ed25519(); +// let delegate = get_ed25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(revoker.clone()), +// ); +// let (parent_delegation_id, parent_delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, revoker.clone()), +// ); +// let (delegation_id, mut delegation_node) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate), +// ); +// delegation_node.parent = Some(parent_delegation_id); + +// let mut operation = generate_base_delegation_revocation_details(parent_delegation_id); +// operation.max_revocations = 2u32; + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// // Root -> Parent -> Child +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (parent_delegation_id, parent_delegation_node), +// (delegation_id, delegation_node), +// ]) +// .with_children(vec![ +// (root_id, vec![parent_delegation_id]), +// (parent_delegation_id, vec![delegation_id]), +// ]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_ok!(Delegation::revoke_delegation( +// get_origin(revoker.clone()), +// operation.delegation_id, +// operation.max_parent_checks, +// operation.max_revocations +// )); +// }); + +// let stored_parent_delegation = ext.execute_with(|| { +// Delegation::delegations(&parent_delegation_id).expect("Parent delegation should be present on chain.") +// }); +// assert!(stored_parent_delegation.revoked); + +// let stored_child_delegation = ext.execute_with(|| { +// Delegation::delegations(&delegation_id).expect("Child delegation should be present on chain.") +// }); +// assert!(stored_child_delegation.revoked); +// } + +// #[test] +// fn parent_owner_revoke_delegation_successful() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); +// let delegate_keypair = get_alice_ed25519(); +// let delegate = get_ed25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(revoker.clone()), +// ); +// let (parent_delegation_id, parent_delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, revoker.clone()), +// ); +// let (delegation_id, mut delegation_node) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate), +// ); +// delegation_node.parent = Some(parent_delegation_id); + +// let mut operation = generate_base_delegation_revocation_details(delegation_id); +// operation.max_parent_checks = 1u32; +// operation.max_revocations = 1u32; + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (parent_delegation_id, parent_delegation_node), +// (delegation_id, delegation_node), +// ]) +// .with_children(vec![ +// (root_id, vec![parent_delegation_id]), +// (parent_delegation_id, vec![delegation_id]), +// ]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_ok!(Delegation::revoke_delegation( +// get_origin(revoker.clone()), +// operation.delegation_id, +// operation.max_parent_checks, +// operation.max_revocations +// )); +// }); + +// let stored_parent_delegation = ext.execute_with(|| { +// Delegation::delegations(&parent_delegation_id).expect("Parent delegation should be present on chain.") +// }); +// assert!(!stored_parent_delegation.revoked); + +// let stored_child_delegation = ext.execute_with(|| { +// Delegation::delegations(&delegation_id).expect("Child delegation should be present on chain.") +// }); +// assert!(stored_child_delegation.revoked); +// } + +// #[test] +// fn delegation_not_found_revoke_delegation_error() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(revoker.clone()), +// ); +// let delegation_id = get_delegation_id(true); + +// let operation = generate_base_delegation_revocation_details(delegation_id); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_noop!( +// Delegation::revoke_delegation( +// get_origin(revoker.clone()), +// operation.delegation_id, +// operation.max_parent_checks, +// operation.max_revocations +// ), +// delegation::Error::::DelegationNotFound +// ); +// }); +// } + +// #[test] +// fn not_delegating_revoke_delegation_error() { +// let owner_keypair = get_alice_ed25519(); +// let owner = get_ed25519_account(owner_keypair.public()); +// let revoker_keypair = get_bob_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(owner.clone()), +// ); +// let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(root_id, owner)); + +// let mut operation = generate_base_delegation_revocation_details(delegation_id); +// operation.max_parent_checks = MaxParentChecks::get(); + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![(delegation_id, delegation_node)]) +// .with_children(vec![(root_id, vec![delegation_id])]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_noop!( +// Delegation::revoke_delegation( +// get_origin(revoker.clone()), +// operation.delegation_id, +// operation.max_parent_checks, +// operation.max_revocations +// ), +// delegation::Error::::UnauthorizedRevocation +// ); +// }); +// } + +// #[test] +// fn parent_too_far_revoke_delegation_error() { +// let owner_keypair = get_alice_ed25519(); +// let owner = get_ed25519_account(owner_keypair.public()); +// let intermediate_keypair = get_charlie_ed25519(); +// let intermediate = get_ed25519_account(intermediate_keypair.public()); +// let delegate_keypair = get_bob_ed25519(); +// let delegate = get_ed25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(owner.clone()), +// ); +// let (parent_delegation_id, parent_delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, intermediate.clone()), +// ); +// let (delegation_id, mut delegation_node) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate), +// ); +// delegation_node.parent = Some(parent_delegation_id); + +// let mut operation = generate_base_delegation_revocation_details(delegation_id); +// operation.max_parent_checks = 0u32; + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, owner)]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (parent_delegation_id, parent_delegation_node), +// (delegation_id, delegation_node), +// ]) +// .with_children(vec![ +// (root_id, vec![parent_delegation_id]), +// (parent_delegation_id, vec![delegation_id]), +// ]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_noop!( +// Delegation::revoke_delegation( +// get_origin(intermediate.clone()), +// operation.delegation_id, +// operation.max_parent_checks, +// operation.max_revocations +// ), +// delegation::Error::::MaxSearchDepthReached +// ); +// }); +// } + +// #[test] +// fn too_many_revocations_revoke_delegation_error() { +// let revoker_keypair = get_alice_ed25519(); +// let revoker = get_ed25519_account(revoker_keypair.public()); +// let delegate_keypair = get_bob_ed25519(); +// let delegate = get_ed25519_account(delegate_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(revoker.clone()), +// ); +// let (parent_delegation_id, parent_delegation_node) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, revoker.clone()), +// ); +// let (delegation_id, mut delegation_node) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, delegate), +// ); +// delegation_node.parent = Some(parent_delegation_id); + +// let mut operation = generate_base_delegation_revocation_details(delegation_id); +// operation.max_parent_checks = 1u32; + +// let ext = ctype_mock::ExtBuilder::default() +// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) +// .build(None); +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (parent_delegation_id, parent_delegation_node), +// (delegation_id, delegation_node), +// ]) +// .with_children(vec![ +// (root_id, vec![parent_delegation_id]), +// (parent_delegation_id, vec![delegation_id]), +// ]) +// .build(Some(ext)); + +// ext.execute_with(|| { +// assert_noop!( +// Delegation::revoke_delegation( +// get_origin(revoker.clone()), +// operation.delegation_id, +// operation.max_parent_checks, +// operation.max_revocations +// ), +// delegation::Error::::ExceededRevocationBounds +// ); +// }); +// } + +// // Internal function: is_delegating() + +// #[test] +// fn is_delegating_direct_not_revoked() { +// let user_1_keypair = get_alice_ed25519(); +// let user_1 = get_ed25519_account(user_1_keypair.public()); +// let user_2_keypair = get_bob_ed25519(); +// let user_2 = get_ed25519_account(user_2_keypair.public()); +// let user_3_keypair = get_charlie_ed25519(); +// let user_3 = get_ed25519_account(user_3_keypair.public()); + +// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); +// let (delegation_id_1, delegation_node_1) = +// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); +// let (delegation_id_2, mut delegation_node_2) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, user_3.clone()), +// ); +// delegation_node_2.parent = Some(delegation_id_1); + +// let max_parent_checks = 0u32; + +// // Root -> Delegation 1 -> Delegation 2 +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (delegation_id_1, delegation_node_1), +// (delegation_id_2, delegation_node_2), +// ]) +// .with_children(vec![ +// (root_id, vec![delegation_id_1]), +// (delegation_id_1, vec![delegation_id_2]), +// ]) +// .build(None); + +// ext.execute_with(|| { +// assert_eq!( +// Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), +// Ok((true, max_parent_checks)) +// ); +// }); +// } + +// #[test] +// fn is_delegating_direct_not_revoked_max_parent_checks_value() { +// let user_1_keypair = get_alice_ed25519(); +// let user_1 = get_ed25519_account(user_1_keypair.public()); +// let user_2_keypair = get_bob_ed25519(); +// let user_2 = get_ed25519_account(user_2_keypair.public()); +// let user_3_keypair = get_charlie_ed25519(); +// let user_3 = get_ed25519_account(user_3_keypair.public()); + +// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); +// let (delegation_id_1, delegation_node_1) = +// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); +// let (delegation_id_2, mut delegation_node_2) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, user_3.clone()), +// ); +// delegation_node_2.parent = Some(delegation_id_1); + +// let max_parent_checks = u32::MAX; + +// // Root -> Delegation 1 -> Delegation 2 +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (delegation_id_1, delegation_node_1), +// (delegation_id_2, delegation_node_2), +// ]) +// .with_children(vec![ +// (root_id, vec![delegation_id_1]), +// (delegation_id_1, vec![delegation_id_2]), +// ]) +// .build(None); + +// ext.execute_with(|| { +// assert_eq!( +// Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), +// Ok((true, 0u32)) +// ); +// }); +// } + +// #[test] +// fn is_delegating_direct_revoked() { +// let user_1_keypair = get_alice_ed25519(); +// let user_1 = get_ed25519_account(user_1_keypair.public()); +// let user_2_keypair = get_bob_ed25519(); +// let user_2 = get_ed25519_account(user_2_keypair.public()); +// let user_3_keypair = get_charlie_ed25519(); +// let user_3 = get_ed25519_account(user_3_keypair.public()); + +// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); +// let (delegation_id_1, delegation_node_1) = +// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); +// let (delegation_id_2, mut delegation_node_2) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, user_3.clone()), +// ); +// delegation_node_2.parent = Some(delegation_id_1); +// delegation_node_2.revoked = true; + +// let max_parent_checks = 0u32; + +// // Root -> Delegation 1 -> Delegation 2 +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (delegation_id_1, delegation_node_1), +// (delegation_id_2, delegation_node_2), +// ]) +// .with_children(vec![ +// (root_id, vec![delegation_id_1]), +// (delegation_id_1, vec![delegation_id_2]), +// ]) +// .build(None); + +// ext.execute_with(|| { +// assert_eq!( +// Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), +// Ok((false, max_parent_checks)) +// ); +// }); +// } + +// #[test] +// fn is_delegating_direct_revoked_max_parent_checks_value() { +// let user_1_keypair = get_alice_ed25519(); +// let user_1 = get_ed25519_account(user_1_keypair.public()); +// let user_2_keypair = get_bob_ed25519(); +// let user_2 = get_ed25519_account(user_2_keypair.public()); +// let user_3_keypair = get_charlie_ed25519(); +// let user_3 = get_ed25519_account(user_3_keypair.public()); + +// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); +// let (delegation_id_1, delegation_node_1) = +// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); +// let (delegation_id_2, mut delegation_node_2) = ( +// get_delegation_id(false), +// generate_base_delegation_node(root_id, user_3.clone()), +// ); +// delegation_node_2.parent = Some(delegation_id_1); +// delegation_node_2.revoked = true; + +// let max_parent_checks = u32::MAX; + +// // Root -> Delegation 1 -> Delegation 2 +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (delegation_id_1, delegation_node_1), +// (delegation_id_2, delegation_node_2), +// ]) +// .with_children(vec![ +// (root_id, vec![delegation_id_1]), +// (delegation_id_1, vec![delegation_id_2]), +// ]) +// .build(None); + +// ext.execute_with(|| { +// assert_eq!( +// Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), +// Ok((false, 0u32)) +// ); +// }); +// } + +// #[test] +// fn is_delegating_max_parent_not_revoked() { +// let user_1_keypair = get_alice_ed25519(); +// let user_1 = get_ed25519_account(user_1_keypair.public()); +// let user_2_keypair = get_bob_ed25519(); +// let user_2 = get_ed25519_account(user_2_keypair.public()); +// let user_3_keypair = get_charlie_ed25519(); +// let user_3 = get_ed25519_account(user_3_keypair.public()); + +// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); +// let (delegation_id_1, delegation_node_1) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, user_2.clone()), +// ); +// let (delegation_id_2, mut delegation_node_2) = +// (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); +// delegation_node_2.parent = Some(delegation_id_1); + +// let max_parent_checks = 1u32; + +// // Root -> Delegation 1 -> Delegation 2 +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (delegation_id_1, delegation_node_1), +// (delegation_id_2, delegation_node_2), +// ]) +// .with_children(vec![ +// (root_id, vec![delegation_id_1]), +// (delegation_id_1, vec![delegation_id_2]), +// ]) +// .build(None); + +// ext.execute_with(|| { +// assert_eq!( +// Delegation::is_delegating(&user_2, &delegation_id_2, max_parent_checks), +// Ok((true, max_parent_checks - 1)) +// ); +// }); +// } + +// #[test] +// fn is_delegating_max_parent_revoked() { +// let user_1_keypair = get_alice_ed25519(); +// let user_1 = get_ed25519_account(user_1_keypair.public()); +// let user_2_keypair = get_bob_ed25519(); +// let user_2 = get_ed25519_account(user_2_keypair.public()); +// let user_3_keypair = get_charlie_ed25519(); +// let user_3 = get_ed25519_account(user_3_keypair.public()); + +// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); +// let (delegation_id_1, mut delegation_node_1) = ( +// get_delegation_id(true), +// generate_base_delegation_node(root_id, user_2.clone()), +// ); +// delegation_node_1.revoked = true; +// let (delegation_id_2, mut delegation_node_2) = +// (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); +// delegation_node_2.parent = Some(delegation_id_1); + +// let max_parent_checks = 2u32; + +// // Root -> Delegation 1 -> Delegation 2 +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (delegation_id_1, delegation_node_1), +// (delegation_id_2, delegation_node_2), +// ]) +// .with_children(vec![ +// (root_id, vec![delegation_id_1]), +// (delegation_id_1, vec![delegation_id_2]), +// ]) +// .build(None); + +// ext.execute_with(|| { +// assert_eq!( +// Delegation::is_delegating(&user_2, &delegation_id_2, max_parent_checks), +// Ok((false, max_parent_checks - 2)) +// ); +// }); +// } + +// #[test] +// fn is_delegating_root_owner_not_revoked() { +// let user_1_keypair = get_alice_ed25519(); +// let user_1 = get_ed25519_account(user_1_keypair.public()); +// let user_2_keypair = get_bob_ed25519(); +// let user_2 = get_ed25519_account(user_2_keypair.public()); +// let user_3_keypair = get_charlie_ed25519(); +// let user_3 = get_ed25519_account(user_3_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(user_1.clone()), +// ); +// let (delegation_id_1, delegation_node_1) = +// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); +// let (delegation_id_2, mut delegation_node_2) = +// (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); +// delegation_node_2.parent = Some(delegation_id_1); + +// let max_parent_checks = 2u32; + +// // Root -> Delegation 1 -> Delegation 2 +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (delegation_id_1, delegation_node_1), +// (delegation_id_2, delegation_node_2), +// ]) +// .with_children(vec![ +// (root_id, vec![delegation_id_1]), +// (delegation_id_1, vec![delegation_id_2]), +// ]) +// .build(None); + +// ext.execute_with(|| { +// assert_eq!( +// Delegation::is_delegating(&user_1, &delegation_id_2, max_parent_checks), +// Ok((true, max_parent_checks - 1)) +// ); +// }); +// } + +// #[test] +// fn is_delegating_root_owner_revoked() { +// let user_1_keypair = get_alice_ed25519(); +// let user_1 = get_ed25519_account(user_1_keypair.public()); +// let user_2_keypair = get_bob_ed25519(); +// let user_2 = get_ed25519_account(user_2_keypair.public()); +// let user_3_keypair = get_charlie_ed25519(); +// let user_3 = get_ed25519_account(user_3_keypair.public()); + +// let (root_id, mut root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(user_1.clone()), +// ); +// root_node.revoked = true; +// let (delegation_id_1, mut delegation_node_1) = +// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); +// delegation_node_1.revoked = true; +// let (delegation_id_2, mut delegation_node_2) = +// (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); +// delegation_node_2.parent = Some(delegation_id_1); + +// let max_parent_checks = u32::MAX; + +// // Root -> Delegation 1 -> Delegation 2 +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (delegation_id_1, delegation_node_1), +// (delegation_id_2, delegation_node_2), +// ]) +// .with_children(vec![ +// (root_id, vec![delegation_id_1]), +// (delegation_id_1, vec![delegation_id_2]), +// ]) +// .build(None); + +// ext.execute_with(|| { +// assert_eq!( +// Delegation::is_delegating(&user_1, &delegation_id_2, max_parent_checks), +// Ok((false, 1u32)) +// ); +// }); +// } + +// #[test] +// fn is_delegating_delegation_not_found() { +// let user_1_keypair = get_alice_ed25519(); +// let user_1 = get_ed25519_account(user_1_keypair.public()); + +// let (root_id, root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(user_1.clone()), +// ); +// let delegation_id = get_delegation_id(true); + +// let max_parent_checks = 2u32; + +// // Root -> Delegation 1 +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .build(None); + +// ext.execute_with(|| { +// assert_noop!( +// Delegation::is_delegating(&user_1, &delegation_id, max_parent_checks), +// delegation::Error::::DelegationNotFound +// ); +// }); +// } + +// #[test] +// fn is_delegating_root_after_max_limit() { +// let user_1_keypair = get_alice_ed25519(); +// let user_1 = get_ed25519_account(user_1_keypair.public()); +// let user_2_keypair = get_bob_ed25519(); +// let user_2 = get_ed25519_account(user_2_keypair.public()); +// let user_3_keypair = get_charlie_ed25519(); +// let user_3 = get_ed25519_account(user_3_keypair.public()); + +// let (root_id, mut root_node) = ( +// get_delegation_root_id(true), +// generate_base_delegation_hierarchy(user_1.clone()), +// ); +// root_node.revoked = true; +// let (delegation_id_1, mut delegation_node_1) = +// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); +// delegation_node_1.revoked = true; +// let (delegation_id_2, mut delegation_node_2) = +// (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); +// delegation_node_2.parent = Some(delegation_id_1); + +// // 1 less than needed +// let max_parent_checks = 1u32; + +// // Root -> Delegation 1 -> Delegation 2 +// let mut ext = ExtBuilder::default() +// .with_delegation_hierarchies(vec![(root_id, root_node)]) +// .with_delegations(vec![ +// (delegation_id_1, delegation_node_1), +// (delegation_id_2, delegation_node_2), +// ]) +// .with_children(vec![ +// (root_id, vec![delegation_id_1]), +// (delegation_id_1, vec![delegation_id_2]), +// ]) +// .build(None); + +// ext.execute_with(|| { +// assert_noop!( +// Delegation::is_delegating(&user_1, &delegation_id_2, max_parent_checks), +// delegation::Error::::MaxSearchDepthReached +// ); +// }); +// } From 7249e291f8bf95b53cb4daa1ed52628ee7352df3 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 12 Jul 2021 15:52:26 +0200 Subject: [PATCH 04/49] wip: refactoring test cases --- .../delegation/src/delegation_hierarchy.rs | 41 +- pallets/delegation/src/lib.rs | 20 +- pallets/delegation/src/mock.rs | 113 +- pallets/delegation/src/tests.rs | 1483 +++++++---------- 4 files changed, 701 insertions(+), 956 deletions(-) diff --git a/pallets/delegation/src/delegation_hierarchy.rs b/pallets/delegation/src/delegation_hierarchy.rs index 1a02be1b2a..85ac551fcb 100644 --- a/pallets/delegation/src/delegation_hierarchy.rs +++ b/pallets/delegation/src/delegation_hierarchy.rs @@ -56,37 +56,25 @@ impl Default for Permissions { #[derive(Clone, Debug, Encode, Decode, PartialEq)] pub struct DelegationNode { - pub hierarchy_id: DelegationHierarchyIdOf, + pub hierarchy_root_id: DelegationNodeIdOf, pub parent: Option>, pub children: BTreeSet>, pub details: DelegationDetails, } -#[derive(Clone, Debug, Encode, Decode, PartialEq)] -pub struct DelegationDetails { - pub owner: DelegatorIdOf, - pub revoked: bool, - pub permissions: Permissions, -} - impl DelegationNode { - pub fn new_root_node(hierarchy_id: DelegationHierarchyIdOf, owner: DelegatorIdOf) -> Self { + pub fn new_root_node(id: DelegationNodeIdOf, details: DelegationDetails) -> Self { Self { - hierarchy_id, + hierarchy_root_id: id, parent: None, children: BTreeSet::new(), - details: DelegationDetails { - owner, - revoked: false, - permissions: Permissions::all(), - }, + details, } } - pub fn new_node(hierarchy_id: DelegationHierarchyIdOf, parent: DelegationNodeIdOf, owner: DelegatorIdOf, permissions: Permissions) -> Self { - let mut new_node = Self::new_root_node(hierarchy_id, owner); + pub fn new_node(hierarchy_root_id: DelegationNodeIdOf, parent: DelegationNodeIdOf, details: DelegationDetails) -> Self { + let mut new_node = Self::new_root_node(hierarchy_root_id, details); new_node.parent = Some(parent); - new_node.details.permissions = permissions; new_node } @@ -96,6 +84,23 @@ impl DelegationNode { } } +#[derive(Clone, Debug, Encode, Decode, PartialEq)] +pub struct DelegationDetails { + pub owner: DelegatorIdOf, + pub revoked: bool, + pub permissions: Permissions, +} + +impl DelegationDetails { + pub fn default_with_owner(owner: DelegatorIdOf) -> Self { + Self { + owner, + permissions: Permissions::all(), + revoked: false + } + } +} + #[derive(Clone, Debug, Encode, Decode, Eq, PartialEq, Ord, PartialOrd)] pub struct DelegationHierarchyInfo { pub ctype_hash: CtypeHashOf, diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 38cc40967e..6e9dfe54e8 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -192,7 +192,7 @@ pub mod pallet { >::CTypeNotFound ); - Self::create_and_store_hierarchy_root(root_node_id, DelegationHierarchyInfo:: { ctype_hash }, creator.clone()); + Self::create_and_store_new_hierarchy(root_node_id, DelegationHierarchyInfo:: { ctype_hash }, creator.clone()); Self::deposit_event(Event::HierarchyCreated(creator, root_node_id, ctype_hash)); @@ -231,7 +231,7 @@ pub mod pallet { let delegator = ::EnsureOrigin::ensure_origin(origin)?; // Calculate the hash root - let hash_root = Self::calculate_hash_root(&delegation_id, &root_node_id.into(), &Some(parent_id), &permissions); + let hash_root = Self::calculate_delegation_hash_root(&delegation_id, &root_node_id, &parent_id, &permissions); // Verify that the hash root signature is correct. DelegationSignatureVerificationOf::::verify(&delegate, &hash_root.encode(), &delegate_signature) @@ -255,7 +255,7 @@ pub mod pallet { Error::::UnauthorizedDelegation ); - Self::store_delegation_under_parent(delegation_id, DelegationNode::new_node(root_node_id, parent_id, delegate.clone(), permissions), parent_id, parent_node); + Self::store_delegation_under_parent(delegation_id, DelegationNode::new_node(root_node_id, parent_id, DelegationDetails { owner: delegate.clone(), permissions, revoked: false }), parent_id, parent_node); Self::deposit_event(Event::DelegationCreated( delegator, @@ -383,26 +383,24 @@ pub mod pallet { impl Pallet { // Calculate the hash of all values of a delegation transaction - fn calculate_hash_root( + fn calculate_delegation_hash_root( delegation_id: &DelegationNodeIdOf, root_id: &DelegationNodeIdOf, - parent_id: &Option>, + parent_id: &DelegationNodeIdOf, permissions: &Permissions, ) -> T::Hash { // Add all values to an u8 vector let mut hashed_values: Vec = delegation_id.as_ref().to_vec(); hashed_values.extend_from_slice(root_id.as_ref()); - if let Some(parent) = parent_id { - hashed_values.extend_from_slice(parent.as_ref()) - } + hashed_values.extend_from_slice(parent_id.as_ref()); hashed_values.extend_from_slice(permissions.as_u8().as_ref()); // Hash the resulting vector T::Hashing::hash(&hashed_values) } - fn create_and_store_hierarchy_root(root_id: DelegationNodeIdOf, hierarchy_info: DelegationHierarchyInfo, hierarchy_owner: DelegatorIdOf) { - let root_node = DelegationNode::new_root_node(root_id, hierarchy_owner); - >::insert(root_id.into(), root_node); + fn create_and_store_new_hierarchy(root_id: DelegationNodeIdOf, hierarchy_info: DelegationHierarchyInfo, hierarchy_owner: DelegatorIdOf) { + let root_node = DelegationNode::new_root_node(root_id, DelegationDetails::default_with_owner(hierarchy_owner)); + >::insert(root_id, root_node); >::insert(root_id, hierarchy_info); } diff --git a/pallets/delegation/src/mock.rs b/pallets/delegation/src/mock.rs index 3ec4cff2fa..30c8096328 100644 --- a/pallets/delegation/src/mock.rs +++ b/pallets/delegation/src/mock.rs @@ -43,7 +43,6 @@ pub type Block = frame_system::mocking::MockBlock; pub type TestCtypeOwner = kilt_primitives::AccountId; pub type TestCtypeHash = kilt_primitives::Hash; pub type TestDelegationNodeId = kilt_primitives::Hash; -pub type TestDelegationHierarchyId = TestDelegationNodeId; pub type TestDelegatorId = TestCtypeOwner; pub type TestDelegateSignature = MultiSignature; @@ -108,7 +107,6 @@ impl Config for Test { type DelegationSignatureVerification = Self; type DelegationEntityId = TestDelegatorId; type DelegationNodeId = TestDelegationNodeId; - type DelegationHierarchyId = TestDelegationHierarchyId; type EnsureOrigin = EnsureSigned; type Event = (); type MaxSignatureByteLength = MaxSignatureByteLength; @@ -149,8 +147,8 @@ const DEFAULT_HIERARCHY_ID_SEED: u64 = 1u64; const ALTERNATIVE_HIERARCHY_ID_SEED: u64 = 2u64; const DEFAULT_DELEGATION_ID_SEED: u64 = 3u64; const ALTERNATIVE_DELEGATION_ID_SEED: u64 = 4u64; -const DEFAULT_DELEGATION_ID_2_SEED: u64 = 3u64; -const ALTERNATIVE_DELEGATION_ID_2_SEED: u64 = 4u64; +const DEFAULT_DELEGATION_ID_2_SEED: u64 = 5u64; +const ALTERNATIVE_DELEGATION_ID_2_SEED: u64 = 6u64; pub fn get_origin(account: TestDelegatorId) -> Origin { Origin::signed(account) @@ -188,11 +186,11 @@ pub fn get_charlie_sr25519() -> sr25519::Pair { sr25519::Pair::from_seed(&CHARLIE_SEED) } -pub fn get_delegation_hierarchy_id(default: bool) -> TestDelegationHierarchyId { +pub fn get_delegation_hierarchy_id(default: bool) -> TestDelegationNodeId { if default { - TestDelegationHierarchyId::from_low_u64_be(DEFAULT_HIERARCHY_ID_SEED) + TestDelegationNodeId::from_low_u64_be(DEFAULT_HIERARCHY_ID_SEED) } else { - TestDelegationHierarchyId::from_low_u64_be(ALTERNATIVE_HIERARCHY_ID_SEED) + TestDelegationNodeId::from_low_u64_be(ALTERNATIVE_HIERARCHY_ID_SEED) } } @@ -217,95 +215,97 @@ pub(crate) fn hash_to_u8(hash: T) -> Vec { hash.encode() } -pub struct DelegationHierarchyCreationDetails { - pub id: TestDelegationHierarchyId, +pub fn generate_base_delegation_hierarchy_info() -> DelegationHierarchyInfo { + DelegationHierarchyInfo { + ctype_hash: ctype_mock::get_ctype_hash(true), + } +} + +pub fn generate_base_delegation_node(hierarchy_id: TestDelegationNodeId, owner: TestDelegatorId, parent: Option) -> DelegationNode { + DelegationNode { + details: generate_base_delegation_details(owner), + children: BTreeSet::new(), + hierarchy_root_id: hierarchy_id, + parent, + } +} + +pub fn generate_base_delegation_details(owner: TestDelegatorId) -> DelegationDetails { + DelegationDetails { + owner, + permissions: Permissions::DELEGATE, + revoked: false, + } +} + +pub struct DelegationHierarchyCreationOperation { + pub id: TestDelegationNodeId, pub ctype_hash: TestCtypeHash, } -pub fn generate_base_delegation_hierarchy_creation_details( - id: TestDelegationHierarchyId -) -> DelegationHierarchyCreationDetails { - DelegationHierarchyCreationDetails { +pub fn generate_base_delegation_hierarchy_creation_operation(id: TestDelegationNodeId) -> DelegationHierarchyCreationOperation { + DelegationHierarchyCreationOperation { id, - ctype_hash: ctype_mock::get_ctype_hash(true) + ctype_hash: ctype::mock::get_ctype_hash(true) } } -pub struct DelegationCreationDetails { +pub struct DelegationCreationOperation { pub delegation_id: TestDelegationNodeId, - pub hierarchy_id: TestDelegationHierarchyId, - pub parent_id: Option, + pub hierarchy_id: TestDelegationNodeId, + pub parent_id: TestDelegationNodeId, pub delegate: TestDelegatorId, pub permissions: Permissions, pub delegate_signature: TestDelegateSignature, } -pub fn generate_base_delegation_creation_details( +pub fn generate_base_delegation_creation_operation( delegation_id: TestDelegationNodeId, delegate_signature: TestDelegateSignature, delegation_node: DelegationNode, -) -> DelegationCreationDetails { - DelegationCreationDetails { +) -> DelegationCreationOperation { + DelegationCreationOperation { delegation_id, - parent_id: delegation_node.parent, - hierarchy_id: delegation_node.hierarchy_id, + parent_id: delegation_node.parent.expect("Delegation node must specify a parent ID upon creation"), + hierarchy_id: delegation_node.hierarchy_root_id, delegate: delegation_node.details.owner, delegate_signature, permissions: delegation_node.details.permissions, } } -pub struct DelegationHierarchyRevocationDetails { - pub id: TestDelegationHierarchyId, +pub struct DelegationHierarchyRevocationOperation { + pub id: TestDelegationNodeId, pub max_children: u32, } -pub fn generate_base_delegation_hierarchy_revocation_details( - id: TestDelegationHierarchyId, -) -> DelegationHierarchyRevocationDetails { - DelegationHierarchyRevocationDetails { +pub fn generate_base_delegation_hierarchy_revocation_operation( + id: TestDelegationNodeId, +) -> DelegationHierarchyRevocationOperation { + DelegationHierarchyRevocationOperation { id, max_children: 0u32, } } -pub struct DelegationRevocationDetails { +pub struct DelegationRevocationOperation { pub delegation_id: TestDelegationNodeId, pub max_parent_checks: u32, pub max_revocations: u32, } -pub fn generate_base_delegation_revocation_details(delegation_id: TestDelegationNodeId) -> DelegationRevocationDetails { - DelegationRevocationDetails { +pub fn generate_base_delegation_revocation_operation(delegation_id: TestDelegationNodeId) -> DelegationRevocationOperation { + DelegationRevocationOperation { delegation_id, max_parent_checks: 0u32, max_revocations: 0u32, } } -pub fn generate_base_delegation_hierarchy(owner: TestDelegatorId) -> DelegationHierarchyInfo { - DelegationHierarchyInfo { - ctype_hash: ctype_mock::get_ctype_hash(true), - } -} - -pub fn generate_base_delegation_node(hierarchy_id: TestDelegationHierarchyId, owner: TestDelegatorId) -> DelegationNode { - DelegationNode { - details: DelegationDetails { - owner, - permissions: Permissions::DELEGATE, - revoked: false, - }, - children: BTreeSet::new(), - hierarchy_id, - parent: None, - } -} - #[derive(Clone)] pub struct ExtBuilder { ctype_builder: Option, - delegation_hierarchies_stored: Vec<(TestDelegationHierarchyId, DelegationHierarchyInfo, DelegationDetails)>, + delegation_hierarchies_stored: Vec<(TestDelegationNodeId, DelegationHierarchyInfo, DelegatorIdOf)>, delegations_stored: Vec<(TestDelegationNodeId, DelegationNode)>, } @@ -322,7 +322,7 @@ impl Default for ExtBuilder { impl ExtBuilder { pub fn with_delegation_hierarchies( mut self, - delegation_hierarchies: Vec<(TestDelegationHierarchyId, DelegationHierarchyInfo, DelegationDetails)>, + delegation_hierarchies: Vec<(TestDelegationNodeId, DelegationHierarchyInfo, DelegatorIdOf)>, ) -> Self { self.delegation_hierarchies_stored = delegation_hierarchies; self @@ -344,7 +344,7 @@ impl ExtBuilder { if !self.delegation_hierarchies_stored.is_empty() { ext.execute_with(|| { self.delegation_hierarchies_stored.iter().for_each(|delegation_hierarchy| { - delegation::Pallet::create_and_store_hierarchy_root(delegation_hierarchy.0, delegation_hierarchy.1.clone(), delegation_hierarchy.2.owner.clone()); + delegation::Pallet::create_and_store_new_hierarchy(delegation_hierarchy.0, delegation_hierarchy.1.clone(), delegation_hierarchy.2.clone()); }) }); } @@ -352,10 +352,9 @@ impl ExtBuilder { if !self.delegations_stored.is_empty() { ext.execute_with(|| { self.delegations_stored.iter().for_each(|del| { - if let Some(parent_node_id) = del.1.parent { - let mut parent_node = delegation::DelegationNodes::::get(&parent_node_id).unwrap(); - delegation::Pallet::store_delegation_under_parent(del.0, del.1.clone(), parent_node_id, parent_node); - } + let parent_node_id = del.1.parent.expect("Delegation node that is not a root must have a parent ID specified."); + let parent_node = delegation::DelegationNodes::::get(&parent_node_id).unwrap(); + delegation::Pallet::store_delegation_under_parent(del.0, del.1.clone(), parent_node_id, parent_node); }) }); } diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index 7f278689a1..ade4f173c6 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -30,9 +30,9 @@ fn create_root_delegation_successful() { let creator_keypair = get_alice_ed25519(); let creator = get_ed25519_account(creator_keypair.public()); - let hierarchy_id = get_delegation_hierarchy_id(true); + let hierarchy_root_id = get_delegation_hierarchy_id(true); - let operation = generate_base_delegation_hierarchy_creation_details(hierarchy_id); + let operation = generate_base_delegation_hierarchy_creation_operation(hierarchy_root_id); let mut ext = ctype_mock::ExtBuilder::default() .with_ctypes(vec![(operation.ctype_hash.clone(), creator.clone())]) @@ -46,998 +46,741 @@ fn create_root_delegation_successful() { )); }); - let stored_hierarchy_details = ext.execute_with(|| Delegation::delegation_hierarchies(&hierarchy_id).expect("Delegation hierarchy should be present on chain.")); + let stored_hierarchy_details = ext.execute_with(|| Delegation::delegation_hierarchies(&hierarchy_root_id).expect("Delegation hierarchy should be present on chain.")); assert_eq!(stored_hierarchy_details.ctype_hash, operation.ctype_hash); - let stored_delegation_root = ext.execute_with(|| Delegation::delegation_nodes(&hierarchy_id).expect("Delegation root should be present on chain.")); + let stored_delegation_root = ext.execute_with(|| Delegation::delegation_nodes(&hierarchy_root_id).expect("Delegation root should be present on chain.")); - - assert_eq!(stored_delegation_root.hierarchy_id, hierarchy_id); + assert_eq!(stored_delegation_root.hierarchy_root_id, hierarchy_root_id); assert_eq!(stored_delegation_root.parent, None); assert_eq!(stored_delegation_root.children.len(), 0); assert_eq!(stored_delegation_root.details.owner, creator); assert!(!stored_delegation_root.details.revoked); } -// #[test] -// fn duplicate_create_root_delegation_error() { -// let creator_keypair = get_alice_ed25519(); -// let creator = get_ed25519_account(creator_keypair.public()); +#[test] +fn duplicate_create_root_delegation_error() { + let creator_keypair = get_alice_ed25519(); + let creator = get_ed25519_account(creator_keypair.public()); -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(creator.clone()), -// ); + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); -// let operation = generate_base_delegation_hierarchy_creation_details(root_id, root_node.clone()); + let operation = generate_base_delegation_hierarchy_creation_operation(hierarchy_root_id); -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .build(Some(ext)); + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(operation.ctype_hash.clone(), creator.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), creator.clone())]).build(Some(ext)); -// ext.execute_with(|| { -// assert_err!( -// Delegation::create_root(get_origin(creator.clone()), operation.id, operation.ctype_hash), -// delegation::Error::::RootAlreadyExists -// ); -// }); -// } + ext.execute_with(|| { + assert_noop!(Delegation::create_hierarchy( + get_origin(creator.clone()), + operation.id, + operation.ctype_hash + ), + delegation::Error::::HierarchyAlreadyExists + ); + }); +} -// #[test] -// fn ctype_not_found_create_root_delegation_error() { -// let creator_keypair = get_alice_ed25519(); -// let creator = get_ed25519_account(creator_keypair.public()); +#[test] +fn ctype_not_found_create_root_delegation_error() { + let creator_keypair = get_alice_ed25519(); + let creator = get_ed25519_account(creator_keypair.public()); -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(creator.clone()), -// ); + let hierarchy_root_id = get_delegation_hierarchy_id(true); -// let operation = generate_base_delegation_hierarchy_creation_details(root_id, root_node); + let operation = generate_base_delegation_hierarchy_creation_operation(hierarchy_root_id); -// // No CTYPE stored, -// let mut ext = ExtBuilder::default().build(None); + // No CTYPE stored, + let mut ext = ExtBuilder::default().build(None); -// ext.execute_with(|| { -// assert_err!( -// Delegation::create_root(get_origin(creator.clone()), operation.id, operation.ctype_hash), -// ctype::Error::::CTypeNotFound -// ); -// }); -// } + ext.execute_with(|| { + assert_noop!( + Delegation::create_hierarchy(get_origin(creator.clone()), operation.id, operation.ctype_hash), + ctype::Error::::CTypeNotFound + ); + }); +} -// // submit_delegation_creation_operation() +// submit_delegation_creation_operation() -// #[test] -// fn create_delegation_no_parent_successful() { -// let creator_keypair = get_alice_ed25519(); -// let creator = get_ed25519_account(creator_keypair.public()); -// let delegate_keypair = get_bob_sr25519(); -// let delegate = get_sr25519_account(delegate_keypair.public()); +#[test] +fn create_delegation_direct_root_successful() { + let creator_keypair = get_alice_ed25519(); + let creator = get_ed25519_account(creator_keypair.public()); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(creator.clone()), -// ); -// let (delegation_id, delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, delegate), -// ); + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); -// let delegation_info = Delegation::calculate_hash( -// &delegation_id, -// &delegation_node.root_id, -// &delegation_node.parent, -// &delegation_node.permissions, -// ); + let delegation_info = Delegation::calculate_delegation_hash_root( + &delegation_id, + &delegation_node.hierarchy_root_id, + &hierarchy_root_id, + &delegation_node.details.permissions, + ); -// let delegate_signature = delegate_keypair.sign(&hash_to_u8(delegation_info)); + let delegate_signature = delegate_keypair.sign(&hash_to_u8(delegation_info)); -// let operation = -// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + let operation = generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .build(Some(ext)); + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash.clone(), creator.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), creator.clone())]) + .build(Some(ext)); -// ext.execute_with(|| { -// assert_ok!(Delegation::add_delegation( -// get_origin(creator.clone()), -// operation.delegation_id, -// operation.hierarchy_id, -// operation.parent_id, -// operation.delegate.clone(), -// operation.permissions, -// operation.delegate_signature.clone().encode(), -// )); -// }); + ext.execute_with(|| { + assert_ok!(Delegation::add_delegation( + get_origin(creator.clone()), + operation.delegation_id, + operation.hierarchy_id, + operation.parent_id, + operation.delegate.clone(), + operation.permissions, + operation.delegate_signature.clone().encode(), + )); + }); -// let stored_delegation = ext.execute_with(|| { -// Delegation::delegations(&operation.delegation_id).expect("Delegation should be present on chain.") -// }); + let stored_delegation = ext.execute_with(|| { + Delegation::delegation_nodes(&operation.delegation_id).expect("Delegation should be present on chain.") + }); -// assert_eq!(stored_delegation.root_id, operation.hierarchy_id); -// assert_eq!(stored_delegation.parent, operation.parent_id); -// assert_eq!(stored_delegation.owner, operation.delegate); -// assert_eq!(stored_delegation.permissions, operation.permissions); -// assert!(!stored_delegation.revoked); + assert_eq!(stored_delegation.hierarchy_root_id, operation.hierarchy_id); + assert_eq!(stored_delegation.parent, Some(operation.parent_id)); + assert!(stored_delegation.children.is_empty()); + assert_eq!(stored_delegation.details.owner, operation.delegate); + assert_eq!(stored_delegation.details.permissions, operation.permissions); + assert!(!stored_delegation.details.revoked); -// // Verify that the root has the new delegation among its children -// let stored_root_children = ext.execute_with(|| { -// Delegation::children(&operation.hierarchy_id).expect("Delegation root children should be present on chain.") -// }); + // Verify that the root has the new delegation among its children + let stored_root = ext.execute_with(|| { + Delegation::delegation_nodes(&operation.hierarchy_id).expect("Delegation root should be present on chain.") + }); -// assert_eq!(stored_root_children, vec![operation.delegation_id]); -// } + assert!(stored_root.children.contains(&operation.delegation_id)); +} -// #[test] -// fn create_delegation_with_parent_successful() { -// let creator_keypair = get_alice_ed25519(); -// let creator = get_ed25519_account(creator_keypair.public()); -// let delegate_keypair = get_bob_sr25519(); -// let delegate = get_sr25519_account(delegate_keypair.public()); +#[test] +fn create_delegation_with_parent_successful() { + let creator_keypair = get_alice_ed25519(); + let creator = get_ed25519_account(creator_keypair.public()); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(creator.clone()), -// ); -// let (parent_delegation_id, parent_delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, creator.clone()), -// ); -// let (delegation_id, mut delegation_node) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate.clone()), -// ); -// delegation_node.parent = Some(parent_delegation_id); + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, creator.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); -// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( -// &delegation_id, -// &delegation_node.root_id, -// &delegation_node.parent, -// &delegation_node.permissions, -// ))); + let delegation_info = Delegation::calculate_delegation_hash_root( + &delegation_id, + &delegation_node.hierarchy_root_id, + &parent_id, + &delegation_node.details.permissions, + ); -// let operation = -// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + let delegate_signature = delegate_keypair.sign(&hash_to_u8(delegation_info)); -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![(parent_delegation_id, parent_delegation_node)]) -// .with_children(vec![(root_id, vec![(parent_delegation_id)])]) -// .build(Some(ext)); + let operation = generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); -// ext.execute_with(|| { -// assert_ok!(Delegation::add_delegation( -// get_origin(creator.clone()), -// operation.delegation_id, -// operation.hierarchy_id, -// operation.parent_id, -// delegate.clone(), -// operation.permissions, -// operation.delegate_signature.clone().encode(), -// )); -// }); + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash.clone(), creator.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), creator.clone())]) + .with_delegations(vec![(parent_id.clone(), parent_node.clone())]) + .build(Some(ext)); -// let stored_delegation = ext.execute_with(|| { -// Delegation::delegations(&operation.delegation_id).expect("Delegation should be present on chain.") -// }); + ext.execute_with(|| { + assert_ok!(Delegation::add_delegation( + get_origin(creator.clone()), + operation.delegation_id, + operation.hierarchy_id, + operation.parent_id, + operation.delegate.clone(), + operation.permissions, + operation.delegate_signature.clone().encode(), + )); + }); -// assert_eq!(stored_delegation.root_id, operation.hierarchy_id); -// assert_eq!(stored_delegation.parent, operation.parent_id); -// assert_eq!(stored_delegation.owner, operation.delegate); -// assert_eq!(stored_delegation.permissions, operation.permissions); -// assert!(!stored_delegation.revoked); + let stored_delegation = ext.execute_with(|| { + Delegation::delegation_nodes(&operation.delegation_id).expect("Delegation should be present on chain.") + }); -// // Verify that the parent has the new delegation among its children -// let stored_parent_children = ext.execute_with(|| { -// Delegation::children(&operation.parent_id.unwrap()) -// .expect("Delegation parent children should be present on chain.") -// }); + assert_eq!(stored_delegation.hierarchy_root_id, operation.hierarchy_id); + assert_eq!(stored_delegation.parent, Some(operation.parent_id)); + assert!(stored_delegation.children.is_empty()); + assert_eq!(stored_delegation.details.owner, operation.delegate); + assert_eq!(stored_delegation.details.permissions, operation.permissions); + assert!(!stored_delegation.details.revoked); -// assert_eq!(stored_parent_children, vec![delegation_id]); -// } + // Verify that the parent has the new delegation among its children + let stored_parent = ext.execute_with(|| { + Delegation::delegation_nodes(&operation.parent_id).expect("Delegation parent should be present on chain.") + }); -// #[test] -// fn invalid_delegate_signature_create_delegation_error() { -// let creator_keypair = get_alice_ed25519(); -// let creator = get_ed25519_account(creator_keypair.public()); -// let alternative_keypair = get_alice_sr25519(); -// let delegate_keypair = get_bob_sr25519(); -// let delegate = get_sr25519_account(delegate_keypair.public()); + assert!(stored_parent.children.contains(&operation.delegation_id)); +} -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(creator.clone()), -// ); -// let (delegation_id, delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, delegate.clone()), -// ); +#[test] +fn invalid_delegate_signature_create_delegation_error() { + let creator_keypair = get_alice_ed25519(); + let creator = get_ed25519_account(creator_keypair.public()); + let alternative_keypair = get_alice_sr25519(); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); -// let delegate_signature = alternative_keypair.sign(&hash_to_u8(Delegation::calculate_hash( -// &delegation_id, -// &delegation_node.root_id, -// &delegation_node.parent, -// &delegation_node.permissions, -// ))); + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); -// let operation = -// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + let delegate_signature = alternative_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( + &delegation_id, + &delegation_node.hierarchy_root_id, + &hierarchy_root_id, + &delegation_node.details.permissions, + ))); -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .build(Some(ext)); + let operation = + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); -// ext.execute_with(|| { -// assert_err!( -// Delegation::add_delegation( -// get_origin(creator.clone()), -// operation.delegation_id, -// operation.hierarchy_id, -// operation.parent_id, -// delegate.clone(), -// operation.permissions, -// operation.delegate_signature.clone().encode(), -// ), -// delegation::Error::::InvalidDelegateSignature -// ); -// }); -// } + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .build(Some(ext)); -// #[test] -// fn duplicate_delegation_create_delegation_error() { -// let creator_keypair = get_alice_ed25519(); -// let creator = get_ed25519_account(creator_keypair.public()); -// let delegate_keypair = get_bob_sr25519(); -// let delegate = get_sr25519_account(delegate_keypair.public()); + ext.execute_with(|| { + assert_noop!( + Delegation::add_delegation( + get_origin(creator.clone()), + operation.delegation_id, + operation.hierarchy_id, + operation.parent_id, + delegate.clone(), + operation.permissions, + operation.delegate_signature.clone().encode(), + ), + delegation::Error::::InvalidDelegateSignature + ); + }); +} -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(creator.clone()), -// ); -// let (delegation_id, delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, delegate.clone()), -// ); +#[test] +fn duplicate_delegation_create_delegation_error() { + let creator_keypair = get_alice_ed25519(); + let creator = get_ed25519_account(creator_keypair.public()); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); -// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( -// &delegation_id, -// &delegation_node.root_id, -// &delegation_node.parent, -// &delegation_node.permissions, -// ))); + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); -// let operation = -// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node.clone()); + let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( + &delegation_id, + &delegation_node.hierarchy_root_id, + &hierarchy_root_id, + &delegation_node.details.permissions, + ))); -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![(delegation_id, delegation_node)]) -// .with_children(vec![(root_id, vec![delegation_id])]) -// .build(Some(ext)); + let operation = + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); -// ext.execute_with(|| { -// assert_err!( -// Delegation::add_delegation( -// get_origin(creator.clone()), -// operation.delegation_id, -// operation.hierarchy_id, -// operation.parent_id, -// delegate.clone(), -// operation.permissions, -// operation.delegate_signature.clone().encode(), -// ), -// delegation::Error::::DelegationAlreadyExists -// ); -// }); -// } + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .with_delegations(vec![(delegation_id, delegation_node)]) + .build(Some(ext)); -// #[test] -// fn root_not_existing_create_delegation_error() { -// let creator_keypair = get_alice_ed25519(); -// let creator = get_ed25519_account(creator_keypair.public()); -// let delegate_keypair = get_bob_sr25519(); -// let delegate = get_sr25519_account(delegate_keypair.public()); + ext.execute_with(|| { + assert_noop!( + Delegation::add_delegation( + get_origin(creator.clone()), + operation.delegation_id, + operation.hierarchy_id, + operation.parent_id, + delegate.clone(), + operation.permissions, + operation.delegate_signature.clone().encode(), + ), + delegation::Error::::DelegationAlreadyExists + ); + }); +} -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(creator.clone()), -// ); -// let (delegation_id, delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, delegate.clone()), -// ); +#[test] +fn parent_not_existing_create_delegation_error() { + let creator_keypair = get_alice_ed25519(); + let creator = get_ed25519_account(creator_keypair.public()); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); -// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( -// &delegation_id, -// &delegation_node.root_id, -// &delegation_node.parent, -// &delegation_node.permissions, -// ))); + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); -// let operation = -// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( + &delegation_id, + &delegation_node.hierarchy_root_id, + &hierarchy_root_id, + &delegation_node.details.permissions, + ))); -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) -// .build(None); -// // No delegations added to the pallet storage -// let mut ext = ExtBuilder::default().build(Some(ext)); + let operation = + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); -// ext.execute_with(|| { -// assert_err!( -// Delegation::add_delegation( -// get_origin(creator.clone()), -// operation.delegation_id, -// operation.hierarchy_id, -// operation.parent_id, -// delegate.clone(), -// operation.permissions, -// operation.delegate_signature.clone().encode(), -// ), -// delegation::Error::::RootNotFound -// ); -// }); -// } + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .build(None); + // No delegations added to the pallet storage + let mut ext = ExtBuilder::default().build(Some(ext)); -// #[test] -// fn parent_not_existing_create_delegation_error() { -// let creator_keypair = get_alice_ed25519(); -// let creator = get_ed25519_account(creator_keypair.public()); -// let delegate_keypair = get_bob_sr25519(); -// let delegate = get_sr25519_account(delegate_keypair.public()); + ext.execute_with(|| { + assert_noop!( + Delegation::add_delegation( + get_origin(creator.clone()), + operation.delegation_id, + operation.hierarchy_id, + operation.parent_id, + delegate.clone(), + operation.permissions, + operation.delegate_signature.clone().encode(), + ), + delegation::Error::::ParentDelegationNotFound + ); + }); +} -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(creator.clone()), -// ); -// let alternative_parent_id = get_delegation_id(false); -// let (delegation_id, mut delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, delegate.clone()), -// ); -// delegation_node.parent = Some(alternative_parent_id); +#[test] +fn not_owner_of_parent_create_delegation_error() { + let creator_keypair = get_alice_ed25519(); + let creator = get_ed25519_account(creator_keypair.public()); + let alternative_owner_keypair = get_charlie_ed25519(); + let alternative_owner = get_ed25519_account(alternative_owner_keypair.public()); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, alternative_owner.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + + let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( + &delegation_id, + &delegation_node.hierarchy_root_id, + &parent_id, + &delegation_node.details.permissions, + ))); + + let operation = + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); + + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .with_delegations(vec![(parent_id, parent_node)]) + .build(Some(ext)); -// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( -// &delegation_id, -// &delegation_node.root_id, -// &delegation_node.parent, -// &delegation_node.permissions, -// ))); + ext.execute_with(|| { + assert_err!( + Delegation::add_delegation( + get_origin(creator.clone()), + operation.delegation_id, + operation.hierarchy_id, + operation.parent_id, + delegate.clone(), + operation.permissions, + operation.delegate_signature.clone().encode(), + ), + delegation::Error::::NotOwnerOfParentDelegation + ); + }); +} -// let operation = -// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); +#[test] +fn unauthorised_delegation_create_delegation_error() { + let creator_keypair = get_alice_ed25519(); + let creator = get_ed25519_account(creator_keypair.public()); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, mut parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, creator.clone(), Some(hierarchy_root_id))); + parent_node.details.permissions = delegation::Permissions::ATTEST; + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + + let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( + &delegation_id, + &delegation_node.hierarchy_root_id, + &parent_id, + &delegation_node.details.permissions, + ))); + + let operation = + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); + + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .with_delegations(vec![(parent_id, parent_node)]) + .build(Some(ext)); -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .build(Some(ext)); + ext.execute_with(|| { + assert_err!( + Delegation::add_delegation( + get_origin(creator.clone()), + operation.delegation_id, + operation.hierarchy_id, + operation.parent_id, + delegate.clone(), + operation.permissions, + operation.delegate_signature.clone().encode(), + ), + delegation::Error::::UnauthorizedDelegation + ); + }); +} -// ext.execute_with(|| { -// assert_err!( -// Delegation::add_delegation( -// get_origin(creator.clone()), -// operation.delegation_id, -// operation.hierarchy_id, -// operation.parent_id, -// delegate.clone(), -// operation.permissions, -// operation.delegate_signature.clone().encode(), -// ), -// delegation::Error::::ParentDelegationNotFound -// ); -// }); -// } +// submit_delegation_root_revocation_operation() -// #[test] -// fn not_owner_of_parent_create_delegation_error() { -// let creator_keypair = get_alice_ed25519(); -// let creator = get_ed25519_account(creator_keypair.public()); -// let alternative_owner_keypair = get_charlie_ed25519(); -// let alternative_owner = get_ed25519_account(alternative_owner_keypair.public()); -// let delegate_keypair = get_bob_sr25519(); -// let delegate = get_sr25519_account(delegate_keypair.public()); +#[test] +fn empty_revoke_root_successful() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(creator.clone()), -// ); -// let (parent_delegation_id, parent_delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, alternative_owner), -// ); -// let (delegation_id, mut delegation_node) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate.clone()), -// ); -// delegation_node.parent = Some(parent_delegation_id); + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); -// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( -// &delegation_id, -// &delegation_node.root_id, -// &delegation_node.parent, -// &delegation_node.permissions, -// ))); + let operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); -// let operation = -// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .build(Some(ext)); -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![(parent_delegation_id, parent_delegation_node)]) -// .with_children(vec![(root_id, vec![parent_delegation_id])]) -// .build(Some(ext)); + ext.execute_with(|| { + assert_ok!(Delegation::revoke_hierarchy( + get_origin(revoker.clone()), + operation.id, + operation.max_children + )); + }); -// ext.execute_with(|| { -// assert_err!( -// Delegation::add_delegation( -// get_origin(creator.clone()), -// operation.delegation_id, -// operation.hierarchy_id, -// operation.parent_id, -// delegate.clone(), -// operation.permissions, -// operation.delegate_signature.clone().encode(), -// ), -// delegation::Error::::NotOwnerOfParentDelegation -// ); -// }); -// } + let stored_delegation_hierarchy_root = ext + .execute_with(|| Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.")); -// #[test] -// fn unauthorised_delegation_create_delegation_error() { -// let creator_keypair = get_alice_ed25519(); -// let creator = get_ed25519_account(creator_keypair.public()); -// let delegate_keypair = get_bob_sr25519(); -// let delegate = get_sr25519_account(delegate_keypair.public()); + assert!(stored_delegation_hierarchy_root.details.revoked); +} -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(creator.clone()), -// ); -// let (parent_delegation_id, mut parent_delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, creator.clone()), -// ); -// parent_delegation_node.permissions = delegation::Permissions::ATTEST; -// let (delegation_id, mut delegation_node) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate.clone()), -// ); -// delegation_node.parent = Some(parent_delegation_id); +#[test] +fn list_hierarchy_revoke_root_successful() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); -// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( -// &delegation_id, -// &delegation_node.root_id, -// &delegation_node.parent, -// &delegation_node.permissions, -// ))); + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); -// let operation = -// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); + let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); + operation.max_children = 2u32; -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![(parent_delegation_id, parent_delegation_node)]) -// .with_children(vec![(root_id, vec![parent_delegation_id])]) -// .build(Some(ext)); + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); -// ext.execute_with(|| { -// assert_err!( -// Delegation::add_delegation( -// get_origin(creator.clone()), -// operation.delegation_id, -// operation.hierarchy_id, -// operation.parent_id, -// delegate.clone(), -// operation.permissions, -// operation.delegate_signature.clone().encode(), -// ), -// delegation::Error::::UnauthorizedDelegation -// ); -// }); -// } - -// #[test] -// fn not_owner_of_root_create_delegation_error() { -// let creator_keypair = get_alice_ed25519(); -// let creator = get_ed25519_account(creator_keypair.public()); -// let alternative_owner_keypair = get_charlie_ed25519(); -// let alternative_owner = get_ed25519_account(alternative_owner_keypair.public()); -// let delegate_keypair = get_bob_sr25519(); -// let delegate = get_sr25519_account(delegate_keypair.public()); - -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(alternative_owner), -// ); -// let (delegation_id, delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, delegate.clone()), -// ); - -// let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_hash( -// &delegation_id, -// &delegation_node.root_id, -// &delegation_node.parent, -// &delegation_node.permissions, -// ))); - -// let operation = -// generate_base_delegation_creation_details(delegation_id, delegate_signature.into(), delegation_node); - -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, creator.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .build(Some(ext)); - -// ext.execute_with(|| { -// assert_noop!( -// Delegation::add_delegation( -// get_origin(creator.clone()), -// operation.delegation_id, -// operation.hierarchy_id, -// operation.parent_id, -// delegate.clone(), -// operation.permissions, -// operation.delegate_signature.clone().encode(), -// ), -// delegation::Error::::NotOwnerOfRootDelegation -// ); -// }); -// } - -// // submit_delegation_root_revocation_operation() -// #[test] -// fn empty_revoke_root_successful() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); - -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(revoker.clone()), -// ); - -// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); -// operation.max_children = 2u32; - -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .build(Some(ext)); - -// ext.execute_with(|| { -// assert_ok!(Delegation::revoke_root( -// get_origin(revoker.clone()), -// operation.id, -// operation.max_children -// )); -// }); - -// let stored_delegation_root = ext -// .execute_with(|| Delegation::roots(&operation.id).expect("Delegation root should be present on chain.")); -// assert!(stored_delegation_root.revoked); -// } - -// #[test] -// fn list_hierarchy_revoke_root_successful() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); -// let delegate_keypair = get_bob_ed25519(); -// let delegate = get_ed25519_account(delegate_keypair.public()); - -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(revoker.clone()), -// ); -// let (parent_delegation_id, parent_delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, revoker.clone()), -// ); -// let (delegation_id, mut delegation_node) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate), -// ); -// delegation_node.parent = Some(parent_delegation_id); - -// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); -// operation.max_children = 2u32; - -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (parent_delegation_id, parent_delegation_node), -// (delegation_id, delegation_node), -// ]) -// .with_children(vec![ -// // Root -> Parent -> Delegation -// (root_id, vec![parent_delegation_id]), -// (parent_delegation_id, vec![delegation_id]), -// ]) -// .build(Some(ext)); - -// ext.execute_with(|| { -// assert_ok!(Delegation::revoke_root( -// get_origin(revoker.clone()), -// operation.id, -// operation.max_children -// )); -// }); - -// let stored_delegation_root = ext -// .execute_with(|| Delegation::roots(&operation.id).expect("Delegation root should be present on chain.")); -// assert!(stored_delegation_root.revoked); - -// let stored_parent_delegation = ext.execute_with(|| { -// Delegation::delegations(&parent_delegation_id).expect("Parent delegation should be present on chain.") -// }); -// assert!(stored_parent_delegation.revoked); + ext.execute_with(|| { + assert_ok!(Delegation::revoke_hierarchy( + get_origin(revoker.clone()), + operation.id, + operation.max_children + )); + }); -// let stored_delegation = -// ext.execute_with(|| Delegation::delegations(&delegation_id).expect("Delegation should be present on chain.")); -// assert!(stored_delegation.revoked); -// } + let stored_delegation_hierarchy_root = ext + .execute_with(|| Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.")); + assert!(stored_delegation_hierarchy_root.details.revoked); -// #[test] -// fn tree_hierarchy_revoke_root_successful() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); -// let delegate_keypair = get_bob_ed25519(); -// let delegate = get_ed25519_account(delegate_keypair.public()); + let stored_parent_delegation = ext.execute_with(|| { + Delegation::delegation_nodes(&parent_id).expect("Parent delegation should be present on chain.") + }); + assert!(stored_parent_delegation.details.revoked); -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(revoker.clone()), -// ); -// let (delegation_id_1, delegation_node_1) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, revoker.clone()), -// ); -// let (delegation_id_2, delegation_node_2) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate), -// ); + let stored_delegation = + ext.execute_with(|| Delegation::delegation_nodes(&delegation_id).expect("Delegation should be present on chain.")); + assert!(stored_delegation.details.revoked); +} -// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); -// operation.max_children = 2u32; +#[test] +fn tree_hierarchy_revoke_root_successful() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (delegation_id_1, delegation_node_1), -// (delegation_id_2, delegation_node_2), -// ]) -// .with_children(vec![ -// // Root -> Delegation 1 && Delegation 2 -// (root_id, vec![delegation_id_1, delegation_id_2]), -// ]) -// .build(Some(ext)); + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (delegation1_id, delegation1_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); + let (delegation2_id, delegation2_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); -// ext.execute_with(|| { -// assert_ok!(Delegation::revoke_root( -// get_origin(revoker.clone()), -// operation.id, -// operation.max_children -// )); -// }); + let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); + operation.max_children = 2u32; -// let stored_delegation_root = ext -// .execute_with(|| Delegation::roots(&operation.id).expect("Delegation root should be present on chain.")); -// assert!(stored_delegation_root.revoked); + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(delegation1_id, delegation1_node), (delegation2_id, delegation2_node)]) + .build(Some(ext)); -// let stored_delegation_1 = ext -// .execute_with(|| Delegation::delegations(&delegation_id_1).expect("Delegation 1 should be present on chain.")); -// assert!(stored_delegation_1.revoked); + ext.execute_with(|| { + assert_ok!(Delegation::revoke_hierarchy( + get_origin(revoker.clone()), + operation.id, + operation.max_children + )); + }); -// let stored_delegation_2 = ext -// .execute_with(|| Delegation::delegations(&delegation_id_2).expect("Delegation 2 should be present on chain.")); -// assert!(stored_delegation_2.revoked); -// } + let stored_delegation_hierarchy_root = ext + .execute_with(|| Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.")); + assert!(stored_delegation_hierarchy_root.details.revoked); -// #[test] -// fn greater_max_revocations_revoke_root_successful() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); -// let delegate_keypair = get_alice_ed25519(); -// let delegate = get_ed25519_account(delegate_keypair.public()); + let stored_delegation_1 = ext.execute_with(|| { + Delegation::delegation_nodes(&delegation1_id).expect("Delegation 1 should be present on chain.") + }); + assert!(stored_delegation_1.details.revoked); -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(revoker.clone()), -// ); -// let (delegation_id, delegation_node) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate), -// ); + let stored_delegation_2 = + ext.execute_with(|| Delegation::delegation_nodes(&delegation2_id).expect("Delegation 2 should be present on chain.")); + assert!(stored_delegation_2.details.revoked); +} -// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); -// operation.max_children = MaxRevocations::get(); +#[test] +fn max_max_revocations_revoke_successful() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![(delegation_id, delegation_node)]) -// .with_children(vec![ -// // Root -> Delegation -// (root_id, vec![delegation_id]), -// ]) -// .build(Some(ext)); + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); -// ext.execute_with(|| { -// assert_ok!(Delegation::revoke_root( -// get_origin(revoker.clone()), -// operation.id, -// operation.max_children -// )); -// }); + let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); + operation.max_children = MaxRevocations::get(); -// let stored_delegation_root = ext -// .execute_with(|| Delegation::roots(&operation.id).expect("Delegation root should be present on chain.")); -// assert!(stored_delegation_root.revoked); + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); -// let stored_delegation = -// ext.execute_with(|| Delegation::delegations(&delegation_id).expect("Delegation should be present on chain.")); -// assert!(stored_delegation.revoked); -// } + ext.execute_with(|| { + assert_ok!(Delegation::revoke_hierarchy( + get_origin(revoker.clone()), + operation.id, + operation.max_children + )); + }); -// #[test] -// fn root_not_found_revoke_root_error() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); + let stored_delegation_hierarchy_root = ext + .execute_with(|| Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.")); + assert!(stored_delegation_hierarchy_root.details.revoked); -// let root_id = get_delegation_root_id(true); + let stored_parent_delegation = ext.execute_with(|| { + Delegation::delegation_nodes(&parent_id).expect("Parent delegation should be present on chain.") + }); + assert!(stored_parent_delegation.details.revoked); -// let operation = generate_base_delegation_hierarchy_revocation_details(root_id); + let stored_delegation = + ext.execute_with(|| Delegation::delegation_nodes(&delegation_id).expect("Delegation should be present on chain.")); + assert!(stored_delegation.details.revoked); +} -// let mut ext = ExtBuilder::default().build(None); +#[test] +fn root_not_found_revoke_root_error() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); -// ext.execute_with(|| { -// assert_noop!( -// Delegation::revoke_root(get_origin(revoker.clone()), operation.id, operation.max_children), -// delegation::Error::::RootNotFound -// ); -// }); -// } + let hierarchy_root_id = get_delegation_hierarchy_id(true); -// #[test] -// fn different_root_creator_revoke_root_error() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); -// let alternative_revoker_keypair = get_charlie_ed25519(); -// let alternative_revoker = get_ed25519_account(alternative_revoker_keypair.public()); + let operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(alternative_revoker), -// ); + let mut ext = ExtBuilder::default().build(None); -// let operation = generate_base_delegation_hierarchy_revocation_details(root_id); + ext.execute_with(|| { + assert_noop!( + Delegation::revoke_hierarchy(get_origin(revoker.clone()), operation.id, operation.max_children), + delegation::Error::::HierarchyNotFound + ); + }); +} -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .build(Some(ext)); +#[test] +fn different_root_creator_revoke_root_error() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); + let alternative_revoker_keypair = get_charlie_ed25519(); + let alternative_revoker = get_ed25519_account(alternative_revoker_keypair.public()); -// ext.execute_with(|| { -// assert_noop!( -// Delegation::revoke_root(get_origin(revoker.clone()), operation.id, operation.max_children), -// delegation::Error::::UnauthorizedRevocation -// ); -// }); -// } + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); -// #[test] -// fn too_small_max_revocations_revoke_root_error() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); -// let delegate_keypair = get_alice_ed25519(); -// let delegate = get_ed25519_account(delegate_keypair.public()); + let operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(revoker.clone()), -// ); -// let (delegation_id, delegation_node) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate), -// ); + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, alternative_revoker.clone())]) + .build(Some(ext)); -// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); -// operation.max_children = 0u32; + ext.execute_with(|| { + assert_noop!( + Delegation::revoke_hierarchy(get_origin(revoker.clone()), operation.id, operation.max_children), + delegation::Error::::UnauthorizedRevocation + ); + }); +} -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![(delegation_id, delegation_node)]) -// .with_children(vec![ -// // Root -> Delegation -// (root_id, vec![delegation_id]), -// ]) -// .build(Some(ext)); +#[test] +fn too_small_max_revocations_revoke_root_error() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); + let delegate_keypair = get_alice_ed25519(); + let delegate = get_ed25519_account(delegate_keypair.public()); -// ext.execute_with(|| { -// assert_noop!( -// Delegation::revoke_root(get_origin(revoker.clone()), operation.id, operation.max_children), -// delegation::Error::::ExceededRevocationBounds -// ); -// }); -// } + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); -// #[test] -// fn exact_children_max_revocations_revoke_root_error() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); -// let delegate_keypair = get_alice_ed25519(); -// let delegate = get_ed25519_account(delegate_keypair.public()); + let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); + operation.max_children = 0u32; -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(revoker.clone()), -// ); -// let (delegation_id_1, delegation_node_1) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, delegate.clone()), -// ); -// let (delegation_id_2, mut delegation_node_2) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate.clone()), -// ); -// delegation_node_2.parent = Some(delegation_id_1); -// let (delegation_id_3, mut delegation_node_3) = ( -// get_delegation_root_id(false), -// generate_base_delegation_node(root_id, delegate), -// ); -// delegation_node_3.parent = Some(delegation_id_1); + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(delegation_id, delegation_node)]) + .build(Some(ext)); -// let mut operation = generate_base_delegation_hierarchy_revocation_details(root_id); -// operation.max_children = 2u32; + ext.execute_with(|| { + assert_noop!( + Delegation::revoke_hierarchy(get_origin(revoker.clone()), operation.id, operation.max_children), + delegation::Error::::ExceededRevocationBounds + ); + }); +} -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (delegation_id_1, delegation_node_1), -// (delegation_id_2, delegation_node_2), -// (delegation_id_3, delegation_node_3), -// ]) -// .with_children(vec![ -// // Root -> Delegation 1 -> Delegation 2 && Delegation 3 -// (root_id, vec![delegation_id_1]), -// (delegation_id_1, vec![delegation_id_2, delegation_id_3]), -// ]) -// .build(Some(ext)); +#[test] +fn exact_children_max_revocations_revoke_root_error() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); + let delegate_keypair = get_alice_ed25519(); + let delegate = get_ed25519_account(delegate_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (delegation1_id, delegation1_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); + let (delegation2_id, delegation2_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(delegation1_id))); + let (delegation3_id, delegation3_node) = (get_delegation_id_2(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(delegation1_id))); + + let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); + operation.max_children = 2u32; + + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(delegation1_id, delegation1_node), (delegation2_id, delegation2_node), (delegation3_id, delegation3_node)]) + .build(Some(ext)); -// ext.execute_with(|| { -// // assert_err and not asser_noop becase the storage is indeed changed, even tho -// // partially -// assert_err!( -// Delegation::revoke_root(get_origin(revoker.clone()), operation.id, operation.max_children), -// delegation::Error::::ExceededRevocationBounds -// ); -// }); + ext.execute_with(|| { + // assert_err and not asser_noop becase the storage is indeed changed, even tho + // partially + assert_err!( + Delegation::revoke_hierarchy(get_origin(revoker.clone()), operation.id, operation.max_children), + delegation::Error::::ExceededRevocationBounds + ); + }); -// let stored_delegation_root = ext -// .execute_with(|| Delegation::roots(&operation.id).expect("Delegation root should be present on chain.")); -// assert!(!stored_delegation_root.revoked); + let stored_delegation_root = ext + .execute_with(|| Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.")); + assert!(!stored_delegation_root.details.revoked); -// let stored_delegation_1 = ext -// .execute_with(|| Delegation::delegations(&delegation_id_1).expect("Delegation 1 should be present on chain.")); -// assert!(!stored_delegation_1.revoked); + let stored_delegation_1 = ext + .execute_with(|| Delegation::delegation_nodes(&delegation1_id).expect("Delegation 1 should be present on chain.")); + assert!(!stored_delegation_1.details.revoked); -// // Only this leaf should have been revoked as it is the first child of -// // delegation_1 -// let stored_delegation_2 = ext -// .execute_with(|| Delegation::delegations(&delegation_id_2).expect("Delegation 2 should be present on chain.")); -// assert!(stored_delegation_2.revoked); + // Only this leaf should have been revoked as it is the first child of + // delegation_1 + let stored_delegation_2 = ext + .execute_with(|| Delegation::delegation_nodes(&delegation2_id).expect("Delegation 2 should be present on chain.")); + assert!(stored_delegation_2.details.revoked); -// let stored_delegation_3 = ext -// .execute_with(|| Delegation::delegations(&delegation_id_3).expect("Delegation 3 should be present on chain.")); -// assert!(!stored_delegation_3.revoked); -// } + let stored_delegation_3 = ext + .execute_with(|| Delegation::delegation_nodes(&delegation3_id).expect("Delegation 3 should be present on chain.")); + assert!(!stored_delegation_3.details.revoked); +} -// // submit_delegation_revocation_operation() +// submit_delegation_revocation_operation() -// #[test] -// fn direct_owner_revoke_delegation_successful() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); -// let delegate_keypair = get_alice_ed25519(); -// let delegate = get_ed25519_account(delegate_keypair.public()); +#[test] +fn direct_owner_revoke_delegation_successful() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); + let delegate_keypair = get_alice_ed25519(); + let delegate = get_ed25519_account(delegate_keypair.public()); -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(revoker.clone()), -// ); -// let (parent_delegation_id, parent_delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, revoker.clone()), -// ); -// let (delegation_id, mut delegation_node) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate), -// ); -// delegation_node.parent = Some(parent_delegation_id); + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); -// let mut operation = generate_base_delegation_revocation_details(parent_delegation_id); -// operation.max_revocations = 2u32; + let mut operation = generate_base_delegation_revocation_operation(parent_id); + operation.max_revocations = 2u32; -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// // Root -> Parent -> Child -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (parent_delegation_id, parent_delegation_node), -// (delegation_id, delegation_node), -// ]) -// .with_children(vec![ -// (root_id, vec![parent_delegation_id]), -// (parent_delegation_id, vec![delegation_id]), -// ]) -// .build(Some(ext)); + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); -// ext.execute_with(|| { -// assert_ok!(Delegation::revoke_delegation( -// get_origin(revoker.clone()), -// operation.delegation_id, -// operation.max_parent_checks, -// operation.max_revocations -// )); -// }); + ext.execute_with(|| { + assert_ok!(Delegation::revoke_delegation( + get_origin(revoker.clone()), + operation.delegation_id, + operation.max_parent_checks, + operation.max_revocations + )); + }); -// let stored_parent_delegation = ext.execute_with(|| { -// Delegation::delegations(&parent_delegation_id).expect("Parent delegation should be present on chain.") -// }); -// assert!(stored_parent_delegation.revoked); + let stored_parent_delegation = ext.execute_with(|| { + Delegation::delegation_nodes(&parent_id).expect("Parent delegation should be present on chain.") + }); + assert!(stored_parent_delegation.details.revoked); -// let stored_child_delegation = ext.execute_with(|| { -// Delegation::delegations(&delegation_id).expect("Child delegation should be present on chain.") -// }); -// assert!(stored_child_delegation.revoked); -// } + let stored_child_delegation = ext.execute_with(|| { + Delegation::delegation_nodes(&delegation_id).expect("Child delegation should be present on chain.") + }); + assert!(stored_child_delegation.details.revoked); +} // #[test] // fn parent_owner_revoke_delegation_successful() { From 7c9e8e882ffa441d1dd5b3f3e76e188e70b00b8d Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 13 Jul 2021 09:06:39 +0200 Subject: [PATCH 05/49] test: unit tests passing again --- pallets/delegation/src/tests.rs | 1147 ++++++++++++++----------------- 1 file changed, 500 insertions(+), 647 deletions(-) diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index ade4f173c6..f5eb61a428 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -20,7 +20,7 @@ use codec::Encode; use frame_support::{assert_err, assert_noop, assert_ok}; use sp_core::Pair; -use crate::{self as delegation, DelegationHierarchyInfo, mock::*}; +use crate::{self as delegation, mock::*}; use ctype::mock as ctype_mock; // submit_delegation_root_creation_operation() @@ -388,7 +388,7 @@ fn not_owner_of_parent_create_delegation_error() { .build(Some(ext)); ext.execute_with(|| { - assert_err!( + assert_noop!( Delegation::add_delegation( get_origin(creator.clone()), operation.delegation_id, @@ -434,7 +434,7 @@ fn unauthorised_delegation_create_delegation_error() { .build(Some(ext)); ext.execute_with(|| { - assert_err!( + assert_noop!( Delegation::add_delegation( get_origin(creator.clone()), operation.delegation_id, @@ -782,647 +782,500 @@ fn direct_owner_revoke_delegation_successful() { assert!(stored_child_delegation.details.revoked); } -// #[test] -// fn parent_owner_revoke_delegation_successful() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); -// let delegate_keypair = get_alice_ed25519(); -// let delegate = get_ed25519_account(delegate_keypair.public()); - -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(revoker.clone()), -// ); -// let (parent_delegation_id, parent_delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, revoker.clone()), -// ); -// let (delegation_id, mut delegation_node) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate), -// ); -// delegation_node.parent = Some(parent_delegation_id); - -// let mut operation = generate_base_delegation_revocation_details(delegation_id); -// operation.max_parent_checks = 1u32; -// operation.max_revocations = 1u32; - -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (parent_delegation_id, parent_delegation_node), -// (delegation_id, delegation_node), -// ]) -// .with_children(vec![ -// (root_id, vec![parent_delegation_id]), -// (parent_delegation_id, vec![delegation_id]), -// ]) -// .build(Some(ext)); - -// ext.execute_with(|| { -// assert_ok!(Delegation::revoke_delegation( -// get_origin(revoker.clone()), -// operation.delegation_id, -// operation.max_parent_checks, -// operation.max_revocations -// )); -// }); - -// let stored_parent_delegation = ext.execute_with(|| { -// Delegation::delegations(&parent_delegation_id).expect("Parent delegation should be present on chain.") -// }); -// assert!(!stored_parent_delegation.revoked); - -// let stored_child_delegation = ext.execute_with(|| { -// Delegation::delegations(&delegation_id).expect("Child delegation should be present on chain.") -// }); -// assert!(stored_child_delegation.revoked); -// } - -// #[test] -// fn delegation_not_found_revoke_delegation_error() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); - -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(revoker.clone()), -// ); -// let delegation_id = get_delegation_id(true); - -// let operation = generate_base_delegation_revocation_details(delegation_id); - -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .build(Some(ext)); - -// ext.execute_with(|| { -// assert_noop!( -// Delegation::revoke_delegation( -// get_origin(revoker.clone()), -// operation.delegation_id, -// operation.max_parent_checks, -// operation.max_revocations -// ), -// delegation::Error::::DelegationNotFound -// ); -// }); -// } - -// #[test] -// fn not_delegating_revoke_delegation_error() { -// let owner_keypair = get_alice_ed25519(); -// let owner = get_ed25519_account(owner_keypair.public()); -// let revoker_keypair = get_bob_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); - -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(owner.clone()), -// ); -// let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(root_id, owner)); - -// let mut operation = generate_base_delegation_revocation_details(delegation_id); -// operation.max_parent_checks = MaxParentChecks::get(); - -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![(delegation_id, delegation_node)]) -// .with_children(vec![(root_id, vec![delegation_id])]) -// .build(Some(ext)); - -// ext.execute_with(|| { -// assert_noop!( -// Delegation::revoke_delegation( -// get_origin(revoker.clone()), -// operation.delegation_id, -// operation.max_parent_checks, -// operation.max_revocations -// ), -// delegation::Error::::UnauthorizedRevocation -// ); -// }); -// } - -// #[test] -// fn parent_too_far_revoke_delegation_error() { -// let owner_keypair = get_alice_ed25519(); -// let owner = get_ed25519_account(owner_keypair.public()); -// let intermediate_keypair = get_charlie_ed25519(); -// let intermediate = get_ed25519_account(intermediate_keypair.public()); -// let delegate_keypair = get_bob_ed25519(); -// let delegate = get_ed25519_account(delegate_keypair.public()); - -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(owner.clone()), -// ); -// let (parent_delegation_id, parent_delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, intermediate.clone()), -// ); -// let (delegation_id, mut delegation_node) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate), -// ); -// delegation_node.parent = Some(parent_delegation_id); - -// let mut operation = generate_base_delegation_revocation_details(delegation_id); -// operation.max_parent_checks = 0u32; - -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, owner)]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (parent_delegation_id, parent_delegation_node), -// (delegation_id, delegation_node), -// ]) -// .with_children(vec![ -// (root_id, vec![parent_delegation_id]), -// (parent_delegation_id, vec![delegation_id]), -// ]) -// .build(Some(ext)); - -// ext.execute_with(|| { -// assert_noop!( -// Delegation::revoke_delegation( -// get_origin(intermediate.clone()), -// operation.delegation_id, -// operation.max_parent_checks, -// operation.max_revocations -// ), -// delegation::Error::::MaxSearchDepthReached -// ); -// }); -// } - -// #[test] -// fn too_many_revocations_revoke_delegation_error() { -// let revoker_keypair = get_alice_ed25519(); -// let revoker = get_ed25519_account(revoker_keypair.public()); -// let delegate_keypair = get_bob_ed25519(); -// let delegate = get_ed25519_account(delegate_keypair.public()); - -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(revoker.clone()), -// ); -// let (parent_delegation_id, parent_delegation_node) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, revoker.clone()), -// ); -// let (delegation_id, mut delegation_node) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, delegate), -// ); -// delegation_node.parent = Some(parent_delegation_id); - -// let mut operation = generate_base_delegation_revocation_details(delegation_id); -// operation.max_parent_checks = 1u32; - -// let ext = ctype_mock::ExtBuilder::default() -// .with_ctypes(vec![(root_node.ctype_hash, revoker.clone())]) -// .build(None); -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (parent_delegation_id, parent_delegation_node), -// (delegation_id, delegation_node), -// ]) -// .with_children(vec![ -// (root_id, vec![parent_delegation_id]), -// (parent_delegation_id, vec![delegation_id]), -// ]) -// .build(Some(ext)); - -// ext.execute_with(|| { -// assert_noop!( -// Delegation::revoke_delegation( -// get_origin(revoker.clone()), -// operation.delegation_id, -// operation.max_parent_checks, -// operation.max_revocations -// ), -// delegation::Error::::ExceededRevocationBounds -// ); -// }); -// } - -// // Internal function: is_delegating() - -// #[test] -// fn is_delegating_direct_not_revoked() { -// let user_1_keypair = get_alice_ed25519(); -// let user_1 = get_ed25519_account(user_1_keypair.public()); -// let user_2_keypair = get_bob_ed25519(); -// let user_2 = get_ed25519_account(user_2_keypair.public()); -// let user_3_keypair = get_charlie_ed25519(); -// let user_3 = get_ed25519_account(user_3_keypair.public()); - -// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); -// let (delegation_id_1, delegation_node_1) = -// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); -// let (delegation_id_2, mut delegation_node_2) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, user_3.clone()), -// ); -// delegation_node_2.parent = Some(delegation_id_1); - -// let max_parent_checks = 0u32; - -// // Root -> Delegation 1 -> Delegation 2 -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (delegation_id_1, delegation_node_1), -// (delegation_id_2, delegation_node_2), -// ]) -// .with_children(vec![ -// (root_id, vec![delegation_id_1]), -// (delegation_id_1, vec![delegation_id_2]), -// ]) -// .build(None); - -// ext.execute_with(|| { -// assert_eq!( -// Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), -// Ok((true, max_parent_checks)) -// ); -// }); -// } - -// #[test] -// fn is_delegating_direct_not_revoked_max_parent_checks_value() { -// let user_1_keypair = get_alice_ed25519(); -// let user_1 = get_ed25519_account(user_1_keypair.public()); -// let user_2_keypair = get_bob_ed25519(); -// let user_2 = get_ed25519_account(user_2_keypair.public()); -// let user_3_keypair = get_charlie_ed25519(); -// let user_3 = get_ed25519_account(user_3_keypair.public()); - -// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); -// let (delegation_id_1, delegation_node_1) = -// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); -// let (delegation_id_2, mut delegation_node_2) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, user_3.clone()), -// ); -// delegation_node_2.parent = Some(delegation_id_1); - -// let max_parent_checks = u32::MAX; - -// // Root -> Delegation 1 -> Delegation 2 -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (delegation_id_1, delegation_node_1), -// (delegation_id_2, delegation_node_2), -// ]) -// .with_children(vec![ -// (root_id, vec![delegation_id_1]), -// (delegation_id_1, vec![delegation_id_2]), -// ]) -// .build(None); - -// ext.execute_with(|| { -// assert_eq!( -// Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), -// Ok((true, 0u32)) -// ); -// }); -// } - -// #[test] -// fn is_delegating_direct_revoked() { -// let user_1_keypair = get_alice_ed25519(); -// let user_1 = get_ed25519_account(user_1_keypair.public()); -// let user_2_keypair = get_bob_ed25519(); -// let user_2 = get_ed25519_account(user_2_keypair.public()); -// let user_3_keypair = get_charlie_ed25519(); -// let user_3 = get_ed25519_account(user_3_keypair.public()); - -// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); -// let (delegation_id_1, delegation_node_1) = -// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); -// let (delegation_id_2, mut delegation_node_2) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, user_3.clone()), -// ); -// delegation_node_2.parent = Some(delegation_id_1); -// delegation_node_2.revoked = true; - -// let max_parent_checks = 0u32; - -// // Root -> Delegation 1 -> Delegation 2 -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (delegation_id_1, delegation_node_1), -// (delegation_id_2, delegation_node_2), -// ]) -// .with_children(vec![ -// (root_id, vec![delegation_id_1]), -// (delegation_id_1, vec![delegation_id_2]), -// ]) -// .build(None); - -// ext.execute_with(|| { -// assert_eq!( -// Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), -// Ok((false, max_parent_checks)) -// ); -// }); -// } - -// #[test] -// fn is_delegating_direct_revoked_max_parent_checks_value() { -// let user_1_keypair = get_alice_ed25519(); -// let user_1 = get_ed25519_account(user_1_keypair.public()); -// let user_2_keypair = get_bob_ed25519(); -// let user_2 = get_ed25519_account(user_2_keypair.public()); -// let user_3_keypair = get_charlie_ed25519(); -// let user_3 = get_ed25519_account(user_3_keypair.public()); - -// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); -// let (delegation_id_1, delegation_node_1) = -// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); -// let (delegation_id_2, mut delegation_node_2) = ( -// get_delegation_id(false), -// generate_base_delegation_node(root_id, user_3.clone()), -// ); -// delegation_node_2.parent = Some(delegation_id_1); -// delegation_node_2.revoked = true; - -// let max_parent_checks = u32::MAX; - -// // Root -> Delegation 1 -> Delegation 2 -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (delegation_id_1, delegation_node_1), -// (delegation_id_2, delegation_node_2), -// ]) -// .with_children(vec![ -// (root_id, vec![delegation_id_1]), -// (delegation_id_1, vec![delegation_id_2]), -// ]) -// .build(None); - -// ext.execute_with(|| { -// assert_eq!( -// Delegation::is_delegating(&user_3, &delegation_id_2, max_parent_checks), -// Ok((false, 0u32)) -// ); -// }); -// } - -// #[test] -// fn is_delegating_max_parent_not_revoked() { -// let user_1_keypair = get_alice_ed25519(); -// let user_1 = get_ed25519_account(user_1_keypair.public()); -// let user_2_keypair = get_bob_ed25519(); -// let user_2 = get_ed25519_account(user_2_keypair.public()); -// let user_3_keypair = get_charlie_ed25519(); -// let user_3 = get_ed25519_account(user_3_keypair.public()); - -// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); -// let (delegation_id_1, delegation_node_1) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, user_2.clone()), -// ); -// let (delegation_id_2, mut delegation_node_2) = -// (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); -// delegation_node_2.parent = Some(delegation_id_1); - -// let max_parent_checks = 1u32; - -// // Root -> Delegation 1 -> Delegation 2 -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (delegation_id_1, delegation_node_1), -// (delegation_id_2, delegation_node_2), -// ]) -// .with_children(vec![ -// (root_id, vec![delegation_id_1]), -// (delegation_id_1, vec![delegation_id_2]), -// ]) -// .build(None); - -// ext.execute_with(|| { -// assert_eq!( -// Delegation::is_delegating(&user_2, &delegation_id_2, max_parent_checks), -// Ok((true, max_parent_checks - 1)) -// ); -// }); -// } - -// #[test] -// fn is_delegating_max_parent_revoked() { -// let user_1_keypair = get_alice_ed25519(); -// let user_1 = get_ed25519_account(user_1_keypair.public()); -// let user_2_keypair = get_bob_ed25519(); -// let user_2 = get_ed25519_account(user_2_keypair.public()); -// let user_3_keypair = get_charlie_ed25519(); -// let user_3 = get_ed25519_account(user_3_keypair.public()); - -// let (root_id, root_node) = (get_delegation_root_id(true), generate_base_delegation_hierarchy(user_1)); -// let (delegation_id_1, mut delegation_node_1) = ( -// get_delegation_id(true), -// generate_base_delegation_node(root_id, user_2.clone()), -// ); -// delegation_node_1.revoked = true; -// let (delegation_id_2, mut delegation_node_2) = -// (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); -// delegation_node_2.parent = Some(delegation_id_1); - -// let max_parent_checks = 2u32; - -// // Root -> Delegation 1 -> Delegation 2 -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (delegation_id_1, delegation_node_1), -// (delegation_id_2, delegation_node_2), -// ]) -// .with_children(vec![ -// (root_id, vec![delegation_id_1]), -// (delegation_id_1, vec![delegation_id_2]), -// ]) -// .build(None); - -// ext.execute_with(|| { -// assert_eq!( -// Delegation::is_delegating(&user_2, &delegation_id_2, max_parent_checks), -// Ok((false, max_parent_checks - 2)) -// ); -// }); -// } - -// #[test] -// fn is_delegating_root_owner_not_revoked() { -// let user_1_keypair = get_alice_ed25519(); -// let user_1 = get_ed25519_account(user_1_keypair.public()); -// let user_2_keypair = get_bob_ed25519(); -// let user_2 = get_ed25519_account(user_2_keypair.public()); -// let user_3_keypair = get_charlie_ed25519(); -// let user_3 = get_ed25519_account(user_3_keypair.public()); - -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(user_1.clone()), -// ); -// let (delegation_id_1, delegation_node_1) = -// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); -// let (delegation_id_2, mut delegation_node_2) = -// (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); -// delegation_node_2.parent = Some(delegation_id_1); - -// let max_parent_checks = 2u32; - -// // Root -> Delegation 1 -> Delegation 2 -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (delegation_id_1, delegation_node_1), -// (delegation_id_2, delegation_node_2), -// ]) -// .with_children(vec![ -// (root_id, vec![delegation_id_1]), -// (delegation_id_1, vec![delegation_id_2]), -// ]) -// .build(None); - -// ext.execute_with(|| { -// assert_eq!( -// Delegation::is_delegating(&user_1, &delegation_id_2, max_parent_checks), -// Ok((true, max_parent_checks - 1)) -// ); -// }); -// } - -// #[test] -// fn is_delegating_root_owner_revoked() { -// let user_1_keypair = get_alice_ed25519(); -// let user_1 = get_ed25519_account(user_1_keypair.public()); -// let user_2_keypair = get_bob_ed25519(); -// let user_2 = get_ed25519_account(user_2_keypair.public()); -// let user_3_keypair = get_charlie_ed25519(); -// let user_3 = get_ed25519_account(user_3_keypair.public()); - -// let (root_id, mut root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(user_1.clone()), -// ); -// root_node.revoked = true; -// let (delegation_id_1, mut delegation_node_1) = -// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); -// delegation_node_1.revoked = true; -// let (delegation_id_2, mut delegation_node_2) = -// (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); -// delegation_node_2.parent = Some(delegation_id_1); - -// let max_parent_checks = u32::MAX; - -// // Root -> Delegation 1 -> Delegation 2 -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (delegation_id_1, delegation_node_1), -// (delegation_id_2, delegation_node_2), -// ]) -// .with_children(vec![ -// (root_id, vec![delegation_id_1]), -// (delegation_id_1, vec![delegation_id_2]), -// ]) -// .build(None); - -// ext.execute_with(|| { -// assert_eq!( -// Delegation::is_delegating(&user_1, &delegation_id_2, max_parent_checks), -// Ok((false, 1u32)) -// ); -// }); -// } - -// #[test] -// fn is_delegating_delegation_not_found() { -// let user_1_keypair = get_alice_ed25519(); -// let user_1 = get_ed25519_account(user_1_keypair.public()); - -// let (root_id, root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(user_1.clone()), -// ); -// let delegation_id = get_delegation_id(true); - -// let max_parent_checks = 2u32; - -// // Root -> Delegation 1 -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .build(None); - -// ext.execute_with(|| { -// assert_noop!( -// Delegation::is_delegating(&user_1, &delegation_id, max_parent_checks), -// delegation::Error::::DelegationNotFound -// ); -// }); -// } - -// #[test] -// fn is_delegating_root_after_max_limit() { -// let user_1_keypair = get_alice_ed25519(); -// let user_1 = get_ed25519_account(user_1_keypair.public()); -// let user_2_keypair = get_bob_ed25519(); -// let user_2 = get_ed25519_account(user_2_keypair.public()); -// let user_3_keypair = get_charlie_ed25519(); -// let user_3 = get_ed25519_account(user_3_keypair.public()); - -// let (root_id, mut root_node) = ( -// get_delegation_root_id(true), -// generate_base_delegation_hierarchy(user_1.clone()), -// ); -// root_node.revoked = true; -// let (delegation_id_1, mut delegation_node_1) = -// (get_delegation_id(true), generate_base_delegation_node(root_id, user_2)); -// delegation_node_1.revoked = true; -// let (delegation_id_2, mut delegation_node_2) = -// (get_delegation_id(false), generate_base_delegation_node(root_id, user_3)); -// delegation_node_2.parent = Some(delegation_id_1); - -// // 1 less than needed -// let max_parent_checks = 1u32; - -// // Root -> Delegation 1 -> Delegation 2 -// let mut ext = ExtBuilder::default() -// .with_delegation_hierarchies(vec![(root_id, root_node)]) -// .with_delegations(vec![ -// (delegation_id_1, delegation_node_1), -// (delegation_id_2, delegation_node_2), -// ]) -// .with_children(vec![ -// (root_id, vec![delegation_id_1]), -// (delegation_id_1, vec![delegation_id_2]), -// ]) -// .build(None); - -// ext.execute_with(|| { -// assert_noop!( -// Delegation::is_delegating(&user_1, &delegation_id_2, max_parent_checks), -// delegation::Error::::MaxSearchDepthReached -// ); -// }); -// } +#[test] +fn parent_owner_revoke_delegation_successful() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); + let delegate_keypair = get_alice_ed25519(); + let delegate = get_ed25519_account(delegate_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + + let mut operation = generate_base_delegation_revocation_operation(delegation_id); + operation.max_parent_checks = 1u32; + operation.max_revocations = 1u32; + + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_ok!(Delegation::revoke_delegation( + get_origin(revoker.clone()), + operation.delegation_id, + operation.max_parent_checks, + operation.max_revocations + )); + }); + + let stored_parent_delegation = ext.execute_with(|| { + Delegation::delegation_nodes(&parent_id).expect("Parent delegation should be present on chain.") + }); + assert!(!stored_parent_delegation.details.revoked); + + let stored_child_delegation = ext.execute_with(|| { + Delegation::delegation_nodes(&delegation_id).expect("Child delegation should be present on chain.") + }); + assert!(stored_child_delegation.details.revoked); +} + +#[test] +fn delegation_not_found_revoke_delegation_error() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let delegation_id = get_delegation_id(false); + + let operation = generate_base_delegation_revocation_operation(delegation_id); + + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_noop!( + Delegation::revoke_delegation( + get_origin(revoker.clone()), + operation.delegation_id, + operation.max_parent_checks, + operation.max_revocations + ), + delegation::Error::::DelegationNotFound + ); + }); +} + +#[test] +fn not_delegating_revoke_delegation_error() { + let owner_keypair = get_alice_ed25519(); + let owner = get_ed25519_account(owner_keypair.public()); + let revoker_keypair = get_bob_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, owner.clone(), Some(hierarchy_root_id))); + + let mut operation = generate_base_delegation_revocation_operation(delegation_id); + operation.max_parent_checks = MaxParentChecks::get(); + + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, owner.clone())]) + .with_delegations(vec![(delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_noop!( + Delegation::revoke_delegation( + get_origin(revoker.clone()), + operation.delegation_id, + operation.max_parent_checks, + operation.max_revocations + ), + delegation::Error::::UnauthorizedRevocation + ); + }); +} + +#[test] +fn parent_too_far_revoke_delegation_error() { + let owner_keypair = get_alice_ed25519(); + let owner = get_ed25519_account(owner_keypair.public()); + let intermediate_keypair = get_charlie_ed25519(); + let intermediate = get_ed25519_account(intermediate_keypair.public()); + let delegate_keypair = get_bob_ed25519(); + let delegate = get_ed25519_account(delegate_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, intermediate.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + + let mut operation = generate_base_delegation_revocation_operation(delegation_id); + operation.max_parent_checks = 0u32; + + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, owner.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, owner.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_noop!( + Delegation::revoke_delegation( + get_origin(intermediate.clone()), + operation.delegation_id, + operation.max_parent_checks, + operation.max_revocations + ), + delegation::Error::::MaxSearchDepthReached + ); + }); +} + +#[test] +fn too_many_revocations_revoke_delegation_error() { + let revoker_keypair = get_alice_ed25519(); + let revoker = get_ed25519_account(revoker_keypair.public()); + let delegate_keypair = get_bob_ed25519(); + let delegate = get_ed25519_account(delegate_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + + let mut operation = generate_base_delegation_revocation_operation(delegation_id); + operation.max_parent_checks = 1u32; + + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_noop!( + Delegation::revoke_delegation( + get_origin(revoker.clone()), + operation.delegation_id, + operation.max_parent_checks, + operation.max_revocations + ), + delegation::Error::::ExceededRevocationBounds + ); + }); +} + +// Internal function: is_delegating() + +#[test] +fn is_delegating_direct_not_revoked() { + let user_1_keypair = get_alice_ed25519(); + let user_1 = get_ed25519_account(user_1_keypair.public()); + let user_2_keypair = get_bob_ed25519(); + let user_2 = get_ed25519_account(user_2_keypair.public()); + let user_3_keypair = get_charlie_ed25519(); + let user_3 = get_ed25519_account(user_3_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + + let max_parent_checks = 0u32; + + // Root -> Parent -> Delegation + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_eq!( + Delegation::is_delegating(&user_3, &delegation_id, max_parent_checks), + Ok((true, max_parent_checks)) + ); + }); +} + +#[test] +fn is_delegating_direct_not_revoked_max_parent_checks_value() { + let user_1_keypair = get_alice_ed25519(); + let user_1 = get_ed25519_account(user_1_keypair.public()); + let user_2_keypair = get_bob_ed25519(); + let user_2 = get_ed25519_account(user_2_keypair.public()); + let user_3_keypair = get_charlie_ed25519(); + let user_3 = get_ed25519_account(user_3_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + + let max_parent_checks = u32::MAX; + + // Root -> Parent -> Delegation + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_eq!( + Delegation::is_delegating(&user_3, &delegation_id, max_parent_checks), + Ok((true, 0u32)) + ); + }); +} + +#[test] +fn is_delegating_direct_revoked() { + let user_1_keypair = get_alice_ed25519(); + let user_1 = get_ed25519_account(user_1_keypair.public()); + let user_2_keypair = get_bob_ed25519(); + let user_2 = get_ed25519_account(user_2_keypair.public()); + let user_3_keypair = get_charlie_ed25519(); + let user_3 = get_ed25519_account(user_3_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (delegation_id, mut delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + delegation_node.details.revoked = true; + + let max_parent_checks = 0u32; + + // Root -> Parent -> Delegation + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_eq!( + Delegation::is_delegating(&user_3, &delegation_id, max_parent_checks), + Ok((false, 0)) + ); + }); +} + +#[test] +fn is_delegating_direct_revoked_max_parent_checks_value() { + let user_1_keypair = get_alice_ed25519(); + let user_1 = get_ed25519_account(user_1_keypair.public()); + let user_2_keypair = get_bob_ed25519(); + let user_2 = get_ed25519_account(user_2_keypair.public()); + let user_3_keypair = get_charlie_ed25519(); + let user_3 = get_ed25519_account(user_3_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (delegation_id, mut delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + delegation_node.details.revoked = true; + + let max_parent_checks = u32::MAX; + + // Root -> Parent -> Delegation + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_eq!( + Delegation::is_delegating(&user_3, &delegation_id, max_parent_checks), + Ok((false, 0)) + ); + }); +} + +#[test] +fn is_delegating_max_parent_not_revoked() { + let user_1_keypair = get_alice_ed25519(); + let user_1 = get_ed25519_account(user_1_keypair.public()); + let user_2_keypair = get_bob_ed25519(); + let user_2 = get_ed25519_account(user_2_keypair.public()); + let user_3_keypair = get_charlie_ed25519(); + let user_3 = get_ed25519_account(user_3_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + + let max_parent_checks = 1u32; + + // Root -> Parent -> Delegation + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_eq!( + Delegation::is_delegating(&user_2, &delegation_id, max_parent_checks), + Ok((true, max_parent_checks - 1)) + ); + }); +} + +#[test] +fn is_delegating_max_parent_revoked() { + let user_1_keypair = get_alice_ed25519(); + let user_1 = get_ed25519_account(user_1_keypair.public()); + let user_2_keypair = get_bob_ed25519(); + let user_2 = get_ed25519_account(user_2_keypair.public()); + let user_3_keypair = get_charlie_ed25519(); + let user_3 = get_ed25519_account(user_3_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, mut parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + parent_node.details.revoked = true; + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + + let max_parent_checks = 2u32; + + // Root -> Parent -> Delegation + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_eq!( + Delegation::is_delegating(&user_2, &delegation_id, max_parent_checks), + Ok((false, max_parent_checks - 2)) + ); + }); +} + +#[test] +fn is_delegating_root_owner_not_revoked() { + let user_1_keypair = get_alice_ed25519(); + let user_1 = get_ed25519_account(user_1_keypair.public()); + let user_2_keypair = get_bob_ed25519(); + let user_2 = get_ed25519_account(user_2_keypair.public()); + let user_3_keypair = get_charlie_ed25519(); + let user_3 = get_ed25519_account(user_3_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + + let max_parent_checks = 2u32; + + // Root -> Parent -> Delegation + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_eq!( + Delegation::is_delegating(&user_1, &delegation_id, max_parent_checks), + Ok((true, max_parent_checks - 2)) + ); + }); +} + +#[test] +fn is_delegating_root_owner_revoked() { + let user_1_keypair = get_alice_ed25519(); + let user_1 = get_ed25519_account(user_1_keypair.public()); + let user_2_keypair = get_bob_ed25519(); + let user_2 = get_ed25519_account(user_2_keypair.public()); + let user_3_keypair = get_charlie_ed25519(); + let user_3 = get_ed25519_account(user_3_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + + let max_parent_checks = 2u32; + + // Root -> Parent -> Delegation + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + // First revoke the hierarchy, then test is_delegating. + let _ = Delegation::revoke_hierarchy(get_origin(user_1.clone()), hierarchy_root_id, 2); + assert_eq!( + Delegation::is_delegating(&user_1, &delegation_id, max_parent_checks), + Ok((false, 0u32)) + ); + }); +} + +#[test] +fn is_delegating_delegation_not_found() { + let user_1_keypair = get_alice_ed25519(); + let user_1 = get_ed25519_account(user_1_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let delegation_id = get_delegation_id(true); + + let max_parent_checks = 2u32; + + // Root -> Delegation 1 + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .build(None); + + ext.execute_with(|| { + assert_noop!( + Delegation::is_delegating(&user_1, &delegation_id, max_parent_checks), + delegation::Error::::DelegationNotFound + ); + }); +} + +#[test] +fn is_delegating_root_after_max_limit() { + let user_1_keypair = get_alice_ed25519(); + let user_1 = get_ed25519_account(user_1_keypair.public()); + let user_2_keypair = get_bob_ed25519(); + let user_2 = get_ed25519_account(user_2_keypair.public()); + let user_3_keypair = get_charlie_ed25519(); + let user_3 = get_ed25519_account(user_3_keypair.public()); + + let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + + // 1 less than needed + let max_parent_checks = 1u32; + + // Root -> Parent -> Delegation + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + assert_noop!( + Delegation::is_delegating(&user_1, &delegation_id, max_parent_checks), + delegation::Error::::MaxSearchDepthReached + ); + }); +} From 5c8dc904fc7a629206381668088164b87dc7bcbb Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 13 Jul 2021 11:01:55 +0200 Subject: [PATCH 06/49] benchmark tests passing --- pallets/delegation/src/benchmarking.rs | 124 +++++++++++-------------- pallets/delegation/src/lib.rs | 74 ++++++++------- 2 files changed, 94 insertions(+), 104 deletions(-) diff --git a/pallets/delegation/src/benchmarking.rs b/pallets/delegation/src/benchmarking.rs index 72fc175363..9bd9a73849 100644 --- a/pallets/delegation/src/benchmarking.rs +++ b/pallets/delegation/src/benchmarking.rs @@ -23,7 +23,7 @@ use frame_system::RawOrigin; use sp_core::{offchain::KeyTypeId, sr25519}; use sp_io::crypto::sr25519_generate; use sp_runtime::MultiSignature; -use sp_std::{num::NonZeroU32, vec::Vec}; +use sp_std::{collections::btree_set::BTreeSet, num::NonZeroU32, vec::Vec}; use crate::*; @@ -45,20 +45,8 @@ where hash.into() } -/// sets parent to `None` if it is the root -fn parent_id_check( - root_id: T::DelegationNodeId, - parent_id: T::DelegationNodeId, -) -> Option { - if parent_id == root_id { - None - } else { - Some(parent_id) - } -} - /// add ctype to storage and root delegation -fn add_root_delegation(number: u32) -> Result<(DelegationTriplet, T::Hash), DispatchErrorWithPostInfo> +fn add_delegation_hierarchy(number: u32) -> Result<(DelegationTriplet, T::Hash), DispatchErrorWithPostInfo> where T::AccountId: From, T::DelegationNodeId: From, @@ -66,16 +54,16 @@ where let root_public = sr25519_generate(KeyTypeId(*b"aura"), None); let root_acc: T::AccountId = root_public.into(); let ctype_hash = ::default(); - let root_id = generate_delegation_id::(number); + let hierarchy_root_id = generate_delegation_id::(number); ctype::Pallet::::add(RawOrigin::Signed(root_acc.clone()).into(), ctype_hash)?; - Pallet::::create_root(RawOrigin::Signed(root_acc.clone()).into(), root_id, ctype_hash)?; + Pallet::::create_hierarchy(RawOrigin::Signed(root_acc.clone()).into(), hierarchy_root_id, ctype_hash)?; Ok(( DelegationTriplet:: { public: root_public, acc: root_acc, - delegation_id: root_id, + delegation_id: hierarchy_root_id, }, ctype_hash, )) @@ -107,11 +95,8 @@ where let delegation_acc_id: T::AccountId = delegation_acc_public.into(); let delegation_id = generate_delegation_id::(level * children_per_level.get() + c); - // only set parent if not root - let parent = parent_id_check::(root_id, parent_id); - // delegate signs delegation to parent - let hash: Vec = Pallet::::calculate_hash(&delegation_id, &root_id, &parent, &permissions).encode(); + let hash: Vec = Pallet::::calculate_delegation_hash_root(&delegation_id, &root_id, &parent_id, &permissions).encode(); let sig = sp_io::crypto::sr25519_sign(KeyTypeId(*b"aura"), &delegation_acc_public, hash.as_ref()) .ok_or("Error while building signature of delegation.")?; @@ -120,7 +105,7 @@ where RawOrigin::Signed(parent_acc_id.clone()).into(), delegation_id, root_id, - parent, + parent_id, delegation_acc_id.clone().into(), permissions, MultiSignature::from(sig).encode(), @@ -169,58 +154,58 @@ where DelegationTriplet:: { public: root_public, acc: root_acc, - delegation_id: root_id, + delegation_id: hierarchy_id, }, _, - ) = add_root_delegation::(0)?; + ) = add_delegation_hierarchy::(0)?; // iterate levels and start with parent == root let (leaf_acc_public, _, leaf_id) = add_children::( - root_id, - root_id, + hierarchy_id, + hierarchy_id, root_public, root_acc, permissions, levels, children_per_level, )?; - Ok((root_public, root_id, leaf_acc_public, leaf_id)) + Ok((root_public, hierarchy_id, leaf_acc_public, leaf_id)) } benchmarks! { where_clause { where T: core::fmt::Debug, T::AccountId: From + Into, T::DelegationNodeId: From, ::Origin: From::DelegationEntityId>> } - create_root { + create_hierarchy { let caller: T::AccountId = account("caller", 0, SEED); let ctype = ::default(); let delegation = generate_delegation_id::(0); ctype::Pallet::::add(RawOrigin::Signed(caller.clone()).into(), ctype)?; }: _(RawOrigin::Signed(caller), delegation, ctype) verify { - assert!(Roots::::contains_key(delegation)); + assert!(DelegationHierarchies::::contains_key(delegation)); } - revoke_root { + revoke_hierarchy { let r in 1 .. T::MaxRevocations::get(); - let (root_acc, root_id, leaf_acc, leaf_id) = setup_delegations::(r, ONE_CHILD_PER_LEVEL.expect(">0"), Permissions::DELEGATE)?; + let (root_acc, hierarchy_id, leaf_acc, leaf_id) = setup_delegations::(r, ONE_CHILD_PER_LEVEL.expect(">0"), Permissions::DELEGATE)?; let root_acc_id: T::AccountId = root_acc.into(); - }: _(RawOrigin::Signed(root_acc_id.clone()), root_id, r) + }: _(RawOrigin::Signed(root_acc_id.clone()), hierarchy_id, r) verify { - assert!(Roots::::contains_key(root_id)); - let root_delegation = Roots::::get(root_id).ok_or("Missing root delegation")?; - assert_eq!(root_delegation.owner, root_acc_id.into()); - assert!(root_delegation.revoked); - - assert!(Delegations::::contains_key(leaf_id)); - let leaf_delegation = Delegations::::get(leaf_id).ok_or("Missing leaf delegation")?; - assert_eq!(leaf_delegation.root_id, root_id); - assert_eq!(leaf_delegation.owner, T::AccountId::from(leaf_acc).into()); - assert!(leaf_delegation.revoked); + assert!(DelegationHierarchies::::contains_key(hierarchy_id)); + let root_delegation = DelegationNodes::::get(hierarchy_id).ok_or("Missing root delegation")?; + assert_eq!(root_delegation.details.owner, root_acc_id.into()); + assert!(root_delegation.details.revoked); + + assert!(DelegationNodes::::contains_key(leaf_id)); + let leaf_delegation = DelegationNodes::::get(leaf_id).ok_or("Missing leaf delegation")?; + assert_eq!(leaf_delegation.hierarchy_root_id, hierarchy_id); + assert_eq!(leaf_delegation.details.owner, T::AccountId::from(leaf_acc).into()); + assert!(leaf_delegation.details.revoked); } add_delegation { // do setup - let (_, root_id, leaf_acc, leaf_id) = setup_delegations::(1, ONE_CHILD_PER_LEVEL.expect(">0"), Permissions::DELEGATE)?; + let (_, hierarchy_id, leaf_acc, leaf_id) = setup_delegations::(1, ONE_CHILD_PER_LEVEL.expect(">0"), Permissions::DELEGATE)?; // add one more delegation let delegate_acc_public = sr25519_generate( @@ -228,17 +213,17 @@ benchmarks! { None ); let delegation_id = generate_delegation_id::(u32::MAX); - let parent_id = parent_id_check::(root_id, leaf_id); + let parent_id = leaf_id; let perm: Permissions = Permissions::ATTEST | Permissions::DELEGATE; - let hash_root = Pallet::::calculate_hash(&delegation_id, &root_id, &parent_id, &perm); + let hash_root = Pallet::::calculate_delegation_hash_root(&delegation_id, &hierarchy_id, &parent_id, &perm); let sig = sp_io::crypto::sr25519_sign(KeyTypeId(*b"aura"), &delegate_acc_public, hash_root.as_ref()).ok_or("Error while building signature of delegation.")?; let delegate_acc_id: T::AccountId = delegate_acc_public.into(); let leaf_acc_id: T::AccountId = leaf_acc.into(); - }: _(RawOrigin::Signed(leaf_acc_id), delegation_id, root_id, parent_id, delegate_acc_id.into(), perm, MultiSignature::from(sig).encode()) + }: _(RawOrigin::Signed(leaf_acc_id), delegation_id, hierarchy_id, parent_id, delegate_acc_id.into(), perm, MultiSignature::from(sig).encode()) verify { - assert!(Delegations::::contains_key(delegation_id)); + assert!(DelegationNodes::::contains_key(delegation_id)); } // worst case #1: revoke a child of the root delegation @@ -247,21 +232,22 @@ benchmarks! { revoke_delegation_root_child { let r in 1 .. T::MaxRevocations::get(); let c in 1 .. T::MaxParentChecks::get(); - let (_, root_id, leaf_acc, leaf_id) = setup_delegations::(r, ONE_CHILD_PER_LEVEL.expect(">0"), Permissions::DELEGATE)?; - let children: Vec = Children::::get(root_id).unwrap_or_default(); - let child_id: T::DelegationNodeId = *children.get(0).ok_or("Root should have children")?; - let child_delegation = Delegations::::get(child_id).ok_or("Child of root should have delegation id")?; - }: revoke_delegation(RawOrigin::Signed(child_delegation.owner.clone()), child_id, c, r) + let (_, hierarchy_id, leaf_acc, leaf_id) = setup_delegations::(r, ONE_CHILD_PER_LEVEL.expect(">0"), Permissions::DELEGATE)?; + let root_node = DelegationNodes::::get(hierarchy_id).expect("Root hierarchy node should be present on chain."); + let mut children: BTreeSet = root_node.children; + let child_id: T::DelegationNodeId = *children.iter().next().ok_or("Root should have children")?; + let child_delegation = DelegationNodes::::get(child_id).ok_or("Child of root should have delegation id")?; + }: revoke_delegation(RawOrigin::Signed(child_delegation.details.owner.clone()), child_id, c, r) verify { - assert!(Delegations::::contains_key(child_id)); - let DelegationNode:: { revoked, .. } = Delegations::::get(leaf_id).ok_or("Child of root should have delegation id")?; - assert!(revoked); - - assert!(Delegations::::contains_key(leaf_id)); - let leaf_delegation = Delegations::::get(leaf_id).ok_or("Missing leaf delegation")?; - assert_eq!(leaf_delegation.root_id, root_id); - assert_eq!(leaf_delegation.owner, T::AccountId::from(leaf_acc).into()); - assert!(leaf_delegation.revoked); + assert!(DelegationNodes::::contains_key(child_id)); + let DelegationNode:: { details, .. } = DelegationNodes::::get(leaf_id).ok_or("Child of root should have delegation id")?; + assert!(details.revoked); + + assert!(DelegationNodes::::contains_key(leaf_id)); + let leaf_delegation = DelegationNodes::::get(leaf_id).ok_or("Missing leaf delegation")?; + assert_eq!(leaf_delegation.hierarchy_root_id, hierarchy_id); + assert_eq!(leaf_delegation.details.owner, T::AccountId::from(leaf_acc).into()); + assert!(leaf_delegation.details.revoked); } // TODO: Might want to add variant iterating over children instead of depth at some later point @@ -274,15 +260,15 @@ benchmarks! { let (root_acc, _, _, leaf_id) = setup_delegations::(c, ONE_CHILD_PER_LEVEL.expect(">0"), Permissions::DELEGATE)?; }: revoke_delegation(RawOrigin::Signed(T::AccountId::from(root_acc).into()), leaf_id, c, r) verify { - assert!(Delegations::::contains_key(leaf_id)); - let DelegationNode:: { revoked, .. } = Delegations::::get(leaf_id).ok_or("Child of root should have delegation id")?; - assert!(revoked); + assert!(DelegationNodes::::contains_key(leaf_id)); + let DelegationNode:: { details, .. } = DelegationNodes::::get(leaf_id).ok_or("Child of root should have delegation id")?; + assert!(details.revoked); } // TODO: Might want to add variant iterating over children instead of depth at some later point } -// impl_benchmark_test_suite! { -// Pallet, -// crate::mock::ExtBuilder::default().build_with_keystore(None), -// crate::mock::Test -// } +impl_benchmark_test_suite! { + Pallet, + crate::mock::ExtBuilder::default().build_with_keystore(None), + crate::mock::Test +} diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 6e9dfe54e8..2000770d97 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -177,7 +177,8 @@ pub mod pallet { /// * origin: the identifier of the delegation creator /// * root_id: the ID of the root node. It has to be unique /// * ctype_hash: the CTYPE hash that delegates can use for attestations - #[pallet::weight(::WeightInfo::create_root())] + // #[pallet::weight(::WeightInfo::create_root())] + #[pallet::weight(0)] pub fn create_hierarchy( origin: OriginFor, root_node_id: DelegationNodeIdOf, @@ -218,7 +219,8 @@ pub mod pallet { /// is allowed to perform /// * delegate_signature: the delegate's signature over the new /// delegation ID, root ID, parent ID, and permission flags - #[pallet::weight(::WeightInfo::add_delegation())] + // #[pallet::weight(::WeightInfo::add_delegation())] + #[pallet::weight(0)] pub fn add_delegation( origin: OriginFor, delegation_id: DelegationNodeIdOf, @@ -282,7 +284,8 @@ pub mod pallet { /// * root_id: the ID of the delegation root to revoke /// * max_children: the maximum number of nodes descending from the root /// to revoke as a consequence of the root revocation - #[pallet::weight(::WeightInfo::revoke_root(*max_children))] + // #[pallet::weight(::WeightInfo::revoke_root(*max_children))] + #[pallet::weight(0)] pub fn revoke_hierarchy( origin: OriginFor, root_node_id: DelegationNodeIdOf, @@ -301,7 +304,7 @@ pub mod pallet { let consumed_weight: Weight = if !hierarchy_root_node.details.revoked { // Recursively revoke all children - let (_, post_weight) = Self::revoke_children(&root_node_id.into(), &invoker, max_children)?; + let (_, post_weight) = Self::revoke_children(&root_node_id, &invoker, max_children)?; // If we didn't return an ExceededRevocationBounds error, we can revoke the root // too. @@ -338,9 +341,10 @@ pub mod pallet { /// max number of parents is reached /// * max_revocations: the maximum number of nodes descending from this /// one to revoke as a consequence of this node revocation - #[pallet::weight( - ::WeightInfo::revoke_delegation_root_child(*max_revocations, *max_parent_checks) - .max(::WeightInfo::revoke_delegation_leaf(*max_revocations, *max_parent_checks)))] + // #[pallet::weight( + // ::WeightInfo::revoke_delegation_root_child(*max_revocations, *max_parent_checks) + // .max(::WeightInfo::revoke_delegation_leaf(*max_revocations, *max_parent_checks)))] + #[pallet::weight(0)] pub fn revoke_delegation( origin: OriginFor, delegation_id: DelegationNodeIdOf, @@ -458,6 +462,34 @@ impl Pallet { } } + /// Revokes all children of a delegation. + /// Returns the number of revoked delegations and the consumed weight. + fn revoke_children( + delegation: &DelegationNodeIdOf, + sender: &DelegatorIdOf, + max_revocations: u32, + ) -> Result<(u32, Weight), DispatchError> { + let mut revocations: u32 = 0; + let mut consumed_weight: Weight = 0; + if let Some(delegation_node) = >::get(delegation) { + // Iterate children and revoke all nodes + for child in delegation_node.children.iter() { + let remaining_revocations = max_revocations + .checked_sub(revocations) + .ok_or(Error::::ExceededRevocationBounds)?; + + // Check whether we ran out of gas + ensure!(remaining_revocations > 0, Error::::ExceededRevocationBounds); + + Self::revoke(&child, sender, remaining_revocations).map(|(r, w)| { + revocations = revocations.saturating_add(r); + consumed_weight = consumed_weight.saturating_add(w); + })?; + } + } + Ok((revocations, consumed_weight.saturating_add(T::DbWeight::get().reads(1)))) + } + // Revoke a delegation and all of its children recursively. fn revoke( delegation: &DelegationNodeIdOf, @@ -495,32 +527,4 @@ impl Pallet { } Ok((revocations, consumed_weight)) } - - /// Revokes all children of a delegation. - /// Returns the number of revoked delegations and the consumed weight. - fn revoke_children( - delegation: &DelegationNodeIdOf, - sender: &DelegatorIdOf, - max_revocations: u32, - ) -> Result<(u32, Weight), DispatchError> { - let mut revocations: u32 = 0; - let mut consumed_weight: Weight = 0; - if let Some(delegation_node) = >::get(delegation) { - // Iterate children and revoke all nodes - for child in delegation_node.children.iter() { - let remaining_revocations = max_revocations - .checked_sub(revocations) - .ok_or(Error::::ExceededRevocationBounds)?; - - // Check whether we ran out of gas - ensure!(remaining_revocations > 0, Error::::ExceededRevocationBounds); - - Self::revoke(&child, sender, remaining_revocations).map(|(r, w)| { - revocations = revocations.saturating_add(r); - consumed_weight = consumed_weight.saturating_add(w); - })?; - } - } - Ok((revocations, consumed_weight.saturating_add(T::DbWeight::get().reads(1)))) - } } From 080bb41daffe04cb05aa4083a960cc3e624748fb Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 13 Jul 2021 11:19:26 +0200 Subject: [PATCH 07/49] test: attestation unit tests passing --- pallets/attestation/src/lib.rs | 10 +- pallets/attestation/src/tests.rs | 213 ++++++++++++++----------------- 2 files changed, 103 insertions(+), 120 deletions(-) diff --git a/pallets/attestation/src/lib.rs b/pallets/attestation/src/lib.rs index 872ecf704b..9aabeeb916 100644 --- a/pallets/attestation/src/lib.rs +++ b/pallets/attestation/src/lib.rs @@ -162,21 +162,21 @@ pub mod pallet { // Check for validity of the delegation node if specified. if let Some(delegation_id) = delegation_id { - let delegation = >::get(delegation_id) + let delegation = >::get(delegation_id) .ok_or(delegation::Error::::DelegationNotFound)?; - ensure!(!delegation.revoked, Error::::DelegationRevoked); + ensure!(!delegation.details.revoked, Error::::DelegationRevoked); - ensure!(delegation.owner == attester, Error::::NotDelegatedToAttester); + ensure!(delegation.details.owner == attester, Error::::NotDelegatedToAttester); ensure!( - (delegation.permissions & delegation::Permissions::ATTEST) == delegation::Permissions::ATTEST, + (delegation.details.permissions & delegation::Permissions::ATTEST) == delegation::Permissions::ATTEST, Error::::DelegationUnauthorizedToAttest ); // Check if the CTYPE of the delegation is matching the CTYPE of the attestation let root = - >::get(delegation.root_id).ok_or(delegation::Error::::RootNotFound)?; + >::get(delegation.hierarchy_root_id).ok_or(delegation::Error::::HierarchyNotFound)?; ensure!(root.ctype_hash == ctype_hash, Error::::CTypeMismatch); // If the attestation is based on a delegation, store separately diff --git a/pallets/attestation/src/tests.rs b/pallets/attestation/src/tests.rs index 9d84703145..d22f5bf2d2 100644 --- a/pallets/attestation/src/tests.rs +++ b/pallets/attestation/src/tests.rs @@ -61,15 +61,16 @@ fn attest_with_delegation_successful() { let attester_keypair = get_alice_ed25519(); let attester = get_ed25519_account(attester_keypair.public()); let claim_hash = get_claim_hash(true); - let (root_id, root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(attester.clone()), + + let (hierarchy_root_id, hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, attester.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(hierarchy_root_id)), ); - delegation_node.permissions = delegation::Permissions::ATTEST; + delegation_node.details.permissions = delegation::Permissions::ATTEST; let mut attestation = generate_base_attestation(attester.clone()); attestation.delegation_id = Some(delegation_id); @@ -79,9 +80,8 @@ fn attest_with_delegation_successful() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![delegation_id])]) + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) + .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -196,16 +196,16 @@ fn delegation_revoked_attest_error() { let attester_keypair = get_alice_ed25519(); let attester = get_ed25519_account(attester_keypair.public()); let claim_hash = get_claim_hash(true); - let (root_id, root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(attester.clone()), + let (hierarchy_root_id, hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, attester.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(hierarchy_root_id)) ); - delegation_node.permissions = delegation::Permissions::ATTEST; - delegation_node.revoked = true; + delegation_node.details.permissions = delegation::Permissions::ATTEST; + delegation_node.details.revoked = true; let mut attestation = generate_base_attestation(attester.clone()); attestation.delegation_id = Some(delegation_id); @@ -215,9 +215,8 @@ fn delegation_revoked_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![delegation_id])]) + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) + .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -240,15 +239,15 @@ fn not_delegation_owner_attest_error() { let alternative_owner_keypair = get_bob_ed25519(); let alternative_owner = get_ed25519_account(alternative_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (root_id, root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(alternative_owner.clone()), + let (hierarchy_root_id, hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, alternative_owner), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, alternative_owner.clone(), Some(hierarchy_root_id)) ); - delegation_node.permissions = delegation::Permissions::ATTEST; + delegation_node.details.permissions = delegation::Permissions::ATTEST; let mut attestation = generate_base_attestation(attester.clone()); attestation.delegation_id = Some(delegation_id); @@ -258,9 +257,8 @@ fn not_delegation_owner_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![delegation_id])]) + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) + .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -281,13 +279,14 @@ fn unauthorised_permissions_attest_error() { let attester_keypair = get_alice_ed25519(); let attester = get_ed25519_account(attester_keypair.public()); let claim_hash = get_claim_hash(true); - let (root_id, root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(attester.clone()), + let (hierarchy_root_id, hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); + // Delegation node does not have permissions to attest. let (delegation_id, delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, attester.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(hierarchy_root_id)) ); let mut attestation = generate_base_attestation(attester.clone()); attestation.delegation_id = Some(delegation_id); @@ -298,9 +297,8 @@ fn unauthorised_permissions_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![delegation_id])]) + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) + .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -321,16 +319,16 @@ fn root_not_present_attest_error() { let attester_keypair = get_alice_ed25519(); let attester = get_ed25519_account(attester_keypair.public()); let claim_hash = get_claim_hash(true); - let (root_id, root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(attester.clone()), + let (hierarchy_root_id, hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); - let alternative_root_id = delegation_mock::get_delegation_root_id(false); + let alternative_hierarchy_root_id = delegation_mock::get_delegation_hierarchy_id(false); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, attester.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(alternative_hierarchy_root_id)) ); - delegation_node.permissions = delegation::Permissions::ATTEST; + delegation_node.details.permissions = delegation::Permissions::ATTEST; let mut attestation = generate_base_attestation(attester.clone()); attestation.delegation_id = Some(delegation_id); @@ -340,9 +338,8 @@ fn root_not_present_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(alternative_root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![(alternative_root_id, vec![delegation_id])]) + .with_delegation_hierarchies(vec![(alternative_hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) + .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -353,7 +350,7 @@ fn root_not_present_attest_error() { operation.ctype_hash, operation.delegation_id ), - delegation::Error::::RootNotFound + delegation::Error::::HierarchyNotFound ); }); } @@ -364,16 +361,16 @@ fn root_ctype_mismatch_attest_error() { let attester = get_ed25519_account(attester_keypair.public()); let claim_hash = get_claim_hash(true); let alternative_ctype_hash = ctype_mock::get_ctype_hash(false); - let (root_id, mut root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(attester.clone()), + let (hierarchy_root_id, mut hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); - root_node.ctype_hash = alternative_ctype_hash; + hierarchy_info.ctype_hash = alternative_ctype_hash; let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, attester.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(hierarchy_root_id)) ); - delegation_node.permissions = delegation::Permissions::ATTEST; + delegation_node.details.permissions = delegation::Permissions::ATTEST; let mut attestation = generate_base_attestation(attester.clone()); attestation.delegation_id = Some(delegation_id); @@ -383,9 +380,8 @@ fn root_ctype_mismatch_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![delegation_id])]) + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) + .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -442,15 +438,15 @@ fn revoke_with_delegation_successful() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (root_id, root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), + let (hierarchy_root_id, hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, revoker.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) ); - delegation_node.permissions = delegation::Permissions::ATTEST; + delegation_node.details.permissions = delegation::Permissions::ATTEST; // Attestation owned by a different user, but delegation owned by the user // submitting the operation. let mut attestation = generate_base_attestation(attestation_owner); @@ -463,10 +459,9 @@ fn revoke_with_delegation_successful() { let ext = ctype_mock::ExtBuilder::default() .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); - let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![delegation_id])]) + let mut ext = delegation_mock::ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) + .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) @@ -495,18 +490,18 @@ fn revoke_with_parent_delegation_successful() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (root_id, root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), + let (hierarchy_root_id, hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, revoker.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) ); - parent_node.permissions = delegation::Permissions::ATTEST; + parent_node.details.permissions = delegation::Permissions::ATTEST; let (delegation_id, delegation_node) = ( delegation_mock::get_delegation_id(false), - delegation_mock::generate_base_delegation_node(root_id, attestation_owner.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)) ); let mut attestation = generate_base_attestation(attestation_owner); attestation.delegation_id = Some(delegation_id); @@ -520,9 +515,8 @@ fn revoke_with_parent_delegation_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(root_id, root_node)]) - .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![parent_id]), (parent_id, vec![delegation_id])]) + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) + .with_delegations(vec![(parent_id.clone(), parent_node.clone()), (delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) @@ -550,18 +544,18 @@ fn revoke_parent_delegation_no_attestation_permissions_successful() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (root_id, root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), + let (hierarchy_root_id, hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, revoker.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) ); - parent_node.permissions = delegation::Permissions::DELEGATE; + parent_node.details.permissions = delegation::Permissions::ATTEST; let (delegation_id, delegation_node) = ( delegation_mock::get_delegation_id(false), - delegation_mock::generate_base_delegation_node(root_id, attestation_owner.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)) ); let mut attestation = generate_base_attestation(attestation_owner); attestation.delegation_id = Some(delegation_id); @@ -575,9 +569,8 @@ fn revoke_parent_delegation_no_attestation_permissions_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(root_id, root_node)]) - .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![parent_id]), (parent_id, vec![delegation_id])]) + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) + .with_delegations(vec![(parent_id.clone(), parent_node.clone()), (delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) @@ -605,20 +598,20 @@ fn revoke_parent_delegation_with_direct_delegation_revoked_successful() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (root_id, root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), + let (hierarchy_root_id, hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, revoker.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) ); - parent_node.permissions = delegation::Permissions::ATTEST; + parent_node.details.permissions = delegation::Permissions::ATTEST; let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(false), - delegation_mock::generate_base_delegation_node(root_id, attestation_owner.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)) ); - delegation_node.revoked = true; + delegation_node.details.revoked = true; let mut attestation = generate_base_attestation(attestation_owner); attestation.delegation_id = Some(delegation_id); @@ -631,9 +624,8 @@ fn revoke_parent_delegation_with_direct_delegation_revoked_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(root_id, root_node)]) - .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![parent_id]), (parent_id, vec![delegation_id])]) + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) + .with_delegations(vec![(parent_id.clone(), parent_node.clone()), (delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) @@ -752,20 +744,19 @@ fn max_parent_lookups_revoke_error() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (root_id, root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), + let (hierarchy_root_id, hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); - let (parent_delegation_id, parent_delegation_node) = ( + let (parent_id, parent_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, revoker.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) ); let (delegation_id, mut delegation_node) = ( - delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, attestation_owner.clone()), + delegation_mock::get_delegation_id(false), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)) ); - delegation_node.permissions = delegation::Permissions::ATTEST; - delegation_node.parent = Some(parent_delegation_id); + delegation_node.details.permissions = delegation::Permissions::ATTEST; let mut attestation = generate_base_attestation(attestation_owner); attestation.delegation_id = Some(delegation_id); @@ -776,15 +767,8 @@ fn max_parent_lookups_revoke_error() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(root_id, root_node)]) - .with_delegations(vec![ - (parent_delegation_id, parent_delegation_node), - (delegation_id, delegation_node), - ]) - .with_children(vec![ - (root_id, vec![parent_delegation_id]), - (parent_delegation_id, vec![delegation_id]), - ]) + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) + .with_delegations(vec![(parent_id.clone(), parent_node.clone()), (delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) @@ -810,16 +794,16 @@ fn revoked_delegation_revoke_error() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (root_id, root_node) = ( - delegation_mock::get_delegation_root_id(true), - delegation_mock::generate_base_delegation_hierarchy(revoker.clone()), + let (hierarchy_root_id, hierarchy_info) = ( + delegation_mock::get_delegation_hierarchy_id(true), + delegation_mock::generate_base_delegation_hierarchy_info(), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(root_id, revoker.clone()), + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) ); - delegation_node.permissions = delegation::Permissions::ATTEST; - delegation_node.revoked = true; + delegation_node.details.permissions = delegation::Permissions::ATTEST; + delegation_node.details.revoked = true; let mut attestation = generate_base_attestation(attestation_owner); attestation.delegation_id = Some(delegation_id); @@ -829,9 +813,8 @@ fn revoked_delegation_revoke_error() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(root_id, root_node)]) - .with_delegations(vec![(delegation_id, delegation_node)]) - .with_children(vec![(root_id, vec![delegation_id])]) + .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) + .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) From 626c23b606c699204ab3c80ade32741334d62d2a Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 13 Jul 2021 11:24:20 +0200 Subject: [PATCH 08/49] chore: clippy fixes --- pallets/attestation/src/tests.rs | 52 +++++++-------- pallets/delegation/src/benchmarking.rs | 2 +- pallets/delegation/src/lib.rs | 6 +- pallets/delegation/src/tests.rs | 92 +++++++++++++------------- 4 files changed, 76 insertions(+), 76 deletions(-) diff --git a/pallets/attestation/src/tests.rs b/pallets/attestation/src/tests.rs index d22f5bf2d2..21bfe04314 100644 --- a/pallets/attestation/src/tests.rs +++ b/pallets/attestation/src/tests.rs @@ -80,8 +80,8 @@ fn attest_with_delegation_successful() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) - .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); ext.execute_with(|| { @@ -215,8 +215,8 @@ fn delegation_revoked_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) - .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); ext.execute_with(|| { @@ -245,7 +245,7 @@ fn not_delegation_owner_attest_error() { ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, alternative_owner.clone(), Some(hierarchy_root_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, alternative_owner, Some(hierarchy_root_id)) ); delegation_node.details.permissions = delegation::Permissions::ATTEST; let mut attestation = generate_base_attestation(attester.clone()); @@ -257,8 +257,8 @@ fn not_delegation_owner_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) - .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); ext.execute_with(|| { @@ -297,8 +297,8 @@ fn unauthorised_permissions_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) - .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); ext.execute_with(|| { @@ -338,8 +338,8 @@ fn root_not_present_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(alternative_hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) - .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) + .with_delegation_hierarchies(vec![(alternative_hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); ext.execute_with(|| { @@ -380,8 +380,8 @@ fn root_ctype_mismatch_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), attester.clone())]) - .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); ext.execute_with(|| { @@ -459,9 +459,9 @@ fn revoke_with_delegation_successful() { let ext = ctype_mock::ExtBuilder::default() .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); - let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) - .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) + let ext = delegation_mock::ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) @@ -515,8 +515,8 @@ fn revoke_with_parent_delegation_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) - .with_delegations(vec![(parent_id.clone(), parent_node.clone()), (delegation_id.clone(), delegation_node.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) @@ -569,8 +569,8 @@ fn revoke_parent_delegation_no_attestation_permissions_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) - .with_delegations(vec![(parent_id.clone(), parent_node.clone()), (delegation_id.clone(), delegation_node.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) @@ -624,8 +624,8 @@ fn revoke_parent_delegation_with_direct_delegation_revoked_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) - .with_delegations(vec![(parent_id.clone(), parent_node.clone()), (delegation_id.clone(), delegation_node.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) @@ -767,8 +767,8 @@ fn max_parent_lookups_revoke_error() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) - .with_delegations(vec![(parent_id.clone(), parent_node.clone()), (delegation_id.clone(), delegation_node.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) @@ -813,8 +813,8 @@ fn revoked_delegation_revoke_error() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), revoker.clone())]) - .with_delegations(vec![(delegation_id.clone(), delegation_node.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() .with_attestations(vec![(operation.claim_hash, attestation)]) diff --git a/pallets/delegation/src/benchmarking.rs b/pallets/delegation/src/benchmarking.rs index 9bd9a73849..bdd6399772 100644 --- a/pallets/delegation/src/benchmarking.rs +++ b/pallets/delegation/src/benchmarking.rs @@ -234,7 +234,7 @@ benchmarks! { let c in 1 .. T::MaxParentChecks::get(); let (_, hierarchy_id, leaf_acc, leaf_id) = setup_delegations::(r, ONE_CHILD_PER_LEVEL.expect(">0"), Permissions::DELEGATE)?; let root_node = DelegationNodes::::get(hierarchy_id).expect("Root hierarchy node should be present on chain."); - let mut children: BTreeSet = root_node.children; + let children: BTreeSet = root_node.children; let child_id: T::DelegationNodeId = *children.iter().next().ok_or("Root should have children")?; let child_delegation = DelegationNodes::::get(child_id).ok_or("Child of root should have delegation id")?; }: revoke_delegation(RawOrigin::Signed(child_delegation.details.owner.clone()), child_id, c, r) diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 2000770d97..e1c61a08d4 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -454,10 +454,10 @@ impl Pallet { if let Some(parent) = delegation_node.parent { // Recursively check upwards in hierarchy - return Self::is_delegating(identity, &parent, remaining_lookups); + Self::is_delegating(identity, &parent, remaining_lookups) } else { // Safe because remaining lookups is at most max_parent_checks - return Ok((false, max_parent_checks - remaining_lookups)); + Ok((false, max_parent_checks - remaining_lookups)) } } } @@ -481,7 +481,7 @@ impl Pallet { // Check whether we ran out of gas ensure!(remaining_revocations > 0, Error::::ExceededRevocationBounds); - Self::revoke(&child, sender, remaining_revocations).map(|(r, w)| { + Self::revoke(child, sender, remaining_revocations).map(|(r, w)| { revocations = revocations.saturating_add(r); consumed_weight = consumed_weight.saturating_add(w); })?; diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index f5eb61a428..da41760498 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -35,7 +35,7 @@ fn create_root_delegation_successful() { let operation = generate_base_delegation_hierarchy_creation_operation(hierarchy_root_id); let mut ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(operation.ctype_hash.clone(), creator.clone())]) + .with_ctypes(vec![(operation.ctype_hash, creator.clone())]) .build(None); ext.execute_with(|| { @@ -68,10 +68,10 @@ fn duplicate_create_root_delegation_error() { let operation = generate_base_delegation_hierarchy_creation_operation(hierarchy_root_id); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(operation.ctype_hash.clone(), creator.clone())]) + .with_ctypes(vec![(operation.ctype_hash, creator.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), creator.clone())]).build(Some(ext)); + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]).build(Some(ext)); ext.execute_with(|| { assert_noop!(Delegation::create_hierarchy( @@ -114,7 +114,7 @@ fn create_delegation_direct_root_successful() { let delegate = get_sr25519_account(delegate_keypair.public()); let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate, Some(hierarchy_root_id))); let delegation_info = Delegation::calculate_delegation_hash_root( &delegation_id, @@ -125,13 +125,13 @@ fn create_delegation_direct_root_successful() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(delegation_info)); - let operation = generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); + let operation = generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash.clone(), creator.clone())]) + .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), creator.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -174,7 +174,7 @@ fn create_delegation_with_parent_successful() { let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, creator.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); let delegation_info = Delegation::calculate_delegation_hash_root( &delegation_id, @@ -185,14 +185,14 @@ fn create_delegation_with_parent_successful() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(delegation_info)); - let operation = generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); + let operation = generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash.clone(), creator.clone())]) + .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id.clone(), hierarchy_info.clone(), creator.clone())]) - .with_delegations(vec![(parent_id.clone(), parent_node.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .with_delegations(vec![(parent_id, parent_node)]) .build(Some(ext)); ext.execute_with(|| { @@ -332,7 +332,7 @@ fn parent_not_existing_create_delegation_error() { ))); let operation = - generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) @@ -366,7 +366,7 @@ fn not_owner_of_parent_create_delegation_error() { let delegate = get_sr25519_account(delegate_keypair.public()); let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, alternative_owner.clone(), Some(hierarchy_root_id))); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, alternative_owner, Some(hierarchy_root_id))); let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( @@ -377,7 +377,7 @@ fn not_owner_of_parent_create_delegation_error() { ))); let operation = - generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) @@ -423,7 +423,7 @@ fn unauthorised_delegation_create_delegation_error() { ))); let operation = - generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) @@ -490,7 +490,7 @@ fn list_hierarchy_revoke_root_successful() { let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); operation.max_children = 2u32; @@ -534,7 +534,7 @@ fn tree_hierarchy_revoke_root_successful() { let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); let (delegation1_id, delegation1_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation2_id, delegation2_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); + let (delegation2_id, delegation2_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(hierarchy_root_id))); let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); operation.max_children = 2u32; @@ -578,7 +578,7 @@ fn max_max_revocations_revoke_successful() { let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); operation.max_children = MaxRevocations::get(); @@ -647,7 +647,7 @@ fn different_root_creator_revoke_root_error() { .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, alternative_revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, alternative_revoker)]) .build(Some(ext)); ext.execute_with(|| { @@ -666,7 +666,7 @@ fn too_small_max_revocations_revoke_root_error() { let delegate = get_ed25519_account(delegate_keypair.public()); let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(hierarchy_root_id))); let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); operation.max_children = 0u32; @@ -697,7 +697,7 @@ fn exact_children_max_revocations_revoke_root_error() { let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); let (delegation1_id, delegation1_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); let (delegation2_id, delegation2_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(delegation1_id))); - let (delegation3_id, delegation3_node) = (get_delegation_id_2(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(delegation1_id))); + let (delegation3_id, delegation3_node) = (get_delegation_id_2(true), generate_base_delegation_node(hierarchy_root_id, delegate, Some(delegation1_id))); let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); operation.max_children = 2u32; @@ -749,7 +749,7 @@ fn direct_owner_revoke_delegation_successful() { let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); let mut operation = generate_base_delegation_revocation_operation(parent_id); operation.max_revocations = 2u32; @@ -791,7 +791,7 @@ fn parent_owner_revoke_delegation_successful() { let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); let mut operation = generate_base_delegation_revocation_operation(delegation_id); operation.max_parent_checks = 1u32; @@ -872,7 +872,7 @@ fn not_delegating_revoke_delegation_error() { .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, owner.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, owner)]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); @@ -900,7 +900,7 @@ fn parent_too_far_revoke_delegation_error() { let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, intermediate.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); let mut operation = generate_base_delegation_revocation_operation(delegation_id); operation.max_parent_checks = 0u32; @@ -909,7 +909,7 @@ fn parent_too_far_revoke_delegation_error() { .with_ctypes(vec![(hierarchy_info.ctype_hash, owner.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, owner.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, owner)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -935,7 +935,7 @@ fn too_many_revocations_revoke_delegation_error() { let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); let mut operation = generate_base_delegation_revocation_operation(delegation_id); operation.max_parent_checks = 1u32; @@ -973,7 +973,7 @@ fn is_delegating_direct_not_revoked() { let user_3 = get_ed25519_account(user_3_keypair.public()); let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); let max_parent_checks = 0u32; @@ -983,7 +983,7 @@ fn is_delegating_direct_not_revoked() { .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1005,7 +1005,7 @@ fn is_delegating_direct_not_revoked_max_parent_checks_value() { let user_3 = get_ed25519_account(user_3_keypair.public()); let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); let max_parent_checks = u32::MAX; @@ -1015,7 +1015,7 @@ fn is_delegating_direct_not_revoked_max_parent_checks_value() { .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1037,7 +1037,7 @@ fn is_delegating_direct_revoked() { let user_3 = get_ed25519_account(user_3_keypair.public()); let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); let (delegation_id, mut delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); delegation_node.details.revoked = true; @@ -1048,7 +1048,7 @@ fn is_delegating_direct_revoked() { .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1070,7 +1070,7 @@ fn is_delegating_direct_revoked_max_parent_checks_value() { let user_3 = get_ed25519_account(user_3_keypair.public()); let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); let (delegation_id, mut delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); delegation_node.details.revoked = true; @@ -1081,7 +1081,7 @@ fn is_delegating_direct_revoked_max_parent_checks_value() { .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1104,7 +1104,7 @@ fn is_delegating_max_parent_not_revoked() { let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id))); let max_parent_checks = 1u32; @@ -1113,7 +1113,7 @@ fn is_delegating_max_parent_not_revoked() { .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1137,7 +1137,7 @@ fn is_delegating_max_parent_revoked() { let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); let (parent_id, mut parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); parent_node.details.revoked = true; - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id))); let max_parent_checks = 2u32; @@ -1146,7 +1146,7 @@ fn is_delegating_max_parent_revoked() { .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1168,8 +1168,8 @@ fn is_delegating_root_owner_not_revoked() { let user_3 = get_ed25519_account(user_3_keypair.public()); let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id))); let max_parent_checks = 2u32; @@ -1200,8 +1200,8 @@ fn is_delegating_root_owner_revoked() { let user_3 = get_ed25519_account(user_3_keypair.public()); let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id))); let max_parent_checks = 2u32; @@ -1257,8 +1257,8 @@ fn is_delegating_root_after_max_limit() { let user_3 = get_ed25519_account(user_3_keypair.public()); let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); + let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id))); // 1 less than needed let max_parent_checks = 1u32; From 16c8e012e3a36b86f5b9ee8033cd6d5e8b15c75b Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 13 Jul 2021 11:24:40 +0200 Subject: [PATCH 09/49] chore: fmt fixes --- pallets/attestation/src/lib.rs | 7 +- pallets/attestation/src/tests.rs | 34 +- pallets/delegation/src/benchmarking.rs | 13 +- .../delegation/src/delegation_hierarchy.rs | 8 +- pallets/delegation/src/lib.rs | 65 ++- pallets/delegation/src/mock.rs | 49 +- pallets/delegation/src/tests.rs | 481 ++++++++++++++---- 7 files changed, 490 insertions(+), 167 deletions(-) diff --git a/pallets/attestation/src/lib.rs b/pallets/attestation/src/lib.rs index 9aabeeb916..c6a0d82db9 100644 --- a/pallets/attestation/src/lib.rs +++ b/pallets/attestation/src/lib.rs @@ -170,13 +170,14 @@ pub mod pallet { ensure!(delegation.details.owner == attester, Error::::NotDelegatedToAttester); ensure!( - (delegation.details.permissions & delegation::Permissions::ATTEST) == delegation::Permissions::ATTEST, + (delegation.details.permissions & delegation::Permissions::ATTEST) + == delegation::Permissions::ATTEST, Error::::DelegationUnauthorizedToAttest ); // Check if the CTYPE of the delegation is matching the CTYPE of the attestation - let root = - >::get(delegation.hierarchy_root_id).ok_or(delegation::Error::::HierarchyNotFound)?; + let root = >::get(delegation.hierarchy_root_id) + .ok_or(delegation::Error::::HierarchyNotFound)?; ensure!(root.ctype_hash == ctype_hash, Error::::CTypeMismatch); // If the attestation is based on a delegation, store separately diff --git a/pallets/attestation/src/tests.rs b/pallets/attestation/src/tests.rs index 21bfe04314..32ac6d1b2f 100644 --- a/pallets/attestation/src/tests.rs +++ b/pallets/attestation/src/tests.rs @@ -202,7 +202,7 @@ fn delegation_revoked_attest_error() { ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(hierarchy_root_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(hierarchy_root_id)), ); delegation_node.details.permissions = delegation::Permissions::ATTEST; delegation_node.details.revoked = true; @@ -245,7 +245,7 @@ fn not_delegation_owner_attest_error() { ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, alternative_owner, Some(hierarchy_root_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, alternative_owner, Some(hierarchy_root_id)), ); delegation_node.details.permissions = delegation::Permissions::ATTEST; let mut attestation = generate_base_attestation(attester.clone()); @@ -286,7 +286,7 @@ fn unauthorised_permissions_attest_error() { // Delegation node does not have permissions to attest. let (delegation_id, delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(hierarchy_root_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(hierarchy_root_id)), ); let mut attestation = generate_base_attestation(attester.clone()); attestation.delegation_id = Some(delegation_id); @@ -326,7 +326,11 @@ fn root_not_present_attest_error() { let alternative_hierarchy_root_id = delegation_mock::get_delegation_hierarchy_id(false); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(alternative_hierarchy_root_id)) + delegation_mock::generate_base_delegation_node( + hierarchy_root_id, + attester.clone(), + Some(alternative_hierarchy_root_id), + ), ); delegation_node.details.permissions = delegation::Permissions::ATTEST; let mut attestation = generate_base_attestation(attester.clone()); @@ -368,7 +372,7 @@ fn root_ctype_mismatch_attest_error() { hierarchy_info.ctype_hash = alternative_ctype_hash; let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(hierarchy_root_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(hierarchy_root_id)), ); delegation_node.details.permissions = delegation::Permissions::ATTEST; let mut attestation = generate_base_attestation(attester.clone()); @@ -444,7 +448,7 @@ fn revoke_with_delegation_successful() { ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), ); delegation_node.details.permissions = delegation::Permissions::ATTEST; // Attestation owned by a different user, but delegation owned by the user @@ -496,12 +500,12 @@ fn revoke_with_parent_delegation_successful() { ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), ); parent_node.details.permissions = delegation::Permissions::ATTEST; let (delegation_id, delegation_node) = ( delegation_mock::get_delegation_id(false), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)), ); let mut attestation = generate_base_attestation(attestation_owner); attestation.delegation_id = Some(delegation_id); @@ -550,12 +554,12 @@ fn revoke_parent_delegation_no_attestation_permissions_successful() { ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), ); parent_node.details.permissions = delegation::Permissions::ATTEST; let (delegation_id, delegation_node) = ( delegation_mock::get_delegation_id(false), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)), ); let mut attestation = generate_base_attestation(attestation_owner); attestation.delegation_id = Some(delegation_id); @@ -604,12 +608,12 @@ fn revoke_parent_delegation_with_direct_delegation_revoked_successful() { ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), ); parent_node.details.permissions = delegation::Permissions::ATTEST; let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(false), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)), ); delegation_node.details.revoked = true; let mut attestation = generate_base_attestation(attestation_owner); @@ -750,11 +754,11 @@ fn max_parent_lookups_revoke_error() { ); let (parent_id, parent_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(false), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)), ); delegation_node.details.permissions = delegation::Permissions::ATTEST; let mut attestation = generate_base_attestation(attestation_owner); @@ -800,7 +804,7 @@ fn revoked_delegation_revoke_error() { ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), - delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)) + delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), ); delegation_node.details.permissions = delegation::Permissions::ATTEST; delegation_node.details.revoked = true; diff --git a/pallets/delegation/src/benchmarking.rs b/pallets/delegation/src/benchmarking.rs index bdd6399772..c56c746d37 100644 --- a/pallets/delegation/src/benchmarking.rs +++ b/pallets/delegation/src/benchmarking.rs @@ -46,7 +46,9 @@ where } /// add ctype to storage and root delegation -fn add_delegation_hierarchy(number: u32) -> Result<(DelegationTriplet, T::Hash), DispatchErrorWithPostInfo> +fn add_delegation_hierarchy( + number: u32, +) -> Result<(DelegationTriplet, T::Hash), DispatchErrorWithPostInfo> where T::AccountId: From, T::DelegationNodeId: From, @@ -57,7 +59,11 @@ where let hierarchy_root_id = generate_delegation_id::(number); ctype::Pallet::::add(RawOrigin::Signed(root_acc.clone()).into(), ctype_hash)?; - Pallet::::create_hierarchy(RawOrigin::Signed(root_acc.clone()).into(), hierarchy_root_id, ctype_hash)?; + Pallet::::create_hierarchy( + RawOrigin::Signed(root_acc.clone()).into(), + hierarchy_root_id, + ctype_hash, + )?; Ok(( DelegationTriplet:: { @@ -96,7 +102,8 @@ where let delegation_id = generate_delegation_id::(level * children_per_level.get() + c); // delegate signs delegation to parent - let hash: Vec = Pallet::::calculate_delegation_hash_root(&delegation_id, &root_id, &parent_id, &permissions).encode(); + let hash: Vec = + Pallet::::calculate_delegation_hash_root(&delegation_id, &root_id, &parent_id, &permissions).encode(); let sig = sp_io::crypto::sr25519_sign(KeyTypeId(*b"aura"), &delegation_acc_public, hash.as_ref()) .ok_or("Error while building signature of delegation.")?; diff --git a/pallets/delegation/src/delegation_hierarchy.rs b/pallets/delegation/src/delegation_hierarchy.rs index 85ac551fcb..7e82c8c4f2 100644 --- a/pallets/delegation/src/delegation_hierarchy.rs +++ b/pallets/delegation/src/delegation_hierarchy.rs @@ -72,7 +72,11 @@ impl DelegationNode { } } - pub fn new_node(hierarchy_root_id: DelegationNodeIdOf, parent: DelegationNodeIdOf, details: DelegationDetails) -> Self { + pub fn new_node( + hierarchy_root_id: DelegationNodeIdOf, + parent: DelegationNodeIdOf, + details: DelegationDetails, + ) -> Self { let mut new_node = Self::new_root_node(hierarchy_root_id, details); new_node.parent = Some(parent); @@ -96,7 +100,7 @@ impl DelegationDetails { Self { owner, permissions: Permissions::all(), - revoked: false + revoked: false, } } } diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index e1c61a08d4..253b590e45 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -101,7 +101,8 @@ pub mod pallet { /// It maps for a (root) node ID to the hierarchy details. #[pallet::storage] #[pallet::getter(fn delegation_hierarchies)] - pub type DelegationHierarchies = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, DelegationHierarchyInfo>; + pub type DelegationHierarchies = + StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, DelegationHierarchyInfo>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -186,14 +187,21 @@ pub mod pallet { ) -> DispatchResult { let creator = ::EnsureOrigin::ensure_origin(origin)?; - ensure!(!>::contains_key(&root_node_id), Error::::HierarchyAlreadyExists); + ensure!( + !>::contains_key(&root_node_id), + Error::::HierarchyAlreadyExists + ); ensure!( >::contains_key(&ctype_hash), >::CTypeNotFound ); - Self::create_and_store_new_hierarchy(root_node_id, DelegationHierarchyInfo:: { ctype_hash }, creator.clone()); + Self::create_and_store_new_hierarchy( + root_node_id, + DelegationHierarchyInfo:: { ctype_hash }, + creator.clone(), + ); Self::deposit_event(Event::HierarchyCreated(creator, root_node_id, ctype_hash)); @@ -233,7 +241,8 @@ pub mod pallet { let delegator = ::EnsureOrigin::ensure_origin(origin)?; // Calculate the hash root - let hash_root = Self::calculate_delegation_hash_root(&delegation_id, &root_node_id, &parent_id, &permissions); + let hash_root = + Self::calculate_delegation_hash_root(&delegation_id, &root_node_id, &parent_id, &permissions); // Verify that the hash root signature is correct. DelegationSignatureVerificationOf::::verify(&delegate, &hash_root.encode(), &delegate_signature) @@ -250,14 +259,30 @@ pub mod pallet { let parent_node = >::get(&parent_id).ok_or(Error::::ParentDelegationNotFound)?; // Check if the parent's delegate is the creator of this delegation node... - ensure!(parent_node.details.owner == delegator, Error::::NotOwnerOfParentDelegation); + ensure!( + parent_node.details.owner == delegator, + Error::::NotOwnerOfParentDelegation + ); // ... and has permission to delegate ensure!( (parent_node.details.permissions & Permissions::DELEGATE) == Permissions::DELEGATE, Error::::UnauthorizedDelegation ); - Self::store_delegation_under_parent(delegation_id, DelegationNode::new_node(root_node_id, parent_id, DelegationDetails { owner: delegate.clone(), permissions, revoked: false }), parent_id, parent_node); + Self::store_delegation_under_parent( + delegation_id, + DelegationNode::new_node( + root_node_id, + parent_id, + DelegationDetails { + owner: delegate.clone(), + permissions, + revoked: false, + }, + ), + parent_id, + parent_node, + ); Self::deposit_event(Event::DelegationCreated( delegator, @@ -295,7 +320,10 @@ pub mod pallet { let hierarchy_root_node = >::get(&root_node_id).ok_or(Error::::HierarchyNotFound)?; - ensure!(hierarchy_root_node.details.owner == invoker, Error::::UnauthorizedRevocation); + ensure!( + hierarchy_root_node.details.owner == invoker, + Error::::UnauthorizedRevocation + ); ensure!( max_children <= T::MaxRevocations::get(), @@ -402,23 +430,26 @@ impl Pallet { T::Hashing::hash(&hashed_values) } - fn create_and_store_new_hierarchy(root_id: DelegationNodeIdOf, hierarchy_info: DelegationHierarchyInfo, hierarchy_owner: DelegatorIdOf) { + fn create_and_store_new_hierarchy( + root_id: DelegationNodeIdOf, + hierarchy_info: DelegationHierarchyInfo, + hierarchy_owner: DelegatorIdOf, + ) { let root_node = DelegationNode::new_root_node(root_id, DelegationDetails::default_with_owner(hierarchy_owner)); >::insert(root_id, root_node); >::insert(root_id, hierarchy_info); } - fn store_delegation_under_parent(delegation_id: DelegationNodeIdOf, delegation_node: DelegationNode, parent_id: DelegationNodeIdOf, mut parent_node: DelegationNode) { - >::insert( - delegation_id, - delegation_node - ); + fn store_delegation_under_parent( + delegation_id: DelegationNodeIdOf, + delegation_node: DelegationNode, + parent_id: DelegationNodeIdOf, + mut parent_node: DelegationNode, + ) { + >::insert(delegation_id, delegation_node); // Add the new node as a child of that node parent_node.add_child(delegation_id); - >::insert( - parent_id, - parent_node - ); + >::insert(parent_id, parent_node); } fn revoke_and_store_hierarchy_root(root_id: DelegationNodeIdOf, mut root_node: DelegationNode) { diff --git a/pallets/delegation/src/mock.rs b/pallets/delegation/src/mock.rs index 30c8096328..dc81c6cbf7 100644 --- a/pallets/delegation/src/mock.rs +++ b/pallets/delegation/src/mock.rs @@ -221,7 +221,11 @@ pub fn generate_base_delegation_hierarchy_info() -> DelegationHierarchyInfo) -> DelegationNode { +pub fn generate_base_delegation_node( + hierarchy_id: TestDelegationNodeId, + owner: TestDelegatorId, + parent: Option, +) -> DelegationNode { DelegationNode { details: generate_base_delegation_details(owner), children: BTreeSet::new(), @@ -243,10 +247,12 @@ pub struct DelegationHierarchyCreationOperation { pub ctype_hash: TestCtypeHash, } -pub fn generate_base_delegation_hierarchy_creation_operation(id: TestDelegationNodeId) -> DelegationHierarchyCreationOperation { +pub fn generate_base_delegation_hierarchy_creation_operation( + id: TestDelegationNodeId, +) -> DelegationHierarchyCreationOperation { DelegationHierarchyCreationOperation { id, - ctype_hash: ctype::mock::get_ctype_hash(true) + ctype_hash: ctype::mock::get_ctype_hash(true), } } @@ -266,7 +272,9 @@ pub fn generate_base_delegation_creation_operation( ) -> DelegationCreationOperation { DelegationCreationOperation { delegation_id, - parent_id: delegation_node.parent.expect("Delegation node must specify a parent ID upon creation"), + parent_id: delegation_node + .parent + .expect("Delegation node must specify a parent ID upon creation"), hierarchy_id: delegation_node.hierarchy_root_id, delegate: delegation_node.details.owner, delegate_signature, @@ -282,10 +290,7 @@ pub struct DelegationHierarchyRevocationOperation { pub fn generate_base_delegation_hierarchy_revocation_operation( id: TestDelegationNodeId, ) -> DelegationHierarchyRevocationOperation { - DelegationHierarchyRevocationOperation { - id, - max_children: 0u32, - } + DelegationHierarchyRevocationOperation { id, max_children: 0u32 } } pub struct DelegationRevocationOperation { @@ -294,7 +299,9 @@ pub struct DelegationRevocationOperation { pub max_revocations: u32, } -pub fn generate_base_delegation_revocation_operation(delegation_id: TestDelegationNodeId) -> DelegationRevocationOperation { +pub fn generate_base_delegation_revocation_operation( + delegation_id: TestDelegationNodeId, +) -> DelegationRevocationOperation { DelegationRevocationOperation { delegation_id, max_parent_checks: 0u32, @@ -343,18 +350,32 @@ impl ExtBuilder { if !self.delegation_hierarchies_stored.is_empty() { ext.execute_with(|| { - self.delegation_hierarchies_stored.iter().for_each(|delegation_hierarchy| { - delegation::Pallet::create_and_store_new_hierarchy(delegation_hierarchy.0, delegation_hierarchy.1.clone(), delegation_hierarchy.2.clone()); - }) + self.delegation_hierarchies_stored + .iter() + .for_each(|delegation_hierarchy| { + delegation::Pallet::create_and_store_new_hierarchy( + delegation_hierarchy.0, + delegation_hierarchy.1.clone(), + delegation_hierarchy.2.clone(), + ); + }) }); } if !self.delegations_stored.is_empty() { ext.execute_with(|| { self.delegations_stored.iter().for_each(|del| { - let parent_node_id = del.1.parent.expect("Delegation node that is not a root must have a parent ID specified."); + let parent_node_id = del + .1 + .parent + .expect("Delegation node that is not a root must have a parent ID specified."); let parent_node = delegation::DelegationNodes::::get(&parent_node_id).unwrap(); - delegation::Pallet::store_delegation_under_parent(del.0, del.1.clone(), parent_node_id, parent_node); + delegation::Pallet::store_delegation_under_parent( + del.0, + del.1.clone(), + parent_node_id, + parent_node, + ); }) }); } diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index da41760498..ac0425fcf9 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -46,10 +46,15 @@ fn create_root_delegation_successful() { )); }); - let stored_hierarchy_details = ext.execute_with(|| Delegation::delegation_hierarchies(&hierarchy_root_id).expect("Delegation hierarchy should be present on chain.")); + let stored_hierarchy_details = ext.execute_with(|| { + Delegation::delegation_hierarchies(&hierarchy_root_id) + .expect("Delegation hierarchy should be present on chain.") + }); assert_eq!(stored_hierarchy_details.ctype_hash, operation.ctype_hash); - let stored_delegation_root = ext.execute_with(|| Delegation::delegation_nodes(&hierarchy_root_id).expect("Delegation root should be present on chain.")); + let stored_delegation_root = ext.execute_with(|| { + Delegation::delegation_nodes(&hierarchy_root_id).expect("Delegation root should be present on chain.") + }); assert_eq!(stored_delegation_root.hierarchy_root_id, hierarchy_root_id); assert_eq!(stored_delegation_root.parent, None); @@ -63,7 +68,10 @@ fn duplicate_create_root_delegation_error() { let creator_keypair = get_alice_ed25519(); let creator = get_ed25519_account(creator_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); let operation = generate_base_delegation_hierarchy_creation_operation(hierarchy_root_id); @@ -71,15 +79,13 @@ fn duplicate_create_root_delegation_error() { .with_ctypes(vec![(operation.ctype_hash, creator.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]).build(Some(ext)); + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .build(Some(ext)); ext.execute_with(|| { - assert_noop!(Delegation::create_hierarchy( - get_origin(creator.clone()), - operation.id, - operation.ctype_hash - ), - delegation::Error::::HierarchyAlreadyExists + assert_noop!( + Delegation::create_hierarchy(get_origin(creator.clone()), operation.id, operation.ctype_hash), + delegation::Error::::HierarchyAlreadyExists ); }); } @@ -113,8 +119,14 @@ fn create_delegation_direct_root_successful() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate, Some(hierarchy_root_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, delegate, Some(hierarchy_root_id)), + ); let delegation_info = Delegation::calculate_delegation_hash_root( &delegation_id, @@ -125,7 +137,8 @@ fn create_delegation_direct_root_successful() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(delegation_info)); - let operation = generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); + let operation = + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) @@ -172,9 +185,18 @@ fn create_delegation_with_parent_successful() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, creator.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, creator.clone(), Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id)), + ); let delegation_info = Delegation::calculate_delegation_hash_root( &delegation_id, @@ -185,7 +207,8 @@ fn create_delegation_with_parent_successful() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(delegation_info)); - let operation = generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); + let operation = + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) @@ -234,8 +257,14 @@ fn invalid_delegate_signature_create_delegation_error() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id)), + ); let delegate_signature = alternative_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( &delegation_id, @@ -277,8 +306,14 @@ fn duplicate_delegation_create_delegation_error() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id)), + ); let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( &delegation_id, @@ -321,8 +356,14 @@ fn parent_not_existing_create_delegation_error() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id)), + ); let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( &delegation_id, @@ -365,9 +406,18 @@ fn not_owner_of_parent_create_delegation_error() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, alternative_owner, Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, alternative_owner, Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id)), + ); let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( &delegation_id, @@ -410,10 +460,19 @@ fn unauthorised_delegation_create_delegation_error() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, mut parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, creator.clone(), Some(hierarchy_root_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, mut parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, creator.clone(), Some(hierarchy_root_id)), + ); parent_node.details.permissions = delegation::Permissions::ATTEST; - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id))); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id)), + ); let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( &delegation_id, @@ -456,7 +515,10 @@ fn empty_revoke_root_successful() { let revoker_keypair = get_alice_ed25519(); let revoker = get_ed25519_account(revoker_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); let operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); @@ -475,8 +537,9 @@ fn empty_revoke_root_successful() { )); }); - let stored_delegation_hierarchy_root = ext - .execute_with(|| Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.")); + let stored_delegation_hierarchy_root = ext.execute_with(|| { + Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.") + }); assert!(stored_delegation_hierarchy_root.details.revoked); } @@ -488,9 +551,18 @@ fn list_hierarchy_revoke_root_successful() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id)), + ); let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); operation.max_children = 2u32; @@ -511,8 +583,9 @@ fn list_hierarchy_revoke_root_successful() { )); }); - let stored_delegation_hierarchy_root = ext - .execute_with(|| Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.")); + let stored_delegation_hierarchy_root = ext.execute_with(|| { + Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.") + }); assert!(stored_delegation_hierarchy_root.details.revoked); let stored_parent_delegation = ext.execute_with(|| { @@ -520,8 +593,8 @@ fn list_hierarchy_revoke_root_successful() { }); assert!(stored_parent_delegation.details.revoked); - let stored_delegation = - ext.execute_with(|| Delegation::delegation_nodes(&delegation_id).expect("Delegation should be present on chain.")); + let stored_delegation = ext + .execute_with(|| Delegation::delegation_nodes(&delegation_id).expect("Delegation should be present on chain.")); assert!(stored_delegation.details.revoked); } @@ -532,9 +605,18 @@ fn tree_hierarchy_revoke_root_successful() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (delegation1_id, delegation1_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation2_id, delegation2_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(hierarchy_root_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (delegation1_id, delegation1_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), + ); + let (delegation2_id, delegation2_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate, Some(hierarchy_root_id)), + ); let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); operation.max_children = 2u32; @@ -544,7 +626,10 @@ fn tree_hierarchy_revoke_root_successful() { .build(None); let mut ext = ExtBuilder::default() .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) - .with_delegations(vec![(delegation1_id, delegation1_node), (delegation2_id, delegation2_node)]) + .with_delegations(vec![ + (delegation1_id, delegation1_node), + (delegation2_id, delegation2_node), + ]) .build(Some(ext)); ext.execute_with(|| { @@ -555,8 +640,9 @@ fn tree_hierarchy_revoke_root_successful() { )); }); - let stored_delegation_hierarchy_root = ext - .execute_with(|| Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.")); + let stored_delegation_hierarchy_root = ext.execute_with(|| { + Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.") + }); assert!(stored_delegation_hierarchy_root.details.revoked); let stored_delegation_1 = ext.execute_with(|| { @@ -564,8 +650,9 @@ fn tree_hierarchy_revoke_root_successful() { }); assert!(stored_delegation_1.details.revoked); - let stored_delegation_2 = - ext.execute_with(|| Delegation::delegation_nodes(&delegation2_id).expect("Delegation 2 should be present on chain.")); + let stored_delegation_2 = ext.execute_with(|| { + Delegation::delegation_nodes(&delegation2_id).expect("Delegation 2 should be present on chain.") + }); assert!(stored_delegation_2.details.revoked); } @@ -576,9 +663,18 @@ fn max_max_revocations_revoke_successful() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id)), + ); let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); operation.max_children = MaxRevocations::get(); @@ -599,8 +695,9 @@ fn max_max_revocations_revoke_successful() { )); }); - let stored_delegation_hierarchy_root = ext - .execute_with(|| Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.")); + let stored_delegation_hierarchy_root = ext.execute_with(|| { + Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.") + }); assert!(stored_delegation_hierarchy_root.details.revoked); let stored_parent_delegation = ext.execute_with(|| { @@ -608,8 +705,8 @@ fn max_max_revocations_revoke_successful() { }); assert!(stored_parent_delegation.details.revoked); - let stored_delegation = - ext.execute_with(|| Delegation::delegation_nodes(&delegation_id).expect("Delegation should be present on chain.")); + let stored_delegation = ext + .execute_with(|| Delegation::delegation_nodes(&delegation_id).expect("Delegation should be present on chain.")); assert!(stored_delegation.details.revoked); } @@ -639,7 +736,10 @@ fn different_root_creator_revoke_root_error() { let alternative_revoker_keypair = get_charlie_ed25519(); let alternative_revoker = get_ed25519_account(alternative_revoker_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); let operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); @@ -665,8 +765,14 @@ fn too_small_max_revocations_revoke_root_error() { let delegate_keypair = get_alice_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(hierarchy_root_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate, Some(hierarchy_root_id)), + ); let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); operation.max_children = 0u32; @@ -694,10 +800,22 @@ fn exact_children_max_revocations_revoke_root_error() { let delegate_keypair = get_alice_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (delegation1_id, delegation1_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id))); - let (delegation2_id, delegation2_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(delegation1_id))); - let (delegation3_id, delegation3_node) = (get_delegation_id_2(true), generate_base_delegation_node(hierarchy_root_id, delegate, Some(delegation1_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (delegation1_id, delegation1_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id)), + ); + let (delegation2_id, delegation2_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(delegation1_id)), + ); + let (delegation3_id, delegation3_node) = ( + get_delegation_id_2(true), + generate_base_delegation_node(hierarchy_root_id, delegate, Some(delegation1_id)), + ); let mut operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); operation.max_children = 2u32; @@ -707,7 +825,11 @@ fn exact_children_max_revocations_revoke_root_error() { .build(None); let mut ext = ExtBuilder::default() .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) - .with_delegations(vec![(delegation1_id, delegation1_node), (delegation2_id, delegation2_node), (delegation3_id, delegation3_node)]) + .with_delegations(vec![ + (delegation1_id, delegation1_node), + (delegation2_id, delegation2_node), + (delegation3_id, delegation3_node), + ]) .build(Some(ext)); ext.execute_with(|| { @@ -719,22 +841,26 @@ fn exact_children_max_revocations_revoke_root_error() { ); }); - let stored_delegation_root = ext - .execute_with(|| Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.")); + let stored_delegation_root = ext.execute_with(|| { + Delegation::delegation_nodes(&operation.id).expect("Delegation root should be present on chain.") + }); assert!(!stored_delegation_root.details.revoked); - let stored_delegation_1 = ext - .execute_with(|| Delegation::delegation_nodes(&delegation1_id).expect("Delegation 1 should be present on chain.")); + let stored_delegation_1 = ext.execute_with(|| { + Delegation::delegation_nodes(&delegation1_id).expect("Delegation 1 should be present on chain.") + }); assert!(!stored_delegation_1.details.revoked); // Only this leaf should have been revoked as it is the first child of // delegation_1 - let stored_delegation_2 = ext - .execute_with(|| Delegation::delegation_nodes(&delegation2_id).expect("Delegation 2 should be present on chain.")); + let stored_delegation_2 = ext.execute_with(|| { + Delegation::delegation_nodes(&delegation2_id).expect("Delegation 2 should be present on chain.") + }); assert!(stored_delegation_2.details.revoked); - let stored_delegation_3 = ext - .execute_with(|| Delegation::delegation_nodes(&delegation3_id).expect("Delegation 3 should be present on chain.")); + let stored_delegation_3 = ext.execute_with(|| { + Delegation::delegation_nodes(&delegation3_id).expect("Delegation 3 should be present on chain.") + }); assert!(!stored_delegation_3.details.revoked); } @@ -747,9 +873,18 @@ fn direct_owner_revoke_delegation_successful() { let delegate_keypair = get_alice_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id)), + ); let mut operation = generate_base_delegation_revocation_operation(parent_id); operation.max_revocations = 2u32; @@ -789,9 +924,18 @@ fn parent_owner_revoke_delegation_successful() { let delegate_keypair = get_alice_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id)), + ); let mut operation = generate_base_delegation_revocation_operation(delegation_id); operation.max_parent_checks = 1u32; @@ -830,7 +974,10 @@ fn delegation_not_found_revoke_delegation_error() { let revoker_keypair = get_alice_ed25519(); let revoker = get_ed25519_account(revoker_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); let delegation_id = get_delegation_id(false); let operation = generate_base_delegation_revocation_operation(delegation_id); @@ -862,8 +1009,14 @@ fn not_delegating_revoke_delegation_error() { let revoker_keypair = get_bob_ed25519(); let revoker = get_ed25519_account(revoker_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (delegation_id, delegation_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, owner.clone(), Some(hierarchy_root_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, owner.clone(), Some(hierarchy_root_id)), + ); let mut operation = generate_base_delegation_revocation_operation(delegation_id); operation.max_parent_checks = MaxParentChecks::get(); @@ -898,9 +1051,18 @@ fn parent_too_far_revoke_delegation_error() { let delegate_keypair = get_bob_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, intermediate.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, intermediate.clone(), Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id)), + ); let mut operation = generate_base_delegation_revocation_operation(delegation_id); operation.max_parent_checks = 0u32; @@ -933,9 +1095,18 @@ fn too_many_revocations_revoke_delegation_error() { let delegate_keypair = get_bob_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id)), + ); let mut operation = generate_base_delegation_revocation_operation(delegation_id); operation.max_parent_checks = 1u32; @@ -972,9 +1143,18 @@ fn is_delegating_direct_not_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id)), + ); let max_parent_checks = 0u32; @@ -1004,9 +1184,18 @@ fn is_delegating_direct_not_revoked_max_parent_checks_value() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id)), + ); let max_parent_checks = u32::MAX; @@ -1036,9 +1225,18 @@ fn is_delegating_direct_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); - let (delegation_id, mut delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id)), + ); + let (delegation_id, mut delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id)), + ); delegation_node.details.revoked = true; let max_parent_checks = 0u32; @@ -1069,9 +1267,18 @@ fn is_delegating_direct_revoked_max_parent_checks_value() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); - let (delegation_id, mut delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id)), + ); + let (delegation_id, mut delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, user_3.clone(), Some(parent_id)), + ); delegation_node.details.revoked = true; let max_parent_checks = u32::MAX; @@ -1102,9 +1309,18 @@ fn is_delegating_max_parent_not_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id)), + ); let max_parent_checks = 1u32; @@ -1134,10 +1350,19 @@ fn is_delegating_max_parent_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, mut parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, mut parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, user_2.clone(), Some(hierarchy_root_id)), + ); parent_node.details.revoked = true; - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id))); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id)), + ); let max_parent_checks = 2u32; @@ -1167,9 +1392,18 @@ fn is_delegating_root_owner_not_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id)), + ); let max_parent_checks = 2u32; @@ -1199,9 +1433,18 @@ fn is_delegating_root_owner_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id)), + ); let max_parent_checks = 2u32; @@ -1229,7 +1472,10 @@ fn is_delegating_delegation_not_found() { let user_1_keypair = get_alice_ed25519(); let user_1 = get_ed25519_account(user_1_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); let delegation_id = get_delegation_id(true); let max_parent_checks = 2u32; @@ -1256,9 +1502,18 @@ fn is_delegating_root_after_max_limit() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = (get_delegation_hierarchy_id(true), generate_base_delegation_hierarchy_info()); - let (parent_id, parent_node) = (get_delegation_id(true), generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id))); - let (delegation_id, delegation_node) = (get_delegation_id(false), generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id))); + let (hierarchy_root_id, hierarchy_info) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_info(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, user_2, Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, user_3, Some(parent_id)), + ); // 1 less than needed let max_parent_checks = 1u32; From b292231e94b9eafe52885c447246add5eb39403b Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 13 Jul 2021 11:41:27 +0200 Subject: [PATCH 10/49] bench: re-execute benchmarks for delegation and attestation + temporarily remove benchmarks from peregrine runtime --- pallets/attestation/src/default_weights.rs | 47 +++---- pallets/delegation/src/default_weights.rs | 127 +++++++++---------- pallets/delegation/src/lib.rs | 16 +-- runtimes/peregrine/src/lib.rs | 4 +- runtimes/peregrine/src/weights/delegation.rs | 96 -------------- runtimes/peregrine/src/weights/mod.rs | 1 - 6 files changed, 90 insertions(+), 201 deletions(-) delete mode 100644 runtimes/peregrine/src/weights/delegation.rs diff --git a/pallets/attestation/src/default_weights.rs b/pallets/attestation/src/default_weights.rs index a8fd991570..b00f97cf95 100644 --- a/pallets/attestation/src/default_weights.rs +++ b/pallets/attestation/src/default_weights.rs @@ -19,29 +19,24 @@ //! Autogenerated weights for attestation //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-06-11, STEPS: {{cmd.steps}}\, REPEAT: {{cmd.repeat}}\, LOW RANGE: {{cmd.lowest_range_values}}\, HIGH RANGE: {{cmd.highest_range_values}}\ +//! DATE: 2021-07-13, STEPS: {{cmd.steps}}\, REPEAT: {{cmd.repeat}}\, LOW RANGE: {{cmd.lowest_range_values}}\, HIGH RANGE: {{cmd.highest_range_values}}\ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// ./kilt-parachain +// target/release/kilt-parachain // benchmark -// --chain -// dev -// --execution -// wasm -// --wasm-execution -// compiled -// --pallet -// attestation -// --extrinsic -// * -// --steps -// 1 -// --repeat -// 10 +// --chain=dev +// --execution=wasm +// --wasm-execution=Compiled // --heap-pages=4096 -// --output=../../pallets/attestation/src/default_weights.rs -// --template=../../.maintain/weight-template.hbs +// --extrinsic=* +// --pallet=attestation +// --steps=1 +// --repeat=20 +// --template +// .maintain/weight-template.hbs +// --output +// pallets/attestation/src/default_weights.rs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -61,14 +56,14 @@ pub trait WeightInfo { pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { fn add() -> Weight { - (37_981_000_u64) + (39_554_000_u64) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } fn revoke(d: u32, ) -> Weight { - (23_806_000_u64) - // Standard Error: 20_000 - .saturating_add((4_670_000_u64).saturating_mul(d as Weight)) + (25_295_000_u64) + // Standard Error: 50_000 + .saturating_add((5_239_000_u64).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(d as Weight))) .saturating_add(T::DbWeight::get().writes(1_u64)) @@ -78,14 +73,14 @@ impl WeightInfo for SubstrateWeight { // For backwards compatibility and tests impl WeightInfo for () { fn add() -> Weight { - (37_981_000_u64) + (39_554_000_u64) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } fn revoke(d: u32, ) -> Weight { - (23_806_000_u64) - // Standard Error: 20_000 - .saturating_add((4_670_000_u64).saturating_mul(d as Weight)) + (25_295_000_u64) + // Standard Error: 50_000 + .saturating_add((5_239_000_u64).saturating_mul(d as Weight)) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(d as Weight))) .saturating_add(RocksDbWeight::get().writes(1_u64)) diff --git a/pallets/delegation/src/default_weights.rs b/pallets/delegation/src/default_weights.rs index a5f96986d2..502cce902c 100644 --- a/pallets/delegation/src/default_weights.rs +++ b/pallets/delegation/src/default_weights.rs @@ -19,29 +19,24 @@ //! Autogenerated weights for delegation //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-06-11, STEPS: {{cmd.steps}}\, REPEAT: {{cmd.repeat}}\, LOW RANGE: {{cmd.lowest_range_values}}\, HIGH RANGE: {{cmd.highest_range_values}}\ +//! DATE: 2021-07-13, STEPS: {{cmd.steps}}\, REPEAT: {{cmd.repeat}}\, LOW RANGE: {{cmd.lowest_range_values}}\, HIGH RANGE: {{cmd.highest_range_values}}\ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// ./kilt-parachain +// target/release/kilt-parachain // benchmark -// --chain -// dev -// --execution -// wasm -// --wasm-execution -// compiled -// --pallet -// delegation -// --extrinsic -// * -// --steps -// 1 -// --repeat -// 10 +// --chain=dev +// --execution=wasm +// --wasm-execution=Compiled // --heap-pages=4096 -// --output=../../pallets/delegation/src/default_weights.rs -// --template=../../.maintain/weight-template.hbs +// --extrinsic=* +// --pallet=delegation +// --steps=1 +// --repeat=20 +// --template +// .maintain/weight-template.hbs +// --output +// pallets/delegation/src/default_weights.rs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -53,8 +48,8 @@ use sp_std::marker::PhantomData; /// Weight functions needed for delegation. pub trait WeightInfo { - fn create_root() -> Weight; - fn revoke_root(r: u32, ) -> Weight; + fn create_hierarchy() -> Weight; + fn revoke_hierarchy(r: u32, ) -> Weight; fn add_delegation() -> Weight; fn revoke_delegation_root_child(r: u32, c: u32, ) -> Weight; fn revoke_delegation_leaf(r: u32, c: u32, ) -> Weight; @@ -63,39 +58,39 @@ pub trait WeightInfo { /// Weights for delegation using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - fn create_root() -> Weight { - (22_442_000_u64) + fn create_hierarchy() -> Weight { + (25_218_000_u64) .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } - fn revoke_root(r: u32, ) -> Weight { - (24_418_000_u64) - // Standard Error: 29_000 - .saturating_add((17_591_000_u64).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(r as Weight))) + fn revoke_hierarchy(r: u32, ) -> Weight { + (25_605_000_u64) + // Standard Error: 58_000 + .saturating_add((17_141_000_u64).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r as Weight))) } fn add_delegation() -> Weight { - (83_497_000_u64) - .saturating_add(T::DbWeight::get().reads(4_u64)) + (80_662_000_u64) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - fn revoke_delegation_root_child(r: u32, _c: u32, ) -> Weight { - (11_210_000_u64) - // Standard Error: 55_000 - .saturating_add((17_485_000_u64).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(r as Weight))) + fn revoke_delegation_root_child(r: u32, c: u32, ) -> Weight { + (11_077_000_u64) + // Standard Error: 35_000 + .saturating_add((17_545_000_u64).saturating_mul(r as Weight)) + // Standard Error: 35_000 + .saturating_add((82_000_u64).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r as Weight))) } - fn revoke_delegation_leaf(r: u32, c: u32, ) -> Weight { - (27_413_000_u64) - // Standard Error: 30_000 - .saturating_add((111_000_u64).saturating_mul(r as Weight)) - // Standard Error: 30_000 - .saturating_add((4_692_000_u64).saturating_mul(c as Weight)) - .saturating_add(T::DbWeight::get().reads(2_u64)) + fn revoke_delegation_leaf(_r: u32, c: u32, ) -> Weight { + (30_265_000_u64) + // Standard Error: 41_000 + .saturating_add((5_076_000_u64).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c as Weight))) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -103,39 +98,39 @@ impl WeightInfo for SubstrateWeight { // For backwards compatibility and tests impl WeightInfo for () { - fn create_root() -> Weight { - (22_442_000_u64) + fn create_hierarchy() -> Weight { + (25_218_000_u64) .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } - fn revoke_root(r: u32, ) -> Weight { - (24_418_000_u64) - // Standard Error: 29_000 - .saturating_add((17_591_000_u64).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(r as Weight))) + fn revoke_hierarchy(r: u32, ) -> Weight { + (25_605_000_u64) + // Standard Error: 58_000 + .saturating_add((17_141_000_u64).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r as Weight))) } fn add_delegation() -> Weight { - (83_497_000_u64) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + (80_662_000_u64) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - fn revoke_delegation_root_child(r: u32, _c: u32, ) -> Weight { - (11_210_000_u64) - // Standard Error: 55_000 - .saturating_add((17_485_000_u64).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(r as Weight))) + fn revoke_delegation_root_child(r: u32, c: u32, ) -> Weight { + (11_077_000_u64) + // Standard Error: 35_000 + .saturating_add((17_545_000_u64).saturating_mul(r as Weight)) + // Standard Error: 35_000 + .saturating_add((82_000_u64).saturating_mul(c as Weight)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r as Weight))) } - fn revoke_delegation_leaf(r: u32, c: u32, ) -> Weight { - (27_413_000_u64) - // Standard Error: 30_000 - .saturating_add((111_000_u64).saturating_mul(r as Weight)) - // Standard Error: 30_000 - .saturating_add((4_692_000_u64).saturating_mul(c as Weight)) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + fn revoke_delegation_leaf(_r: u32, c: u32, ) -> Weight { + (30_265_000_u64) + // Standard Error: 41_000 + .saturating_add((5_076_000_u64).saturating_mul(c as Weight)) + .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(c as Weight))) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 253b590e45..d77f814c28 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -178,8 +178,7 @@ pub mod pallet { /// * origin: the identifier of the delegation creator /// * root_id: the ID of the root node. It has to be unique /// * ctype_hash: the CTYPE hash that delegates can use for attestations - // #[pallet::weight(::WeightInfo::create_root())] - #[pallet::weight(0)] + #[pallet::weight(::WeightInfo::create_hierarchy())] pub fn create_hierarchy( origin: OriginFor, root_node_id: DelegationNodeIdOf, @@ -227,8 +226,7 @@ pub mod pallet { /// is allowed to perform /// * delegate_signature: the delegate's signature over the new /// delegation ID, root ID, parent ID, and permission flags - // #[pallet::weight(::WeightInfo::add_delegation())] - #[pallet::weight(0)] + #[pallet::weight(::WeightInfo::add_delegation())] pub fn add_delegation( origin: OriginFor, delegation_id: DelegationNodeIdOf, @@ -309,8 +307,7 @@ pub mod pallet { /// * root_id: the ID of the delegation root to revoke /// * max_children: the maximum number of nodes descending from the root /// to revoke as a consequence of the root revocation - // #[pallet::weight(::WeightInfo::revoke_root(*max_children))] - #[pallet::weight(0)] + #[pallet::weight(::WeightInfo::revoke_hierarchy(*max_children))] pub fn revoke_hierarchy( origin: OriginFor, root_node_id: DelegationNodeIdOf, @@ -369,10 +366,9 @@ pub mod pallet { /// max number of parents is reached /// * max_revocations: the maximum number of nodes descending from this /// one to revoke as a consequence of this node revocation - // #[pallet::weight( - // ::WeightInfo::revoke_delegation_root_child(*max_revocations, *max_parent_checks) - // .max(::WeightInfo::revoke_delegation_leaf(*max_revocations, *max_parent_checks)))] - #[pallet::weight(0)] + #[pallet::weight( + ::WeightInfo::revoke_delegation_root_child(*max_revocations, *max_parent_checks) + .max(::WeightInfo::revoke_delegation_leaf(*max_revocations, *max_parent_checks)))] pub fn revoke_delegation( origin: OriginFor, delegation_id: DelegationNodeIdOf, diff --git a/runtimes/peregrine/src/lib.rs b/runtimes/peregrine/src/lib.rs index ea353995d1..acbc9137ac 100644 --- a/runtimes/peregrine/src/lib.rs +++ b/runtimes/peregrine/src/lib.rs @@ -672,7 +672,7 @@ impl delegation::Config for Runtime { type MaxSignatureByteLength = MaxSignatureByteLength; type MaxParentChecks = MaxParentChecks; type MaxRevocations = MaxRevocations; - type WeightInfo = weights::delegation::WeightInfo; + type WeightInfo = (); } impl ctype::Config for Runtime { @@ -1038,7 +1038,7 @@ impl_runtime_apis! { add_benchmark!(params, batches, attestation, Attestation); add_benchmark!(params, batches, ctype, Ctype); - add_benchmark!(params, batches, delegation, Delegation); + // add_benchmark!(params, batches, delegation, Delegation); add_benchmark!(params, batches, did, Did); add_benchmark!(params, batches, kilt_launch, KiltLaunch); add_benchmark!(params, batches, pallet_vesting, Vesting); diff --git a/runtimes/peregrine/src/weights/delegation.rs b/runtimes/peregrine/src/weights/delegation.rs deleted file mode 100644 index 358cf251e3..0000000000 --- a/runtimes/peregrine/src/weights/delegation.rs +++ /dev/null @@ -1,96 +0,0 @@ -// KILT Blockchain – https://botlabs.org -// Copyright (C) 2019-2021 BOTLabs GmbH - -// The KILT Blockchain is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The KILT Blockchain is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// If you feel like getting in touch with us, you can do so at info@botlabs.org - -//! Autogenerated weights for delegation -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-06-17, STEPS: `[1, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 - -// Executed Command: -// ./target/release/kilt-parachain -// benchmark -// --chain -// dev -// --heap-pages -// 4096 -// --extrinsic -// * -// --pallet -// delegation -// --steps -// 1 -// --repeat -// 20 -// --execution -// wasm -// --wasm-execution -// Compiled -// --output -// runtimes/parachain/src/weights/delegation.rs -// --template -// .maintain/runtime-weight-template.hbs - - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] - -use frame_support::{traits::Get, weights::Weight}; -use sp_std::marker::PhantomData; - -/// Weights for delegation using the recommended hardware. -pub struct WeightInfo(PhantomData); -impl delegation::WeightInfo for WeightInfo { - fn create_root() -> Weight { - 45_635_000_u64 - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - fn revoke_root(r: u32, ) -> Weight { - 48_761_000_u64 - // Standard Error: 311_000 - .saturating_add(31_784_000_u64.saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().reads(2_u64.saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64.saturating_mul(r as Weight))) - } - fn add_delegation() -> Weight { - 142_316_000_u64 - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - fn revoke_delegation_root_child(r: u32, _c: u32, ) -> Weight { - 21_746_000_u64 - // Standard Error: 60_000 - .saturating_add(32_601_000_u64.saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(2_u64.saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes(1_u64.saturating_mul(r as Weight))) - } - fn revoke_delegation_leaf(r: u32, c: u32, ) -> Weight { - 52_521_000_u64 - // Standard Error: 45_000 - .saturating_add(93_000_u64.saturating_mul(r as Weight)) - // Standard Error: 45_000 - .saturating_add(8_110_000_u64.saturating_mul(c as Weight)) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().reads(1_u64.saturating_mul(c as Weight))) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } -} \ No newline at end of file diff --git a/runtimes/peregrine/src/weights/mod.rs b/runtimes/peregrine/src/weights/mod.rs index 66fa4afcd9..ba398ac5cf 100644 --- a/runtimes/peregrine/src/weights/mod.rs +++ b/runtimes/peregrine/src/weights/mod.rs @@ -18,7 +18,6 @@ pub mod attestation; pub mod ctype; -pub mod delegation; pub mod did; pub mod frame_system; pub mod kilt_launch; From 9f11e2d298d2d7ac14db143ebf2a768bb72fa381 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 13 Jul 2021 13:32:41 +0200 Subject: [PATCH 11/49] fix: adjust pre-condition for an attestation unit test --- pallets/attestation/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/attestation/src/tests.rs b/pallets/attestation/src/tests.rs index 32ac6d1b2f..7ea2e2e28d 100644 --- a/pallets/attestation/src/tests.rs +++ b/pallets/attestation/src/tests.rs @@ -556,7 +556,7 @@ fn revoke_parent_delegation_no_attestation_permissions_successful() { delegation_mock::get_delegation_id(true), delegation_mock::generate_base_delegation_node(hierarchy_root_id, revoker.clone(), Some(hierarchy_root_id)), ); - parent_node.details.permissions = delegation::Permissions::ATTEST; + parent_node.details.permissions = delegation::Permissions::DELEGATE; let (delegation_id, delegation_node) = ( delegation_mock::get_delegation_id(false), delegation_mock::generate_base_delegation_node(hierarchy_root_id, attestation_owner.clone(), Some(parent_id)), From 9bf111980cc3f059025172c28569fa8b130bbf3d Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 14 Jul 2021 12:22:20 +0200 Subject: [PATCH 12/49] wip: add initial support for delegation storage migrations --- pallets/delegation/src/lib.rs | 38 +++++++- pallets/delegation/src/migrations.rs | 126 +++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 pallets/delegation/src/migrations.rs diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index d77f814c28..c318235fa1 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -24,6 +24,7 @@ pub mod default_weights; pub mod delegation_hierarchy; +pub mod migrations; #[cfg(any(feature = "mock", test))] pub mod mock; @@ -87,7 +88,42 @@ pub mod pallet { pub struct Pallet(_); #[pallet::hooks] - impl Hooks> for Pallet {} + impl Hooks> for Pallet { + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + let last_upgrade_version = LastUpgradeVersion::::get(); + if let Ok(migrator) = migrations::StorageMigrator::::try_new(last_upgrade_version) { + return migrator.pre_migrate(); + } else { + return Err("No migrations to apply."); + } + } + + fn on_runtime_upgrade() -> Weight { + let last_upgrade_version = LastUpgradeVersion::::get(); + if let Ok(migrator) = migrations::StorageMigrator::::try_new(last_upgrade_version) { + migrator.migrate() + } else { + 0u64 + } + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + let last_upgrade_version = LastUpgradeVersion::::get(); + if let Ok(migrator) = migrations::StorageMigrator::::try_new(last_upgrade_version) { + return migrator.post_migrate(); + } else { + return Err("No migrations applied."); + } + } + } + + /// Contains the version of the latest runtime upgrade performed. + #[pallet::storage] + #[pallet::getter(fn last_upgrade_version)] + pub type LastUpgradeVersion = StorageValue<_, u16, ValueQuery>; /// Delegation nodes stored on chain. /// diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs new file mode 100644 index 0000000000..62ddac6612 --- /dev/null +++ b/pallets/delegation/src/migrations.rs @@ -0,0 +1,126 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2021 BOTLabs GmbH + +// The KILT Blockchain is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The KILT Blockchain is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// If you feel like getting in touch with us, you can do so at info@botlabs.org + +use sp_std::{boxed::Box, vec}; + +use crate::*; + +pub const LATEST_UPGRADEABLE_VERSION: u16 = 0; + +trait VersionMigrator { + fn pre_migrate(&self, current_version: u16) -> Result; + fn migrate(&self) -> Weight; + fn post_migrate(&self) -> Result<(), &'static str>; +} + +pub struct StorageMigrator { + version: u16, + migrations: Vec>>, +} + +impl StorageMigrator { + pub(crate) fn try_new(from_version: u16) -> Result { + ensure!( + from_version <= LATEST_UPGRADEABLE_VERSION, + "Version to migrate from cannot be higher than the latest upgradeable version." + ); + + Ok(Self { + version: from_version, + migrations: vec![Box::new(V0Migrator{})] + }) + } + + // Calls the pre-migrate of the first migration to apply. + #[cfg(feature = "try-runtime")] + pub(crate) fn pre_migrate(&self) -> Result<(), &'static str> { + self.migrations[self.version as usize].as_ref().pre_migrate(self.version).map(|_| ()) + } + + pub(crate) fn migrate(& self) -> Weight { + let mut total_weight_used: Weight = 0; + + for version in self.version..=LATEST_UPGRADEABLE_VERSION { + let version_migrator: &dyn VersionMigrator = self.migrations[version as usize].as_ref(); + #[cfg(feature = "try-runtime")] + if let Err(err) = version_migrator.pre_migrate(version) { + assert!(false, "{}", err); + } + total_weight_used = total_weight_used.saturating_add(version_migrator.migrate()); + #[cfg(feature = "try-runtime")] + if let Err(err) = version_migrator.post_migrate() { + assert!(false, "{}", err); + } + } + + total_weight_used + } + + // Calls the post-migrate of the last migration applied. + #[cfg(feature = "try-runtime")] + pub(crate) fn post_migrate(&self) -> Result<(), &'static str> { + self.migrations[LATEST_UPGRADEABLE_VERSION as usize].as_ref().post_migrate() + } +} + +struct V0Migrator(); + +impl VersionMigrator for V0Migrator { + fn pre_migrate(&self, current_version: u16) -> Result { + assert!( + current_version == 0, + "Current version not equal to 0" + ); + log::debug!("Migrating version storage from v0 to v1"); + Ok(1) + } + + fn migrate(&self) -> Weight { + log::debug!("V0 delegation storage migrator started!"); + let total_weight = 0u64; + log::debug!("V0 delegation storage migrator finished!"); + total_weight + } + + fn post_migrate(&self) -> Result<(), &'static str> { + log::debug!("Version storage migrated from v0 to v1"); + Ok(()) + } +} + +#[test] +fn test_migrator_v0() { + let migrator = StorageMigrator::::try_new(0).expect("Initializing storage migrator with version 0 should not fail."); + migrator.migrate(); +} + +#[test] +fn test_migrator_v1() { + assert!( + StorageMigrator::::try_new(1).is_err(), + "Initializing storage migrator with at least version 1 should fail." + ); +} + +#[test] +fn test_migrator_v2() { + assert!( + StorageMigrator::::try_new(2).is_err(), + "Initializing storage migrator with at least version 2 should fail." + ); +} From badcb0f417809502bd9617fc5c19a9a3b57c71aa Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 14 Jul 2021 14:26:27 +0200 Subject: [PATCH 13/49] delegation storage migrator compiling --- pallets/delegation/src/lib.rs | 23 +---- pallets/delegation/src/migrations.rs | 137 ++++++++++++++++++--------- 2 files changed, 95 insertions(+), 65 deletions(-) diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index c318235fa1..d29f6542b3 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -92,38 +92,23 @@ pub mod pallet { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { - let last_upgrade_version = LastUpgradeVersion::::get(); - if let Ok(migrator) = migrations::StorageMigrator::::try_new(last_upgrade_version) { - return migrator.pre_migrate(); - } else { - return Err("No migrations to apply."); - } + migrations::StorageMigrator::::new().pre_migration().map_err(|_| "pre-migration failed") } fn on_runtime_upgrade() -> Weight { - let last_upgrade_version = LastUpgradeVersion::::get(); - if let Ok(migrator) = migrations::StorageMigrator::::try_new(last_upgrade_version) { - migrator.migrate() - } else { - 0u64 - } + migrations::StorageMigrator::::new().migrate() } #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { - let last_upgrade_version = LastUpgradeVersion::::get(); - if let Ok(migrator) = migrations::StorageMigrator::::try_new(last_upgrade_version) { - return migrator.post_migrate(); - } else { - return Err("No migrations applied."); - } + migrations::StorageMigrator::::new().post_migration().map_err(|_| "post-migration failed") } } /// Contains the version of the latest runtime upgrade performed. #[pallet::storage] #[pallet::getter(fn last_upgrade_version)] - pub type LastUpgradeVersion = StorageValue<_, u16, ValueQuery>; + pub(crate) type LastUpgradeVersion = StorageValue<_, u16, ValueQuery>; /// Delegation nodes stored on chain. /// diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 62ddac6612..3e59959f7b 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -20,107 +20,152 @@ use sp_std::{boxed::Box, vec}; use crate::*; -pub const LATEST_UPGRADEABLE_VERSION: u16 = 0; +// Contains the latest version that can be upgraded. +// For instance, if v1 of the storage is the last one available, only v0 would be +// upgradeable to v1, so the value of LATEST_UPGRADEABLE_VERSION would be 0. +const LATEST_UPGRADEABLE_VERSION: u16 = 0; trait VersionMigrator { - fn pre_migrate(&self, current_version: u16) -> Result; + #[cfg(feature = "try-runtime")] + fn pre_migrate(&self) -> Result<(), &'static str>; fn migrate(&self) -> Weight; + #[cfg(feature = "try-runtime")] fn post_migrate(&self) -> Result<(), &'static str>; } -pub struct StorageMigrator { - version: u16, +#[derive(Clone, Copy, Debug)] +pub(crate) enum DelegationMigrationError { + AlreadyLatest, + MigrationResultInconsistent, +} + +pub(crate) struct StorageMigrator { migrations: Vec>>, } impl StorageMigrator { - pub(crate) fn try_new(from_version: u16) -> Result { - ensure!( - from_version <= LATEST_UPGRADEABLE_VERSION, - "Version to migrate from cannot be higher than the latest upgradeable version." - ); - - Ok(Self { - version: from_version, + pub(crate) fn new() -> Self { + Self { migrations: vec![Box::new(V0Migrator{})] - }) + } } - // Calls the pre-migrate of the first migration to apply. - #[cfg(feature = "try-runtime")] - pub(crate) fn pre_migrate(&self) -> Result<(), &'static str> { - self.migrations[self.version as usize].as_ref().pre_migrate(self.version).map(|_| ()) + #[cfg(any(feature = "try-runtime", test))] + pub(crate) fn pre_migration(&self) -> Result<(), DelegationMigrationError> { + ensure!( + LastUpgradeVersion::::get() <= migrations::LATEST_UPGRADEABLE_VERSION, + DelegationMigrationError::AlreadyLatest + ); + + Ok(()) } - pub(crate) fn migrate(& self) -> Weight { + pub(crate) fn migrate(&self) -> Weight { let mut total_weight_used: Weight = 0; - - for version in self.version..=LATEST_UPGRADEABLE_VERSION { + let current_version = LastUpgradeVersion::::get(); + for version in current_version..=LATEST_UPGRADEABLE_VERSION { let version_migrator: &dyn VersionMigrator = self.migrations[version as usize].as_ref(); + // Test pre-conditions for each migrated version #[cfg(feature = "try-runtime")] - if let Err(err) = version_migrator.pre_migrate(version) { + if let Err(err) = version_migrator.pre_migrate() { assert!(false, "{}", err); } total_weight_used = total_weight_used.saturating_add(version_migrator.migrate()); + // Test post-conditions for each migrated version #[cfg(feature = "try-runtime")] if let Err(err) = version_migrator.post_migrate() { assert!(false, "{}", err); } } + // Set a version number that is not upgradeable anymore until a new version is available + LastUpgradeVersion::::set(LATEST_UPGRADEABLE_VERSION.saturating_add(1)); - total_weight_used + // Add a DB read and write for the LastUpgradeVersion storage update + total_weight_used.saturating_add(T::DbWeight::get().reads_writes(1, 1)) } - // Calls the post-migrate of the last migration applied. - #[cfg(feature = "try-runtime")] - pub(crate) fn post_migrate(&self) -> Result<(), &'static str> { - self.migrations[LATEST_UPGRADEABLE_VERSION as usize].as_ref().post_migrate() + #[cfg(any(feature = "try-runtime", test))] + pub(crate) fn post_migration(&self) -> Result<(), DelegationMigrationError> { + ensure!( + LastUpgradeVersion::::get() == migrations::LATEST_UPGRADEABLE_VERSION.saturating_add(1), + DelegationMigrationError::MigrationResultInconsistent + ); + + Ok(()) } } struct V0Migrator(); impl VersionMigrator for V0Migrator { - fn pre_migrate(&self, current_version: u16) -> Result { + #[cfg(feature = "try-runtime")] + fn pre_migrate(&self) -> Result<(), &'static str> { assert!( - current_version == 0, - "Current version not equal to 0" + LastUpgradeVersion::::get() == 0, + "Version not equal to 0 before v0 -> v1 migration." ); - log::debug!("Migrating version storage from v0 to v1"); - Ok(1) + log::debug!("Version storage migrating from v0 to v1"); + Ok(()) } fn migrate(&self) -> Weight { - log::debug!("V0 delegation storage migrator started!"); + log::debug!("v0 -> v1 delegation storage migrator started!"); let total_weight = 0u64; - log::debug!("V0 delegation storage migrator finished!"); + LastUpgradeVersion::::set(1); + log::debug!("v0 -> v1 delegation storage migrator finished!"); total_weight } + #[cfg(feature = "try-runtime")] fn post_migrate(&self) -> Result<(), &'static str> { + assert!( + LastUpgradeVersion::::get() == 0, + "Version not equal to 1 after v0 -> v1 migration." + ); log::debug!("Version storage migrated from v0 to v1"); Ok(()) } } #[test] -fn test_migrator_v0() { - let migrator = StorageMigrator::::try_new(0).expect("Initializing storage migrator with version 0 should not fail."); - migrator.migrate(); +fn ok_migrator_v0() { + let migrator = StorageMigrator::::new(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + assert!( + migrator.pre_migration().is_ok(), + "Pre-migration for v0 should not fail." + ); + migrator.migrate(); + assert!( + migrator.post_migration().is_ok(), + "Post-migration for v0 should not fail." + ); + }); } #[test] -fn test_migrator_v1() { - assert!( - StorageMigrator::::try_new(1).is_err(), - "Initializing storage migrator with at least version 1 should fail." - ); +fn already_max_migrator_v0() { + let migrator = StorageMigrator::::new(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + LastUpgradeVersion::::set(1); + assert!( + migrator.pre_migration().is_err(), + "Pre-migration for v0 should fail." + ); + }); } #[test] -fn test_migrator_v2() { - assert!( - StorageMigrator::::try_new(2).is_err(), - "Initializing storage migrator with at least version 2 should fail." - ); +fn more_than_max_migrator_v0() { + let migrator = StorageMigrator::::new(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + LastUpgradeVersion::::set(u16::MAX); + assert!( + migrator.pre_migration().is_err(), + "Pre-migration for v0 should fail." + ); + }); } From 2dd672fb14278b144674704eb9a65b863d55d1cb Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 14 Jul 2021 16:02:27 +0200 Subject: [PATCH 14/49] wip: storage migrator working, now writing unit tests for it --- .../delegation/src/delegation_hierarchy.rs | 175 ++++++++++++++---- pallets/delegation/src/lib.rs | 22 +++ pallets/delegation/src/migrations.rs | 76 +++++++- 3 files changed, 225 insertions(+), 48 deletions(-) diff --git a/pallets/delegation/src/delegation_hierarchy.rs b/pallets/delegation/src/delegation_hierarchy.rs index 7e82c8c4f2..a019f93b8c 100644 --- a/pallets/delegation/src/delegation_hierarchy.rs +++ b/pallets/delegation/src/delegation_hierarchy.rs @@ -16,6 +16,8 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org +pub use v1::*; + use bitflags::bitflags; use codec::{Decode, Encode}; use ctype::CtypeHashOf; @@ -54,60 +56,151 @@ impl Default for Permissions { } } -#[derive(Clone, Debug, Encode, Decode, PartialEq)] -pub struct DelegationNode { - pub hierarchy_root_id: DelegationNodeIdOf, - pub parent: Option>, - pub children: BTreeSet>, - pub details: DelegationDetails, -} +pub(crate) mod v0 { + use super::*; + + /// A node representing a delegation hierarchy root. + #[derive(Clone, Debug, Encode, Decode, PartialEq)] + pub struct DelegationRoot { + /// The hash of the CTYPE that delegated attesters within this trust + /// hierarchy can attest. + pub ctype_hash: CtypeHashOf, + /// The identifier of the root owner. + pub owner: DelegatorIdOf, + /// The flag indicating whether the root has been revoked or not. + pub revoked: bool, + } -impl DelegationNode { - pub fn new_root_node(id: DelegationNodeIdOf, details: DelegationDetails) -> Self { - Self { - hierarchy_root_id: id, - parent: None, - children: BTreeSet::new(), - details, + impl DelegationRoot { + pub fn new(ctype_hash: CtypeHashOf, owner: DelegatorIdOf) -> Self { + DelegationRoot { + ctype_hash, + owner, + revoked: false, + } } } - pub fn new_node( - hierarchy_root_id: DelegationNodeIdOf, - parent: DelegationNodeIdOf, - details: DelegationDetails, - ) -> Self { - let mut new_node = Self::new_root_node(hierarchy_root_id, details); - new_node.parent = Some(parent); - - new_node + /// A node representing a node in the delegation hierarchy. + #[derive(Clone, Debug, Encode, Decode, PartialEq)] + pub struct DelegationNode { + /// The ID of the delegation hierarchy root. + pub root_id: DelegationNodeIdOf, + /// \[OPTIONAL\] The ID of the parent node. If None, the node is + /// considered a direct child of the root node. + pub parent: Option>, + /// The identifier of the owner of the delegation node, i.e., the delegate. + pub owner: DelegatorIdOf, + /// The permission flags for the operations the delegate is allowed to + /// perform. + pub permissions: Permissions, + /// The flag indicating whether the delegation has been revoked or not. + pub revoked: bool, } - pub fn add_child(&mut self, child_id: DelegationNodeIdOf) { - self.children.insert(child_id); + impl DelegationNode { + /// Create a new delegation node that is a direct descendent of the + /// given root. + /// + /// * root_id: the root node ID this node will be a child of + /// * owner: the identifier of the owner of the new delegation, i.e., the + /// new delegate + /// * permissions: the permission flags for the operations the delegate is + /// allowed to perform + pub fn new_root_child(root_id: DelegationNodeIdOf, owner: DelegatorIdOf, permissions: Permissions) -> Self { + DelegationNode { + root_id, + owner, + permissions, + revoked: false, + parent: None, + } + } + + /// Creates a new delegation node that is a direct descendent of the + /// given node. + /// + /// * root_id: the root node ID this node will be a child of + /// * parent - the parent node ID this node will be a child of + /// * owner: the identifier of the owner of the new delegation, i.e., the + /// new delegate + /// * permissions: the permission flags for the operations the delegate is + /// allowed to perform + pub fn new_node_child( + root_id: DelegationNodeIdOf, + parent: DelegationNodeIdOf, + owner: DelegatorIdOf, + permissions: Permissions, + ) -> Self { + DelegationNode { + root_id, + parent: Some(parent), + owner, + permissions, + revoked: false, + } + } } } -#[derive(Clone, Debug, Encode, Decode, PartialEq)] -pub struct DelegationDetails { - pub owner: DelegatorIdOf, - pub revoked: bool, - pub permissions: Permissions, -} +pub(crate) mod v1 { + use super::*; + + #[derive(Clone, Debug, Encode, Decode, PartialEq)] + pub struct DelegationNode { + pub hierarchy_root_id: DelegationNodeIdOf, + pub parent: Option>, + pub children: BTreeSet>, + pub details: DelegationDetails, + } + + impl DelegationNode { + pub fn new_root_node(id: DelegationNodeIdOf, details: DelegationDetails) -> Self { + Self { + hierarchy_root_id: id, + parent: None, + children: BTreeSet::new(), + details, + } + } + + pub fn new_node( + hierarchy_root_id: DelegationNodeIdOf, + parent: DelegationNodeIdOf, + details: DelegationDetails, + ) -> Self { + let mut new_node = Self::new_root_node(hierarchy_root_id, details); + new_node.parent = Some(parent); + + new_node + } -impl DelegationDetails { - pub fn default_with_owner(owner: DelegatorIdOf) -> Self { - Self { - owner, - permissions: Permissions::all(), - revoked: false, + pub fn add_child(&mut self, child_id: DelegationNodeIdOf) { + self.children.insert(child_id); } } -} -#[derive(Clone, Debug, Encode, Decode, Eq, PartialEq, Ord, PartialOrd)] -pub struct DelegationHierarchyInfo { - pub ctype_hash: CtypeHashOf, + #[derive(Clone, Debug, Encode, Decode, PartialEq)] + pub struct DelegationDetails { + pub owner: DelegatorIdOf, + pub revoked: bool, + pub permissions: Permissions, + } + + impl DelegationDetails { + pub fn default_with_owner(owner: DelegatorIdOf) -> Self { + Self { + owner, + permissions: Permissions::all(), + revoked: false, + } + } + } + + #[derive(Clone, Debug, Encode, Decode, Eq, PartialEq, Ord, PartialOrd)] + pub struct DelegationHierarchyInfo { + pub ctype_hash: CtypeHashOf, + } } /// The result that the delegation pallet expects from the implementer of the diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index d29f6542b3..76f16f4c64 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -105,6 +105,28 @@ pub mod pallet { } } + /// Delegation root nodes stored on chain. DEPRECATED. + /// + /// It maps from a root node ID to the full root node. + #[pallet::storage] + #[pallet::getter(fn roots)] + pub type Roots = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, delegation_hierarchy::v0::DelegationRoot>; + + /// Delegation nodes stored on chain. DEPRECATED. + /// + /// It maps from a node ID to the full delegation node. + #[pallet::storage] + #[pallet::getter(fn delegations)] + pub type Delegations = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, delegation_hierarchy::v0::DelegationNode>; + + /// Children delegation nodes. DEPRECATED. + /// + /// It maps from a delegation node ID, including the root node, to the list + /// of children nodes, sorted by time of creation. + #[pallet::storage] + #[pallet::getter(fn children)] + pub type Children = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, Vec>>; + /// Contains the version of the latest runtime upgrade performed. #[pallet::storage] #[pallet::getter(fn last_upgrade_version)] diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 3e59959f7b..fd329d788a 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -16,7 +16,7 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org -use sp_std::{boxed::Box, vec}; +use sp_std::{boxed::Box, collections::{btree_map::BTreeMap}, vec}; use crate::*; @@ -104,15 +104,76 @@ impl VersionMigrator for V0Migrator { LastUpgradeVersion::::get() == 0, "Version not equal to 0 before v0 -> v1 migration." ); - log::debug!("Version storage migrating from v0 to v1"); + log::info!("Version storage migrating from v0 to v1"); Ok(()) } fn migrate(&self) -> Weight { - log::debug!("v0 -> v1 delegation storage migrator started!"); - let total_weight = 0u64; + log::info!("v0 -> v1 delegation storage migrator started!"); + let mut total_weight = 0u64; + + // First iterate over the delegation roots and translate them to hierarchies. + let mut new_nodes: BTreeMap, DelegationNode> = BTreeMap::new(); + + for (old_root_id, old_root_node) in Roots::::drain() { + let new_hierarchy_info = DelegationHierarchyInfo:: { + ctype_hash: old_root_node.ctype_hash + }; + let new_root_details = DelegationDetails:: { + owner: old_root_node.owner, + // Old roots did not have any permissions. So now we give them all permissions. + permissions: Permissions::all(), + revoked: old_root_node.revoked + }; + // In here, we already check for potential children of root nodes. + let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); + if let Some(root_children_ids) = Children::::take(old_root_id) { + // Add Chilred::take() + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + new_root_node.children = root_children_ids.iter().copied().collect(); + } + DelegationHierarchies::insert(old_root_id, new_hierarchy_info); + // Adds a read from Roots::drain() and DelegationHierarchies::insert() + total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + new_nodes.insert(old_root_id, new_root_node); + } + + // Then iterate over the regular delegation nodes. + for (old_node_id, old_node) in Delegations::::drain() { + let new_node_details = DelegationDetails:: { + owner: old_node.owner, + permissions: old_node.permissions, + revoked: old_node.revoked + }; + let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); + let mut new_node = DelegationNode::::new_node(old_node.root_id, new_node_parent_id, new_node_details); + if let Some(children_ids) = Children::::take(old_node_id) { + // Add Chilred::take() + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + new_node.children = children_ids.iter().copied().collect(); + } + // Adds a read from Roots::drain() + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + new_nodes.insert(old_node_id, new_node); + } + + // By now, all the children should have been correctly added to the nodes. + // We now need to modify all the nodes that are children by adding a reference to their parents. + for (new_node_id, new_node) in new_nodes.clone().into_iter() { + for child_id in new_node.children.iter().cloned() { + new_nodes.entry(child_id).and_modify(|node| node.parent = Some(new_node_id)); + } + // We can then insert the new delegation node in the storage. + DelegationNodes::::insert(new_node_id, new_node); + // Adds a write from DelegationNodes::insert() + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + } + LastUpgradeVersion::::set(1); - log::debug!("v0 -> v1 delegation storage migrator finished!"); + // Adds a write from LastUpgradeVersion::set() + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + log::debug!("Total weight consumed: {}", total_weight); + log::info!("v0 -> v1 delegation storage migrator finished!"); total_weight } @@ -122,13 +183,14 @@ impl VersionMigrator for V0Migrator { LastUpgradeVersion::::get() == 0, "Version not equal to 1 after v0 -> v1 migration." ); - log::debug!("Version storage migrated from v0 to v1"); + log::info!("Version storage migrated from v0 to v1"); Ok(()) } } #[test] -fn ok_migrator_v0() { +fn ok_migrator_v0_no_delegations() { + let _ = env_logger::builder().is_test(true).try_init(); let migrator = StorageMigrator::::new(); let mut ext = mock::ExtBuilder::default().build(None); ext.execute_with(|| { From ce7c8c750d239906165cc39f798d81d7b466faad Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 14 Jul 2021 16:41:33 +0200 Subject: [PATCH 15/49] test: unit tests passing --- pallets/delegation/src/migrations.rs | 370 ++++++++++++++++++++++++--- 1 file changed, 330 insertions(+), 40 deletions(-) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index fd329d788a..786a55b34e 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -188,46 +188,336 @@ impl VersionMigrator for V0Migrator { } } -#[test] -fn ok_migrator_v0_no_delegations() { - let _ = env_logger::builder().is_test(true).try_init(); - let migrator = StorageMigrator::::new(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - assert!( - migrator.pre_migration().is_ok(), - "Pre-migration for v0 should not fail." - ); - migrator.migrate(); - assert!( - migrator.post_migration().is_ok(), - "Post-migration for v0 should not fail." - ); - }); -} +#[cfg(test)] +mod tests_v0 { + use super::*; -#[test] -fn already_max_migrator_v0() { - let migrator = StorageMigrator::::new(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - LastUpgradeVersion::::set(1); - assert!( - migrator.pre_migration().is_err(), - "Pre-migration for v0 should fail." - ); - }); -} + use sp_core::Pair; + use mock::Test as TestRuntime; -#[test] -fn more_than_max_migrator_v0() { - let migrator = StorageMigrator::::new(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - LastUpgradeVersion::::set(u16::MAX); - assert!( - migrator.pre_migration().is_err(), - "Pre-migration for v0 should fail." - ); - }); + fn get_storage_migrator() -> StorageMigrator { + StorageMigrator::::new() + } + + fn init_logger() { + let _ = env_logger::builder().is_test(true).try_init(); + } + + #[test] + fn ok_no_delegations() { + let migrator = get_storage_migrator(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + assert!( + migrator.pre_migration().is_ok(), + "Pre-migration for v0 should not fail." + ); + migrator.migrate(); + assert!( + migrator.post_migration().is_ok(), + "Post-migration for v0 should not fail." + ); + }); + } + + #[test] + fn ok_only_root() { + init_logger(); + let migrator = get_storage_migrator(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); + Roots::insert(old_root_id, old_root_node.clone()); + + migrator.migrate(); + + assert_eq!( + Roots::::iter_values().count(), + 0 + ); + assert_eq!( + Delegations::::iter_values().count(), + 0 + ); + assert_eq!( + Children::::iter_values().count(), + 0 + ); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id).expect("New delegation hierarchy should exist in the storage."); + assert_eq!( + new_stored_hierarchy.ctype_hash, + old_root_node.ctype_hash + ); + let new_stored_root = DelegationNodes::::get(old_root_id).expect("New delegation root should exist in the storage."); + assert_eq!( + new_stored_root.hierarchy_root_id, + old_root_id + ); + assert!( + new_stored_root.parent.is_none() + ); + assert!( + new_stored_root.children.is_empty() + ); + assert_eq!( + new_stored_root.details.owner, + old_root_node.owner + ); + assert_eq!( + new_stored_root.details.revoked, + old_root_node.revoked + ); + }); + } + + #[test] + fn ok_three_level_hierarchy() { + init_logger(); + let migrator = get_storage_migrator(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_parent_id = mock::get_delegation_id(false); + let old_parent_node = crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); + let old_node_id = mock::get_delegation_id_2(true); + let old_node = crate::v0::DelegationNode::::new_node_child(old_root_id, old_parent_id, bob, Permissions::ATTEST); + Roots::insert(old_root_id, old_root_node.clone()); + Delegations::insert(old_parent_id, old_parent_node.clone()); + Delegations::insert(old_node_id, old_node.clone()); + Children::::insert(old_root_id, vec![old_parent_id]); + Children::::insert(old_parent_id, vec![old_node_id]); + + migrator.migrate(); + + assert_eq!( + Roots::::iter_values().count(), + 0 + ); + assert_eq!( + Delegations::::iter_values().count(), + 0 + ); + assert_eq!( + Children::::iter_values().count(), + 0 + ); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id).expect("New delegation hierarchy should exist in the storage."); + assert_eq!( + new_stored_hierarchy.ctype_hash, + old_root_node.ctype_hash + ); + let new_stored_root = DelegationNodes::::get(old_root_id).expect("New delegation root should exist in the storage."); + assert_eq!( + new_stored_root.hierarchy_root_id, + old_root_id + ); + assert!( + new_stored_root.parent.is_none() + ); + assert_eq!( + new_stored_root.children.len(), + 1 + ); + assert!( + new_stored_root.children.contains(&old_parent_id) + ); + assert_eq!( + new_stored_root.details.owner, + old_root_node.owner + ); + assert_eq!( + new_stored_root.details.revoked, + old_root_node.revoked + ); + + let new_stored_parent = DelegationNodes::::get(old_parent_id).expect("New delegation parent should exist in the storage."); + assert_eq!( + new_stored_parent.hierarchy_root_id, + old_root_id + ); + assert_eq!( + new_stored_parent.parent, + Some(old_root_id) + ); + assert_eq!( + new_stored_parent.children.len(), + 1 + ); + assert!( + new_stored_parent.children.contains(&old_node_id) + ); + assert_eq!( + new_stored_parent.details.owner, + old_parent_node.owner + ); + assert_eq!( + new_stored_parent.details.revoked, + old_parent_node.revoked + ); + + let new_stored_node = DelegationNodes::::get(old_node_id).expect("New delegation node should exist in the storage."); + assert_eq!( + new_stored_node.hierarchy_root_id, + old_root_id + ); + assert_eq!( + new_stored_node.parent, + Some(old_parent_id) + ); + assert!( + new_stored_node.children.is_empty() + ); + assert_eq!( + new_stored_node.details.owner, + old_node.owner + ); + assert_eq!( + new_stored_node.details.revoked, + old_node.revoked + ); + }); + } + + #[test] + fn ok_root_two_children() { + init_logger(); + let migrator = get_storage_migrator(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_node_id_1 = mock::get_delegation_id(false); + let old_node_1 = crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); + let old_node_id_2 = mock::get_delegation_id_2(true); + let old_node_2 = crate::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); + Roots::insert(old_root_id, old_root_node.clone()); + Delegations::insert(old_node_id_1, old_node_1.clone()); + Delegations::insert(old_node_id_2, old_node_2.clone()); + Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); + + migrator.migrate(); + + assert_eq!( + Roots::::iter_values().count(), + 0 + ); + assert_eq!( + Delegations::::iter_values().count(), + 0 + ); + assert_eq!( + Children::::iter_values().count(), + 0 + ); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id).expect("New delegation hierarchy should exist in the storage."); + assert_eq!( + new_stored_hierarchy.ctype_hash, + old_root_node.ctype_hash + ); + let new_stored_root = DelegationNodes::::get(old_root_id).expect("New delegation root should exist in the storage."); + assert_eq!( + new_stored_root.hierarchy_root_id, + old_root_id + ); + assert!( + new_stored_root.parent.is_none() + ); + assert_eq!( + new_stored_root.children.len(), + 2 + ); + assert!( + new_stored_root.children.contains(&old_node_id_1) + ); + assert!( + new_stored_root.children.contains(&old_node_id_2) + ); + assert_eq!( + new_stored_root.details.owner, + old_root_node.owner + ); + assert_eq!( + new_stored_root.details.revoked, + old_root_node.revoked + ); + + let new_stored_node_1 = DelegationNodes::::get(old_node_id_1).expect("New delegation 1 should exist in the storage."); + assert_eq!( + new_stored_node_1.hierarchy_root_id, + old_root_id + ); + assert_eq!( + new_stored_node_1.parent, + Some(old_root_id) + ); + assert!( + new_stored_node_1.children.is_empty() + ); + assert_eq!( + new_stored_node_1.details.owner, + old_node_1.owner + ); + assert_eq!( + new_stored_node_1.details.revoked, + old_node_1.revoked + ); + + let new_stored_node_2 = DelegationNodes::::get(old_node_id_2).expect("New delegation 2 should exist in the storage."); + assert_eq!( + new_stored_node_2.hierarchy_root_id, + old_root_id + ); + assert_eq!( + new_stored_node_2.parent, + Some(old_root_id) + ); + assert!( + new_stored_node_2.children.is_empty() + ); + assert_eq!( + new_stored_node_2.details.owner, + old_node_2.owner + ); + assert_eq!( + new_stored_node_2.details.revoked, + old_node_2.revoked + ); + }); + } + + #[test] + fn err_already_max_migrator() { + let migrator = StorageMigrator::::new(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + LastUpgradeVersion::::set(1); + assert!( + migrator.pre_migration().is_err(), + "Pre-migration for v0 should fail." + ); + }); + } + + #[test] + fn err_more_than_max_migrator() { + let migrator = StorageMigrator::::new(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + LastUpgradeVersion::::set(u16::MAX); + assert!( + migrator.pre_migration().is_err(), + "Pre-migration for v0 should fail." + ); + }); + } } From 18955fb56df4e3c9d38c87162b7e1a6aee7a9e0b Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 14 Jul 2021 16:53:20 +0200 Subject: [PATCH 16/49] chore: clippy hints --- Cargo.lock | 1 + pallets/delegation/Cargo.toml | 1 + pallets/delegation/src/migrations.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 131445d772..03b943864a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1809,6 +1809,7 @@ version = "0.24.0" dependencies = [ "bitflags", "ctype", + "env_logger 0.8.4", "frame-benchmarking", "frame-support", "frame-system", diff --git a/pallets/delegation/Cargo.toml b/pallets/delegation/Cargo.toml index 06a551e0e1..4b2e647ac7 100644 --- a/pallets/delegation/Cargo.toml +++ b/pallets/delegation/Cargo.toml @@ -14,6 +14,7 @@ substrate-wasm-builder-runner = {version = "3.0.0"} [dev-dependencies] ctype = {features = ["mock"], path = "../ctype", version = "0.24.0"} +env_logger = {version = "0.8.4"} kilt-primitives = {default-features = false, path = "../../primitives"} serde = {version = "1.0.101"} sp-core = {branch = "polkadot-v0.9.8", default-features = false, git = "https://github.com/paritytech/substrate", version = "3.0.0"} diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 786a55b34e..5d2282ae08 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -51,6 +51,7 @@ impl StorageMigrator { } #[cfg(any(feature = "try-runtime", test))] + #[allow(clippy::absurd_extreme_comparisons)] pub(crate) fn pre_migration(&self) -> Result<(), DelegationMigrationError> { ensure!( LastUpgradeVersion::::get() <= migrations::LATEST_UPGRADEABLE_VERSION, From 82b2c13fc4d0a4f926a244b695204d1022827a34 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 14 Jul 2021 16:55:43 +0200 Subject: [PATCH 17/49] chore: further clippy fixes --- pallets/delegation/src/migrations.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 5d2282ae08..7ff6c585a1 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -69,13 +69,13 @@ impl StorageMigrator { // Test pre-conditions for each migrated version #[cfg(feature = "try-runtime")] if let Err(err) = version_migrator.pre_migrate() { - assert!(false, "{}", err); + panic!("{}", err); } total_weight_used = total_weight_used.saturating_add(version_migrator.migrate()); // Test post-conditions for each migrated version #[cfg(feature = "try-runtime")] if let Err(err) = version_migrator.post_migrate() { - assert!(false, "{}", err); + panic!("{}", err); } } // Set a version number that is not upgradeable anymore until a new version is available From 3122b26c6f9798611697a656fed83d28fba336ae Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 14 Jul 2021 17:00:00 +0200 Subject: [PATCH 18/49] chore: fmt --- .../delegation/src/delegation_hierarchy.rs | 25 +- pallets/delegation/src/lib.rs | 15 +- pallets/delegation/src/migrations.rs | 346 ++++++------------ 3 files changed, 136 insertions(+), 250 deletions(-) diff --git a/pallets/delegation/src/delegation_hierarchy.rs b/pallets/delegation/src/delegation_hierarchy.rs index a019f93b8c..ba21090a66 100644 --- a/pallets/delegation/src/delegation_hierarchy.rs +++ b/pallets/delegation/src/delegation_hierarchy.rs @@ -89,7 +89,8 @@ pub(crate) mod v0 { /// \[OPTIONAL\] The ID of the parent node. If None, the node is /// considered a direct child of the root node. pub parent: Option>, - /// The identifier of the owner of the delegation node, i.e., the delegate. + /// The identifier of the owner of the delegation node, i.e., the + /// delegate. pub owner: DelegatorIdOf, /// The permission flags for the operations the delegate is allowed to /// perform. @@ -103,11 +104,15 @@ pub(crate) mod v0 { /// given root. /// /// * root_id: the root node ID this node will be a child of - /// * owner: the identifier of the owner of the new delegation, i.e., the - /// new delegate - /// * permissions: the permission flags for the operations the delegate is - /// allowed to perform - pub fn new_root_child(root_id: DelegationNodeIdOf, owner: DelegatorIdOf, permissions: Permissions) -> Self { + /// * owner: the identifier of the owner of the new delegation, i.e., + /// the new delegate + /// * permissions: the permission flags for the operations the delegate + /// is allowed to perform + pub fn new_root_child( + root_id: DelegationNodeIdOf, + owner: DelegatorIdOf, + permissions: Permissions, + ) -> Self { DelegationNode { root_id, owner, @@ -122,10 +127,10 @@ pub(crate) mod v0 { /// /// * root_id: the root node ID this node will be a child of /// * parent - the parent node ID this node will be a child of - /// * owner: the identifier of the owner of the new delegation, i.e., the - /// new delegate - /// * permissions: the permission flags for the operations the delegate is - /// allowed to perform + /// * owner: the identifier of the owner of the new delegation, i.e., + /// the new delegate + /// * permissions: the permission flags for the operations the delegate + /// is allowed to perform pub fn new_node_child( root_id: DelegationNodeIdOf, parent: DelegationNodeIdOf, diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 76f16f4c64..49754bbd9c 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -89,10 +89,11 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { - #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { - migrations::StorageMigrator::::new().pre_migration().map_err(|_| "pre-migration failed") + migrations::StorageMigrator::::new() + .pre_migration() + .map_err(|_| "pre-migration failed") } fn on_runtime_upgrade() -> Weight { @@ -101,7 +102,9 @@ pub mod pallet { #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { - migrations::StorageMigrator::::new().post_migration().map_err(|_| "post-migration failed") + migrations::StorageMigrator::::new() + .post_migration() + .map_err(|_| "post-migration failed") } } @@ -110,14 +113,16 @@ pub mod pallet { /// It maps from a root node ID to the full root node. #[pallet::storage] #[pallet::getter(fn roots)] - pub type Roots = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, delegation_hierarchy::v0::DelegationRoot>; + pub type Roots = + StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, delegation_hierarchy::v0::DelegationRoot>; /// Delegation nodes stored on chain. DEPRECATED. /// /// It maps from a node ID to the full delegation node. #[pallet::storage] #[pallet::getter(fn delegations)] - pub type Delegations = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, delegation_hierarchy::v0::DelegationNode>; + pub type Delegations = + StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, delegation_hierarchy::v0::DelegationNode>; /// Children delegation nodes. DEPRECATED. /// diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 7ff6c585a1..6b8dc17509 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -16,13 +16,13 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org -use sp_std::{boxed::Box, collections::{btree_map::BTreeMap}, vec}; +use sp_std::{boxed::Box, collections::btree_map::BTreeMap, vec}; use crate::*; // Contains the latest version that can be upgraded. -// For instance, if v1 of the storage is the last one available, only v0 would be -// upgradeable to v1, so the value of LATEST_UPGRADEABLE_VERSION would be 0. +// For instance, if v1 of the storage is the last one available, only v0 would +// be upgradeable to v1, so the value of LATEST_UPGRADEABLE_VERSION would be 0. const LATEST_UPGRADEABLE_VERSION: u16 = 0; trait VersionMigrator { @@ -46,7 +46,7 @@ pub(crate) struct StorageMigrator { impl StorageMigrator { pub(crate) fn new() -> Self { Self { - migrations: vec![Box::new(V0Migrator{})] + migrations: vec![Box::new(V0Migrator {})], } } @@ -78,7 +78,8 @@ impl StorageMigrator { panic!("{}", err); } } - // Set a version number that is not upgradeable anymore until a new version is available + // Set a version number that is not upgradeable anymore until a new version is + // available LastUpgradeVersion::::set(LATEST_UPGRADEABLE_VERSION.saturating_add(1)); // Add a DB read and write for the LastUpgradeVersion storage update @@ -118,13 +119,13 @@ impl VersionMigrator for V0Migrator { for (old_root_id, old_root_node) in Roots::::drain() { let new_hierarchy_info = DelegationHierarchyInfo:: { - ctype_hash: old_root_node.ctype_hash + ctype_hash: old_root_node.ctype_hash, }; let new_root_details = DelegationDetails:: { owner: old_root_node.owner, // Old roots did not have any permissions. So now we give them all permissions. permissions: Permissions::all(), - revoked: old_root_node.revoked + revoked: old_root_node.revoked, }; // In here, we already check for potential children of root nodes. let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); @@ -144,7 +145,7 @@ impl VersionMigrator for V0Migrator { let new_node_details = DelegationDetails:: { owner: old_node.owner, permissions: old_node.permissions, - revoked: old_node.revoked + revoked: old_node.revoked, }; let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); let mut new_node = DelegationNode::::new_node(old_node.root_id, new_node_parent_id, new_node_details); @@ -159,10 +160,13 @@ impl VersionMigrator for V0Migrator { } // By now, all the children should have been correctly added to the nodes. - // We now need to modify all the nodes that are children by adding a reference to their parents. + // We now need to modify all the nodes that are children by adding a reference + // to their parents. for (new_node_id, new_node) in new_nodes.clone().into_iter() { for child_id in new_node.children.iter().cloned() { - new_nodes.entry(child_id).and_modify(|node| node.parent = Some(new_node_id)); + new_nodes + .entry(child_id) + .and_modify(|node| node.parent = Some(new_node_id)); } // We can then insert the new delegation node in the storage. DelegationNodes::::insert(new_node_id, new_node); @@ -193,8 +197,8 @@ impl VersionMigrator for V0Migrator { mod tests_v0 { use super::*; - use sp_core::Pair; use mock::Test as TestRuntime; + use sp_core::Pair; fn get_storage_migrator() -> StorageMigrator { StorageMigrator::::new() @@ -234,43 +238,20 @@ mod tests_v0 { migrator.migrate(); - assert_eq!( - Roots::::iter_values().count(), - 0 - ); - assert_eq!( - Delegations::::iter_values().count(), - 0 - ); - assert_eq!( - Children::::iter_values().count(), - 0 - ); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id).expect("New delegation hierarchy should exist in the storage."); - assert_eq!( - new_stored_hierarchy.ctype_hash, - old_root_node.ctype_hash - ); - let new_stored_root = DelegationNodes::::get(old_root_id).expect("New delegation root should exist in the storage."); - assert_eq!( - new_stored_root.hierarchy_root_id, - old_root_id - ); - assert!( - new_stored_root.parent.is_none() - ); - assert!( - new_stored_root.children.is_empty() - ); - assert_eq!( - new_stored_root.details.owner, - old_root_node.owner - ); - assert_eq!( - new_stored_root.details.revoked, - old_root_node.revoked - ); + assert_eq!(Roots::::iter_values().count(), 0); + assert_eq!(Delegations::::iter_values().count(), 0); + assert_eq!(Children::::iter_values().count(), 0); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert!(new_stored_root.children.is_empty()); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); }); } @@ -283,11 +264,18 @@ mod tests_v0 { let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); let old_root_id = mock::get_delegation_id(true); - let old_root_node = crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_root_node = + crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); let old_parent_id = mock::get_delegation_id(false); - let old_parent_node = crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); + let old_parent_node = + crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); let old_node_id = mock::get_delegation_id_2(true); - let old_node = crate::v0::DelegationNode::::new_node_child(old_root_id, old_parent_id, bob, Permissions::ATTEST); + let old_node = crate::v0::DelegationNode::::new_node_child( + old_root_id, + old_parent_id, + bob, + Permissions::ATTEST, + ); Roots::insert(old_root_id, old_root_node.clone()); Delegations::insert(old_parent_id, old_parent_node.clone()); Delegations::insert(old_node_id, old_node.clone()); @@ -296,93 +284,38 @@ mod tests_v0 { migrator.migrate(); - assert_eq!( - Roots::::iter_values().count(), - 0 - ); - assert_eq!( - Delegations::::iter_values().count(), - 0 - ); - assert_eq!( - Children::::iter_values().count(), - 0 - ); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id).expect("New delegation hierarchy should exist in the storage."); - assert_eq!( - new_stored_hierarchy.ctype_hash, - old_root_node.ctype_hash - ); - let new_stored_root = DelegationNodes::::get(old_root_id).expect("New delegation root should exist in the storage."); - assert_eq!( - new_stored_root.hierarchy_root_id, - old_root_id - ); - assert!( - new_stored_root.parent.is_none() - ); - assert_eq!( - new_stored_root.children.len(), - 1 - ); - assert!( - new_stored_root.children.contains(&old_parent_id) - ); - assert_eq!( - new_stored_root.details.owner, - old_root_node.owner - ); - assert_eq!( - new_stored_root.details.revoked, - old_root_node.revoked - ); - - let new_stored_parent = DelegationNodes::::get(old_parent_id).expect("New delegation parent should exist in the storage."); - assert_eq!( - new_stored_parent.hierarchy_root_id, - old_root_id - ); - assert_eq!( - new_stored_parent.parent, - Some(old_root_id) - ); - assert_eq!( - new_stored_parent.children.len(), - 1 - ); - assert!( - new_stored_parent.children.contains(&old_node_id) - ); - assert_eq!( - new_stored_parent.details.owner, - old_parent_node.owner - ); - assert_eq!( - new_stored_parent.details.revoked, - old_parent_node.revoked - ); - - let new_stored_node = DelegationNodes::::get(old_node_id).expect("New delegation node should exist in the storage."); - assert_eq!( - new_stored_node.hierarchy_root_id, - old_root_id - ); - assert_eq!( - new_stored_node.parent, - Some(old_parent_id) - ); - assert!( - new_stored_node.children.is_empty() - ); - assert_eq!( - new_stored_node.details.owner, - old_node.owner - ); - assert_eq!( - new_stored_node.details.revoked, - old_node.revoked - ); + assert_eq!(Roots::::iter_values().count(), 0); + assert_eq!(Delegations::::iter_values().count(), 0); + assert_eq!(Children::::iter_values().count(), 0); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert_eq!(new_stored_root.children.len(), 1); + assert!(new_stored_root.children.contains(&old_parent_id)); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + + let new_stored_parent = DelegationNodes::::get(old_parent_id) + .expect("New delegation parent should exist in the storage."); + assert_eq!(new_stored_parent.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_parent.parent, Some(old_root_id)); + assert_eq!(new_stored_parent.children.len(), 1); + assert!(new_stored_parent.children.contains(&old_node_id)); + assert_eq!(new_stored_parent.details.owner, old_parent_node.owner); + assert_eq!(new_stored_parent.details.revoked, old_parent_node.revoked); + + let new_stored_node = DelegationNodes::::get(old_node_id) + .expect("New delegation node should exist in the storage."); + assert_eq!(new_stored_node.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node.parent, Some(old_parent_id)); + assert!(new_stored_node.children.is_empty()); + assert_eq!(new_stored_node.details.owner, old_node.owner); + assert_eq!(new_stored_node.details.revoked, old_node.revoked); }); } @@ -395,11 +328,14 @@ mod tests_v0 { let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); let old_root_id = mock::get_delegation_id(true); - let old_root_node = crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_root_node = + crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); let old_node_id_1 = mock::get_delegation_id(false); - let old_node_1 = crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); + let old_node_1 = + crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); let old_node_id_2 = mock::get_delegation_id_2(true); - let old_node_2 = crate::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); + let old_node_2 = + crate::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); Roots::insert(old_root_id, old_root_node.clone()); Delegations::insert(old_node_id_1, old_node_1.clone()); Delegations::insert(old_node_id_2, old_node_2.clone()); @@ -407,92 +343,38 @@ mod tests_v0 { migrator.migrate(); - assert_eq!( - Roots::::iter_values().count(), - 0 - ); - assert_eq!( - Delegations::::iter_values().count(), - 0 - ); - assert_eq!( - Children::::iter_values().count(), - 0 - ); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id).expect("New delegation hierarchy should exist in the storage."); - assert_eq!( - new_stored_hierarchy.ctype_hash, - old_root_node.ctype_hash - ); - let new_stored_root = DelegationNodes::::get(old_root_id).expect("New delegation root should exist in the storage."); - assert_eq!( - new_stored_root.hierarchy_root_id, - old_root_id - ); - assert!( - new_stored_root.parent.is_none() - ); - assert_eq!( - new_stored_root.children.len(), - 2 - ); - assert!( - new_stored_root.children.contains(&old_node_id_1) - ); - assert!( - new_stored_root.children.contains(&old_node_id_2) - ); - assert_eq!( - new_stored_root.details.owner, - old_root_node.owner - ); - assert_eq!( - new_stored_root.details.revoked, - old_root_node.revoked - ); - - let new_stored_node_1 = DelegationNodes::::get(old_node_id_1).expect("New delegation 1 should exist in the storage."); - assert_eq!( - new_stored_node_1.hierarchy_root_id, - old_root_id - ); - assert_eq!( - new_stored_node_1.parent, - Some(old_root_id) - ); - assert!( - new_stored_node_1.children.is_empty() - ); - assert_eq!( - new_stored_node_1.details.owner, - old_node_1.owner - ); - assert_eq!( - new_stored_node_1.details.revoked, - old_node_1.revoked - ); - - let new_stored_node_2 = DelegationNodes::::get(old_node_id_2).expect("New delegation 2 should exist in the storage."); - assert_eq!( - new_stored_node_2.hierarchy_root_id, - old_root_id - ); - assert_eq!( - new_stored_node_2.parent, - Some(old_root_id) - ); - assert!( - new_stored_node_2.children.is_empty() - ); - assert_eq!( - new_stored_node_2.details.owner, - old_node_2.owner - ); - assert_eq!( - new_stored_node_2.details.revoked, - old_node_2.revoked - ); + assert_eq!(Roots::::iter_values().count(), 0); + assert_eq!(Delegations::::iter_values().count(), 0); + assert_eq!(Children::::iter_values().count(), 0); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert_eq!(new_stored_root.children.len(), 2); + assert!(new_stored_root.children.contains(&old_node_id_1)); + assert!(new_stored_root.children.contains(&old_node_id_2)); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + + let new_stored_node_1 = DelegationNodes::::get(old_node_id_1) + .expect("New delegation 1 should exist in the storage."); + assert_eq!(new_stored_node_1.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node_1.parent, Some(old_root_id)); + assert!(new_stored_node_1.children.is_empty()); + assert_eq!(new_stored_node_1.details.owner, old_node_1.owner); + assert_eq!(new_stored_node_1.details.revoked, old_node_1.revoked); + + let new_stored_node_2 = DelegationNodes::::get(old_node_id_2) + .expect("New delegation 2 should exist in the storage."); + assert_eq!(new_stored_node_2.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node_2.parent, Some(old_root_id)); + assert!(new_stored_node_2.children.is_empty()); + assert_eq!(new_stored_node_2.details.owner, old_node_2.owner); + assert_eq!(new_stored_node_2.details.revoked, old_node_2.revoked); }); } @@ -502,10 +384,7 @@ mod tests_v0 { let mut ext = mock::ExtBuilder::default().build(None); ext.execute_with(|| { LastUpgradeVersion::::set(1); - assert!( - migrator.pre_migration().is_err(), - "Pre-migration for v0 should fail." - ); + assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); }); } @@ -515,10 +394,7 @@ mod tests_v0 { let mut ext = mock::ExtBuilder::default().build(None); ext.execute_with(|| { LastUpgradeVersion::::set(u16::MAX); - assert!( - migrator.pre_migration().is_err(), - "Pre-migration for v0 should fail." - ); + assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); }); } } From 9730fc4f98cd159af9bf21590e60e59a328b7d0e Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 14 Jul 2021 17:34:09 +0200 Subject: [PATCH 19/49] wip: adjusting last things before possible to review --- .../delegation/src/delegation_hierarchy.rs | 3 + pallets/delegation/src/migrations.rs | 120 ++++++++++++++---- 2 files changed, 95 insertions(+), 28 deletions(-) diff --git a/pallets/delegation/src/delegation_hierarchy.rs b/pallets/delegation/src/delegation_hierarchy.rs index ba21090a66..5e45daa9b3 100644 --- a/pallets/delegation/src/delegation_hierarchy.rs +++ b/pallets/delegation/src/delegation_hierarchy.rs @@ -16,6 +16,7 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org +// Publicly re-export the most recent types used. pub use v1::*; use bitflags::bitflags; @@ -56,6 +57,7 @@ impl Default for Permissions { } } +// The old types. pub(crate) mod v0 { use super::*; @@ -148,6 +150,7 @@ pub(crate) mod v0 { } } +// The new types. pub(crate) mod v1 { use super::*; diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 6b8dc17509..b66b176c15 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -23,14 +23,18 @@ use crate::*; // Contains the latest version that can be upgraded. // For instance, if v1 of the storage is the last one available, only v0 would // be upgradeable to v1, so the value of LATEST_UPGRADEABLE_VERSION would be 0. +// This needs to be bumped (by 1) every time a new storage migration should take place. +// Along with this, a new version migrator must be defined and added to the `migrations` vector +// or the `StorageMigrator`. const LATEST_UPGRADEABLE_VERSION: u16 = 0; +// The trait that each version migrator must implement. trait VersionMigrator { #[cfg(feature = "try-runtime")] - fn pre_migrate(&self) -> Result<(), &'static str>; + fn pre_migrate(&self) -> Result<(), DelegationMigrationError>; fn migrate(&self) -> Weight; #[cfg(feature = "try-runtime")] - fn post_migrate(&self) -> Result<(), &'static str>; + fn post_migrate(&self) -> Result<(), DelegationMigrationError>; } #[derive(Clone, Copy, Debug)] @@ -39,7 +43,15 @@ pub(crate) enum DelegationMigrationError { MigrationResultInconsistent, } +// The "manager" of the pallet's storage migrations. It contains a vector of version migrations +// each of which corresponds to a new runtime upgrade to run, sequencially. +// It interacts with the `LastUpgradeVersion` of the pallet's storage. +// +// When a new runtime upgrade needs to be added, a new component implementing the `VersionMigrator` trait +// must be defined and added at the end of the `migrations` vector, so that it is always executed after all +// previous migrations have taken place. pub(crate) struct StorageMigrator { + // The vector of version migrators. migrations: Vec>>, } @@ -50,6 +62,7 @@ impl StorageMigrator { } } + // Checks whether there is at least one storage migration to perform. #[cfg(any(feature = "try-runtime", test))] #[allow(clippy::absurd_extreme_comparisons)] pub(crate) fn pre_migration(&self) -> Result<(), DelegationMigrationError> { @@ -61,31 +74,41 @@ impl StorageMigrator { Ok(()) } + // It retrieves the latest version deployed on chain, and sequencially applies any + // runtime migration until the state is update to the latest version. + // It provides a test feature that panics whenver something goes wrong for one of the + // version migrators, but in production it is just assumed that all the migrations will go through. pub(crate) fn migrate(&self) -> Weight { let mut total_weight_used: Weight = 0; let current_version = LastUpgradeVersion::::get(); + // Applies all the needed migration from the current version up to LATEST_UPGRADEABLE_VERSION + // (which is always the latest possible version - 1). for version in current_version..=LATEST_UPGRADEABLE_VERSION { + // It is assumed that the are exactly LATEST_UPGRADEABLE_VERSION+1 migrators, so as long as + // the pre-condition is met, the following is assumed to never panic. let version_migrator: &dyn VersionMigrator = self.migrations[version as usize].as_ref(); - // Test pre-conditions for each migrated version + // Test pre-conditions (only in testing) for each version migrator. #[cfg(feature = "try-runtime")] if let Err(err) = version_migrator.pre_migrate() { - panic!("{}", err); + // panic!("{:?}", err); } + // Apply the migration and keep adding the weight. total_weight_used = total_weight_used.saturating_add(version_migrator.migrate()); - // Test post-conditions for each migrated version + // Test post-conditions (only in testing) for each version migrator. #[cfg(feature = "try-runtime")] if let Err(err) = version_migrator.post_migrate() { - panic!("{}", err); + panic!("{:?}", err); } } // Set a version number that is not upgradeable anymore until a new version is - // available + // available, which means that the new version will be LATEST_UPGRADEABLE_VERSION + 1. LastUpgradeVersion::::set(LATEST_UPGRADEABLE_VERSION.saturating_add(1)); // Add a DB read and write for the LastUpgradeVersion storage update total_weight_used.saturating_add(T::DbWeight::get().reads_writes(1, 1)) } + // Checks whether the upgrade as a whole went through by verifying that the latest version set it not upgradeable anymore. #[cfg(any(feature = "try-runtime", test))] pub(crate) fn post_migration(&self) -> Result<(), DelegationMigrationError> { ensure!( @@ -97,14 +120,16 @@ impl StorageMigrator { } } +// Migrator for the first actual pallet's migration. It migrates the Roots, Delegations, and Children storage entries +// to a simpler HierarchyInfos, DelegationNodes, while maintaining the original information an all parent-child links. struct V0Migrator(); impl VersionMigrator for V0Migrator { #[cfg(feature = "try-runtime")] - fn pre_migrate(&self) -> Result<(), &'static str> { + fn pre_migrate(&self) -> Result<(), DelegationMigrationError> { assert!( LastUpgradeVersion::::get() == 0, - "Version not equal to 0 before v0 -> v1 migration." + DelegationMigrationError::AlreadyLatest ); log::info!("Version storage migrating from v0 to v1"); Ok(()) @@ -114,9 +139,12 @@ impl VersionMigrator for V0Migrator { log::info!("v0 -> v1 delegation storage migrator started!"); let mut total_weight = 0u64; - // First iterate over the delegation roots and translate them to hierarchies. + // Before being stored, the nodes are saved in a map so that after we go over all the nodes and the parent-child + // relationship in the storage, we can update the `parent` link of each node accordingly. + // Otherwise, it would be possible that a node does not exist when fetched from the Children storage entry. let mut new_nodes: BTreeMap, DelegationNode> = BTreeMap::new(); + // First iterate over the delegation roots and translate them to hierarchies. for (old_root_id, old_root_node) in Roots::::drain() { let new_hierarchy_info = DelegationHierarchyInfo:: { ctype_hash: old_root_node.ctype_hash, @@ -127,15 +155,17 @@ impl VersionMigrator for V0Migrator { permissions: Permissions::all(), revoked: old_root_node.revoked, }; - // In here, we already check for potential children of root nodes. + // In here, we already check for potential children of root nodes and ONLY update the children information. + // The parent information will be updated later, when we know we have seen all the children already. let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); if let Some(root_children_ids) = Children::::take(old_root_id) { - // Add Chilred::take() - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); new_root_node.children = root_children_ids.iter().copied().collect(); } + // Add Chilred::take() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + DelegationHierarchies::insert(old_root_id, new_hierarchy_info); - // Adds a read from Roots::drain() and DelegationHierarchies::insert() + // Adds a read from Roots::drain() and a write from DelegationHierarchies::insert() weights total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); new_nodes.insert(old_root_id, new_root_node); } @@ -147,14 +177,15 @@ impl VersionMigrator for V0Migrator { permissions: old_node.permissions, revoked: old_node.revoked, }; + // In the old version, a parent None indicated the node is a child of the root. let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); let mut new_node = DelegationNode::::new_node(old_node.root_id, new_node_parent_id, new_node_details); if let Some(children_ids) = Children::::take(old_node_id) { - // Add Chilred::take() - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); new_node.children = children_ids.iter().copied().collect(); } - // Adds a read from Roots::drain() + // Add Chilred::take() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + // Adds a read from Roots::drain() weight total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); new_nodes.insert(old_node_id, new_node); } @@ -163,19 +194,20 @@ impl VersionMigrator for V0Migrator { // We now need to modify all the nodes that are children by adding a reference // to their parents. for (new_node_id, new_node) in new_nodes.clone().into_iter() { + // FIXME: new_node.children.iter().cloned() might be possibly changed to iter_mut. for child_id in new_node.children.iter().cloned() { new_nodes .entry(child_id) .and_modify(|node| node.parent = Some(new_node_id)); } - // We can then insert the new delegation node in the storage. + // We can then finally insert the new delegation node in the storage. DelegationNodes::::insert(new_node_id, new_node); - // Adds a write from DelegationNodes::insert() + // Adds a write from DelegationNodes::insert() weight total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); } LastUpgradeVersion::::set(1); - // Adds a write from LastUpgradeVersion::set() + // Adds a write from LastUpgradeVersion::set() weight total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); log::debug!("Total weight consumed: {}", total_weight); log::info!("v0 -> v1 delegation storage migrator finished!"); @@ -183,10 +215,10 @@ impl VersionMigrator for V0Migrator { } #[cfg(feature = "try-runtime")] - fn post_migrate(&self) -> Result<(), &'static str> { + fn post_migrate(&self) -> Result<(), DelegationMigrationError> { assert!( - LastUpgradeVersion::::get() == 0, - "Version not equal to 1 after v0 -> v1 migration." + LastUpgradeVersion::::get() == 1, + DelegationMigrationError::MigrationResultInconsistent ); log::info!("Version storage migrated from v0 to v1"); Ok(()) @@ -201,7 +233,7 @@ mod tests_v0 { use sp_core::Pair; fn get_storage_migrator() -> StorageMigrator { - StorageMigrator::::new() + StorageMigrator::::new() } fn init_logger() { @@ -217,7 +249,9 @@ mod tests_v0 { migrator.pre_migration().is_ok(), "Pre-migration for v0 should not fail." ); + migrator.migrate(); + assert!( migrator.post_migration().is_ok(), "Post-migration for v0 should not fail." @@ -236,8 +270,18 @@ mod tests_v0 { let old_root_node = crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); Roots::insert(old_root_id, old_root_node.clone()); + assert!( + migrator.pre_migration().is_ok(), + "Pre-migration for v0 should not fail." + ); + migrator.migrate(); + assert!( + migrator.post_migration().is_ok(), + "Post-migration for v0 should not fail." + ); + assert_eq!(Roots::::iter_values().count(), 0); assert_eq!(Delegations::::iter_values().count(), 0); assert_eq!(Children::::iter_values().count(), 0); @@ -282,8 +326,18 @@ mod tests_v0 { Children::::insert(old_root_id, vec![old_parent_id]); Children::::insert(old_parent_id, vec![old_node_id]); + assert!( + migrator.pre_migration().is_ok(), + "Pre-migration for v0 should not fail." + ); + migrator.migrate(); + assert!( + migrator.post_migration().is_ok(), + "Post-migration for v0 should not fail." + ); + assert_eq!(Roots::::iter_values().count(), 0); assert_eq!(Delegations::::iter_values().count(), 0); assert_eq!(Children::::iter_values().count(), 0); @@ -341,8 +395,18 @@ mod tests_v0 { Delegations::insert(old_node_id_2, old_node_2.clone()); Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); + assert!( + migrator.pre_migration().is_ok(), + "Pre-migration for v0 should not fail." + ); + migrator.migrate(); + assert!( + migrator.post_migration().is_ok(), + "Post-migration for v0 should not fail." + ); + assert_eq!(Roots::::iter_values().count(), 0); assert_eq!(Delegations::::iter_values().count(), 0); assert_eq!(Children::::iter_values().count(), 0); @@ -380,20 +444,20 @@ mod tests_v0 { #[test] fn err_already_max_migrator() { - let migrator = StorageMigrator::::new(); + let migrator = StorageMigrator::::new(); let mut ext = mock::ExtBuilder::default().build(None); ext.execute_with(|| { - LastUpgradeVersion::::set(1); + LastUpgradeVersion::::set(1); assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); }); } #[test] fn err_more_than_max_migrator() { - let migrator = StorageMigrator::::new(); + let migrator = StorageMigrator::::new(); let mut ext = mock::ExtBuilder::default().build(None); ext.execute_with(|| { - LastUpgradeVersion::::set(u16::MAX); + LastUpgradeVersion::::set(u16::MAX); assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); }); } From e51b47896d0e8cedc2e1106d9e7770b3f7adb44a Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 15 Jul 2021 08:59:29 +0200 Subject: [PATCH 20/49] chore: clippy + fmt --- pallets/delegation/src/migrations.rs | 694 ++++++++++++++------------- 1 file changed, 355 insertions(+), 339 deletions(-) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index b66b176c15..da1f9c64d2 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -23,9 +23,9 @@ use crate::*; // Contains the latest version that can be upgraded. // For instance, if v1 of the storage is the last one available, only v0 would // be upgradeable to v1, so the value of LATEST_UPGRADEABLE_VERSION would be 0. -// This needs to be bumped (by 1) every time a new storage migration should take place. -// Along with this, a new version migrator must be defined and added to the `migrations` vector -// or the `StorageMigrator`. +// This needs to be bumped (by 1) every time a new storage migration should take +// place. Along with this, a new version migrator must be defined and added to +// the `migrations` vector or the `StorageMigrator`. const LATEST_UPGRADEABLE_VERSION: u16 = 0; // The trait that each version migrator must implement. @@ -43,12 +43,14 @@ pub(crate) enum DelegationMigrationError { MigrationResultInconsistent, } -// The "manager" of the pallet's storage migrations. It contains a vector of version migrations -// each of which corresponds to a new runtime upgrade to run, sequencially. -// It interacts with the `LastUpgradeVersion` of the pallet's storage. +// The "manager" of the pallet's storage migrations. It contains a vector of +// version migrations each of which corresponds to a new runtime upgrade to run, +// sequencially. It interacts with the `LastUpgradeVersion` of the pallet's +// storage. // -// When a new runtime upgrade needs to be added, a new component implementing the `VersionMigrator` trait -// must be defined and added at the end of the `migrations` vector, so that it is always executed after all +// When a new runtime upgrade needs to be added, a new component implementing +// the `VersionMigrator` trait must be defined and added at the end of the +// `migrations` vector, so that it is always executed after all // previous migrations have taken place. pub(crate) struct StorageMigrator { // The vector of version migrators. @@ -58,7 +60,7 @@ pub(crate) struct StorageMigrator { impl StorageMigrator { pub(crate) fn new() -> Self { Self { - migrations: vec![Box::new(V0Migrator {})], + migrations: vec![Box::new(v0::V0Migrator {})], } } @@ -74,23 +76,24 @@ impl StorageMigrator { Ok(()) } - // It retrieves the latest version deployed on chain, and sequencially applies any - // runtime migration until the state is update to the latest version. - // It provides a test feature that panics whenver something goes wrong for one of the - // version migrators, but in production it is just assumed that all the migrations will go through. + // It retrieves the latest version deployed on chain, and sequencially applies + // any runtime migration until the state is update to the latest version. + // It provides a test feature that panics whenver something goes wrong for one + // of the version migrators, but in production it is just assumed that all the + // migrations will go through. pub(crate) fn migrate(&self) -> Weight { let mut total_weight_used: Weight = 0; let current_version = LastUpgradeVersion::::get(); - // Applies all the needed migration from the current version up to LATEST_UPGRADEABLE_VERSION - // (which is always the latest possible version - 1). + // Applies all the needed migration from the current version up to + // LATEST_UPGRADEABLE_VERSION (which is always the latest possible version - 1). for version in current_version..=LATEST_UPGRADEABLE_VERSION { - // It is assumed that the are exactly LATEST_UPGRADEABLE_VERSION+1 migrators, so as long as - // the pre-condition is met, the following is assumed to never panic. + // It is assumed that the are exactly LATEST_UPGRADEABLE_VERSION+1 migrators, so + // as long as the pre-condition is met, the following is assumed to never panic. let version_migrator: &dyn VersionMigrator = self.migrations[version as usize].as_ref(); // Test pre-conditions (only in testing) for each version migrator. #[cfg(feature = "try-runtime")] if let Err(err) = version_migrator.pre_migrate() { - // panic!("{:?}", err); + panic!("{:?}", err); } // Apply the migration and keep adding the weight. total_weight_used = total_weight_used.saturating_add(version_migrator.migrate()); @@ -101,14 +104,16 @@ impl StorageMigrator { } } // Set a version number that is not upgradeable anymore until a new version is - // available, which means that the new version will be LATEST_UPGRADEABLE_VERSION + 1. + // available, which means that the new version will be + // LATEST_UPGRADEABLE_VERSION + 1. LastUpgradeVersion::::set(LATEST_UPGRADEABLE_VERSION.saturating_add(1)); // Add a DB read and write for the LastUpgradeVersion storage update total_weight_used.saturating_add(T::DbWeight::get().reads_writes(1, 1)) } - // Checks whether the upgrade as a whole went through by verifying that the latest version set it not upgradeable anymore. + // Checks whether the upgrade as a whole went through by verifying that the + // latest version set it not upgradeable anymore. #[cfg(any(feature = "try-runtime", test))] pub(crate) fn post_migration(&self) -> Result<(), DelegationMigrationError> { ensure!( @@ -120,345 +125,356 @@ impl StorageMigrator { } } -// Migrator for the first actual pallet's migration. It migrates the Roots, Delegations, and Children storage entries -// to a simpler HierarchyInfos, DelegationNodes, while maintaining the original information an all parent-child links. -struct V0Migrator(); - -impl VersionMigrator for V0Migrator { - #[cfg(feature = "try-runtime")] - fn pre_migrate(&self) -> Result<(), DelegationMigrationError> { - assert!( - LastUpgradeVersion::::get() == 0, - DelegationMigrationError::AlreadyLatest - ); - log::info!("Version storage migrating from v0 to v1"); - Ok(()) - } +mod v0 { + use super::*; + // Migrator for the first actual pallet's migration. It migrates the Roots, + // Delegations, and Children storage entries to a simpler HierarchyInfos, + // DelegationNodes, while maintaining the original information an all + // parent-child links. + pub struct V0Migrator(); + + impl VersionMigrator for V0Migrator { + #[cfg(feature = "try-runtime")] + fn pre_migrate(&self) -> Result<(), DelegationMigrationError> { + ensure!( + LastUpgradeVersion::::get() == 0, + DelegationMigrationError::AlreadyLatest + ); + log::info!("Version storage migrating from v0 to v1"); + Ok(()) + } - fn migrate(&self) -> Weight { - log::info!("v0 -> v1 delegation storage migrator started!"); - let mut total_weight = 0u64; - - // Before being stored, the nodes are saved in a map so that after we go over all the nodes and the parent-child - // relationship in the storage, we can update the `parent` link of each node accordingly. - // Otherwise, it would be possible that a node does not exist when fetched from the Children storage entry. - let mut new_nodes: BTreeMap, DelegationNode> = BTreeMap::new(); - - // First iterate over the delegation roots and translate them to hierarchies. - for (old_root_id, old_root_node) in Roots::::drain() { - let new_hierarchy_info = DelegationHierarchyInfo:: { - ctype_hash: old_root_node.ctype_hash, - }; - let new_root_details = DelegationDetails:: { - owner: old_root_node.owner, - // Old roots did not have any permissions. So now we give them all permissions. - permissions: Permissions::all(), - revoked: old_root_node.revoked, - }; - // In here, we already check for potential children of root nodes and ONLY update the children information. - // The parent information will be updated later, when we know we have seen all the children already. - let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); - if let Some(root_children_ids) = Children::::take(old_root_id) { - new_root_node.children = root_children_ids.iter().copied().collect(); + fn migrate(&self) -> Weight { + log::info!("v0 -> v1 delegation storage migrator started!"); + let mut total_weight = 0u64; + + // Before being stored, the nodes are saved in a map so that after we go over + // all the nodes and the parent-child relationship in the storage, we can update + // the `parent` link of each node accordingly. Otherwise, it would be possible + // that a node does not exist when fetched from the Children storage entry. + let mut new_nodes: BTreeMap, DelegationNode> = BTreeMap::new(); + + // First iterate over the delegation roots and translate them to hierarchies. + for (old_root_id, old_root_node) in Roots::::drain() { + let new_hierarchy_info = DelegationHierarchyInfo:: { + ctype_hash: old_root_node.ctype_hash, + }; + let new_root_details = DelegationDetails:: { + owner: old_root_node.owner, + // Old roots did not have any permissions. So now we give them all permissions. + permissions: Permissions::all(), + revoked: old_root_node.revoked, + }; + // In here, we already check for potential children of root nodes and ONLY + // update the children information. The parent information will be updated + // later, when we know we have seen all the children already. + let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); + if let Some(root_children_ids) = Children::::take(old_root_id) { + new_root_node.children = root_children_ids.iter().copied().collect(); + } + // Add Chilred::take() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + + DelegationHierarchies::insert(old_root_id, new_hierarchy_info); + // Adds a read from Roots::drain() and a write from + // DelegationHierarchies::insert() weights + total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + new_nodes.insert(old_root_id, new_root_node); } - // Add Chilred::take() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - - DelegationHierarchies::insert(old_root_id, new_hierarchy_info); - // Adds a read from Roots::drain() and a write from DelegationHierarchies::insert() weights - total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); - new_nodes.insert(old_root_id, new_root_node); - } - // Then iterate over the regular delegation nodes. - for (old_node_id, old_node) in Delegations::::drain() { - let new_node_details = DelegationDetails:: { - owner: old_node.owner, - permissions: old_node.permissions, - revoked: old_node.revoked, - }; - // In the old version, a parent None indicated the node is a child of the root. - let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); - let mut new_node = DelegationNode::::new_node(old_node.root_id, new_node_parent_id, new_node_details); - if let Some(children_ids) = Children::::take(old_node_id) { - new_node.children = children_ids.iter().copied().collect(); + // Then iterate over the regular delegation nodes. + for (old_node_id, old_node) in Delegations::::drain() { + let new_node_details = DelegationDetails:: { + owner: old_node.owner, + permissions: old_node.permissions, + revoked: old_node.revoked, + }; + // In the old version, a parent None indicated the node is a child of the root. + let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); + let mut new_node = + DelegationNode::::new_node(old_node.root_id, new_node_parent_id, new_node_details); + if let Some(children_ids) = Children::::take(old_node_id) { + new_node.children = children_ids.iter().copied().collect(); + } + // Add Chilred::take() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + // Adds a read from Roots::drain() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + new_nodes.insert(old_node_id, new_node); } - // Add Chilred::take() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - // Adds a read from Roots::drain() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - new_nodes.insert(old_node_id, new_node); - } - // By now, all the children should have been correctly added to the nodes. - // We now need to modify all the nodes that are children by adding a reference - // to their parents. - for (new_node_id, new_node) in new_nodes.clone().into_iter() { - // FIXME: new_node.children.iter().cloned() might be possibly changed to iter_mut. - for child_id in new_node.children.iter().cloned() { - new_nodes - .entry(child_id) - .and_modify(|node| node.parent = Some(new_node_id)); + // By now, all the children should have been correctly added to the nodes. + // We now need to modify all the nodes that are children by adding a reference + // to their parents. + for (new_node_id, new_node) in new_nodes.clone().into_iter() { + // FIXME: new_node.children.iter().cloned() might be possibly changed to + // iter_mut. + for child_id in new_node.children.iter().cloned() { + new_nodes + .entry(child_id) + .and_modify(|node| node.parent = Some(new_node_id)); + } + // We can then finally insert the new delegation node in the storage. + DelegationNodes::::insert(new_node_id, new_node); + // Adds a write from DelegationNodes::insert() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); } - // We can then finally insert the new delegation node in the storage. - DelegationNodes::::insert(new_node_id, new_node); - // Adds a write from DelegationNodes::insert() weight + + LastUpgradeVersion::::set(1); + // Adds a write from LastUpgradeVersion::set() weight total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + log::debug!("Total weight consumed: {}", total_weight); + log::info!("v0 -> v1 delegation storage migrator finished!"); + total_weight } - LastUpgradeVersion::::set(1); - // Adds a write from LastUpgradeVersion::set() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - log::debug!("Total weight consumed: {}", total_weight); - log::info!("v0 -> v1 delegation storage migrator finished!"); - total_weight - } - - #[cfg(feature = "try-runtime")] - fn post_migrate(&self) -> Result<(), DelegationMigrationError> { - assert!( - LastUpgradeVersion::::get() == 1, - DelegationMigrationError::MigrationResultInconsistent - ); - log::info!("Version storage migrated from v0 to v1"); - Ok(()) - } -} - -#[cfg(test)] -mod tests_v0 { - use super::*; - - use mock::Test as TestRuntime; - use sp_core::Pair; - - fn get_storage_migrator() -> StorageMigrator { - StorageMigrator::::new() - } - - fn init_logger() { - let _ = env_logger::builder().is_test(true).try_init(); - } - - #[test] - fn ok_no_delegations() { - let migrator = get_storage_migrator(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - assert!( - migrator.pre_migration().is_ok(), - "Pre-migration for v0 should not fail." - ); - - migrator.migrate(); - - assert!( - migrator.post_migration().is_ok(), - "Post-migration for v0 should not fail." - ); - }); - } - - #[test] - fn ok_only_root() { - init_logger(); - let migrator = get_storage_migrator(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); - let old_root_id = mock::get_delegation_id(true); - let old_root_node = crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); - Roots::insert(old_root_id, old_root_node.clone()); - - assert!( - migrator.pre_migration().is_ok(), - "Pre-migration for v0 should not fail." + #[cfg(feature = "try-runtime")] + fn post_migrate(&self) -> Result<(), DelegationMigrationError> { + ensure!( + LastUpgradeVersion::::get() == 1, + DelegationMigrationError::MigrationResultInconsistent ); - - migrator.migrate(); - - assert!( - migrator.post_migration().is_ok(), - "Post-migration for v0 should not fail." - ); - - assert_eq!(Roots::::iter_values().count(), 0); - assert_eq!(Delegations::::iter_values().count(), 0); - assert_eq!(Children::::iter_values().count(), 0); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) - .expect("New delegation hierarchy should exist in the storage."); - assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); - let new_stored_root = DelegationNodes::::get(old_root_id) - .expect("New delegation root should exist in the storage."); - assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); - assert!(new_stored_root.parent.is_none()); - assert!(new_stored_root.children.is_empty()); - assert_eq!(new_stored_root.details.owner, old_root_node.owner); - assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); - }); + log::info!("Version storage migrated from v0 to v1"); + Ok(()) + } } - #[test] - fn ok_three_level_hierarchy() { - init_logger(); - let migrator = get_storage_migrator(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); - let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); - let old_root_id = mock::get_delegation_id(true); - let old_root_node = - crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); - let old_parent_id = mock::get_delegation_id(false); - let old_parent_node = - crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); - let old_node_id = mock::get_delegation_id_2(true); - let old_node = crate::v0::DelegationNode::::new_node_child( - old_root_id, - old_parent_id, - bob, - Permissions::ATTEST, - ); - Roots::insert(old_root_id, old_root_node.clone()); - Delegations::insert(old_parent_id, old_parent_node.clone()); - Delegations::insert(old_node_id, old_node.clone()); - Children::::insert(old_root_id, vec![old_parent_id]); - Children::::insert(old_parent_id, vec![old_node_id]); - - assert!( - migrator.pre_migration().is_ok(), - "Pre-migration for v0 should not fail." - ); + #[cfg(test)] + mod tests { + use super::*; - migrator.migrate(); + use mock::Test as TestRuntime; + use sp_core::Pair; - assert!( - migrator.post_migration().is_ok(), - "Post-migration for v0 should not fail." - ); + fn get_storage_migrator() -> StorageMigrator { + StorageMigrator::::new() + } - assert_eq!(Roots::::iter_values().count(), 0); - assert_eq!(Delegations::::iter_values().count(), 0); - assert_eq!(Children::::iter_values().count(), 0); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) - .expect("New delegation hierarchy should exist in the storage."); - assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); - let new_stored_root = DelegationNodes::::get(old_root_id) - .expect("New delegation root should exist in the storage."); - assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); - assert!(new_stored_root.parent.is_none()); - assert_eq!(new_stored_root.children.len(), 1); - assert!(new_stored_root.children.contains(&old_parent_id)); - assert_eq!(new_stored_root.details.owner, old_root_node.owner); - assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); - - let new_stored_parent = DelegationNodes::::get(old_parent_id) - .expect("New delegation parent should exist in the storage."); - assert_eq!(new_stored_parent.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_parent.parent, Some(old_root_id)); - assert_eq!(new_stored_parent.children.len(), 1); - assert!(new_stored_parent.children.contains(&old_node_id)); - assert_eq!(new_stored_parent.details.owner, old_parent_node.owner); - assert_eq!(new_stored_parent.details.revoked, old_parent_node.revoked); - - let new_stored_node = DelegationNodes::::get(old_node_id) - .expect("New delegation node should exist in the storage."); - assert_eq!(new_stored_node.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_node.parent, Some(old_parent_id)); - assert!(new_stored_node.children.is_empty()); - assert_eq!(new_stored_node.details.owner, old_node.owner); - assert_eq!(new_stored_node.details.revoked, old_node.revoked); - }); - } + fn init_logger() { + let _ = env_logger::builder().is_test(true).try_init(); + } - #[test] - fn ok_root_two_children() { - init_logger(); - let migrator = get_storage_migrator(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); - let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); - let old_root_id = mock::get_delegation_id(true); - let old_root_node = - crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); - let old_node_id_1 = mock::get_delegation_id(false); - let old_node_1 = - crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); - let old_node_id_2 = mock::get_delegation_id_2(true); - let old_node_2 = - crate::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); - Roots::insert(old_root_id, old_root_node.clone()); - Delegations::insert(old_node_id_1, old_node_1.clone()); - Delegations::insert(old_node_id_2, old_node_2.clone()); - Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); - - assert!( - migrator.pre_migration().is_ok(), - "Pre-migration for v0 should not fail." - ); + #[test] + fn ok_no_delegations() { + let migrator = get_storage_migrator(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + assert!( + migrator.pre_migration().is_ok(), + "Pre-migration for v0 should not fail." + ); + + migrator.migrate(); + + assert!( + migrator.post_migration().is_ok(), + "Post-migration for v0 should not fail." + ); + }); + } - migrator.migrate(); + #[test] + fn ok_only_root() { + init_logger(); + let migrator = get_storage_migrator(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = + crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); + Roots::insert(old_root_id, old_root_node.clone()); + + assert!( + migrator.pre_migration().is_ok(), + "Pre-migration for v0 should not fail." + ); + + migrator.migrate(); + + assert!( + migrator.post_migration().is_ok(), + "Post-migration for v0 should not fail." + ); + + assert_eq!(Roots::::iter_values().count(), 0); + assert_eq!(Delegations::::iter_values().count(), 0); + assert_eq!(Children::::iter_values().count(), 0); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert!(new_stored_root.children.is_empty()); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + }); + } - assert!( - migrator.post_migration().is_ok(), - "Post-migration for v0 should not fail." - ); + #[test] + fn ok_three_level_hierarchy() { + init_logger(); + let migrator = get_storage_migrator(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = + crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_parent_id = mock::get_delegation_id(false); + let old_parent_node = + crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); + let old_node_id = mock::get_delegation_id_2(true); + let old_node = crate::v0::DelegationNode::::new_node_child( + old_root_id, + old_parent_id, + bob, + Permissions::ATTEST, + ); + Roots::insert(old_root_id, old_root_node.clone()); + Delegations::insert(old_parent_id, old_parent_node.clone()); + Delegations::insert(old_node_id, old_node.clone()); + Children::::insert(old_root_id, vec![old_parent_id]); + Children::::insert(old_parent_id, vec![old_node_id]); + + assert!( + migrator.pre_migration().is_ok(), + "Pre-migration for v0 should not fail." + ); + + migrator.migrate(); + + assert!( + migrator.post_migration().is_ok(), + "Post-migration for v0 should not fail." + ); + + assert_eq!(Roots::::iter_values().count(), 0); + assert_eq!(Delegations::::iter_values().count(), 0); + assert_eq!(Children::::iter_values().count(), 0); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert_eq!(new_stored_root.children.len(), 1); + assert!(new_stored_root.children.contains(&old_parent_id)); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + + let new_stored_parent = DelegationNodes::::get(old_parent_id) + .expect("New delegation parent should exist in the storage."); + assert_eq!(new_stored_parent.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_parent.parent, Some(old_root_id)); + assert_eq!(new_stored_parent.children.len(), 1); + assert!(new_stored_parent.children.contains(&old_node_id)); + assert_eq!(new_stored_parent.details.owner, old_parent_node.owner); + assert_eq!(new_stored_parent.details.revoked, old_parent_node.revoked); + + let new_stored_node = DelegationNodes::::get(old_node_id) + .expect("New delegation node should exist in the storage."); + assert_eq!(new_stored_node.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node.parent, Some(old_parent_id)); + assert!(new_stored_node.children.is_empty()); + assert_eq!(new_stored_node.details.owner, old_node.owner); + assert_eq!(new_stored_node.details.revoked, old_node.revoked); + }); + } - assert_eq!(Roots::::iter_values().count(), 0); - assert_eq!(Delegations::::iter_values().count(), 0); - assert_eq!(Children::::iter_values().count(), 0); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) - .expect("New delegation hierarchy should exist in the storage."); - assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); - let new_stored_root = DelegationNodes::::get(old_root_id) - .expect("New delegation root should exist in the storage."); - assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); - assert!(new_stored_root.parent.is_none()); - assert_eq!(new_stored_root.children.len(), 2); - assert!(new_stored_root.children.contains(&old_node_id_1)); - assert!(new_stored_root.children.contains(&old_node_id_2)); - assert_eq!(new_stored_root.details.owner, old_root_node.owner); - assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); - - let new_stored_node_1 = DelegationNodes::::get(old_node_id_1) - .expect("New delegation 1 should exist in the storage."); - assert_eq!(new_stored_node_1.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_node_1.parent, Some(old_root_id)); - assert!(new_stored_node_1.children.is_empty()); - assert_eq!(new_stored_node_1.details.owner, old_node_1.owner); - assert_eq!(new_stored_node_1.details.revoked, old_node_1.revoked); - - let new_stored_node_2 = DelegationNodes::::get(old_node_id_2) - .expect("New delegation 2 should exist in the storage."); - assert_eq!(new_stored_node_2.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_node_2.parent, Some(old_root_id)); - assert!(new_stored_node_2.children.is_empty()); - assert_eq!(new_stored_node_2.details.owner, old_node_2.owner); - assert_eq!(new_stored_node_2.details.revoked, old_node_2.revoked); - }); - } + #[test] + fn ok_root_two_children() { + init_logger(); + let migrator = get_storage_migrator(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = + crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_node_id_1 = mock::get_delegation_id(false); + let old_node_1 = + crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); + let old_node_id_2 = mock::get_delegation_id_2(true); + let old_node_2 = + crate::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); + Roots::insert(old_root_id, old_root_node.clone()); + Delegations::insert(old_node_id_1, old_node_1.clone()); + Delegations::insert(old_node_id_2, old_node_2.clone()); + Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); + + assert!( + migrator.pre_migration().is_ok(), + "Pre-migration for v0 should not fail." + ); + + migrator.migrate(); + + assert!( + migrator.post_migration().is_ok(), + "Post-migration for v0 should not fail." + ); + + assert_eq!(Roots::::iter_values().count(), 0); + assert_eq!(Delegations::::iter_values().count(), 0); + assert_eq!(Children::::iter_values().count(), 0); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert_eq!(new_stored_root.children.len(), 2); + assert!(new_stored_root.children.contains(&old_node_id_1)); + assert!(new_stored_root.children.contains(&old_node_id_2)); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + + let new_stored_node_1 = DelegationNodes::::get(old_node_id_1) + .expect("New delegation 1 should exist in the storage."); + assert_eq!(new_stored_node_1.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node_1.parent, Some(old_root_id)); + assert!(new_stored_node_1.children.is_empty()); + assert_eq!(new_stored_node_1.details.owner, old_node_1.owner); + assert_eq!(new_stored_node_1.details.revoked, old_node_1.revoked); + + let new_stored_node_2 = DelegationNodes::::get(old_node_id_2) + .expect("New delegation 2 should exist in the storage."); + assert_eq!(new_stored_node_2.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node_2.parent, Some(old_root_id)); + assert!(new_stored_node_2.children.is_empty()); + assert_eq!(new_stored_node_2.details.owner, old_node_2.owner); + assert_eq!(new_stored_node_2.details.revoked, old_node_2.revoked); + }); + } - #[test] - fn err_already_max_migrator() { - let migrator = StorageMigrator::::new(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - LastUpgradeVersion::::set(1); - assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); - }); - } + #[test] + fn err_already_max_migrator() { + let migrator = StorageMigrator::::new(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + LastUpgradeVersion::::set(1); + assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); + }); + } - #[test] - fn err_more_than_max_migrator() { - let migrator = StorageMigrator::::new(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - LastUpgradeVersion::::set(u16::MAX); - assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); - }); + #[test] + fn err_more_than_max_migrator() { + let migrator = StorageMigrator::::new(); + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + LastUpgradeVersion::::set(u16::MAX); + assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); + }); + } } } From cbc29eb171e169aa6cc223b017b57d2d7b4303bd Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 15 Jul 2021 14:02:06 +0200 Subject: [PATCH 21/49] fix: address part of PR review comments --- pallets/delegation/src/benchmarking.rs | 7 +- .../delegation/src/delegation_hierarchy.rs | 186 +++++------------- pallets/delegation/src/deprecated.rs | 111 +++++++++++ pallets/delegation/src/lib.rs | 32 +-- pallets/delegation/src/migrations.rs | 26 +-- pallets/delegation/src/tests.rs | 14 -- 6 files changed, 187 insertions(+), 189 deletions(-) create mode 100644 pallets/delegation/src/deprecated.rs diff --git a/pallets/delegation/src/benchmarking.rs b/pallets/delegation/src/benchmarking.rs index c56c746d37..4a79cff829 100644 --- a/pallets/delegation/src/benchmarking.rs +++ b/pallets/delegation/src/benchmarking.rs @@ -103,7 +103,7 @@ where // delegate signs delegation to parent let hash: Vec = - Pallet::::calculate_delegation_hash_root(&delegation_id, &root_id, &parent_id, &permissions).encode(); + Pallet::::calculate_delegation_hash_root(&delegation_id, &parent_id, &permissions).encode(); let sig = sp_io::crypto::sr25519_sign(KeyTypeId(*b"aura"), &delegation_acc_public, hash.as_ref()) .ok_or("Error while building signature of delegation.")?; @@ -111,7 +111,6 @@ where let _ = Pallet::::add_delegation( RawOrigin::Signed(parent_acc_id.clone()).into(), delegation_id, - root_id, parent_id, delegation_acc_id.clone().into(), permissions, @@ -223,12 +222,12 @@ benchmarks! { let parent_id = leaf_id; let perm: Permissions = Permissions::ATTEST | Permissions::DELEGATE; - let hash_root = Pallet::::calculate_delegation_hash_root(&delegation_id, &hierarchy_id, &parent_id, &perm); + let hash_root = Pallet::::calculate_delegation_hash_root(&delegation_id, &parent_id, &perm); let sig = sp_io::crypto::sr25519_sign(KeyTypeId(*b"aura"), &delegate_acc_public, hash_root.as_ref()).ok_or("Error while building signature of delegation.")?; let delegate_acc_id: T::AccountId = delegate_acc_public.into(); let leaf_acc_id: T::AccountId = leaf_acc.into(); - }: _(RawOrigin::Signed(leaf_acc_id), delegation_id, hierarchy_id, parent_id, delegate_acc_id.into(), perm, MultiSignature::from(sig).encode()) + }: _(RawOrigin::Signed(leaf_acc_id), delegation_id, parent_id, delegate_acc_id.into(), perm, MultiSignature::from(sig).encode()) verify { assert!(DelegationNodes::::contains_key(delegation_id)); } diff --git a/pallets/delegation/src/delegation_hierarchy.rs b/pallets/delegation/src/delegation_hierarchy.rs index 5e45daa9b3..569113d5bf 100644 --- a/pallets/delegation/src/delegation_hierarchy.rs +++ b/pallets/delegation/src/delegation_hierarchy.rs @@ -16,9 +16,6 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org -// Publicly re-export the most recent types used. -pub use v1::*; - use bitflags::bitflags; use codec::{Decode, Encode}; use ctype::CtypeHashOf; @@ -57,158 +54,63 @@ impl Default for Permissions { } } -// The old types. -pub(crate) mod v0 { - use super::*; - - /// A node representing a delegation hierarchy root. - #[derive(Clone, Debug, Encode, Decode, PartialEq)] - pub struct DelegationRoot { - /// The hash of the CTYPE that delegated attesters within this trust - /// hierarchy can attest. - pub ctype_hash: CtypeHashOf, - /// The identifier of the root owner. - pub owner: DelegatorIdOf, - /// The flag indicating whether the root has been revoked or not. - pub revoked: bool, - } - - impl DelegationRoot { - pub fn new(ctype_hash: CtypeHashOf, owner: DelegatorIdOf) -> Self { - DelegationRoot { - ctype_hash, - owner, - revoked: false, - } - } - } - - /// A node representing a node in the delegation hierarchy. - #[derive(Clone, Debug, Encode, Decode, PartialEq)] - pub struct DelegationNode { - /// The ID of the delegation hierarchy root. - pub root_id: DelegationNodeIdOf, - /// \[OPTIONAL\] The ID of the parent node. If None, the node is - /// considered a direct child of the root node. - pub parent: Option>, - /// The identifier of the owner of the delegation node, i.e., the - /// delegate. - pub owner: DelegatorIdOf, - /// The permission flags for the operations the delegate is allowed to - /// perform. - pub permissions: Permissions, - /// The flag indicating whether the delegation has been revoked or not. - pub revoked: bool, - } - - impl DelegationNode { - /// Create a new delegation node that is a direct descendent of the - /// given root. - /// - /// * root_id: the root node ID this node will be a child of - /// * owner: the identifier of the owner of the new delegation, i.e., - /// the new delegate - /// * permissions: the permission flags for the operations the delegate - /// is allowed to perform - pub fn new_root_child( - root_id: DelegationNodeIdOf, - owner: DelegatorIdOf, - permissions: Permissions, - ) -> Self { - DelegationNode { - root_id, - owner, - permissions, - revoked: false, - parent: None, - } - } - /// Creates a new delegation node that is a direct descendent of the - /// given node. - /// - /// * root_id: the root node ID this node will be a child of - /// * parent - the parent node ID this node will be a child of - /// * owner: the identifier of the owner of the new delegation, i.e., - /// the new delegate - /// * permissions: the permission flags for the operations the delegate - /// is allowed to perform - pub fn new_node_child( - root_id: DelegationNodeIdOf, - parent: DelegationNodeIdOf, - owner: DelegatorIdOf, - permissions: Permissions, - ) -> Self { - DelegationNode { - root_id, - parent: Some(parent), - owner, - permissions, - revoked: false, - } - } - } +#[derive(Clone, Debug, Encode, Decode, PartialEq)] +pub struct DelegationNode { + pub hierarchy_root_id: DelegationNodeIdOf, + pub parent: Option>, + pub children: BTreeSet>, + pub details: DelegationDetails, } -// The new types. -pub(crate) mod v1 { - use super::*; - - #[derive(Clone, Debug, Encode, Decode, PartialEq)] - pub struct DelegationNode { - pub hierarchy_root_id: DelegationNodeIdOf, - pub parent: Option>, - pub children: BTreeSet>, - pub details: DelegationDetails, - } - - impl DelegationNode { - pub fn new_root_node(id: DelegationNodeIdOf, details: DelegationDetails) -> Self { - Self { - hierarchy_root_id: id, - parent: None, - children: BTreeSet::new(), - details, - } - } - - pub fn new_node( - hierarchy_root_id: DelegationNodeIdOf, - parent: DelegationNodeIdOf, - details: DelegationDetails, - ) -> Self { - let mut new_node = Self::new_root_node(hierarchy_root_id, details); - new_node.parent = Some(parent); - - new_node +impl DelegationNode { + pub fn new_root_node(id: DelegationNodeIdOf, details: DelegationDetails) -> Self { + Self { + hierarchy_root_id: id, + parent: None, + children: BTreeSet::new(), + details, } + } - pub fn add_child(&mut self, child_id: DelegationNodeIdOf) { - self.children.insert(child_id); + pub fn new_node( + hierarchy_root_id: DelegationNodeIdOf, + parent: DelegationNodeIdOf, + details: DelegationDetails, + ) -> Self { + Self { + hierarchy_root_id, + parent: Some(parent), + children: BTreeSet::new(), + details } } - #[derive(Clone, Debug, Encode, Decode, PartialEq)] - pub struct DelegationDetails { - pub owner: DelegatorIdOf, - pub revoked: bool, - pub permissions: Permissions, + pub fn add_child(&mut self, child_id: DelegationNodeIdOf) { + self.children.insert(child_id); } +} + +#[derive(Clone, Debug, Encode, Decode, PartialEq)] +pub struct DelegationDetails { + pub owner: DelegatorIdOf, + pub revoked: bool, + pub permissions: Permissions, +} - impl DelegationDetails { - pub fn default_with_owner(owner: DelegatorIdOf) -> Self { - Self { - owner, - permissions: Permissions::all(), - revoked: false, - } +impl DelegationDetails { + pub fn default_with_owner(owner: DelegatorIdOf) -> Self { + Self { + owner, + permissions: Permissions::all(), + revoked: false, } } +} - #[derive(Clone, Debug, Encode, Decode, Eq, PartialEq, Ord, PartialOrd)] - pub struct DelegationHierarchyInfo { - pub ctype_hash: CtypeHashOf, - } +#[derive(Clone, Debug, Encode, Decode, Eq, PartialEq, Ord, PartialOrd)] +pub struct DelegationHierarchyInfo { + pub ctype_hash: CtypeHashOf, } /// The result that the delegation pallet expects from the implementer of the diff --git a/pallets/delegation/src/deprecated.rs b/pallets/delegation/src/deprecated.rs new file mode 100644 index 0000000000..5f9f3894af --- /dev/null +++ b/pallets/delegation/src/deprecated.rs @@ -0,0 +1,111 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2021 BOTLabs GmbH + +// The KILT Blockchain is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The KILT Blockchain is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// If you feel like getting in touch with us, you can do so at info@botlabs.org + +pub(crate) mod v0 { + use codec::{Decode, Encode}; + + use crate::*; + + /// A node representing a delegation hierarchy root. + #[derive(Clone, Debug, Encode, Decode, PartialEq)] + pub struct DelegationRoot { + /// The hash of the CTYPE that delegated attesters within this trust + /// hierarchy can attest. + pub ctype_hash: CtypeHashOf, + /// The identifier of the root owner. + pub owner: DelegatorIdOf, + /// The flag indicating whether the root has been revoked or not. + pub revoked: bool, + } + + impl DelegationRoot { + pub fn new(ctype_hash: CtypeHashOf, owner: DelegatorIdOf) -> Self { + DelegationRoot { + ctype_hash, + owner, + revoked: false, + } + } + } + + /// A node representing a node in the delegation hierarchy. + #[derive(Clone, Debug, Encode, Decode, PartialEq)] + pub struct DelegationNode { + /// The ID of the delegation hierarchy root. + pub root_id: DelegationNodeIdOf, + /// \[OPTIONAL\] The ID of the parent node. If None, the node is + /// considered a direct child of the root node. + pub parent: Option>, + /// The identifier of the owner of the delegation node, i.e., the + /// delegate. + pub owner: DelegatorIdOf, + /// The permission flags for the operations the delegate is allowed to + /// perform. + pub permissions: Permissions, + /// The flag indicating whether the delegation has been revoked or not. + pub revoked: bool, + } + + impl DelegationNode { + /// Create a new delegation node that is a direct descendent of the + /// given root. + /// + /// * root_id: the root node ID this node will be a child of + /// * owner: the identifier of the owner of the new delegation, i.e., + /// the new delegate + /// * permissions: the permission flags for the operations the delegate + /// is allowed to perform + pub fn new_root_child( + root_id: DelegationNodeIdOf, + owner: DelegatorIdOf, + permissions: Permissions, + ) -> Self { + DelegationNode { + root_id, + owner, + permissions, + revoked: false, + parent: None, + } + } + + /// Creates a new delegation node that is a direct descendent of the + /// given node. + /// + /// * root_id: the root node ID this node will be a child of + /// * parent - the parent node ID this node will be a child of + /// * owner: the identifier of the owner of the new delegation, i.e., + /// the new delegate + /// * permissions: the permission flags for the operations the delegate + /// is allowed to perform + pub fn new_node_child( + root_id: DelegationNodeIdOf, + parent: DelegationNodeIdOf, + owner: DelegatorIdOf, + permissions: Permissions, + ) -> Self { + DelegationNode { + root_id, + parent: Some(parent), + owner, + permissions, + revoked: false, + } + } + } +} diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 49754bbd9c..7bb1297553 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -35,6 +35,8 @@ pub mod benchmarking; #[cfg(test)] mod tests; +mod deprecated; + pub use crate::{default_weights::WeightInfo, delegation_hierarchy::*, pallet::*}; use frame_support::{ensure, pallet_prelude::Weight, traits::Get}; @@ -114,7 +116,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn roots)] pub type Roots = - StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, delegation_hierarchy::v0::DelegationRoot>; + StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, deprecated::v0::DelegationRoot>; /// Delegation nodes stored on chain. DEPRECATED. /// @@ -122,7 +124,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn delegations)] pub type Delegations = - StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, delegation_hierarchy::v0::DelegationNode>; + StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, deprecated::v0::DelegationNode>; /// Children delegation nodes. DEPRECATED. /// @@ -244,6 +246,8 @@ pub mod pallet { >::CTypeNotFound ); + log::debug!("insert Delegation Root"); + Self::create_and_store_new_hierarchy( root_node_id, DelegationHierarchyInfo:: { ctype_hash }, @@ -264,8 +268,6 @@ pub mod pallet { /// * origin: the identifier of the delegation creator /// * delegation_id: the ID of the new delegation node. It has to be /// unique - /// * root_id: the ID of the delegation hierarchy root to add this - /// delegation to /// * parent_id: \[OPTIONAL\] The ID of the parent node to verify that /// the creator is allowed to create a new delegation. If None, the /// verification is performed against the provided root node @@ -278,7 +280,6 @@ pub mod pallet { pub fn add_delegation( origin: OriginFor, delegation_id: DelegationNodeIdOf, - root_node_id: DelegationNodeIdOf, parent_id: DelegationNodeIdOf, delegate: DelegatorIdOf, permissions: Permissions, @@ -288,7 +289,7 @@ pub mod pallet { // Calculate the hash root let hash_root = - Self::calculate_delegation_hash_root(&delegation_id, &root_node_id, &parent_id, &permissions); + Self::calculate_delegation_creation_hash(&delegation_id, &parent_id, &permissions); // Verify that the hash root signature is correct. DelegationSignatureVerificationOf::::verify(&delegate, &hash_root.encode(), &delegate_signature) @@ -303,6 +304,7 @@ pub mod pallet { ); let parent_node = >::get(&parent_id).ok_or(Error::::ParentDelegationNotFound)?; + let hierarchy_root_id = parent_node.hierarchy_root_id; // Check if the parent's delegate is the creator of this delegation node... ensure!( @@ -318,25 +320,25 @@ pub mod pallet { Self::store_delegation_under_parent( delegation_id, DelegationNode::new_node( - root_node_id, + hierarchy_root_id, parent_id, DelegationDetails { owner: delegate.clone(), permissions, revoked: false, - }, + } ), parent_id, - parent_node, + parent_node ); Self::deposit_event(Event::DelegationCreated( delegator, - root_node_id, + hierarchy_root_id, delegation_id, parent_id, delegate, - permissions, + permissions )); Ok(()) @@ -458,16 +460,14 @@ pub mod pallet { } impl Pallet { - // Calculate the hash of all values of a delegation transaction - fn calculate_delegation_hash_root( + // Calculate the hash of all values of a delegation creation transaction + fn calculate_delegation_creation_hash( delegation_id: &DelegationNodeIdOf, - root_id: &DelegationNodeIdOf, parent_id: &DelegationNodeIdOf, permissions: &Permissions, ) -> T::Hash { - // Add all values to an u8 vector + // Add all values to an u8 vector. let mut hashed_values: Vec = delegation_id.as_ref().to_vec(); - hashed_values.extend_from_slice(root_id.as_ref()); hashed_values.extend_from_slice(parent_id.as_ref()); hashed_values.extend_from_slice(permissions.as_u8().as_ref()); // Hash the resulting vector diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index da1f9c64d2..92687c198a 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -45,7 +45,7 @@ pub(crate) enum DelegationMigrationError { // The "manager" of the pallet's storage migrations. It contains a vector of // version migrations each of which corresponds to a new runtime upgrade to run, -// sequencially. It interacts with the `LastUpgradeVersion` of the pallet's +// sequentially. It interacts with the `LastUpgradeVersion` of the pallet's // storage. // // When a new runtime upgrade needs to be added, a new component implementing @@ -76,9 +76,9 @@ impl StorageMigrator { Ok(()) } - // It retrieves the latest version deployed on chain, and sequencially applies - // any runtime migration until the state is update to the latest version. - // It provides a test feature that panics whenver something goes wrong for one + // It retrieves the latest version deployed on chain, and sequentially applies + // any runtime migration until the state is updated to the latest version. + // It provides a test feature that panics whenever something goes wrong for one // of the version migrators, but in production it is just assumed that all the // migrations will go through. pub(crate) fn migrate(&self) -> Weight { @@ -172,7 +172,7 @@ mod v0 { if let Some(root_children_ids) = Children::::take(old_root_id) { new_root_node.children = root_children_ids.iter().copied().collect(); } - // Add Chilred::take() weight + // Add Children::take() weight total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); DelegationHierarchies::insert(old_root_id, new_hierarchy_info); @@ -196,7 +196,7 @@ mod v0 { if let Some(children_ids) = Children::::take(old_node_id) { new_node.children = children_ids.iter().copied().collect(); } - // Add Chilred::take() weight + // Add Children::take() weight total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); // Adds a read from Roots::drain() weight total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); @@ -282,7 +282,7 @@ mod v0 { let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); let old_root_id = mock::get_delegation_id(true); let old_root_node = - crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); + crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); Roots::insert(old_root_id, old_root_node.clone()); assert!( @@ -324,12 +324,12 @@ mod v0 { let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); let old_root_id = mock::get_delegation_id(true); let old_root_node = - crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); let old_parent_id = mock::get_delegation_id(false); let old_parent_node = - crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); + crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); let old_node_id = mock::get_delegation_id_2(true); - let old_node = crate::v0::DelegationNode::::new_node_child( + let old_node = crate::deprecated::v0::DelegationNode::::new_node_child( old_root_id, old_parent_id, bob, @@ -398,13 +398,13 @@ mod v0 { let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); let old_root_id = mock::get_delegation_id(true); let old_root_node = - crate::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); let old_node_id_1 = mock::get_delegation_id(false); let old_node_1 = - crate::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); + crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); let old_node_id_2 = mock::get_delegation_id_2(true); let old_node_2 = - crate::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); + crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); Roots::insert(old_root_id, old_root_node.clone()); Delegations::insert(old_node_id_1, old_node_1.clone()); Delegations::insert(old_node_id_2, old_node_2.clone()); diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index ac0425fcf9..db68256716 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -130,7 +130,6 @@ fn create_delegation_direct_root_successful() { let delegation_info = Delegation::calculate_delegation_hash_root( &delegation_id, - &delegation_node.hierarchy_root_id, &hierarchy_root_id, &delegation_node.details.permissions, ); @@ -151,7 +150,6 @@ fn create_delegation_direct_root_successful() { assert_ok!(Delegation::add_delegation( get_origin(creator.clone()), operation.delegation_id, - operation.hierarchy_id, operation.parent_id, operation.delegate.clone(), operation.permissions, @@ -200,7 +198,6 @@ fn create_delegation_with_parent_successful() { let delegation_info = Delegation::calculate_delegation_hash_root( &delegation_id, - &delegation_node.hierarchy_root_id, &parent_id, &delegation_node.details.permissions, ); @@ -222,7 +219,6 @@ fn create_delegation_with_parent_successful() { assert_ok!(Delegation::add_delegation( get_origin(creator.clone()), operation.delegation_id, - operation.hierarchy_id, operation.parent_id, operation.delegate.clone(), operation.permissions, @@ -268,7 +264,6 @@ fn invalid_delegate_signature_create_delegation_error() { let delegate_signature = alternative_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( &delegation_id, - &delegation_node.hierarchy_root_id, &hierarchy_root_id, &delegation_node.details.permissions, ))); @@ -288,7 +283,6 @@ fn invalid_delegate_signature_create_delegation_error() { Delegation::add_delegation( get_origin(creator.clone()), operation.delegation_id, - operation.hierarchy_id, operation.parent_id, delegate.clone(), operation.permissions, @@ -317,7 +311,6 @@ fn duplicate_delegation_create_delegation_error() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( &delegation_id, - &delegation_node.hierarchy_root_id, &hierarchy_root_id, &delegation_node.details.permissions, ))); @@ -338,7 +331,6 @@ fn duplicate_delegation_create_delegation_error() { Delegation::add_delegation( get_origin(creator.clone()), operation.delegation_id, - operation.hierarchy_id, operation.parent_id, delegate.clone(), operation.permissions, @@ -367,7 +359,6 @@ fn parent_not_existing_create_delegation_error() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( &delegation_id, - &delegation_node.hierarchy_root_id, &hierarchy_root_id, &delegation_node.details.permissions, ))); @@ -386,7 +377,6 @@ fn parent_not_existing_create_delegation_error() { Delegation::add_delegation( get_origin(creator.clone()), operation.delegation_id, - operation.hierarchy_id, operation.parent_id, delegate.clone(), operation.permissions, @@ -421,7 +411,6 @@ fn not_owner_of_parent_create_delegation_error() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( &delegation_id, - &delegation_node.hierarchy_root_id, &parent_id, &delegation_node.details.permissions, ))); @@ -442,7 +431,6 @@ fn not_owner_of_parent_create_delegation_error() { Delegation::add_delegation( get_origin(creator.clone()), operation.delegation_id, - operation.hierarchy_id, operation.parent_id, delegate.clone(), operation.permissions, @@ -476,7 +464,6 @@ fn unauthorised_delegation_create_delegation_error() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( &delegation_id, - &delegation_node.hierarchy_root_id, &parent_id, &delegation_node.details.permissions, ))); @@ -497,7 +484,6 @@ fn unauthorised_delegation_create_delegation_error() { Delegation::add_delegation( get_origin(creator.clone()), operation.delegation_id, - operation.hierarchy_id, operation.parent_id, delegate.clone(), operation.permissions, From ad732b30653b5e750a91be2234e802455fa333f9 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 15 Jul 2021 14:38:41 +0200 Subject: [PATCH 22/49] fix: more comments from PR review --- pallets/delegation/src/benchmarking.rs | 4 ++-- pallets/delegation/src/migrations.rs | 20 +++++++++++++++++--- pallets/delegation/src/tests.rs | 14 +++++++------- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/pallets/delegation/src/benchmarking.rs b/pallets/delegation/src/benchmarking.rs index 4a79cff829..13edb6352d 100644 --- a/pallets/delegation/src/benchmarking.rs +++ b/pallets/delegation/src/benchmarking.rs @@ -103,7 +103,7 @@ where // delegate signs delegation to parent let hash: Vec = - Pallet::::calculate_delegation_hash_root(&delegation_id, &parent_id, &permissions).encode(); + Pallet::::calculate_delegation_creation_hash(&delegation_id, &parent_id, &permissions).encode(); let sig = sp_io::crypto::sr25519_sign(KeyTypeId(*b"aura"), &delegation_acc_public, hash.as_ref()) .ok_or("Error while building signature of delegation.")?; @@ -222,7 +222,7 @@ benchmarks! { let parent_id = leaf_id; let perm: Permissions = Permissions::ATTEST | Permissions::DELEGATE; - let hash_root = Pallet::::calculate_delegation_hash_root(&delegation_id, &parent_id, &perm); + let hash_root = Pallet::::calculate_delegation_creation_hash(&delegation_id, &parent_id, &perm); let sig = sp_io::crypto::sr25519_sign(KeyTypeId(*b"aura"), &delegate_acc_public, hash_root.as_ref()).ok_or("Error while building signature of delegation.")?; let delegate_acc_id: T::AccountId = delegate_acc_public.into(); diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 92687c198a..fac2aac91b 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -29,7 +29,7 @@ use crate::*; const LATEST_UPGRADEABLE_VERSION: u16 = 0; // The trait that each version migrator must implement. -trait VersionMigrator { +trait VersionMigrator { #[cfg(feature = "try-runtime")] fn pre_migrate(&self) -> Result<(), DelegationMigrationError>; fn migrate(&self) -> Weight; @@ -37,6 +37,7 @@ trait VersionMigrator { fn post_migrate(&self) -> Result<(), DelegationMigrationError>; } +#[allow(dead_code)] #[derive(Clone, Copy, Debug)] pub(crate) enum DelegationMigrationError { AlreadyLatest, @@ -52,7 +53,7 @@ pub(crate) enum DelegationMigrationError { // the `VersionMigrator` trait must be defined and added at the end of the // `migrations` vector, so that it is always executed after all // previous migrations have taken place. -pub(crate) struct StorageMigrator { +pub(crate) struct StorageMigrator { // The vector of version migrators. migrations: Vec>>, } @@ -127,6 +128,10 @@ impl StorageMigrator { mod v0 { use super::*; + + #[cfg(feature = "try-runtime")] + use sp_runtime::traits::Zero; + // Migrator for the first actual pallet's migration. It migrates the Roots, // Delegations, and Children storage entries to a simpler HierarchyInfos, // DelegationNodes, while maintaining the original information an all @@ -137,7 +142,7 @@ mod v0 { #[cfg(feature = "try-runtime")] fn pre_migrate(&self) -> Result<(), DelegationMigrationError> { ensure!( - LastUpgradeVersion::::get() == 0, + LastUpgradeVersion::::get().is_zero(), DelegationMigrationError::AlreadyLatest ); log::info!("Version storage migrating from v0 to v1"); @@ -234,6 +239,15 @@ mod v0 { LastUpgradeVersion::::get() == 1, DelegationMigrationError::MigrationResultInconsistent ); + for (node_id, node) in DelegationNodes::::iter() { + if let Some(parent_id) = node.parent { + let parent_node = DelegationNodes::::get(parent_id).expect("Parent node should be in the storage."); + ensure!( + parent_node.children.contains(&node_id), + DelegationMigrationError::MigrationResultInconsistent + ); + } + } log::info!("Version storage migrated from v0 to v1"); Ok(()) } diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index db68256716..3584a5b800 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -128,7 +128,7 @@ fn create_delegation_direct_root_successful() { generate_base_delegation_node(hierarchy_root_id, delegate, Some(hierarchy_root_id)), ); - let delegation_info = Delegation::calculate_delegation_hash_root( + let delegation_info = Delegation::calculate_delegation_creation_hash( &delegation_id, &hierarchy_root_id, &delegation_node.details.permissions, @@ -196,7 +196,7 @@ fn create_delegation_with_parent_successful() { generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id)), ); - let delegation_info = Delegation::calculate_delegation_hash_root( + let delegation_info = Delegation::calculate_delegation_creation_hash( &delegation_id, &parent_id, &delegation_node.details.permissions, @@ -262,7 +262,7 @@ fn invalid_delegate_signature_create_delegation_error() { generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id)), ); - let delegate_signature = alternative_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( + let delegate_signature = alternative_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_creation_hash( &delegation_id, &hierarchy_root_id, &delegation_node.details.permissions, @@ -309,7 +309,7 @@ fn duplicate_delegation_create_delegation_error() { generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id)), ); - let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( + let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_creation_hash( &delegation_id, &hierarchy_root_id, &delegation_node.details.permissions, @@ -357,7 +357,7 @@ fn parent_not_existing_create_delegation_error() { generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id)), ); - let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( + let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_creation_hash( &delegation_id, &hierarchy_root_id, &delegation_node.details.permissions, @@ -409,7 +409,7 @@ fn not_owner_of_parent_create_delegation_error() { generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id)), ); - let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( + let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_creation_hash( &delegation_id, &parent_id, &delegation_node.details.permissions, @@ -462,7 +462,7 @@ fn unauthorised_delegation_create_delegation_error() { generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id)), ); - let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_hash_root( + let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_creation_hash( &delegation_id, &parent_id, &delegation_node.details.permissions, From 91cfc82a5c3f933924681629c9186f97fb5bd695 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 15 Jul 2021 15:58:34 +0200 Subject: [PATCH 23/49] wip: change vector of versions to enum --- pallets/delegation/src/lib.rs | 19 +- pallets/delegation/src/migrations.rs | 819 +++++++++++++-------------- 2 files changed, 405 insertions(+), 433 deletions(-) diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 7bb1297553..532cbd9de3 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -43,8 +43,11 @@ use frame_support::{ensure, pallet_prelude::Weight, traits::Get}; use sp_runtime::{traits::Hash, DispatchError}; use sp_std::vec::Vec; +use migrations::*; + #[frame_support::pallet] pub mod pallet { + use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; @@ -93,20 +96,16 @@ pub mod pallet { impl Hooks> for Pallet { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { - migrations::StorageMigrator::::new() - .pre_migration() - .map_err(|_| "pre-migration failed") + migrations::DelegationStorageMigration::::pre_migrate() } fn on_runtime_upgrade() -> Weight { - migrations::StorageMigrator::::new().migrate() + migrations::DelegationStorageMigration::::migrate() } #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { - migrations::StorageMigrator::::new() - .post_migration() - .map_err(|_| "post-migration failed") + migrations::DelegationStorageMigration::::post_migrate() } } @@ -134,10 +133,10 @@ pub mod pallet { #[pallet::getter(fn children)] pub type Children = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, Vec>>; - /// Contains the version of the latest runtime upgrade performed. + /// Contains the latest version migrator used. #[pallet::storage] - #[pallet::getter(fn last_upgrade_version)] - pub(crate) type LastUpgradeVersion = StorageValue<_, u16, ValueQuery>; + #[pallet::getter(fn last_version_migration_used)] + pub(crate) type LastVersionMigrationUsed = StorageValue<_, DelegationStorageVersion, ValueQuery>; /// Delegation nodes stored on chain. /// diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index fac2aac91b..fc6c1ff908 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -16,7 +16,10 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org -use sp_std::{boxed::Box, collections::btree_map::BTreeMap, vec}; +use sp_std::marker::PhantomData; + +use codec::{Decode, Encode}; +use sp_std::collections::btree_map::BTreeMap; use crate::*; @@ -26,469 +29,439 @@ use crate::*; // This needs to be bumped (by 1) every time a new storage migration should take // place. Along with this, a new version migrator must be defined and added to // the `migrations` vector or the `StorageMigrator`. -const LATEST_UPGRADEABLE_VERSION: u16 = 0; -// The trait that each version migrator must implement. -trait VersionMigrator { +pub trait VersionMigratorTrait { #[cfg(feature = "try-runtime")] - fn pre_migrate(&self) -> Result<(), DelegationMigrationError>; + fn pre_migrate(&self) -> Result<(), &str>; fn migrate(&self) -> Weight; #[cfg(feature = "try-runtime")] - fn post_migrate(&self) -> Result<(), DelegationMigrationError>; + fn post_migrate(&self) -> Result<(), &str>; } -#[allow(dead_code)] -#[derive(Clone, Copy, Debug)] -pub(crate) enum DelegationMigrationError { - AlreadyLatest, - MigrationResultInconsistent, +#[allow(non_camel_case_types)] +#[derive(Encode, Eq, Decode, PartialEq)] +pub enum DelegationStorageVersion { + v1, v2 } -// The "manager" of the pallet's storage migrations. It contains a vector of -// version migrations each of which corresponds to a new runtime upgrade to run, -// sequentially. It interacts with the `LastUpgradeVersion` of the pallet's -// storage. -// -// When a new runtime upgrade needs to be added, a new component implementing -// the `VersionMigrator` trait must be defined and added at the end of the -// `migrations` vector, so that it is always executed after all -// previous migrations have taken place. -pub(crate) struct StorageMigrator { - // The vector of version migrators. - migrations: Vec>>, +impl Default for DelegationStorageVersion { + fn default() -> Self { + Self::v2 + } } -impl StorageMigrator { - pub(crate) fn new() -> Self { - Self { - migrations: vec![Box::new(v0::V0Migrator {})], +impl DelegationStorageVersion { + pub(crate) fn get_next_version_migrator(&self) -> Option { + match *self { + Self::v1 => Some(Self::v2), + _ => None } } +} - // Checks whether there is at least one storage migration to perform. - #[cfg(any(feature = "try-runtime", test))] - #[allow(clippy::absurd_extreme_comparisons)] - pub(crate) fn pre_migration(&self) -> Result<(), DelegationMigrationError> { - ensure!( - LastUpgradeVersion::::get() <= migrations::LATEST_UPGRADEABLE_VERSION, - DelegationMigrationError::AlreadyLatest - ); +impl VersionMigratorTrait for DelegationStorageVersion { - Ok(()) + #[cfg(feature = "try-runtime")] + fn pre_migrate(&self) -> Result<(), &str> { + match *self { + Self::v1 => Self::pre_migrate_v1::(), + _ => Ok(()) + } } - // It retrieves the latest version deployed on chain, and sequentially applies - // any runtime migration until the state is updated to the latest version. - // It provides a test feature that panics whenever something goes wrong for one - // of the version migrators, but in production it is just assumed that all the - // migrations will go through. - pub(crate) fn migrate(&self) -> Weight { - let mut total_weight_used: Weight = 0; - let current_version = LastUpgradeVersion::::get(); - // Applies all the needed migration from the current version up to - // LATEST_UPGRADEABLE_VERSION (which is always the latest possible version - 1). - for version in current_version..=LATEST_UPGRADEABLE_VERSION { - // It is assumed that the are exactly LATEST_UPGRADEABLE_VERSION+1 migrators, so - // as long as the pre-condition is met, the following is assumed to never panic. - let version_migrator: &dyn VersionMigrator = self.migrations[version as usize].as_ref(); - // Test pre-conditions (only in testing) for each version migrator. - #[cfg(feature = "try-runtime")] - if let Err(err) = version_migrator.pre_migrate() { - panic!("{:?}", err); - } - // Apply the migration and keep adding the weight. - total_weight_used = total_weight_used.saturating_add(version_migrator.migrate()); - // Test post-conditions (only in testing) for each version migrator. - #[cfg(feature = "try-runtime")] - if let Err(err) = version_migrator.post_migrate() { - panic!("{:?}", err); - } + fn migrate(&self) -> Weight { + match *self { + Self::v1 => Self::migrate_v1::(), + _ => 0u64 } - // Set a version number that is not upgradeable anymore until a new version is - // available, which means that the new version will be - // LATEST_UPGRADEABLE_VERSION + 1. - LastUpgradeVersion::::set(LATEST_UPGRADEABLE_VERSION.saturating_add(1)); + } - // Add a DB read and write for the LastUpgradeVersion storage update - total_weight_used.saturating_add(T::DbWeight::get().reads_writes(1, 1)) + #[cfg(feature = "try-runtime")] + fn post_migrate(&self) -> Result<(), &str> { + match *self { + Self::v1 => Self::post_migrate_v1::(), + _ => Ok(()) + } } +} - // Checks whether the upgrade as a whole went through by verifying that the - // latest version set it not upgradeable anymore. - #[cfg(any(feature = "try-runtime", test))] - pub(crate) fn post_migration(&self) -> Result<(), DelegationMigrationError> { +// v0 functions +impl DelegationStorageVersion { + #[cfg(feature = "try-runtime")] + fn pre_migrate_v1() -> Result<(), &str> { ensure!( - LastUpgradeVersion::::get() == migrations::LATEST_UPGRADEABLE_VERSION.saturating_add(1), - DelegationMigrationError::MigrationResultInconsistent + LastVersionMigrationUsed::::get() == Self::v1, + "Current deployed version is not v1." ); - + log::info!("Version storage migrating from v1 to v2"); Ok(()) } -} - -mod v0 { - use super::*; - #[cfg(feature = "try-runtime")] - use sp_runtime::traits::Zero; - - // Migrator for the first actual pallet's migration. It migrates the Roots, - // Delegations, and Children storage entries to a simpler HierarchyInfos, - // DelegationNodes, while maintaining the original information an all - // parent-child links. - pub struct V0Migrator(); - - impl VersionMigrator for V0Migrator { - #[cfg(feature = "try-runtime")] - fn pre_migrate(&self) -> Result<(), DelegationMigrationError> { - ensure!( - LastUpgradeVersion::::get().is_zero(), - DelegationMigrationError::AlreadyLatest - ); - log::info!("Version storage migrating from v0 to v1"); - Ok(()) - } - - fn migrate(&self) -> Weight { - log::info!("v0 -> v1 delegation storage migrator started!"); - let mut total_weight = 0u64; - - // Before being stored, the nodes are saved in a map so that after we go over - // all the nodes and the parent-child relationship in the storage, we can update - // the `parent` link of each node accordingly. Otherwise, it would be possible - // that a node does not exist when fetched from the Children storage entry. - let mut new_nodes: BTreeMap, DelegationNode> = BTreeMap::new(); - - // First iterate over the delegation roots and translate them to hierarchies. - for (old_root_id, old_root_node) in Roots::::drain() { - let new_hierarchy_info = DelegationHierarchyInfo:: { - ctype_hash: old_root_node.ctype_hash, - }; - let new_root_details = DelegationDetails:: { - owner: old_root_node.owner, - // Old roots did not have any permissions. So now we give them all permissions. - permissions: Permissions::all(), - revoked: old_root_node.revoked, - }; - // In here, we already check for potential children of root nodes and ONLY - // update the children information. The parent information will be updated - // later, when we know we have seen all the children already. - let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); - if let Some(root_children_ids) = Children::::take(old_root_id) { - new_root_node.children = root_children_ids.iter().copied().collect(); - } - // Add Children::take() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - - DelegationHierarchies::insert(old_root_id, new_hierarchy_info); - // Adds a read from Roots::drain() and a write from - // DelegationHierarchies::insert() weights - total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); - new_nodes.insert(old_root_id, new_root_node); + fn migrate_v1() -> Weight { + log::info!("v1 -> v2 delegation storage migrator started!"); + let mut total_weight = 0u64; + + // Before being stored, the nodes are saved in a map so that after we go over + // all the nodes and the parent-child relationship in the storage, we can update + // the `parent` link of each node accordingly. Otherwise, it would be possible + // that a node does not exist when fetched from the Children storage entry. + let mut new_nodes: BTreeMap, DelegationNode> = BTreeMap::new(); + + // First iterate over the delegation roots and translate them to hierarchies. + for (old_root_id, old_root_node) in Roots::::drain() { + let new_hierarchy_info = DelegationHierarchyInfo:: { + ctype_hash: old_root_node.ctype_hash, + }; + let new_root_details = DelegationDetails:: { + owner: old_root_node.owner, + // Old roots did not have any permissions. So now we give them all permissions. + permissions: Permissions::all(), + revoked: old_root_node.revoked, + }; + // In here, we already check for potential children of root nodes and ONLY + // update the children information. The parent information will be updated + // later, when we know we have seen all the children already. + let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); + if let Some(root_children_ids) = Children::::take(old_root_id) { + new_root_node.children = root_children_ids.iter().copied().collect(); } + // Add Children::take() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + + DelegationHierarchies::insert(old_root_id, new_hierarchy_info); + // Adds a read from Roots::drain() and a write from + // DelegationHierarchies::insert() weights + total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + new_nodes.insert(old_root_id, new_root_node); + } - // Then iterate over the regular delegation nodes. - for (old_node_id, old_node) in Delegations::::drain() { - let new_node_details = DelegationDetails:: { - owner: old_node.owner, - permissions: old_node.permissions, - revoked: old_node.revoked, - }; - // In the old version, a parent None indicated the node is a child of the root. - let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); - let mut new_node = - DelegationNode::::new_node(old_node.root_id, new_node_parent_id, new_node_details); - if let Some(children_ids) = Children::::take(old_node_id) { - new_node.children = children_ids.iter().copied().collect(); - } - // Add Children::take() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - // Adds a read from Roots::drain() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - new_nodes.insert(old_node_id, new_node); + // Then iterate over the regular delegation nodes. + for (old_node_id, old_node) in Delegations::::drain() { + let new_node_details = DelegationDetails:: { + owner: old_node.owner, + permissions: old_node.permissions, + revoked: old_node.revoked, + }; + // In the old version, a parent None indicated the node is a child of the root. + let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); + let mut new_node = + DelegationNode::::new_node(old_node.root_id, new_node_parent_id, new_node_details); + if let Some(children_ids) = Children::::take(old_node_id) { + new_node.children = children_ids.iter().copied().collect(); } + // Add Children::take() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + // Adds a read from Roots::drain() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + new_nodes.insert(old_node_id, new_node); + } - // By now, all the children should have been correctly added to the nodes. - // We now need to modify all the nodes that are children by adding a reference - // to their parents. - for (new_node_id, new_node) in new_nodes.clone().into_iter() { - // FIXME: new_node.children.iter().cloned() might be possibly changed to - // iter_mut. - for child_id in new_node.children.iter().cloned() { - new_nodes - .entry(child_id) - .and_modify(|node| node.parent = Some(new_node_id)); - } - // We can then finally insert the new delegation node in the storage. - DelegationNodes::::insert(new_node_id, new_node); - // Adds a write from DelegationNodes::insert() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + // By now, all the children should have been correctly added to the nodes. + // We now need to modify all the nodes that are children by adding a reference + // to their parents. + for (new_node_id, new_node) in new_nodes.clone().into_iter() { + // FIXME: new_node.children.iter().cloned() might be possibly changed to + // iter_mut. + for child_id in new_node.children.iter().cloned() { + new_nodes + .entry(child_id) + .and_modify(|node| node.parent = Some(new_node_id)); } - - LastUpgradeVersion::::set(1); - // Adds a write from LastUpgradeVersion::set() weight + // We can then finally insert the new delegation node in the storage. + DelegationNodes::::insert(new_node_id, new_node); + // Adds a write from DelegationNodes::insert() weight total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - log::debug!("Total weight consumed: {}", total_weight); - log::info!("v0 -> v1 delegation storage migrator finished!"); - total_weight } - #[cfg(feature = "try-runtime")] - fn post_migrate(&self) -> Result<(), DelegationMigrationError> { - ensure!( - LastUpgradeVersion::::get() == 1, - DelegationMigrationError::MigrationResultInconsistent - ); - for (node_id, node) in DelegationNodes::::iter() { - if let Some(parent_id) = node.parent { - let parent_node = DelegationNodes::::get(parent_id).expect("Parent node should be in the storage."); - ensure!( - parent_node.children.contains(&node_id), - DelegationMigrationError::MigrationResultInconsistent - ); - } - } - log::info!("Version storage migrated from v0 to v1"); - Ok(()) - } + LastVersionMigrationUsed::::set(Self::v2); + // Adds a write from LastUpgradeVersion::set() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + log::debug!("Total weight consumed: {}", total_weight); + log::info!("v1 -> v2 delegation storage migrator finished!"); + total_weight } - #[cfg(test)] - mod tests { - use super::*; - - use mock::Test as TestRuntime; - use sp_core::Pair; - - fn get_storage_migrator() -> StorageMigrator { - StorageMigrator::::new() - } - - fn init_logger() { - let _ = env_logger::builder().is_test(true).try_init(); - } - - #[test] - fn ok_no_delegations() { - let migrator = get_storage_migrator(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - assert!( - migrator.pre_migration().is_ok(), - "Pre-migration for v0 should not fail." - ); - - migrator.migrate(); - - assert!( - migrator.post_migration().is_ok(), - "Post-migration for v0 should not fail." - ); - }); - } - - #[test] - fn ok_only_root() { - init_logger(); - let migrator = get_storage_migrator(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); - let old_root_id = mock::get_delegation_id(true); - let old_root_node = - crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); - Roots::insert(old_root_id, old_root_node.clone()); - - assert!( - migrator.pre_migration().is_ok(), - "Pre-migration for v0 should not fail." - ); - - migrator.migrate(); - - assert!( - migrator.post_migration().is_ok(), - "Post-migration for v0 should not fail." - ); - - assert_eq!(Roots::::iter_values().count(), 0); - assert_eq!(Delegations::::iter_values().count(), 0); - assert_eq!(Children::::iter_values().count(), 0); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) - .expect("New delegation hierarchy should exist in the storage."); - assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); - let new_stored_root = DelegationNodes::::get(old_root_id) - .expect("New delegation root should exist in the storage."); - assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); - assert!(new_stored_root.parent.is_none()); - assert!(new_stored_root.children.is_empty()); - assert_eq!(new_stored_root.details.owner, old_root_node.owner); - assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); - }); - } - - #[test] - fn ok_three_level_hierarchy() { - init_logger(); - let migrator = get_storage_migrator(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); - let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); - let old_root_id = mock::get_delegation_id(true); - let old_root_node = - crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); - let old_parent_id = mock::get_delegation_id(false); - let old_parent_node = - crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); - let old_node_id = mock::get_delegation_id_2(true); - let old_node = crate::deprecated::v0::DelegationNode::::new_node_child( - old_root_id, - old_parent_id, - bob, - Permissions::ATTEST, - ); - Roots::insert(old_root_id, old_root_node.clone()); - Delegations::insert(old_parent_id, old_parent_node.clone()); - Delegations::insert(old_node_id, old_node.clone()); - Children::::insert(old_root_id, vec![old_parent_id]); - Children::::insert(old_parent_id, vec![old_node_id]); - - assert!( - migrator.pre_migration().is_ok(), - "Pre-migration for v0 should not fail." - ); - - migrator.migrate(); - - assert!( - migrator.post_migration().is_ok(), - "Post-migration for v0 should not fail." + fn post_migrate_v1() -> Result<(), &'static str> { + ensure!( + LastVersionMigrationUsed::::get() == Self::v2, + "The version after deployment is not 2 as expected." + ); + for (node_id, node) in DelegationNodes::::iter() { + if let Some(parent_id) = node.parent { + let parent_node = DelegationNodes::::get(parent_id).expect("Parent node should be in the storage."); + ensure!( + parent_node.children.contains(&node_id), + "Parent-child wrong" ); - - assert_eq!(Roots::::iter_values().count(), 0); - assert_eq!(Delegations::::iter_values().count(), 0); - assert_eq!(Children::::iter_values().count(), 0); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) - .expect("New delegation hierarchy should exist in the storage."); - assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); - let new_stored_root = DelegationNodes::::get(old_root_id) - .expect("New delegation root should exist in the storage."); - assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); - assert!(new_stored_root.parent.is_none()); - assert_eq!(new_stored_root.children.len(), 1); - assert!(new_stored_root.children.contains(&old_parent_id)); - assert_eq!(new_stored_root.details.owner, old_root_node.owner); - assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); - - let new_stored_parent = DelegationNodes::::get(old_parent_id) - .expect("New delegation parent should exist in the storage."); - assert_eq!(new_stored_parent.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_parent.parent, Some(old_root_id)); - assert_eq!(new_stored_parent.children.len(), 1); - assert!(new_stored_parent.children.contains(&old_node_id)); - assert_eq!(new_stored_parent.details.owner, old_parent_node.owner); - assert_eq!(new_stored_parent.details.revoked, old_parent_node.revoked); - - let new_stored_node = DelegationNodes::::get(old_node_id) - .expect("New delegation node should exist in the storage."); - assert_eq!(new_stored_node.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_node.parent, Some(old_parent_id)); - assert!(new_stored_node.children.is_empty()); - assert_eq!(new_stored_node.details.owner, old_node.owner); - assert_eq!(new_stored_node.details.revoked, old_node.revoked); - }); + } } + log::info!("Version storage migrated from v1 to v2"); + Ok(()) + } +} - #[test] - fn ok_root_two_children() { - init_logger(); - let migrator = get_storage_migrator(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); - let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); - let old_root_id = mock::get_delegation_id(true); - let old_root_node = - crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); - let old_node_id_1 = mock::get_delegation_id(false); - let old_node_1 = - crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); - let old_node_id_2 = mock::get_delegation_id_2(true); - let old_node_2 = - crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); - Roots::insert(old_root_id, old_root_node.clone()); - Delegations::insert(old_node_id_1, old_node_1.clone()); - Delegations::insert(old_node_id_2, old_node_2.clone()); - Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); - - assert!( - migrator.pre_migration().is_ok(), - "Pre-migration for v0 should not fail." - ); - - migrator.migrate(); +pub struct DelegationStorageMigration(PhantomData); - assert!( - migrator.post_migration().is_ok(), - "Post-migration for v0 should not fail." - ); +impl DelegationStorageMigration { + #[cfg(feature = "try-runtime")] + pub(crate) fn pre_migrate() -> Result<(), &str> { + ensure!( + LastVersionMigrationUsed::get() != DelegationStorageVersion::default(), + "Already the latest (default) storage migrator." + ); + } - assert_eq!(Roots::::iter_values().count(), 0); - assert_eq!(Delegations::::iter_values().count(), 0); - assert_eq!(Children::::iter_values().count(), 0); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) - .expect("New delegation hierarchy should exist in the storage."); - assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); - let new_stored_root = DelegationNodes::::get(old_root_id) - .expect("New delegation root should exist in the storage."); - assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); - assert!(new_stored_root.parent.is_none()); - assert_eq!(new_stored_root.children.len(), 2); - assert!(new_stored_root.children.contains(&old_node_id_1)); - assert!(new_stored_root.children.contains(&old_node_id_2)); - assert_eq!(new_stored_root.details.owner, old_root_node.owner); - assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); - - let new_stored_node_1 = DelegationNodes::::get(old_node_id_1) - .expect("New delegation 1 should exist in the storage."); - assert_eq!(new_stored_node_1.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_node_1.parent, Some(old_root_id)); - assert!(new_stored_node_1.children.is_empty()); - assert_eq!(new_stored_node_1.details.owner, old_node_1.owner); - assert_eq!(new_stored_node_1.details.revoked, old_node_1.revoked); - - let new_stored_node_2 = DelegationNodes::::get(old_node_id_2) - .expect("New delegation 2 should exist in the storage."); - assert_eq!(new_stored_node_2.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_node_2.parent, Some(old_root_id)); - assert!(new_stored_node_2.children.is_empty()); - assert_eq!(new_stored_node_2.details.owner, old_node_2.owner); - assert_eq!(new_stored_node_2.details.revoked, old_node_2.revoked); - }); - } + pub(crate) fn migrate() -> Weight { + 0u64 + } - #[test] - fn err_already_max_migrator() { - let migrator = StorageMigrator::::new(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - LastUpgradeVersion::::set(1); - assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); - }); - } + #[cfg(feature = "try-runtime")] + pub(crate) fn post_migrate() -> Result<(), &str> { + ensure!( + LastUpgradeVersion::::get() == DelegationStorageVersion::default(), + "Not updated to the latest version." + ); - #[test] - fn err_more_than_max_migrator() { - let migrator = StorageMigrator::::new(); - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - LastUpgradeVersion::::set(u16::MAX); - assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); - }); - } + Ok(()) } } + +// #[cfg(test)] +// mod tests { +// use super::*; + +// use mock::Test as TestRuntime; +// use sp_core::Pair; + +// fn get_storage_migrator() -> StorageMigrator { +// StorageMigrator::::new() +// } + +// fn init_logger() { +// let _ = env_logger::builder().is_test(true).try_init(); +// } + +// #[test] +// fn ok_no_delegations() { +// let migrator = get_storage_migrator(); +// let mut ext = mock::ExtBuilder::default().build(None); +// ext.execute_with(|| { +// assert!( +// migrator.pre_migration().is_ok(), +// "Pre-migration for v0 should not fail." +// ); + +// migrator.migrate(); + +// assert!( +// migrator.post_migration().is_ok(), +// "Post-migration for v0 should not fail." +// ); +// }); +// } + +// #[test] +// fn ok_only_root() { +// init_logger(); +// let migrator = get_storage_migrator(); +// let mut ext = mock::ExtBuilder::default().build(None); +// ext.execute_with(|| { +// let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); +// let old_root_id = mock::get_delegation_id(true); +// let old_root_node = +// crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); +// Roots::insert(old_root_id, old_root_node.clone()); + +// assert!( +// migrator.pre_migration().is_ok(), +// "Pre-migration for v0 should not fail." +// ); + +// migrator.migrate(); + +// assert!( +// migrator.post_migration().is_ok(), +// "Post-migration for v0 should not fail." +// ); + +// assert_eq!(Roots::::iter_values().count(), 0); +// assert_eq!(Delegations::::iter_values().count(), 0); +// assert_eq!(Children::::iter_values().count(), 0); + +// let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) +// .expect("New delegation hierarchy should exist in the storage."); +// assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); +// let new_stored_root = DelegationNodes::::get(old_root_id) +// .expect("New delegation root should exist in the storage."); +// assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); +// assert!(new_stored_root.parent.is_none()); +// assert!(new_stored_root.children.is_empty()); +// assert_eq!(new_stored_root.details.owner, old_root_node.owner); +// assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); +// }); +// } + +// #[test] +// fn ok_three_level_hierarchy() { +// init_logger(); +// let migrator = get_storage_migrator(); +// let mut ext = mock::ExtBuilder::default().build(None); +// ext.execute_with(|| { +// let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); +// let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); +// let old_root_id = mock::get_delegation_id(true); +// let old_root_node = +// crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); +// let old_parent_id = mock::get_delegation_id(false); +// let old_parent_node = +// crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); +// let old_node_id = mock::get_delegation_id_2(true); +// let old_node = crate::deprecated::v0::DelegationNode::::new_node_child( +// old_root_id, +// old_parent_id, +// bob, +// Permissions::ATTEST, +// ); +// Roots::insert(old_root_id, old_root_node.clone()); +// Delegations::insert(old_parent_id, old_parent_node.clone()); +// Delegations::insert(old_node_id, old_node.clone()); +// Children::::insert(old_root_id, vec![old_parent_id]); +// Children::::insert(old_parent_id, vec![old_node_id]); + +// assert!( +// migrator.pre_migration().is_ok(), +// "Pre-migration for v0 should not fail." +// ); + +// migrator.migrate(); + +// assert!( +// migrator.post_migration().is_ok(), +// "Post-migration for v0 should not fail." +// ); + +// assert_eq!(Roots::::iter_values().count(), 0); +// assert_eq!(Delegations::::iter_values().count(), 0); +// assert_eq!(Children::::iter_values().count(), 0); + +// let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) +// .expect("New delegation hierarchy should exist in the storage."); +// assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); +// let new_stored_root = DelegationNodes::::get(old_root_id) +// .expect("New delegation root should exist in the storage."); +// assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); +// assert!(new_stored_root.parent.is_none()); +// assert_eq!(new_stored_root.children.len(), 1); +// assert!(new_stored_root.children.contains(&old_parent_id)); +// assert_eq!(new_stored_root.details.owner, old_root_node.owner); +// assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + +// let new_stored_parent = DelegationNodes::::get(old_parent_id) +// .expect("New delegation parent should exist in the storage."); +// assert_eq!(new_stored_parent.hierarchy_root_id, old_root_id); +// assert_eq!(new_stored_parent.parent, Some(old_root_id)); +// assert_eq!(new_stored_parent.children.len(), 1); +// assert!(new_stored_parent.children.contains(&old_node_id)); +// assert_eq!(new_stored_parent.details.owner, old_parent_node.owner); +// assert_eq!(new_stored_parent.details.revoked, old_parent_node.revoked); + +// let new_stored_node = DelegationNodes::::get(old_node_id) +// .expect("New delegation node should exist in the storage."); +// assert_eq!(new_stored_node.hierarchy_root_id, old_root_id); +// assert_eq!(new_stored_node.parent, Some(old_parent_id)); +// assert!(new_stored_node.children.is_empty()); +// assert_eq!(new_stored_node.details.owner, old_node.owner); +// assert_eq!(new_stored_node.details.revoked, old_node.revoked); +// }); +// } + +// #[test] +// fn ok_root_two_children() { +// init_logger(); +// let migrator = get_storage_migrator(); +// let mut ext = mock::ExtBuilder::default().build(None); +// ext.execute_with(|| { +// let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); +// let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); +// let old_root_id = mock::get_delegation_id(true); +// let old_root_node = +// crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); +// let old_node_id_1 = mock::get_delegation_id(false); +// let old_node_1 = +// crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); +// let old_node_id_2 = mock::get_delegation_id_2(true); +// let old_node_2 = +// crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); +// Roots::insert(old_root_id, old_root_node.clone()); +// Delegations::insert(old_node_id_1, old_node_1.clone()); +// Delegations::insert(old_node_id_2, old_node_2.clone()); +// Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); + +// assert!( +// migrator.pre_migration().is_ok(), +// "Pre-migration for v0 should not fail." +// ); + +// migrator.migrate(); + +// assert!( +// migrator.post_migration().is_ok(), +// "Post-migration for v0 should not fail." +// ); + +// assert_eq!(Roots::::iter_values().count(), 0); +// assert_eq!(Delegations::::iter_values().count(), 0); +// assert_eq!(Children::::iter_values().count(), 0); + +// let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) +// .expect("New delegation hierarchy should exist in the storage."); +// assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); +// let new_stored_root = DelegationNodes::::get(old_root_id) +// .expect("New delegation root should exist in the storage."); +// assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); +// assert!(new_stored_root.parent.is_none()); +// assert_eq!(new_stored_root.children.len(), 2); +// assert!(new_stored_root.children.contains(&old_node_id_1)); +// assert!(new_stored_root.children.contains(&old_node_id_2)); +// assert_eq!(new_stored_root.details.owner, old_root_node.owner); +// assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + +// let new_stored_node_1 = DelegationNodes::::get(old_node_id_1) +// .expect("New delegation 1 should exist in the storage."); +// assert_eq!(new_stored_node_1.hierarchy_root_id, old_root_id); +// assert_eq!(new_stored_node_1.parent, Some(old_root_id)); +// assert!(new_stored_node_1.children.is_empty()); +// assert_eq!(new_stored_node_1.details.owner, old_node_1.owner); +// assert_eq!(new_stored_node_1.details.revoked, old_node_1.revoked); + +// let new_stored_node_2 = DelegationNodes::::get(old_node_id_2) +// .expect("New delegation 2 should exist in the storage."); +// assert_eq!(new_stored_node_2.hierarchy_root_id, old_root_id); +// assert_eq!(new_stored_node_2.parent, Some(old_root_id)); +// assert!(new_stored_node_2.children.is_empty()); +// assert_eq!(new_stored_node_2.details.owner, old_node_2.owner); +// assert_eq!(new_stored_node_2.details.revoked, old_node_2.revoked); +// }); +// } + +// #[test] +// fn err_already_max_migrator() { +// let migrator = StorageMigrator::::new(); +// let mut ext = mock::ExtBuilder::default().build(None); +// ext.execute_with(|| { +// LastUpgradeVersion::::set(1); +// assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); +// }); +// } + +// #[test] +// fn err_more_than_max_migrator() { +// let migrator = StorageMigrator::::new(); +// let mut ext = mock::ExtBuilder::default().build(None); +// ext.execute_with(|| { +// LastUpgradeVersion::::set(u16::MAX); +// assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); +// }); +// } +// } +// } From 429076d2bd2d41e221dfecf329dfef2f1836db30 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 16 Jul 2021 09:23:43 +0200 Subject: [PATCH 24/49] test: unit tests refactor for the new storage migrator version --- pallets/delegation/src/lib.rs | 8 +- pallets/delegation/src/migrations.rs | 507 ++++++++++++--------------- pallets/delegation/src/mock.rs | 11 + 3 files changed, 234 insertions(+), 292 deletions(-) diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 532cbd9de3..9771129bfe 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -96,16 +96,16 @@ pub mod pallet { impl Hooks> for Pallet { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { - migrations::DelegationStorageMigration::::pre_migrate() + migrations::DelegationStorageMigrator::::pre_migrate() } fn on_runtime_upgrade() -> Weight { - migrations::DelegationStorageMigration::::migrate() + migrations::DelegationStorageMigrator::::migrate() } #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { - migrations::DelegationStorageMigration::::post_migrate() + migrations::DelegationStorageMigrator::::post_migrate() } } @@ -136,7 +136,7 @@ pub mod pallet { /// Contains the latest version migrator used. #[pallet::storage] #[pallet::getter(fn last_version_migration_used)] - pub(crate) type LastVersionMigrationUsed = StorageValue<_, DelegationStorageVersion, ValueQuery>; + pub(crate) type StorageVersion = StorageValue<_, DelegationStorageVersion, ValueQuery>; /// Delegation nodes stored on chain. /// diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index fc6c1ff908..bff1922e25 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -23,23 +23,16 @@ use sp_std::collections::btree_map::BTreeMap; use crate::*; -// Contains the latest version that can be upgraded. -// For instance, if v1 of the storage is the last one available, only v0 would -// be upgradeable to v1, so the value of LATEST_UPGRADEABLE_VERSION would be 0. -// This needs to be bumped (by 1) every time a new storage migration should take -// place. Along with this, a new version migrator must be defined and added to -// the `migrations` vector or the `StorageMigrator`. - -pub trait VersionMigratorTrait { - #[cfg(feature = "try-runtime")] +pub trait VersionMigratorTrait { + #[cfg(any(feature = "try-runtime", test))] fn pre_migrate(&self) -> Result<(), &str>; fn migrate(&self) -> Weight; - #[cfg(feature = "try-runtime")] + #[cfg(any(feature = "try-runtime", test))] fn post_migrate(&self) -> Result<(), &str>; } #[allow(non_camel_case_types)] -#[derive(Encode, Eq, Decode, PartialEq)] +#[derive(Copy, Clone, Encode, Eq, Decode, PartialEq)] pub enum DelegationStorageVersion { v1, v2 } @@ -50,54 +43,46 @@ impl Default for DelegationStorageVersion { } } -impl DelegationStorageVersion { - pub(crate) fn get_next_version_migrator(&self) -> Option { - match *self { - Self::v1 => Some(Self::v2), - _ => None - } - } -} - impl VersionMigratorTrait for DelegationStorageVersion { - #[cfg(feature = "try-runtime")] + #[cfg(any(feature = "try-runtime", test))] fn pre_migrate(&self) -> Result<(), &str> { match *self { - Self::v1 => Self::pre_migrate_v1::(), - _ => Ok(()) + Self::v1 => v1::pre_migrate::(), + Self::v2 => Ok(()) } } fn migrate(&self) -> Weight { match *self { - Self::v1 => Self::migrate_v1::(), - _ => 0u64 + Self::v1 => v1::migrate::(), + Self::v2 => 0u64 } } - #[cfg(feature = "try-runtime")] + #[cfg(any(feature = "try-runtime", test))] fn post_migrate(&self) -> Result<(), &str> { match *self { - Self::v1 => Self::post_migrate_v1::(), - _ => Ok(()) + Self::v1 => v1::post_migrate::(), + Self::v2 => Ok(()) } } } -// v0 functions -impl DelegationStorageVersion { - #[cfg(feature = "try-runtime")] - fn pre_migrate_v1() -> Result<(), &str> { +mod v1 { + use super::*; + + #[cfg(any(feature = "try-runtime", test))] + pub(crate) fn pre_migrate() -> Result<(), &'static str> { ensure!( - LastVersionMigrationUsed::::get() == Self::v1, + StorageVersion::::get() == DelegationStorageVersion::v1, "Current deployed version is not v1." ); log::info!("Version storage migrating from v1 to v2"); Ok(()) } - fn migrate_v1() -> Weight { + pub(crate) fn migrate() -> Weight { log::info!("v1 -> v2 delegation storage migrator started!"); let mut total_weight = 0u64; @@ -173,17 +158,18 @@ impl DelegationStorageVersion { total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); } - LastVersionMigrationUsed::::set(Self::v2); - // Adds a write from LastUpgradeVersion::set() weight + StorageVersion::::set(DelegationStorageVersion::v2); + // Adds a write from StorageVersion::set() weight total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); log::debug!("Total weight consumed: {}", total_weight); log::info!("v1 -> v2 delegation storage migrator finished!"); total_weight } - fn post_migrate_v1() -> Result<(), &'static str> { + #[cfg(any(feature = "try-runtime", test))] + pub(crate) fn post_migrate() -> Result<(), &'static str> { ensure!( - LastVersionMigrationUsed::::get() == Self::v2, + StorageVersion::::get() == DelegationStorageVersion::v2, "The version after deployment is not 2 as expected." ); for (node_id, node) in DelegationNodes::::iter() { @@ -198,270 +184,215 @@ impl DelegationStorageVersion { log::info!("Version storage migrated from v1 to v2"); Ok(()) } + + #[cfg(test)] + mod tests { + use super::*; + + use sp_core::Pair; + + use mock::Test as TestRuntime; + + #[test] + fn ok_no_delegations() { + let mut ext = mock::ExtBuilder::default().with_storage_version(DelegationStorageVersion::v1).build(None); + ext.execute_with(|| { + assert!( + pre_migrate::().is_ok(), + "Pre-migration for v1 should not fail." + ); + + migrate::(); + + assert!( + post_migrate::().is_ok(), + "Post-migration for v1 should not fail." + ); + }); + } + + #[test] + fn ok_only_root() { + let mut ext = mock::ExtBuilder::default().with_storage_version(DelegationStorageVersion::v1).build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = + crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); + Roots::insert(old_root_id, old_root_node.clone()); + + assert!( + pre_migrate::().is_ok(), + "Pre-migration for v1 should not fail." + ); + + migrate::(); + + assert!( + post_migrate::().is_ok(), + "Post-migration for v1 should not fail." + ); + + assert_eq!(Roots::::iter_values().count(), 0); + assert_eq!(Delegations::::iter_values().count(), 0); + assert_eq!(Children::::iter_values().count(), 0); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert!(new_stored_root.children.is_empty()); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + }); + } + + #[test] + fn ok_root_two_children() { + let mut ext = mock::ExtBuilder::default().with_storage_version(DelegationStorageVersion::v1).build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = + crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_node_id_1 = mock::get_delegation_id(false); + let old_node_1 = + crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); + let old_node_id_2 = mock::get_delegation_id_2(true); + let old_node_2 = + crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); + Roots::insert(old_root_id, old_root_node.clone()); + Delegations::insert(old_node_id_1, old_node_1.clone()); + Delegations::insert(old_node_id_2, old_node_2.clone()); + Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); + + assert!( + pre_migrate::().is_ok(), + "Pre-migration for v1 should not fail." + ); + + migrate::(); + + assert!( + post_migrate::().is_ok(), + "Post-migration for v1 should not fail." + ); + + assert_eq!(Roots::::iter_values().count(), 0); + assert_eq!(Delegations::::iter_values().count(), 0); + assert_eq!(Children::::iter_values().count(), 0); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert_eq!(new_stored_root.children.len(), 2); + assert!(new_stored_root.children.contains(&old_node_id_1)); + assert!(new_stored_root.children.contains(&old_node_id_2)); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + + let new_stored_node_1 = DelegationNodes::::get(old_node_id_1) + .expect("New delegation 1 should exist in the storage."); + assert_eq!(new_stored_node_1.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node_1.parent, Some(old_root_id)); + assert!(new_stored_node_1.children.is_empty()); + assert_eq!(new_stored_node_1.details.owner, old_node_1.owner); + assert_eq!(new_stored_node_1.details.revoked, old_node_1.revoked); + + let new_stored_node_2 = DelegationNodes::::get(old_node_id_2) + .expect("New delegation 2 should exist in the storage."); + assert_eq!(new_stored_node_2.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node_2.parent, Some(old_root_id)); + assert!(new_stored_node_2.children.is_empty()); + assert_eq!(new_stored_node_2.details.owner, old_node_2.owner); + assert_eq!(new_stored_node_2.details.revoked, old_node_2.revoked); + }); + } + } } -pub struct DelegationStorageMigration(PhantomData); +pub struct DelegationStorageMigrator(PhantomData); -impl DelegationStorageMigration { - #[cfg(feature = "try-runtime")] - pub(crate) fn pre_migrate() -> Result<(), &str> { +impl DelegationStorageMigrator { + + fn get_next_storage_version(current: DelegationStorageVersion) -> Option { + match current { + DelegationStorageVersion::v1 => Some(DelegationStorageVersion::v2), + DelegationStorageVersion::v2 => None + } + } + + #[cfg(any(feature = "try-runtime", test))] + pub(crate) fn pre_migrate() -> Result<(), &'static str> { ensure!( - LastVersionMigrationUsed::get() != DelegationStorageVersion::default(), - "Already the latest (default) storage migrator." + StorageVersion::::get() != DelegationStorageVersion::default(), + "Already the latest (default) storage version." ); + + Ok(()) } pub(crate) fn migrate() -> Weight { - 0u64 + let mut current_version: Option = Some(StorageVersion::::get()); + let mut total_weight = T::DbWeight::get().reads(1); + + while let Some(ver) = current_version { + #[cfg(feature = "try-runtime")] + if let Err(err) = >::pre_migrate(&ver) { + panic!("{:?}", err); + } + let consumed_weight = >::migrate(&ver); + total_weight = total_weight.saturating_add(consumed_weight); + #[cfg(feature = "try-runtime")] + if let Err(err) = >::post_migrate(&ver) { + panic!("{:?}", err); + } + current_version = Self::get_next_storage_version(ver); + } + + total_weight } - #[cfg(feature = "try-runtime")] - pub(crate) fn post_migrate() -> Result<(), &str> { + #[cfg(any(feature = "try-runtime", test))] + pub(crate) fn post_migrate() -> Result<(), &'static str> { ensure!( - LastUpgradeVersion::::get() == DelegationStorageVersion::default(), - "Not updated to the latest version." + StorageVersion::::get() == DelegationStorageVersion::default(), + "Not updated to the latest (default) version." ); Ok(()) } } -// #[cfg(test)] -// mod tests { -// use super::*; - -// use mock::Test as TestRuntime; -// use sp_core::Pair; - -// fn get_storage_migrator() -> StorageMigrator { -// StorageMigrator::::new() -// } - -// fn init_logger() { -// let _ = env_logger::builder().is_test(true).try_init(); -// } - -// #[test] -// fn ok_no_delegations() { -// let migrator = get_storage_migrator(); -// let mut ext = mock::ExtBuilder::default().build(None); -// ext.execute_with(|| { -// assert!( -// migrator.pre_migration().is_ok(), -// "Pre-migration for v0 should not fail." -// ); - -// migrator.migrate(); - -// assert!( -// migrator.post_migration().is_ok(), -// "Post-migration for v0 should not fail." -// ); -// }); -// } - -// #[test] -// fn ok_only_root() { -// init_logger(); -// let migrator = get_storage_migrator(); -// let mut ext = mock::ExtBuilder::default().build(None); -// ext.execute_with(|| { -// let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); -// let old_root_id = mock::get_delegation_id(true); -// let old_root_node = -// crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); -// Roots::insert(old_root_id, old_root_node.clone()); - -// assert!( -// migrator.pre_migration().is_ok(), -// "Pre-migration for v0 should not fail." -// ); - -// migrator.migrate(); - -// assert!( -// migrator.post_migration().is_ok(), -// "Post-migration for v0 should not fail." -// ); - -// assert_eq!(Roots::::iter_values().count(), 0); -// assert_eq!(Delegations::::iter_values().count(), 0); -// assert_eq!(Children::::iter_values().count(), 0); - -// let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) -// .expect("New delegation hierarchy should exist in the storage."); -// assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); -// let new_stored_root = DelegationNodes::::get(old_root_id) -// .expect("New delegation root should exist in the storage."); -// assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); -// assert!(new_stored_root.parent.is_none()); -// assert!(new_stored_root.children.is_empty()); -// assert_eq!(new_stored_root.details.owner, old_root_node.owner); -// assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); -// }); -// } - -// #[test] -// fn ok_three_level_hierarchy() { -// init_logger(); -// let migrator = get_storage_migrator(); -// let mut ext = mock::ExtBuilder::default().build(None); -// ext.execute_with(|| { -// let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); -// let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); -// let old_root_id = mock::get_delegation_id(true); -// let old_root_node = -// crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); -// let old_parent_id = mock::get_delegation_id(false); -// let old_parent_node = -// crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); -// let old_node_id = mock::get_delegation_id_2(true); -// let old_node = crate::deprecated::v0::DelegationNode::::new_node_child( -// old_root_id, -// old_parent_id, -// bob, -// Permissions::ATTEST, -// ); -// Roots::insert(old_root_id, old_root_node.clone()); -// Delegations::insert(old_parent_id, old_parent_node.clone()); -// Delegations::insert(old_node_id, old_node.clone()); -// Children::::insert(old_root_id, vec![old_parent_id]); -// Children::::insert(old_parent_id, vec![old_node_id]); - -// assert!( -// migrator.pre_migration().is_ok(), -// "Pre-migration for v0 should not fail." -// ); - -// migrator.migrate(); - -// assert!( -// migrator.post_migration().is_ok(), -// "Post-migration for v0 should not fail." -// ); - -// assert_eq!(Roots::::iter_values().count(), 0); -// assert_eq!(Delegations::::iter_values().count(), 0); -// assert_eq!(Children::::iter_values().count(), 0); - -// let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) -// .expect("New delegation hierarchy should exist in the storage."); -// assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); -// let new_stored_root = DelegationNodes::::get(old_root_id) -// .expect("New delegation root should exist in the storage."); -// assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); -// assert!(new_stored_root.parent.is_none()); -// assert_eq!(new_stored_root.children.len(), 1); -// assert!(new_stored_root.children.contains(&old_parent_id)); -// assert_eq!(new_stored_root.details.owner, old_root_node.owner); -// assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); - -// let new_stored_parent = DelegationNodes::::get(old_parent_id) -// .expect("New delegation parent should exist in the storage."); -// assert_eq!(new_stored_parent.hierarchy_root_id, old_root_id); -// assert_eq!(new_stored_parent.parent, Some(old_root_id)); -// assert_eq!(new_stored_parent.children.len(), 1); -// assert!(new_stored_parent.children.contains(&old_node_id)); -// assert_eq!(new_stored_parent.details.owner, old_parent_node.owner); -// assert_eq!(new_stored_parent.details.revoked, old_parent_node.revoked); - -// let new_stored_node = DelegationNodes::::get(old_node_id) -// .expect("New delegation node should exist in the storage."); -// assert_eq!(new_stored_node.hierarchy_root_id, old_root_id); -// assert_eq!(new_stored_node.parent, Some(old_parent_id)); -// assert!(new_stored_node.children.is_empty()); -// assert_eq!(new_stored_node.details.owner, old_node.owner); -// assert_eq!(new_stored_node.details.revoked, old_node.revoked); -// }); -// } - -// #[test] -// fn ok_root_two_children() { -// init_logger(); -// let migrator = get_storage_migrator(); -// let mut ext = mock::ExtBuilder::default().build(None); -// ext.execute_with(|| { -// let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); -// let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); -// let old_root_id = mock::get_delegation_id(true); -// let old_root_node = -// crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); -// let old_node_id_1 = mock::get_delegation_id(false); -// let old_node_1 = -// crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); -// let old_node_id_2 = mock::get_delegation_id_2(true); -// let old_node_2 = -// crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); -// Roots::insert(old_root_id, old_root_node.clone()); -// Delegations::insert(old_node_id_1, old_node_1.clone()); -// Delegations::insert(old_node_id_2, old_node_2.clone()); -// Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); - -// assert!( -// migrator.pre_migration().is_ok(), -// "Pre-migration for v0 should not fail." -// ); - -// migrator.migrate(); - -// assert!( -// migrator.post_migration().is_ok(), -// "Post-migration for v0 should not fail." -// ); - -// assert_eq!(Roots::::iter_values().count(), 0); -// assert_eq!(Delegations::::iter_values().count(), 0); -// assert_eq!(Children::::iter_values().count(), 0); - -// let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) -// .expect("New delegation hierarchy should exist in the storage."); -// assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); -// let new_stored_root = DelegationNodes::::get(old_root_id) -// .expect("New delegation root should exist in the storage."); -// assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); -// assert!(new_stored_root.parent.is_none()); -// assert_eq!(new_stored_root.children.len(), 2); -// assert!(new_stored_root.children.contains(&old_node_id_1)); -// assert!(new_stored_root.children.contains(&old_node_id_2)); -// assert_eq!(new_stored_root.details.owner, old_root_node.owner); -// assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); - -// let new_stored_node_1 = DelegationNodes::::get(old_node_id_1) -// .expect("New delegation 1 should exist in the storage."); -// assert_eq!(new_stored_node_1.hierarchy_root_id, old_root_id); -// assert_eq!(new_stored_node_1.parent, Some(old_root_id)); -// assert!(new_stored_node_1.children.is_empty()); -// assert_eq!(new_stored_node_1.details.owner, old_node_1.owner); -// assert_eq!(new_stored_node_1.details.revoked, old_node_1.revoked); - -// let new_stored_node_2 = DelegationNodes::::get(old_node_id_2) -// .expect("New delegation 2 should exist in the storage."); -// assert_eq!(new_stored_node_2.hierarchy_root_id, old_root_id); -// assert_eq!(new_stored_node_2.parent, Some(old_root_id)); -// assert!(new_stored_node_2.children.is_empty()); -// assert_eq!(new_stored_node_2.details.owner, old_node_2.owner); -// assert_eq!(new_stored_node_2.details.revoked, old_node_2.revoked); -// }); -// } - -// #[test] -// fn err_already_max_migrator() { -// let migrator = StorageMigrator::::new(); -// let mut ext = mock::ExtBuilder::default().build(None); -// ext.execute_with(|| { -// LastUpgradeVersion::::set(1); -// assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); -// }); -// } - -// #[test] -// fn err_more_than_max_migrator() { -// let migrator = StorageMigrator::::new(); -// let mut ext = mock::ExtBuilder::default().build(None); -// ext.execute_with(|| { -// LastUpgradeVersion::::set(u16::MAX); -// assert!(migrator.pre_migration().is_err(), "Pre-migration for v0 should fail."); -// }); -// } -// } -// } +#[cfg(test)] +mod tests { + use super::*; + + use mock::Test as TestRuntime; + + #[test] + fn ok_v1_migration() { + let mut ext = mock::ExtBuilder::default().with_storage_version(DelegationStorageVersion::v1).build(None); + ext.execute_with(|| { + assert!( + DelegationStorageMigrator::::pre_migrate().is_ok(), + "Storage pre-migrate from v1 should not fail." + ); + + DelegationStorageMigrator::::migrate(); + + assert!( + DelegationStorageMigrator::::post_migrate().is_ok(), + "Storage post-migrate from v1 should not fail." + ); + }); + } +} diff --git a/pallets/delegation/src/mock.rs b/pallets/delegation/src/mock.rs index dc81c6cbf7..7c43780936 100644 --- a/pallets/delegation/src/mock.rs +++ b/pallets/delegation/src/mock.rs @@ -314,6 +314,7 @@ pub struct ExtBuilder { ctype_builder: Option, delegation_hierarchies_stored: Vec<(TestDelegationNodeId, DelegationHierarchyInfo, DelegatorIdOf)>, delegations_stored: Vec<(TestDelegationNodeId, DelegationNode)>, + storage_version: DelegationStorageVersion, } impl Default for ExtBuilder { @@ -322,6 +323,7 @@ impl Default for ExtBuilder { ctype_builder: None, delegation_hierarchies_stored: vec![], delegations_stored: vec![], + storage_version: DelegationStorageVersion::default(), } } } @@ -340,6 +342,11 @@ impl ExtBuilder { self } + pub fn with_storage_version(mut self, storage_version: DelegationStorageVersion) -> Self { + self.storage_version = storage_version; + self + } + pub fn build(self, ext: Option) -> sp_io::TestExternalities { let mut ext = if let Some(ext) = ext { ext @@ -380,6 +387,10 @@ impl ExtBuilder { }); } + ext.execute_with(|| { + delegation::StorageVersion::::set(self.storage_version); + }); + ext } From 29db04355fcef67270dca3e2b24be1c1d2435a8e Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 16 Jul 2021 10:17:06 +0200 Subject: [PATCH 25/49] chore: refactor --- .../delegation/src/delegation_hierarchy.rs | 3 +- pallets/delegation/src/lib.rs | 15 +-- pallets/delegation/src/migrations.rs | 110 ++++++++++++------ 3 files changed, 82 insertions(+), 46 deletions(-) diff --git a/pallets/delegation/src/delegation_hierarchy.rs b/pallets/delegation/src/delegation_hierarchy.rs index 569113d5bf..bf5543b577 100644 --- a/pallets/delegation/src/delegation_hierarchy.rs +++ b/pallets/delegation/src/delegation_hierarchy.rs @@ -54,7 +54,6 @@ impl Default for Permissions { } } - #[derive(Clone, Debug, Encode, Decode, PartialEq)] pub struct DelegationNode { pub hierarchy_root_id: DelegationNodeIdOf, @@ -82,7 +81,7 @@ impl DelegationNode { hierarchy_root_id, parent: Some(parent), children: BTreeSet::new(), - details + details, } } diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 9771129bfe..2e51a175cb 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -114,16 +114,14 @@ pub mod pallet { /// It maps from a root node ID to the full root node. #[pallet::storage] #[pallet::getter(fn roots)] - pub type Roots = - StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, deprecated::v0::DelegationRoot>; + pub type Roots = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, deprecated::v0::DelegationRoot>; /// Delegation nodes stored on chain. DEPRECATED. /// /// It maps from a node ID to the full delegation node. #[pallet::storage] #[pallet::getter(fn delegations)] - pub type Delegations = - StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, deprecated::v0::DelegationNode>; + pub type Delegations = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, deprecated::v0::DelegationNode>; /// Children delegation nodes. DEPRECATED. /// @@ -287,8 +285,7 @@ pub mod pallet { let delegator = ::EnsureOrigin::ensure_origin(origin)?; // Calculate the hash root - let hash_root = - Self::calculate_delegation_creation_hash(&delegation_id, &parent_id, &permissions); + let hash_root = Self::calculate_delegation_creation_hash(&delegation_id, &parent_id, &permissions); // Verify that the hash root signature is correct. DelegationSignatureVerificationOf::::verify(&delegate, &hash_root.encode(), &delegate_signature) @@ -325,10 +322,10 @@ pub mod pallet { owner: delegate.clone(), permissions, revoked: false, - } + }, ), parent_id, - parent_node + parent_node, ); Self::deposit_event(Event::DelegationCreated( @@ -337,7 +334,7 @@ pub mod pallet { delegation_id, parent_id, delegate, - permissions + permissions, )); Ok(()) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index bff1922e25..9facdab2f8 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -32,39 +32,50 @@ pub trait VersionMigratorTrait { } #[allow(non_camel_case_types)] -#[derive(Copy, Clone, Encode, Eq, Decode, PartialEq)] +#[derive(Copy, Clone, Encode, Eq, Decode, Ord, PartialEq, PartialOrd)] pub enum DelegationStorageVersion { - v1, v2 + v1, + v2, } +#[allow(dead_code)] +impl DelegationStorageVersion { + fn latest() -> Self { + Self::v2 + } +} + +// All nodes will default to this, which is not bad, as in case the "real" +// version is the latest one (i.e. the node has been started with already the +// latest version), the migration will simply do nothing as there's nothing in +// the old storage entries. impl Default for DelegationStorageVersion { - fn default() -> Self { - Self::v2 - } + fn default() -> Self { + Self::v1 + } } impl VersionMigratorTrait for DelegationStorageVersion { - #[cfg(any(feature = "try-runtime", test))] fn pre_migrate(&self) -> Result<(), &str> { match *self { Self::v1 => v1::pre_migrate::(), - Self::v2 => Ok(()) + Self::v2 => Ok(()), } } - fn migrate(&self) -> Weight { + fn migrate(&self) -> Weight { match *self { Self::v1 => v1::migrate::(), - Self::v2 => 0u64 + Self::v2 => 0u64, } - } + } #[cfg(any(feature = "try-runtime", test))] fn post_migrate(&self) -> Result<(), &str> { match *self { Self::v1 => v1::post_migrate::(), - Self::v2 => Ok(()) + Self::v2 => Ok(()), } } } @@ -78,6 +89,7 @@ mod v1 { StorageVersion::::get() == DelegationStorageVersion::v1, "Current deployed version is not v1." ); + log::info!("Version storage migrating from v1 to v2"); Ok(()) } @@ -129,8 +141,7 @@ mod v1 { }; // In the old version, a parent None indicated the node is a child of the root. let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); - let mut new_node = - DelegationNode::::new_node(old_node.root_id, new_node_parent_id, new_node_details); + let mut new_node = DelegationNode::::new_node(old_node.root_id, new_node_parent_id, new_node_details); if let Some(children_ids) = Children::::take(old_node_id) { new_node.children = children_ids.iter().copied().collect(); } @@ -175,10 +186,7 @@ mod v1 { for (node_id, node) in DelegationNodes::::iter() { if let Some(parent_id) = node.parent { let parent_node = DelegationNodes::::get(parent_id).expect("Parent node should be in the storage."); - ensure!( - parent_node.children.contains(&node_id), - "Parent-child wrong" - ); + ensure!(parent_node.children.contains(&node_id), "Parent-child wrong"); } } log::info!("Version storage migrated from v1 to v2"); @@ -193,9 +201,24 @@ mod v1 { use mock::Test as TestRuntime; + #[test] + fn fail_version_higher() { + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::v2) + .build(None); + ext.execute_with(|| { + assert!( + pre_migrate::().is_err(), + "Pre-migration for v1 should fail." + ); + }); + } + #[test] fn ok_no_delegations() { - let mut ext = mock::ExtBuilder::default().with_storage_version(DelegationStorageVersion::v1).build(None); + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::v1) + .build(None); ext.execute_with(|| { assert!( pre_migrate::().is_ok(), @@ -213,7 +236,9 @@ mod v1 { #[test] fn ok_only_root() { - let mut ext = mock::ExtBuilder::default().with_storage_version(DelegationStorageVersion::v1).build(None); + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::v1) + .build(None); ext.execute_with(|| { let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); let old_root_id = mock::get_delegation_id(true); @@ -252,19 +277,29 @@ mod v1 { #[test] fn ok_root_two_children() { - let mut ext = mock::ExtBuilder::default().with_storage_version(DelegationStorageVersion::v1).build(None); + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::v1) + .build(None); ext.execute_with(|| { let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); let old_root_id = mock::get_delegation_id(true); - let old_root_node = - crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_root_node = crate::deprecated::v0::DelegationRoot::::new( + ctype::mock::get_ctype_hash(true), + alice.clone(), + ); let old_node_id_1 = mock::get_delegation_id(false); - let old_node_1 = - crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, alice, Permissions::DELEGATE); + let old_node_1 = crate::deprecated::v0::DelegationNode::::new_root_child( + old_root_id, + alice, + Permissions::DELEGATE, + ); let old_node_id_2 = mock::get_delegation_id_2(true); - let old_node_2 = - crate::deprecated::v0::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); + let old_node_2 = crate::deprecated::v0::DelegationNode::::new_root_child( + old_root_id, + bob, + Permissions::ATTEST, + ); Roots::insert(old_root_id, old_root_node.clone()); Delegations::insert(old_node_id_1, old_node_1.clone()); Delegations::insert(old_node_id_2, old_node_2.clone()); @@ -322,21 +357,24 @@ mod v1 { pub struct DelegationStorageMigrator(PhantomData); impl DelegationStorageMigrator { - fn get_next_storage_version(current: DelegationStorageVersion) -> Option { match current { DelegationStorageVersion::v1 => Some(DelegationStorageVersion::v2), - DelegationStorageVersion::v2 => None + DelegationStorageVersion::v2 => None, } } #[cfg(any(feature = "try-runtime", test))] pub(crate) fn pre_migrate() -> Result<(), &'static str> { ensure!( - StorageVersion::::get() != DelegationStorageVersion::default(), - "Already the latest (default) storage version." + StorageVersion::::get() < DelegationStorageVersion::latest(), + "Already the latest storage version." ); + // Don't need to check for any other pre_migrate, as in try-runtime it is also + // called in the migrate() function. Same applies for post_migrate checks for + // each version migrator. + Ok(()) } @@ -346,7 +384,7 @@ impl DelegationStorageMigrator { while let Some(ver) = current_version { #[cfg(feature = "try-runtime")] - if let Err(err) = >::pre_migrate(&ver) { + if let Err(err) = >::pre_migrate(&ver) { panic!("{:?}", err); } let consumed_weight = >::migrate(&ver); @@ -364,8 +402,8 @@ impl DelegationStorageMigrator { #[cfg(any(feature = "try-runtime", test))] pub(crate) fn post_migrate() -> Result<(), &'static str> { ensure!( - StorageVersion::::get() == DelegationStorageVersion::default(), - "Not updated to the latest (default) version." + StorageVersion::::get() == DelegationStorageVersion::latest(), + "Not updated to the latest version." ); Ok(()) @@ -379,8 +417,10 @@ mod tests { use mock::Test as TestRuntime; #[test] - fn ok_v1_migration() { - let mut ext = mock::ExtBuilder::default().with_storage_version(DelegationStorageVersion::v1).build(None); + fn ok_from_v1_migration() { + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::v1) + .build(None); ext.execute_with(|| { assert!( DelegationStorageMigrator::::pre_migrate().is_ok(), From 25a01bd68312b445ced61688cebebada5861613f Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 16 Jul 2021 11:27:49 +0200 Subject: [PATCH 26/49] test: unit tests passing again --- pallets/delegation/src/migrations.rs | 97 ++++++++++++++++++---------- 1 file changed, 64 insertions(+), 33 deletions(-) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 9facdab2f8..77a4ab046a 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -60,7 +60,7 @@ impl VersionMigratorTrait for DelegationStorageVersion { fn pre_migrate(&self) -> Result<(), &str> { match *self { Self::v1 => v1::pre_migrate::(), - Self::v2 => Ok(()), + Self::v2 => Err("Already latest v2 version."), } } @@ -75,7 +75,7 @@ impl VersionMigratorTrait for DelegationStorageVersion { fn post_migrate(&self) -> Result<(), &str> { match *self { Self::v1 => v1::post_migrate::(), - Self::v2 => Ok(()), + Self::v2 => Err("Migration from v2 should have never happened in the first place."), } } } @@ -100,12 +100,32 @@ mod v1 { // Before being stored, the nodes are saved in a map so that after we go over // all the nodes and the parent-child relationship in the storage, we can update - // the `parent` link of each node accordingly. Otherwise, it would be possible - // that a node does not exist when fetched from the Children storage entry. + // the `parent` link of each node accordingly. Otherwise, we would need to save the + // node in the storage, and then retrieve it again to update the parent link. let mut new_nodes: BTreeMap, DelegationNode> = BTreeMap::new(); // First iterate over the delegation roots and translate them to hierarchies. - for (old_root_id, old_root_node) in Roots::::drain() { + total_weight = total_weight.saturating_add(migrate_roots::(&mut new_nodes)); + + // Then iterate over the regular delegation nodes. + total_weight = total_weight.saturating_add(migrate_nodes::(&mut new_nodes, total_weight)); + + // By now, all the children should have been correctly added to the nodes. + // We now need to modify all the nodes that are children by adding a reference + // to their parents. + total_weight = total_weight.saturating_add(finalize_children_nodes::(&mut new_nodes, total_weight)); + + StorageVersion::::set(DelegationStorageVersion::v2); + // Adds a write from StorageVersion::set() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + log::debug!("Total weight consumed: {}", total_weight); + log::info!("v1 -> v2 delegation storage migrator finished!"); + + total_weight + } + + fn migrate_roots(new_nodes: &mut BTreeMap, DelegationNode>) -> Weight { + Roots::::drain().fold(0u64, |mut total_weight, (old_root_id, old_root_node)| { let new_hierarchy_info = DelegationHierarchyInfo:: { ctype_hash: old_root_node.ctype_hash, }; @@ -129,11 +149,15 @@ mod v1 { // Adds a read from Roots::drain() and a write from // DelegationHierarchies::insert() weights total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + // Add the node to the temporary map of nodes to be added at the end. new_nodes.insert(old_root_id, new_root_node); - } - // Then iterate over the regular delegation nodes. - for (old_node_id, old_node) in Delegations::::drain() { + total_weight + }) + } + + fn migrate_nodes(new_nodes: &mut BTreeMap, DelegationNode>, initial_weight: Weight) -> Weight { + Delegations::::drain().fold(initial_weight, |mut total_weight, (old_node_id, old_node)| { let new_node_details = DelegationDetails:: { owner: old_node.owner, permissions: old_node.permissions, @@ -141,7 +165,7 @@ mod v1 { }; // In the old version, a parent None indicated the node is a child of the root. let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); - let mut new_node = DelegationNode::::new_node(old_node.root_id, new_node_parent_id, new_node_details); + let mut new_node = DelegationNode::new_node(old_node.root_id, new_node_parent_id, new_node_details); if let Some(children_ids) = Children::::take(old_node_id) { new_node.children = children_ids.iter().copied().collect(); } @@ -150,31 +174,25 @@ mod v1 { // Adds a read from Roots::drain() weight total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); new_nodes.insert(old_node_id, new_node); - } - // By now, all the children should have been correctly added to the nodes. - // We now need to modify all the nodes that are children by adding a reference - // to their parents. - for (new_node_id, new_node) in new_nodes.clone().into_iter() { - // FIXME: new_node.children.iter().cloned() might be possibly changed to - // iter_mut. - for child_id in new_node.children.iter().cloned() { + total_weight + }) + } + + fn finalize_children_nodes(new_nodes: &mut BTreeMap, DelegationNode>, initial_weight: Weight) -> Weight { + new_nodes.clone().into_iter().fold(initial_weight, |mut total_weight, (new_node_id, new_node)| { + new_node.children.iter().for_each(|child_id| { new_nodes - .entry(child_id) + .entry(*child_id) .and_modify(|node| node.parent = Some(new_node_id)); - } + }); // We can then finally insert the new delegation node in the storage. DelegationNodes::::insert(new_node_id, new_node); // Adds a write from DelegationNodes::insert() weight total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - } - StorageVersion::::set(DelegationStorageVersion::v2); - // Adds a write from StorageVersion::set() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - log::debug!("Total weight consumed: {}", total_weight); - log::info!("v1 -> v2 delegation storage migrator finished!"); - total_weight + total_weight + }) } #[cfg(any(feature = "try-runtime", test))] @@ -183,16 +201,29 @@ mod v1 { StorageVersion::::get() == DelegationStorageVersion::v2, "The version after deployment is not 2 as expected." ); - for (node_id, node) in DelegationNodes::::iter() { - if let Some(parent_id) = node.parent { - let parent_node = DelegationNodes::::get(parent_id).expect("Parent node should be in the storage."); - ensure!(parent_node.children.contains(&node_id), "Parent-child wrong"); - } - } + ensure!( + verify_parent_children_integrity::(), + "Some parent-child relationship has been broken in the migration." + ); log::info!("Version storage migrated from v1 to v2"); Ok(()) } + #[cfg(any(feature = "try-runtime", test))] + fn verify_parent_children_integrity() -> bool { + !DelegationNodes::::iter().any(|(node_id, node)| { + if let Some(parent_id) = node.parent { + if let Some(parent_node) = DelegationNodes::::get(parent_id) { + return !parent_node.children.contains(&node_id); + } else { + // If the parent node cannot be found, it is definitely an error. + return true; + } + } + false + }) + } + #[cfg(test)] mod tests { use super::*; @@ -359,7 +390,7 @@ pub struct DelegationStorageMigrator(PhantomData); impl DelegationStorageMigrator { fn get_next_storage_version(current: DelegationStorageVersion) -> Option { match current { - DelegationStorageVersion::v1 => Some(DelegationStorageVersion::v2), + DelegationStorageVersion::v1 => None, DelegationStorageVersion::v2 => None, } } From 0040f2d75ca135d86b18c86cea6f54e0cb7e24e5 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 16 Jul 2021 14:51:52 +0200 Subject: [PATCH 27/49] chore: move deprecated type to deprecated.rs --- delegation_expanded.rs | 0 pallets/delegation/src/deprecated.rs | 46 +++++++--- pallets/delegation/src/lib.rs | 22 ----- pallets/delegation/src/migrations.rs | 129 ++++++++++++++++++++++----- 4 files changed, 141 insertions(+), 56 deletions(-) create mode 100644 delegation_expanded.rs diff --git a/delegation_expanded.rs b/delegation_expanded.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pallets/delegation/src/deprecated.rs b/pallets/delegation/src/deprecated.rs index 5f9f3894af..3acd2c866f 100644 --- a/pallets/delegation/src/deprecated.rs +++ b/pallets/delegation/src/deprecated.rs @@ -16,7 +16,7 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org -pub(crate) mod v0 { +pub(crate) mod v1 { use codec::{Decode, Encode}; use crate::*; @@ -26,15 +26,16 @@ pub(crate) mod v0 { pub struct DelegationRoot { /// The hash of the CTYPE that delegated attesters within this trust /// hierarchy can attest. - pub ctype_hash: CtypeHashOf, + pub(crate) ctype_hash: CtypeHashOf, /// The identifier of the root owner. - pub owner: DelegatorIdOf, + pub(crate) owner: DelegatorIdOf, /// The flag indicating whether the root has been revoked or not. - pub revoked: bool, + pub(crate) revoked: bool, } impl DelegationRoot { - pub fn new(ctype_hash: CtypeHashOf, owner: DelegatorIdOf) -> Self { + #[cfg(test)] + pub(crate) fn new(ctype_hash: CtypeHashOf, owner: DelegatorIdOf) -> Self { DelegationRoot { ctype_hash, owner, @@ -47,18 +48,18 @@ pub(crate) mod v0 { #[derive(Clone, Debug, Encode, Decode, PartialEq)] pub struct DelegationNode { /// The ID of the delegation hierarchy root. - pub root_id: DelegationNodeIdOf, + pub(crate) root_id: DelegationNodeIdOf, /// \[OPTIONAL\] The ID of the parent node. If None, the node is /// considered a direct child of the root node. - pub parent: Option>, + pub(crate) parent: Option>, /// The identifier of the owner of the delegation node, i.e., the /// delegate. - pub owner: DelegatorIdOf, + pub(crate) owner: DelegatorIdOf, /// The permission flags for the operations the delegate is allowed to /// perform. - pub permissions: Permissions, + pub(crate) permissions: Permissions, /// The flag indicating whether the delegation has been revoked or not. - pub revoked: bool, + pub(crate) revoked: bool, } impl DelegationNode { @@ -70,7 +71,8 @@ pub(crate) mod v0 { /// the new delegate /// * permissions: the permission flags for the operations the delegate /// is allowed to perform - pub fn new_root_child( + #[cfg(test)] + pub(crate) fn new_root_child( root_id: DelegationNodeIdOf, owner: DelegatorIdOf, permissions: Permissions, @@ -93,7 +95,8 @@ pub(crate) mod v0 { /// the new delegate /// * permissions: the permission flags for the operations the delegate /// is allowed to perform - pub fn new_node_child( + #[cfg(test)] + pub(crate) fn new_node_child( root_id: DelegationNodeIdOf, parent: DelegationNodeIdOf, owner: DelegatorIdOf, @@ -108,4 +111,23 @@ pub(crate) mod v0 { } } } + + pub(crate) mod storage { + pub use frame_support::{decl_module, decl_storage}; + pub use sp_std::prelude::*; + + use crate::Config; + + decl_module! { + pub struct OldPallet for enum Call where origin: T::Origin {} + } + + decl_storage! { + trait Store for OldPallet as Delegation { + pub(crate) Roots get(fn roots): map hasher(blake2_128_concat) crate::DelegationNodeIdOf => Option>; + pub(crate) Delegations get(fn delegations): map hasher(blake2_128_concat) crate::DelegationNodeIdOf => Option>; + pub(crate) Children get(fn children): map hasher(blake2_128_concat) crate::DelegationNodeIdOf => Option>>; + } + } + } } diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 2e51a175cb..6b9ca61c02 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -109,28 +109,6 @@ pub mod pallet { } } - /// Delegation root nodes stored on chain. DEPRECATED. - /// - /// It maps from a root node ID to the full root node. - #[pallet::storage] - #[pallet::getter(fn roots)] - pub type Roots = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, deprecated::v0::DelegationRoot>; - - /// Delegation nodes stored on chain. DEPRECATED. - /// - /// It maps from a node ID to the full delegation node. - #[pallet::storage] - #[pallet::getter(fn delegations)] - pub type Delegations = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, deprecated::v0::DelegationNode>; - - /// Children delegation nodes. DEPRECATED. - /// - /// It maps from a delegation node ID, including the root node, to the list - /// of children nodes, sorted by time of creation. - #[pallet::storage] - #[pallet::getter(fn children)] - pub type Children = StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, Vec>>; - /// Contains the latest version migrator used. #[pallet::storage] #[pallet::getter(fn last_version_migration_used)] diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 77a4ab046a..4e7f0c7de7 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -51,7 +51,7 @@ impl DelegationStorageVersion { // the old storage entries. impl Default for DelegationStorageVersion { fn default() -> Self { - Self::v1 + Self::v2 } } @@ -83,6 +83,9 @@ impl VersionMigratorTrait for DelegationStorageVersion { mod v1 { use super::*; + use frame_support::{IterableStorageMap, StoragePrefixedMap, StorageMap}; + use frame_support::traits::PalletInfoAccess; + #[cfg(any(feature = "try-runtime", test))] pub(crate) fn pre_migrate() -> Result<(), &'static str> { ensure!( @@ -125,7 +128,7 @@ mod v1 { } fn migrate_roots(new_nodes: &mut BTreeMap, DelegationNode>) -> Weight { - Roots::::drain().fold(0u64, |mut total_weight, (old_root_id, old_root_node)| { + let total_weight = deprecated::v1::storage::Roots::::drain().fold(0u64, |mut total_weight, (old_root_id, old_root_node)| { let new_hierarchy_info = DelegationHierarchyInfo:: { ctype_hash: old_root_node.ctype_hash, }; @@ -139,7 +142,7 @@ mod v1 { // update the children information. The parent information will be updated // later, when we know we have seen all the children already. let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); - if let Some(root_children_ids) = Children::::take(old_root_id) { + if let Some(root_children_ids) = deprecated::v1::storage::Children::::take(old_root_id) { new_root_node.children = root_children_ids.iter().copied().collect(); } // Add Children::take() weight @@ -153,11 +156,14 @@ mod v1 { new_nodes.insert(old_root_id, new_root_node); total_weight - }) + }); + frame_support::migration::remove_storage_prefix(>::name().as_bytes(), &deprecated::v1::storage::Children::::final_prefix()[..], b""); + + total_weight } fn migrate_nodes(new_nodes: &mut BTreeMap, DelegationNode>, initial_weight: Weight) -> Weight { - Delegations::::drain().fold(initial_weight, |mut total_weight, (old_node_id, old_node)| { + let total_weight = deprecated::v1::storage::Delegations:::: drain().fold(initial_weight, |mut total_weight, (old_node_id, old_node)| { let new_node_details = DelegationDetails:: { owner: old_node.owner, permissions: old_node.permissions, @@ -166,7 +172,7 @@ mod v1 { // In the old version, a parent None indicated the node is a child of the root. let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); let mut new_node = DelegationNode::new_node(old_node.root_id, new_node_parent_id, new_node_details); - if let Some(children_ids) = Children::::take(old_node_id) { + if let Some(children_ids) = deprecated::v1::storage::Children::::take(old_node_id) { new_node.children = children_ids.iter().copied().collect(); } // Add Children::take() weight @@ -176,7 +182,11 @@ mod v1 { new_nodes.insert(old_node_id, new_node); total_weight - }) + }); + frame_support::migration::remove_storage_prefix(>::name().as_bytes(), &deprecated::v1::storage::Delegations::::final_prefix()[..], b""); + frame_support::migration::remove_storage_prefix(>::name().as_bytes(), &deprecated::v1::storage::Children::::final_prefix()[..], b""); + + total_weight } fn finalize_children_nodes(new_nodes: &mut BTreeMap, DelegationNode>, initial_weight: Weight) -> Weight { @@ -214,6 +224,7 @@ mod v1 { !DelegationNodes::::iter().any(|(node_id, node)| { if let Some(parent_id) = node.parent { if let Some(parent_node) = DelegationNodes::::get(parent_id) { + // True if the children set does not contain the parent ID return !parent_node.children.contains(&node_id); } else { // If the parent node cannot be found, it is definitely an error. @@ -274,8 +285,8 @@ mod v1 { let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); let old_root_id = mock::get_delegation_id(true); let old_root_node = - crate::deprecated::v0::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); - Roots::insert(old_root_id, old_root_node.clone()); + crate::deprecated::v1::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); + deprecated::v1::storage::Roots::insert(old_root_id, old_root_node.clone()); assert!( pre_migrate::().is_ok(), @@ -289,9 +300,9 @@ mod v1 { "Post-migration for v1 should not fail." ); - assert_eq!(Roots::::iter_values().count(), 0); - assert_eq!(Delegations::::iter_values().count(), 0); - assert_eq!(Children::::iter_values().count(), 0); + assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); + assert_eq!(deprecated::v1::storage::Delegations::::iter_values().count(), 0); + assert_eq!(deprecated::v1::storage::Children::::iter_values().count(), 0); let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) .expect("New delegation hierarchy should exist in the storage."); @@ -315,26 +326,26 @@ mod v1 { let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); let old_root_id = mock::get_delegation_id(true); - let old_root_node = crate::deprecated::v0::DelegationRoot::::new( + let old_root_node = deprecated::v1::DelegationRoot::::new( ctype::mock::get_ctype_hash(true), alice.clone(), ); let old_node_id_1 = mock::get_delegation_id(false); - let old_node_1 = crate::deprecated::v0::DelegationNode::::new_root_child( + let old_node_1 = deprecated::v1::DelegationNode::::new_root_child( old_root_id, alice, Permissions::DELEGATE, ); let old_node_id_2 = mock::get_delegation_id_2(true); - let old_node_2 = crate::deprecated::v0::DelegationNode::::new_root_child( + let old_node_2 = deprecated::v1::DelegationNode::::new_root_child( old_root_id, bob, Permissions::ATTEST, ); - Roots::insert(old_root_id, old_root_node.clone()); - Delegations::insert(old_node_id_1, old_node_1.clone()); - Delegations::insert(old_node_id_2, old_node_2.clone()); - Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); + deprecated::v1::storage::Roots::insert(old_root_id, old_root_node.clone()); + deprecated::v1::storage::Delegations::insert(old_node_id_1, old_node_1.clone()); + deprecated::v1::storage::Delegations::insert(old_node_id_2, old_node_2.clone()); + deprecated::v1::storage::Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); assert!( pre_migrate::().is_ok(), @@ -348,9 +359,9 @@ mod v1 { "Post-migration for v1 should not fail." ); - assert_eq!(Roots::::iter_values().count(), 0); - assert_eq!(Delegations::::iter_values().count(), 0); - assert_eq!(Children::::iter_values().count(), 0); + assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); + assert_eq!(deprecated::v1::storage::Delegations::::iter_values().count(), 0); + assert_eq!(deprecated::v1::storage::Children::::iter_values().count(), 0); let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) .expect("New delegation hierarchy should exist in the storage."); @@ -382,6 +393,80 @@ mod v1 { assert_eq!(new_stored_node_2.details.revoked, old_node_2.revoked); }); } + + #[test] + fn ok_three_level_hierarchy() { + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::v1) + .build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = + deprecated::v1::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_parent_id = mock::get_delegation_id(false); + let old_parent_node = + deprecated::v1::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); + let old_node_id = mock::get_delegation_id_2(true); + let old_node = deprecated::v1::DelegationNode::::new_node_child( + old_root_id, + old_parent_id, + bob, + Permissions::ATTEST, + ); + deprecated::v1::storage::Roots::insert(old_root_id, old_root_node.clone()); + deprecated::v1::storage::Delegations::insert(old_parent_id, old_parent_node.clone()); + deprecated::v1::storage::Delegations::insert(old_node_id, old_node.clone()); + deprecated::v1::storage::Children::::insert(old_root_id, vec![old_parent_id]); + deprecated::v1::storage::Children::::insert(old_parent_id, vec![old_node_id]); + + assert!( + pre_migrate::().is_ok(), + "Pre-migration for v1 should not fail." + ); + + migrate::(); + + assert!( + post_migrate::().is_ok(), + "Post-migration for v1 should not fail." + ); + + assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); + assert_eq!(deprecated::v1::storage::Delegations::::iter_values().count(), 0); + assert_eq!(deprecated::v1::storage::Children::::iter_values().count(), 0); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert_eq!(new_stored_root.children.len(), 1); + assert!(new_stored_root.children.contains(&old_parent_id)); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + + let new_stored_parent = DelegationNodes::::get(old_parent_id) + .expect("New delegation parent should exist in the storage."); + assert_eq!(new_stored_parent.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_parent.parent, Some(old_root_id)); + assert_eq!(new_stored_parent.children.len(), 1); + assert!(new_stored_parent.children.contains(&old_node_id)); + assert_eq!(new_stored_parent.details.owner, old_parent_node.owner); + assert_eq!(new_stored_parent.details.revoked, old_parent_node.revoked); + + let new_stored_node = DelegationNodes::::get(old_node_id) + .expect("New delegation node should exist in the storage."); + assert_eq!(new_stored_node.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node.parent, Some(old_parent_id)); + assert!(new_stored_node.children.is_empty()); + assert_eq!(new_stored_node.details.owner, old_node.owner); + assert_eq!(new_stored_node.details.revoked, old_node.revoked); + }); + } } } From b26051955bb38dee0ec9b6f0c7d0e42ecda7c5b4 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 16 Jul 2021 15:28:13 +0200 Subject: [PATCH 28/49] chore: refactor import/export --- .../delegation/src/delegation_hierarchy.rs | 2 +- pallets/delegation/src/deprecated.rs | 43 +++--------------- pallets/delegation/src/lib.rs | 6 +-- pallets/delegation/src/migrations.rs | 45 ++++++++++++------- pallets/delegation/src/mock.rs | 8 ++-- 5 files changed, 44 insertions(+), 60 deletions(-) diff --git a/pallets/delegation/src/delegation_hierarchy.rs b/pallets/delegation/src/delegation_hierarchy.rs index bf5543b577..1763bfb2bb 100644 --- a/pallets/delegation/src/delegation_hierarchy.rs +++ b/pallets/delegation/src/delegation_hierarchy.rs @@ -108,7 +108,7 @@ impl DelegationDetails { } #[derive(Clone, Debug, Encode, Decode, Eq, PartialEq, Ord, PartialOrd)] -pub struct DelegationHierarchyInfo { +pub struct DelegationHierarchyDetails { pub ctype_hash: CtypeHashOf, } diff --git a/pallets/delegation/src/deprecated.rs b/pallets/delegation/src/deprecated.rs index 3acd2c866f..21c78ca562 100644 --- a/pallets/delegation/src/deprecated.rs +++ b/pallets/delegation/src/deprecated.rs @@ -21,15 +21,10 @@ pub(crate) mod v1 { use crate::*; - /// A node representing a delegation hierarchy root. #[derive(Clone, Debug, Encode, Decode, PartialEq)] pub struct DelegationRoot { - /// The hash of the CTYPE that delegated attesters within this trust - /// hierarchy can attest. pub(crate) ctype_hash: CtypeHashOf, - /// The identifier of the root owner. pub(crate) owner: DelegatorIdOf, - /// The flag indicating whether the root has been revoked or not. pub(crate) revoked: bool, } @@ -44,33 +39,16 @@ pub(crate) mod v1 { } } - /// A node representing a node in the delegation hierarchy. #[derive(Clone, Debug, Encode, Decode, PartialEq)] pub struct DelegationNode { - /// The ID of the delegation hierarchy root. pub(crate) root_id: DelegationNodeIdOf, - /// \[OPTIONAL\] The ID of the parent node. If None, the node is - /// considered a direct child of the root node. pub(crate) parent: Option>, - /// The identifier of the owner of the delegation node, i.e., the - /// delegate. pub(crate) owner: DelegatorIdOf, - /// The permission flags for the operations the delegate is allowed to - /// perform. pub(crate) permissions: Permissions, - /// The flag indicating whether the delegation has been revoked or not. pub(crate) revoked: bool, } impl DelegationNode { - /// Create a new delegation node that is a direct descendent of the - /// given root. - /// - /// * root_id: the root node ID this node will be a child of - /// * owner: the identifier of the owner of the new delegation, i.e., - /// the new delegate - /// * permissions: the permission flags for the operations the delegate - /// is allowed to perform #[cfg(test)] pub(crate) fn new_root_child( root_id: DelegationNodeIdOf, @@ -86,15 +64,6 @@ pub(crate) mod v1 { } } - /// Creates a new delegation node that is a direct descendent of the - /// given node. - /// - /// * root_id: the root node ID this node will be a child of - /// * parent - the parent node ID this node will be a child of - /// * owner: the identifier of the owner of the new delegation, i.e., - /// the new delegate - /// * permissions: the permission flags for the operations the delegate - /// is allowed to perform #[cfg(test)] pub(crate) fn new_node_child( root_id: DelegationNodeIdOf, @@ -113,10 +82,10 @@ pub(crate) mod v1 { } pub(crate) mod storage { - pub use frame_support::{decl_module, decl_storage}; - pub use sp_std::prelude::*; + use frame_support::{decl_module, decl_storage}; + use sp_std::prelude::*; - use crate::Config; + use super::*; decl_module! { pub struct OldPallet for enum Call where origin: T::Origin {} @@ -124,9 +93,9 @@ pub(crate) mod v1 { decl_storage! { trait Store for OldPallet as Delegation { - pub(crate) Roots get(fn roots): map hasher(blake2_128_concat) crate::DelegationNodeIdOf => Option>; - pub(crate) Delegations get(fn delegations): map hasher(blake2_128_concat) crate::DelegationNodeIdOf => Option>; - pub(crate) Children get(fn children): map hasher(blake2_128_concat) crate::DelegationNodeIdOf => Option>>; + pub(crate) Roots get(fn roots): map hasher(blake2_128_concat) DelegationNodeIdOf => Option>; + pub(crate) Delegations get(fn delegations): map hasher(blake2_128_concat) DelegationNodeIdOf => Option>; + pub(crate) Children get(fn children): map hasher(blake2_128_concat) DelegationNodeIdOf => Option>>; } } } diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 6b9ca61c02..9deb7cd7cf 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -127,7 +127,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn delegation_hierarchies)] pub type DelegationHierarchies = - StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, DelegationHierarchyInfo>; + StorageMap<_, Blake2_128Concat, DelegationNodeIdOf, DelegationHierarchyDetails>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -225,7 +225,7 @@ pub mod pallet { Self::create_and_store_new_hierarchy( root_node_id, - DelegationHierarchyInfo:: { ctype_hash }, + DelegationHierarchyDetails:: { ctype_hash }, creator.clone(), ); @@ -450,7 +450,7 @@ impl Pallet { fn create_and_store_new_hierarchy( root_id: DelegationNodeIdOf, - hierarchy_info: DelegationHierarchyInfo, + hierarchy_info: DelegationHierarchyDetails, hierarchy_owner: DelegatorIdOf, ) { let root_node = DelegationNode::new_root_node(root_id, DelegationDetails::default_with_owner(hierarchy_owner)); diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 4e7f0c7de7..8b31f2592f 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -16,10 +16,8 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org -use sp_std::marker::PhantomData; - use codec::{Decode, Encode}; -use sp_std::collections::btree_map::BTreeMap; +use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData}; use crate::*; @@ -51,7 +49,7 @@ impl DelegationStorageVersion { // the old storage entries. impl Default for DelegationStorageVersion { fn default() -> Self { - Self::v2 + Self::v1 } } @@ -84,7 +82,6 @@ mod v1 { use super::*; use frame_support::{IterableStorageMap, StoragePrefixedMap, StorageMap}; - use frame_support::traits::PalletInfoAccess; #[cfg(any(feature = "try-runtime", test))] pub(crate) fn pre_migrate() -> Result<(), &'static str> { @@ -128,8 +125,8 @@ mod v1 { } fn migrate_roots(new_nodes: &mut BTreeMap, DelegationNode>) -> Weight { - let total_weight = deprecated::v1::storage::Roots::::drain().fold(0u64, |mut total_weight, (old_root_id, old_root_node)| { - let new_hierarchy_info = DelegationHierarchyInfo:: { + let total_weight = deprecated::v1::storage::Roots::::iter().fold(0u64, |mut total_weight, (old_root_id, old_root_node)| { + let new_hierarchy_info = DelegationHierarchyDetails:: { ctype_hash: old_root_node.ctype_hash, }; let new_root_details = DelegationDetails:: { @@ -157,13 +154,13 @@ mod v1 { total_weight }); - frame_support::migration::remove_storage_prefix(>::name().as_bytes(), &deprecated::v1::storage::Children::::final_prefix()[..], b""); + frame_support::migration::remove_storage_prefix(&deprecated::v1::storage::Roots::::module_prefix()[..], &deprecated::v1::storage::Roots::::storage_prefix()[..], b""); total_weight } fn migrate_nodes(new_nodes: &mut BTreeMap, DelegationNode>, initial_weight: Weight) -> Weight { - let total_weight = deprecated::v1::storage::Delegations:::: drain().fold(initial_weight, |mut total_weight, (old_node_id, old_node)| { + let total_weight = deprecated::v1::storage::Delegations::::iter().fold(initial_weight, |mut total_weight, (old_node_id, old_node)| { let new_node_details = DelegationDetails:: { owner: old_node.owner, permissions: old_node.permissions, @@ -183,8 +180,8 @@ mod v1 { total_weight }); - frame_support::migration::remove_storage_prefix(>::name().as_bytes(), &deprecated::v1::storage::Delegations::::final_prefix()[..], b""); - frame_support::migration::remove_storage_prefix(>::name().as_bytes(), &deprecated::v1::storage::Children::::final_prefix()[..], b""); + frame_support::migration::remove_storage_prefix(&deprecated::v1::storage::Delegations::::module_prefix()[..], &deprecated::v1::storage::Delegations::::storage_prefix()[..], b""); + frame_support::migration::remove_storage_prefix(&deprecated::v1::storage::Children::::module_prefix()[..], &deprecated::v1::storage::Children::::storage_prefix()[..], b""); total_weight } @@ -237,11 +234,10 @@ mod v1 { #[cfg(test)] mod tests { - use super::*; - use sp_core::Pair; - use mock::Test as TestRuntime; + use crate::mock::Test as TestRuntime; + use super::*; #[test] fn fail_version_higher() { @@ -530,7 +526,7 @@ impl DelegationStorageMigrator { mod tests { use super::*; - use mock::Test as TestRuntime; + use crate::mock::Test as TestRuntime; #[test] fn ok_from_v1_migration() { @@ -551,4 +547,23 @@ mod tests { ); }); } + + #[test] + fn ok_from_default_migration() { + let mut ext = mock::ExtBuilder::default() + .build(None); + ext.execute_with(|| { + assert!( + DelegationStorageMigrator::::pre_migrate().is_ok(), + "Storage pre-migrate from default version should not fail." + ); + + DelegationStorageMigrator::::migrate(); + + assert!( + DelegationStorageMigrator::::post_migrate().is_ok(), + "Storage post-migrate from default version should not fail." + ); + }); + } } diff --git a/pallets/delegation/src/mock.rs b/pallets/delegation/src/mock.rs index 7c43780936..5d6aaeb562 100644 --- a/pallets/delegation/src/mock.rs +++ b/pallets/delegation/src/mock.rs @@ -215,8 +215,8 @@ pub(crate) fn hash_to_u8(hash: T) -> Vec { hash.encode() } -pub fn generate_base_delegation_hierarchy_info() -> DelegationHierarchyInfo { - DelegationHierarchyInfo { +pub fn generate_base_delegation_hierarchy_info() -> DelegationHierarchyDetails { + DelegationHierarchyDetails { ctype_hash: ctype_mock::get_ctype_hash(true), } } @@ -312,7 +312,7 @@ pub fn generate_base_delegation_revocation_operation( #[derive(Clone)] pub struct ExtBuilder { ctype_builder: Option, - delegation_hierarchies_stored: Vec<(TestDelegationNodeId, DelegationHierarchyInfo, DelegatorIdOf)>, + delegation_hierarchies_stored: Vec<(TestDelegationNodeId, DelegationHierarchyDetails, DelegatorIdOf)>, delegations_stored: Vec<(TestDelegationNodeId, DelegationNode)>, storage_version: DelegationStorageVersion, } @@ -331,7 +331,7 @@ impl Default for ExtBuilder { impl ExtBuilder { pub fn with_delegation_hierarchies( mut self, - delegation_hierarchies: Vec<(TestDelegationNodeId, DelegationHierarchyInfo, DelegatorIdOf)>, + delegation_hierarchies: Vec<(TestDelegationNodeId, DelegationHierarchyDetails, DelegatorIdOf)>, ) -> Self { self.delegation_hierarchies_stored = delegation_hierarchies; self From c68e3f3ac55ba92c55c8bc100015183bc86f97c9 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 16 Jul 2021 16:16:05 +0200 Subject: [PATCH 29/49] doc: refine documentation --- pallets/attestation/src/tests.rs | 74 +++--- .../delegation/src/delegation_hierarchy.rs | 20 ++ pallets/delegation/src/deprecated.rs | 1 + pallets/delegation/src/lib.rs | 22 +- pallets/delegation/src/migrations.rs | 60 ++++- pallets/delegation/src/mock.rs | 2 +- pallets/delegation/src/tests.rs | 242 +++++++++--------- 7 files changed, 245 insertions(+), 176 deletions(-) diff --git a/pallets/attestation/src/tests.rs b/pallets/attestation/src/tests.rs index 7ea2e2e28d..7e47fd08b5 100644 --- a/pallets/attestation/src/tests.rs +++ b/pallets/attestation/src/tests.rs @@ -62,9 +62,9 @@ fn attest_with_delegation_successful() { let attester = get_ed25519_account(attester_keypair.public()); let claim_hash = get_claim_hash(true); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -80,7 +80,7 @@ fn attest_with_delegation_successful() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, attester.clone())]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); @@ -196,9 +196,9 @@ fn delegation_revoked_attest_error() { let attester_keypair = get_alice_ed25519(); let attester = get_ed25519_account(attester_keypair.public()); let claim_hash = get_claim_hash(true); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -215,7 +215,7 @@ fn delegation_revoked_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, attester.clone())]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); @@ -239,9 +239,9 @@ fn not_delegation_owner_attest_error() { let alternative_owner_keypair = get_bob_ed25519(); let alternative_owner = get_ed25519_account(alternative_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -257,7 +257,7 @@ fn not_delegation_owner_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, attester.clone())]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); @@ -279,9 +279,9 @@ fn unauthorised_permissions_attest_error() { let attester_keypair = get_alice_ed25519(); let attester = get_ed25519_account(attester_keypair.public()); let claim_hash = get_claim_hash(true); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); // Delegation node does not have permissions to attest. let (delegation_id, delegation_node) = ( @@ -297,7 +297,7 @@ fn unauthorised_permissions_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, attester.clone())]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); @@ -319,9 +319,9 @@ fn root_not_present_attest_error() { let attester_keypair = get_alice_ed25519(); let attester = get_ed25519_account(attester_keypair.public()); let claim_hash = get_claim_hash(true); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); let alternative_hierarchy_root_id = delegation_mock::get_delegation_hierarchy_id(false); let (delegation_id, mut delegation_node) = ( @@ -342,7 +342,7 @@ fn root_not_present_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(alternative_hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegation_hierarchies(vec![(alternative_hierarchy_root_id, hierarchy_details, attester.clone())]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); @@ -365,11 +365,11 @@ fn root_ctype_mismatch_attest_error() { let attester = get_ed25519_account(attester_keypair.public()); let claim_hash = get_claim_hash(true); let alternative_ctype_hash = ctype_mock::get_ctype_hash(false); - let (hierarchy_root_id, mut hierarchy_info) = ( + let (hierarchy_root_id, mut hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); - hierarchy_info.ctype_hash = alternative_ctype_hash; + hierarchy_details.ctype_hash = alternative_ctype_hash; let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), delegation_mock::generate_base_delegation_node(hierarchy_root_id, attester.clone(), Some(hierarchy_root_id)), @@ -384,7 +384,7 @@ fn root_ctype_mismatch_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, attester.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, attester.clone())]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); @@ -442,9 +442,9 @@ fn revoke_with_delegation_successful() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -464,7 +464,7 @@ fn revoke_with_delegation_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() @@ -494,9 +494,9 @@ fn revoke_with_parent_delegation_successful() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), @@ -519,7 +519,7 @@ fn revoke_with_parent_delegation_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() @@ -548,9 +548,9 @@ fn revoke_parent_delegation_no_attestation_permissions_successful() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), @@ -573,7 +573,7 @@ fn revoke_parent_delegation_no_attestation_permissions_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() @@ -602,9 +602,9 @@ fn revoke_parent_delegation_with_direct_delegation_revoked_successful() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); let (parent_id, mut parent_node) = ( delegation_mock::get_delegation_id(true), @@ -628,7 +628,7 @@ fn revoke_parent_delegation_with_direct_delegation_revoked_successful() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() @@ -748,9 +748,9 @@ fn max_parent_lookups_revoke_error() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( delegation_mock::get_delegation_id(true), @@ -771,7 +771,7 @@ fn max_parent_lookups_revoke_error() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() @@ -798,9 +798,9 @@ fn revoked_delegation_revoke_error() { let attestation_owner = get_ed25519_account(attestation_owner_keypair.public()); let claim_hash = get_claim_hash(true); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( delegation_mock::get_delegation_hierarchy_id(true), - delegation_mock::generate_base_delegation_hierarchy_info(), + delegation_mock::generate_base_delegation_hierarchy_details(), ); let (delegation_id, mut delegation_node) = ( delegation_mock::get_delegation_id(true), @@ -817,7 +817,7 @@ fn revoked_delegation_revoke_error() { .with_ctypes(vec![(attestation.ctype_hash, revoker.clone())]) .build(None); let ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); let mut ext = ExtBuilder::default() diff --git a/pallets/delegation/src/delegation_hierarchy.rs b/pallets/delegation/src/delegation_hierarchy.rs index 1763bfb2bb..5ee0b0c55c 100644 --- a/pallets/delegation/src/delegation_hierarchy.rs +++ b/pallets/delegation/src/delegation_hierarchy.rs @@ -54,15 +54,24 @@ impl Default for Permissions { } } +/// A node in a delegation hierarchy. +/// +/// For quicker lookups of the hierarchy details, all nodes maintain a direct link to the hierarchy root node. +/// Furthermore, all nodes have a parent but the root nodes, which point to themselves for the hierarchy root node link. #[derive(Clone, Debug, Encode, Decode, PartialEq)] pub struct DelegationNode { + /// The ID of the delegation hierarchy the node is part of. pub hierarchy_root_id: DelegationNodeIdOf, + /// The ID of the parent. For all but root nodes this is not None. pub parent: Option>, + /// The set of IDs of all the children nodes. pub children: BTreeSet>, + /// The additional information attached to the delegation node. pub details: DelegationDetails, } impl DelegationNode { + /// Creates a new delegation root node with the given ID and delegation details. pub fn new_root_node(id: DelegationNodeIdOf, details: DelegationDetails) -> Self { Self { hierarchy_root_id: id, @@ -72,6 +81,7 @@ impl DelegationNode { } } + /// Creates a new delegation node under the given hierarchy ID, with the given parent and delegation details. pub fn new_node( hierarchy_root_id: DelegationNodeIdOf, parent: DelegationNodeIdOf, @@ -85,19 +95,27 @@ impl DelegationNode { } } + /// Adds a node by its ID to the current node's children. pub fn add_child(&mut self, child_id: DelegationNodeIdOf) { self.children.insert(child_id); } } +/// Delegation information attached to delegation nodes. #[derive(Clone, Debug, Encode, Decode, PartialEq)] pub struct DelegationDetails { + /// The owner of the delegation (and its node). pub owner: DelegatorIdOf, + /// Status indicating whether the delegation has been revoked (true) or not (false). pub revoked: bool, + /// The set of permissions associated with the delegation. pub permissions: Permissions, } impl DelegationDetails { + /// Creates new delegation details including the given owner. + /// + /// The default revocation status is false and all permissions are granted by default. pub fn default_with_owner(owner: DelegatorIdOf) -> Self { Self { owner, @@ -107,8 +125,10 @@ impl DelegationDetails { } } +/// The details associated with a delegation hierarchy. #[derive(Clone, Debug, Encode, Decode, Eq, PartialEq, Ord, PartialOrd)] pub struct DelegationHierarchyDetails { + /// The authorised CTYPE hash that attesters can attest using this delegation hierarchy. pub ctype_hash: CtypeHashOf, } diff --git a/pallets/delegation/src/deprecated.rs b/pallets/delegation/src/deprecated.rs index 21c78ca562..51c25a66f8 100644 --- a/pallets/delegation/src/deprecated.rs +++ b/pallets/delegation/src/deprecated.rs @@ -16,6 +16,7 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org +/// Deprecated types used in version 1. pub(crate) mod v1 { use codec::{Decode, Encode}; diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 9deb7cd7cf..3b44807bad 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -109,7 +109,7 @@ pub mod pallet { } } - /// Contains the latest version migrator used. + /// Contains the latest storage version deployed. #[pallet::storage] #[pallet::getter(fn last_version_migration_used)] pub(crate) type StorageVersion = StorageValue<_, DelegationStorageVersion, ValueQuery>; @@ -201,7 +201,7 @@ pub mod pallet { /// adding children delegations to the root. /// /// * origin: the identifier of the delegation creator - /// * root_id: the ID of the root node. It has to be unique + /// * root_node_id: the ID of the root node. It has to be unique /// * ctype_hash: the CTYPE hash that delegates can use for attestations #[pallet::weight(::WeightInfo::create_hierarchy())] pub fn create_hierarchy( @@ -318,7 +318,7 @@ pub mod pallet { Ok(()) } - /// Revoke a delegation root. + /// Revoke a delegation hierarchy starting from its root node. /// /// Revoking a delegation root results in the whole trust hierarchy /// being revoked. Nevertheless, revocation starts from the leave nodes @@ -328,7 +328,7 @@ pub mod pallet { /// the whole trust hierarchy is to be considered revoked. /// /// * origin: the identifier of the revoker - /// * root_id: the ID of the delegation root to revoke + /// * root_node_id: the ID of the delegation root node to revoke /// * max_children: the maximum number of nodes descending from the root /// to revoke as a consequence of the root revocation #[pallet::weight(::WeightInfo::revoke_hierarchy(*max_children))] @@ -434,7 +434,7 @@ pub mod pallet { } impl Pallet { - // Calculate the hash of all values of a delegation creation transaction + // Calculates the hash of all values of a delegation creation transaction. fn calculate_delegation_creation_hash( delegation_id: &DelegationNodeIdOf, parent_id: &DelegationNodeIdOf, @@ -448,16 +448,20 @@ impl Pallet { T::Hashing::hash(&hashed_values) } + // Creates a new root node with the given details and store the new hierarchy in the hierarchies storage and the new root node in the nodes storage. fn create_and_store_new_hierarchy( root_id: DelegationNodeIdOf, - hierarchy_info: DelegationHierarchyDetails, + hierarchy_details: DelegationHierarchyDetails, hierarchy_owner: DelegatorIdOf, ) { let root_node = DelegationNode::new_root_node(root_id, DelegationDetails::default_with_owner(hierarchy_owner)); >::insert(root_id, root_node); - >::insert(root_id, hierarchy_info); + >::insert(root_id, hierarchy_details); } + // Adds the given node to the storage and updates the parent node to include the given node as child. + // + // This function assumes that the parent node is already stored on the chain. If not, the behaviour of the system is undefined. fn store_delegation_under_parent( delegation_id: DelegationNodeIdOf, delegation_node: DelegationNode, @@ -470,6 +474,7 @@ impl Pallet { >::insert(parent_id, parent_node); } + // Marks the provided hierarchy as revoked and stores the resulting state back in the storage. fn revoke_and_store_hierarchy_root(root_id: DelegationNodeIdOf, mut root_node: DelegationNode) { root_node.details.revoked = true; >::insert(root_id, root_node); @@ -494,9 +499,6 @@ impl Pallet { if &delegation_node.details.owner == identity { Ok((!delegation_node.details.revoked, 0u32)) } else { - // Counter is decreased regardless of whether we are checking the parent node - // next of the root node, as the root node is as a matter of fact the top node's - // parent. let remaining_lookups = max_parent_checks .checked_sub(1) .ok_or(Error::::MaxSearchDepthReached)?; diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 8b31f2592f..62358ad07f 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -21,6 +21,9 @@ use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData}; use crate::*; +/// A trait that allows version migrators to access the underlying pallet's context, i.e., its Config trait. +/// +/// In this way, the migrator can access the pallet's storage and the pallet's types directly. pub trait VersionMigratorTrait { #[cfg(any(feature = "try-runtime", test))] fn pre_migrate(&self) -> Result<(), &str>; @@ -29,6 +32,7 @@ pub trait VersionMigratorTrait { fn post_migrate(&self) -> Result<(), &str>; } +/// Storage version of the delegation pallet. #[allow(non_camel_case_types)] #[derive(Copy, Clone, Encode, Eq, Decode, Ord, PartialEq, PartialOrd)] pub enum DelegationStorageVersion { @@ -38,15 +42,18 @@ pub enum DelegationStorageVersion { #[allow(dead_code)] impl DelegationStorageVersion { + /// The latest storage version. fn latest() -> Self { Self::v2 } } // All nodes will default to this, which is not bad, as in case the "real" -// version is the latest one (i.e. the node has been started with already the +// version is a later one (i.e. the node has been started with already the // latest version), the migration will simply do nothing as there's nothing in -// the old storage entries. +// the old storage entries to migrate from. +// +// It might get updated in the future when we know that no node is running this old version anymore. impl Default for DelegationStorageVersion { fn default() -> Self { Self::v1 @@ -54,6 +61,7 @@ impl Default for DelegationStorageVersion { } impl VersionMigratorTrait for DelegationStorageVersion { + // It runs the right pre_migrate logic depending on the current storage version. #[cfg(any(feature = "try-runtime", test))] fn pre_migrate(&self) -> Result<(), &str> { match *self { @@ -62,6 +70,7 @@ impl VersionMigratorTrait for DelegationStorageVersion { } } + // It runs the righ migration logic depending on the current storage version. fn migrate(&self) -> Weight { match *self { Self::v1 => v1::migrate::(), @@ -69,6 +78,7 @@ impl VersionMigratorTrait for DelegationStorageVersion { } } + // It runs the right post_migrate logic depending on the current storage version. #[cfg(any(feature = "try-runtime", test))] fn post_migrate(&self) -> Result<(), &str> { match *self { @@ -83,6 +93,12 @@ mod v1 { use frame_support::{IterableStorageMap, StoragePrefixedMap, StorageMap}; + /// Checks whether the deployed storage version is v1. If not, it won't try migrate any data. + /// + /// Since we have the default storage version to this one, it can happen that new nodes will + /// still try to perform runtime migrations. This is not a problem as at the end of the day there + /// will not be anything in the old storage entries to migrate from. Hence, the "pseudo-"migration will + /// simply result in the update of the storage deployed version. #[cfg(any(feature = "try-runtime", test))] pub(crate) fn pre_migrate() -> Result<(), &'static str> { ensure!( @@ -94,6 +110,12 @@ mod v1 { Ok(()) } + /// It migrates the old storage entries to the new ones. + /// + /// Specifically, for each entry in Roots, a new entry in DelegationHierarchies + /// + a new node in DelegationNodes is created. Furthermore, nodes + /// in Delegations are migrated to the new structure and stored under DelegationNodes, + /// with any children from the Children storage entry added to the nodes under the children set. pub(crate) fn migrate() -> Weight { log::info!("v1 -> v2 delegation storage migrator started!"); let mut total_weight = 0u64; @@ -116,7 +138,7 @@ mod v1 { total_weight = total_weight.saturating_add(finalize_children_nodes::(&mut new_nodes, total_weight)); StorageVersion::::set(DelegationStorageVersion::v2); - // Adds a write from StorageVersion::set() weight + // Adds a write from StorageVersion::set() weight. total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); log::debug!("Total weight consumed: {}", total_weight); log::info!("v1 -> v2 delegation storage migrator finished!"); @@ -126,7 +148,7 @@ mod v1 { fn migrate_roots(new_nodes: &mut BTreeMap, DelegationNode>) -> Weight { let total_weight = deprecated::v1::storage::Roots::::iter().fold(0u64, |mut total_weight, (old_root_id, old_root_node)| { - let new_hierarchy_info = DelegationHierarchyDetails:: { + let new_hierarchy_details = DelegationHierarchyDetails:: { ctype_hash: old_root_node.ctype_hash, }; let new_root_details = DelegationDetails:: { @@ -145,7 +167,7 @@ mod v1 { // Add Children::take() weight total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - DelegationHierarchies::insert(old_root_id, new_hierarchy_info); + DelegationHierarchies::insert(old_root_id, new_hierarchy_details); // Adds a read from Roots::drain() and a write from // DelegationHierarchies::insert() weights total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); @@ -154,6 +176,7 @@ mod v1 { total_weight }); + // Removes the whole Roots storage. frame_support::migration::remove_storage_prefix(&deprecated::v1::storage::Roots::::module_prefix()[..], &deprecated::v1::storage::Roots::::storage_prefix()[..], b""); total_weight @@ -180,6 +203,7 @@ mod v1 { total_weight }); + // Removes the whole Delegations and Children storages. frame_support::migration::remove_storage_prefix(&deprecated::v1::storage::Delegations::::module_prefix()[..], &deprecated::v1::storage::Delegations::::storage_prefix()[..], b""); frame_support::migration::remove_storage_prefix(&deprecated::v1::storage::Children::::module_prefix()[..], &deprecated::v1::storage::Children::::storage_prefix()[..], b""); @@ -188,12 +212,13 @@ mod v1 { fn finalize_children_nodes(new_nodes: &mut BTreeMap, DelegationNode>, initial_weight: Weight) -> Weight { new_nodes.clone().into_iter().fold(initial_weight, |mut total_weight, (new_node_id, new_node)| { + // Iterate over the children of every node and update their parent link. new_node.children.iter().for_each(|child_id| { new_nodes .entry(*child_id) .and_modify(|node| node.parent = Some(new_node_id)); }); - // We can then finally insert the new delegation node in the storage. + // We can then finally insert the new delegation node in the storage as it won't be updated anymore during the migration. DelegationNodes::::insert(new_node_id, new_node); // Adds a write from DelegationNodes::insert() weight total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); @@ -202,6 +227,7 @@ mod v1 { }) } + /// Checks whether the deployed storage version is v2 and whether any parent-child link has gone missing. #[cfg(any(feature = "try-runtime", test))] pub(crate) fn post_migrate() -> Result<(), &'static str> { ensure!( @@ -216,22 +242,26 @@ mod v1 { Ok(()) } + // Verifies that for any node that has a parent, the parent includes the node in its children. #[cfg(any(feature = "try-runtime", test))] fn verify_parent_children_integrity() -> bool { + // If all's good and false is returned, returns true. !DelegationNodes::::iter().any(|(node_id, node)| { if let Some(parent_id) = node.parent { if let Some(parent_node) = DelegationNodes::::get(parent_id) { // True if the children set does not contain the parent ID return !parent_node.children.contains(&node_id); } else { - // If the parent node cannot be found, it is definitely an error. + // If the parent node cannot be found, it is definitely an error, so return true. return true; } } + // If all's good we keep returning false. false }) } + // Tests for the v1 storage migrator. #[cfg(test)] mod tests { use sp_core::Pair; @@ -466,16 +496,23 @@ mod v1 { } } +/// The delegation pallet's storage migrator, which handles all version migrations in a sequential fashion. +/// +/// If a node has missed on more than one upgrade, the migrator will apply the needed migrations one after the other. +/// Otherwise, if no migration is needed, the migrator will simply not do anything. pub struct DelegationStorageMigrator(PhantomData); impl DelegationStorageMigrator { + // Contains the migration sequence logic. fn get_next_storage_version(current: DelegationStorageVersion) -> Option { + // If the version current deployed is at least v1, there is no more migrations to run (other than the one from v1). match current { DelegationStorageVersion::v1 => None, DelegationStorageVersion::v2 => None, } } + /// Checks whether the latest storage version deployed is lower than the latest possible. #[cfg(any(feature = "try-runtime", test))] pub(crate) fn pre_migrate() -> Result<(), &'static str> { ensure!( @@ -490,27 +527,35 @@ impl DelegationStorageMigrator { Ok(()) } + /// Applies all the needed migrations from the currently deployed version to the latest possible, one after the other. + /// + /// It returns the total weight consumed by ALL the migrations applied. pub(crate) fn migrate() -> Weight { let mut current_version: Option = Some(StorageVersion::::get()); + // Weight for StorageVersion::get(). let mut total_weight = T::DbWeight::get().reads(1); while let Some(ver) = current_version { + // If any of the needed migrations pre-checks fail, the whole chain panics (during tests). #[cfg(feature = "try-runtime")] if let Err(err) = >::pre_migrate(&ver) { panic!("{:?}", err); } let consumed_weight = >::migrate(&ver); total_weight = total_weight.saturating_add(consumed_weight); + // If any of the needed migrations post-checks fail, the whole chain panics (during tests). #[cfg(feature = "try-runtime")] if let Err(err) = >::post_migrate(&ver) { panic!("{:?}", err); } + // If more migrations should be applied, current_version will not be None. current_version = Self::get_next_storage_version(ver); } total_weight } + /// Checks whether the storage version after all the needed migrations match the latest one. #[cfg(any(feature = "try-runtime", test))] pub(crate) fn post_migrate() -> Result<(), &'static str> { ensure!( @@ -522,6 +567,7 @@ impl DelegationStorageMigrator { } } +// Tests for the entire storage migrator. #[cfg(test)] mod tests { use super::*; diff --git a/pallets/delegation/src/mock.rs b/pallets/delegation/src/mock.rs index 5d6aaeb562..0154acab49 100644 --- a/pallets/delegation/src/mock.rs +++ b/pallets/delegation/src/mock.rs @@ -215,7 +215,7 @@ pub(crate) fn hash_to_u8(hash: T) -> Vec { hash.encode() } -pub fn generate_base_delegation_hierarchy_info() -> DelegationHierarchyDetails { +pub fn generate_base_delegation_hierarchy_details() -> DelegationHierarchyDetails { DelegationHierarchyDetails { ctype_hash: ctype_mock::get_ctype_hash(true), } diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index 3584a5b800..245086c24b 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -68,9 +68,9 @@ fn duplicate_create_root_delegation_error() { let creator_keypair = get_alice_ed25519(); let creator = get_ed25519_account(creator_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let operation = generate_base_delegation_hierarchy_creation_operation(hierarchy_root_id); @@ -79,7 +79,7 @@ fn duplicate_create_root_delegation_error() { .with_ctypes(vec![(operation.ctype_hash, creator.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, creator.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -119,9 +119,9 @@ fn create_delegation_direct_root_successful() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (delegation_id, delegation_node) = ( get_delegation_id(true), @@ -140,10 +140,10 @@ fn create_delegation_direct_root_successful() { generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, creator.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, creator.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -183,9 +183,9 @@ fn create_delegation_with_parent_successful() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -208,10 +208,10 @@ fn create_delegation_with_parent_successful() { generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, creator.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, creator.clone())]) .with_delegations(vec![(parent_id, parent_node)]) .build(Some(ext)); @@ -253,9 +253,9 @@ fn invalid_delegate_signature_create_delegation_error() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (delegation_id, delegation_node) = ( get_delegation_id(true), @@ -272,10 +272,10 @@ fn invalid_delegate_signature_create_delegation_error() { generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, creator.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, creator.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -300,9 +300,9 @@ fn duplicate_delegation_create_delegation_error() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (delegation_id, delegation_node) = ( get_delegation_id(true), @@ -319,10 +319,10 @@ fn duplicate_delegation_create_delegation_error() { generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node.clone()); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, creator.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, creator.clone())]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); @@ -348,9 +348,9 @@ fn parent_not_existing_create_delegation_error() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (delegation_id, delegation_node) = ( get_delegation_id(true), @@ -367,7 +367,7 @@ fn parent_not_existing_create_delegation_error() { generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, creator.clone())]) .build(None); // No delegations added to the pallet storage let mut ext = ExtBuilder::default().build(Some(ext)); @@ -396,9 +396,9 @@ fn not_owner_of_parent_create_delegation_error() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -419,10 +419,10 @@ fn not_owner_of_parent_create_delegation_error() { generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, creator.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, creator.clone())]) .with_delegations(vec![(parent_id, parent_node)]) .build(Some(ext)); @@ -448,9 +448,9 @@ fn unauthorised_delegation_create_delegation_error() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, mut parent_node) = ( get_delegation_id(true), @@ -472,10 +472,10 @@ fn unauthorised_delegation_create_delegation_error() { generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, creator.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, creator.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, creator.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, creator.clone())]) .with_delegations(vec![(parent_id, parent_node)]) .build(Some(ext)); @@ -501,18 +501,18 @@ fn empty_revoke_root_successful() { let revoker_keypair = get_alice_ed25519(); let revoker = get_ed25519_account(revoker_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -537,9 +537,9 @@ fn list_hierarchy_revoke_root_successful() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -554,10 +554,10 @@ fn list_hierarchy_revoke_root_successful() { operation.max_children = 2u32; let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -591,9 +591,9 @@ fn tree_hierarchy_revoke_root_successful() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (delegation1_id, delegation1_node) = ( get_delegation_id(true), @@ -608,10 +608,10 @@ fn tree_hierarchy_revoke_root_successful() { operation.max_children = 2u32; let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![ (delegation1_id, delegation1_node), (delegation2_id, delegation2_node), @@ -649,9 +649,9 @@ fn max_max_revocations_revoke_successful() { let delegate_keypair = get_bob_sr25519(); let delegate = get_sr25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -666,10 +666,10 @@ fn max_max_revocations_revoke_successful() { operation.max_children = MaxRevocations::get(); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -722,18 +722,18 @@ fn different_root_creator_revoke_root_error() { let alternative_revoker_keypair = get_charlie_ed25519(); let alternative_revoker = get_ed25519_account(alternative_revoker_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let operation = generate_base_delegation_hierarchy_revocation_operation(hierarchy_root_id); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, alternative_revoker)]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, alternative_revoker)]) .build(Some(ext)); ext.execute_with(|| { @@ -751,9 +751,9 @@ fn too_small_max_revocations_revoke_root_error() { let delegate_keypair = get_alice_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (delegation_id, delegation_node) = ( get_delegation_id(false), @@ -764,10 +764,10 @@ fn too_small_max_revocations_revoke_root_error() { operation.max_children = 0u32; let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); @@ -786,9 +786,9 @@ fn exact_children_max_revocations_revoke_root_error() { let delegate_keypair = get_alice_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (delegation1_id, delegation1_node) = ( get_delegation_id(true), @@ -807,10 +807,10 @@ fn exact_children_max_revocations_revoke_root_error() { operation.max_children = 2u32; let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![ (delegation1_id, delegation1_node), (delegation2_id, delegation2_node), @@ -859,9 +859,9 @@ fn direct_owner_revoke_delegation_successful() { let delegate_keypair = get_alice_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -876,10 +876,10 @@ fn direct_owner_revoke_delegation_successful() { operation.max_revocations = 2u32; let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -910,9 +910,9 @@ fn parent_owner_revoke_delegation_successful() { let delegate_keypair = get_alice_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -928,10 +928,10 @@ fn parent_owner_revoke_delegation_successful() { operation.max_revocations = 1u32; let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -960,19 +960,19 @@ fn delegation_not_found_revoke_delegation_error() { let revoker_keypair = get_alice_ed25519(); let revoker = get_ed25519_account(revoker_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let delegation_id = get_delegation_id(false); let operation = generate_base_delegation_revocation_operation(delegation_id); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .build(Some(ext)); ext.execute_with(|| { @@ -995,9 +995,9 @@ fn not_delegating_revoke_delegation_error() { let revoker_keypair = get_bob_ed25519(); let revoker = get_ed25519_account(revoker_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (delegation_id, delegation_node) = ( get_delegation_id(true), @@ -1008,10 +1008,10 @@ fn not_delegating_revoke_delegation_error() { operation.max_parent_checks = MaxParentChecks::get(); let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, owner)]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, owner)]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); @@ -1037,9 +1037,9 @@ fn parent_too_far_revoke_delegation_error() { let delegate_keypair = get_bob_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -1054,10 +1054,10 @@ fn parent_too_far_revoke_delegation_error() { operation.max_parent_checks = 0u32; let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, owner.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, owner.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, owner)]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, owner)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1081,9 +1081,9 @@ fn too_many_revocations_revoke_delegation_error() { let delegate_keypair = get_bob_ed25519(); let delegate = get_ed25519_account(delegate_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -1098,10 +1098,10 @@ fn too_many_revocations_revoke_delegation_error() { operation.max_parent_checks = 1u32; let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, revoker.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, revoker.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, revoker.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1129,9 +1129,9 @@ fn is_delegating_direct_not_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -1146,10 +1146,10 @@ fn is_delegating_direct_not_revoked() { // Root -> Parent -> Delegation let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1170,9 +1170,9 @@ fn is_delegating_direct_not_revoked_max_parent_checks_value() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -1187,10 +1187,10 @@ fn is_delegating_direct_not_revoked_max_parent_checks_value() { // Root -> Parent -> Delegation let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1211,9 +1211,9 @@ fn is_delegating_direct_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -1229,10 +1229,10 @@ fn is_delegating_direct_revoked() { // Root -> Parent -> Delegation let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1253,9 +1253,9 @@ fn is_delegating_direct_revoked_max_parent_checks_value() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -1271,10 +1271,10 @@ fn is_delegating_direct_revoked_max_parent_checks_value() { // Root -> Parent -> Delegation let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1295,9 +1295,9 @@ fn is_delegating_max_parent_not_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -1312,10 +1312,10 @@ fn is_delegating_max_parent_not_revoked() { // Root -> Parent -> Delegation let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1336,9 +1336,9 @@ fn is_delegating_max_parent_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, mut parent_node) = ( get_delegation_id(true), @@ -1354,10 +1354,10 @@ fn is_delegating_max_parent_revoked() { // Root -> Parent -> Delegation let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1)]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, user_1)]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1378,9 +1378,9 @@ fn is_delegating_root_owner_not_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -1395,10 +1395,10 @@ fn is_delegating_root_owner_not_revoked() { // Root -> Parent -> Delegation let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, user_1.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1419,9 +1419,9 @@ fn is_delegating_root_owner_revoked() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -1436,10 +1436,10 @@ fn is_delegating_root_owner_revoked() { // Root -> Parent -> Delegation let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, user_1.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); @@ -1458,9 +1458,9 @@ fn is_delegating_delegation_not_found() { let user_1_keypair = get_alice_ed25519(); let user_1 = get_ed25519_account(user_1_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let delegation_id = get_delegation_id(true); @@ -1468,7 +1468,7 @@ fn is_delegating_delegation_not_found() { // Root -> Delegation 1 let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, user_1.clone())]) .build(None); ext.execute_with(|| { @@ -1488,9 +1488,9 @@ fn is_delegating_root_after_max_limit() { let user_3_keypair = get_charlie_ed25519(); let user_3 = get_ed25519_account(user_3_keypair.public()); - let (hierarchy_root_id, hierarchy_info) = ( + let (hierarchy_root_id, hierarchy_details) = ( get_delegation_hierarchy_id(true), - generate_base_delegation_hierarchy_info(), + generate_base_delegation_hierarchy_details(), ); let (parent_id, parent_node) = ( get_delegation_id(true), @@ -1506,10 +1506,10 @@ fn is_delegating_root_after_max_limit() { // Root -> Parent -> Delegation let ext = ctype_mock::ExtBuilder::default() - .with_ctypes(vec![(hierarchy_info.ctype_hash, user_1.clone())]) + .with_ctypes(vec![(hierarchy_details.ctype_hash, user_1.clone())]) .build(None); let mut ext = ExtBuilder::default() - .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_info, user_1.clone())]) + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, user_1.clone())]) .with_delegations(vec![(parent_id, parent_node), (delegation_id, delegation_node)]) .build(Some(ext)); From dc92d9520dffd354632cce233547fb71985d812c Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 16 Jul 2021 16:20:54 +0200 Subject: [PATCH 30/49] chore: fmt + clippy --- pallets/attestation/src/tests.rs | 6 +- .../delegation/src/delegation_hierarchy.rs | 20 +- pallets/delegation/src/deprecated.rs | 10 +- pallets/delegation/src/lib.rs | 12 +- pallets/delegation/src/migrations.rs | 288 +++++++++++------- pallets/delegation/src/mock.rs | 12 +- 6 files changed, 220 insertions(+), 128 deletions(-) diff --git a/pallets/attestation/src/tests.rs b/pallets/attestation/src/tests.rs index 7e47fd08b5..2b752aafbc 100644 --- a/pallets/attestation/src/tests.rs +++ b/pallets/attestation/src/tests.rs @@ -342,7 +342,11 @@ fn root_not_present_attest_error() { .with_ctypes(vec![(operation.ctype_hash, attester.clone())]) .build(None); let mut ext = delegation_mock::ExtBuilder::default() - .with_delegation_hierarchies(vec![(alternative_hierarchy_root_id, hierarchy_details, attester.clone())]) + .with_delegation_hierarchies(vec![( + alternative_hierarchy_root_id, + hierarchy_details, + attester.clone(), + )]) .with_delegations(vec![(delegation_id, delegation_node)]) .build(Some(ext)); diff --git a/pallets/delegation/src/delegation_hierarchy.rs b/pallets/delegation/src/delegation_hierarchy.rs index 5ee0b0c55c..75eb79c13e 100644 --- a/pallets/delegation/src/delegation_hierarchy.rs +++ b/pallets/delegation/src/delegation_hierarchy.rs @@ -56,8 +56,9 @@ impl Default for Permissions { /// A node in a delegation hierarchy. /// -/// For quicker lookups of the hierarchy details, all nodes maintain a direct link to the hierarchy root node. -/// Furthermore, all nodes have a parent but the root nodes, which point to themselves for the hierarchy root node link. +/// For quicker lookups of the hierarchy details, all nodes maintain a direct +/// link to the hierarchy root node. Furthermore, all nodes have a parent but +/// the root nodes, which point to themselves for the hierarchy root node link. #[derive(Clone, Debug, Encode, Decode, PartialEq)] pub struct DelegationNode { /// The ID of the delegation hierarchy the node is part of. @@ -71,7 +72,8 @@ pub struct DelegationNode { } impl DelegationNode { - /// Creates a new delegation root node with the given ID and delegation details. + /// Creates a new delegation root node with the given ID and delegation + /// details. pub fn new_root_node(id: DelegationNodeIdOf, details: DelegationDetails) -> Self { Self { hierarchy_root_id: id, @@ -81,7 +83,8 @@ impl DelegationNode { } } - /// Creates a new delegation node under the given hierarchy ID, with the given parent and delegation details. + /// Creates a new delegation node under the given hierarchy ID, with the + /// given parent and delegation details. pub fn new_node( hierarchy_root_id: DelegationNodeIdOf, parent: DelegationNodeIdOf, @@ -106,7 +109,8 @@ impl DelegationNode { pub struct DelegationDetails { /// The owner of the delegation (and its node). pub owner: DelegatorIdOf, - /// Status indicating whether the delegation has been revoked (true) or not (false). + /// Status indicating whether the delegation has been revoked (true) or not + /// (false). pub revoked: bool, /// The set of permissions associated with the delegation. pub permissions: Permissions, @@ -115,7 +119,8 @@ pub struct DelegationDetails { impl DelegationDetails { /// Creates new delegation details including the given owner. /// - /// The default revocation status is false and all permissions are granted by default. + /// The default revocation status is false and all permissions are granted + /// by default. pub fn default_with_owner(owner: DelegatorIdOf) -> Self { Self { owner, @@ -128,7 +133,8 @@ impl DelegationDetails { /// The details associated with a delegation hierarchy. #[derive(Clone, Debug, Encode, Decode, Eq, PartialEq, Ord, PartialOrd)] pub struct DelegationHierarchyDetails { - /// The authorised CTYPE hash that attesters can attest using this delegation hierarchy. + /// The authorised CTYPE hash that attesters can attest using this + /// delegation hierarchy. pub ctype_hash: CtypeHashOf, } diff --git a/pallets/delegation/src/deprecated.rs b/pallets/delegation/src/deprecated.rs index 51c25a66f8..0f6ea788b3 100644 --- a/pallets/delegation/src/deprecated.rs +++ b/pallets/delegation/src/deprecated.rs @@ -42,11 +42,11 @@ pub(crate) mod v1 { #[derive(Clone, Debug, Encode, Decode, PartialEq)] pub struct DelegationNode { - pub(crate) root_id: DelegationNodeIdOf, - pub(crate) parent: Option>, - pub(crate) owner: DelegatorIdOf, - pub(crate) permissions: Permissions, - pub(crate) revoked: bool, + pub(crate) root_id: DelegationNodeIdOf, + pub(crate) parent: Option>, + pub(crate) owner: DelegatorIdOf, + pub(crate) permissions: Permissions, + pub(crate) revoked: bool, } impl DelegationNode { diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 3b44807bad..bbf71b92d7 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -448,7 +448,8 @@ impl Pallet { T::Hashing::hash(&hashed_values) } - // Creates a new root node with the given details and store the new hierarchy in the hierarchies storage and the new root node in the nodes storage. + // Creates a new root node with the given details and store the new hierarchy in + // the hierarchies storage and the new root node in the nodes storage. fn create_and_store_new_hierarchy( root_id: DelegationNodeIdOf, hierarchy_details: DelegationHierarchyDetails, @@ -459,9 +460,11 @@ impl Pallet { >::insert(root_id, hierarchy_details); } - // Adds the given node to the storage and updates the parent node to include the given node as child. + // Adds the given node to the storage and updates the parent node to include the + // given node as child. // - // This function assumes that the parent node is already stored on the chain. If not, the behaviour of the system is undefined. + // This function assumes that the parent node is already stored on the chain. If + // not, the behaviour of the system is undefined. fn store_delegation_under_parent( delegation_id: DelegationNodeIdOf, delegation_node: DelegationNode, @@ -474,7 +477,8 @@ impl Pallet { >::insert(parent_id, parent_node); } - // Marks the provided hierarchy as revoked and stores the resulting state back in the storage. + // Marks the provided hierarchy as revoked and stores the resulting state back + // in the storage. fn revoke_and_store_hierarchy_root(root_id: DelegationNodeIdOf, mut root_node: DelegationNode) { root_node.details.revoked = true; >::insert(root_id, root_node); diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 62358ad07f..c26c8a0105 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -21,9 +21,11 @@ use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData}; use crate::*; -/// A trait that allows version migrators to access the underlying pallet's context, i.e., its Config trait. +/// A trait that allows version migrators to access the underlying pallet's +/// context, i.e., its Config trait. /// -/// In this way, the migrator can access the pallet's storage and the pallet's types directly. +/// In this way, the migrator can access the pallet's storage and the pallet's +/// types directly. pub trait VersionMigratorTrait { #[cfg(any(feature = "try-runtime", test))] fn pre_migrate(&self) -> Result<(), &str>; @@ -53,7 +55,8 @@ impl DelegationStorageVersion { // latest version), the migration will simply do nothing as there's nothing in // the old storage entries to migrate from. // -// It might get updated in the future when we know that no node is running this old version anymore. +// It might get updated in the future when we know that no node is running this +// old version anymore. impl Default for DelegationStorageVersion { fn default() -> Self { Self::v1 @@ -78,7 +81,8 @@ impl VersionMigratorTrait for DelegationStorageVersion { } } - // It runs the right post_migrate logic depending on the current storage version. + // It runs the right post_migrate logic depending on the current storage + // version. #[cfg(any(feature = "try-runtime", test))] fn post_migrate(&self) -> Result<(), &str> { match *self { @@ -91,13 +95,15 @@ impl VersionMigratorTrait for DelegationStorageVersion { mod v1 { use super::*; - use frame_support::{IterableStorageMap, StoragePrefixedMap, StorageMap}; + use frame_support::{IterableStorageMap, StorageMap, StoragePrefixedMap}; - /// Checks whether the deployed storage version is v1. If not, it won't try migrate any data. + /// Checks whether the deployed storage version is v1. If not, it won't try + /// migrate any data. /// - /// Since we have the default storage version to this one, it can happen that new nodes will - /// still try to perform runtime migrations. This is not a problem as at the end of the day there - /// will not be anything in the old storage entries to migrate from. Hence, the "pseudo-"migration will + /// Since we have the default storage version to this one, it can happen + /// that new nodes will still try to perform runtime migrations. This is not + /// a problem as at the end of the day there will not be anything in the old + /// storage entries to migrate from. Hence, the "pseudo-"migration will /// simply result in the update of the storage deployed version. #[cfg(any(feature = "try-runtime", test))] pub(crate) fn pre_migrate() -> Result<(), &'static str> { @@ -112,18 +118,20 @@ mod v1 { /// It migrates the old storage entries to the new ones. /// - /// Specifically, for each entry in Roots, a new entry in DelegationHierarchies - /// + a new node in DelegationNodes is created. Furthermore, nodes - /// in Delegations are migrated to the new structure and stored under DelegationNodes, - /// with any children from the Children storage entry added to the nodes under the children set. + /// Specifically, for each entry in Roots, a new entry in + /// DelegationHierarchies + a new node in DelegationNodes is created. + /// Furthermore, nodes in Delegations are migrated to the new structure and + /// stored under DelegationNodes, with any children from the Children + /// storage entry added to the nodes under the children set. pub(crate) fn migrate() -> Weight { log::info!("v1 -> v2 delegation storage migrator started!"); let mut total_weight = 0u64; // Before being stored, the nodes are saved in a map so that after we go over // all the nodes and the parent-child relationship in the storage, we can update - // the `parent` link of each node accordingly. Otherwise, we would need to save the - // node in the storage, and then retrieve it again to update the parent link. + // the `parent` link of each node accordingly. Otherwise, we would need to save + // the node in the storage, and then retrieve it again to update the parent + // link. let mut new_nodes: BTreeMap, DelegationNode> = BTreeMap::new(); // First iterate over the delegation roots and translate them to hierarchies. @@ -147,87 +155,114 @@ mod v1 { } fn migrate_roots(new_nodes: &mut BTreeMap, DelegationNode>) -> Weight { - let total_weight = deprecated::v1::storage::Roots::::iter().fold(0u64, |mut total_weight, (old_root_id, old_root_node)| { - let new_hierarchy_details = DelegationHierarchyDetails:: { - ctype_hash: old_root_node.ctype_hash, - }; - let new_root_details = DelegationDetails:: { - owner: old_root_node.owner, - // Old roots did not have any permissions. So now we give them all permissions. - permissions: Permissions::all(), - revoked: old_root_node.revoked, - }; - // In here, we already check for potential children of root nodes and ONLY - // update the children information. The parent information will be updated - // later, when we know we have seen all the children already. - let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); - if let Some(root_children_ids) = deprecated::v1::storage::Children::::take(old_root_id) { - new_root_node.children = root_children_ids.iter().copied().collect(); - } - // Add Children::take() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + let total_weight = + deprecated::v1::storage::Roots::::iter().fold(0u64, |mut total_weight, (old_root_id, old_root_node)| { + let new_hierarchy_details = DelegationHierarchyDetails:: { + ctype_hash: old_root_node.ctype_hash, + }; + let new_root_details = DelegationDetails:: { + owner: old_root_node.owner, + // Old roots did not have any permissions. So now we give them all permissions. + permissions: Permissions::all(), + revoked: old_root_node.revoked, + }; + // In here, we already check for potential children of root nodes and ONLY + // update the children information. The parent information will be updated + // later, when we know we have seen all the children already. + let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); + if let Some(root_children_ids) = deprecated::v1::storage::Children::::take(old_root_id) { + new_root_node.children = root_children_ids.iter().copied().collect(); + } + // Add Children::take() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - DelegationHierarchies::insert(old_root_id, new_hierarchy_details); - // Adds a read from Roots::drain() and a write from - // DelegationHierarchies::insert() weights - total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); - // Add the node to the temporary map of nodes to be added at the end. - new_nodes.insert(old_root_id, new_root_node); + DelegationHierarchies::insert(old_root_id, new_hierarchy_details); + // Adds a read from Roots::drain() and a write from + // DelegationHierarchies::insert() weights + total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + // Add the node to the temporary map of nodes to be added at the end. + new_nodes.insert(old_root_id, new_root_node); - total_weight - }); + total_weight + }); // Removes the whole Roots storage. - frame_support::migration::remove_storage_prefix(&deprecated::v1::storage::Roots::::module_prefix()[..], &deprecated::v1::storage::Roots::::storage_prefix()[..], b""); + frame_support::migration::remove_storage_prefix( + deprecated::v1::storage::Roots::::module_prefix(), + deprecated::v1::storage::Roots::::storage_prefix(), + b"", + ); total_weight } - fn migrate_nodes(new_nodes: &mut BTreeMap, DelegationNode>, initial_weight: Weight) -> Weight { - let total_weight = deprecated::v1::storage::Delegations::::iter().fold(initial_weight, |mut total_weight, (old_node_id, old_node)| { - let new_node_details = DelegationDetails:: { - owner: old_node.owner, - permissions: old_node.permissions, - revoked: old_node.revoked, - }; - // In the old version, a parent None indicated the node is a child of the root. - let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); - let mut new_node = DelegationNode::new_node(old_node.root_id, new_node_parent_id, new_node_details); - if let Some(children_ids) = deprecated::v1::storage::Children::::take(old_node_id) { - new_node.children = children_ids.iter().copied().collect(); - } - // Add Children::take() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - // Adds a read from Roots::drain() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - new_nodes.insert(old_node_id, new_node); - - total_weight - }); + fn migrate_nodes( + new_nodes: &mut BTreeMap, DelegationNode>, + initial_weight: Weight, + ) -> Weight { + let total_weight = deprecated::v1::storage::Delegations::::iter().fold( + initial_weight, + |mut total_weight, (old_node_id, old_node)| { + let new_node_details = DelegationDetails:: { + owner: old_node.owner, + permissions: old_node.permissions, + revoked: old_node.revoked, + }; + // In the old version, a parent None indicated the node is a child of the root. + let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); + let mut new_node = DelegationNode::new_node(old_node.root_id, new_node_parent_id, new_node_details); + if let Some(children_ids) = deprecated::v1::storage::Children::::take(old_node_id) { + new_node.children = children_ids.iter().copied().collect(); + } + // Add Children::take() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + // Adds a read from Roots::drain() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + new_nodes.insert(old_node_id, new_node); + + total_weight + }, + ); // Removes the whole Delegations and Children storages. - frame_support::migration::remove_storage_prefix(&deprecated::v1::storage::Delegations::::module_prefix()[..], &deprecated::v1::storage::Delegations::::storage_prefix()[..], b""); - frame_support::migration::remove_storage_prefix(&deprecated::v1::storage::Children::::module_prefix()[..], &deprecated::v1::storage::Children::::storage_prefix()[..], b""); + frame_support::migration::remove_storage_prefix( + deprecated::v1::storage::Delegations::::module_prefix(), + deprecated::v1::storage::Delegations::::storage_prefix(), + b"", + ); + frame_support::migration::remove_storage_prefix( + deprecated::v1::storage::Children::::module_prefix(), + deprecated::v1::storage::Children::::storage_prefix(), + b"", + ); total_weight } - fn finalize_children_nodes(new_nodes: &mut BTreeMap, DelegationNode>, initial_weight: Weight) -> Weight { - new_nodes.clone().into_iter().fold(initial_weight, |mut total_weight, (new_node_id, new_node)| { - // Iterate over the children of every node and update their parent link. - new_node.children.iter().for_each(|child_id| { - new_nodes - .entry(*child_id) - .and_modify(|node| node.parent = Some(new_node_id)); - }); - // We can then finally insert the new delegation node in the storage as it won't be updated anymore during the migration. - DelegationNodes::::insert(new_node_id, new_node); - // Adds a write from DelegationNodes::insert() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - - total_weight - }) + fn finalize_children_nodes( + new_nodes: &mut BTreeMap, DelegationNode>, + initial_weight: Weight, + ) -> Weight { + new_nodes + .clone() + .into_iter() + .fold(initial_weight, |mut total_weight, (new_node_id, new_node)| { + // Iterate over the children of every node and update their parent link. + new_node.children.iter().for_each(|child_id| { + new_nodes + .entry(*child_id) + .and_modify(|node| node.parent = Some(new_node_id)); + }); + // We can then finally insert the new delegation node in the storage as it won't + // be updated anymore during the migration. + DelegationNodes::::insert(new_node_id, new_node); + // Adds a write from DelegationNodes::insert() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + + total_weight + }) } - /// Checks whether the deployed storage version is v2 and whether any parent-child link has gone missing. + /// Checks whether the deployed storage version is v2 and whether any + /// parent-child link has gone missing. #[cfg(any(feature = "try-runtime", test))] pub(crate) fn post_migrate() -> Result<(), &'static str> { ensure!( @@ -242,7 +277,8 @@ mod v1 { Ok(()) } - // Verifies that for any node that has a parent, the parent includes the node in its children. + // Verifies that for any node that has a parent, the parent includes the node in + // its children. #[cfg(any(feature = "try-runtime", test))] fn verify_parent_children_integrity() -> bool { // If all's good and false is returned, returns true. @@ -252,7 +288,8 @@ mod v1 { // True if the children set does not contain the parent ID return !parent_node.children.contains(&node_id); } else { - // If the parent node cannot be found, it is definitely an error, so return true. + // If the parent node cannot be found, it is definitely an error, so return + // true. return true; } } @@ -266,8 +303,8 @@ mod v1 { mod tests { use sp_core::Pair; - use crate::mock::Test as TestRuntime; use super::*; + use crate::mock::Test as TestRuntime; #[test] fn fail_version_higher() { @@ -327,8 +364,14 @@ mod v1 { ); assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); - assert_eq!(deprecated::v1::storage::Delegations::::iter_values().count(), 0); - assert_eq!(deprecated::v1::storage::Children::::iter_values().count(), 0); + assert_eq!( + deprecated::v1::storage::Delegations::::iter_values().count(), + 0 + ); + assert_eq!( + deprecated::v1::storage::Children::::iter_values().count(), + 0 + ); let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) .expect("New delegation hierarchy should exist in the storage."); @@ -371,7 +414,10 @@ mod v1 { deprecated::v1::storage::Roots::insert(old_root_id, old_root_node.clone()); deprecated::v1::storage::Delegations::insert(old_node_id_1, old_node_1.clone()); deprecated::v1::storage::Delegations::insert(old_node_id_2, old_node_2.clone()); - deprecated::v1::storage::Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); + deprecated::v1::storage::Children::::insert( + old_root_id, + vec![old_node_id_1, old_node_id_2], + ); assert!( pre_migrate::().is_ok(), @@ -386,8 +432,14 @@ mod v1 { ); assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); - assert_eq!(deprecated::v1::storage::Delegations::::iter_values().count(), 0); - assert_eq!(deprecated::v1::storage::Children::::iter_values().count(), 0); + assert_eq!( + deprecated::v1::storage::Delegations::::iter_values().count(), + 0 + ); + assert_eq!( + deprecated::v1::storage::Children::::iter_values().count(), + 0 + ); let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) .expect("New delegation hierarchy should exist in the storage."); @@ -423,17 +475,22 @@ mod v1 { #[test] fn ok_three_level_hierarchy() { let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::v1) - .build(None); + .with_storage_version(DelegationStorageVersion::v1) + .build(None); ext.execute_with(|| { let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); let old_root_id = mock::get_delegation_id(true); - let old_root_node = - deprecated::v1::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_root_node = deprecated::v1::DelegationRoot::::new( + ctype::mock::get_ctype_hash(true), + alice.clone(), + ); let old_parent_id = mock::get_delegation_id(false); - let old_parent_node = - deprecated::v1::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); + let old_parent_node = deprecated::v1::DelegationNode::::new_root_child( + old_root_id, + alice, + Permissions::all(), + ); let old_node_id = mock::get_delegation_id_2(true); let old_node = deprecated::v1::DelegationNode::::new_node_child( old_root_id, @@ -460,8 +517,14 @@ mod v1 { ); assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); - assert_eq!(deprecated::v1::storage::Delegations::::iter_values().count(), 0); - assert_eq!(deprecated::v1::storage::Children::::iter_values().count(), 0); + assert_eq!( + deprecated::v1::storage::Delegations::::iter_values().count(), + 0 + ); + assert_eq!( + deprecated::v1::storage::Children::::iter_values().count(), + 0 + ); let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) .expect("New delegation hierarchy should exist in the storage."); @@ -496,23 +559,27 @@ mod v1 { } } -/// The delegation pallet's storage migrator, which handles all version migrations in a sequential fashion. +/// The delegation pallet's storage migrator, which handles all version +/// migrations in a sequential fashion. /// -/// If a node has missed on more than one upgrade, the migrator will apply the needed migrations one after the other. -/// Otherwise, if no migration is needed, the migrator will simply not do anything. +/// If a node has missed on more than one upgrade, the migrator will apply the +/// needed migrations one after the other. Otherwise, if no migration is needed, +/// the migrator will simply not do anything. pub struct DelegationStorageMigrator(PhantomData); impl DelegationStorageMigrator { // Contains the migration sequence logic. fn get_next_storage_version(current: DelegationStorageVersion) -> Option { - // If the version current deployed is at least v1, there is no more migrations to run (other than the one from v1). + // If the version current deployed is at least v1, there is no more migrations + // to run (other than the one from v1). match current { DelegationStorageVersion::v1 => None, DelegationStorageVersion::v2 => None, } } - /// Checks whether the latest storage version deployed is lower than the latest possible. + /// Checks whether the latest storage version deployed is lower than the + /// latest possible. #[cfg(any(feature = "try-runtime", test))] pub(crate) fn pre_migrate() -> Result<(), &'static str> { ensure!( @@ -527,7 +594,8 @@ impl DelegationStorageMigrator { Ok(()) } - /// Applies all the needed migrations from the currently deployed version to the latest possible, one after the other. + /// Applies all the needed migrations from the currently deployed version to + /// the latest possible, one after the other. /// /// It returns the total weight consumed by ALL the migrations applied. pub(crate) fn migrate() -> Weight { @@ -536,14 +604,16 @@ impl DelegationStorageMigrator { let mut total_weight = T::DbWeight::get().reads(1); while let Some(ver) = current_version { - // If any of the needed migrations pre-checks fail, the whole chain panics (during tests). + // If any of the needed migrations pre-checks fail, the whole chain panics + // (during tests). #[cfg(feature = "try-runtime")] if let Err(err) = >::pre_migrate(&ver) { panic!("{:?}", err); } let consumed_weight = >::migrate(&ver); total_weight = total_weight.saturating_add(consumed_weight); - // If any of the needed migrations post-checks fail, the whole chain panics (during tests). + // If any of the needed migrations post-checks fail, the whole chain panics + // (during tests). #[cfg(feature = "try-runtime")] if let Err(err) = >::post_migrate(&ver) { panic!("{:?}", err); @@ -555,7 +625,8 @@ impl DelegationStorageMigrator { total_weight } - /// Checks whether the storage version after all the needed migrations match the latest one. + /// Checks whether the storage version after all the needed migrations match + /// the latest one. #[cfg(any(feature = "try-runtime", test))] pub(crate) fn post_migrate() -> Result<(), &'static str> { ensure!( @@ -596,8 +667,7 @@ mod tests { #[test] fn ok_from_default_migration() { - let mut ext = mock::ExtBuilder::default() - .build(None); + let mut ext = mock::ExtBuilder::default().build(None); ext.execute_with(|| { assert!( DelegationStorageMigrator::::pre_migrate().is_ok(), diff --git a/pallets/delegation/src/mock.rs b/pallets/delegation/src/mock.rs index 0154acab49..4c8b77baf9 100644 --- a/pallets/delegation/src/mock.rs +++ b/pallets/delegation/src/mock.rs @@ -312,7 +312,11 @@ pub fn generate_base_delegation_revocation_operation( #[derive(Clone)] pub struct ExtBuilder { ctype_builder: Option, - delegation_hierarchies_stored: Vec<(TestDelegationNodeId, DelegationHierarchyDetails, DelegatorIdOf)>, + delegation_hierarchies_stored: Vec<( + TestDelegationNodeId, + DelegationHierarchyDetails, + DelegatorIdOf, + )>, delegations_stored: Vec<(TestDelegationNodeId, DelegationNode)>, storage_version: DelegationStorageVersion, } @@ -331,7 +335,11 @@ impl Default for ExtBuilder { impl ExtBuilder { pub fn with_delegation_hierarchies( mut self, - delegation_hierarchies: Vec<(TestDelegationNodeId, DelegationHierarchyDetails, DelegatorIdOf)>, + delegation_hierarchies: Vec<( + TestDelegationNodeId, + DelegationHierarchyDetails, + DelegatorIdOf, + )>, ) -> Self { self.delegation_hierarchies_stored = delegation_hierarchies; self From 93265d66d75a17df0a1a26d2546dc2b7071a7427 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 16 Jul 2021 17:29:36 +0200 Subject: [PATCH 31/49] test: add TODO to improve post_migration tests --- pallets/delegation/src/migrations.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index c26c8a0105..f681b14263 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -265,6 +265,8 @@ mod v1 { /// parent-child link has gone missing. #[cfg(any(feature = "try-runtime", test))] pub(crate) fn post_migrate() -> Result<(), &'static str> { + //TODO: Add the try-runtime test storage to check that + // the total number of nodes is kept the same before and after. ensure!( StorageVersion::::get() == DelegationStorageVersion::v2, "The version after deployment is not 2 as expected." From cc9687391af328e26a45ed7b2ee59f35758a878b Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 19 Jul 2021 09:54:39 +0200 Subject: [PATCH 32/49] feat: remove test feature from traits --- pallets/delegation/src/migrations.rs | 31 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index f681b14263..cfbea0d734 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -27,10 +27,10 @@ use crate::*; /// In this way, the migrator can access the pallet's storage and the pallet's /// types directly. pub trait VersionMigratorTrait { - #[cfg(any(feature = "try-runtime", test))] + #[cfg(feature = "try-runtime")] fn pre_migrate(&self) -> Result<(), &str>; fn migrate(&self) -> Weight; - #[cfg(any(feature = "try-runtime", test))] + #[cfg(feature = "try-runtime")] fn post_migrate(&self) -> Result<(), &str>; } @@ -65,7 +65,7 @@ impl Default for DelegationStorageVersion { impl VersionMigratorTrait for DelegationStorageVersion { // It runs the right pre_migrate logic depending on the current storage version. - #[cfg(any(feature = "try-runtime", test))] + #[cfg(feature = "try-runtime")] fn pre_migrate(&self) -> Result<(), &str> { match *self { Self::v1 => v1::pre_migrate::(), @@ -83,7 +83,7 @@ impl VersionMigratorTrait for DelegationStorageVersion { // It runs the right post_migrate logic depending on the current storage // version. - #[cfg(any(feature = "try-runtime", test))] + #[cfg(feature = "try-runtime")] fn post_migrate(&self) -> Result<(), &str> { match *self { Self::v1 => v1::post_migrate::(), @@ -105,7 +105,7 @@ mod v1 { /// a problem as at the end of the day there will not be anything in the old /// storage entries to migrate from. Hence, the "pseudo-"migration will /// simply result in the update of the storage deployed version. - #[cfg(any(feature = "try-runtime", test))] + #[cfg(feature = "try-runtime")] pub(crate) fn pre_migrate() -> Result<(), &'static str> { ensure!( StorageVersion::::get() == DelegationStorageVersion::v1, @@ -263,7 +263,7 @@ mod v1 { /// Checks whether the deployed storage version is v2 and whether any /// parent-child link has gone missing. - #[cfg(any(feature = "try-runtime", test))] + #[cfg(feature = "try-runtime")] pub(crate) fn post_migrate() -> Result<(), &'static str> { //TODO: Add the try-runtime test storage to check that // the total number of nodes is kept the same before and after. @@ -281,7 +281,7 @@ mod v1 { // Verifies that for any node that has a parent, the parent includes the node in // its children. - #[cfg(any(feature = "try-runtime", test))] + #[cfg(feature = "try-runtime")] fn verify_parent_children_integrity() -> bool { // If all's good and false is returned, returns true. !DelegationNodes::::iter().any(|(node_id, node)| { @@ -314,6 +314,7 @@ mod v1 { .with_storage_version(DelegationStorageVersion::v2) .build(None); ext.execute_with(|| { + #[cfg(feature = "try-runtime")] assert!( pre_migrate::().is_err(), "Pre-migration for v1 should fail." @@ -327,6 +328,7 @@ mod v1 { .with_storage_version(DelegationStorageVersion::v1) .build(None); ext.execute_with(|| { + #[cfg(feature = "try-runtime")] assert!( pre_migrate::().is_ok(), "Pre-migration for v1 should not fail." @@ -334,6 +336,7 @@ mod v1 { migrate::(); + #[cfg(feature = "try-runtime")] assert!( post_migrate::().is_ok(), "Post-migration for v1 should not fail." @@ -353,6 +356,7 @@ mod v1 { crate::deprecated::v1::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); deprecated::v1::storage::Roots::insert(old_root_id, old_root_node.clone()); + #[cfg(feature = "try-runtime")] assert!( pre_migrate::().is_ok(), "Pre-migration for v1 should not fail." @@ -360,6 +364,7 @@ mod v1 { migrate::(); + #[cfg(feature = "try-runtime")] assert!( post_migrate::().is_ok(), "Post-migration for v1 should not fail." @@ -421,6 +426,7 @@ mod v1 { vec![old_node_id_1, old_node_id_2], ); + #[cfg(feature = "try-runtime")] assert!( pre_migrate::().is_ok(), "Pre-migration for v1 should not fail." @@ -428,6 +434,7 @@ mod v1 { migrate::(); + #[cfg(feature = "try-runtime")] assert!( post_migrate::().is_ok(), "Post-migration for v1 should not fail." @@ -506,6 +513,7 @@ mod v1 { deprecated::v1::storage::Children::::insert(old_root_id, vec![old_parent_id]); deprecated::v1::storage::Children::::insert(old_parent_id, vec![old_node_id]); + #[cfg(feature = "try-runtime")] assert!( pre_migrate::().is_ok(), "Pre-migration for v1 should not fail." @@ -513,6 +521,7 @@ mod v1 { migrate::(); + #[cfg(feature = "try-runtime")] assert!( post_migrate::().is_ok(), "Post-migration for v1 should not fail." @@ -582,7 +591,7 @@ impl DelegationStorageMigrator { /// Checks whether the latest storage version deployed is lower than the /// latest possible. - #[cfg(any(feature = "try-runtime", test))] + #[cfg(feature = "try-runtime")] pub(crate) fn pre_migrate() -> Result<(), &'static str> { ensure!( StorageVersion::::get() < DelegationStorageVersion::latest(), @@ -629,7 +638,7 @@ impl DelegationStorageMigrator { /// Checks whether the storage version after all the needed migrations match /// the latest one. - #[cfg(any(feature = "try-runtime", test))] + #[cfg(feature = "try-runtime")] pub(crate) fn post_migrate() -> Result<(), &'static str> { ensure!( StorageVersion::::get() == DelegationStorageVersion::latest(), @@ -653,6 +662,7 @@ mod tests { .with_storage_version(DelegationStorageVersion::v1) .build(None); ext.execute_with(|| { + #[cfg(feature = "try-runtime")] assert!( DelegationStorageMigrator::::pre_migrate().is_ok(), "Storage pre-migrate from v1 should not fail." @@ -660,6 +670,7 @@ mod tests { DelegationStorageMigrator::::migrate(); + #[cfg(feature = "try-runtime")] assert!( DelegationStorageMigrator::::post_migrate().is_ok(), "Storage post-migrate from v1 should not fail." @@ -671,6 +682,7 @@ mod tests { fn ok_from_default_migration() { let mut ext = mock::ExtBuilder::default().build(None); ext.execute_with(|| { + #[cfg(feature = "try-runtime")] assert!( DelegationStorageMigrator::::pre_migrate().is_ok(), "Storage pre-migrate from default version should not fail." @@ -678,6 +690,7 @@ mod tests { DelegationStorageMigrator::::migrate(); + #[cfg(feature = "try-runtime")] assert!( DelegationStorageMigrator::::post_migrate().is_ok(), "Storage post-migrate from default version should not fail." From 37fb96984dc53019d586b94a1cef446e7ca02072 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 19 Jul 2021 10:34:20 +0200 Subject: [PATCH 33/49] test: add checks during migration in try-runtime --- pallets/delegation/src/migrations.rs | 36 +++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index cfbea0d734..c19c305281 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -22,11 +22,11 @@ use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData}; use crate::*; /// A trait that allows version migrators to access the underlying pallet's -/// context, i.e., its Config trait. +/// context, e.g., its Config trait. /// /// In this way, the migrator can access the pallet's storage and the pallet's /// types directly. -pub trait VersionMigratorTrait { +pub trait VersionMigratorTrait { #[cfg(feature = "try-runtime")] fn pre_migrate(&self) -> Result<(), &str>; fn migrate(&self) -> Weight; @@ -185,6 +185,23 @@ mod v1 { total_weight }); + // If runtime testing, makes sure that the old number of roots is reflected in + // the new number of nodes and hierarchies migrated. + #[cfg(feature = "try-runtime")] + { + assert_eq!( + deprecated::v1::storage::Roots::::iter().count(), + DelegationHierarchies::::iter().count(), + "The # of old roots does not match the # of new delegation hierarchies." + ); + + assert_eq!( + deprecated::v1::storage::Roots::::iter().count(), + new_nodes.iter().count(), + "The # of old roots does not match the current # of new delegation nodes." + ); + } + // Removes the whole Roots storage. frame_support::migration::remove_storage_prefix( deprecated::v1::storage::Roots::::module_prefix(), @@ -222,6 +239,15 @@ mod v1 { total_weight }, ); + // If runtime testing, makes sure that the old number of delegations is + // reflected in the new number of nodes that will be added to the storage. + #[cfg(feature = "try-runtime")] + assert_eq!( + deprecated::v1::storage::Delegations::::iter().count(), + new_nodes.iter().count().saturating_sub(DelegationHierarchies::::iter().count()), + "The # of old delegation nodes does not match the # of new delegation nodes (calculate as the total # of nodes - the # of delegation hierarchies)." + ); + // Removes the whole Delegations and Children storages. frame_support::migration::remove_storage_prefix( deprecated::v1::storage::Delegations::::module_prefix(), @@ -265,8 +291,6 @@ mod v1 { /// parent-child link has gone missing. #[cfg(feature = "try-runtime")] pub(crate) fn post_migrate() -> Result<(), &'static str> { - //TODO: Add the try-runtime test storage to check that - // the total number of nodes is kept the same before and after. ensure!( StorageVersion::::get() == DelegationStorageVersion::v2, "The version after deployment is not 2 as expected." @@ -279,8 +303,8 @@ mod v1 { Ok(()) } - // Verifies that for any node that has a parent, the parent includes the node in - // its children. + // Verifies that for any node that has a parent, the parent includes that node + // in its children. #[cfg(feature = "try-runtime")] fn verify_parent_children_integrity() -> bool { // If all's good and false is returned, returns true. From d9506a774eaea5206712efb774eb01cbcc48f57a Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 19 Jul 2021 12:04:32 +0200 Subject: [PATCH 34/49] bench: add spiritnet benchmarks for delegation and attestation --- runtimes/peregrine/src/lib.rs | 4 +- runtimes/peregrine/src/weights/attestation.rs | 40 ++++----- runtimes/peregrine/src/weights/delegation.rs | 88 +++++++++++++++++++ runtimes/peregrine/src/weights/mod.rs | 1 + 4 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 runtimes/peregrine/src/weights/delegation.rs diff --git a/runtimes/peregrine/src/lib.rs b/runtimes/peregrine/src/lib.rs index be6011fe79..4673a03ee7 100644 --- a/runtimes/peregrine/src/lib.rs +++ b/runtimes/peregrine/src/lib.rs @@ -672,7 +672,7 @@ impl delegation::Config for Runtime { type MaxSignatureByteLength = MaxSignatureByteLength; type MaxParentChecks = MaxParentChecks; type MaxRevocations = MaxRevocations; - type WeightInfo = (); + type WeightInfo = weights::delegation::WeightInfo; } impl ctype::Config for Runtime { @@ -1039,7 +1039,7 @@ impl_runtime_apis! { add_benchmark!(params, batches, attestation, Attestation); add_benchmark!(params, batches, ctype, Ctype); - // add_benchmark!(params, batches, delegation, Delegation); + add_benchmark!(params, batches, delegation, Delegation); add_benchmark!(params, batches, did, Did); add_benchmark!(params, batches, kilt_launch, KiltLaunch); add_benchmark!(params, batches, pallet_vesting, Vesting); diff --git a/runtimes/peregrine/src/weights/attestation.rs b/runtimes/peregrine/src/weights/attestation.rs index 1d409b375d..4f61f7928e 100644 --- a/runtimes/peregrine/src/weights/attestation.rs +++ b/runtimes/peregrine/src/weights/attestation.rs @@ -19,30 +19,22 @@ //! Autogenerated weights for attestation //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-06-17, STEPS: `[1, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-07-19, STEPS: `[1, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// ./target/release/kilt-parachain +// target/release/kilt-parachain // benchmark -// --chain -// dev -// --heap-pages -// 4096 -// --extrinsic -// * -// --pallet -// attestation -// --steps -// 1 -// --repeat -// 20 -// --execution -// wasm -// --wasm-execution -// Compiled +// --chain=dev +// --execution=wasm +// --wasm-execution=Compiled +// --heap-pages=4096 +// --extrinsic=* +// --pallet=attestation +// --steps=1 +// --repeat=20 // --output -// runtimes/parachain/src/weights/attestation.rs +// runtimes/peregrine/src/weights/attestation.rs // --template // .maintain/runtime-weight-template.hbs @@ -58,16 +50,16 @@ use sp_std::marker::PhantomData; pub struct WeightInfo(PhantomData); impl attestation::WeightInfo for WeightInfo { fn add() -> Weight { - 67_947_000_u64 + (73_618_000_u64) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } fn revoke(d: u32, ) -> Weight { - 44_056_000_u64 - // Standard Error: 30_000 - .saturating_add(8_178_000_u64.saturating_mul(d as Weight)) + (43_775_000_u64) + // Standard Error: 42_000 + .saturating_add((8_458_000_u64).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().reads(1_u64.saturating_mul(d as Weight))) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(d as Weight))) .saturating_add(T::DbWeight::get().writes(1_u64)) } } \ No newline at end of file diff --git a/runtimes/peregrine/src/weights/delegation.rs b/runtimes/peregrine/src/weights/delegation.rs new file mode 100644 index 0000000000..5d3910682a --- /dev/null +++ b/runtimes/peregrine/src/weights/delegation.rs @@ -0,0 +1,88 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2021 BOTLabs GmbH + +// The KILT Blockchain is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The KILT Blockchain is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// If you feel like getting in touch with us, you can do so at info@botlabs.org + +//! Autogenerated weights for delegation +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-07-19, STEPS: `[1, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// target/release/kilt-parachain +// benchmark +// --chain=dev +// --execution=wasm +// --wasm-execution=Compiled +// --heap-pages=4096 +// --extrinsic=* +// --pallet=delegation +// --steps=1 +// --repeat=20 +// --output +// runtimes/peregrine/src/weights/delegation.rs +// --template +// .maintain/runtime-weight-template.hbs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weights for delegation using the recommended hardware. +pub struct WeightInfo(PhantomData); +impl delegation::WeightInfo for WeightInfo { + fn create_hierarchy() -> Weight { + (44_864_000_u64) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + fn revoke_hierarchy(r: u32, ) -> Weight { + (43_886_000_u64) + // Standard Error: 558_000 + .saturating_add((30_900_000_u64).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r as Weight))) + .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r as Weight))) + } + fn add_delegation() -> Weight { + (132_759_000_u64) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + fn revoke_delegation_root_child(r: u32, _c: u32, ) -> Weight { + (21_840_000_u64) + // Standard Error: 386_000 + .saturating_add((30_669_000_u64).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r as Weight))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r as Weight))) + } + fn revoke_delegation_leaf(r: u32, c: u32, ) -> Weight { + (52_078_000_u64) + // Standard Error: 193_000 + .saturating_add((228_000_u64).saturating_mul(r as Weight)) + // Standard Error: 193_000 + .saturating_add((7_997_000_u64).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +} \ No newline at end of file diff --git a/runtimes/peregrine/src/weights/mod.rs b/runtimes/peregrine/src/weights/mod.rs index ba398ac5cf..66fa4afcd9 100644 --- a/runtimes/peregrine/src/weights/mod.rs +++ b/runtimes/peregrine/src/weights/mod.rs @@ -18,6 +18,7 @@ pub mod attestation; pub mod ctype; +pub mod delegation; pub mod did; pub mod frame_system; pub mod kilt_launch; From 3dc973e7864da3dba00a567cb4b5bd5ede341117 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 19 Jul 2021 11:26:47 +0200 Subject: [PATCH 35/49] feat: additional logs for count of migrated nodes --- pallets/delegation/src/migrations.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index c19c305281..a6c341e0b7 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -200,6 +200,8 @@ mod v1 { new_nodes.iter().count(), "The # of old roots does not match the current # of new delegation nodes." ); + + log::info!("{} root(s) migrated.", deprecated::v1::storage::Roots::::iter().count()); } // Removes the whole Roots storage. @@ -242,11 +244,15 @@ mod v1 { // If runtime testing, makes sure that the old number of delegations is // reflected in the new number of nodes that will be added to the storage. #[cfg(feature = "try-runtime")] - assert_eq!( - deprecated::v1::storage::Delegations::::iter().count(), - new_nodes.iter().count().saturating_sub(DelegationHierarchies::::iter().count()), - "The # of old delegation nodes does not match the # of new delegation nodes (calculate as the total # of nodes - the # of delegation hierarchies)." - ); + { + assert_eq!( + deprecated::v1::storage::Delegations::::iter().count(), + new_nodes.iter().count().saturating_sub(DelegationHierarchies::::iter().count()), + "The # of old delegation nodes does not match the # of new delegation nodes (calculate as the total # of nodes - the # of delegation hierarchies)." + ); + + log::info!("{} regular node(s) migrated.", deprecated::v1::storage::Delegations::::iter().count()); + } // Removes the whole Delegations and Children storages. frame_support::migration::remove_storage_prefix( From 48d51d303f20470ccc7f9d3636990ed2ff479534 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 19 Jul 2021 12:07:37 +0200 Subject: [PATCH 36/49] chore: fmt --- pallets/delegation/src/migrations.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index a6c341e0b7..0e11aa26fb 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -201,7 +201,10 @@ mod v1 { "The # of old roots does not match the current # of new delegation nodes." ); - log::info!("{} root(s) migrated.", deprecated::v1::storage::Roots::::iter().count()); + log::info!( + "{} root(s) migrated.", + deprecated::v1::storage::Roots::::iter().count() + ); } // Removes the whole Roots storage. @@ -251,7 +254,10 @@ mod v1 { "The # of old delegation nodes does not match the # of new delegation nodes (calculate as the total # of nodes - the # of delegation hierarchies)." ); - log::info!("{} regular node(s) migrated.", deprecated::v1::storage::Delegations::::iter().count()); + log::info!( + "{} regular node(s) migrated.", + deprecated::v1::storage::Delegations::::iter().count() + ); } // Removes the whole Delegations and Children storages. From 135facf07931283d06b01b9557820138e68c0e78 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 19 Jul 2021 12:09:16 +0200 Subject: [PATCH 37/49] chore: removed useless file --- delegation_expanded.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 delegation_expanded.rs diff --git a/delegation_expanded.rs b/delegation_expanded.rs deleted file mode 100644 index e69de29bb2..0000000000 From 13030f7fe98b9d0e17b4c223c99cfad549473bd4 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 19 Jul 2021 13:48:34 +0200 Subject: [PATCH 38/49] chore: bump runtime version --- runtimes/peregrine/src/lib.rs | 2 +- runtimes/spiritnet/src/lib.rs | 2 +- runtimes/standalone/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runtimes/peregrine/src/lib.rs b/runtimes/peregrine/src/lib.rs index 4673a03ee7..14a93e613a 100644 --- a/runtimes/peregrine/src/lib.rs +++ b/runtimes/peregrine/src/lib.rs @@ -121,7 +121,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("mashnet-node"), impl_name: create_runtime_str!("mashnet-node"), authoring_version: 4, - spec_version: 16, + spec_version: 17, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2, diff --git a/runtimes/spiritnet/src/lib.rs b/runtimes/spiritnet/src/lib.rs index a36be7b449..871bc46ad4 100644 --- a/runtimes/spiritnet/src/lib.rs +++ b/runtimes/spiritnet/src/lib.rs @@ -102,7 +102,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("kilt-spiritnet"), impl_name: create_runtime_str!("kilt-spiritnet"), authoring_version: 1, - spec_version: 16, + spec_version: 17, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/runtimes/standalone/src/lib.rs b/runtimes/standalone/src/lib.rs index ff16c6bd31..9ab472eee6 100644 --- a/runtimes/standalone/src/lib.rs +++ b/runtimes/standalone/src/lib.rs @@ -109,7 +109,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("mashnet-node"), impl_name: create_runtime_str!("mashnet-node"), authoring_version: 4, - spec_version: 16, + spec_version: 17, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2, From 78ea8b51f15e76eafedd411eed18cebeb4dcce18 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 19 Jul 2021 16:18:00 +0200 Subject: [PATCH 39/49] fix: PR comments --- pallets/delegation/src/migrations.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 0e11aa26fb..35b4e60716 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -96,6 +96,7 @@ mod v1 { use super::*; use frame_support::{IterableStorageMap, StorageMap, StoragePrefixedMap}; + use sp_runtime::traits::Zero; /// Checks whether the deployed storage version is v1. If not, it won't try /// migrate any data. @@ -125,7 +126,7 @@ mod v1 { /// storage entry added to the nodes under the children set. pub(crate) fn migrate() -> Weight { log::info!("v1 -> v2 delegation storage migrator started!"); - let mut total_weight = 0u64; + let mut total_weight = Weight::zero(); // Before being stored, the nodes are saved in a map so that after we go over // all the nodes and the parent-child relationship in the storage, we can update @@ -155,8 +156,9 @@ mod v1 { } fn migrate_roots(new_nodes: &mut BTreeMap, DelegationNode>) -> Weight { - let total_weight = - deprecated::v1::storage::Roots::::iter().fold(0u64, |mut total_weight, (old_root_id, old_root_node)| { + let total_weight = deprecated::v1::storage::Roots::::iter().fold( + Weight::zero(), + |mut total_weight, (old_root_id, old_root_node)| { let new_hierarchy_details = DelegationHierarchyDetails:: { ctype_hash: old_root_node.ctype_hash, }; @@ -184,7 +186,9 @@ mod v1 { new_nodes.insert(old_root_id, new_root_node); total_weight - }); + }, + ); + // If runtime testing, makes sure that the old number of roots is reflected in // the new number of nodes and hierarchies migrated. #[cfg(feature = "try-runtime")] @@ -244,6 +248,7 @@ mod v1 { total_weight }, ); + // If runtime testing, makes sure that the old number of delegations is // reflected in the new number of nodes that will be added to the storage. #[cfg(feature = "try-runtime")] From 310cad8bc19ba5887a722660543ab4e0b8d6ce17 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 21 Jul 2021 08:46:40 +0200 Subject: [PATCH 40/49] fix: re-introduce root_id in delegation creation hash --- pallets/delegation/src/benchmarking.rs | 4 ++-- pallets/delegation/src/lib.rs | 20 +++++++++++--------- pallets/delegation/src/tests.rs | 7 +++++++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/pallets/delegation/src/benchmarking.rs b/pallets/delegation/src/benchmarking.rs index 13edb6352d..73864fdc99 100644 --- a/pallets/delegation/src/benchmarking.rs +++ b/pallets/delegation/src/benchmarking.rs @@ -103,7 +103,7 @@ where // delegate signs delegation to parent let hash: Vec = - Pallet::::calculate_delegation_creation_hash(&delegation_id, &parent_id, &permissions).encode(); + Pallet::::calculate_delegation_creation_hash(&delegation_id, &root_id, &parent_id, &permissions).encode(); let sig = sp_io::crypto::sr25519_sign(KeyTypeId(*b"aura"), &delegation_acc_public, hash.as_ref()) .ok_or("Error while building signature of delegation.")?; @@ -222,7 +222,7 @@ benchmarks! { let parent_id = leaf_id; let perm: Permissions = Permissions::ATTEST | Permissions::DELEGATE; - let hash_root = Pallet::::calculate_delegation_creation_hash(&delegation_id, &parent_id, &perm); + let hash_root = Pallet::::calculate_delegation_creation_hash(&delegation_id, &hierarchy_id, &parent_id, &perm); let sig = sp_io::crypto::sr25519_sign(KeyTypeId(*b"aura"), &delegate_acc_public, hash_root.as_ref()).ok_or("Error while building signature of delegation.")?; let delegate_acc_id: T::AccountId = delegate_acc_public.into(); diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index bbf71b92d7..f9426bb2f4 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -262,8 +262,16 @@ pub mod pallet { ) -> DispatchResult { let delegator = ::EnsureOrigin::ensure_origin(origin)?; + ensure!( + !>::contains_key(&delegation_id), + Error::::DelegationAlreadyExists + ); + + let parent_node = >::get(&parent_id).ok_or(Error::::ParentDelegationNotFound)?; + let hierarchy_root_id = parent_node.hierarchy_root_id; + // Calculate the hash root - let hash_root = Self::calculate_delegation_creation_hash(&delegation_id, &parent_id, &permissions); + let hash_root = Self::calculate_delegation_creation_hash(&delegation_id, &hierarchy_root_id, &parent_id, &permissions); // Verify that the hash root signature is correct. DelegationSignatureVerificationOf::::verify(&delegate, &hash_root.encode(), &delegate_signature) @@ -272,14 +280,6 @@ pub mod pallet { SignatureVerificationError::SignatureInvalid => Error::::InvalidDelegateSignature, })?; - ensure!( - !>::contains_key(&delegation_id), - Error::::DelegationAlreadyExists - ); - - let parent_node = >::get(&parent_id).ok_or(Error::::ParentDelegationNotFound)?; - let hierarchy_root_id = parent_node.hierarchy_root_id; - // Check if the parent's delegate is the creator of this delegation node... ensure!( parent_node.details.owner == delegator, @@ -437,11 +437,13 @@ impl Pallet { // Calculates the hash of all values of a delegation creation transaction. fn calculate_delegation_creation_hash( delegation_id: &DelegationNodeIdOf, + root_id: &DelegationNodeIdOf, parent_id: &DelegationNodeIdOf, permissions: &Permissions, ) -> T::Hash { // Add all values to an u8 vector. let mut hashed_values: Vec = delegation_id.as_ref().to_vec(); + hashed_values.extend_from_slice(root_id.as_ref()); hashed_values.extend_from_slice(parent_id.as_ref()); hashed_values.extend_from_slice(permissions.as_u8().as_ref()); // Hash the resulting vector diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index 245086c24b..bef6794b0c 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -131,6 +131,7 @@ fn create_delegation_direct_root_successful() { let delegation_info = Delegation::calculate_delegation_creation_hash( &delegation_id, &hierarchy_root_id, + &hierarchy_root_id, &delegation_node.details.permissions, ); @@ -198,6 +199,7 @@ fn create_delegation_with_parent_successful() { let delegation_info = Delegation::calculate_delegation_creation_hash( &delegation_id, + &hierarchy_root_id, &parent_id, &delegation_node.details.permissions, ); @@ -265,6 +267,7 @@ fn invalid_delegate_signature_create_delegation_error() { let delegate_signature = alternative_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_creation_hash( &delegation_id, &hierarchy_root_id, + &hierarchy_root_id, &delegation_node.details.permissions, ))); @@ -312,6 +315,7 @@ fn duplicate_delegation_create_delegation_error() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_creation_hash( &delegation_id, &hierarchy_root_id, + &hierarchy_root_id, &delegation_node.details.permissions, ))); @@ -360,6 +364,7 @@ fn parent_not_existing_create_delegation_error() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_creation_hash( &delegation_id, &hierarchy_root_id, + &hierarchy_root_id, &delegation_node.details.permissions, ))); @@ -411,6 +416,7 @@ fn not_owner_of_parent_create_delegation_error() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_creation_hash( &delegation_id, + &hierarchy_root_id, &parent_id, &delegation_node.details.permissions, ))); @@ -464,6 +470,7 @@ fn unauthorised_delegation_create_delegation_error() { let delegate_signature = delegate_keypair.sign(&hash_to_u8(Delegation::calculate_delegation_creation_hash( &delegation_id, + &hierarchy_root_id, &parent_id, &delegation_node.details.permissions, ))); From ef941d3877348943b383b329bfa62d393c9562af Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 21 Jul 2021 08:53:55 +0200 Subject: [PATCH 41/49] chore: capitalize storage version enum --- pallets/delegation/src/migrations.rs | 45 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs index 35b4e60716..298c130a5a 100644 --- a/pallets/delegation/src/migrations.rs +++ b/pallets/delegation/src/migrations.rs @@ -35,18 +35,17 @@ pub trait VersionMigratorTrait { } /// Storage version of the delegation pallet. -#[allow(non_camel_case_types)] #[derive(Copy, Clone, Encode, Eq, Decode, Ord, PartialEq, PartialOrd)] pub enum DelegationStorageVersion { - v1, - v2, + V1, + V2, } -#[allow(dead_code)] +#[cfg(feature = "try-runtime")] impl DelegationStorageVersion { /// The latest storage version. fn latest() -> Self { - Self::v2 + Self::V2 } } @@ -59,7 +58,7 @@ impl DelegationStorageVersion { // old version anymore. impl Default for DelegationStorageVersion { fn default() -> Self { - Self::v1 + Self::V1 } } @@ -68,16 +67,16 @@ impl VersionMigratorTrait for DelegationStorageVersion { #[cfg(feature = "try-runtime")] fn pre_migrate(&self) -> Result<(), &str> { match *self { - Self::v1 => v1::pre_migrate::(), - Self::v2 => Err("Already latest v2 version."), + Self::V1 => v1::pre_migrate::(), + Self::V2 => Err("Already latest v2 version."), } } // It runs the righ migration logic depending on the current storage version. fn migrate(&self) -> Weight { match *self { - Self::v1 => v1::migrate::(), - Self::v2 => 0u64, + Self::V1 => v1::migrate::(), + Self::V2 => 0u64, } } @@ -86,8 +85,8 @@ impl VersionMigratorTrait for DelegationStorageVersion { #[cfg(feature = "try-runtime")] fn post_migrate(&self) -> Result<(), &str> { match *self { - Self::v1 => v1::post_migrate::(), - Self::v2 => Err("Migration from v2 should have never happened in the first place."), + Self::V1 => v1::post_migrate::(), + Self::V2 => Err("Migration from v2 should have never happened in the first place."), } } } @@ -109,7 +108,7 @@ mod v1 { #[cfg(feature = "try-runtime")] pub(crate) fn pre_migrate() -> Result<(), &'static str> { ensure!( - StorageVersion::::get() == DelegationStorageVersion::v1, + StorageVersion::::get() == DelegationStorageVersion::V1, "Current deployed version is not v1." ); @@ -146,7 +145,7 @@ mod v1 { // to their parents. total_weight = total_weight.saturating_add(finalize_children_nodes::(&mut new_nodes, total_weight)); - StorageVersion::::set(DelegationStorageVersion::v2); + StorageVersion::::set(DelegationStorageVersion::V2); // Adds a write from StorageVersion::set() weight. total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); log::debug!("Total weight consumed: {}", total_weight); @@ -309,7 +308,7 @@ mod v1 { #[cfg(feature = "try-runtime")] pub(crate) fn post_migrate() -> Result<(), &'static str> { ensure!( - StorageVersion::::get() == DelegationStorageVersion::v2, + StorageVersion::::get() == DelegationStorageVersion::V2, "The version after deployment is not 2 as expected." ); ensure!( @@ -352,7 +351,7 @@ mod v1 { #[test] fn fail_version_higher() { let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::v2) + .with_storage_version(DelegationStorageVersion::V2) .build(None); ext.execute_with(|| { #[cfg(feature = "try-runtime")] @@ -366,7 +365,7 @@ mod v1 { #[test] fn ok_no_delegations() { let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::v1) + .with_storage_version(DelegationStorageVersion::V1) .build(None); ext.execute_with(|| { #[cfg(feature = "try-runtime")] @@ -388,7 +387,7 @@ mod v1 { #[test] fn ok_only_root() { let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::v1) + .with_storage_version(DelegationStorageVersion::V1) .build(None); ext.execute_with(|| { let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); @@ -437,7 +436,7 @@ mod v1 { #[test] fn ok_root_two_children() { let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::v1) + .with_storage_version(DelegationStorageVersion::V1) .build(None); ext.execute_with(|| { let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); @@ -525,7 +524,7 @@ mod v1 { #[test] fn ok_three_level_hierarchy() { let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::v1) + .with_storage_version(DelegationStorageVersion::V1) .build(None); ext.execute_with(|| { let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); @@ -625,8 +624,8 @@ impl DelegationStorageMigrator { // If the version current deployed is at least v1, there is no more migrations // to run (other than the one from v1). match current { - DelegationStorageVersion::v1 => None, - DelegationStorageVersion::v2 => None, + DelegationStorageVersion::V1 => None, + DelegationStorageVersion::V2 => None, } } @@ -700,7 +699,7 @@ mod tests { #[test] fn ok_from_v1_migration() { let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::v1) + .with_storage_version(DelegationStorageVersion::V1) .build(None); ext.execute_with(|| { #[cfg(feature = "try-runtime")] From e96bc31fb6d8f4809f7a29616a363ce4b45af05f Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 21 Jul 2021 09:06:35 +0200 Subject: [PATCH 42/49] chore: move migrations in their own module --- pallets/delegation/src/benchmarking.rs | 3 +- pallets/delegation/src/lib.rs | 3 +- pallets/delegation/src/migrations.rs | 740 ----------------------- pallets/delegation/src/migrations/mod.rs | 223 +++++++ pallets/delegation/src/migrations/v1.rs | 522 ++++++++++++++++ 5 files changed, 749 insertions(+), 742 deletions(-) delete mode 100644 pallets/delegation/src/migrations.rs create mode 100644 pallets/delegation/src/migrations/mod.rs create mode 100644 pallets/delegation/src/migrations/v1.rs diff --git a/pallets/delegation/src/benchmarking.rs b/pallets/delegation/src/benchmarking.rs index 73864fdc99..c0acdfe21e 100644 --- a/pallets/delegation/src/benchmarking.rs +++ b/pallets/delegation/src/benchmarking.rs @@ -103,7 +103,8 @@ where // delegate signs delegation to parent let hash: Vec = - Pallet::::calculate_delegation_creation_hash(&delegation_id, &root_id, &parent_id, &permissions).encode(); + Pallet::::calculate_delegation_creation_hash(&delegation_id, &root_id, &parent_id, &permissions) + .encode(); let sig = sp_io::crypto::sr25519_sign(KeyTypeId(*b"aura"), &delegation_acc_public, hash.as_ref()) .ok_or("Error while building signature of delegation.")?; diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index f9426bb2f4..7d50ff5b07 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -271,7 +271,8 @@ pub mod pallet { let hierarchy_root_id = parent_node.hierarchy_root_id; // Calculate the hash root - let hash_root = Self::calculate_delegation_creation_hash(&delegation_id, &hierarchy_root_id, &parent_id, &permissions); + let hash_root = + Self::calculate_delegation_creation_hash(&delegation_id, &hierarchy_root_id, &parent_id, &permissions); // Verify that the hash root signature is correct. DelegationSignatureVerificationOf::::verify(&delegate, &hash_root.encode(), &delegate_signature) diff --git a/pallets/delegation/src/migrations.rs b/pallets/delegation/src/migrations.rs deleted file mode 100644 index 298c130a5a..0000000000 --- a/pallets/delegation/src/migrations.rs +++ /dev/null @@ -1,740 +0,0 @@ -// KILT Blockchain – https://botlabs.org -// Copyright (C) 2019-2021 BOTLabs GmbH - -// The KILT Blockchain is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The KILT Blockchain is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// If you feel like getting in touch with us, you can do so at info@botlabs.org - -use codec::{Decode, Encode}; -use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData}; - -use crate::*; - -/// A trait that allows version migrators to access the underlying pallet's -/// context, e.g., its Config trait. -/// -/// In this way, the migrator can access the pallet's storage and the pallet's -/// types directly. -pub trait VersionMigratorTrait { - #[cfg(feature = "try-runtime")] - fn pre_migrate(&self) -> Result<(), &str>; - fn migrate(&self) -> Weight; - #[cfg(feature = "try-runtime")] - fn post_migrate(&self) -> Result<(), &str>; -} - -/// Storage version of the delegation pallet. -#[derive(Copy, Clone, Encode, Eq, Decode, Ord, PartialEq, PartialOrd)] -pub enum DelegationStorageVersion { - V1, - V2, -} - -#[cfg(feature = "try-runtime")] -impl DelegationStorageVersion { - /// The latest storage version. - fn latest() -> Self { - Self::V2 - } -} - -// All nodes will default to this, which is not bad, as in case the "real" -// version is a later one (i.e. the node has been started with already the -// latest version), the migration will simply do nothing as there's nothing in -// the old storage entries to migrate from. -// -// It might get updated in the future when we know that no node is running this -// old version anymore. -impl Default for DelegationStorageVersion { - fn default() -> Self { - Self::V1 - } -} - -impl VersionMigratorTrait for DelegationStorageVersion { - // It runs the right pre_migrate logic depending on the current storage version. - #[cfg(feature = "try-runtime")] - fn pre_migrate(&self) -> Result<(), &str> { - match *self { - Self::V1 => v1::pre_migrate::(), - Self::V2 => Err("Already latest v2 version."), - } - } - - // It runs the righ migration logic depending on the current storage version. - fn migrate(&self) -> Weight { - match *self { - Self::V1 => v1::migrate::(), - Self::V2 => 0u64, - } - } - - // It runs the right post_migrate logic depending on the current storage - // version. - #[cfg(feature = "try-runtime")] - fn post_migrate(&self) -> Result<(), &str> { - match *self { - Self::V1 => v1::post_migrate::(), - Self::V2 => Err("Migration from v2 should have never happened in the first place."), - } - } -} - -mod v1 { - use super::*; - - use frame_support::{IterableStorageMap, StorageMap, StoragePrefixedMap}; - use sp_runtime::traits::Zero; - - /// Checks whether the deployed storage version is v1. If not, it won't try - /// migrate any data. - /// - /// Since we have the default storage version to this one, it can happen - /// that new nodes will still try to perform runtime migrations. This is not - /// a problem as at the end of the day there will not be anything in the old - /// storage entries to migrate from. Hence, the "pseudo-"migration will - /// simply result in the update of the storage deployed version. - #[cfg(feature = "try-runtime")] - pub(crate) fn pre_migrate() -> Result<(), &'static str> { - ensure!( - StorageVersion::::get() == DelegationStorageVersion::V1, - "Current deployed version is not v1." - ); - - log::info!("Version storage migrating from v1 to v2"); - Ok(()) - } - - /// It migrates the old storage entries to the new ones. - /// - /// Specifically, for each entry in Roots, a new entry in - /// DelegationHierarchies + a new node in DelegationNodes is created. - /// Furthermore, nodes in Delegations are migrated to the new structure and - /// stored under DelegationNodes, with any children from the Children - /// storage entry added to the nodes under the children set. - pub(crate) fn migrate() -> Weight { - log::info!("v1 -> v2 delegation storage migrator started!"); - let mut total_weight = Weight::zero(); - - // Before being stored, the nodes are saved in a map so that after we go over - // all the nodes and the parent-child relationship in the storage, we can update - // the `parent` link of each node accordingly. Otherwise, we would need to save - // the node in the storage, and then retrieve it again to update the parent - // link. - let mut new_nodes: BTreeMap, DelegationNode> = BTreeMap::new(); - - // First iterate over the delegation roots and translate them to hierarchies. - total_weight = total_weight.saturating_add(migrate_roots::(&mut new_nodes)); - - // Then iterate over the regular delegation nodes. - total_weight = total_weight.saturating_add(migrate_nodes::(&mut new_nodes, total_weight)); - - // By now, all the children should have been correctly added to the nodes. - // We now need to modify all the nodes that are children by adding a reference - // to their parents. - total_weight = total_weight.saturating_add(finalize_children_nodes::(&mut new_nodes, total_weight)); - - StorageVersion::::set(DelegationStorageVersion::V2); - // Adds a write from StorageVersion::set() weight. - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - log::debug!("Total weight consumed: {}", total_weight); - log::info!("v1 -> v2 delegation storage migrator finished!"); - - total_weight - } - - fn migrate_roots(new_nodes: &mut BTreeMap, DelegationNode>) -> Weight { - let total_weight = deprecated::v1::storage::Roots::::iter().fold( - Weight::zero(), - |mut total_weight, (old_root_id, old_root_node)| { - let new_hierarchy_details = DelegationHierarchyDetails:: { - ctype_hash: old_root_node.ctype_hash, - }; - let new_root_details = DelegationDetails:: { - owner: old_root_node.owner, - // Old roots did not have any permissions. So now we give them all permissions. - permissions: Permissions::all(), - revoked: old_root_node.revoked, - }; - // In here, we already check for potential children of root nodes and ONLY - // update the children information. The parent information will be updated - // later, when we know we have seen all the children already. - let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); - if let Some(root_children_ids) = deprecated::v1::storage::Children::::take(old_root_id) { - new_root_node.children = root_children_ids.iter().copied().collect(); - } - // Add Children::take() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - - DelegationHierarchies::insert(old_root_id, new_hierarchy_details); - // Adds a read from Roots::drain() and a write from - // DelegationHierarchies::insert() weights - total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); - // Add the node to the temporary map of nodes to be added at the end. - new_nodes.insert(old_root_id, new_root_node); - - total_weight - }, - ); - - // If runtime testing, makes sure that the old number of roots is reflected in - // the new number of nodes and hierarchies migrated. - #[cfg(feature = "try-runtime")] - { - assert_eq!( - deprecated::v1::storage::Roots::::iter().count(), - DelegationHierarchies::::iter().count(), - "The # of old roots does not match the # of new delegation hierarchies." - ); - - assert_eq!( - deprecated::v1::storage::Roots::::iter().count(), - new_nodes.iter().count(), - "The # of old roots does not match the current # of new delegation nodes." - ); - - log::info!( - "{} root(s) migrated.", - deprecated::v1::storage::Roots::::iter().count() - ); - } - - // Removes the whole Roots storage. - frame_support::migration::remove_storage_prefix( - deprecated::v1::storage::Roots::::module_prefix(), - deprecated::v1::storage::Roots::::storage_prefix(), - b"", - ); - - total_weight - } - - fn migrate_nodes( - new_nodes: &mut BTreeMap, DelegationNode>, - initial_weight: Weight, - ) -> Weight { - let total_weight = deprecated::v1::storage::Delegations::::iter().fold( - initial_weight, - |mut total_weight, (old_node_id, old_node)| { - let new_node_details = DelegationDetails:: { - owner: old_node.owner, - permissions: old_node.permissions, - revoked: old_node.revoked, - }; - // In the old version, a parent None indicated the node is a child of the root. - let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); - let mut new_node = DelegationNode::new_node(old_node.root_id, new_node_parent_id, new_node_details); - if let Some(children_ids) = deprecated::v1::storage::Children::::take(old_node_id) { - new_node.children = children_ids.iter().copied().collect(); - } - // Add Children::take() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - // Adds a read from Roots::drain() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - new_nodes.insert(old_node_id, new_node); - - total_weight - }, - ); - - // If runtime testing, makes sure that the old number of delegations is - // reflected in the new number of nodes that will be added to the storage. - #[cfg(feature = "try-runtime")] - { - assert_eq!( - deprecated::v1::storage::Delegations::::iter().count(), - new_nodes.iter().count().saturating_sub(DelegationHierarchies::::iter().count()), - "The # of old delegation nodes does not match the # of new delegation nodes (calculate as the total # of nodes - the # of delegation hierarchies)." - ); - - log::info!( - "{} regular node(s) migrated.", - deprecated::v1::storage::Delegations::::iter().count() - ); - } - - // Removes the whole Delegations and Children storages. - frame_support::migration::remove_storage_prefix( - deprecated::v1::storage::Delegations::::module_prefix(), - deprecated::v1::storage::Delegations::::storage_prefix(), - b"", - ); - frame_support::migration::remove_storage_prefix( - deprecated::v1::storage::Children::::module_prefix(), - deprecated::v1::storage::Children::::storage_prefix(), - b"", - ); - - total_weight - } - - fn finalize_children_nodes( - new_nodes: &mut BTreeMap, DelegationNode>, - initial_weight: Weight, - ) -> Weight { - new_nodes - .clone() - .into_iter() - .fold(initial_weight, |mut total_weight, (new_node_id, new_node)| { - // Iterate over the children of every node and update their parent link. - new_node.children.iter().for_each(|child_id| { - new_nodes - .entry(*child_id) - .and_modify(|node| node.parent = Some(new_node_id)); - }); - // We can then finally insert the new delegation node in the storage as it won't - // be updated anymore during the migration. - DelegationNodes::::insert(new_node_id, new_node); - // Adds a write from DelegationNodes::insert() weight - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - - total_weight - }) - } - - /// Checks whether the deployed storage version is v2 and whether any - /// parent-child link has gone missing. - #[cfg(feature = "try-runtime")] - pub(crate) fn post_migrate() -> Result<(), &'static str> { - ensure!( - StorageVersion::::get() == DelegationStorageVersion::V2, - "The version after deployment is not 2 as expected." - ); - ensure!( - verify_parent_children_integrity::(), - "Some parent-child relationship has been broken in the migration." - ); - log::info!("Version storage migrated from v1 to v2"); - Ok(()) - } - - // Verifies that for any node that has a parent, the parent includes that node - // in its children. - #[cfg(feature = "try-runtime")] - fn verify_parent_children_integrity() -> bool { - // If all's good and false is returned, returns true. - !DelegationNodes::::iter().any(|(node_id, node)| { - if let Some(parent_id) = node.parent { - if let Some(parent_node) = DelegationNodes::::get(parent_id) { - // True if the children set does not contain the parent ID - return !parent_node.children.contains(&node_id); - } else { - // If the parent node cannot be found, it is definitely an error, so return - // true. - return true; - } - } - // If all's good we keep returning false. - false - }) - } - - // Tests for the v1 storage migrator. - #[cfg(test)] - mod tests { - use sp_core::Pair; - - use super::*; - use crate::mock::Test as TestRuntime; - - #[test] - fn fail_version_higher() { - let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::V2) - .build(None); - ext.execute_with(|| { - #[cfg(feature = "try-runtime")] - assert!( - pre_migrate::().is_err(), - "Pre-migration for v1 should fail." - ); - }); - } - - #[test] - fn ok_no_delegations() { - let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::V1) - .build(None); - ext.execute_with(|| { - #[cfg(feature = "try-runtime")] - assert!( - pre_migrate::().is_ok(), - "Pre-migration for v1 should not fail." - ); - - migrate::(); - - #[cfg(feature = "try-runtime")] - assert!( - post_migrate::().is_ok(), - "Post-migration for v1 should not fail." - ); - }); - } - - #[test] - fn ok_only_root() { - let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::V1) - .build(None); - ext.execute_with(|| { - let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); - let old_root_id = mock::get_delegation_id(true); - let old_root_node = - crate::deprecated::v1::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); - deprecated::v1::storage::Roots::insert(old_root_id, old_root_node.clone()); - - #[cfg(feature = "try-runtime")] - assert!( - pre_migrate::().is_ok(), - "Pre-migration for v1 should not fail." - ); - - migrate::(); - - #[cfg(feature = "try-runtime")] - assert!( - post_migrate::().is_ok(), - "Post-migration for v1 should not fail." - ); - - assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); - assert_eq!( - deprecated::v1::storage::Delegations::::iter_values().count(), - 0 - ); - assert_eq!( - deprecated::v1::storage::Children::::iter_values().count(), - 0 - ); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) - .expect("New delegation hierarchy should exist in the storage."); - assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); - let new_stored_root = DelegationNodes::::get(old_root_id) - .expect("New delegation root should exist in the storage."); - assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); - assert!(new_stored_root.parent.is_none()); - assert!(new_stored_root.children.is_empty()); - assert_eq!(new_stored_root.details.owner, old_root_node.owner); - assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); - }); - } - - #[test] - fn ok_root_two_children() { - let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::V1) - .build(None); - ext.execute_with(|| { - let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); - let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); - let old_root_id = mock::get_delegation_id(true); - let old_root_node = deprecated::v1::DelegationRoot::::new( - ctype::mock::get_ctype_hash(true), - alice.clone(), - ); - let old_node_id_1 = mock::get_delegation_id(false); - let old_node_1 = deprecated::v1::DelegationNode::::new_root_child( - old_root_id, - alice, - Permissions::DELEGATE, - ); - let old_node_id_2 = mock::get_delegation_id_2(true); - let old_node_2 = deprecated::v1::DelegationNode::::new_root_child( - old_root_id, - bob, - Permissions::ATTEST, - ); - deprecated::v1::storage::Roots::insert(old_root_id, old_root_node.clone()); - deprecated::v1::storage::Delegations::insert(old_node_id_1, old_node_1.clone()); - deprecated::v1::storage::Delegations::insert(old_node_id_2, old_node_2.clone()); - deprecated::v1::storage::Children::::insert( - old_root_id, - vec![old_node_id_1, old_node_id_2], - ); - - #[cfg(feature = "try-runtime")] - assert!( - pre_migrate::().is_ok(), - "Pre-migration for v1 should not fail." - ); - - migrate::(); - - #[cfg(feature = "try-runtime")] - assert!( - post_migrate::().is_ok(), - "Post-migration for v1 should not fail." - ); - - assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); - assert_eq!( - deprecated::v1::storage::Delegations::::iter_values().count(), - 0 - ); - assert_eq!( - deprecated::v1::storage::Children::::iter_values().count(), - 0 - ); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) - .expect("New delegation hierarchy should exist in the storage."); - assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); - let new_stored_root = DelegationNodes::::get(old_root_id) - .expect("New delegation root should exist in the storage."); - assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); - assert!(new_stored_root.parent.is_none()); - assert_eq!(new_stored_root.children.len(), 2); - assert!(new_stored_root.children.contains(&old_node_id_1)); - assert!(new_stored_root.children.contains(&old_node_id_2)); - assert_eq!(new_stored_root.details.owner, old_root_node.owner); - assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); - - let new_stored_node_1 = DelegationNodes::::get(old_node_id_1) - .expect("New delegation 1 should exist in the storage."); - assert_eq!(new_stored_node_1.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_node_1.parent, Some(old_root_id)); - assert!(new_stored_node_1.children.is_empty()); - assert_eq!(new_stored_node_1.details.owner, old_node_1.owner); - assert_eq!(new_stored_node_1.details.revoked, old_node_1.revoked); - - let new_stored_node_2 = DelegationNodes::::get(old_node_id_2) - .expect("New delegation 2 should exist in the storage."); - assert_eq!(new_stored_node_2.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_node_2.parent, Some(old_root_id)); - assert!(new_stored_node_2.children.is_empty()); - assert_eq!(new_stored_node_2.details.owner, old_node_2.owner); - assert_eq!(new_stored_node_2.details.revoked, old_node_2.revoked); - }); - } - - #[test] - fn ok_three_level_hierarchy() { - let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::V1) - .build(None); - ext.execute_with(|| { - let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); - let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); - let old_root_id = mock::get_delegation_id(true); - let old_root_node = deprecated::v1::DelegationRoot::::new( - ctype::mock::get_ctype_hash(true), - alice.clone(), - ); - let old_parent_id = mock::get_delegation_id(false); - let old_parent_node = deprecated::v1::DelegationNode::::new_root_child( - old_root_id, - alice, - Permissions::all(), - ); - let old_node_id = mock::get_delegation_id_2(true); - let old_node = deprecated::v1::DelegationNode::::new_node_child( - old_root_id, - old_parent_id, - bob, - Permissions::ATTEST, - ); - deprecated::v1::storage::Roots::insert(old_root_id, old_root_node.clone()); - deprecated::v1::storage::Delegations::insert(old_parent_id, old_parent_node.clone()); - deprecated::v1::storage::Delegations::insert(old_node_id, old_node.clone()); - deprecated::v1::storage::Children::::insert(old_root_id, vec![old_parent_id]); - deprecated::v1::storage::Children::::insert(old_parent_id, vec![old_node_id]); - - #[cfg(feature = "try-runtime")] - assert!( - pre_migrate::().is_ok(), - "Pre-migration for v1 should not fail." - ); - - migrate::(); - - #[cfg(feature = "try-runtime")] - assert!( - post_migrate::().is_ok(), - "Post-migration for v1 should not fail." - ); - - assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); - assert_eq!( - deprecated::v1::storage::Delegations::::iter_values().count(), - 0 - ); - assert_eq!( - deprecated::v1::storage::Children::::iter_values().count(), - 0 - ); - - let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) - .expect("New delegation hierarchy should exist in the storage."); - assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); - let new_stored_root = DelegationNodes::::get(old_root_id) - .expect("New delegation root should exist in the storage."); - assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); - assert!(new_stored_root.parent.is_none()); - assert_eq!(new_stored_root.children.len(), 1); - assert!(new_stored_root.children.contains(&old_parent_id)); - assert_eq!(new_stored_root.details.owner, old_root_node.owner); - assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); - - let new_stored_parent = DelegationNodes::::get(old_parent_id) - .expect("New delegation parent should exist in the storage."); - assert_eq!(new_stored_parent.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_parent.parent, Some(old_root_id)); - assert_eq!(new_stored_parent.children.len(), 1); - assert!(new_stored_parent.children.contains(&old_node_id)); - assert_eq!(new_stored_parent.details.owner, old_parent_node.owner); - assert_eq!(new_stored_parent.details.revoked, old_parent_node.revoked); - - let new_stored_node = DelegationNodes::::get(old_node_id) - .expect("New delegation node should exist in the storage."); - assert_eq!(new_stored_node.hierarchy_root_id, old_root_id); - assert_eq!(new_stored_node.parent, Some(old_parent_id)); - assert!(new_stored_node.children.is_empty()); - assert_eq!(new_stored_node.details.owner, old_node.owner); - assert_eq!(new_stored_node.details.revoked, old_node.revoked); - }); - } - } -} - -/// The delegation pallet's storage migrator, which handles all version -/// migrations in a sequential fashion. -/// -/// If a node has missed on more than one upgrade, the migrator will apply the -/// needed migrations one after the other. Otherwise, if no migration is needed, -/// the migrator will simply not do anything. -pub struct DelegationStorageMigrator(PhantomData); - -impl DelegationStorageMigrator { - // Contains the migration sequence logic. - fn get_next_storage_version(current: DelegationStorageVersion) -> Option { - // If the version current deployed is at least v1, there is no more migrations - // to run (other than the one from v1). - match current { - DelegationStorageVersion::V1 => None, - DelegationStorageVersion::V2 => None, - } - } - - /// Checks whether the latest storage version deployed is lower than the - /// latest possible. - #[cfg(feature = "try-runtime")] - pub(crate) fn pre_migrate() -> Result<(), &'static str> { - ensure!( - StorageVersion::::get() < DelegationStorageVersion::latest(), - "Already the latest storage version." - ); - - // Don't need to check for any other pre_migrate, as in try-runtime it is also - // called in the migrate() function. Same applies for post_migrate checks for - // each version migrator. - - Ok(()) - } - - /// Applies all the needed migrations from the currently deployed version to - /// the latest possible, one after the other. - /// - /// It returns the total weight consumed by ALL the migrations applied. - pub(crate) fn migrate() -> Weight { - let mut current_version: Option = Some(StorageVersion::::get()); - // Weight for StorageVersion::get(). - let mut total_weight = T::DbWeight::get().reads(1); - - while let Some(ver) = current_version { - // If any of the needed migrations pre-checks fail, the whole chain panics - // (during tests). - #[cfg(feature = "try-runtime")] - if let Err(err) = >::pre_migrate(&ver) { - panic!("{:?}", err); - } - let consumed_weight = >::migrate(&ver); - total_weight = total_weight.saturating_add(consumed_weight); - // If any of the needed migrations post-checks fail, the whole chain panics - // (during tests). - #[cfg(feature = "try-runtime")] - if let Err(err) = >::post_migrate(&ver) { - panic!("{:?}", err); - } - // If more migrations should be applied, current_version will not be None. - current_version = Self::get_next_storage_version(ver); - } - - total_weight - } - - /// Checks whether the storage version after all the needed migrations match - /// the latest one. - #[cfg(feature = "try-runtime")] - pub(crate) fn post_migrate() -> Result<(), &'static str> { - ensure!( - StorageVersion::::get() == DelegationStorageVersion::latest(), - "Not updated to the latest version." - ); - - Ok(()) - } -} - -// Tests for the entire storage migrator. -#[cfg(test)] -mod tests { - use super::*; - - use crate::mock::Test as TestRuntime; - - #[test] - fn ok_from_v1_migration() { - let mut ext = mock::ExtBuilder::default() - .with_storage_version(DelegationStorageVersion::V1) - .build(None); - ext.execute_with(|| { - #[cfg(feature = "try-runtime")] - assert!( - DelegationStorageMigrator::::pre_migrate().is_ok(), - "Storage pre-migrate from v1 should not fail." - ); - - DelegationStorageMigrator::::migrate(); - - #[cfg(feature = "try-runtime")] - assert!( - DelegationStorageMigrator::::post_migrate().is_ok(), - "Storage post-migrate from v1 should not fail." - ); - }); - } - - #[test] - fn ok_from_default_migration() { - let mut ext = mock::ExtBuilder::default().build(None); - ext.execute_with(|| { - #[cfg(feature = "try-runtime")] - assert!( - DelegationStorageMigrator::::pre_migrate().is_ok(), - "Storage pre-migrate from default version should not fail." - ); - - DelegationStorageMigrator::::migrate(); - - #[cfg(feature = "try-runtime")] - assert!( - DelegationStorageMigrator::::post_migrate().is_ok(), - "Storage post-migrate from default version should not fail." - ); - }); - } -} diff --git a/pallets/delegation/src/migrations/mod.rs b/pallets/delegation/src/migrations/mod.rs new file mode 100644 index 0000000000..b4a6b447e9 --- /dev/null +++ b/pallets/delegation/src/migrations/mod.rs @@ -0,0 +1,223 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2021 BOTLabs GmbH + +// The KILT Blockchain is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The KILT Blockchain is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// If you feel like getting in touch with us, you can do so at info@botlabs.org + +use codec::{Decode, Encode}; +use sp_std::marker::PhantomData; + +use crate::*; + +mod v1; + +/// A trait that allows version migrators to access the underlying pallet's +/// context, e.g., its Config trait. +/// +/// In this way, the migrator can access the pallet's storage and the pallet's +/// types directly. +pub trait VersionMigratorTrait { + #[cfg(feature = "try-runtime")] + fn pre_migrate(&self) -> Result<(), &str>; + fn migrate(&self) -> Weight; + #[cfg(feature = "try-runtime")] + fn post_migrate(&self) -> Result<(), &str>; +} + +/// Storage version of the delegation pallet. +#[derive(Copy, Clone, Encode, Eq, Decode, Ord, PartialEq, PartialOrd)] +pub enum DelegationStorageVersion { + V1, + V2, +} + +#[cfg(feature = "try-runtime")] +impl DelegationStorageVersion { + /// The latest storage version. + fn latest() -> Self { + Self::V2 + } +} + +// All nodes will default to this, which is not bad, as in case the "real" +// version is a later one (i.e. the node has been started with already the +// latest version), the migration will simply do nothing as there's nothing in +// the old storage entries to migrate from. +// +// It might get updated in the future when we know that no node is running this +// old version anymore. +impl Default for DelegationStorageVersion { + fn default() -> Self { + Self::V1 + } +} + +impl VersionMigratorTrait for DelegationStorageVersion { + // It runs the right pre_migrate logic depending on the current storage version. + #[cfg(feature = "try-runtime")] + fn pre_migrate(&self) -> Result<(), &str> { + match *self { + Self::V1 => v1::pre_migrate::(), + Self::V2 => Err("Already latest v2 version."), + } + } + + // It runs the righ migration logic depending on the current storage version. + fn migrate(&self) -> Weight { + match *self { + Self::V1 => v1::migrate::(), + Self::V2 => 0u64, + } + } + + // It runs the right post_migrate logic depending on the current storage + // version. + #[cfg(feature = "try-runtime")] + fn post_migrate(&self) -> Result<(), &str> { + match *self { + Self::V1 => v1::post_migrate::(), + Self::V2 => Err("Migration from v2 should have never happened in the first place."), + } + } +} + +/// The delegation pallet's storage migrator, which handles all version +/// migrations in a sequential fashion. +/// +/// If a node has missed on more than one upgrade, the migrator will apply the +/// needed migrations one after the other. Otherwise, if no migration is needed, +/// the migrator will simply not do anything. +pub struct DelegationStorageMigrator(PhantomData); + +impl DelegationStorageMigrator { + // Contains the migration sequence logic. + fn get_next_storage_version(current: DelegationStorageVersion) -> Option { + // If the version current deployed is at least v1, there is no more migrations + // to run (other than the one from v1). + match current { + DelegationStorageVersion::V1 => None, + DelegationStorageVersion::V2 => None, + } + } + + /// Checks whether the latest storage version deployed is lower than the + /// latest possible. + #[cfg(feature = "try-runtime")] + pub(crate) fn pre_migrate() -> Result<(), &'static str> { + ensure!( + StorageVersion::::get() < DelegationStorageVersion::latest(), + "Already the latest storage version." + ); + + // Don't need to check for any other pre_migrate, as in try-runtime it is also + // called in the migrate() function. Same applies for post_migrate checks for + // each version migrator. + + Ok(()) + } + + /// Applies all the needed migrations from the currently deployed version to + /// the latest possible, one after the other. + /// + /// It returns the total weight consumed by ALL the migrations applied. + pub(crate) fn migrate() -> Weight { + let mut current_version: Option = Some(StorageVersion::::get()); + // Weight for StorageVersion::get(). + let mut total_weight = T::DbWeight::get().reads(1); + + while let Some(ver) = current_version { + // If any of the needed migrations pre-checks fail, the whole chain panics + // (during tests). + #[cfg(feature = "try-runtime")] + if let Err(err) = >::pre_migrate(&ver) { + panic!("{:?}", err); + } + let consumed_weight = >::migrate(&ver); + total_weight = total_weight.saturating_add(consumed_weight); + // If any of the needed migrations post-checks fail, the whole chain panics + // (during tests). + #[cfg(feature = "try-runtime")] + if let Err(err) = >::post_migrate(&ver) { + panic!("{:?}", err); + } + // If more migrations should be applied, current_version will not be None. + current_version = Self::get_next_storage_version(ver); + } + + total_weight + } + + /// Checks whether the storage version after all the needed migrations match + /// the latest one. + #[cfg(feature = "try-runtime")] + pub(crate) fn post_migrate() -> Result<(), &'static str> { + ensure!( + StorageVersion::::get() == DelegationStorageVersion::latest(), + "Not updated to the latest version." + ); + + Ok(()) + } +} + +// Tests for the entire storage migrator. +#[cfg(test)] +mod tests { + use super::*; + + use crate::mock::Test as TestRuntime; + + #[test] + fn ok_from_v1_migration() { + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::V1) + .build(None); + ext.execute_with(|| { + #[cfg(feature = "try-runtime")] + assert!( + DelegationStorageMigrator::::pre_migrate().is_ok(), + "Storage pre-migrate from v1 should not fail." + ); + + DelegationStorageMigrator::::migrate(); + + #[cfg(feature = "try-runtime")] + assert!( + DelegationStorageMigrator::::post_migrate().is_ok(), + "Storage post-migrate from v1 should not fail." + ); + }); + } + + #[test] + fn ok_from_default_migration() { + let mut ext = mock::ExtBuilder::default().build(None); + ext.execute_with(|| { + #[cfg(feature = "try-runtime")] + assert!( + DelegationStorageMigrator::::pre_migrate().is_ok(), + "Storage pre-migrate from default version should not fail." + ); + + DelegationStorageMigrator::::migrate(); + + #[cfg(feature = "try-runtime")] + assert!( + DelegationStorageMigrator::::post_migrate().is_ok(), + "Storage post-migrate from default version should not fail." + ); + }); + } +} diff --git a/pallets/delegation/src/migrations/v1.rs b/pallets/delegation/src/migrations/v1.rs new file mode 100644 index 0000000000..f69a115ec7 --- /dev/null +++ b/pallets/delegation/src/migrations/v1.rs @@ -0,0 +1,522 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2021 BOTLabs GmbH + +// The KILT Blockchain is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The KILT Blockchain is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// If you feel like getting in touch with us, you can do so at info@botlabs.org + +use crate::*; + +use frame_support::{IterableStorageMap, StorageMap, StoragePrefixedMap}; +use sp_runtime::traits::Zero; +use sp_std::collections::btree_map::BTreeMap; + +/// Checks whether the deployed storage version is v1. If not, it won't try +/// migrate any data. +/// +/// Since we have the default storage version to this one, it can happen +/// that new nodes will still try to perform runtime migrations. This is not +/// a problem as at the end of the day there will not be anything in the old +/// storage entries to migrate from. Hence, the "pseudo-"migration will +/// simply result in the update of the storage deployed version. +#[cfg(feature = "try-runtime")] +pub(crate) fn pre_migrate() -> Result<(), &'static str> { + ensure!( + StorageVersion::::get() == DelegationStorageVersion::V1, + "Current deployed version is not v1." + ); + + log::info!("Version storage migrating from v1 to v2"); + Ok(()) +} + +/// It migrates the old storage entries to the new ones. +/// +/// Specifically, for each entry in Roots, a new entry in +/// DelegationHierarchies + a new node in DelegationNodes is created. +/// Furthermore, nodes in Delegations are migrated to the new structure and +/// stored under DelegationNodes, with any children from the Children +/// storage entry added to the nodes under the children set. +pub(crate) fn migrate() -> Weight { + log::info!("v1 -> v2 delegation storage migrator started!"); + let mut total_weight = Weight::zero(); + + // Before being stored, the nodes are saved in a map so that after we go over + // all the nodes and the parent-child relationship in the storage, we can update + // the `parent` link of each node accordingly. Otherwise, we would need to save + // the node in the storage, and then retrieve it again to update the parent + // link. + let mut new_nodes: BTreeMap, DelegationNode> = BTreeMap::new(); + + // First iterate over the delegation roots and translate them to hierarchies. + total_weight = total_weight.saturating_add(migrate_roots::(&mut new_nodes)); + + // Then iterate over the regular delegation nodes. + total_weight = total_weight.saturating_add(migrate_nodes::(&mut new_nodes, total_weight)); + + // By now, all the children should have been correctly added to the nodes. + // We now need to modify all the nodes that are children by adding a reference + // to their parents. + total_weight = total_weight.saturating_add(finalize_children_nodes::(&mut new_nodes, total_weight)); + + StorageVersion::::set(DelegationStorageVersion::V2); + // Adds a write from StorageVersion::set() weight. + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + log::debug!("Total weight consumed: {}", total_weight); + log::info!("v1 -> v2 delegation storage migrator finished!"); + + total_weight +} + +fn migrate_roots(new_nodes: &mut BTreeMap, DelegationNode>) -> Weight { + let total_weight = deprecated::v1::storage::Roots::::iter().fold( + Weight::zero(), + |mut total_weight, (old_root_id, old_root_node)| { + let new_hierarchy_details = DelegationHierarchyDetails:: { + ctype_hash: old_root_node.ctype_hash, + }; + let new_root_details = DelegationDetails:: { + owner: old_root_node.owner, + // Old roots did not have any permissions. So now we give them all permissions. + permissions: Permissions::all(), + revoked: old_root_node.revoked, + }; + // In here, we already check for potential children of root nodes and ONLY + // update the children information. The parent information will be updated + // later, when we know we have seen all the children already. + let mut new_root_node = DelegationNode::new_root_node(old_root_id, new_root_details); + if let Some(root_children_ids) = deprecated::v1::storage::Children::::take(old_root_id) { + new_root_node.children = root_children_ids.iter().copied().collect(); + } + // Add Children::take() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + + DelegationHierarchies::insert(old_root_id, new_hierarchy_details); + // Adds a read from Roots::drain() and a write from + // DelegationHierarchies::insert() weights + total_weight = total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + // Add the node to the temporary map of nodes to be added at the end. + new_nodes.insert(old_root_id, new_root_node); + + total_weight + }, + ); + + // If runtime testing, makes sure that the old number of roots is reflected in + // the new number of nodes and hierarchies migrated. + #[cfg(feature = "try-runtime")] + { + assert_eq!( + deprecated::v1::storage::Roots::::iter().count(), + DelegationHierarchies::::iter().count(), + "The # of old roots does not match the # of new delegation hierarchies." + ); + + assert_eq!( + deprecated::v1::storage::Roots::::iter().count(), + new_nodes.iter().count(), + "The # of old roots does not match the current # of new delegation nodes." + ); + + log::info!( + "{} root(s) migrated.", + deprecated::v1::storage::Roots::::iter().count() + ); + } + + // Removes the whole Roots storage. + frame_support::migration::remove_storage_prefix( + deprecated::v1::storage::Roots::::module_prefix(), + deprecated::v1::storage::Roots::::storage_prefix(), + b"", + ); + + total_weight +} + +fn migrate_nodes( + new_nodes: &mut BTreeMap, DelegationNode>, + initial_weight: Weight, +) -> Weight { + let total_weight = deprecated::v1::storage::Delegations::::iter().fold( + initial_weight, + |mut total_weight, (old_node_id, old_node)| { + let new_node_details = DelegationDetails:: { + owner: old_node.owner, + permissions: old_node.permissions, + revoked: old_node.revoked, + }; + // In the old version, a parent None indicated the node is a child of the root. + let new_node_parent_id = old_node.parent.unwrap_or(old_node.root_id); + let mut new_node = DelegationNode::new_node(old_node.root_id, new_node_parent_id, new_node_details); + if let Some(children_ids) = deprecated::v1::storage::Children::::take(old_node_id) { + new_node.children = children_ids.iter().copied().collect(); + } + // Add Children::take() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + // Adds a read from Roots::drain() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + new_nodes.insert(old_node_id, new_node); + + total_weight + }, + ); + + // If runtime testing, makes sure that the old number of delegations is + // reflected in the new number of nodes that will be added to the storage. + #[cfg(feature = "try-runtime")] + { + assert_eq!( + deprecated::v1::storage::Delegations::::iter().count(), + new_nodes.iter().count().saturating_sub(DelegationHierarchies::::iter().count()), + "The # of old delegation nodes does not match the # of new delegation nodes (calculate as the total # of nodes - the # of delegation hierarchies)." + ); + + log::info!( + "{} regular node(s) migrated.", + deprecated::v1::storage::Delegations::::iter().count() + ); + } + + // Removes the whole Delegations and Children storages. + frame_support::migration::remove_storage_prefix( + deprecated::v1::storage::Delegations::::module_prefix(), + deprecated::v1::storage::Delegations::::storage_prefix(), + b"", + ); + frame_support::migration::remove_storage_prefix( + deprecated::v1::storage::Children::::module_prefix(), + deprecated::v1::storage::Children::::storage_prefix(), + b"", + ); + + total_weight +} + +fn finalize_children_nodes( + new_nodes: &mut BTreeMap, DelegationNode>, + initial_weight: Weight, +) -> Weight { + new_nodes + .clone() + .into_iter() + .fold(initial_weight, |mut total_weight, (new_node_id, new_node)| { + // Iterate over the children of every node and update their parent link. + new_node.children.iter().for_each(|child_id| { + new_nodes + .entry(*child_id) + .and_modify(|node| node.parent = Some(new_node_id)); + }); + // We can then finally insert the new delegation node in the storage as it won't + // be updated anymore during the migration. + DelegationNodes::::insert(new_node_id, new_node); + // Adds a write from DelegationNodes::insert() weight + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + + total_weight + }) +} + +/// Checks whether the deployed storage version is v2 and whether any +/// parent-child link has gone missing. +#[cfg(feature = "try-runtime")] +pub(crate) fn post_migrate() -> Result<(), &'static str> { + ensure!( + StorageVersion::::get() == DelegationStorageVersion::V2, + "The version after deployment is not 2 as expected." + ); + ensure!( + verify_parent_children_integrity::(), + "Some parent-child relationship has been broken in the migration." + ); + log::info!("Version storage migrated from v1 to v2"); + Ok(()) +} + +// Verifies that for any node that has a parent, the parent includes that node +// in its children. +#[cfg(feature = "try-runtime")] +fn verify_parent_children_integrity() -> bool { + // If all's good and false is returned, returns true. + !DelegationNodes::::iter().any(|(node_id, node)| { + if let Some(parent_id) = node.parent { + if let Some(parent_node) = DelegationNodes::::get(parent_id) { + // True if the children set does not contain the parent ID + return !parent_node.children.contains(&node_id); + } else { + // If the parent node cannot be found, it is definitely an error, so return + // true. + return true; + } + } + // If all's good we keep returning false. + false + }) +} + +// Tests for the v1 storage migrator. +#[cfg(test)] +mod tests { + use sp_core::Pair; + + use super::*; + use crate::mock::Test as TestRuntime; + + #[test] + fn fail_version_higher() { + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::V2) + .build(None); + ext.execute_with(|| { + #[cfg(feature = "try-runtime")] + assert!( + pre_migrate::().is_err(), + "Pre-migration for v1 should fail." + ); + }); + } + + #[test] + fn ok_no_delegations() { + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::V1) + .build(None); + ext.execute_with(|| { + #[cfg(feature = "try-runtime")] + assert!( + pre_migrate::().is_ok(), + "Pre-migration for v1 should not fail." + ); + + migrate::(); + + #[cfg(feature = "try-runtime")] + assert!( + post_migrate::().is_ok(), + "Post-migration for v1 should not fail." + ); + }); + } + + #[test] + fn ok_only_root() { + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::V1) + .build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = + crate::deprecated::v1::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice); + deprecated::v1::storage::Roots::insert(old_root_id, old_root_node.clone()); + + #[cfg(feature = "try-runtime")] + assert!( + pre_migrate::().is_ok(), + "Pre-migration for v1 should not fail." + ); + + migrate::(); + + #[cfg(feature = "try-runtime")] + assert!( + post_migrate::().is_ok(), + "Post-migration for v1 should not fail." + ); + + assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); + assert_eq!( + deprecated::v1::storage::Delegations::::iter_values().count(), + 0 + ); + assert_eq!( + deprecated::v1::storage::Children::::iter_values().count(), + 0 + ); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert!(new_stored_root.children.is_empty()); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + }); + } + + #[test] + fn ok_root_two_children() { + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::V1) + .build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = + deprecated::v1::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_node_id_1 = mock::get_delegation_id(false); + let old_node_1 = deprecated::v1::DelegationNode::::new_root_child( + old_root_id, + alice, + Permissions::DELEGATE, + ); + let old_node_id_2 = mock::get_delegation_id_2(true); + let old_node_2 = + deprecated::v1::DelegationNode::::new_root_child(old_root_id, bob, Permissions::ATTEST); + deprecated::v1::storage::Roots::insert(old_root_id, old_root_node.clone()); + deprecated::v1::storage::Delegations::insert(old_node_id_1, old_node_1.clone()); + deprecated::v1::storage::Delegations::insert(old_node_id_2, old_node_2.clone()); + deprecated::v1::storage::Children::::insert(old_root_id, vec![old_node_id_1, old_node_id_2]); + + #[cfg(feature = "try-runtime")] + assert!( + pre_migrate::().is_ok(), + "Pre-migration for v1 should not fail." + ); + + migrate::(); + + #[cfg(feature = "try-runtime")] + assert!( + post_migrate::().is_ok(), + "Post-migration for v1 should not fail." + ); + + assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); + assert_eq!( + deprecated::v1::storage::Delegations::::iter_values().count(), + 0 + ); + assert_eq!( + deprecated::v1::storage::Children::::iter_values().count(), + 0 + ); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert_eq!(new_stored_root.children.len(), 2); + assert!(new_stored_root.children.contains(&old_node_id_1)); + assert!(new_stored_root.children.contains(&old_node_id_2)); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + + let new_stored_node_1 = DelegationNodes::::get(old_node_id_1) + .expect("New delegation 1 should exist in the storage."); + assert_eq!(new_stored_node_1.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node_1.parent, Some(old_root_id)); + assert!(new_stored_node_1.children.is_empty()); + assert_eq!(new_stored_node_1.details.owner, old_node_1.owner); + assert_eq!(new_stored_node_1.details.revoked, old_node_1.revoked); + + let new_stored_node_2 = DelegationNodes::::get(old_node_id_2) + .expect("New delegation 2 should exist in the storage."); + assert_eq!(new_stored_node_2.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node_2.parent, Some(old_root_id)); + assert!(new_stored_node_2.children.is_empty()); + assert_eq!(new_stored_node_2.details.owner, old_node_2.owner); + assert_eq!(new_stored_node_2.details.revoked, old_node_2.revoked); + }); + } + + #[test] + fn ok_three_level_hierarchy() { + let mut ext = mock::ExtBuilder::default() + .with_storage_version(DelegationStorageVersion::V1) + .build(None); + ext.execute_with(|| { + let alice = mock::get_ed25519_account(mock::get_alice_ed25519().public()); + let bob = mock::get_sr25519_account(mock::get_bob_sr25519().public()); + let old_root_id = mock::get_delegation_id(true); + let old_root_node = + deprecated::v1::DelegationRoot::::new(ctype::mock::get_ctype_hash(true), alice.clone()); + let old_parent_id = mock::get_delegation_id(false); + let old_parent_node = + deprecated::v1::DelegationNode::::new_root_child(old_root_id, alice, Permissions::all()); + let old_node_id = mock::get_delegation_id_2(true); + let old_node = deprecated::v1::DelegationNode::::new_node_child( + old_root_id, + old_parent_id, + bob, + Permissions::ATTEST, + ); + deprecated::v1::storage::Roots::insert(old_root_id, old_root_node.clone()); + deprecated::v1::storage::Delegations::insert(old_parent_id, old_parent_node.clone()); + deprecated::v1::storage::Delegations::insert(old_node_id, old_node.clone()); + deprecated::v1::storage::Children::::insert(old_root_id, vec![old_parent_id]); + deprecated::v1::storage::Children::::insert(old_parent_id, vec![old_node_id]); + + #[cfg(feature = "try-runtime")] + assert!( + pre_migrate::().is_ok(), + "Pre-migration for v1 should not fail." + ); + + migrate::(); + + #[cfg(feature = "try-runtime")] + assert!( + post_migrate::().is_ok(), + "Post-migration for v1 should not fail." + ); + + assert_eq!(deprecated::v1::storage::Roots::::iter_values().count(), 0); + assert_eq!( + deprecated::v1::storage::Delegations::::iter_values().count(), + 0 + ); + assert_eq!( + deprecated::v1::storage::Children::::iter_values().count(), + 0 + ); + + let new_stored_hierarchy = DelegationHierarchies::::get(old_root_id) + .expect("New delegation hierarchy should exist in the storage."); + assert_eq!(new_stored_hierarchy.ctype_hash, old_root_node.ctype_hash); + let new_stored_root = DelegationNodes::::get(old_root_id) + .expect("New delegation root should exist in the storage."); + assert_eq!(new_stored_root.hierarchy_root_id, old_root_id); + assert!(new_stored_root.parent.is_none()); + assert_eq!(new_stored_root.children.len(), 1); + assert!(new_stored_root.children.contains(&old_parent_id)); + assert_eq!(new_stored_root.details.owner, old_root_node.owner); + assert_eq!(new_stored_root.details.revoked, old_root_node.revoked); + + let new_stored_parent = DelegationNodes::::get(old_parent_id) + .expect("New delegation parent should exist in the storage."); + assert_eq!(new_stored_parent.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_parent.parent, Some(old_root_id)); + assert_eq!(new_stored_parent.children.len(), 1); + assert!(new_stored_parent.children.contains(&old_node_id)); + assert_eq!(new_stored_parent.details.owner, old_parent_node.owner); + assert_eq!(new_stored_parent.details.revoked, old_parent_node.revoked); + + let new_stored_node = DelegationNodes::::get(old_node_id) + .expect("New delegation node should exist in the storage."); + assert_eq!(new_stored_node.hierarchy_root_id, old_root_id); + assert_eq!(new_stored_node.parent, Some(old_parent_id)); + assert!(new_stored_node.children.is_empty()); + assert_eq!(new_stored_node.details.owner, old_node.owner); + assert_eq!(new_stored_node.details.revoked, old_node.revoked); + }); + } +} From 234571c5a3b07df7b3fa0fbcb09dae82bd70fbcb Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 21 Jul 2021 10:30:29 +0200 Subject: [PATCH 43/49] chore: move migrations.rs out of the migrations folder --- pallets/delegation/src/{migrations/mod.rs => migrations.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pallets/delegation/src/{migrations/mod.rs => migrations.rs} (100%) diff --git a/pallets/delegation/src/migrations/mod.rs b/pallets/delegation/src/migrations.rs similarity index 100% rename from pallets/delegation/src/migrations/mod.rs rename to pallets/delegation/src/migrations.rs From 1e6b4361d5c22400c2424cf02e5c1d8f48221d41 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 21 Jul 2021 13:34:51 +0200 Subject: [PATCH 44/49] fix: add check for parent revocation status when creating a delegation --- pallets/delegation/src/lib.rs | 9 ++- pallets/delegation/src/tests.rs | 107 ++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 7d50ff5b07..6a8ef37879 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -178,6 +178,8 @@ pub mod pallet { NotOwnerOfDelegationHierarchy, /// No parent delegation with the given ID stored on chain. ParentDelegationNotFound, + /// The parent delegation has previously been revoked. + ParentDelegationRevoked, /// The delegation revoker is not allowed to revoke the delegation. UnauthorizedRevocation, /// The delegation creator is not allowed to create the delegation. @@ -286,7 +288,12 @@ pub mod pallet { parent_node.details.owner == delegator, Error::::NotOwnerOfParentDelegation ); - // ... and has permission to delegate + // ... and that the node has not been revoked... + ensure!( + !parent_node.details.revoked, + Error::::ParentDelegationRevoked + ); + // ... and that has permission to delegate ensure!( (parent_node.details.permissions & Permissions::DELEGATE) == Permissions::DELEGATE, Error::::UnauthorizedDelegation diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index bef6794b0c..620545e703 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -247,6 +247,113 @@ fn create_delegation_with_parent_successful() { assert!(stored_parent.children.contains(&operation.delegation_id)); } +#[test] +fn create_delegation_direct_root_revoked_error() { + let creator_keypair = get_alice_ed25519(); + let creator = get_ed25519_account(creator_keypair.public()); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); + + let (hierarchy_root_id, hierarchy_details) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_details(), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(hierarchy_root_id)), + ); + + let delegation_info = Delegation::calculate_delegation_creation_hash( + &delegation_id, + &hierarchy_root_id, + &hierarchy_root_id, + &delegation_node.details.permissions, + ); + + let delegate_signature = delegate_keypair.sign(&hash_to_u8(delegation_info)); + + let operation = + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); + + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_details.ctype_hash, creator.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, creator.clone())]) + .build(Some(ext)); + + ext.execute_with(|| { + let _ = Delegation::revoke_hierarchy(get_origin(creator.clone()), operation.hierarchy_id, MaxRevocations::get()); + assert_noop!( + Delegation::add_delegation( + get_origin(creator.clone()), + operation.delegation_id, + operation.parent_id, + delegate, + operation.permissions, + operation.delegate_signature.clone().encode(), + ), + delegation::Error::::ParentDelegationRevoked + ); + }); +} + +#[test] +fn create_delegation_with_parent_revoked_error() { + let creator_keypair = get_alice_ed25519(); + let creator = get_ed25519_account(creator_keypair.public()); + let delegate_keypair = get_bob_sr25519(); + let delegate = get_sr25519_account(delegate_keypair.public()); + + let (hierarchy_root_id, hierarchy_details) = ( + get_delegation_hierarchy_id(true), + generate_base_delegation_hierarchy_details(), + ); + let (parent_id, parent_node) = ( + get_delegation_id(true), + generate_base_delegation_node(hierarchy_root_id, creator.clone(), Some(hierarchy_root_id)), + ); + let (delegation_id, delegation_node) = ( + get_delegation_id(false), + generate_base_delegation_node(hierarchy_root_id, delegate.clone(), Some(parent_id)), + ); + + let delegation_info = Delegation::calculate_delegation_creation_hash( + &delegation_id, + &hierarchy_root_id, + &parent_id, + &delegation_node.details.permissions, + ); + + let delegate_signature = delegate_keypair.sign(&hash_to_u8(delegation_info)); + + let operation = + generate_base_delegation_creation_operation(delegation_id, delegate_signature.into(), delegation_node); + + let ext = ctype_mock::ExtBuilder::default() + .with_ctypes(vec![(hierarchy_details.ctype_hash, creator.clone())]) + .build(None); + let mut ext = ExtBuilder::default() + .with_delegation_hierarchies(vec![(hierarchy_root_id, hierarchy_details, creator.clone())]) + .with_delegations(vec![(parent_id, parent_node)]) + .build(Some(ext)); + + ext.execute_with(|| { + let _ = Delegation::revoke_delegation(get_origin(creator.clone()), operation.parent_id, MaxRevocations::get(), MaxParentChecks::get()); + assert_noop!( + Delegation::add_delegation( + get_origin(creator.clone()), + operation.delegation_id, + operation.parent_id, + delegate, + operation.permissions, + operation.delegate_signature.clone().encode(), + ), + delegation::Error::::ParentDelegationRevoked + ); + }); +} + #[test] fn invalid_delegate_signature_create_delegation_error() { let creator_keypair = get_alice_ed25519(); From 364c7a8602e1b968e3d30ec2039e3fae80fa0679 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 21 Jul 2021 13:35:52 +0200 Subject: [PATCH 45/49] chore: fmt --- pallets/delegation/src/lib.rs | 5 +---- pallets/delegation/src/tests.rs | 13 +++++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 6a8ef37879..30929e18fd 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -289,10 +289,7 @@ pub mod pallet { Error::::NotOwnerOfParentDelegation ); // ... and that the node has not been revoked... - ensure!( - !parent_node.details.revoked, - Error::::ParentDelegationRevoked - ); + ensure!(!parent_node.details.revoked, Error::::ParentDelegationRevoked); // ... and that has permission to delegate ensure!( (parent_node.details.permissions & Permissions::DELEGATE) == Permissions::DELEGATE, diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index 620545e703..5ef4534b40 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -283,7 +283,11 @@ fn create_delegation_direct_root_revoked_error() { .build(Some(ext)); ext.execute_with(|| { - let _ = Delegation::revoke_hierarchy(get_origin(creator.clone()), operation.hierarchy_id, MaxRevocations::get()); + let _ = Delegation::revoke_hierarchy( + get_origin(creator.clone()), + operation.hierarchy_id, + MaxRevocations::get(), + ); assert_noop!( Delegation::add_delegation( get_origin(creator.clone()), @@ -339,7 +343,12 @@ fn create_delegation_with_parent_revoked_error() { .build(Some(ext)); ext.execute_with(|| { - let _ = Delegation::revoke_delegation(get_origin(creator.clone()), operation.parent_id, MaxRevocations::get(), MaxParentChecks::get()); + let _ = Delegation::revoke_delegation( + get_origin(creator.clone()), + operation.parent_id, + MaxRevocations::get(), + MaxParentChecks::get(), + ); assert_noop!( Delegation::add_delegation( get_origin(creator.clone()), From 11bcc2d8cda5c55dce3f38e43d5f25392b886286 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 21 Jul 2021 14:26:40 +0200 Subject: [PATCH 46/49] feat: remove revoke_hierarchy extrinsic --- pallets/delegation/src/benchmarking.rs | 18 ---- pallets/delegation/src/lib.rs | 98 +++++--------------- pallets/delegation/src/tests.rs | 30 +++--- runtimes/peregrine/src/weights/delegation.rs | 2 +- 4 files changed, 41 insertions(+), 107 deletions(-) diff --git a/pallets/delegation/src/benchmarking.rs b/pallets/delegation/src/benchmarking.rs index c0acdfe21e..62a00badd6 100644 --- a/pallets/delegation/src/benchmarking.rs +++ b/pallets/delegation/src/benchmarking.rs @@ -192,24 +192,6 @@ benchmarks! { assert!(DelegationHierarchies::::contains_key(delegation)); } - revoke_hierarchy { - let r in 1 .. T::MaxRevocations::get(); - let (root_acc, hierarchy_id, leaf_acc, leaf_id) = setup_delegations::(r, ONE_CHILD_PER_LEVEL.expect(">0"), Permissions::DELEGATE)?; - let root_acc_id: T::AccountId = root_acc.into(); - }: _(RawOrigin::Signed(root_acc_id.clone()), hierarchy_id, r) - verify { - assert!(DelegationHierarchies::::contains_key(hierarchy_id)); - let root_delegation = DelegationNodes::::get(hierarchy_id).ok_or("Missing root delegation")?; - assert_eq!(root_delegation.details.owner, root_acc_id.into()); - assert!(root_delegation.details.revoked); - - assert!(DelegationNodes::::contains_key(leaf_id)); - let leaf_delegation = DelegationNodes::::get(leaf_id).ok_or("Missing leaf delegation")?; - assert_eq!(leaf_delegation.hierarchy_root_id, hierarchy_id); - assert_eq!(leaf_delegation.details.owner, T::AccountId::from(leaf_acc).into()); - assert!(leaf_delegation.details.revoked); - } - add_delegation { // do setup let (_, hierarchy_id, leaf_acc, leaf_id) = setup_delegations::(1, ONE_CHILD_PER_LEVEL.expect(">0"), Permissions::DELEGATE)?; diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 30929e18fd..46ae05b034 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -323,59 +323,8 @@ pub mod pallet { Ok(()) } - /// Revoke a delegation hierarchy starting from its root node. - /// - /// Revoking a delegation root results in the whole trust hierarchy - /// being revoked. Nevertheless, revocation starts from the leave nodes - /// upwards, so if the operation ends prematurely because it runs out of - /// gas, the delegation state would be consisent as no child would - /// "survive" its parent. As a consequence, if the root node is revoked, - /// the whole trust hierarchy is to be considered revoked. - /// - /// * origin: the identifier of the revoker - /// * root_node_id: the ID of the delegation root node to revoke - /// * max_children: the maximum number of nodes descending from the root - /// to revoke as a consequence of the root revocation - #[pallet::weight(::WeightInfo::revoke_hierarchy(*max_children))] - pub fn revoke_hierarchy( - origin: OriginFor, - root_node_id: DelegationNodeIdOf, - max_children: u32, - ) -> DispatchResultWithPostInfo { - let invoker = ::EnsureOrigin::ensure_origin(origin)?; - - let hierarchy_root_node = >::get(&root_node_id).ok_or(Error::::HierarchyNotFound)?; - - ensure!( - hierarchy_root_node.details.owner == invoker, - Error::::UnauthorizedRevocation - ); - - ensure!( - max_children <= T::MaxRevocations::get(), - Error::::MaxRevocationsTooLarge - ); - - let consumed_weight: Weight = if !hierarchy_root_node.details.revoked { - // Recursively revoke all children - let (_, post_weight) = Self::revoke_children(&root_node_id, &invoker, max_children)?; - - // If we didn't return an ExceededRevocationBounds error, we can revoke the root - // too. - Self::revoke_and_store_hierarchy_root(root_node_id, hierarchy_root_node); - // We don't cancel the delegation_hierarchy from storage. - - post_weight.saturating_add(T::DbWeight::get().writes(1)) - } else { - 0 - }; - - Self::deposit_event(Event::HierarchyRevoked(invoker, root_node_id)); - - Ok(Some(consumed_weight.saturating_add(T::DbWeight::get().reads(1))).into()) - } - - /// Revoke a delegation node and all its children. + /// Revoke a delegation node (potentially a root node) and all its + /// children. /// /// Revoking a delegation node results in the trust hierarchy starting /// from the given node being revoked. Nevertheless, revocation starts @@ -393,8 +342,8 @@ pub mod pallet { /// evaluation terminates when a valid node is reached, when the whole /// hierarchy including the root node has been checked, or when the /// max number of parents is reached - /// * max_revocations: the maximum number of nodes descending from this - /// one to revoke as a consequence of this node revocation + /// * max_revocations: the maximum number of children nodes of this one + /// to revoke as a consequence of this node revocation #[pallet::weight( ::WeightInfo::revoke_delegation_root_child(*max_revocations, *max_parent_checks) .max(::WeightInfo::revoke_delegation_leaf(*max_revocations, *max_parent_checks)))] @@ -416,16 +365,22 @@ pub mod pallet { Error::::MaxParentChecksTooLarge ); - let (authorized, parent_checks) = Self::is_delegating(&invoker, &delegation_id, max_parent_checks)?; - ensure!(authorized, Error::::UnauthorizedRevocation); - ensure!( max_revocations <= T::MaxRevocations::get(), Error::::MaxRevocationsTooLarge ); - // Revoke the delegation and recursively all of its children - let (revocation_checks, _) = Self::revoke(&delegation_id, &invoker, max_revocations)?; + let (authorized, parent_checks) = Self::is_delegating(&invoker, &delegation_id, max_parent_checks)?; + ensure!(authorized, Error::::UnauthorizedRevocation); + + // Revoke the delegation and recursively all of its children (add 1 to + // max_revocations to account for the node itself) + let (revocation_checks, _) = Self::revoke(&delegation_id, &invoker, max_revocations.saturating_add(1))?; + + // If the revoked node is a root node, emit also a HierarchyRevoked event. + if DelegationHierarchies::::contains_key(&delegation_id) { + Self::deposit_event(Event::HierarchyRevoked(invoker, delegation_id)); + } // Add worst case reads from `is_delegating` Ok(Some( @@ -484,13 +439,6 @@ impl Pallet { >::insert(parent_id, parent_node); } - // Marks the provided hierarchy as revoked and stores the resulting state back - // in the storage. - fn revoke_and_store_hierarchy_root(root_id: DelegationNodeIdOf, mut root_node: DelegationNode) { - root_node.details.revoked = true; - >::insert(root_id, root_node); - } - /// Check if an identity is the owner of the given delegation node or any /// node up the hierarchy, and if the delegation has not been yet revoked. /// @@ -509,18 +457,18 @@ impl Pallet { // delegation has not been removed if &delegation_node.details.owner == identity { Ok((!delegation_node.details.revoked, 0u32)) - } else { + } else if let Some(parent) = delegation_node.parent { + // Only decrease (and perhaps fail) remaining_lookups if there are more parents + // to visit let remaining_lookups = max_parent_checks .checked_sub(1) .ok_or(Error::::MaxSearchDepthReached)?; - if let Some(parent) = delegation_node.parent { - // Recursively check upwards in hierarchy - Self::is_delegating(identity, &parent, remaining_lookups) - } else { - // Safe because remaining lookups is at most max_parent_checks - Ok((false, max_parent_checks - remaining_lookups)) - } + // Recursively check upwards in hierarchy + Self::is_delegating(identity, &parent, remaining_lookups) + } else { + // Return false and return max_parent_checks as no other check is performed + Ok((false, max_parent_checks)) } } diff --git a/pallets/delegation/src/tests.rs b/pallets/delegation/src/tests.rs index 5ef4534b40..e0c974bd86 100644 --- a/pallets/delegation/src/tests.rs +++ b/pallets/delegation/src/tests.rs @@ -283,9 +283,10 @@ fn create_delegation_direct_root_revoked_error() { .build(Some(ext)); ext.execute_with(|| { - let _ = Delegation::revoke_hierarchy( + let _ = Delegation::revoke_delegation( get_origin(creator.clone()), operation.hierarchy_id, + 0u32, MaxRevocations::get(), ); assert_noop!( @@ -639,9 +640,10 @@ fn empty_revoke_root_successful() { .build(Some(ext)); ext.execute_with(|| { - assert_ok!(Delegation::revoke_hierarchy( + assert_ok!(Delegation::revoke_delegation( get_origin(revoker.clone()), operation.id, + 0u32, operation.max_children )); }); @@ -685,9 +687,10 @@ fn list_hierarchy_revoke_root_successful() { .build(Some(ext)); ext.execute_with(|| { - assert_ok!(Delegation::revoke_hierarchy( + assert_ok!(Delegation::revoke_delegation( get_origin(revoker.clone()), operation.id, + 0u32, operation.max_children )); }); @@ -742,9 +745,10 @@ fn tree_hierarchy_revoke_root_successful() { .build(Some(ext)); ext.execute_with(|| { - assert_ok!(Delegation::revoke_hierarchy( + assert_ok!(Delegation::revoke_delegation( get_origin(revoker.clone()), operation.id, + 0u32, operation.max_children )); }); @@ -797,9 +801,10 @@ fn max_max_revocations_revoke_successful() { .build(Some(ext)); ext.execute_with(|| { - assert_ok!(Delegation::revoke_hierarchy( + assert_ok!(Delegation::revoke_delegation( get_origin(revoker.clone()), operation.id, + 0u32, operation.max_children )); }); @@ -832,8 +837,8 @@ fn root_not_found_revoke_root_error() { ext.execute_with(|| { assert_noop!( - Delegation::revoke_hierarchy(get_origin(revoker.clone()), operation.id, operation.max_children), - delegation::Error::::HierarchyNotFound + Delegation::revoke_delegation(get_origin(revoker.clone()), operation.id, 0u32, operation.max_children), + delegation::Error::::DelegationNotFound ); }); } @@ -861,7 +866,7 @@ fn different_root_creator_revoke_root_error() { ext.execute_with(|| { assert_noop!( - Delegation::revoke_hierarchy(get_origin(revoker.clone()), operation.id, operation.max_children), + Delegation::revoke_delegation(get_origin(revoker.clone()), operation.id, 0u32, operation.max_children), delegation::Error::::UnauthorizedRevocation ); }); @@ -896,7 +901,7 @@ fn too_small_max_revocations_revoke_root_error() { ext.execute_with(|| { assert_noop!( - Delegation::revoke_hierarchy(get_origin(revoker.clone()), operation.id, operation.max_children), + Delegation::revoke_delegation(get_origin(revoker.clone()), operation.id, 0u32, operation.max_children), delegation::Error::::ExceededRevocationBounds ); }); @@ -945,7 +950,7 @@ fn exact_children_max_revocations_revoke_root_error() { // assert_err and not asser_noop becase the storage is indeed changed, even tho // partially assert_err!( - Delegation::revoke_hierarchy(get_origin(revoker.clone()), operation.id, operation.max_children), + Delegation::revoke_delegation(get_origin(revoker.clone()), operation.id, 0u32, operation.max_children), delegation::Error::::ExceededRevocationBounds ); }); @@ -1217,8 +1222,7 @@ fn too_many_revocations_revoke_delegation_error() { generate_base_delegation_node(hierarchy_root_id, delegate, Some(parent_id)), ); - let mut operation = generate_base_delegation_revocation_operation(delegation_id); - operation.max_parent_checks = 1u32; + let operation = generate_base_delegation_revocation_operation(parent_id); let ext = ctype_mock::ExtBuilder::default() .with_ctypes(vec![(hierarchy_details.ctype_hash, revoker.clone())]) @@ -1568,7 +1572,7 @@ fn is_delegating_root_owner_revoked() { ext.execute_with(|| { // First revoke the hierarchy, then test is_delegating. - let _ = Delegation::revoke_hierarchy(get_origin(user_1.clone()), hierarchy_root_id, 2); + let _ = Delegation::revoke_delegation(get_origin(user_1.clone()), hierarchy_root_id, 0u32, 2); assert_eq!( Delegation::is_delegating(&user_1, &delegation_id, max_parent_checks), Ok((false, 0u32)) diff --git a/runtimes/peregrine/src/weights/delegation.rs b/runtimes/peregrine/src/weights/delegation.rs index 5d3910682a..e97ac476f8 100644 --- a/runtimes/peregrine/src/weights/delegation.rs +++ b/runtimes/peregrine/src/weights/delegation.rs @@ -85,4 +85,4 @@ impl delegation::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c as Weight))) .saturating_add(T::DbWeight::get().writes(1_u64)) } -} \ No newline at end of file +} From cf550eb58673e4f98590897e218d62e8bc33ebec Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 21 Jul 2021 14:38:20 +0200 Subject: [PATCH 47/49] bench: add peregrine benchmarks --- pallets/delegation/src/default_weights.rs | 19 --------- runtimes/peregrine/src/weights/attestation.rs | 10 ++--- runtimes/peregrine/src/weights/delegation.rs | 40 ++++++++----------- 3 files changed, 22 insertions(+), 47 deletions(-) diff --git a/pallets/delegation/src/default_weights.rs b/pallets/delegation/src/default_weights.rs index 502cce902c..bb3b177a10 100644 --- a/pallets/delegation/src/default_weights.rs +++ b/pallets/delegation/src/default_weights.rs @@ -49,7 +49,6 @@ use sp_std::marker::PhantomData; /// Weight functions needed for delegation. pub trait WeightInfo { fn create_hierarchy() -> Weight; - fn revoke_hierarchy(r: u32, ) -> Weight; fn add_delegation() -> Weight; fn revoke_delegation_root_child(r: u32, c: u32, ) -> Weight; fn revoke_delegation_leaf(r: u32, c: u32, ) -> Weight; @@ -63,15 +62,6 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - fn revoke_hierarchy(r: u32, ) -> Weight { - (25_605_000_u64) - // Standard Error: 58_000 - .saturating_add((17_141_000_u64).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes(1_u64)) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r as Weight))) - } fn add_delegation() -> Weight { (80_662_000_u64) .saturating_add(T::DbWeight::get().reads(2_u64)) @@ -103,15 +93,6 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - fn revoke_hierarchy(r: u32, ) -> Weight { - (25_605_000_u64) - // Standard Error: 58_000 - .saturating_add((17_141_000_u64).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r as Weight))) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r as Weight))) - } fn add_delegation() -> Weight { (80_662_000_u64) .saturating_add(RocksDbWeight::get().reads(2_u64)) diff --git a/runtimes/peregrine/src/weights/attestation.rs b/runtimes/peregrine/src/weights/attestation.rs index 4f61f7928e..ca84370d96 100644 --- a/runtimes/peregrine/src/weights/attestation.rs +++ b/runtimes/peregrine/src/weights/attestation.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for attestation //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-07-19, STEPS: `[1, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-07-21, STEPS: `[1, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -50,14 +50,14 @@ use sp_std::marker::PhantomData; pub struct WeightInfo(PhantomData); impl attestation::WeightInfo for WeightInfo { fn add() -> Weight { - (73_618_000_u64) + (68_138_000_u64) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } fn revoke(d: u32, ) -> Weight { - (43_775_000_u64) - // Standard Error: 42_000 - .saturating_add((8_458_000_u64).saturating_mul(d as Weight)) + (46_806_000_u64) + // Standard Error: 134_000 + .saturating_add((8_122_000_u64).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(d as Weight))) .saturating_add(T::DbWeight::get().writes(1_u64)) diff --git a/runtimes/peregrine/src/weights/delegation.rs b/runtimes/peregrine/src/weights/delegation.rs index e97ac476f8..f77437b42c 100644 --- a/runtimes/peregrine/src/weights/delegation.rs +++ b/runtimes/peregrine/src/weights/delegation.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for delegation //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-07-19, STEPS: `[1, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-07-21, STEPS: `[1, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -50,39 +50,33 @@ use sp_std::marker::PhantomData; pub struct WeightInfo(PhantomData); impl delegation::WeightInfo for WeightInfo { fn create_hierarchy() -> Weight { - (44_864_000_u64) + (48_641_000_u64) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - fn revoke_hierarchy(r: u32, ) -> Weight { - (43_886_000_u64) - // Standard Error: 558_000 - .saturating_add((30_900_000_u64).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes(1_u64)) - .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r as Weight))) - } fn add_delegation() -> Weight { - (132_759_000_u64) + (130_555_000_u64) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - fn revoke_delegation_root_child(r: u32, _c: u32, ) -> Weight { - (21_840_000_u64) - // Standard Error: 386_000 - .saturating_add((30_669_000_u64).saturating_mul(r as Weight)) + fn revoke_delegation_root_child(r: u32, c: u32, ) -> Weight { + (24_607_000_u64) + // Standard Error: 425_000 + .saturating_add((30_915_000_u64).saturating_mul(r as Weight)) + // Standard Error: 425_000 + .saturating_add((860_000_u64).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r as Weight))) } fn revoke_delegation_leaf(r: u32, c: u32, ) -> Weight { - (52_078_000_u64) - // Standard Error: 193_000 - .saturating_add((228_000_u64).saturating_mul(r as Weight)) - // Standard Error: 193_000 - .saturating_add((7_997_000_u64).saturating_mul(c as Weight)) - .saturating_add(T::DbWeight::get().reads(1_u64)) + (58_402_000_u64) + // Standard Error: 307_000 + .saturating_add((57_000_u64).saturating_mul(r as Weight)) + // Standard Error: 307_000 + .saturating_add((8_464_000_u64).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c as Weight))) .saturating_add(T::DbWeight::get().writes(1_u64)) } -} +} \ No newline at end of file From 05fac683c9a32c5fb98e91f032415793cdd1dbae Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 21 Jul 2021 14:35:16 +0200 Subject: [PATCH 48/49] bench: re-run delegation and attestation default benchmarks --- pallets/attestation/src/default_weights.rs | 18 +++---- pallets/delegation/src/default_weights.rs | 56 +++++++++++----------- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/pallets/attestation/src/default_weights.rs b/pallets/attestation/src/default_weights.rs index b00f97cf95..271f0e2371 100644 --- a/pallets/attestation/src/default_weights.rs +++ b/pallets/attestation/src/default_weights.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for attestation //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-07-13, STEPS: {{cmd.steps}}\, REPEAT: {{cmd.repeat}}\, LOW RANGE: {{cmd.lowest_range_values}}\, HIGH RANGE: {{cmd.highest_range_values}}\ +//! DATE: 2021-07-21, STEPS: {{cmd.steps}}\, REPEAT: {{cmd.repeat}}\, LOW RANGE: {{cmd.lowest_range_values}}\, HIGH RANGE: {{cmd.highest_range_values}}\ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -56,14 +56,14 @@ pub trait WeightInfo { pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { fn add() -> Weight { - (39_554_000_u64) + (38_091_000_u64) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } fn revoke(d: u32, ) -> Weight { - (25_295_000_u64) - // Standard Error: 50_000 - .saturating_add((5_239_000_u64).saturating_mul(d as Weight)) + (25_042_000_u64) + // Standard Error: 28_000 + .saturating_add((4_866_000_u64).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(d as Weight))) .saturating_add(T::DbWeight::get().writes(1_u64)) @@ -73,14 +73,14 @@ impl WeightInfo for SubstrateWeight { // For backwards compatibility and tests impl WeightInfo for () { fn add() -> Weight { - (39_554_000_u64) + (38_091_000_u64) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } fn revoke(d: u32, ) -> Weight { - (25_295_000_u64) - // Standard Error: 50_000 - .saturating_add((5_239_000_u64).saturating_mul(d as Weight)) + (25_042_000_u64) + // Standard Error: 28_000 + .saturating_add((4_866_000_u64).saturating_mul(d as Weight)) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(d as Weight))) .saturating_add(RocksDbWeight::get().writes(1_u64)) diff --git a/pallets/delegation/src/default_weights.rs b/pallets/delegation/src/default_weights.rs index bb3b177a10..6bee212825 100644 --- a/pallets/delegation/src/default_weights.rs +++ b/pallets/delegation/src/default_weights.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for delegation //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-07-13, STEPS: {{cmd.steps}}\, REPEAT: {{cmd.repeat}}\, LOW RANGE: {{cmd.lowest_range_values}}\, HIGH RANGE: {{cmd.highest_range_values}}\ +//! DATE: 2021-07-21, STEPS: {{cmd.steps}}\, REPEAT: {{cmd.repeat}}\, LOW RANGE: {{cmd.lowest_range_values}}\, HIGH RANGE: {{cmd.highest_range_values}}\ //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -58,29 +58,30 @@ pub trait WeightInfo { pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { fn create_hierarchy() -> Weight { - (25_218_000_u64) + (24_797_000_u64) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } fn add_delegation() -> Weight { - (80_662_000_u64) + (80_841_000_u64) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - fn revoke_delegation_root_child(r: u32, c: u32, ) -> Weight { - (11_077_000_u64) - // Standard Error: 35_000 - .saturating_add((17_545_000_u64).saturating_mul(r as Weight)) - // Standard Error: 35_000 - .saturating_add((82_000_u64).saturating_mul(c as Weight)) + fn revoke_delegation_root_child(r: u32, _c: u32, ) -> Weight { + (17_804_000_u64) + // Standard Error: 94_000 + .saturating_add((17_445_000_u64).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r as Weight))) } - fn revoke_delegation_leaf(_r: u32, c: u32, ) -> Weight { - (30_265_000_u64) - // Standard Error: 41_000 - .saturating_add((5_076_000_u64).saturating_mul(c as Weight)) - .saturating_add(T::DbWeight::get().reads(1_u64)) + fn revoke_delegation_leaf(r: u32, c: u32, ) -> Weight { + (31_213_000_u64) + // Standard Error: 61_000 + .saturating_add((327_000_u64).saturating_mul(r as Weight)) + // Standard Error: 61_000 + .saturating_add((5_210_000_u64).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c as Weight))) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -89,29 +90,30 @@ impl WeightInfo for SubstrateWeight { // For backwards compatibility and tests impl WeightInfo for () { fn create_hierarchy() -> Weight { - (25_218_000_u64) + (24_797_000_u64) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } fn add_delegation() -> Weight { - (80_662_000_u64) + (80_841_000_u64) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - fn revoke_delegation_root_child(r: u32, c: u32, ) -> Weight { - (11_077_000_u64) - // Standard Error: 35_000 - .saturating_add((17_545_000_u64).saturating_mul(r as Weight)) - // Standard Error: 35_000 - .saturating_add((82_000_u64).saturating_mul(c as Weight)) + fn revoke_delegation_root_child(r: u32, _c: u32, ) -> Weight { + (17_804_000_u64) + // Standard Error: 94_000 + .saturating_add((17_445_000_u64).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r as Weight))) } - fn revoke_delegation_leaf(_r: u32, c: u32, ) -> Weight { - (30_265_000_u64) - // Standard Error: 41_000 - .saturating_add((5_076_000_u64).saturating_mul(c as Weight)) - .saturating_add(RocksDbWeight::get().reads(1_u64)) + fn revoke_delegation_leaf(r: u32, c: u32, ) -> Weight { + (31_213_000_u64) + // Standard Error: 61_000 + .saturating_add((327_000_u64).saturating_mul(r as Weight)) + // Standard Error: 61_000 + .saturating_add((5_210_000_u64).saturating_mul(c as Weight)) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(c as Weight))) .saturating_add(RocksDbWeight::get().writes(1_u64)) } From 879e194de56300f4b9031cd8f76cc53fc513e8de Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 27 Jul 2021 09:00:10 +0200 Subject: [PATCH 49/49] chore: fmt --- pallets/ctype/src/lib.rs | 4 ++-- pallets/delegation/src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/ctype/src/lib.rs b/pallets/ctype/src/lib.rs index 249ad20ae5..285579adb0 100644 --- a/pallets/ctype/src/lib.rs +++ b/pallets/ctype/src/lib.rs @@ -115,8 +115,8 @@ pub mod pallet { #[pallet::call] impl Pallet { - /// Create a new CType from the given unique CType hash and associates it - /// with its creator. + /// Create a new CType from the given unique CType hash and associates + /// it with its creator. /// /// A CType with the same hash must not be stored on chain. /// diff --git a/pallets/delegation/src/lib.rs b/pallets/delegation/src/lib.rs index 0ca3fcb838..ce3229ac82 100644 --- a/pallets/delegation/src/lib.rs +++ b/pallets/delegation/src/lib.rs @@ -585,7 +585,7 @@ impl Pallet { } } Ok((revocations, consumed_weight.saturating_add(T::DbWeight::get().reads(1)))) - } + } /// Revoke a delegation and all of its children recursively. ///