From 85869ea02c5462c5d62db4fae43aec5010f90229 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 23 Feb 2024 08:20:09 +0100 Subject: [PATCH 01/39] pallet-dip-consumer unit tests complete --- Cargo.lock | 2 + pallets/pallet-dip-consumer/Cargo.toml | 2 + pallets/pallet-dip-consumer/src/lib.rs | 5 +- pallets/pallet-dip-consumer/src/mock.rs | 103 +++++++++++++++--- .../src/tests/dispatch_as.rs | 85 +++++++++++++++ pallets/pallet-dip-consumer/src/tests/mod.rs | 19 ++++ support/src/traits.rs | 7 ++ 7 files changed, 209 insertions(+), 14 deletions(-) create mode 100644 pallets/pallet-dip-consumer/src/tests/dispatch_as.rs create mode 100644 pallets/pallet-dip-consumer/src/tests/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 951e714cba..b093264889 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6581,6 +6581,8 @@ dependencies = [ "frame-support", "frame-system", "kilt-support", + "pallet-balances", + "pallet-did-lookup", "parity-scale-codec", "scale-info", "sp-io", diff --git a/pallets/pallet-dip-consumer/Cargo.toml b/pallets/pallet-dip-consumer/Cargo.toml index edfd082d6f..752bb04067 100644 --- a/pallets/pallet-dip-consumer/Cargo.toml +++ b/pallets/pallet-dip-consumer/Cargo.toml @@ -14,6 +14,8 @@ version.workspace = true targets = ["x86_64-unknown-linux-gnu"] [dev-dependencies] +pallet-balances = {workspace = true, features = ["std"]} +pallet-did-lookup = {workspace = true, features = ["std"]} sp-io = {workspace = true, features = ["std"]} sp-keystore = {workspace = true, features = ["std"]} sp-runtime = {workspace = true, features = ["std"]} diff --git a/pallets/pallet-dip-consumer/src/lib.rs b/pallets/pallet-dip-consumer/src/lib.rs index bc633025bb..5122e0b7ff 100644 --- a/pallets/pallet-dip-consumer/src/lib.rs +++ b/pallets/pallet-dip-consumer/src/lib.rs @@ -24,7 +24,10 @@ pub mod traits; mod default_weights; #[cfg(test)] -pub mod mock; +mod mock; + +#[cfg(test)] +mod tests; #[cfg(feature = "runtime-benchmarks")] pub mod benchmarking; diff --git a/pallets/pallet-dip-consumer/src/mock.rs b/pallets/pallet-dip-consumer/src/mock.rs index 401dc2f239..6799780280 100644 --- a/pallets/pallet-dip-consumer/src/mock.rs +++ b/pallets/pallet-dip-consumer/src/mock.rs @@ -23,21 +23,27 @@ use frame_support::{ traits::{BlakeTwo256, IdentityLookup}, AccountId32, }, - traits::{ConstU16, ConstU32, ConstU64, Contains, Everything}, + traits::{ConstU16, ConstU32, ConstU64, Contains, Currency, Everything}, }; use frame_system::{mocking::MockBlock, EnsureSigned}; -use crate::traits::SuccessfulProofVerifier; +use crate::{traits::IdentityProofVerifier, Config, DipOrigin, EnsureDipOrigin, RuntimeCallOf}; +// This mock is used both for benchmarks and unit tests. +// For benchmarks, the `system::remark` call must be allowed to be dispatched, +// while for the unit tests we use the `pallet_did_lookup` as an example pallet +// consuming the generated DIP origin. construct_runtime!( pub struct TestRuntime { System: frame_system, + Balances: pallet_balances, + DidLookup: pallet_did_lookup, DipConsumer: crate, } ); impl frame_system::Config for TestRuntime { - type AccountData = (); + type AccountData = pallet_balances::AccountData; type AccountId = AccountId32; type BaseCallFilter = Everything; type Block = MockBlock; @@ -62,36 +68,107 @@ impl frame_system::Config for TestRuntime { type Version = (); } -pub struct CallFilter; +impl pallet_balances::Config for TestRuntime { + type AccountStore = System; + type Balance = u64; + type DustRemoval = (); + type ExistentialDeposit = ConstU64<1>; + type FreezeIdentifier = [u8; 8]; + type MaxFreezes = ConstU32<10>; + type MaxHolds = ConstU32<10>; + type MaxLocks = ConstU32<10>; + type MaxReserves = ConstU32<10>; + type ReserveIdentifier = [u8; 8]; + type RuntimeEvent = RuntimeEvent; + type RuntimeHoldReason = RuntimeHoldReason; + type WeightInfo = (); +} -impl Contains for CallFilter { +impl pallet_did_lookup::Config for TestRuntime { + type BalanceMigrationManager = (); + type Currency = Balances; + type Deposit = ConstU64<1>; + type DidIdentifier = AccountId32; + type EnsureOrigin = EnsureDipOrigin; + type OriginSuccess = DipOrigin; + type RuntimeEvent = RuntimeEvent; + type RuntimeHoldReason = RuntimeHoldReason; + type WeightInfo = (); +} + +pub struct OnlySystemRemarksWithoutEventsAndDidLookupCalls; + +impl Contains for OnlySystemRemarksWithoutEventsAndDidLookupCalls { fn contains(t: &RuntimeCall) -> bool { - matches!(t, RuntimeCall::System { .. }) + matches!( + t, + // Required by the benchmarking logic + RuntimeCall::System(frame_system::Call::remark { .. }) | + // Used in these tests + RuntimeCall::DidLookup { .. } + ) + } +} + +pub struct BooleanProofVerifier; +impl IdentityProofVerifier for BooleanProofVerifier { + type Error = u16; + type Proof = bool; + type VerificationResult = (); + + fn verify_proof_for_call_against_details( + _call: &RuntimeCallOf, + _subject: &::Identifier, + _submitter: &::AccountId, + _identity_details: &mut Option<::LocalIdentityInfo>, + proof: Self::Proof, + ) -> Result { + if proof { + Ok(()) + } else { + Err(1) + } } } impl crate::Config for TestRuntime { type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; - type ProofVerifier = SuccessfulProofVerifier; + type ProofVerifier = BooleanProofVerifier; type LocalIdentityInfo = u128; type Identifier = AccountId32; type DispatchOriginCheck = EnsureSigned; - type DipCallOriginFilter = CallFilter; + type DipCallOriginFilter = OnlySystemRemarksWithoutEventsAndDidLookupCalls; type WeightInfo = (); } +pub(crate) const SUBMITTER: AccountId32 = AccountId32::new([100u8; 32]); +pub(crate) const SUBJECT: AccountId32 = AccountId32::new([200u8; 32]); + #[derive(Default)] -pub(crate) struct ExtBuilder; +pub(crate) struct ExtBuilder(Vec<(AccountId32, u64)>); impl ExtBuilder { - pub fn _build(self) -> sp_io::TestExternalities { - sp_io::TestExternalities::default() + pub(crate) fn with_balances(mut self, balances: Vec<(AccountId32, u64)>) -> Self { + self.0 = balances; + self + } + + pub(crate) fn build(self) -> sp_io::TestExternalities { + let mut ext = sp_io::TestExternalities::default(); + + ext.execute_with(|| { + for (account_id, balance) in self.0 { + Balances::make_free_balance_be(&account_id, balance); + } + }); + + ext } #[cfg(feature = "runtime-benchmarks")] - pub fn build_with_keystore(self) -> sp_io::TestExternalities { - let mut ext = self._build(); + pub(crate) fn build_with_keystore(self) -> sp_io::TestExternalities { + let mut ext = self.build(); let keystore = sp_keystore::testing::MemoryKeystore::new(); ext.register_extension(sp_keystore::KeystoreExt(sp_std::sync::Arc::new(keystore))); ext diff --git a/pallets/pallet-dip-consumer/src/tests/dispatch_as.rs b/pallets/pallet-dip-consumer/src/tests/dispatch_as.rs new file mode 100644 index 0000000000..84d6861b86 --- /dev/null +++ b/pallets/pallet-dip-consumer/src/tests/dispatch_as.rs @@ -0,0 +1,85 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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 frame_support::{assert_noop, assert_ok}; +use frame_system::RawOrigin; + +use crate::{ + mock::{ExtBuilder, System, TestRuntime, SUBJECT, SUBMITTER}, + Error, Pallet, +}; + +#[test] +fn dispatch_as_successful() { + ExtBuilder::default() + .with_balances(vec![(SUBMITTER, 10_000)]) + .build() + .execute_with(|| { + // Needed to test event generation. See for more context. + frame_system::Pallet::::set_block_number(1); + assert_ok!(Pallet::::dispatch_as( + RawOrigin::Signed(SUBMITTER).into(), + SUBJECT, + true, + Box::new(pallet_did_lookup::Call::associate_sender {}.into()) + )); + System::assert_last_event( + pallet_did_lookup::Event::::AssociationEstablished(SUBMITTER.into(), SUBJECT).into(), + ); + }); +} + +#[test] +fn dispatch_as_filtered() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + Pallet::::dispatch_as( + RawOrigin::Signed(SUBMITTER).into(), + SUBJECT, + true, + Box::new( + frame_system::Call::remark_with_event { + remark: b"Hello!".to_vec(), + } + .into(), + ), + ), + Error::::Filtered + ); + }); +} + +#[test] +fn dispatch_as_invalid_proof() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + Pallet::::dispatch_as( + RawOrigin::Signed(SUBMITTER).into(), + SUBJECT, + false, + Box::new( + frame_system::Call::remark { + remark: b"Hello!".to_vec(), + } + .into(), + ), + ), + Error::::InvalidProof(1) + ); + }); +} diff --git a/pallets/pallet-dip-consumer/src/tests/mod.rs b/pallets/pallet-dip-consumer/src/tests/mod.rs new file mode 100644 index 0000000000..93b84f7b9a --- /dev/null +++ b/pallets/pallet-dip-consumer/src/tests/mod.rs @@ -0,0 +1,19 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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 + +mod dispatch_as; diff --git a/support/src/traits.rs b/support/src/traits.rs index 52a0c5e114..5b6cf4a226 100644 --- a/support/src/traits.rs +++ b/support/src/traits.rs @@ -97,6 +97,13 @@ impl GetWorstCase for () { fn worst_case(_context: T) -> Self {} } +#[cfg(feature = "runtime-benchmarks")] +impl GetWorstCase for bool { + fn worst_case(_context: T) -> Self { + true + } +} + /// Trait that allows instanciating multiple instances of a type. #[cfg(feature = "runtime-benchmarks")] pub trait Instanciate { From 96939f9ad5b6c6f7a0a9645a100a1274f303ddd1 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 23 Feb 2024 10:02:13 +0100 Subject: [PATCH 02/39] pallet-relay-store unit tests complete --- Cargo.lock | 1 + pallets/pallet-relay-store/Cargo.toml | 6 +- pallets/pallet-relay-store/src/lib.rs | 16 +++- pallets/pallet-relay-store/src/mock.rs | 51 +++++++++-- pallets/pallet-relay-store/src/tests/mod.rs | 19 ++++ .../src/tests/on_finalize.rs | 86 +++++++++++++++++++ 6 files changed, 168 insertions(+), 11 deletions(-) create mode 100644 pallets/pallet-relay-store/src/tests/mod.rs create mode 100644 pallets/pallet-relay-store/src/tests/on_finalize.rs diff --git a/Cargo.lock b/Cargo.lock index b093264889..96b6738688 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7093,6 +7093,7 @@ dependencies = [ "sp-keystore", "sp-runtime", "sp-std", + "sp-trie", ] [[package]] diff --git a/pallets/pallet-relay-store/Cargo.toml b/pallets/pallet-relay-store/Cargo.toml index 724b327558..3efed88124 100644 --- a/pallets/pallet-relay-store/Cargo.toml +++ b/pallets/pallet-relay-store/Cargo.toml @@ -18,6 +18,7 @@ cumulus-primitives-core = { workspace = true, features = ["std"] } sp-io = {workspace = true, features = ["std"]} sp-keystore = {workspace = true, features = ["std"]} sp-runtime = {workspace = true, features = ["std"]} +sp-trie = {workspace = true, features = ["std"]} [dependencies] cumulus-pallet-parachain-system.workspace = true @@ -53,4 +54,7 @@ runtime-benchmarks = [ "frame-benchmarking", "sp-runtime/runtime-benchmarks", ] -try-runtime = [] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", +] diff --git a/pallets/pallet-relay-store/src/lib.rs b/pallets/pallet-relay-store/src/lib.rs index 27ad314cf4..8ff46be4d5 100644 --- a/pallets/pallet-relay-store/src/lib.rs +++ b/pallets/pallet-relay-store/src/lib.rs @@ -32,12 +32,16 @@ mod benchmarking; #[cfg(test)] mod mock; +#[cfg(test)] +mod tests; + pub use crate::{default_weights::WeightInfo, pallet::*}; #[frame_support::pallet] pub mod pallet { use super::*; + use cumulus_primitives_core::PersistedValidationData; use frame_support::{pallet_prelude::*, BoundedVec}; use frame_system::pallet_prelude::*; use sp_core::H256; @@ -97,6 +101,10 @@ pub mod pallet { let Some(new_validation_data) = cumulus_pallet_parachain_system::Pallet::::validation_data() else { return; }; + Self::store_new_validation_data(new_validation_data) + } + + pub(crate) fn store_new_validation_data(validation_data: PersistedValidationData) { let mut latest_block_heights = LatestBlockHeights::::get(); // Remove old relay block from both storage entries. if latest_block_heights.is_full() { @@ -108,11 +116,11 @@ pub mod pallet { ); } // Set the new relay block in storage. - let relay_block_height = new_validation_data.relay_parent_number; + let relay_block_height = validation_data.relay_parent_number; log::trace!( "Adding new relay block with state root {:#02x?} and number {:?}", - new_validation_data.relay_parent_storage_root, - new_validation_data.relay_parent_number, + validation_data.relay_parent_storage_root, + validation_data.relay_parent_number, ); let push_res = latest_block_heights.try_push(relay_block_height); if let Err(err) = push_res { @@ -125,7 +133,7 @@ pub mod pallet { LatestRelayHeads::::insert( relay_block_height, RelayParentInfo { - relay_parent_storage_root: new_validation_data.relay_parent_storage_root, + relay_parent_storage_root: validation_data.relay_parent_storage_root, }, ); } diff --git a/pallets/pallet-relay-store/src/mock.rs b/pallets/pallet-relay-store/src/mock.rs index 13a53b6263..8ee0e87c70 100644 --- a/pallets/pallet-relay-store/src/mock.rs +++ b/pallets/pallet-relay-store/src/mock.rs @@ -17,7 +17,7 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org use cumulus_pallet_parachain_system::{ParachainSetCode, RelayNumberStrictlyIncreases}; -use cumulus_primitives_core::ParaId; +use cumulus_primitives_core::{ParaId, PersistedValidationData}; use frame_support::{ construct_runtime, parameter_types, sp_runtime::{ @@ -25,9 +25,13 @@ use frame_support::{ traits::{BlakeTwo256, IdentityLookup}, AccountId32, }, + storage_alias, traits::{ConstU16, ConstU32, ConstU64, Everything}, }; use frame_system::mocking::MockBlock; +use sp_runtime::BoundedVec; + +use crate::{Config, Pallet}; construct_runtime!( pub struct TestRuntime { @@ -84,17 +88,52 @@ impl crate::Config for TestRuntime { type WeightInfo = (); } +// Alias to the ParachainSystem storage which cannot be modified directly. +#[storage_alias] +type ValidationData = StorageValue; + #[derive(Default)] -pub(crate) struct ExtBuilder; +pub(crate) struct ExtBuilder( + Option<(u32, H256)>, + BoundedVec<(u32, H256), ::MaxRelayBlocksStored>, +); impl ExtBuilder { - pub fn _build(self) -> sp_io::TestExternalities { - sp_io::TestExternalities::default() + pub(crate) fn with_new_relay_state_root(mut self, relay_root: (u32, H256)) -> Self { + self.0 = Some(relay_root); + self + } + + pub(crate) fn with_stored_relay_roots(mut self, relay_roots: Vec<(u32, H256)>) -> Self { + self.1 = relay_roots.try_into().unwrap(); + self + } + + pub(crate) fn build(self) -> sp_io::TestExternalities { + let mut ext = sp_io::TestExternalities::default(); + ext.execute_with(|| { + if let Some(new_relay_state_root) = self.0 { + ValidationData::put(PersistedValidationData { + relay_parent_number: new_relay_state_root.0, + relay_parent_storage_root: new_relay_state_root.1, + ..Default::default() + }); + } + for (stored_relay_block_number, stored_relay_state_root) in self.1 { + Pallet::::store_new_validation_data(PersistedValidationData { + relay_parent_number: stored_relay_block_number, + relay_parent_storage_root: stored_relay_state_root, + ..Default::default() + }); + } + }); + + ext } #[cfg(feature = "runtime-benchmarks")] - pub fn build_with_keystore(self) -> sp_io::TestExternalities { - let mut ext = self._build(); + pub(crate) fn build_with_keystore(self) -> sp_io::TestExternalities { + let mut ext = self.build(); let keystore = sp_keystore::testing::MemoryKeystore::new(); ext.register_extension(sp_keystore::KeystoreExt(sp_std::sync::Arc::new(keystore))); ext diff --git a/pallets/pallet-relay-store/src/tests/mod.rs b/pallets/pallet-relay-store/src/tests/mod.rs new file mode 100644 index 0000000000..aff45dd1d3 --- /dev/null +++ b/pallets/pallet-relay-store/src/tests/mod.rs @@ -0,0 +1,19 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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 + +mod on_finalize; diff --git a/pallets/pallet-relay-store/src/tests/on_finalize.rs b/pallets/pallet-relay-store/src/tests/on_finalize.rs new file mode 100644 index 0000000000..560124660f --- /dev/null +++ b/pallets/pallet-relay-store/src/tests/on_finalize.rs @@ -0,0 +1,86 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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 frame_support::traits::Hooks; +use sp_runtime::traits::Zero; + +use crate::{ + mock::{ExtBuilder, System, TestRuntime}, + relay::RelayParentInfo, + LatestBlockHeights, LatestRelayHeads, Pallet, +}; + +#[test] +fn on_finalize_empty_state() { + ExtBuilder::default() + .with_new_relay_state_root((1, [100; 32].into())) + .build() + .execute_with(|| { + assert!(LatestRelayHeads::::iter().count().is_zero()); + assert!(LatestBlockHeights::::get().is_empty()); + + Pallet::::on_finalize(System::block_number()); + + assert_eq!( + LatestRelayHeads::::iter().collect::>(), + vec![( + 1, + RelayParentInfo { + relay_parent_storage_root: [100; 32].into() + } + )] + ); + assert_eq!(LatestBlockHeights::::get(), vec![1]); + }); +} + +// This should never happen, but we add a test to make sure the code in here +// never panics. +#[test] +fn on_finalize_empty_validation_data() { + ExtBuilder::default().build().execute_with(|| { + Pallet::::on_finalize(System::block_number()); + assert!(LatestRelayHeads::::iter().count().is_zero()); + assert!(LatestBlockHeights::::get().is_empty()); + }); +} + +#[test] +fn on_finalize_full_state() { + ExtBuilder::default() + .with_stored_relay_roots(vec![ + (1, [1; 32].into()), + (2, [2; 32].into()), + (3, [3; 32].into()), + (4, [4; 32].into()), + (5, [5; 32].into()), + ]) + .with_new_relay_state_root((6, [6; 32].into())) + .build() + .execute_with(|| { + Pallet::::on_finalize(System::block_number()); + assert!(LatestRelayHeads::::get(1).is_none(),); + assert_eq!( + LatestRelayHeads::::get(6), + Some(RelayParentInfo { + relay_parent_storage_root: [6; 32].into() + }) + ); + assert_eq!(LatestBlockHeights::::get(), vec![2, 3, 4, 5, 6]); + }); +} From 4063a805105d9fb31597b7ba84adcad47bffd23d Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 26 Feb 2024 06:44:24 +0100 Subject: [PATCH 03/39] Fix build error for pallet-relay-store --- pallets/pallet-relay-store/Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pallets/pallet-relay-store/Cargo.toml b/pallets/pallet-relay-store/Cargo.toml index 3efed88124..f9ac62b733 100644 --- a/pallets/pallet-relay-store/Cargo.toml +++ b/pallets/pallet-relay-store/Cargo.toml @@ -14,7 +14,6 @@ version.workspace = true targets = ["x86_64-unknown-linux-gnu"] [dev-dependencies] -cumulus-primitives-core = { workspace = true, features = ["std"] } sp-io = {workspace = true, features = ["std"]} sp-keystore = {workspace = true, features = ["std"]} sp-runtime = {workspace = true, features = ["std"]} @@ -22,6 +21,7 @@ sp-trie = {workspace = true, features = ["std"]} [dependencies] cumulus-pallet-parachain-system.workspace = true +cumulus-primitives-core.workspace = true frame-support.workspace = true frame-system.workspace = true log.workspace = true @@ -38,6 +38,7 @@ sp-runtime = {workspace = true, optional = true} default = ["std"] std = [ "cumulus-pallet-parachain-system/std", + "cumulus-primitives-core/std", "frame-support/std", "frame-system/std", "parity-scale-codec/std", From d34c2ce96accef1067de29248de22ba70b2cc142 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 26 Feb 2024 08:12:36 +0100 Subject: [PATCH 04/39] unit tests for error u8 and u16 values --- Cargo.lock | 21 +++++ Cargo.toml | 1 + crates/kilt-dip-primitives/Cargo.toml | 1 + .../src/merkle/v0/error.rs | 89 +++++++++++++++++++ .../src/merkle/{v0.rs => v0/mod.rs} | 49 ++-------- .../src/state_proofs/error.rs | 65 ++++++++++++++ .../src/state_proofs/mod.rs | 23 +---- .../src/verifier/parachain/error.rs | 80 +++++++++++++++++ .../{parachain.rs => parachain/mod.rs} | 36 +------- .../src/verifier/relaychain/error.rs | 80 +++++++++++++++++ .../{relaychain.rs => relaychain/mod.rs} | 36 +------- 11 files changed, 352 insertions(+), 129 deletions(-) create mode 100644 crates/kilt-dip-primitives/src/merkle/v0/error.rs rename crates/kilt-dip-primitives/src/merkle/{v0.rs => v0/mod.rs} (96%) create mode 100644 crates/kilt-dip-primitives/src/state_proofs/error.rs create mode 100644 crates/kilt-dip-primitives/src/verifier/parachain/error.rs rename crates/kilt-dip-primitives/src/verifier/{parachain.rs => parachain/mod.rs} (93%) create mode 100644 crates/kilt-dip-primitives/src/verifier/relaychain/error.rs rename crates/kilt-dip-primitives/src/verifier/{relaychain.rs => relaychain/mod.rs} (92%) diff --git a/Cargo.lock b/Cargo.lock index 96b6738688..1c294e0911 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2899,6 +2899,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "enum-iterator" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "600536cfe9e2da0820aa498e570f6b2b9223eec3ce2f835c8ae4861304fa4794" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03cdc46ec28bd728e67540c528013c6a10eb69a02eb31078a1bda695438cbfb8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "enumflags2" version = "0.7.8" @@ -4604,6 +4624,7 @@ dependencies = [ "cfg-if", "cumulus-primitives-core", "did", + "enum-iterator", "frame-support", "frame-system", "hash-db", diff --git a/Cargo.toml b/Cargo.toml index 8762fded57..031c51ab9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ base58 = {version = "0.2.0", default-features = false} bitflags = {version = "1.3.2", default-features = false} cfg-if = "1.0" clap = "4.1.6" +enum-iterator = "2.0.0" env_logger = "0.10.0" fluent-uri = { version = "0.1.4", default-features = false } futures = {version = "0.3.21", default-features = false} diff --git a/crates/kilt-dip-primitives/Cargo.toml b/crates/kilt-dip-primitives/Cargo.toml index 2b7f4adce1..e9d005fec0 100644 --- a/crates/kilt-dip-primitives/Cargo.toml +++ b/crates/kilt-dip-primitives/Cargo.toml @@ -43,6 +43,7 @@ sp-trie.workspace = true cumulus-primitives-core.workspace = true [dev-dependencies] +enum-iterator.workspace = true hex-literal.workspace = true sp-io = { workspace = true, features = ["std"] } diff --git a/crates/kilt-dip-primitives/src/merkle/v0/error.rs b/crates/kilt-dip-primitives/src/merkle/v0/error.rs new file mode 100644 index 0000000000..c7e120c3b6 --- /dev/null +++ b/crates/kilt-dip-primitives/src/merkle/v0/error.rs @@ -0,0 +1,89 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2023 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 scale_info::TypeInfo; + +use crate::state_proofs::MerkleProofError; + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, TypeInfo)] +#[cfg_attr(test, derive(enum_iterator::Sequence))] +pub enum Error { + InvalidRelayHeader, + RelayBlockNotFound, + RelayStateRootNotFound, + InvalidDidMerkleProof, + TooManyLeavesRevealed, + InvalidSignatureTime, + InvalidDidKeyRevealed, + ParaHeadMerkleProof(MerkleProofError), + DipCommitmentMerkleProof(MerkleProofError), + Internal, +} + +impl From for u8 { + fn from(value: Error) -> Self { + match value { + // DO NOT USE 0 + // Errors of different sub-parts are separated by a `u8::MAX`. + // A value of 0 would make it confusing whether it's the previous sub-part error (u8::MAX) + // or the new sub-part error (u8::MAX + 0). + Error::InvalidRelayHeader => 1, + Error::RelayBlockNotFound => 2, + Error::RelayStateRootNotFound => 3, + Error::InvalidDidMerkleProof => 4, + Error::TooManyLeavesRevealed => 5, + Error::InvalidSignatureTime => 6, + Error::InvalidDidKeyRevealed => 7, + Error::ParaHeadMerkleProof(error) => match error { + MerkleProofError::InvalidProof => 11, + MerkleProofError::RequiredLeafNotRevealed => 12, + MerkleProofError::ResultDecoding => 13, + }, + Error::DipCommitmentMerkleProof(error) => match error { + MerkleProofError::InvalidProof => 21, + MerkleProofError::RequiredLeafNotRevealed => 22, + MerkleProofError::ResultDecoding => 23, + }, + Error::Internal => u8::MAX, + } + } +} + +#[test] +fn error_value_never_zero() { + assert!( + enum_iterator::all::().all(|e| u8::from(e) != 0), + "One of the u8 values for the error is 0, which is not allowed." + ); +} + +#[test] +fn error_value_not_duplicated() { + enum_iterator::all::().fold( + sp_std::collections::btree_set::BTreeSet::::new(), + |mut values, new_value| { + let new_encoded_value = u8::from(new_value); + assert!( + values.insert(new_encoded_value), + "Failed to add unique value {:#?} for error variant", + new_encoded_value + ); + values + }, + ); +} diff --git a/crates/kilt-dip-primitives/src/merkle/v0.rs b/crates/kilt-dip-primitives/src/merkle/v0/mod.rs similarity index 96% rename from crates/kilt-dip-primitives/src/merkle/v0.rs rename to crates/kilt-dip-primitives/src/merkle/v0/mod.rs index a5719e4c84..00b89e62cc 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/mod.rs @@ -17,6 +17,7 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org //! Module to deal with cross-chain Merkle proof as generated by the KILT chain. + use did::{ did_details::{DidPublicKey, DidPublicKeyDetails}, DidSignature, DidVerificationKeyRelationship, @@ -35,7 +36,7 @@ use sp_std::{fmt::Debug, vec::Vec}; use sp_trie::{verify_trie_proof, LayoutV1}; use crate::{ - state_proofs::{verify_storage_value_proof, verify_storage_value_proof_with_decoder, MerkleProofError}, + state_proofs::{verify_storage_value_proof, verify_storage_value_proof_with_decoder}, traits::{BenchmarkDefault, GetWithArg}, utils::{ calculate_dip_identity_commitment_storage_key_for_runtime, calculate_parachain_head_storage_key, @@ -43,6 +44,9 @@ use crate::{ }, }; +mod error; +pub use error::*; + /// The state proof for a parachain head. /// /// The generic types indicate the following: @@ -188,49 +192,6 @@ where } } -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, TypeInfo)] -pub enum Error { - InvalidRelayHeader, - RelayBlockNotFound, - RelayStateRootNotFound, - InvalidDidMerkleProof, - TooManyLeavesRevealed, - InvalidSignatureTime, - InvalidDidKeyRevealed, - ParaHeadMerkleProof(MerkleProofError), - DipCommitmentMerkleProof(MerkleProofError), - Internal, -} - -impl From for u8 { - fn from(value: Error) -> Self { - match value { - // DO NOT USE 0 - // Errors of different sub-parts are separated by a `u8::MAX`. - // A value of 0 would make it confusing whether it's the previous sub-part error (u8::MAX) - // or the new sub-part error (u8::MAX + 0). - Error::InvalidRelayHeader => 1, - Error::RelayBlockNotFound => 2, - Error::RelayStateRootNotFound => 3, - Error::InvalidDidMerkleProof => 4, - Error::TooManyLeavesRevealed => 5, - Error::InvalidSignatureTime => 6, - Error::InvalidDidKeyRevealed => 7, - Error::ParaHeadMerkleProof(error) => match error { - MerkleProofError::InvalidProof => 11, - MerkleProofError::RequiredLeafNotRevealed => 12, - MerkleProofError::ResultDecoding => 13, - }, - Error::DipCommitmentMerkleProof(error) => match error { - MerkleProofError::InvalidProof => 21, - MerkleProofError::RequiredLeafNotRevealed => 22, - MerkleProofError::ResultDecoding => 23, - }, - Error::Internal => u8::MAX, - } - } -} - /// A DIP proof submitted to a relaychain consumer. /// /// The generic types indicate the following: diff --git a/crates/kilt-dip-primitives/src/state_proofs/error.rs b/crates/kilt-dip-primitives/src/state_proofs/error.rs new file mode 100644 index 0000000000..2332699351 --- /dev/null +++ b/crates/kilt-dip-primitives/src/state_proofs/error.rs @@ -0,0 +1,65 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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 scale_info::TypeInfo; + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, TypeInfo)] +#[cfg_attr(test, derive(enum_iterator::Sequence))] +pub enum MerkleProofError { + InvalidProof, + RequiredLeafNotRevealed, + ResultDecoding, +} + +impl From for u8 { + fn from(value: MerkleProofError) -> Self { + match value { + // DO NOT USE 0 + // Errors of different sub-parts are separated by a `u8::MAX`. + // A value of 0 would make it confusing whether it's the previous sub-part error (u8::MAX) + // or the new sub-part error (u8::MAX + 0). + MerkleProofError::InvalidProof => 1, + MerkleProofError::RequiredLeafNotRevealed => 2, + MerkleProofError::ResultDecoding => 3, + } + } +} + +#[test] +fn merkle_proof_error_value_never_zero() { + assert!( + enum_iterator::all::().all(|e| u8::from(e) != 0), + "One of the u8 values for the error is 0, which is not allowed." + ); +} + +#[test] +fn merkle_proof_error_value_not_duplicated() { + enum_iterator::all::().fold( + sp_std::collections::btree_set::BTreeSet::::new(), + |mut values, new_value| { + let new_encoded_value = u8::from(new_value); + assert!( + values.insert(new_encoded_value), + "Failed to add unique value {:#?} for error variant", + new_encoded_value + ); + values + }, + ); +} diff --git a/crates/kilt-dip-primitives/src/state_proofs/mod.rs b/crates/kilt-dip-primitives/src/state_proofs/mod.rs index 2f8eb4c531..e007bf92ab 100644 --- a/crates/kilt-dip-primitives/src/state_proofs/mod.rs +++ b/crates/kilt-dip-primitives/src/state_proofs/mod.rs @@ -17,7 +17,6 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org use parity_scale_codec::Decode; -use scale_info::TypeInfo; use sp_runtime::traits::Hash; use sp_std::vec::Vec; use sp_trie::StorageProof; @@ -30,26 +29,8 @@ use crate::{state_proofs::substrate_no_std_port::read_proof_check, utils::Output // kept up-to-date with upstream. mod substrate_no_std_port; -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, TypeInfo)] -pub enum MerkleProofError { - InvalidProof, - RequiredLeafNotRevealed, - ResultDecoding, -} - -impl From for u8 { - fn from(value: MerkleProofError) -> Self { - match value { - // DO NOT USE 0 - // Errors of different sub-parts are separated by a `u8::MAX`. - // A value of 0 would make it confusing whether it's the previous sub-part error (u8::MAX) - // or the new sub-part error (u8::MAX + 0). - MerkleProofError::InvalidProof => 1, - MerkleProofError::RequiredLeafNotRevealed => 2, - MerkleProofError::ResultDecoding => 3, - } - } -} +mod error; +pub use error::*; /// Verify a Merkle-based storage proof for a given storage key according to the /// provided state root. The generic types indicate the following: diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/error.rs b/crates/kilt-dip-primitives/src/verifier/parachain/error.rs new file mode 100644 index 0000000000..0eb1f0bcdc --- /dev/null +++ b/crates/kilt-dip-primitives/src/verifier/parachain/error.rs @@ -0,0 +1,80 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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::Error; + +#[cfg_attr(test, derive(enum_iterator::Sequence))] +pub enum DipParachainStateProofVerifierError { + UnsupportedVersion, + ProofComponentTooLarge(u8), + ProofVerification(Error), + DidOriginError(DidOriginError), + Internal, +} + +impl From> for u16 +where + DidOriginError: Into, +{ + fn from(value: DipParachainStateProofVerifierError) -> Self { + match value { + // DO NOT USE 0 + // Errors of different sub-parts are separated by a `u8::MAX`. + // A value of 0 would make it confusing whether it's the previous sub-part error (u8::MAX) + // or the new sub-part error (u8::MAX + 0). + DipParachainStateProofVerifierError::UnsupportedVersion => 1, + DipParachainStateProofVerifierError::ProofComponentTooLarge(component_id) => { + u8::MAX as u16 + component_id as u16 + } + DipParachainStateProofVerifierError::ProofVerification(error) => { + u8::MAX as u16 * 2 + u8::from(error) as u16 + } + DipParachainStateProofVerifierError::DidOriginError(error) => u8::MAX as u16 * 3 + error.into() as u16, + DipParachainStateProofVerifierError::Internal => u16::MAX, + } + } +} + +#[test] +fn dip_parachain_state_proof_verifier_error_value_never_zero() { + assert!( + enum_iterator::all::>().all(|e| u16::from(e) != 0), + "One of the u8 values for the error is 0, which is not allowed." + ); +} + +#[test] +fn dip_parachain_state_proof_verifier_error_value_not_duplicated() { + enum_iterator::all::>().fold( + sp_std::collections::btree_set::BTreeSet::::new(), + |mut values, new_value| { + let new_encoded_value = u16::from(new_value); + // DidOriginError is generic, and we cannot test its constraints in this unit + // test, so we skip it. + if new_encoded_value == u8::MAX as u16 * 3 { + return values; + } + assert!( + values.insert(new_encoded_value), + "Failed to add unique value {:#?} for error variant", + new_encoded_value + ); + values + }, + ); +} diff --git a/crates/kilt-dip-primitives/src/verifier/parachain.rs b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs similarity index 93% rename from crates/kilt-dip-primitives/src/verifier/parachain.rs rename to crates/kilt-dip-primitives/src/verifier/parachain/mod.rs index 817e4ad8f9..9274a2713a 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs @@ -30,9 +30,12 @@ use crate::{ merkle::v0::RevealedDidKey, traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, utils::OutputOf, - DipOriginInfo, Error, + DipOriginInfo, }; +mod error; +pub use error::*; + /// A KILT-specific DIP identity proof for a sibling consumer that supports /// versioning. /// @@ -94,37 +97,6 @@ impl< } } -pub enum DipParachainStateProofVerifierError { - UnsupportedVersion, - ProofComponentTooLarge(u8), - ProofVerification(Error), - DidOriginError(DidOriginError), - Internal, -} - -impl From> for u16 -where - DidOriginError: Into, -{ - fn from(value: DipParachainStateProofVerifierError) -> Self { - match value { - // DO NOT USE 0 - // Errors of different sub-parts are separated by a `u8::MAX`. - // A value of 0 would make it confusing whether it's the previous sub-part error (u8::MAX) - // or the new sub-part error (u8::MAX + 0). - DipParachainStateProofVerifierError::UnsupportedVersion => 1, - DipParachainStateProofVerifierError::ProofComponentTooLarge(component_id) => { - u8::MAX as u16 + component_id as u16 - } - DipParachainStateProofVerifierError::ProofVerification(error) => { - u8::MAX as u16 * 2 + u8::from(error) as u16 - } - DipParachainStateProofVerifierError::DidOriginError(error) => u8::MAX as u16 * 3 + error.into() as u16, - DipParachainStateProofVerifierError::Internal => u16::MAX, - } - } -} - /// Versioned proof verifier. For version-specific description, refer to each /// verifier's documentation. pub struct KiltVersionedParachainVerifier< diff --git a/crates/kilt-dip-primitives/src/verifier/relaychain/error.rs b/crates/kilt-dip-primitives/src/verifier/relaychain/error.rs new file mode 100644 index 0000000000..9bfd8e2a70 --- /dev/null +++ b/crates/kilt-dip-primitives/src/verifier/relaychain/error.rs @@ -0,0 +1,80 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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::Error; + +#[cfg_attr(test, derive(enum_iterator::Sequence))] +pub enum DipRelaychainStateProofVerifierError { + UnsupportedVersion, + ProofComponentTooLarge(u8), + ProofVerification(Error), + DidOriginError(DidOriginError), + Internal, +} + +impl From> for u16 +where + DidOriginError: Into, +{ + fn from(value: DipRelaychainStateProofVerifierError) -> Self { + match value { + // DO NOT USE 0 + // Errors of different sub-parts are separated by a `u8::MAX`. + // A value of 0 would make it confusing whether it's the previous sub-part error (u8::MAX) + // or the new sub-part error (u8::MAX + 0). + DipRelaychainStateProofVerifierError::UnsupportedVersion => 1, + DipRelaychainStateProofVerifierError::ProofComponentTooLarge(component_id) => { + u8::MAX as u16 + component_id as u16 + } + DipRelaychainStateProofVerifierError::ProofVerification(error) => { + u8::MAX as u16 * 2 + u8::from(error) as u16 + } + DipRelaychainStateProofVerifierError::DidOriginError(error) => u8::MAX as u16 * 3 + error.into() as u16, + DipRelaychainStateProofVerifierError::Internal => u16::MAX, + } + } +} + +#[test] +fn dip_relaychain_state_proof_verifier_error_value_never_zero() { + assert!( + enum_iterator::all::>().all(|e| u16::from(e) != 0), + "One of the u8 values for the error is 0, which is not allowed." + ); +} + +#[test] +fn dip_relaychain_state_proof_verifier_error_value_not_duplicated() { + enum_iterator::all::>().fold( + sp_std::collections::btree_set::BTreeSet::::new(), + |mut values, new_value| { + let new_encoded_value = u16::from(new_value); + // DidOriginError is generic, and we cannot test its constraints in this unit + // test, so we skip it. + if new_encoded_value == u8::MAX as u16 * 3 { + return values; + } + assert!( + values.insert(new_encoded_value), + "Failed to add unique value {:#?} for error variant", + new_encoded_value + ); + values + }, + ); +} diff --git a/crates/kilt-dip-primitives/src/verifier/relaychain.rs b/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs similarity index 92% rename from crates/kilt-dip-primitives/src/verifier/relaychain.rs rename to crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs index a97d2e7e1e..bf8cb83b68 100644 --- a/crates/kilt-dip-primitives/src/verifier/relaychain.rs +++ b/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs @@ -32,9 +32,12 @@ use crate::{ merkle::v0::RevealedDidKey, traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, utils::OutputOf, - DipOriginInfo, Error, + DipOriginInfo, }; +mod error; +pub use error::*; + /// A KILT-specific DIP identity proof for a parent consumer that supports /// versioning. /// @@ -62,37 +65,6 @@ pub enum VersionedRelaychainStateProof< ), } -pub enum DipRelaychainStateProofVerifierError { - UnsupportedVersion, - ProofComponentTooLarge(u8), - ProofVerification(Error), - DidOriginError(DidOriginError), - Internal, -} - -impl From> for u16 -where - DidOriginError: Into, -{ - fn from(value: DipRelaychainStateProofVerifierError) -> Self { - match value { - // DO NOT USE 0 - // Errors of different sub-parts are separated by a `u8::MAX`. - // A value of 0 would make it confusing whether it's the previous sub-part error (u8::MAX) - // or the new sub-part error (u8::MAX + 0). - DipRelaychainStateProofVerifierError::UnsupportedVersion => 1, - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(component_id) => { - u8::MAX as u16 + component_id as u16 - } - DipRelaychainStateProofVerifierError::ProofVerification(error) => { - u8::MAX as u16 * 2 + u8::from(error) as u16 - } - DipRelaychainStateProofVerifierError::DidOriginError(error) => u8::MAX as u16 * 3 + error.into() as u16, - DipRelaychainStateProofVerifierError::Internal => u16::MAX, - } - } -} - /// Versioned proof verifier. For version-specific description, refer to each /// verifier's documentation. pub struct KiltVersionedRelaychainVerifier< From 5dba83476eabe9c0041d9cc3d1aa7656c61c3b85 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 26 Feb 2024 08:27:40 +0100 Subject: [PATCH 05/39] split Verifier components --- .../src/state_proofs/mod.rs | 4 +- .../src/verifier/parachain/mod.rs | 235 +--------------- .../src/verifier/parachain/v0/mod.rs | 256 ++++++++++++++++++ .../src/verifier/relaychain/mod.rs | 223 +-------------- .../src/verifier/relaychain/v0/mod.rs | 239 ++++++++++++++++ 5 files changed, 503 insertions(+), 454 deletions(-) create mode 100644 crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs create mode 100644 crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs diff --git a/crates/kilt-dip-primitives/src/state_proofs/mod.rs b/crates/kilt-dip-primitives/src/state_proofs/mod.rs index e007bf92ab..b58a9213a5 100644 --- a/crates/kilt-dip-primitives/src/state_proofs/mod.rs +++ b/crates/kilt-dip-primitives/src/state_proofs/mod.rs @@ -108,7 +108,7 @@ mod test { use crate::state_proofs::verify_storage_value_proof; #[test] - fn spiritnet_system_event_count() { + fn verify_storage_value_proof_spiritnet_system_event_count() { // As of RPC state_getReadProof(" // 0x26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850", // "0x2c0746e7e9ccc6e4d27bcb4118cb6821ae53ae9bf372f4f49ac28d8598f9bed5") @@ -137,7 +137,7 @@ mod test { } #[test] - fn polkadot_parahead_proof_for_spiritnet() { + fn verify_storage_value_proof_polkadot_parahead_proof_for_spiritnet() { // As of RPC state_getReadProof("0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000", "0x18e90e9aa8e3b063f60386ba1b0415111798e72d01de58b1438d620d42f58e39") let spiritnet_head_storage_key = StorageKey( [ diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs index 9274a2713a..4ba160045f 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs @@ -17,7 +17,7 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org use did::KeyIdOf; -use frame_system::pallet_prelude::{BlockNumberFor, HeaderFor}; +use frame_system::pallet_prelude::BlockNumberFor; use pallet_did_lookup::linkable_account::LinkableAccountId; use pallet_dip_consumer::{traits::IdentityProofVerifier, RuntimeCallOf}; use pallet_dip_provider::traits::IdentityCommitmentGenerator; @@ -33,6 +33,8 @@ use crate::{ DipOriginInfo, }; +pub mod v0; + mod error; pub use error::*; @@ -225,234 +227,3 @@ impl< } } } - -pub mod v0 { - use super::*; - - use frame_support::ensure; - use sp_runtime::{traits::Zero, SaturatedConversion}; - - use crate::merkle::v0::ParachainDipDidProof; - - /// Proof verifier configured given a specific KILT runtime implementation. - /// - /// The generic types - /// indicate the following: - /// * `RelaychainRuntime`: The relaychain runtime definition. - /// * `RelaychainStateRootStore`: A type providing state roots for - /// relaychain blocks. - /// * `KILT_PARA_ID`: The ID of the specific KILT parachain instance. - /// * `KiltRuntime`: A KILT runtime definition. - /// * `DidCallVerifier`: Logic to map `RuntimeCall`s to a specific DID key - /// relationship. This information is used once the Merkle proof is - /// verified, to filter only the revealed keys that match the provided - /// relationship. - /// * `SignedExtra`: Any additional information that must be signed by the - /// DID subject in the cross-chain operation. - /// * `MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT`: The maximum number of leaves - /// that can be revealed as part of the parachain head storage proof. - /// * `MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE`: The maximum size of each leaf - /// revealed as part of the parachain head storage proof. - /// * `MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT`: The maximum number of leaves - /// that can be revealed as part of the DIP commitment storage proof. - /// * `MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE`: The maximum size of each leaf - /// revealed as part of the DIP commitment storage proof. - /// * `MAX_DID_MERKLE_PROOF_LEAVE_COUNT`: The maximum number of *blinded* - /// leaves that can be revealed as part of the DID Merkle proof. - /// * `MAX_DID_MERKLE_PROOF_LEAVE_SIZE`: The maximum size of each *blinded* - /// leaf revealed as part of the DID Merkle proof. - /// * `MAX_DID_MERKLE_LEAVES_REVEALED`: The maximum number of leaves that - /// can be revealed as part of the DID Merkle proof. - pub struct ParachainVerifier< - RelaychainRuntime, - RelaychainStateRootStore, - const KILT_PARA_ID: u32, - KiltRuntime, - DidCallVerifier, - SignedExtra, - const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32, - const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32, - const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32, - const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32, - const MAX_DID_MERKLE_LEAVES_REVEALED: u32, - >( - PhantomData<( - RelaychainRuntime, - RelaychainStateRootStore, - KiltRuntime, - DidCallVerifier, - SignedExtra, - )>, - ); - - impl< - ConsumerRuntime, - RelaychainRuntime, - RelaychainStateRootStore, - const KILT_PARA_ID: u32, - KiltRuntime, - DidCallVerifier, - SignedExtra, - const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32, - const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32, - const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32, - const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32, - const MAX_DID_MERKLE_LEAVES_REVEALED: u32, - > IdentityProofVerifier - for ParachainVerifier< - RelaychainRuntime, - RelaychainStateRootStore, - KILT_PARA_ID, - KiltRuntime, - DidCallVerifier, - SignedExtra, - MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, - MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, - MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT, - MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE, - MAX_DID_MERKLE_PROOF_LEAVE_COUNT, - MAX_DID_MERKLE_PROOF_LEAVE_SIZE, - MAX_DID_MERKLE_LEAVES_REVEALED, - > where - ConsumerRuntime: pallet_dip_consumer::Config, - ConsumerRuntime::LocalIdentityInfo: Incrementable + Default, - RelaychainRuntime: frame_system::Config, - RelaychainStateRootStore: - GetWithArg, Result = Option>>, - KiltRuntime: frame_system::Config - + pallet_dip_provider::Config - + did::Config - + pallet_web3_names::Config - + pallet_did_lookup::Config, - KiltRuntime::IdentityCommitmentGenerator: - IdentityCommitmentGenerator, - SignedExtra: GetWithoutArg, - SignedExtra::Result: Encode, - DidCallVerifier: DipCallOriginFilter< - RuntimeCallOf, - OriginInfo = RevealedDidKey, BlockNumberFor, KiltRuntime::AccountId>, - >, - DidCallVerifier::Error: Into, - { - type Error = DipParachainStateProofVerifierError; - type Proof = ParachainDipDidProof< - BlockNumberFor, - KeyIdOf, - KiltRuntime::AccountId, - BlockNumberFor, - Web3NameOf, - LinkableAccountId, - BlockNumberFor, - >; - - type VerificationResult = DipOriginInfo< - KeyIdOf, - KiltRuntime::AccountId, - BlockNumberFor, - Web3NameOf, - LinkableAccountId, - MAX_DID_MERKLE_LEAVES_REVEALED, - >; - - fn verify_proof_for_call_against_details( - call: &RuntimeCallOf, - subject: &::Identifier, - submitter: &::AccountId, - identity_details: &mut Option<::LocalIdentityInfo>, - proof: Self::Proof, - ) -> Result { - // 1. Verify parachain state is finalized by relay chain and fresh. - ensure!( - proof.provider_head_proof.proof.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT.saturated_into(), - DipParachainStateProofVerifierError::ProofComponentTooLarge(0) - ); - ensure!( - proof - .provider_head_proof - .proof - .iter() - .all(|l| l.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE.saturated_into()), - DipParachainStateProofVerifierError::ProofComponentTooLarge(1) - ); - let proof_without_relaychain = proof - .verify_provider_head_proof::>( - KILT_PARA_ID, - ) - .map_err(DipParachainStateProofVerifierError::ProofVerification)?; - - // 2. Verify commitment is included in provider parachain state. - ensure!( - proof_without_relaychain.dip_commitment_proof.0.len() - <= MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT.saturated_into(), - DipParachainStateProofVerifierError::ProofComponentTooLarge(2) - ); - ensure!( - proof_without_relaychain - .dip_commitment_proof - .0 - .iter() - .all(|l| l.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE.saturated_into()), - DipParachainStateProofVerifierError::ProofComponentTooLarge(3) - ); - let proof_without_parachain = proof_without_relaychain - .verify_dip_commitment_proof_for_subject::(subject) - .map_err(DipParachainStateProofVerifierError::ProofVerification)?; - - // 3. Verify DIP Merkle proof. - ensure!( - proof_without_parachain.dip_proof.blinded.len() <= MAX_DID_MERKLE_PROOF_LEAVE_COUNT.saturated_into(), - DipParachainStateProofVerifierError::ProofComponentTooLarge(4) - ); - ensure!( - proof_without_parachain - .dip_proof - .blinded - .iter() - .all(|l| l.len() <= MAX_DID_MERKLE_PROOF_LEAVE_SIZE.saturated_into()), - DipParachainStateProofVerifierError::ProofComponentTooLarge(5) - ); - let proof_without_dip_merkle = proof_without_parachain - .verify_dip_proof::() - .map_err(DipParachainStateProofVerifierError::ProofVerification)?; - - // 4. Verify call is signed by one of the DID keys revealed in the proof - let current_block_number = frame_system::Pallet::::block_number(); - let consumer_genesis_hash = - frame_system::Pallet::::block_hash(BlockNumberFor::::zero()); - let signed_extra = SignedExtra::get(); - let encoded_payload = ( - call, - &identity_details, - submitter, - proof_without_dip_merkle.signature.valid_until, - consumer_genesis_hash, - signed_extra, - ) - .encode(); - let revealed_did_info = proof_without_dip_merkle - .verify_signature_time(¤t_block_number) - .and_then(|p| p.retrieve_signing_leaf_for_payload(&encoded_payload[..])) - .map_err(DipParachainStateProofVerifierError::ProofVerification)?; - - // 5. Verify the signing key fulfills the requirements - let signing_key = revealed_did_info - .get_signing_leaf() - .map_err(DipParachainStateProofVerifierError::ProofVerification)?; - DidCallVerifier::check_call_origin_info(call, signing_key) - .map_err(DipParachainStateProofVerifierError::DidOriginError)?; - - // 6. Increment the local details - if let Some(details) = identity_details { - details.increment(); - } else { - *identity_details = Some(Default::default()); - }; - - Ok(revealed_did_info) - } - } -} diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs new file mode 100644 index 0000000000..d6e1134742 --- /dev/null +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs @@ -0,0 +1,256 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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 did::KeyIdOf; +use frame_support::ensure; +use frame_system::pallet_prelude::{BlockNumberFor, HeaderFor}; +use pallet_did_lookup::linkable_account::LinkableAccountId; +use pallet_dip_consumer::{traits::IdentityProofVerifier, RuntimeCallOf}; +use pallet_dip_provider::traits::IdentityCommitmentGenerator; +use pallet_web3_names::Web3NameOf; +use parity_scale_codec::Encode; +use sp_runtime::{traits::Zero, SaturatedConversion}; +use sp_std::marker::PhantomData; + +use crate::{ + merkle::v0::ParachainDipDidProof, + traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, + utils::OutputOf, + DipOriginInfo, DipParachainStateProofVerifierError, RevealedDidKey, +}; + +/// Proof verifier configured given a specific KILT runtime implementation. +/// +/// The generic types +/// indicate the following: +/// * `RelaychainRuntime`: The relaychain runtime definition. +/// * `RelaychainStateRootStore`: A type providing state roots for relaychain +/// blocks. +/// * `KILT_PARA_ID`: The ID of the specific KILT parachain instance. +/// * `KiltRuntime`: A KILT runtime definition. +/// * `DidCallVerifier`: Logic to map `RuntimeCall`s to a specific DID key +/// relationship. This information is used once the Merkle proof is verified, +/// to filter only the revealed keys that match the provided relationship. +/// * `SignedExtra`: Any additional information that must be signed by the DID +/// subject in the cross-chain operation. +/// * `MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT`: The maximum number of leaves that +/// can be revealed as part of the parachain head storage proof. +/// * `MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE`: The maximum size of each leaf +/// revealed as part of the parachain head storage proof. +/// * `MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT`: The maximum number of leaves that +/// can be revealed as part of the DIP commitment storage proof. +/// * `MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE`: The maximum size of each leaf +/// revealed as part of the DIP commitment storage proof. +/// * `MAX_DID_MERKLE_PROOF_LEAVE_COUNT`: The maximum number of *blinded* leaves +/// that can be revealed as part of the DID Merkle proof. +/// * `MAX_DID_MERKLE_PROOF_LEAVE_SIZE`: The maximum size of each *blinded* leaf +/// revealed as part of the DID Merkle proof. +/// * `MAX_DID_MERKLE_LEAVES_REVEALED`: The maximum number of leaves that can be +/// revealed as part of the DID Merkle proof. +pub struct ParachainVerifier< + RelaychainRuntime, + RelaychainStateRootStore, + const KILT_PARA_ID: u32, + KiltRuntime, + DidCallVerifier, + SignedExtra, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32, + const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32, + const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32, + const MAX_DID_MERKLE_LEAVES_REVEALED: u32, +>( + PhantomData<( + RelaychainRuntime, + RelaychainStateRootStore, + KiltRuntime, + DidCallVerifier, + SignedExtra, + )>, +); + +impl< + ConsumerRuntime, + RelaychainRuntime, + RelaychainStateRootStore, + const KILT_PARA_ID: u32, + KiltRuntime, + DidCallVerifier, + SignedExtra, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32, + const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32, + const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32, + const MAX_DID_MERKLE_LEAVES_REVEALED: u32, + > IdentityProofVerifier + for ParachainVerifier< + RelaychainRuntime, + RelaychainStateRootStore, + KILT_PARA_ID, + KiltRuntime, + DidCallVerifier, + SignedExtra, + MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, + MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, + MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT, + MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE, + MAX_DID_MERKLE_PROOF_LEAVE_COUNT, + MAX_DID_MERKLE_PROOF_LEAVE_SIZE, + MAX_DID_MERKLE_LEAVES_REVEALED, + > where + ConsumerRuntime: pallet_dip_consumer::Config, + ConsumerRuntime::LocalIdentityInfo: Incrementable + Default, + RelaychainRuntime: frame_system::Config, + RelaychainStateRootStore: + GetWithArg, Result = Option>>, + KiltRuntime: frame_system::Config + + pallet_dip_provider::Config + + did::Config + + pallet_web3_names::Config + + pallet_did_lookup::Config, + KiltRuntime::IdentityCommitmentGenerator: + IdentityCommitmentGenerator, + SignedExtra: GetWithoutArg, + SignedExtra::Result: Encode, + DidCallVerifier: DipCallOriginFilter< + RuntimeCallOf, + OriginInfo = RevealedDidKey, BlockNumberFor, KiltRuntime::AccountId>, + >, + DidCallVerifier::Error: Into, +{ + type Error = DipParachainStateProofVerifierError; + type Proof = ParachainDipDidProof< + BlockNumberFor, + KeyIdOf, + KiltRuntime::AccountId, + BlockNumberFor, + Web3NameOf, + LinkableAccountId, + BlockNumberFor, + >; + + type VerificationResult = DipOriginInfo< + KeyIdOf, + KiltRuntime::AccountId, + BlockNumberFor, + Web3NameOf, + LinkableAccountId, + MAX_DID_MERKLE_LEAVES_REVEALED, + >; + + fn verify_proof_for_call_against_details( + call: &RuntimeCallOf, + subject: &::Identifier, + submitter: &::AccountId, + identity_details: &mut Option<::LocalIdentityInfo>, + proof: Self::Proof, + ) -> Result { + // 1. Verify parachain state is finalized by relay chain and fresh. + ensure!( + proof.provider_head_proof.proof.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT.saturated_into(), + DipParachainStateProofVerifierError::ProofComponentTooLarge(0) + ); + ensure!( + proof + .provider_head_proof + .proof + .iter() + .all(|l| l.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE.saturated_into()), + DipParachainStateProofVerifierError::ProofComponentTooLarge(1) + ); + let proof_without_relaychain = proof + .verify_provider_head_proof::>( + KILT_PARA_ID, + ) + .map_err(DipParachainStateProofVerifierError::ProofVerification)?; + + // 2. Verify commitment is included in provider parachain state. + ensure!( + proof_without_relaychain.dip_commitment_proof.0.len() + <= MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT.saturated_into(), + DipParachainStateProofVerifierError::ProofComponentTooLarge(2) + ); + ensure!( + proof_without_relaychain + .dip_commitment_proof + .0 + .iter() + .all(|l| l.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE.saturated_into()), + DipParachainStateProofVerifierError::ProofComponentTooLarge(3) + ); + let proof_without_parachain = proof_without_relaychain + .verify_dip_commitment_proof_for_subject::(subject) + .map_err(DipParachainStateProofVerifierError::ProofVerification)?; + + // 3. Verify DIP Merkle proof. + ensure!( + proof_without_parachain.dip_proof.blinded.len() <= MAX_DID_MERKLE_PROOF_LEAVE_COUNT.saturated_into(), + DipParachainStateProofVerifierError::ProofComponentTooLarge(4) + ); + ensure!( + proof_without_parachain + .dip_proof + .blinded + .iter() + .all(|l| l.len() <= MAX_DID_MERKLE_PROOF_LEAVE_SIZE.saturated_into()), + DipParachainStateProofVerifierError::ProofComponentTooLarge(5) + ); + let proof_without_dip_merkle = proof_without_parachain + .verify_dip_proof::() + .map_err(DipParachainStateProofVerifierError::ProofVerification)?; + + // 4. Verify call is signed by one of the DID keys revealed in the proof + let current_block_number = frame_system::Pallet::::block_number(); + let consumer_genesis_hash = + frame_system::Pallet::::block_hash(BlockNumberFor::::zero()); + let signed_extra = SignedExtra::get(); + let encoded_payload = ( + call, + &identity_details, + submitter, + proof_without_dip_merkle.signature.valid_until, + consumer_genesis_hash, + signed_extra, + ) + .encode(); + let revealed_did_info = proof_without_dip_merkle + .verify_signature_time(¤t_block_number) + .and_then(|p| p.retrieve_signing_leaf_for_payload(&encoded_payload[..])) + .map_err(DipParachainStateProofVerifierError::ProofVerification)?; + + // 5. Verify the signing key fulfills the requirements + let signing_key = revealed_did_info + .get_signing_leaf() + .map_err(DipParachainStateProofVerifierError::ProofVerification)?; + DidCallVerifier::check_call_origin_info(call, signing_key) + .map_err(DipParachainStateProofVerifierError::DidOriginError)?; + + // 6. Increment the local details + if let Some(details) = identity_details { + details.increment(); + } else { + *identity_details = Some(Default::default()); + }; + + Ok(revealed_did_info) + } +} diff --git a/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs b/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs index bf8cb83b68..64cb8ee733 100644 --- a/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs @@ -20,7 +20,7 @@ use did::KeyIdOf; use frame_system::pallet_prelude::BlockNumberFor; use pallet_did_lookup::linkable_account::LinkableAccountId; use pallet_dip_consumer::{traits::IdentityProofVerifier, RuntimeCallOf}; -use pallet_dip_provider::{traits::IdentityCommitmentGenerator, IdentityCommitmentOf}; +use pallet_dip_provider::traits::IdentityCommitmentGenerator; use pallet_web3_names::Web3NameOf; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; @@ -35,6 +35,8 @@ use crate::{ DipOriginInfo, }; +pub mod v0; + mod error; pub use error::*; @@ -180,222 +182,3 @@ impl< } } } - -pub mod v0 { - use super::*; - - use frame_support::ensure; - use frame_system::pallet_prelude::HeaderFor; - use sp_runtime::{traits::Zero, SaturatedConversion}; - - use crate::RelayDipDidProof; - - /// Proof verifier configured given a specific KILT runtime implementation. - /// - /// The generic types are the following: - /// - /// * `ConsumerBlockHashStore`: A type providing block hashes for the - /// relaychain blocks. - /// * `KILT_PARA_ID`: The ID of the specific KILT parachain instance. - /// * `KiltRuntime`: A KILT runtime definition. - /// * `DidCallVerifier`: Logic to map `RuntimeCall`s to a specific DID key - /// relationship. This information is used once the Merkle proof is - /// verified, to filter only the revealed keys that match the provided - /// relationship. - /// * `SignedExtra`: Any additional information that must be signed by the - /// DID subject in the cross-chain operation. - /// * `MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT`: The maximum number of leaves - /// that can be revealed as part of the parachain head storage proof. - /// * `MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE`: The maximum size of each leaf - /// revealed as part of the parachain head storage proof. - /// * `MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT`: The maximum number of leaves - /// that can be revealed as part of the DIP commitment storage proof. - /// * `MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE`: The maximum size of each leaf - /// revealed as part of the DIP commitment storage proof. - /// * `MAX_DID_MERKLE_PROOF_LEAVE_COUNT`: The maximum number of *blinded* - /// leaves that can be revealed as part of the DID Merkle proof. - /// * `MAX_DID_MERKLE_PROOF_LEAVE_SIZE`: The maximum size of each *blinded* - /// leaf revealed as part of the DID Merkle proof. - /// * `MAX_DID_MERKLE_PROOF_LEAVE_SIZE`: The maximum number of leaves that - /// can be revealed as part of the DID Merkle proof. - pub struct RelaychainVerifier< - ConsumerBlockHashStore, - const KILT_PARA_ID: u32, - KiltRuntime, - DidCallVerifier, - SignedExtra, - const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32, - const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32, - const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32, - const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32, - const MAX_DID_MERKLE_LEAVES_REVEALED: u32, - >( - #[allow(clippy::type_complexity)] - PhantomData<(ConsumerBlockHashStore, KiltRuntime, DidCallVerifier, SignedExtra)>, - ); - - impl< - ConsumerRuntime, - ConsumerBlockHashStore, - const KILT_PARA_ID: u32, - KiltRuntime, - DidCallVerifier, - SignedExtra, - const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32, - const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32, - const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32, - const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32, - const MAX_DID_MERKLE_LEAVES_REVEALED: u32, - > IdentityProofVerifier - for RelaychainVerifier< - ConsumerBlockHashStore, - KILT_PARA_ID, - KiltRuntime, - DidCallVerifier, - SignedExtra, - MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, - MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, - MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT, - MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE, - MAX_DID_MERKLE_PROOF_LEAVE_COUNT, - MAX_DID_MERKLE_PROOF_LEAVE_SIZE, - MAX_DID_MERKLE_LEAVES_REVEALED, - > where - ConsumerRuntime: pallet_dip_consumer::Config, - ConsumerRuntime::LocalIdentityInfo: Incrementable + Default, - BlockNumberFor: Into + TryFrom, - ConsumerBlockHashStore: - GetWithArg, Result = Option>>, - KiltRuntime: frame_system::Config - + pallet_dip_provider::Config - + did::Config - + pallet_web3_names::Config - + pallet_did_lookup::Config, - KiltRuntime::IdentityCommitmentGenerator: - IdentityCommitmentGenerator, - IdentityCommitmentOf: Into, - SignedExtra: GetWithoutArg, - SignedExtra::Result: Encode, - DidCallVerifier: DipCallOriginFilter< - RuntimeCallOf, - OriginInfo = RevealedDidKey, BlockNumberFor, KiltRuntime::AccountId>, - >, - DidCallVerifier::Error: Into, - { - type Error = DipRelaychainStateProofVerifierError; - type Proof = RelayDipDidProof< - BlockNumberFor, - ConsumerRuntime::Hashing, - KeyIdOf, - KiltRuntime::AccountId, - BlockNumberFor, - Web3NameOf, - LinkableAccountId, - >; - type VerificationResult = DipOriginInfo< - KeyIdOf, - KiltRuntime::AccountId, - BlockNumberFor, - Web3NameOf, - LinkableAccountId, - MAX_DID_MERKLE_LEAVES_REVEALED, - >; - - fn verify_proof_for_call_against_details( - call: &RuntimeCallOf, - subject: &ConsumerRuntime::Identifier, - submitter: &ConsumerRuntime::AccountId, - identity_details: &mut Option, - proof: Self::Proof, - ) -> Result { - // 1. Verify provided relaychain header. - let proof_without_header = proof - .verify_relay_header::() - .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; - - // 2. Verify parachain state is finalized by relay chain and fresh. - ensure!( - proof_without_header.provider_head_proof.proof.len() - <= MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT.saturated_into(), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(0) - ); - ensure!( - proof_without_header - .provider_head_proof - .proof - .iter() - .all(|l| l.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE.saturated_into()), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(1) - ); - let proof_without_relaychain = proof_without_header - .verify_provider_head_proof::>(KILT_PARA_ID) - .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; - - // 3. Verify commitment is included in provider parachain state. - ensure!( - proof_without_relaychain.dip_commitment_proof.0.len() - <= MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT.saturated_into(), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(2) - ); - ensure!( - proof_without_relaychain - .dip_commitment_proof - .0 - .iter() - .all(|l| l.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE.saturated_into()), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(3) - ); - let proof_without_parachain = proof_without_relaychain - .verify_dip_commitment_proof_for_subject::(subject) - .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; - - // 4. Verify DIP Merkle proof. - ensure!( - proof_without_parachain.dip_proof.blinded.len() <= MAX_DID_MERKLE_PROOF_LEAVE_COUNT.saturated_into(), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(4) - ); - ensure!( - proof_without_parachain - .dip_proof - .blinded - .iter() - .all(|l| l.len() <= MAX_DID_MERKLE_PROOF_LEAVE_SIZE.saturated_into()), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(5) - ); - let proof_without_dip_merkle = proof_without_parachain - .verify_dip_proof::() - .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; - - // 5. Verify call is signed by one of the DID keys revealed in the proof - let current_block_number = frame_system::Pallet::::block_number(); - let consumer_genesis_hash = - frame_system::Pallet::::block_hash(BlockNumberFor::::zero()); - let signed_extra = SignedExtra::get(); - let encoded_payload = (call, &identity_details, submitter, consumer_genesis_hash, signed_extra).encode(); - let revealed_did_info = proof_without_dip_merkle - .verify_signature_time(¤t_block_number) - .and_then(|p| p.retrieve_signing_leaf_for_payload(&encoded_payload[..])) - .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; - - // 6. Verify the signing key fulfills the requirements - let signing_key = revealed_did_info - .get_signing_leaf() - .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; - DidCallVerifier::check_call_origin_info(call, signing_key) - .map_err(DipRelaychainStateProofVerifierError::DidOriginError)?; - - // 7. Increment the local details - if let Some(details) = identity_details { - details.increment(); - } else { - *identity_details = Some(Default::default()); - }; - - Ok(revealed_did_info) - } - } -} diff --git a/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs new file mode 100644 index 0000000000..f53ad2db8f --- /dev/null +++ b/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs @@ -0,0 +1,239 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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 did::KeyIdOf; +use frame_support::ensure; +use frame_system::pallet_prelude::{BlockNumberFor, HeaderFor}; +use pallet_did_lookup::linkable_account::LinkableAccountId; +use pallet_dip_consumer::{traits::IdentityProofVerifier, RuntimeCallOf}; +use pallet_dip_provider::{traits::IdentityCommitmentGenerator, IdentityCommitmentOf}; +use pallet_web3_names::Web3NameOf; +use parity_scale_codec::Encode; +use sp_core::U256; +use sp_runtime::{traits::Zero, SaturatedConversion}; +use sp_std::marker::PhantomData; + +use crate::{ + traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, + utils::OutputOf, + DipOriginInfo, DipRelaychainStateProofVerifierError, RelayDipDidProof, RevealedDidKey, +}; + +/// Proof verifier configured given a specific KILT runtime implementation. +/// +/// The generic types are the following: +/// +/// * `ConsumerBlockHashStore`: A type providing block hashes for the relaychain +/// blocks. +/// * `KILT_PARA_ID`: The ID of the specific KILT parachain instance. +/// * `KiltRuntime`: A KILT runtime definition. +/// * `DidCallVerifier`: Logic to map `RuntimeCall`s to a specific DID key +/// relationship. This information is used once the Merkle proof is verified, +/// to filter only the revealed keys that match the provided relationship. +/// * `SignedExtra`: Any additional information that must be signed by the DID +/// subject in the cross-chain operation. +/// * `MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT`: The maximum number of leaves that +/// can be revealed as part of the parachain head storage proof. +/// * `MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE`: The maximum size of each leaf +/// revealed as part of the parachain head storage proof. +/// * `MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT`: The maximum number of leaves that +/// can be revealed as part of the DIP commitment storage proof. +/// * `MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE`: The maximum size of each leaf +/// revealed as part of the DIP commitment storage proof. +/// * `MAX_DID_MERKLE_PROOF_LEAVE_COUNT`: The maximum number of *blinded* leaves +/// that can be revealed as part of the DID Merkle proof. +/// * `MAX_DID_MERKLE_PROOF_LEAVE_SIZE`: The maximum size of each *blinded* leaf +/// revealed as part of the DID Merkle proof. +/// * `MAX_DID_MERKLE_PROOF_LEAVE_SIZE`: The maximum number of leaves that can +/// be revealed as part of the DID Merkle proof. +pub struct RelaychainVerifier< + ConsumerBlockHashStore, + const KILT_PARA_ID: u32, + KiltRuntime, + DidCallVerifier, + SignedExtra, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32, + const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32, + const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32, + const MAX_DID_MERKLE_LEAVES_REVEALED: u32, +>(#[allow(clippy::type_complexity)] PhantomData<(ConsumerBlockHashStore, KiltRuntime, DidCallVerifier, SignedExtra)>); + +impl< + ConsumerRuntime, + ConsumerBlockHashStore, + const KILT_PARA_ID: u32, + KiltRuntime, + DidCallVerifier, + SignedExtra, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32, + const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32, + const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32, + const MAX_DID_MERKLE_LEAVES_REVEALED: u32, + > IdentityProofVerifier + for RelaychainVerifier< + ConsumerBlockHashStore, + KILT_PARA_ID, + KiltRuntime, + DidCallVerifier, + SignedExtra, + MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, + MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, + MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT, + MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE, + MAX_DID_MERKLE_PROOF_LEAVE_COUNT, + MAX_DID_MERKLE_PROOF_LEAVE_SIZE, + MAX_DID_MERKLE_LEAVES_REVEALED, + > where + ConsumerRuntime: pallet_dip_consumer::Config, + ConsumerRuntime::LocalIdentityInfo: Incrementable + Default, + BlockNumberFor: Into + TryFrom, + ConsumerBlockHashStore: + GetWithArg, Result = Option>>, + KiltRuntime: frame_system::Config + + pallet_dip_provider::Config + + did::Config + + pallet_web3_names::Config + + pallet_did_lookup::Config, + KiltRuntime::IdentityCommitmentGenerator: IdentityCommitmentGenerator, + IdentityCommitmentOf: Into, + SignedExtra: GetWithoutArg, + SignedExtra::Result: Encode, + DidCallVerifier: DipCallOriginFilter< + RuntimeCallOf, + OriginInfo = RevealedDidKey, BlockNumberFor, KiltRuntime::AccountId>, + >, + DidCallVerifier::Error: Into, +{ + type Error = DipRelaychainStateProofVerifierError; + type Proof = RelayDipDidProof< + BlockNumberFor, + ConsumerRuntime::Hashing, + KeyIdOf, + KiltRuntime::AccountId, + BlockNumberFor, + Web3NameOf, + LinkableAccountId, + >; + type VerificationResult = DipOriginInfo< + KeyIdOf, + KiltRuntime::AccountId, + BlockNumberFor, + Web3NameOf, + LinkableAccountId, + MAX_DID_MERKLE_LEAVES_REVEALED, + >; + + fn verify_proof_for_call_against_details( + call: &RuntimeCallOf, + subject: &ConsumerRuntime::Identifier, + submitter: &ConsumerRuntime::AccountId, + identity_details: &mut Option, + proof: Self::Proof, + ) -> Result { + // 1. Verify provided relaychain header. + let proof_without_header = proof + .verify_relay_header::() + .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; + + // 2. Verify parachain state is finalized by relay chain and fresh. + ensure!( + proof_without_header.provider_head_proof.proof.len() + <= MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT.saturated_into(), + DipRelaychainStateProofVerifierError::ProofComponentTooLarge(0) + ); + ensure!( + proof_without_header + .provider_head_proof + .proof + .iter() + .all(|l| l.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE.saturated_into()), + DipRelaychainStateProofVerifierError::ProofComponentTooLarge(1) + ); + let proof_without_relaychain = proof_without_header + .verify_provider_head_proof::>(KILT_PARA_ID) + .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; + + // 3. Verify commitment is included in provider parachain state. + ensure!( + proof_without_relaychain.dip_commitment_proof.0.len() + <= MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT.saturated_into(), + DipRelaychainStateProofVerifierError::ProofComponentTooLarge(2) + ); + ensure!( + proof_without_relaychain + .dip_commitment_proof + .0 + .iter() + .all(|l| l.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE.saturated_into()), + DipRelaychainStateProofVerifierError::ProofComponentTooLarge(3) + ); + let proof_without_parachain = proof_without_relaychain + .verify_dip_commitment_proof_for_subject::(subject) + .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; + + // 4. Verify DIP Merkle proof. + ensure!( + proof_without_parachain.dip_proof.blinded.len() <= MAX_DID_MERKLE_PROOF_LEAVE_COUNT.saturated_into(), + DipRelaychainStateProofVerifierError::ProofComponentTooLarge(4) + ); + ensure!( + proof_without_parachain + .dip_proof + .blinded + .iter() + .all(|l| l.len() <= MAX_DID_MERKLE_PROOF_LEAVE_SIZE.saturated_into()), + DipRelaychainStateProofVerifierError::ProofComponentTooLarge(5) + ); + let proof_without_dip_merkle = proof_without_parachain + .verify_dip_proof::() + .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; + + // 5. Verify call is signed by one of the DID keys revealed in the proof + let current_block_number = frame_system::Pallet::::block_number(); + let consumer_genesis_hash = + frame_system::Pallet::::block_hash(BlockNumberFor::::zero()); + let signed_extra = SignedExtra::get(); + let encoded_payload = (call, &identity_details, submitter, consumer_genesis_hash, signed_extra).encode(); + let revealed_did_info = proof_without_dip_merkle + .verify_signature_time(¤t_block_number) + .and_then(|p| p.retrieve_signing_leaf_for_payload(&encoded_payload[..])) + .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; + + // 6. Verify the signing key fulfills the requirements + let signing_key = revealed_did_info + .get_signing_leaf() + .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; + DidCallVerifier::check_call_origin_info(call, signing_key) + .map_err(DipRelaychainStateProofVerifierError::DidOriginError)?; + + // 7. Increment the local details + if let Some(details) = identity_details { + details.increment(); + } else { + *identity_details = Some(Default::default()); + }; + + Ok(revealed_did_info) + } +} From bcf3c848d32080792de3d3516753f5d8346dbd92 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 26 Feb 2024 09:16:07 +0100 Subject: [PATCH 06/39] Restructure Merkle verification types --- .../src/merkle/v0/dip_subject_state.rs | 228 +++ .../src/merkle/v0/input_common.rs | 169 +++ .../kilt-dip-primitives/src/merkle/v0/mod.rs | 1291 +---------------- .../src/merkle/v0/output_common.rs | 279 ++++ .../src/merkle/v0/provider_state.rs | 491 +++++++ .../src/merkle/v0/relay_state.rs | 246 ++++ .../src/verifier/parachain/mod.rs | 6 +- 7 files changed, 1427 insertions(+), 1283 deletions(-) create mode 100644 crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state.rs create mode 100644 crates/kilt-dip-primitives/src/merkle/v0/input_common.rs create mode 100644 crates/kilt-dip-primitives/src/merkle/v0/output_common.rs create mode 100644 crates/kilt-dip-primitives/src/merkle/v0/provider_state.rs create mode 100644 crates/kilt-dip-primitives/src/merkle/v0/relay_state.rs diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state.rs new file mode 100644 index 0000000000..efd3439aaa --- /dev/null +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state.rs @@ -0,0 +1,228 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2023 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 did::{ + did_details::{DidPublicKey, DidPublicKeyDetails}, + DidSignature, +}; +use sp_core::ConstU32; +use sp_runtime::{traits::SaturatedConversion, BoundedVec}; + +use crate::{ + merkle::v0::{ + input_common::TimeBoundDidSignature, + output_common::{DidKeyRelationship, DipOriginInfo, RevealedDidKey, RevealedDidMerkleProofLeaf}, + }, + traits::BenchmarkDefault, + Error, +}; + +/// A DIP proof whose information has been verified but that contains a +/// cross-chain [`TimeBoundDidSignature`] that still needs verification. +/// +/// The generic types indicate the following: +/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. +/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. +/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. +/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. +/// * `KiltLinkableAccountId`: The linkable account ID type configured by the +/// KILT chain. +/// * `ConsumerBlockNumber`: The `BlockNumber` definition of the consumer +/// parachain. +/// * `MAX_REVEALED_LEAVES_COUNT`: The maximum number of leaves revealable in +/// the proof. +#[derive(Debug)] +pub struct DipRevealedDetailsAndUnverifiedDidSignature< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + const MAX_REVEALED_LEAVES_COUNT: u32, +> { + /// The parts of the subject's DID details revealed in the DIP proof. + pub(crate) revealed_leaves: BoundedVec< + RevealedDidMerkleProofLeaf, + ConstU32, + >, + /// The cross-chain DID signature. + pub(crate) signature: TimeBoundDidSignature, +} + +impl< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + const MAX_REVEALED_LEAVES_COUNT: u32, + > + DipRevealedDetailsAndUnverifiedDidSignature< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + MAX_REVEALED_LEAVES_COUNT, + > where + ConsumerBlockNumber: PartialOrd, +{ + /// Verifies that the DIP proof signature is anchored to a block that has + /// not passed on the consumer chain. + pub fn verify_signature_time( + self, + block_number: &ConsumerBlockNumber, + ) -> Result< + DipRevealedDetailsAndVerifiedDidSignatureFreshness< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + MAX_REVEALED_LEAVES_COUNT, + >, + Error, + > { + cfg_if::cfg_if! { + if #[cfg(feature = "runtime-benchmarks")] { + let _ = self.signature.valid_until >= *block_number; + } else { + frame_support::ensure!(self.signature.valid_until >= *block_number, Error::InvalidSignatureTime); + } + } + Ok(DipRevealedDetailsAndVerifiedDidSignatureFreshness { + revealed_leaves: self.revealed_leaves, + signature: self.signature.signature, + }) + } +} + +/// A DIP proof whose information has been verified and whose signature has been +/// verified not to be expired, but that yet does not contain information as to +/// which of the revealed keys has generated the signature. +/// +/// The generic types indicate the following: +/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. +/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. +/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. +/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. +/// * `KiltLinkableAccountId`: The linkable account ID type configured by the +/// KILT chain. +/// * `MAX_REVEALED_LEAVES_COUNT`: The maximum number of leaves revealable in +/// the proof. +#[derive(Debug)] +pub struct DipRevealedDetailsAndVerifiedDidSignatureFreshness< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + const MAX_REVEALED_LEAVES_COUNT: u32, +> { + /// The parts of the subject's DID details revealed in the DIP proof. + pub(crate) revealed_leaves: BoundedVec< + RevealedDidMerkleProofLeaf, + ConstU32, + >, + /// The cross-chain DID signature without time information. + pub(crate) signature: DidSignature, +} + +impl< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + const MAX_REVEALED_LEAVES_COUNT: u32, + > + DipRevealedDetailsAndVerifiedDidSignatureFreshness< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + MAX_REVEALED_LEAVES_COUNT, + > where + KiltDidKeyId: BenchmarkDefault, + KiltBlockNumber: BenchmarkDefault, +{ + /// Iterates over the revealed DID leafs to find the one that generated a + /// valid signature for the provided payload. + pub fn retrieve_signing_leaf_for_payload( + self, + payload: &[u8], + ) -> Result< + DipOriginInfo< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + MAX_REVEALED_LEAVES_COUNT, + >, + Error, + > { + let revealed_verification_keys = self.revealed_leaves.iter().filter(|leaf| { + matches!( + leaf, + RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey { + relationship: DidKeyRelationship::Verification(_), + .. + }) + ) + }); + let maybe_signing_key_index = revealed_verification_keys + .enumerate() + .find(|(_, revealed_verification_key)| { + let RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey { + details: + DidPublicKeyDetails { + key: DidPublicKey::PublicVerificationKey(verification_key), + .. + }, + .. + }) = revealed_verification_key + else { + return false; + }; + verification_key.verify_signature(payload, &self.signature).is_ok() + }) + .map(|(index, _)| u32::saturated_from(index)); + + let signing_key_entry = if let Some(index) = maybe_signing_key_index { + (self.revealed_leaves, index) + } else { + cfg_if::cfg_if! { + if #[cfg(feature = "runtime-benchmarks")] { + return Ok(DipOriginInfo::default()); + } else { + return Err(Error::InvalidDidKeyRevealed); + } + } + }; + + Ok(DipOriginInfo { + revealed_leaves: signing_key_entry.0, + signing_leaf_index: signing_key_entry.1, + }) + } +} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs b/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs new file mode 100644 index 0000000000..68828191cf --- /dev/null +++ b/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs @@ -0,0 +1,169 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2023 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 did::DidSignature; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_std::vec::Vec; + +use crate::{merkle::v0::output_common::RevealedDidMerkleProofLeaf, utils::BoundedBlindedValue}; + +/// The state proof for a parachain head. +/// +/// The generic types indicate the following: +/// * `RelayBlockNumber`: The `BlockNumber` definition of the relaychain. +#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] +pub struct ProviderHeadStateProof { + pub(crate) relay_block_number: RelayBlockNumber, + pub(crate) proof: BoundedBlindedValue, +} + +#[cfg(feature = "runtime-benchmarks")] +impl kilt_support::traits::GetWorstCase for ProviderHeadStateProof +where + RelayBlockNumber: Default, +{ + fn worst_case(context: Context) -> Self { + Self { + relay_block_number: RelayBlockNumber::default(), + proof: BoundedBlindedValue::worst_case(context), + } + } +} + +/// The state proof for a DIP commitment. +#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] +pub struct DipCommitmentStateProof(pub(crate) BoundedBlindedValue); + +#[cfg(feature = "runtime-benchmarks")] +impl kilt_support::traits::GetWorstCase for DipCommitmentStateProof { + fn worst_case(context: Context) -> Self { + Self(BoundedBlindedValue::worst_case(context)) + } +} + +/// The Merkle proof for a KILT DID. +/// +/// The generic types indicate the following: +/// * `ProviderDidKeyId`: The DID key ID type configured by the provider. +/// * `ProviderAccountId`: The `AccountId` type configured by the provider. +/// * `ProviderBlockNumber`: The `BlockNumber` type configured by the provider. +/// * `ProviderWeb3Name`: The web3name type configured by the provider. +/// * `ProviderLinkableAccountId`: The linkable account ID type configured by +/// the provider. +#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] +pub struct DidMerkleProof< + ProviderDidKeyId, + ProviderAccountId, + ProviderBlockNumber, + ProviderWeb3Name, + ProviderLinkableAccountId, +> { + pub(crate) blinded: BoundedBlindedValue, + pub(crate) revealed: Vec< + RevealedDidMerkleProofLeaf< + ProviderDidKeyId, + ProviderAccountId, + ProviderBlockNumber, + ProviderWeb3Name, + ProviderLinkableAccountId, + >, + >, +} + +impl + DidMerkleProof +{ + pub fn new( + blinded: BoundedBlindedValue, + revealed: Vec< + RevealedDidMerkleProofLeaf< + ProviderDidKeyId, + ProviderAccountId, + ProviderBlockNumber, + ProviderWeb3Name, + ProviderLinkableAccountId, + >, + >, + ) -> Self { + Self { blinded, revealed } + } +} + +#[cfg(feature = "runtime-benchmarks")] +impl< + ProviderDidKeyId, + ProviderAccountId, + ProviderBlockNumber, + ProviderWeb3Name, + ProviderLinkableAccountId, + Context, + > kilt_support::traits::GetWorstCase + for DidMerkleProof< + ProviderDidKeyId, + ProviderAccountId, + ProviderBlockNumber, + ProviderWeb3Name, + ProviderLinkableAccountId, + > where + ProviderDidKeyId: Default + Clone, + ProviderAccountId: Clone, + ProviderBlockNumber: Default + Clone, + ProviderWeb3Name: Clone, + ProviderLinkableAccountId: Clone, +{ + fn worst_case(context: Context) -> Self { + Self { + blinded: BoundedBlindedValue::worst_case(context), + revealed: sp_std::vec![RevealedDidMerkleProofLeaf::default(); 64], + } + } +} + +/// A DID signature anchored to a specific block height. +/// +/// The generic types indicate the following: +/// * `BlockNumber`: The `BlockNumber` definition of the chain consuming (i.e., +/// validating) this signature. +#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] +pub struct TimeBoundDidSignature { + /// The signature. + pub(crate) signature: DidSignature, + /// The block number until the signature is to be considered valid. + pub(crate) valid_until: BlockNumber, +} + +impl TimeBoundDidSignature { + pub fn new(signature: DidSignature, valid_until: BlockNumber) -> Self { + Self { signature, valid_until } + } +} + +#[cfg(feature = "runtime-benchmarks")] +impl kilt_support::traits::GetWorstCase for TimeBoundDidSignature +where + DidSignature: kilt_support::traits::GetWorstCase, + BlockNumber: Default, +{ + fn worst_case(context: Context) -> Self { + Self { + signature: DidSignature::worst_case(context), + valid_until: BlockNumber::default(), + } + } +} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/mod.rs index 00b89e62cc..6628e444d3 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/mod.rs @@ -18,1285 +18,16 @@ //! Module to deal with cross-chain Merkle proof as generated by the KILT chain. -use did::{ - did_details::{DidPublicKey, DidPublicKeyDetails}, - DidSignature, DidVerificationKeyRelationship, -}; -use frame_support::ensure; -use pallet_dip_provider::IdentityCommitmentOf; -use parity_scale_codec::{Codec, Decode, Encode, MaxEncodedLen}; -use scale_info::TypeInfo; -use sp_core::{ConstU32, U256}; -use sp_runtime::{ - generic::Header, - traits::{AtLeast32BitUnsigned, Hash, Header as HeaderT, MaybeDisplay, Member}, - BoundedVec, SaturatedConversion, -}; -use sp_std::{fmt::Debug, vec::Vec}; -use sp_trie::{verify_trie_proof, LayoutV1}; - -use crate::{ - state_proofs::{verify_storage_value_proof, verify_storage_value_proof_with_decoder}, - traits::{BenchmarkDefault, GetWithArg}, - utils::{ - calculate_dip_identity_commitment_storage_key_for_runtime, calculate_parachain_head_storage_key, - BoundedBlindedValue, OutputOf, - }, -}; - +mod dip_subject_state; mod error; -pub use error::*; - -/// The state proof for a parachain head. -/// -/// The generic types indicate the following: -/// * `RelayBlockNumber`: The `BlockNumber` definition of the relaychain. -#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] -pub struct ProviderHeadStateProof { - pub(crate) relay_block_number: RelayBlockNumber, - pub(crate) proof: BoundedBlindedValue, -} - -#[cfg(feature = "runtime-benchmarks")] -impl kilt_support::traits::GetWorstCase for ProviderHeadStateProof -where - RelayBlockNumber: Default, -{ - fn worst_case(context: Context) -> Self { - Self { - relay_block_number: RelayBlockNumber::default(), - proof: BoundedBlindedValue::worst_case(context), - } - } -} - -/// The state proof for a DIP commitment. -#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] -pub struct DipCommitmentStateProof(pub(crate) BoundedBlindedValue); - -#[cfg(feature = "runtime-benchmarks")] -impl kilt_support::traits::GetWorstCase for DipCommitmentStateProof { - fn worst_case(context: Context) -> Self { - Self(BoundedBlindedValue::worst_case(context)) - } -} - -/// The Merkle proof for a KILT DID. -/// -/// The generic types indicate the following: -/// * `ProviderDidKeyId`: The DID key ID type configured by the provider. -/// * `ProviderAccountId`: The `AccountId` type configured by the provider. -/// * `ProviderBlockNumber`: The `BlockNumber` type configured by the provider. -/// * `ProviderWeb3Name`: The web3name type configured by the provider. -/// * `ProviderLinkableAccountId`: The linkable account ID type configured by -/// the provider. -#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] -pub struct DidMerkleProof< - ProviderDidKeyId, - ProviderAccountId, - ProviderBlockNumber, - ProviderWeb3Name, - ProviderLinkableAccountId, -> { - pub(crate) blinded: BoundedBlindedValue, - pub(crate) revealed: Vec< - RevealedDidMerkleProofLeaf< - ProviderDidKeyId, - ProviderAccountId, - ProviderBlockNumber, - ProviderWeb3Name, - ProviderLinkableAccountId, - >, - >, -} - -impl - DidMerkleProof -{ - pub fn new( - blinded: BoundedBlindedValue, - revealed: Vec< - RevealedDidMerkleProofLeaf< - ProviderDidKeyId, - ProviderAccountId, - ProviderBlockNumber, - ProviderWeb3Name, - ProviderLinkableAccountId, - >, - >, - ) -> Self { - Self { blinded, revealed } - } -} - -#[cfg(feature = "runtime-benchmarks")] -impl< - ProviderDidKeyId, - ProviderAccountId, - ProviderBlockNumber, - ProviderWeb3Name, - ProviderLinkableAccountId, - Context, - > kilt_support::traits::GetWorstCase - for DidMerkleProof< - ProviderDidKeyId, - ProviderAccountId, - ProviderBlockNumber, - ProviderWeb3Name, - ProviderLinkableAccountId, - > where - ProviderDidKeyId: Default + Clone, - ProviderAccountId: Clone, - ProviderBlockNumber: Default + Clone, - ProviderWeb3Name: Clone, - ProviderLinkableAccountId: Clone, -{ - fn worst_case(context: Context) -> Self { - Self { - blinded: BoundedBlindedValue::worst_case(context), - revealed: sp_std::vec![RevealedDidMerkleProofLeaf::default(); 64], - } - } -} - -/// A DID signature anchored to a specific block height. -/// -/// The generic types indicate the following: -/// * `BlockNumber`: The `BlockNumber` definition of the chain consuming (i.e., -/// validating) this signature. -#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] -pub struct TimeBoundDidSignature { - /// The signature. - pub(crate) signature: DidSignature, - /// The block number until the signature is to be considered valid. - pub(crate) valid_until: BlockNumber, -} - -impl TimeBoundDidSignature { - pub fn new(signature: DidSignature, valid_until: BlockNumber) -> Self { - Self { signature, valid_until } - } -} - -#[cfg(feature = "runtime-benchmarks")] -impl kilt_support::traits::GetWorstCase for TimeBoundDidSignature -where - DidSignature: kilt_support::traits::GetWorstCase, - BlockNumber: Default, -{ - fn worst_case(context: Context) -> Self { - Self { - signature: DidSignature::worst_case(context), - valid_until: BlockNumber::default(), - } - } -} - -/// A DIP proof submitted to a relaychain consumer. -/// -/// The generic types indicate the following: -/// * `RelayBlockNumber`: The `BlockNumber` definition of the relaychain. -/// * `RelayHasher`: The hashing algorithm used by the relaychain. -/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. -/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. -/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. -/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. -/// * `KiltLinkableAccountId`: The linkable account ID type configured by the -/// KILT chain. -#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] -pub struct RelayDipDidProof< - RelayBlockNumber: Copy + Into + TryFrom, - RelayHasher: Hash, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, -> { - /// The relaychain header for the relaychain block specified in the - /// `provider_head_proof`. - pub(crate) relay_header: Header, - /// The state proof for the given parachain head. - pub(crate) provider_head_proof: ProviderHeadStateProof, - /// The raw state proof for the DIP commitment of the given subject. - pub(crate) dip_commitment_proof: DipCommitmentStateProof, - /// The Merkle proof of the subject's DID details. - pub(crate) dip_proof: - DidMerkleProof, - /// The cross-chain DID signature. - pub(crate) signature: TimeBoundDidSignature, -} - -impl< - RelayBlockNumber: Member + sp_std::hash::Hash + Copy + MaybeDisplay + AtLeast32BitUnsigned + Codec + Into + TryFrom, - RelayHasher: Hash, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - > - RelayDipDidProof< - RelayBlockNumber, - RelayHasher, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - > -{ - /// Verifies the relaychain part of the state proof using the provided block - /// hash. - #[allow(clippy::type_complexity)] - pub fn verify_relay_header_with_block_hash( - self, - block_hash: &OutputOf, - ) -> Result< - RelayDipDidProofWithVerifiedRelayStateRoot< - OutputOf, - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - >, - Error, - > { - if block_hash != &self.relay_header.hash() { - return Err(Error::InvalidRelayHeader); - } - - Ok(RelayDipDidProofWithVerifiedRelayStateRoot { - relay_state_root: self.relay_header.state_root, - provider_head_proof: self.provider_head_proof, - dip_commitment_proof: self.dip_commitment_proof, - dip_proof: self.dip_proof, - signature: self.signature, - }) - } - - /// Verifies the relaychain part of the state proof using the block hash - /// returned by the provided implementation. - /// - /// The generic types indicate the following: - /// * `RelayHashStore`: The type that returns a relaychain block hash given - /// a relaychain block number. - #[allow(clippy::type_complexity)] - pub fn verify_relay_header( - self, - ) -> Result< - RelayDipDidProofWithVerifiedRelayStateRoot< - OutputOf, - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - >, - Error, - > - where - RelayHashStore: GetWithArg>>, - { - let relay_block_hash = RelayHashStore::get(&self.relay_header.number).ok_or(Error::RelayBlockNotFound)?; - self.verify_relay_header_with_block_hash(&relay_block_hash) - } -} - -/// A DIP proof submitted to a relaychain consumer that has had the proof header -/// verified against a given block hash. -/// -/// The generic types indicate the following: -/// * `StateRoot`: The type of the state root used by the relaychain. -/// * `RelayBlockNumber`: The `BlockNumber` definition of the relaychain. -/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. -/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. -/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. -/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. -/// * `KiltLinkableAccountId`: The linkable account ID type configured by the -/// KILT chain. -#[derive(Debug)] -pub struct RelayDipDidProofWithVerifiedRelayStateRoot< - StateRoot, - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, -> { - /// The verified state root for the relaychain at the block specified in the - /// proof. - pub(crate) relay_state_root: StateRoot, - /// The state proof for the given parachain head. - pub(crate) provider_head_proof: ProviderHeadStateProof, - /// The raw state proof for the DIP commitment of the given subject. - pub(crate) dip_commitment_proof: DipCommitmentStateProof, - /// The Merkle proof of the subject's DID details. - pub(crate) dip_proof: - DidMerkleProof, - /// The cross-chain DID signature. - pub(crate) signature: TimeBoundDidSignature, -} - -impl< - StateRoot, - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - > - RelayDipDidProofWithVerifiedRelayStateRoot< - StateRoot, - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - > where - KiltBlockNumber: BenchmarkDefault, -{ - /// Verifies the head data of the state proof for the provider with the - /// given para ID. - /// - /// The generic types indicate the following: - /// * `RelayHasher`: The head data hashing algorithm used by the relaychain. - /// * `ProviderHeader`: The type of the parachain header to be revealed in - /// the state proof. - #[allow(clippy::type_complexity)] - pub fn verify_provider_head_proof( - self, - provider_para_id: u32, - ) -> Result< - DipDidProofWithVerifiedRelayStateRoot< - OutputOf, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - RelayBlockNumber, - >, - Error, - > - where - RelayHasher: Hash, - ProviderHeader: Decode + HeaderT, Number = KiltBlockNumber>, - { - let parachain_dip_proof = ParachainDipDidProof { - provider_head_proof: self.provider_head_proof, - dip_commitment_proof: self.dip_commitment_proof, - dip_proof: self.dip_proof, - signature: self.signature, - }; - - parachain_dip_proof.verify_provider_head_proof_with_state_root::( - provider_para_id, - &self.relay_state_root, - ) - } -} - -/// A DIP proof submitted to a parachain consumer. -/// -/// The generic types indicate the following: -/// * `RelayBlockNumber`: The `BlockNumber` definition of the relaychain. -/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. -/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. -/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. -/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. -/// * `KiltLinkableAccountId`: The linkable account ID type configured by the -/// KILT chain. -/// * `ConsumerBlockNumber`: The `BlockNumber` definition of the consumer -/// parachain. -#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] -pub struct ParachainDipDidProof< - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, -> { - /// The state proof for the given parachain head. - pub(crate) provider_head_proof: ProviderHeadStateProof, - /// The raw state proof for the DIP commitment of the given subject. - pub(crate) dip_commitment_proof: DipCommitmentStateProof, - /// The Merkle proof of the subject's DID details. - pub(crate) dip_proof: - DidMerkleProof, - /// The cross-chain DID signature. - pub(crate) signature: TimeBoundDidSignature, -} - -#[cfg(feature = "runtime-benchmarks")] -impl< - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - Context, - > kilt_support::traits::GetWorstCase - for ParachainDipDidProof< - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > where - RelayBlockNumber: Default, - KiltDidKeyId: Default + Clone, - KiltAccountId: Clone, - KiltBlockNumber: Default + Clone, - KiltWeb3Name: Clone, - KiltLinkableAccountId: Clone, - ConsumerBlockNumber: Default, - Context: Clone, -{ - fn worst_case(context: Context) -> Self { - Self { - provider_head_proof: ProviderHeadStateProof::worst_case(context.clone()), - dip_commitment_proof: DipCommitmentStateProof::worst_case(context.clone()), - dip_proof: DidMerkleProof::worst_case(context.clone()), - signature: TimeBoundDidSignature::worst_case(context), - } - } -} - -impl< - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > - ParachainDipDidProof< - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > where - KiltBlockNumber: BenchmarkDefault, -{ - /// Verifies the head data of the state proof for the provider with the - /// given para ID and relaychain state root. - /// - /// The generic types indicate the following: - /// * `RelayHasher`: The head data hashing algorithm used by the relaychain. - /// * `ProviderHeader`: The type of the parachain header to be revealed in - /// the state proof. - #[allow(clippy::type_complexity)] - pub fn verify_provider_head_proof_with_state_root( - self, - provider_para_id: u32, - relay_state_root: &OutputOf, - ) -> Result< - DipDidProofWithVerifiedRelayStateRoot< - OutputOf, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - >, - Error, - > - where - RelayHasher: Hash, - ProviderHeader: Decode + HeaderT, Number = KiltBlockNumber>, - { - let provider_head_storage_key = calculate_parachain_head_storage_key(provider_para_id); - // TODO: Figure out why RPC call returns 2 bytes in front which we don't need - let provider_header_result = verify_storage_value_proof_with_decoder::<_, RelayHasher, ProviderHeader>( - &provider_head_storage_key, - *relay_state_root, - self.provider_head_proof.proof, - |input| { - if input.len() < 2 { - return None; - } - let mut trimmed_input = &input[2..]; - ProviderHeader::decode(&mut trimmed_input).ok() - }, - ); - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - let provider_header = provider_header_result.unwrap_or_else(|_| ProviderHeader::new(::Number::default(), ::Hash::default(), ::Hash::default(), ::Hash::default(), sp_runtime::Digest::default())); - } else { - let provider_header = provider_header_result.map_err(Error::ParaHeadMerkleProof)?; - } - } - Ok(DipDidProofWithVerifiedRelayStateRoot { - state_root: *provider_header.state_root(), - dip_commitment_proof: self.dip_commitment_proof, - dip_proof: self.dip_proof, - signature: self.signature, - }) - } - - /// Verifies the head data of the state proof for the provider with the - /// given para ID using the state root returned by the provided - /// implementation. - /// - /// The generic types indicate the following: - /// * `RelayHasher`: The hashing algorithm used on the relaychain to - /// generate the parachains head data. - /// * `StateRootStore`: The type that returns a relaychain state root given - /// a relaychain block number. - /// * `ProviderHeader`: The type of the parachain header to be revealed in - /// the state proof. - #[allow(clippy::type_complexity)] - pub fn verify_provider_head_proof( - self, - provider_para_id: u32, - ) -> Result< - DipDidProofWithVerifiedRelayStateRoot< - OutputOf, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - >, - Error, - > - where - RelayHasher: Hash, - StateRootStore: GetWithArg>>, - ProviderHeader: Decode + HeaderT, Number = KiltBlockNumber>, - { - let relay_state_root = StateRootStore::get(&self.provider_head_proof.relay_block_number); - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - let relay_state_root = relay_state_root.unwrap_or_default(); - } else { - let relay_state_root = relay_state_root.ok_or(Error::RelayStateRootNotFound)?; - } - } - self.verify_provider_head_proof_with_state_root::( - provider_para_id, - &relay_state_root, - ) - } -} - -/// A DIP proof that has had the proof header and the relaychain state verified -/// for the provided relaychain block number. -/// -/// The generic types indicate the following: -/// * `StateRoot`: The type of the relaychain state root. -/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. -/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. -/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. -/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. -/// * `KiltLinkableAccountId`: The linkable account ID type configured by the -/// KILT chain. -/// * `ConsumerBlockNumber`: The `BlockNumber` definition of the consumer -/// parachain. -#[derive(Debug)] -pub struct DipDidProofWithVerifiedRelayStateRoot< - StateRoot, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, -> { - /// The relaychain state root for the block specified in the DIP proof. - pub(crate) state_root: StateRoot, - /// The raw state proof for the DIP commitment of the given subject. - pub(crate) dip_commitment_proof: DipCommitmentStateProof, - /// The Merkle proof of the subject's DID details. - pub(crate) dip_proof: - DidMerkleProof, - /// The cross-chain DID signature. - pub(crate) signature: TimeBoundDidSignature, -} - -impl< - StateRoot, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > - DipDidProofWithVerifiedRelayStateRoot< - StateRoot, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > -{ - /// Verifies the DIP commitment part of the state proof for the subject with - /// the given identifier. - /// - /// The generic types indicate the following: - /// * `ParachainHasher`: The hashing algorithm used to hash storage on the - /// parachain. - /// * `ProviderRuntime`: The provider runtime definition. - #[allow(clippy::type_complexity)] - pub fn verify_dip_commitment_proof_for_subject( - self, - subject: &ProviderRuntime::Identifier, - ) -> Result< - DipDidProofWithVerifiedSubjectCommitment< - IdentityCommitmentOf, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - >, - Error, - > - where - StateRoot: Ord, - ParachainHasher: Hash, - ProviderRuntime: pallet_dip_provider::Config, - IdentityCommitmentOf: BenchmarkDefault, - { - let dip_commitment_storage_key = - calculate_dip_identity_commitment_storage_key_for_runtime::(subject, 0); - let dip_commitment_result = - verify_storage_value_proof::<_, ParachainHasher, IdentityCommitmentOf>( - &dip_commitment_storage_key, - self.state_root, - self.dip_commitment_proof.0, - ); - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - let dip_commitment = dip_commitment_result.unwrap_or_default(); - } else { - let dip_commitment = dip_commitment_result.map_err(Error::DipCommitmentMerkleProof)?; - } - } - Ok(DipDidProofWithVerifiedSubjectCommitment { - dip_commitment, - dip_proof: self.dip_proof, - signature: self.signature, - }) - } -} - -/// A DIP proof that has had the relaychain state and the DIP commitment -/// verified for the provided relaychain block number. -/// -/// The generic types indicate the following: -/// * `Commitment`: The DIP identity commitment type configured by the KILT -/// chain. -/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. -/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. -/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. -/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. -/// * `KiltLinkableAccountId`: The linkable account ID type configured by the -/// KILT chain. -/// * `ConsumerBlockNumber`: The `BlockNumber` definition of the consumer -/// parachain. -#[derive(Debug)] -pub struct DipDidProofWithVerifiedSubjectCommitment< - Commitment, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, -> { - /// The verified DIP identity commitment. - pub(crate) dip_commitment: Commitment, - /// The Merkle proof of the subject's DID details. - pub(crate) dip_proof: - DidMerkleProof, - /// The cross-chain DID signature. - pub(crate) signature: TimeBoundDidSignature, -} - -impl< - Commitment, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > - DipDidProofWithVerifiedSubjectCommitment< - Commitment, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > -{ - pub fn new( - dip_commitment: Commitment, - dip_proof: DidMerkleProof, - signature: TimeBoundDidSignature, - ) -> Self { - Self { - dip_commitment, - dip_proof, - signature, - } - } -} +mod input_common; +mod output_common; +mod provider_state; +mod relay_state; -impl< - Commitment, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > - DipDidProofWithVerifiedSubjectCommitment< - Commitment, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > where - KiltDidKeyId: Encode, - KiltAccountId: Encode, - KiltBlockNumber: Encode, - KiltWeb3Name: Encode, - KiltLinkableAccountId: Encode, -{ - /// Verifies the Merkle proof of the subject's DID details. - /// - /// The generic types indicate the following: - /// * `DidMerkleHasher`: The hashing algorithm used to merkleize the DID - /// details. - /// * `MAX_REVEALED_LEAVES_COUNT`: The maximum number of leaves revealable - /// in the proof. - pub fn verify_dip_proof( - self, - ) -> Result< - DipRevealedDetailsAndUnverifiedDidSignature< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - MAX_REVEALED_LEAVES_COUNT, - >, - Error, - > - where - DidMerkleHasher: Hash, - { - ensure!( - self.dip_proof.revealed.len() <= MAX_REVEALED_LEAVES_COUNT.saturated_into(), - Error::TooManyLeavesRevealed - ); - - let proof_leaves_key_value_pairs = self - .dip_proof - .revealed - .iter() - .map(|revealed_leaf| (revealed_leaf.encoded_key(), Some(revealed_leaf.encoded_value()))) - .collect::>(); - let proof_verification_result = verify_trie_proof::, _, _, _>( - &self.dip_commitment, - self.dip_proof.blinded.as_slice(), - proof_leaves_key_value_pairs.as_slice(), - ); - - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - drop(proof_verification_result); - } else { - proof_verification_result.map_err(|_| Error::InvalidDidMerkleProof)?; - } - } - let revealed_leaves = BoundedVec::try_from(self.dip_proof.revealed).map_err(|_| { - log::error!("Should not fail to construct BoundedVec since bounds were checked before."); - Error::Internal - })?; - - Ok(DipRevealedDetailsAndUnverifiedDidSignature { - revealed_leaves, - signature: self.signature, - }) - } -} - -/// A DIP proof whose information has been verified but that contains a -/// cross-chain [`TimeBoundDidSignature`] that still needs verification. -/// -/// The generic types indicate the following: -/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. -/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. -/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. -/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. -/// * `KiltLinkableAccountId`: The linkable account ID type configured by the -/// KILT chain. -/// * `ConsumerBlockNumber`: The `BlockNumber` definition of the consumer -/// parachain. -/// * `MAX_REVEALED_LEAVES_COUNT`: The maximum number of leaves revealable in -/// the proof. -#[derive(Debug)] -pub struct DipRevealedDetailsAndUnverifiedDidSignature< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - const MAX_REVEALED_LEAVES_COUNT: u32, -> { - /// The parts of the subject's DID details revealed in the DIP proof. - pub(crate) revealed_leaves: BoundedVec< - RevealedDidMerkleProofLeaf, - ConstU32, - >, - /// The cross-chain DID signature. - pub(crate) signature: TimeBoundDidSignature, -} - -impl< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - const MAX_REVEALED_LEAVES_COUNT: u32, - > - DipRevealedDetailsAndUnverifiedDidSignature< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - MAX_REVEALED_LEAVES_COUNT, - > where - ConsumerBlockNumber: PartialOrd, -{ - /// Verifies that the DIP proof signature is anchored to a block that has - /// not passed on the consumer chain. - pub fn verify_signature_time( - self, - block_number: &ConsumerBlockNumber, - ) -> Result< - DipRevealedDetailsAndVerifiedDidSignatureFreshness< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - MAX_REVEALED_LEAVES_COUNT, - >, - Error, - > { - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - let _ = self.signature.valid_until >= *block_number; - } else { - frame_support::ensure!(self.signature.valid_until >= *block_number, Error::InvalidSignatureTime); - } - } - Ok(DipRevealedDetailsAndVerifiedDidSignatureFreshness { - revealed_leaves: self.revealed_leaves, - signature: self.signature.signature, - }) - } -} - -/// A DIP proof whose information has been verified and whose signature has been -/// verified not to be expired, but that yet does not contain information as to -/// which of the revealed keys has generated the signature. -/// -/// The generic types indicate the following: -/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. -/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. -/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. -/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. -/// * `KiltLinkableAccountId`: The linkable account ID type configured by the -/// KILT chain. -/// * `MAX_REVEALED_LEAVES_COUNT`: The maximum number of leaves revealable in -/// the proof. -#[derive(Debug)] -pub struct DipRevealedDetailsAndVerifiedDidSignatureFreshness< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - const MAX_REVEALED_LEAVES_COUNT: u32, -> { - /// The parts of the subject's DID details revealed in the DIP proof. - pub(crate) revealed_leaves: BoundedVec< - RevealedDidMerkleProofLeaf, - ConstU32, - >, - /// The cross-chain DID signature without time information. - pub(crate) signature: DidSignature, -} - -impl< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - const MAX_REVEALED_LEAVES_COUNT: u32, - > - DipRevealedDetailsAndVerifiedDidSignatureFreshness< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - MAX_REVEALED_LEAVES_COUNT, - > where - KiltDidKeyId: BenchmarkDefault, - KiltBlockNumber: BenchmarkDefault, -{ - /// Iterates over the revealed DID leafs to find the one that generated a - /// valid signature for the provided payload. - pub fn retrieve_signing_leaf_for_payload( - self, - payload: &[u8], - ) -> Result< - DipOriginInfo< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - MAX_REVEALED_LEAVES_COUNT, - >, - Error, - > { - let revealed_verification_keys = self.revealed_leaves.iter().filter(|leaf| { - matches!( - leaf, - RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey { - relationship: DidKeyRelationship::Verification(_), - .. - }) - ) - }); - let maybe_signing_key_index = revealed_verification_keys - .enumerate() - .find(|(_, revealed_verification_key)| { - let RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey { - details: - DidPublicKeyDetails { - key: DidPublicKey::PublicVerificationKey(verification_key), - .. - }, - .. - }) = revealed_verification_key - else { - return false; - }; - verification_key.verify_signature(payload, &self.signature).is_ok() - }) - .map(|(index, _)| u32::saturated_from(index)); - - let signing_key_entry = if let Some(index) = maybe_signing_key_index { - (self.revealed_leaves, index) - } else { - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - return Ok(DipOriginInfo::default()); - } else { - return Err(Error::InvalidDidKeyRevealed); - } - } - }; - - Ok(DipOriginInfo { - revealed_leaves: signing_key_entry.0, - signing_leaf_index: signing_key_entry.1, - }) - } -} - -/// Information, available as an origin, after the whole DIP proof has been -/// verified. -#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo, MaxEncodedLen)] -pub struct DipOriginInfo< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - const MAX_REVEALED_LEAVES_COUNT: u32, -> { - /// The parts of the subject's DID details revealed in the DIP proof. - revealed_leaves: BoundedVec< - RevealedDidMerkleProofLeaf, - ConstU32, - >, - /// The index of the signing leaf from the vector above, - signing_leaf_index: u32, -} - -impl< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - const MAX_REVEALED_LEAVES_COUNT: u32, - > - DipOriginInfo< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - MAX_REVEALED_LEAVES_COUNT, - > -{ - /// Returns an iterator over the revealed DID leaves. - pub fn iter_leaves( - &self, - ) -> impl Iterator< - Item = &RevealedDidMerkleProofLeaf< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - >, - > { - self.revealed_leaves.iter() - } - - /// Returns a reference to the leaf that signed the cross-chain operation. - /// This operation should never fail, so the only error it returns is an - /// `Error::Internal` which, anyway, should never happen. - pub fn get_signing_leaf(&self) -> Result<&RevealedDidKey, Error> { - let leaf = &self - .revealed_leaves - .get(usize::saturated_from(self.signing_leaf_index)) - .ok_or_else(|| { - log::error!("Should never fail to retrieve the signing leaf."); - Error::Internal - })?; - let RevealedDidMerkleProofLeaf::DidKey(did_key) = leaf else { - log::error!("Should never fail to convert the signing leaf to a DID Key leaf."); - return Err(Error::Internal); - }; - Ok(did_key) - } -} - -#[cfg(feature = "runtime-benchmarks")] -impl< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - const MAX_REVEALED_LEAVES_COUNT: u32, - > Default - for DipOriginInfo< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - MAX_REVEALED_LEAVES_COUNT, - > where - KiltDidKeyId: BenchmarkDefault, - KiltBlockNumber: BenchmarkDefault, -{ - fn default() -> Self { - let default_keys = sp_std::vec![RevealedDidKey { - id: KiltDidKeyId::default(), - details: DidPublicKeyDetails { - key: did::did_details::DidVerificationKey::Ed25519(sp_core::ed25519::Public::from_raw([0u8; 32])) - .into(), - block_number: KiltBlockNumber::default() - }, - relationship: DidVerificationKeyRelationship::Authentication.into() - } - .into()]; - let bounded_keys = default_keys - .try_into() - // To avoid requiring types to implement `Debug`. - .map_err(|_| "Should not fail to convert single element to a BoundedVec.") - .unwrap(); - Self { - revealed_leaves: bounded_keys, - signing_leaf_index: 0u32, - } - } -} - -/// Relationship of a key to a DID Document. -#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, TypeInfo, MaxEncodedLen)] -pub enum DidKeyRelationship { - Encryption, - Verification(DidVerificationKeyRelationship), -} - -impl From for DidKeyRelationship { - fn from(value: DidVerificationKeyRelationship) -> Self { - Self::Verification(value) - } -} - -impl TryFrom for DidVerificationKeyRelationship { - type Error = (); - - fn try_from(value: DidKeyRelationship) -> Result { - if let DidKeyRelationship::Verification(rel) = value { - Ok(rel) - } else { - Err(()) - } - } -} - -/// All possible Merkle leaf types that can be revealed as part of a DIP -/// identity Merkle proof. -#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, TypeInfo, MaxEncodedLen)] -pub enum RevealedDidMerkleProofLeaf { - DidKey(RevealedDidKey), - Web3Name(RevealedWeb3Name), - LinkedAccount(RevealedAccountId), -} - -impl From> - for RevealedDidMerkleProofLeaf -{ - fn from(value: RevealedDidKey) -> Self { - Self::DidKey(value) - } -} - -impl From> - for RevealedDidMerkleProofLeaf -{ - fn from(value: RevealedWeb3Name) -> Self { - Self::Web3Name(value) - } -} - -impl From> - for RevealedDidMerkleProofLeaf -{ - fn from(value: RevealedAccountId) -> Self { - Self::LinkedAccount(value) - } -} - -#[cfg(feature = "runtime-benchmarks")] -impl Default - for RevealedDidMerkleProofLeaf -where - KeyId: Default, - BlockNumber: Default, -{ - fn default() -> Self { - RevealedDidKey { - id: KeyId::default(), - relationship: DidVerificationKeyRelationship::Authentication.into(), - details: DidPublicKeyDetails { - key: did::did_details::DidVerificationKey::Ed25519(sp_core::ed25519::Public::from_raw([0u8; 32])) - .into(), - block_number: BlockNumber::default(), - }, - } - .into() - } -} - -impl - RevealedDidMerkleProofLeaf -where - KeyId: Encode, - Web3Name: Encode, - LinkedAccountId: Encode, -{ - pub fn encoded_key(&self) -> Vec { - match self { - RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey { id, relationship, .. }) => (id, relationship).encode(), - RevealedDidMerkleProofLeaf::Web3Name(RevealedWeb3Name { web3_name, .. }) => web3_name.encode(), - RevealedDidMerkleProofLeaf::LinkedAccount(RevealedAccountId(account_id)) => account_id.encode(), - } - } -} - -impl - RevealedDidMerkleProofLeaf -where - AccountId: Encode, - BlockNumber: Encode, -{ - pub fn encoded_value(&self) -> Vec { - match self { - RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey { details, .. }) => details.encode(), - RevealedDidMerkleProofLeaf::Web3Name(RevealedWeb3Name { claimed_at, .. }) => claimed_at.encode(), - RevealedDidMerkleProofLeaf::LinkedAccount(_) => ().encode(), - } - } -} - -/// The details of a DID key after it has been successfully verified in a Merkle -/// proof. -#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, TypeInfo, MaxEncodedLen)] -pub struct RevealedDidKey { - /// The key ID, according to the provider's definition. - pub id: KeyId, - /// The key relationship to the subject's DID Document. - pub relationship: DidKeyRelationship, - /// The details of the DID Key, including its creation block number on the - /// provider chain. - pub details: DidPublicKeyDetails, -} - -/// The details of a web3name after it has been successfully verified in a -/// Merkle proof. -#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, TypeInfo, MaxEncodedLen)] -pub struct RevealedWeb3Name { - /// The web3name. - pub web3_name: Web3Name, - /// The block number on the provider chain in which it was linked to the DID - /// subject. - pub claimed_at: BlockNumber, -} - -/// The details of an account after it has been successfully verified in a -/// Merkle proof. -#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, TypeInfo, MaxEncodedLen)] -pub struct RevealedAccountId(pub AccountId); +pub use dip_subject_state::*; +pub use error::*; +pub use input_common::*; +pub use output_common::*; +pub use provider_state::*; +pub use relay_state::*; diff --git a/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs b/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs new file mode 100644 index 0000000000..c568a3966b --- /dev/null +++ b/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs @@ -0,0 +1,279 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2023 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 did::{did_details::DidPublicKeyDetails, DidVerificationKeyRelationship}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; +use sp_core::ConstU32; +use sp_runtime::{BoundedVec, SaturatedConversion}; +use sp_std::{fmt::Debug, vec::Vec}; + +use crate::Error; + +/// Information, available as an origin, after the whole DIP proof has been +/// verified. +#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo, MaxEncodedLen)] +pub struct DipOriginInfo< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + const MAX_REVEALED_LEAVES_COUNT: u32, +> { + /// The parts of the subject's DID details revealed in the DIP proof. + pub(crate) revealed_leaves: BoundedVec< + RevealedDidMerkleProofLeaf, + ConstU32, + >, + /// The index of the signing leaf from the vector above, + pub(crate) signing_leaf_index: u32, +} + +impl< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + const MAX_REVEALED_LEAVES_COUNT: u32, + > + DipOriginInfo< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + MAX_REVEALED_LEAVES_COUNT, + > +{ + /// Returns an iterator over the revealed DID leaves. + pub fn iter_leaves( + &self, + ) -> impl Iterator< + Item = &RevealedDidMerkleProofLeaf< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + >, + > { + self.revealed_leaves.iter() + } + + /// Returns a reference to the leaf that signed the cross-chain operation. + /// This operation should never fail, so the only error it returns is an + /// `Error::Internal` which, anyway, should never happen. + pub fn get_signing_leaf(&self) -> Result<&RevealedDidKey, Error> { + let leaf = &self + .revealed_leaves + .get(usize::saturated_from(self.signing_leaf_index)) + .ok_or_else(|| { + log::error!("Should never fail to retrieve the signing leaf."); + Error::Internal + })?; + let RevealedDidMerkleProofLeaf::DidKey(did_key) = leaf else { + log::error!("Should never fail to convert the signing leaf to a DID Key leaf."); + return Err(Error::Internal); + }; + Ok(did_key) + } +} + +#[cfg(feature = "runtime-benchmarks")] +impl< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + const MAX_REVEALED_LEAVES_COUNT: u32, + > Default + for DipOriginInfo< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + MAX_REVEALED_LEAVES_COUNT, + > where + KiltDidKeyId: crate::traits::BenchmarkDefault, + KiltBlockNumber: crate::traits::BenchmarkDefault, +{ + fn default() -> Self { + let default_keys = sp_std::vec![RevealedDidKey { + id: KiltDidKeyId::default(), + details: DidPublicKeyDetails { + key: did::did_details::DidVerificationKey::Ed25519(sp_core::ed25519::Public::from_raw([0u8; 32])) + .into(), + block_number: KiltBlockNumber::default() + }, + relationship: DidVerificationKeyRelationship::Authentication.into() + } + .into()]; + let bounded_keys = default_keys + .try_into() + // To avoid requiring types to implement `Debug`. + .map_err(|_| "Should not fail to convert single element to a BoundedVec.") + .unwrap(); + Self { + revealed_leaves: bounded_keys, + signing_leaf_index: 0u32, + } + } +} + +/// Relationship of a key to a DID Document. +#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, TypeInfo, MaxEncodedLen)] +pub enum DidKeyRelationship { + Encryption, + Verification(DidVerificationKeyRelationship), +} + +impl From for DidKeyRelationship { + fn from(value: DidVerificationKeyRelationship) -> Self { + Self::Verification(value) + } +} + +impl TryFrom for DidVerificationKeyRelationship { + type Error = (); + + fn try_from(value: DidKeyRelationship) -> Result { + if let DidKeyRelationship::Verification(rel) = value { + Ok(rel) + } else { + Err(()) + } + } +} + +/// All possible Merkle leaf types that can be revealed as part of a DIP +/// identity Merkle proof. +#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, TypeInfo, MaxEncodedLen)] +pub enum RevealedDidMerkleProofLeaf { + DidKey(RevealedDidKey), + Web3Name(RevealedWeb3Name), + LinkedAccount(RevealedAccountId), +} + +impl From> + for RevealedDidMerkleProofLeaf +{ + fn from(value: RevealedDidKey) -> Self { + Self::DidKey(value) + } +} + +impl From> + for RevealedDidMerkleProofLeaf +{ + fn from(value: RevealedWeb3Name) -> Self { + Self::Web3Name(value) + } +} + +impl From> + for RevealedDidMerkleProofLeaf +{ + fn from(value: RevealedAccountId) -> Self { + Self::LinkedAccount(value) + } +} + +#[cfg(feature = "runtime-benchmarks")] +impl Default + for RevealedDidMerkleProofLeaf +where + KeyId: Default, + BlockNumber: Default, +{ + fn default() -> Self { + RevealedDidKey { + id: KeyId::default(), + relationship: DidVerificationKeyRelationship::Authentication.into(), + details: DidPublicKeyDetails { + key: did::did_details::DidVerificationKey::Ed25519(sp_core::ed25519::Public::from_raw([0u8; 32])) + .into(), + block_number: BlockNumber::default(), + }, + } + .into() + } +} + +impl + RevealedDidMerkleProofLeaf +where + KeyId: Encode, + Web3Name: Encode, + LinkedAccountId: Encode, +{ + pub fn encoded_key(&self) -> Vec { + match self { + RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey { id, relationship, .. }) => (id, relationship).encode(), + RevealedDidMerkleProofLeaf::Web3Name(RevealedWeb3Name { web3_name, .. }) => web3_name.encode(), + RevealedDidMerkleProofLeaf::LinkedAccount(RevealedAccountId(account_id)) => account_id.encode(), + } + } +} + +impl + RevealedDidMerkleProofLeaf +where + AccountId: Encode, + BlockNumber: Encode, +{ + pub fn encoded_value(&self) -> Vec { + match self { + RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey { details, .. }) => details.encode(), + RevealedDidMerkleProofLeaf::Web3Name(RevealedWeb3Name { claimed_at, .. }) => claimed_at.encode(), + RevealedDidMerkleProofLeaf::LinkedAccount(_) => ().encode(), + } + } +} + +/// The details of a DID key after it has been successfully verified in a Merkle +/// proof. +#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, TypeInfo, MaxEncodedLen)] +pub struct RevealedDidKey { + /// The key ID, according to the provider's definition. + pub id: KeyId, + /// The key relationship to the subject's DID Document. + pub relationship: DidKeyRelationship, + /// The details of the DID Key, including its creation block number on the + /// provider chain. + pub details: DidPublicKeyDetails, +} + +/// The details of a web3name after it has been successfully verified in a +/// Merkle proof. +#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, TypeInfo, MaxEncodedLen)] +pub struct RevealedWeb3Name { + /// The web3name. + pub web3_name: Web3Name, + /// The block number on the provider chain in which it was linked to the DID + /// subject. + pub claimed_at: BlockNumber, +} + +/// The details of an account after it has been successfully verified in a +/// Merkle proof. +#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, TypeInfo, MaxEncodedLen)] +pub struct RevealedAccountId(pub AccountId); diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state.rs new file mode 100644 index 0000000000..692390267e --- /dev/null +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state.rs @@ -0,0 +1,491 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2023 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 frame_support::ensure; +use pallet_dip_provider::IdentityCommitmentOf; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_runtime::{ + traits::{Hash, Header as HeaderT}, + BoundedVec, SaturatedConversion, +}; +use sp_std::{fmt::Debug, vec::Vec}; +use sp_trie::{verify_trie_proof, LayoutV1}; + +use crate::{ + merkle::v0::{ + dip_subject_state::DipRevealedDetailsAndUnverifiedDidSignature, + input_common::{DidMerkleProof, DipCommitmentStateProof, ProviderHeadStateProof, TimeBoundDidSignature}, + }, + state_proofs::{verify_storage_value_proof, verify_storage_value_proof_with_decoder}, + traits::{BenchmarkDefault, GetWithArg}, + utils::{ + calculate_dip_identity_commitment_storage_key_for_runtime, calculate_parachain_head_storage_key, OutputOf, + }, + Error, +}; + +/// A DIP proof submitted to a parachain consumer. +/// +/// The generic types indicate the following: +/// * `RelayBlockNumber`: The `BlockNumber` definition of the relaychain. +/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. +/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. +/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. +/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. +/// * `KiltLinkableAccountId`: The linkable account ID type configured by the +/// KILT chain. +/// * `ConsumerBlockNumber`: The `BlockNumber` definition of the consumer +/// parachain. +#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] +pub struct ParachainDipDidProof< + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, +> { + /// The state proof for the given parachain head. + pub(crate) provider_head_proof: ProviderHeadStateProof, + /// The raw state proof for the DIP commitment of the given subject. + pub(crate) dip_commitment_proof: DipCommitmentStateProof, + /// The Merkle proof of the subject's DID details. + pub(crate) dip_proof: + DidMerkleProof, + /// The cross-chain DID signature. + pub(crate) signature: TimeBoundDidSignature, +} + +#[cfg(feature = "runtime-benchmarks")] +impl< + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + Context, + > kilt_support::traits::GetWorstCase + for ParachainDipDidProof< + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > where + RelayBlockNumber: Default, + KiltDidKeyId: Default + Clone, + KiltAccountId: Clone, + KiltBlockNumber: Default + Clone, + KiltWeb3Name: Clone, + KiltLinkableAccountId: Clone, + ConsumerBlockNumber: Default, + Context: Clone, +{ + fn worst_case(context: Context) -> Self { + Self { + provider_head_proof: ProviderHeadStateProof::worst_case(context.clone()), + dip_commitment_proof: DipCommitmentStateProof::worst_case(context.clone()), + dip_proof: DidMerkleProof::worst_case(context.clone()), + signature: TimeBoundDidSignature::worst_case(context), + } + } +} + +impl< + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > + ParachainDipDidProof< + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > where + KiltBlockNumber: BenchmarkDefault, +{ + /// Verifies the head data of the state proof for the provider with the + /// given para ID and relaychain state root. + /// + /// The generic types indicate the following: + /// * `RelayHasher`: The head data hashing algorithm used by the relaychain. + /// * `ProviderHeader`: The type of the parachain header to be revealed in + /// the state proof. + #[allow(clippy::type_complexity)] + pub fn verify_provider_head_proof_with_state_root( + self, + provider_para_id: u32, + relay_state_root: &OutputOf, + ) -> Result< + DipDidProofWithVerifiedRelayStateRoot< + OutputOf, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + >, + Error, + > + where + RelayHasher: Hash, + ProviderHeader: Decode + HeaderT, Number = KiltBlockNumber>, + { + let provider_head_storage_key = calculate_parachain_head_storage_key(provider_para_id); + // TODO: Figure out why RPC call returns 2 bytes in front which we don't need + let provider_header_result = verify_storage_value_proof_with_decoder::<_, RelayHasher, ProviderHeader>( + &provider_head_storage_key, + *relay_state_root, + self.provider_head_proof.proof, + |input| { + if input.len() < 2 { + return None; + } + let mut trimmed_input = &input[2..]; + ProviderHeader::decode(&mut trimmed_input).ok() + }, + ); + cfg_if::cfg_if! { + if #[cfg(feature = "runtime-benchmarks")] { + let provider_header = provider_header_result.unwrap_or_else(|_| ProviderHeader::new(::Number::default(), ::Hash::default(), ::Hash::default(), ::Hash::default(), sp_runtime::Digest::default())); + } else { + let provider_header = provider_header_result.map_err(Error::ParaHeadMerkleProof)?; + } + } + Ok(DipDidProofWithVerifiedRelayStateRoot { + state_root: *provider_header.state_root(), + dip_commitment_proof: self.dip_commitment_proof, + dip_proof: self.dip_proof, + signature: self.signature, + }) + } + + /// Verifies the head data of the state proof for the provider with the + /// given para ID using the state root returned by the provided + /// implementation. + /// + /// The generic types indicate the following: + /// * `RelayHasher`: The hashing algorithm used on the relaychain to + /// generate the parachains head data. + /// * `StateRootStore`: The type that returns a relaychain state root given + /// a relaychain block number. + /// * `ProviderHeader`: The type of the parachain header to be revealed in + /// the state proof. + #[allow(clippy::type_complexity)] + pub fn verify_provider_head_proof( + self, + provider_para_id: u32, + ) -> Result< + DipDidProofWithVerifiedRelayStateRoot< + OutputOf, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + >, + Error, + > + where + RelayHasher: Hash, + StateRootStore: GetWithArg>>, + ProviderHeader: Decode + HeaderT, Number = KiltBlockNumber>, + { + let relay_state_root = StateRootStore::get(&self.provider_head_proof.relay_block_number); + cfg_if::cfg_if! { + if #[cfg(feature = "runtime-benchmarks")] { + let relay_state_root = relay_state_root.unwrap_or_default(); + } else { + let relay_state_root = relay_state_root.ok_or(Error::RelayStateRootNotFound)?; + } + } + self.verify_provider_head_proof_with_state_root::( + provider_para_id, + &relay_state_root, + ) + } +} + +/// A DIP proof that has had the proof header and the relaychain state verified +/// for the provided relaychain block number. +/// +/// The generic types indicate the following: +/// * `StateRoot`: The type of the relaychain state root. +/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. +/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. +/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. +/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. +/// * `KiltLinkableAccountId`: The linkable account ID type configured by the +/// KILT chain. +/// * `ConsumerBlockNumber`: The `BlockNumber` definition of the consumer +/// parachain. +#[derive(Debug)] +pub struct DipDidProofWithVerifiedRelayStateRoot< + StateRoot, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, +> { + /// The relaychain state root for the block specified in the DIP proof. + pub(crate) state_root: StateRoot, + /// The raw state proof for the DIP commitment of the given subject. + pub(crate) dip_commitment_proof: DipCommitmentStateProof, + /// The Merkle proof of the subject's DID details. + pub(crate) dip_proof: + DidMerkleProof, + /// The cross-chain DID signature. + pub(crate) signature: TimeBoundDidSignature, +} + +impl< + StateRoot, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > + DipDidProofWithVerifiedRelayStateRoot< + StateRoot, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > +{ + /// Verifies the DIP commitment part of the state proof for the subject with + /// the given identifier. + /// + /// The generic types indicate the following: + /// * `ParachainHasher`: The hashing algorithm used to hash storage on the + /// parachain. + /// * `ProviderRuntime`: The provider runtime definition. + #[allow(clippy::type_complexity)] + pub fn verify_dip_commitment_proof_for_subject( + self, + subject: &ProviderRuntime::Identifier, + ) -> Result< + DipDidProofWithVerifiedSubjectCommitment< + IdentityCommitmentOf, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + >, + Error, + > + where + StateRoot: Ord, + ParachainHasher: Hash, + ProviderRuntime: pallet_dip_provider::Config, + IdentityCommitmentOf: BenchmarkDefault, + { + let dip_commitment_storage_key = + calculate_dip_identity_commitment_storage_key_for_runtime::(subject, 0); + let dip_commitment_result = + verify_storage_value_proof::<_, ParachainHasher, IdentityCommitmentOf>( + &dip_commitment_storage_key, + self.state_root, + self.dip_commitment_proof.0, + ); + cfg_if::cfg_if! { + if #[cfg(feature = "runtime-benchmarks")] { + let dip_commitment = dip_commitment_result.unwrap_or_default(); + } else { + let dip_commitment = dip_commitment_result.map_err(Error::DipCommitmentMerkleProof)?; + } + } + Ok(DipDidProofWithVerifiedSubjectCommitment { + dip_commitment, + dip_proof: self.dip_proof, + signature: self.signature, + }) + } +} + +/// A DIP proof that has had the relaychain state and the DIP commitment +/// verified for the provided relaychain block number. +/// +/// The generic types indicate the following: +/// * `Commitment`: The DIP identity commitment type configured by the KILT +/// chain. +/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. +/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. +/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. +/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. +/// * `KiltLinkableAccountId`: The linkable account ID type configured by the +/// KILT chain. +/// * `ConsumerBlockNumber`: The `BlockNumber` definition of the consumer +/// parachain. +#[derive(Debug)] +pub struct DipDidProofWithVerifiedSubjectCommitment< + Commitment, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, +> { + /// The verified DIP identity commitment. + pub(crate) dip_commitment: Commitment, + /// The Merkle proof of the subject's DID details. + pub(crate) dip_proof: + DidMerkleProof, + /// The cross-chain DID signature. + pub(crate) signature: TimeBoundDidSignature, +} + +impl< + Commitment, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > + DipDidProofWithVerifiedSubjectCommitment< + Commitment, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > +{ + pub fn new( + dip_commitment: Commitment, + dip_proof: DidMerkleProof, + signature: TimeBoundDidSignature, + ) -> Self { + Self { + dip_commitment, + dip_proof, + signature, + } + } +} + +impl< + Commitment, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > + DipDidProofWithVerifiedSubjectCommitment< + Commitment, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > where + KiltDidKeyId: Encode, + KiltAccountId: Encode, + KiltBlockNumber: Encode, + KiltWeb3Name: Encode, + KiltLinkableAccountId: Encode, +{ + /// Verifies the Merkle proof of the subject's DID details. + /// + /// The generic types indicate the following: + /// * `DidMerkleHasher`: The hashing algorithm used to merkleize the DID + /// details. + /// * `MAX_REVEALED_LEAVES_COUNT`: The maximum number of leaves revealable + /// in the proof. + pub fn verify_dip_proof( + self, + ) -> Result< + DipRevealedDetailsAndUnverifiedDidSignature< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + MAX_REVEALED_LEAVES_COUNT, + >, + Error, + > + where + DidMerkleHasher: Hash, + { + ensure!( + self.dip_proof.revealed.len() <= MAX_REVEALED_LEAVES_COUNT.saturated_into(), + Error::TooManyLeavesRevealed + ); + + let proof_leaves_key_value_pairs = self + .dip_proof + .revealed + .iter() + .map(|revealed_leaf| (revealed_leaf.encoded_key(), Some(revealed_leaf.encoded_value()))) + .collect::>(); + let proof_verification_result = verify_trie_proof::, _, _, _>( + &self.dip_commitment, + self.dip_proof.blinded.as_slice(), + proof_leaves_key_value_pairs.as_slice(), + ); + + cfg_if::cfg_if! { + if #[cfg(feature = "runtime-benchmarks")] { + drop(proof_verification_result); + } else { + proof_verification_result.map_err(|_| Error::InvalidDidMerkleProof)?; + } + } + let revealed_leaves = BoundedVec::try_from(self.dip_proof.revealed).map_err(|_| { + log::error!("Should not fail to construct BoundedVec since bounds were checked before."); + Error::Internal + })?; + + Ok(DipRevealedDetailsAndUnverifiedDidSignature { + revealed_leaves, + signature: self.signature, + }) + } +} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state.rs b/crates/kilt-dip-primitives/src/merkle/v0/relay_state.rs new file mode 100644 index 0000000000..ff1a1ca2ba --- /dev/null +++ b/crates/kilt-dip-primitives/src/merkle/v0/relay_state.rs @@ -0,0 +1,246 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2023 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 parity_scale_codec::{Codec, Decode, Encode}; +use scale_info::TypeInfo; +use sp_core::U256; +use sp_runtime::{ + generic::Header, + traits::{AtLeast32BitUnsigned, Hash, Header as HeaderT, MaybeDisplay, Member}, +}; + +use crate::{ + merkle::v0::{ + input_common::{DidMerkleProof, DipCommitmentStateProof, ProviderHeadStateProof, TimeBoundDidSignature}, + provider_state::{DipDidProofWithVerifiedRelayStateRoot, ParachainDipDidProof}, + }, + traits::{BenchmarkDefault, GetWithArg}, + utils::OutputOf, + Error, +}; + +/// A DIP proof submitted to a relaychain consumer. +/// +/// The generic types indicate the following: +/// * `RelayBlockNumber`: The `BlockNumber` definition of the relaychain. +/// * `RelayHasher`: The hashing algorithm used by the relaychain. +/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. +/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. +/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. +/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. +/// * `KiltLinkableAccountId`: The linkable account ID type configured by the +/// KILT chain. +#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] +pub struct RelayDipDidProof< + RelayBlockNumber: Copy + Into + TryFrom, + RelayHasher: Hash, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, +> { + /// The relaychain header for the relaychain block specified in the + /// `provider_head_proof`. + pub(crate) relay_header: Header, + /// The state proof for the given parachain head. + pub(crate) provider_head_proof: ProviderHeadStateProof, + /// The raw state proof for the DIP commitment of the given subject. + pub(crate) dip_commitment_proof: DipCommitmentStateProof, + /// The Merkle proof of the subject's DID details. + pub(crate) dip_proof: + DidMerkleProof, + /// The cross-chain DID signature. + pub(crate) signature: TimeBoundDidSignature, +} + +impl< + RelayBlockNumber: Member + sp_std::hash::Hash + Copy + MaybeDisplay + AtLeast32BitUnsigned + Codec + Into + TryFrom, + RelayHasher: Hash, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > + RelayDipDidProof< + RelayBlockNumber, + RelayHasher, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > +{ + /// Verifies the relaychain part of the state proof using the provided block + /// hash. + #[allow(clippy::type_complexity)] + pub fn verify_relay_header_with_block_hash( + self, + block_hash: &OutputOf, + ) -> Result< + RelayDipDidProofWithVerifiedRelayStateRoot< + OutputOf, + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + >, + Error, + > { + if block_hash != &self.relay_header.hash() { + return Err(Error::InvalidRelayHeader); + } + + Ok(RelayDipDidProofWithVerifiedRelayStateRoot { + relay_state_root: self.relay_header.state_root, + provider_head_proof: self.provider_head_proof, + dip_commitment_proof: self.dip_commitment_proof, + dip_proof: self.dip_proof, + signature: self.signature, + }) + } + + /// Verifies the relaychain part of the state proof using the block hash + /// returned by the provided implementation. + /// + /// The generic types indicate the following: + /// * `RelayHashStore`: The type that returns a relaychain block hash given + /// a relaychain block number. + #[allow(clippy::type_complexity)] + pub fn verify_relay_header( + self, + ) -> Result< + RelayDipDidProofWithVerifiedRelayStateRoot< + OutputOf, + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + >, + Error, + > + where + RelayHashStore: GetWithArg>>, + { + let relay_block_hash = RelayHashStore::get(&self.relay_header.number).ok_or(Error::RelayBlockNotFound)?; + self.verify_relay_header_with_block_hash(&relay_block_hash) + } +} + +/// A DIP proof submitted to a relaychain consumer that has had the proof header +/// verified against a given block hash. +/// +/// The generic types indicate the following: +/// * `StateRoot`: The type of the state root used by the relaychain. +/// * `RelayBlockNumber`: The `BlockNumber` definition of the relaychain. +/// * `KiltDidKeyId`: The DID key ID type configured by the KILT chain. +/// * `KiltAccountId`: The `AccountId` type configured by the KILT chain. +/// * `KiltBlockNumber`: The `BlockNumber` type configured by the KILT chain. +/// * `KiltWeb3Name`: The web3name type configured by the KILT chain. +/// * `KiltLinkableAccountId`: The linkable account ID type configured by the +/// KILT chain. +#[derive(Debug)] +pub struct RelayDipDidProofWithVerifiedRelayStateRoot< + StateRoot, + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, +> { + /// The verified state root for the relaychain at the block specified in the + /// proof. + pub(crate) relay_state_root: StateRoot, + /// The state proof for the given parachain head. + pub(crate) provider_head_proof: ProviderHeadStateProof, + /// The raw state proof for the DIP commitment of the given subject. + pub(crate) dip_commitment_proof: DipCommitmentStateProof, + /// The Merkle proof of the subject's DID details. + pub(crate) dip_proof: + DidMerkleProof, + /// The cross-chain DID signature. + pub(crate) signature: TimeBoundDidSignature, +} + +impl< + StateRoot, + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > + RelayDipDidProofWithVerifiedRelayStateRoot< + StateRoot, + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > where + KiltBlockNumber: BenchmarkDefault, +{ + /// Verifies the head data of the state proof for the provider with the + /// given para ID. + /// + /// The generic types indicate the following: + /// * `RelayHasher`: The head data hashing algorithm used by the relaychain. + /// * `ProviderHeader`: The type of the parachain header to be revealed in + /// the state proof. + #[allow(clippy::type_complexity)] + pub fn verify_provider_head_proof( + self, + provider_para_id: u32, + ) -> Result< + DipDidProofWithVerifiedRelayStateRoot< + OutputOf, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + RelayBlockNumber, + >, + Error, + > + where + RelayHasher: Hash, + ProviderHeader: Decode + HeaderT, Number = KiltBlockNumber>, + { + let parachain_dip_proof = ParachainDipDidProof { + provider_head_proof: self.provider_head_proof, + dip_commitment_proof: self.dip_commitment_proof, + dip_proof: self.dip_proof, + signature: self.signature, + }; + + parachain_dip_proof.verify_provider_head_proof_with_state_root::( + provider_para_id, + &self.relay_state_root, + ) + } +} diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs index 4ba160045f..55e39632f1 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs @@ -30,7 +30,7 @@ use crate::{ merkle::v0::RevealedDidKey, traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, utils::OutputOf, - DipOriginInfo, + DipOriginInfo, ParachainDipDidProof, }; pub mod v0; @@ -53,7 +53,7 @@ pub enum VersionedDipParachainStateProof< ConsumerBlockNumber, > { V0( - crate::merkle::v0::ParachainDipDidProof< + ParachainDipDidProof< RelayBlockNumber, KiltDidKeyId, KiltAccountId, @@ -95,7 +95,7 @@ impl< Context: Clone, { fn worst_case(context: Context) -> Self { - Self::V0(crate::merkle::v0::ParachainDipDidProof::worst_case(context)) + Self::V0(ParachainDipDidProof::worst_case(context)) } } From 7736cab199772fb4629a1569978237eae29b1fb3 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 26 Feb 2024 09:37:46 +0100 Subject: [PATCH 07/39] Add test stubs for proof verifier --- .../src/merkle/v0/dip_subject_state.rs | 26 ++++++ .../src/merkle/v0/provider_state.rs | 83 +++++++++++++++++++ .../src/merkle/v0/relay_state.rs | 36 ++++++++ 3 files changed, 145 insertions(+) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state.rs index efd3439aaa..ad8024896f 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state.rs @@ -115,6 +115,19 @@ impl< } } +#[cfg(test)] +mod dip_revealed_details_and_unverified_did_signature { + #[test] + fn verify_signature_time_successful() { + unimplemented!() + } + + #[test] + fn verify_signature_time_too_old() { + unimplemented!() + } +} + /// A DIP proof whose information has been verified and whose signature has been /// verified not to be expired, but that yet does not contain information as to /// which of the revealed keys has generated the signature. @@ -226,3 +239,16 @@ impl< }) } } + +#[cfg(test)] +mod dip_revealed_details_and_verified_did_signature_freshness { + #[test] + fn retrieve_signing_leaf_for_payload_successful() { + unimplemented!() + } + + #[test] + fn retrieve_signing_leaf_for_payload_no_key_present() { + unimplemented!() + } +} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state.rs index 692390267e..10ca6a597a 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state.rs @@ -236,6 +236,36 @@ impl< } } +#[cfg(test)] +mod parachain_dip_did_proof { + #[test] + fn verify_provider_head_proof_with_state_root_successful() { + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_with_state_root_wrong_relay_hasher() { + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_with_state_root_wrong_provider_header_type() { + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_with_state_root_different_storage_key() { + // Valid proof but on a different storage key than the expected one + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_with_state_root_invalid_proof() { + // Invalid proof for the given storage key + unimplemented!() + } +} + /// A DIP proof that has had the proof header and the relaychain state verified /// for the provided relaychain block number. /// @@ -341,6 +371,36 @@ impl< } } +#[cfg(test)] +mod dip_did_proof_with_verified_relay_state_root { + #[test] + fn verify_dip_commitment_proof_for_subject_successful() { + unimplemented!() + } + + #[test] + fn verify_dip_commitment_proof_for_subject_successful_wrong_provider_hasher() { + unimplemented!() + } + + #[test] + fn verify_dip_commitment_proof_for_subject_successful_wrong_provider_runtime() { + unimplemented!() + } + + #[test] + fn verify_dip_commitment_proof_for_subject_different_storage_key() { + // Valid proof but on a different storage key than the expected one + unimplemented!() + } + + #[test] + fn verify_dip_commitment_proof_for_subject_invalid_proof() { + // Invalid proof for the given storage key + unimplemented!() + } +} + /// A DIP proof that has had the relaychain state and the DIP commitment /// verified for the provided relaychain block number. /// @@ -489,3 +549,26 @@ impl< }) } } + +#[cfg(test)] +mod dip_did_proof_with_verified_subject_commitment { + #[test] + fn verify_dip_proof_successful() { + unimplemented!() + } + + #[test] + fn verify_dip_proof_wrong_merkle_hasher() { + unimplemented!() + } + + #[test] + fn verify_dip_proof_too_many_leaves() { + unimplemented!() + } + + #[test] + fn verify_dip_proof_invalid_proof() { + unimplemented!() + } +} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state.rs b/crates/kilt-dip-primitives/src/merkle/v0/relay_state.rs index ff1a1ca2ba..9c300ec5cd 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/relay_state.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/relay_state.rs @@ -148,6 +148,24 @@ impl< } } +#[cfg(test)] +mod relay_did_dip_proof { + #[test] + fn verify_relay_header_with_block_hash_successful() { + unimplemented!() + } + + #[test] + fn verify_relay_header_with_block_hash_wrong_hash() { + unimplemented!() + } + + #[test] + fn verify_relay_header_with_block_hash_wrong_header() { + unimplemented!() + } +} + /// A DIP proof submitted to a relaychain consumer that has had the proof header /// verified against a given block hash. /// @@ -244,3 +262,21 @@ impl< ) } } + +#[cfg(test)] +mod relay_dip_did_proof_with_verified_relay_state_root { + #[test] + fn verify_provider_head_proof_successful() { + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_wrong_hasher() { + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_wrong_header_type() { + unimplemented!() + } +} From 486fa844b657f70c0895563a5bf6633bd976974b Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 27 Feb 2024 07:23:34 +0100 Subject: [PATCH 08/39] Restructure verification components --- .../mod.rs} | 29 +----- .../src/merkle/v0/dip_subject_state/tests.rs | 41 ++++++++ .../mod.rs} | 86 +--------------- .../src/merkle/v0/provider_state/tests.rs | 97 +++++++++++++++++++ .../v0/{relay_state.rs => relay_state/mod.rs} | 39 +------- .../src/merkle/v0/relay_state/tests.rs | 51 ++++++++++ 6 files changed, 198 insertions(+), 145 deletions(-) rename crates/kilt-dip-primitives/src/merkle/v0/{dip_subject_state.rs => dip_subject_state/mod.rs} (93%) create mode 100644 crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs rename crates/kilt-dip-primitives/src/merkle/v0/{provider_state.rs => provider_state/mod.rs} (90%) create mode 100644 crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs rename crates/kilt-dip-primitives/src/merkle/v0/{relay_state.rs => relay_state/mod.rs} (93%) create mode 100644 crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs similarity index 93% rename from crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state.rs rename to crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs index ad8024896f..283c0d2245 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs @@ -32,6 +32,9 @@ use crate::{ Error, }; +#[cfg(test)] +mod tests; + /// A DIP proof whose information has been verified but that contains a /// cross-chain [`TimeBoundDidSignature`] that still needs verification. /// @@ -115,19 +118,6 @@ impl< } } -#[cfg(test)] -mod dip_revealed_details_and_unverified_did_signature { - #[test] - fn verify_signature_time_successful() { - unimplemented!() - } - - #[test] - fn verify_signature_time_too_old() { - unimplemented!() - } -} - /// A DIP proof whose information has been verified and whose signature has been /// verified not to be expired, but that yet does not contain information as to /// which of the revealed keys has generated the signature. @@ -239,16 +229,3 @@ impl< }) } } - -#[cfg(test)] -mod dip_revealed_details_and_verified_did_signature_freshness { - #[test] - fn retrieve_signing_leaf_for_payload_successful() { - unimplemented!() - } - - #[test] - fn retrieve_signing_leaf_for_payload_no_key_present() { - unimplemented!() - } -} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs new file mode 100644 index 0000000000..b9affc76b2 --- /dev/null +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs @@ -0,0 +1,41 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2023 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 + +mod dip_revealed_details_and_unverified_did_signature { + #[test] + fn verify_signature_time_successful() { + unimplemented!() + } + + #[test] + fn verify_signature_time_too_old() { + unimplemented!() + } +} + +mod dip_revealed_details_and_verified_did_signature_freshness { + #[test] + fn retrieve_signing_leaf_for_payload_successful() { + unimplemented!() + } + + #[test] + fn retrieve_signing_leaf_for_payload_no_key_present() { + unimplemented!() + } +} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs similarity index 90% rename from crates/kilt-dip-primitives/src/merkle/v0/provider_state.rs rename to crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs index 10ca6a597a..5d511be2a8 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs @@ -40,6 +40,9 @@ use crate::{ Error, }; +#[cfg(test)] +mod tests; + /// A DIP proof submitted to a parachain consumer. /// /// The generic types indicate the following: @@ -236,36 +239,6 @@ impl< } } -#[cfg(test)] -mod parachain_dip_did_proof { - #[test] - fn verify_provider_head_proof_with_state_root_successful() { - unimplemented!() - } - - #[test] - fn verify_provider_head_proof_with_state_root_wrong_relay_hasher() { - unimplemented!() - } - - #[test] - fn verify_provider_head_proof_with_state_root_wrong_provider_header_type() { - unimplemented!() - } - - #[test] - fn verify_provider_head_proof_with_state_root_different_storage_key() { - // Valid proof but on a different storage key than the expected one - unimplemented!() - } - - #[test] - fn verify_provider_head_proof_with_state_root_invalid_proof() { - // Invalid proof for the given storage key - unimplemented!() - } -} - /// A DIP proof that has had the proof header and the relaychain state verified /// for the provided relaychain block number. /// @@ -371,36 +344,6 @@ impl< } } -#[cfg(test)] -mod dip_did_proof_with_verified_relay_state_root { - #[test] - fn verify_dip_commitment_proof_for_subject_successful() { - unimplemented!() - } - - #[test] - fn verify_dip_commitment_proof_for_subject_successful_wrong_provider_hasher() { - unimplemented!() - } - - #[test] - fn verify_dip_commitment_proof_for_subject_successful_wrong_provider_runtime() { - unimplemented!() - } - - #[test] - fn verify_dip_commitment_proof_for_subject_different_storage_key() { - // Valid proof but on a different storage key than the expected one - unimplemented!() - } - - #[test] - fn verify_dip_commitment_proof_for_subject_invalid_proof() { - // Invalid proof for the given storage key - unimplemented!() - } -} - /// A DIP proof that has had the relaychain state and the DIP commitment /// verified for the provided relaychain block number. /// @@ -549,26 +492,3 @@ impl< }) } } - -#[cfg(test)] -mod dip_did_proof_with_verified_subject_commitment { - #[test] - fn verify_dip_proof_successful() { - unimplemented!() - } - - #[test] - fn verify_dip_proof_wrong_merkle_hasher() { - unimplemented!() - } - - #[test] - fn verify_dip_proof_too_many_leaves() { - unimplemented!() - } - - #[test] - fn verify_dip_proof_invalid_proof() { - unimplemented!() - } -} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs new file mode 100644 index 0000000000..3bbd09d62a --- /dev/null +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs @@ -0,0 +1,97 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2023 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 + +mod parachain_dip_did_proof { + #[test] + fn verify_provider_head_proof_with_state_root_successful() { + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_with_state_root_wrong_relay_hasher() { + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_with_state_root_wrong_provider_header_type() { + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_with_state_root_different_storage_key() { + // Valid proof but on a different storage key than the expected one + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_with_state_root_invalid_proof() { + // Invalid proof for the given storage key + unimplemented!() + } +} + +mod dip_did_proof_with_verified_relay_state_root { + #[test] + fn verify_dip_commitment_proof_for_subject_successful() { + unimplemented!() + } + + #[test] + fn verify_dip_commitment_proof_for_subject_successful_wrong_provider_hasher() { + unimplemented!() + } + + #[test] + fn verify_dip_commitment_proof_for_subject_successful_wrong_provider_runtime() { + unimplemented!() + } + + #[test] + fn verify_dip_commitment_proof_for_subject_different_storage_key() { + // Valid proof but on a different storage key than the expected one + unimplemented!() + } + + #[test] + fn verify_dip_commitment_proof_for_subject_invalid_proof() { + // Invalid proof for the given storage key + unimplemented!() + } +} + +mod dip_did_proof_with_verified_subject_commitment { + #[test] + fn verify_dip_proof_successful() { + unimplemented!() + } + + #[test] + fn verify_dip_proof_wrong_merkle_hasher() { + unimplemented!() + } + + #[test] + fn verify_dip_proof_too_many_leaves() { + unimplemented!() + } + + #[test] + fn verify_dip_proof_invalid_proof() { + unimplemented!() + } +} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state.rs b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs similarity index 93% rename from crates/kilt-dip-primitives/src/merkle/v0/relay_state.rs rename to crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs index 9c300ec5cd..2615a94c7e 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/relay_state.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs @@ -34,6 +34,9 @@ use crate::{ Error, }; +#[cfg(test)] +mod tests; + /// A DIP proof submitted to a relaychain consumer. /// /// The generic types indicate the following: @@ -148,24 +151,6 @@ impl< } } -#[cfg(test)] -mod relay_did_dip_proof { - #[test] - fn verify_relay_header_with_block_hash_successful() { - unimplemented!() - } - - #[test] - fn verify_relay_header_with_block_hash_wrong_hash() { - unimplemented!() - } - - #[test] - fn verify_relay_header_with_block_hash_wrong_header() { - unimplemented!() - } -} - /// A DIP proof submitted to a relaychain consumer that has had the proof header /// verified against a given block hash. /// @@ -262,21 +247,3 @@ impl< ) } } - -#[cfg(test)] -mod relay_dip_did_proof_with_verified_relay_state_root { - #[test] - fn verify_provider_head_proof_successful() { - unimplemented!() - } - - #[test] - fn verify_provider_head_proof_wrong_hasher() { - unimplemented!() - } - - #[test] - fn verify_provider_head_proof_wrong_header_type() { - unimplemented!() - } -} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs new file mode 100644 index 0000000000..72952177e7 --- /dev/null +++ b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs @@ -0,0 +1,51 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2023 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 + +mod relay_did_dip_proof { + #[test] + fn verify_relay_header_with_block_hash_successful() { + unimplemented!() + } + + #[test] + fn verify_relay_header_with_block_hash_wrong_hash() { + unimplemented!() + } + + #[test] + fn verify_relay_header_with_block_hash_wrong_header() { + unimplemented!() + } +} + +mod relay_dip_did_proof_with_verified_relay_state_root { + #[test] + fn verify_provider_head_proof_successful() { + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_wrong_hasher() { + unimplemented!() + } + + #[test] + fn verify_provider_head_proof_wrong_header_type() { + unimplemented!() + } +} From 0dad2f01b3062506ec6f04e9f88fe60f72b5e6cf Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 27 Feb 2024 09:46:14 +0100 Subject: [PATCH 09/39] relay_state unit tests --- Cargo.lock | 1 + crates/kilt-dip-primitives/Cargo.toml | 1 + .../src/merkle/v0/input_common.rs | 16 ++ .../src/merkle/v0/output_common.rs | 2 +- .../src/merkle/v0/provider_state/mod.rs | 16 +- .../src/merkle/v0/relay_state/mod.rs | 85 ++++++++- .../src/merkle/v0/relay_state/tests.rs | 178 ++++++++++++++++-- crates/kilt-dip-primitives/src/utils.rs | 2 +- 8 files changed, 277 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c294e0911..0de3ce7ab1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4644,6 +4644,7 @@ dependencies = [ "sp-state-machine", "sp-std", "sp-trie", + "spiritnet-runtime", ] [[package]] diff --git a/crates/kilt-dip-primitives/Cargo.toml b/crates/kilt-dip-primitives/Cargo.toml index e9d005fec0..292ac71ce1 100644 --- a/crates/kilt-dip-primitives/Cargo.toml +++ b/crates/kilt-dip-primitives/Cargo.toml @@ -45,6 +45,7 @@ cumulus-primitives-core.workspace = true [dev-dependencies] enum-iterator.workspace = true hex-literal.workspace = true +spiritnet-runtime = { workspace = true, features = ["std"] } sp-io = { workspace = true, features = ["std"] } [features] diff --git a/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs b/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs index 68828191cf..57480b4460 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs @@ -28,6 +28,7 @@ use crate::{merkle::v0::output_common::RevealedDidMerkleProofLeaf, utils::Bounde /// The generic types indicate the following: /// * `RelayBlockNumber`: The `BlockNumber` definition of the relaychain. #[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] +#[cfg_attr(test, derive(Default))] pub struct ProviderHeadStateProof { pub(crate) relay_block_number: RelayBlockNumber, pub(crate) proof: BoundedBlindedValue, @@ -48,6 +49,7 @@ where /// The state proof for a DIP commitment. #[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] +#[cfg_attr(test, derive(Default))] pub struct DipCommitmentStateProof(pub(crate) BoundedBlindedValue); #[cfg(feature = "runtime-benchmarks")] @@ -67,6 +69,7 @@ impl kilt_support::traits::GetWorstCase for DipCommitmentState /// * `ProviderLinkableAccountId`: The linkable account ID type configured by /// the provider. #[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] +#[cfg_attr(test, derive(Default))] pub struct DidMerkleProof< ProviderDidKeyId, ProviderAccountId, @@ -154,6 +157,19 @@ impl TimeBoundDidSignature { } } +#[cfg(test)] +impl Default for TimeBoundDidSignature +where + BlockNumber: Default, +{ + fn default() -> Self { + Self { + signature: DidSignature::Ed25519(sp_core::ed25519::Signature([0u8; 64])), + valid_until: BlockNumber::default(), + } + } +} + #[cfg(feature = "runtime-benchmarks")] impl kilt_support::traits::GetWorstCase for TimeBoundDidSignature where diff --git a/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs b/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs index c568a3966b..f71143f529 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs @@ -197,7 +197,7 @@ impl From Default for RevealedDidMerkleProofLeaf where diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs index 5d511be2a8..41c9ba77c0 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs @@ -148,7 +148,7 @@ impl< provider_para_id: u32, relay_state_root: &OutputOf, ) -> Result< - DipDidProofWithVerifiedRelayStateRoot< + DipDidProofWithVerifiedStateRoot< OutputOf, KiltDidKeyId, KiltAccountId, @@ -177,6 +177,8 @@ impl< ProviderHeader::decode(&mut trimmed_input).ok() }, ); + #[cfg(feature = "std")] + println!("{:#?}", provider_header_result); cfg_if::cfg_if! { if #[cfg(feature = "runtime-benchmarks")] { let provider_header = provider_header_result.unwrap_or_else(|_| ProviderHeader::new(::Number::default(), ::Hash::default(), ::Hash::default(), ::Hash::default(), sp_runtime::Digest::default())); @@ -184,7 +186,7 @@ impl< let provider_header = provider_header_result.map_err(Error::ParaHeadMerkleProof)?; } } - Ok(DipDidProofWithVerifiedRelayStateRoot { + Ok(DipDidProofWithVerifiedStateRoot { state_root: *provider_header.state_root(), dip_commitment_proof: self.dip_commitment_proof, dip_proof: self.dip_proof, @@ -208,7 +210,7 @@ impl< self, provider_para_id: u32, ) -> Result< - DipDidProofWithVerifiedRelayStateRoot< + DipDidProofWithVerifiedStateRoot< OutputOf, KiltDidKeyId, KiltAccountId, @@ -252,8 +254,8 @@ impl< /// KILT chain. /// * `ConsumerBlockNumber`: The `BlockNumber` definition of the consumer /// parachain. -#[derive(Debug)] -pub struct DipDidProofWithVerifiedRelayStateRoot< +#[derive(Debug, PartialEq, Eq)] +pub struct DipDidProofWithVerifiedStateRoot< StateRoot, KiltDidKeyId, KiltAccountId, @@ -262,7 +264,7 @@ pub struct DipDidProofWithVerifiedRelayStateRoot< KiltLinkableAccountId, ConsumerBlockNumber, > { - /// The relaychain state root for the block specified in the DIP proof. + /// The provider state root for the block specified in the DIP proof. pub(crate) state_root: StateRoot, /// The raw state proof for the DIP commitment of the given subject. pub(crate) dip_commitment_proof: DipCommitmentStateProof, @@ -282,7 +284,7 @@ impl< KiltLinkableAccountId, ConsumerBlockNumber, > - DipDidProofWithVerifiedRelayStateRoot< + DipDidProofWithVerifiedStateRoot< StateRoot, KiltDidKeyId, KiltAccountId, diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs index 2615a94c7e..defd64748d 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs @@ -27,11 +27,11 @@ use sp_runtime::{ use crate::{ merkle::v0::{ input_common::{DidMerkleProof, DipCommitmentStateProof, ProviderHeadStateProof, TimeBoundDidSignature}, - provider_state::{DipDidProofWithVerifiedRelayStateRoot, ParachainDipDidProof}, + provider_state::ParachainDipDidProof, }, traits::{BenchmarkDefault, GetWithArg}, utils::OutputOf, - Error, + DipDidProofWithVerifiedStateRoot, Error, }; #[cfg(test)] @@ -151,6 +151,43 @@ impl< } } +#[cfg(test)] +impl< + RelayBlockNumber: Member + sp_std::hash::Hash + Copy + MaybeDisplay + AtLeast32BitUnsigned + Codec + Into + TryFrom, + RelayHasher: Hash, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > + RelayDipDidProof< + RelayBlockNumber, + RelayHasher, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > where + RelayBlockNumber: Default, + KiltDidKeyId: Default, + KiltAccountId: Default, + KiltBlockNumber: Default, + KiltWeb3Name: Default, + KiltLinkableAccountId: Default, +{ + pub(crate) fn with_header(header: Header) -> Self { + Self { + relay_header: header, + dip_commitment_proof: Default::default(), + dip_proof: Default::default(), + provider_head_proof: Default::default(), + signature: Default::default(), + } + } +} + /// A DIP proof submitted to a relaychain consumer that has had the proof header /// verified against a given block hash. /// @@ -163,7 +200,7 @@ impl< /// * `KiltWeb3Name`: The web3name type configured by the KILT chain. /// * `KiltLinkableAccountId`: The linkable account ID type configured by the /// KILT chain. -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub struct RelayDipDidProofWithVerifiedRelayStateRoot< StateRoot, RelayBlockNumber, @@ -219,7 +256,7 @@ impl< self, provider_para_id: u32, ) -> Result< - DipDidProofWithVerifiedRelayStateRoot< + DipDidProofWithVerifiedStateRoot< OutputOf, KiltDidKeyId, KiltAccountId, @@ -247,3 +284,43 @@ impl< ) } } + +#[cfg(test)] +impl< + StateRoot, + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > + RelayDipDidProofWithVerifiedRelayStateRoot< + StateRoot, + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > where + RelayBlockNumber: Default, + KiltDidKeyId: Default, + KiltAccountId: Default, + KiltBlockNumber: Default, + KiltWeb3Name: Default, + KiltLinkableAccountId: Default, +{ + pub(crate) fn with_relay_state_root_and_provider_head_proof( + relay_state_root: StateRoot, + provider_head_proof: ProviderHeadStateProof, + ) -> Self { + Self { + relay_state_root, + provider_head_proof, + dip_commitment_proof: Default::default(), + dip_proof: Default::default(), + signature: Default::default(), + } + } +} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs index 72952177e7..078abefd25 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs @@ -17,35 +17,191 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org mod relay_did_dip_proof { + use frame_support::assert_err; + use hex_literal::hex; + use sp_core::H256; + use sp_runtime::{generic::Header, traits::BlakeTwo256, Digest, DigestItem}; + + use crate::{Error, RelayDipDidProof}; + #[test] fn verify_relay_header_with_block_hash_successful() { - unimplemented!() + // Polkadot header at block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` + let header = Header:: { + parent_hash: hex!("444340c3fdd24466307d23f2f38c4a7787b7092aa9e7e614534a4efa4a2e7e4a").into(), + number: 19_663_508, + state_root: hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(), + extrinsics_root: hex!("6784dc16f12dc55d585bb4d8dc0dd08682e1c5714e081821ac2de07df41bb9fb").into(), + digest: Digest { logs: [ + DigestItem::PreRuntime(*b"BABE", hex!("03c00000009740fa1000000000e088288be02358a7c702eee7d31fdf4bb3f47a2e24bedf8db390405bf3cca51c09f060dd63ae5632993fbc156062635eb921b75588bab688c5d2b62dc9e13e0464ceb3835c9c9806b33718282904b0dcbf2a9ce7f7b8a20f3f4696b50473e406").into()), + DigestItem::Consensus(*b"BEEF", hex!("03ea39d1df20f8a9f2509f42dc42e9868d53c5a5581a95660ca12b74d5acfd92fa").into()), + DigestItem::Seal(*b"BABE", hex!("680c6d5888043c8a468fced27d321b3d0937a6fa4961430edb5be4ee118628698a5c3a05969668bcf229dbd63d0179c92fe2242f8fecdd203a8f5dbb584c348d").into()) + ].to_vec() }, + }; + // Only interested in the header verification part, we skip everything else. + let proof = RelayDipDidProof::<_, _, (), (), (), (), ()>::with_header(header); + let proof_verification_result = proof + .verify_relay_header_with_block_hash( + &hex!("6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13").into(), + ) + .unwrap(); + assert_eq!( + proof_verification_result.relay_state_root, + hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into() + ); } #[test] fn verify_relay_header_with_block_hash_wrong_hash() { - unimplemented!() - } - - #[test] - fn verify_relay_header_with_block_hash_wrong_header() { - unimplemented!() + // Polkadot header at block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` + let header = Header:: { + parent_hash: hex!("444340c3fdd24466307d23f2f38c4a7787b7092aa9e7e614534a4efa4a2e7e4a").into(), + number: 19_663_508, + state_root: hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(), + extrinsics_root: hex!("6784dc16f12dc55d585bb4d8dc0dd08682e1c5714e081821ac2de07df41bb9fb").into(), + digest: Digest { logs: [ + DigestItem::PreRuntime(*b"BABE", hex!("03c00000009740fa1000000000e088288be02358a7c702eee7d31fdf4bb3f47a2e24bedf8db390405bf3cca51c09f060dd63ae5632993fbc156062635eb921b75588bab688c5d2b62dc9e13e0464ceb3835c9c9806b33718282904b0dcbf2a9ce7f7b8a20f3f4696b50473e406").into()), + DigestItem::Consensus(*b"BEEF", hex!("03ea39d1df20f8a9f2509f42dc42e9868d53c5a5581a95660ca12b74d5acfd92fa").into()), + DigestItem::Seal(*b"BABE", hex!("680c6d5888043c8a468fced27d321b3d0937a6fa4961430edb5be4ee118628698a5c3a05969668bcf229dbd63d0179c92fe2242f8fecdd203a8f5dbb584c348d").into()) + ].to_vec() }, + }; + let proof = RelayDipDidProof::<_, _, (), (), (), (), ()>::with_header(header); + assert_err!( + // Using a different block hash for verification + proof.verify_relay_header_with_block_hash(&H256::default()), + Error::InvalidRelayHeader + ); } } mod relay_dip_did_proof_with_verified_relay_state_root { + use frame_support::assert_err; + use frame_system::pallet_prelude::HeaderFor; + use hex_literal::hex; + use sp_core::H256; + use sp_runtime::traits::{BlakeTwo256, Keccak256}; + use spiritnet_runtime::Runtime as SpiritnetRuntime; + + use crate::{ + state_proofs::MerkleProofError, Error, ProviderHeadStateProof, RelayDipDidProofWithVerifiedRelayStateRoot, + }; + #[test] fn verify_provider_head_proof_successful() { - unimplemented!() + // Storage proof generated at Polkadot block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for + // storage key + // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000` + // (`paras::heads(2_086)`) + let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); + let provider_head_proof = ProviderHeadStateProof { + relay_block_number: 19_663_508, + proof: vec![ + hex!("560cfd6c23b92a7826080000f102e902fb1bd938b2f4fcea70641da8e64e0e11098b92b767279227cdfdc0ae9500da99d27e5f012937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56eacc28c5503a155c4d8bc7ee4797c38e212428cefff0a7ad19b28ebbab793e64080661757261204a207d0800000000056175726101017cda19117c87384aaebfd2ae546771bcfbfe7011a91119932883382cc62be3050d745c9734f422228c7c43d87e6172519019829b14b2d3b64afafb1fb7d3a683").to_vec(), + hex!("80021080f0c4027f5eba380b623a2d3382ab03961b2b7e753e62d3475a6940207db367cc80fde8c5a37120e2f1d987f5302783d22f8ac1b213c580030a7f5b15e706df6262").to_vec(), + hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), + hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), + hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() + ].into_iter().into(), + }; + // Only interested in the parachain head verification part, we skip everything + // else. + let proof = RelayDipDidProofWithVerifiedRelayStateRoot::<_, _, (), (), _, (), ()>::with_relay_state_root_and_provider_head_proof(relay_state_root, provider_head_proof); + let proof_verification_result = proof + .verify_provider_head_proof::>(2_086) + .unwrap(); + assert_eq!( + proof_verification_result.state_root, + hex!("2937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56").into() + ); + } + + #[test] + fn verify_provider_head_proof_multi_storage() { + // Storage proof generated at Polkadot block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for + // storage keys + // [`0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000`, `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c3b6ff6f7d467b87a9e8030000`] + // ([`paras::heads(2_086)`, `paras::heads(1_000)]`) + let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); + let provider_head_proof = ProviderHeadStateProof { + relay_block_number: 19_663_508, + proof: vec![ + hex!("560cfd6c23b92a7826080000f102e902fb1bd938b2f4fcea70641da8e64e0e11098b92b767279227cdfdc0ae9500da99d27e5f012937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56eacc28c5503a155c4d8bc7ee4797c38e212428cefff0a7ad19b28ebbab793e64080661757261204a207d0800000000056175726101017cda19117c87384aaebfd2ae546771bcfbfe7011a91119932883382cc62be3050d745c9734f422228c7c43d87e6172519019829b14b2d3b64afafb1fb7d3a683").to_vec(), + hex!("56ff6f7d467b87a9e80300009903910331d9f8f427be99ba3b36ad6f66c49b5448e16745fc3cbe08821204e2e94c9abe1ef65e01dc0f3c52d9aaef735eae1aa679e6c3020e993fb3eef8fab9c32cc7b55dfc85362c771d9a07e5b6cf9f8e30b67598c513ca087574ecce0b3e205eb4de8783a4630c0661757261204a207d08000000000452505352906ca2562dd3ddae0ecb7076465e223753e76792653f739d5dfb00ad76a6b3607d4a2ab00405617572610101dadcb6f606d8a71dc6d0d4d20ccc3bd67bae8816c86491b14fa899242cd872f3bf5fe9635d4414f4329a578a0627cf367dcaa3e86beca64a9aaef9afd124c701").to_vec(), + hex!("80021080f0c4027f5eba380b623a2d3382ab03961b2b7e753e62d3475a6940207db367cc80fde8c5a37120e2f1d987f5302783d22f8ac1b213c580030a7f5b15e706df6262").to_vec(), + hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), + hex!("80d510805396188100731505c3fe5f51e7d4a9c6e6e4cd2c50ff6d122f5f091a186b2f9780e69515c0c399ad09a7b5da0afb5a8bbd22c6873b69f9f2da18e26a8bd04c6e9d80d647e804958d947c20337a2ac3714b3eca41be52847542b065da3614230decab806dbb5b1913c89acb68a2e85013c4b7adf37ab010cf9b9d7346348d0ca9aafd4a80702af779edd6e8d659600cbe342947238af804d41589116a3dd7fb48905aeab18076a51b70378cbf602d939a885bbad80c94ee9325398105ec2173324bd7f59b55").to_vec(), + hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), + hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() + ].into_iter().into(), + }; + // Only interested in the parachain head verification part, we skip everything + // else. + let proof = RelayDipDidProofWithVerifiedRelayStateRoot::<_, _, (), (), _, (), ()>::with_relay_state_root_and_provider_head_proof(relay_state_root, provider_head_proof); + let proof_verification_result = proof + .verify_provider_head_proof::>(2_086) + .unwrap(); + assert_eq!( + proof_verification_result.state_root, + hex!("2937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56").into() + ); } #[test] fn verify_provider_head_proof_wrong_hasher() { - unimplemented!() + // Storage proof generated at Polkadot block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for + // storage key + // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000` + // (`paras::heads(2_086)`) + let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); + let provider_head_proof = ProviderHeadStateProof { + relay_block_number: 19_663_508, + proof: vec![ + hex!("560cfd6c23b92a7826080000f102e902fb1bd938b2f4fcea70641da8e64e0e11098b92b767279227cdfdc0ae9500da99d27e5f012937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56eacc28c5503a155c4d8bc7ee4797c38e212428cefff0a7ad19b28ebbab793e64080661757261204a207d0800000000056175726101017cda19117c87384aaebfd2ae546771bcfbfe7011a91119932883382cc62be3050d745c9734f422228c7c43d87e6172519019829b14b2d3b64afafb1fb7d3a683").to_vec(), + hex!("80021080f0c4027f5eba380b623a2d3382ab03961b2b7e753e62d3475a6940207db367cc80fde8c5a37120e2f1d987f5302783d22f8ac1b213c580030a7f5b15e706df6262").to_vec(), + hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), + hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), + hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() + ].into_iter().into(), + }; + let proof = RelayDipDidProofWithVerifiedRelayStateRoot::<_, _, (), (), _, (), ()>::with_relay_state_root_and_provider_head_proof(relay_state_root, provider_head_proof); + assert_err!( + // Using a different hasher for verification + proof.verify_provider_head_proof::>(2_086), + Error::ParaHeadMerkleProof(MerkleProofError::InvalidProof) + ); } #[test] - fn verify_provider_head_proof_wrong_header_type() { - unimplemented!() + fn verify_provider_head_proof_wrong_para_id() { + // Storage proof generated at Polkadot block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for + // storage key + // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c3b6ff6f7d467b87a9e8030000` + // (`paras::heads(1_000)`) + let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); + let provider_head_proof = ProviderHeadStateProof { + relay_block_number: 19_663_508, + proof: vec![ + hex!("56ff6f7d467b87a9e80300009903910331d9f8f427be99ba3b36ad6f66c49b5448e16745fc3cbe08821204e2e94c9abe1ef65e01dc0f3c52d9aaef735eae1aa679e6c3020e993fb3eef8fab9c32cc7b55dfc85362c771d9a07e5b6cf9f8e30b67598c513ca087574ecce0b3e205eb4de8783a4630c0661757261204a207d08000000000452505352906ca2562dd3ddae0ecb7076465e223753e76792653f739d5dfb00ad76a6b3607d4a2ab00405617572610101dadcb6f606d8a71dc6d0d4d20ccc3bd67bae8816c86491b14fa899242cd872f3bf5fe9635d4414f4329a578a0627cf367dcaa3e86beca64a9aaef9afd124c701").to_vec(), + hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), + hex!("80d510805396188100731505c3fe5f51e7d4a9c6e6e4cd2c50ff6d122f5f091a186b2f9780e69515c0c399ad09a7b5da0afb5a8bbd22c6873b69f9f2da18e26a8bd04c6e9d80d647e804958d947c20337a2ac3714b3eca41be52847542b065da3614230decab806dbb5b1913c89acb68a2e85013c4b7adf37ab010cf9b9d7346348d0ca9aafd4a80702af779edd6e8d659600cbe342947238af804d41589116a3dd7fb48905aeab18076a51b70378cbf602d939a885bbad80c94ee9325398105ec2173324bd7f59b55").to_vec(), + hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), + hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() + ].into_iter().into(), + }; + let proof = RelayDipDidProofWithVerifiedRelayStateRoot::<_, _, (), (), _, (), ()>::with_relay_state_root_and_provider_head_proof(relay_state_root, provider_head_proof); + assert_err!( + proof.verify_provider_head_proof::>(2_086), + Error::ParaHeadMerkleProof(MerkleProofError::InvalidProof) + ); } } diff --git a/crates/kilt-dip-primitives/src/utils.rs b/crates/kilt-dip-primitives/src/utils.rs index 7d71fb9cc7..e53b8f8e05 100644 --- a/crates/kilt-dip-primitives/src/utils.rs +++ b/crates/kilt-dip-primitives/src/utils.rs @@ -72,7 +72,7 @@ where } } -#[cfg(feature = "runtime-benchmarks")] +#[cfg(any(test, feature = "runtime-benchmarks"))] impl Default for BoundedBlindedValue where T: Default + Clone, From 5afafa43584795835ef1d4097e39d24575e97574 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 27 Feb 2024 09:57:21 +0100 Subject: [PATCH 10/39] Update test stubs names --- .../src/merkle/v0/provider_state/mod.rs | 2 -- .../src/merkle/v0/provider_state/tests.rs | 17 +++++++++++------ .../src/merkle/v0/relay_state/tests.rs | 6 ++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs index 41c9ba77c0..0beae19669 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs @@ -177,8 +177,6 @@ impl< ProviderHeader::decode(&mut trimmed_input).ok() }, ); - #[cfg(feature = "std")] - println!("{:#?}", provider_header_result); cfg_if::cfg_if! { if #[cfg(feature = "runtime-benchmarks")] { let provider_header = provider_header_result.unwrap_or_else(|_| ProviderHeader::new(::Number::default(), ::Hash::default(), ::Hash::default(), ::Hash::default(), sp_runtime::Digest::default())); diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs index 3bbd09d62a..a6cadeae80 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs @@ -23,17 +23,17 @@ mod parachain_dip_did_proof { } #[test] - fn verify_provider_head_proof_with_state_root_wrong_relay_hasher() { + fn verify_provider_head_proof_with_state_root_multi_storage() { unimplemented!() } #[test] - fn verify_provider_head_proof_with_state_root_wrong_provider_header_type() { + fn verify_provider_head_proof_with_state_root_wrong_relay_hasher() { unimplemented!() } #[test] - fn verify_provider_head_proof_with_state_root_different_storage_key() { + fn verify_provider_head_proof_with_state_root_wrong_para_id() { // Valid proof but on a different storage key than the expected one unimplemented!() } @@ -52,17 +52,22 @@ mod dip_did_proof_with_verified_relay_state_root { } #[test] - fn verify_dip_commitment_proof_for_subject_successful_wrong_provider_hasher() { + fn verify_dip_commitment_proof_for_subject_multi_storage() { + unimplemented!() + } + + #[test] + fn verify_dip_commitment_proof_for_subject_wrong_provider_hasher() { unimplemented!() } #[test] - fn verify_dip_commitment_proof_for_subject_successful_wrong_provider_runtime() { + fn verify_dip_commitment_proof_for_subject_wrong_provider_runtime() { unimplemented!() } #[test] - fn verify_dip_commitment_proof_for_subject_different_storage_key() { + fn verify_dip_commitment_proof_for_subject_different_subject() { // Valid proof but on a different storage key than the expected one unimplemented!() } diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs index 078abefd25..34bb0983c6 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs @@ -204,4 +204,10 @@ mod relay_dip_did_proof_with_verified_relay_state_root { Error::ParaHeadMerkleProof(MerkleProofError::InvalidProof) ); } + + #[test] + fn verify_provider_head_proof_invalid_proof() { + // Invalid proof for the given storage key + unimplemented!() + } } From 767f091d1ce61dd320cc5d447fbd423adb19ee41 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 27 Feb 2024 12:13:07 +0100 Subject: [PATCH 11/39] Add unit test case for invalid proof for relay_state --- .../src/merkle/v0/relay_state/tests.rs | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs index 34bb0983c6..820848c442 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs @@ -207,7 +207,28 @@ mod relay_dip_did_proof_with_verified_relay_state_root { #[test] fn verify_provider_head_proof_invalid_proof() { - // Invalid proof for the given storage key - unimplemented!() + // Storage proof generated at Polkadot block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for + // storage key + // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000` + // (`paras::heads(2_086)`) + let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); + let provider_head_proof = ProviderHeadStateProof { + relay_block_number: 19_663_508, + // Last proof component removed + proof: vec![ + hex!("560cfd6c23b92a7826080000f102e902fb1bd938b2f4fcea70641da8e64e0e11098b92b767279227cdfdc0ae9500da99d27e5f012937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56eacc28c5503a155c4d8bc7ee4797c38e212428cefff0a7ad19b28ebbab793e64080661757261204a207d0800000000056175726101017cda19117c87384aaebfd2ae546771bcfbfe7011a91119932883382cc62be3050d745c9734f422228c7c43d87e6172519019829b14b2d3b64afafb1fb7d3a683").to_vec(), + hex!("80021080f0c4027f5eba380b623a2d3382ab03961b2b7e753e62d3475a6940207db367cc80fde8c5a37120e2f1d987f5302783d22f8ac1b213c580030a7f5b15e706df6262").to_vec(), + hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), + hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), + // hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() + ].into_iter().into(), + }; + let proof = RelayDipDidProofWithVerifiedRelayStateRoot::<_, _, (), (), _, (), ()>::with_relay_state_root_and_provider_head_proof(relay_state_root, provider_head_proof); + assert_err!( + proof.verify_provider_head_proof::>(2_086), + Error::ParaHeadMerkleProof(MerkleProofError::InvalidProof) + ); } } From 3c2919f41737c876ef2a577a44bc6ab62d424d29 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 27 Feb 2024 12:38:03 +0100 Subject: [PATCH 12/39] Add unit tests for parachain_dip_did_proof --- .../src/merkle/v0/provider_state/mod.rs | 36 ++++ .../src/merkle/v0/provider_state/tests.rs | 159 +++++++++++++++++- 2 files changed, 188 insertions(+), 7 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs index 0beae19669..d0fc3233c9 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs @@ -115,6 +115,42 @@ impl< } } +#[cfg(test)] +impl< + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > + ParachainDipDidProof< + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > where + KiltDidKeyId: Default, + KiltAccountId: Default, + KiltBlockNumber: Default, + KiltWeb3Name: Default, + KiltLinkableAccountId: Default, + ConsumerBlockNumber: Default, +{ + pub(crate) fn with_provider_head_proof(provider_head_proof: ProviderHeadStateProof) -> Self { + Self { + provider_head_proof, + dip_commitment_proof: Default::default(), + dip_proof: Default::default(), + signature: Default::default(), + } + } +} + impl< RelayBlockNumber, KiltDidKeyId, diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs index a6cadeae80..b6b9a09cb7 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs @@ -16,32 +16,177 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org +// These test cases are, for now, the same as the ones in +// [`super::relay_state::relay_dip_did_proof_with_verified_relay_state_root`], +// since the functions in there are a wrapper for functions in here. +// Nevertheless, these two components can diverge in the future. mod parachain_dip_did_proof { + use frame_support::assert_err; + use frame_system::pallet_prelude::HeaderFor; + use hex_literal::hex; + use sp_core::H256; + use sp_runtime::traits::{BlakeTwo256, Keccak256}; + use spiritnet_runtime::Runtime as SpiritnetRuntime; + + use crate::{state_proofs::MerkleProofError, Error, ParachainDipDidProof, ProviderHeadStateProof}; + #[test] fn verify_provider_head_proof_with_state_root_successful() { - unimplemented!() + // Storage proof generated at Polkadot block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for + // storage key + // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000` + // (`paras::heads(2_086)`) + let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); + let provider_head_proof = ProviderHeadStateProof { + relay_block_number: 19_663_508, + proof: vec![ + hex!("560cfd6c23b92a7826080000f102e902fb1bd938b2f4fcea70641da8e64e0e11098b92b767279227cdfdc0ae9500da99d27e5f012937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56eacc28c5503a155c4d8bc7ee4797c38e212428cefff0a7ad19b28ebbab793e64080661757261204a207d0800000000056175726101017cda19117c87384aaebfd2ae546771bcfbfe7011a91119932883382cc62be3050d745c9734f422228c7c43d87e6172519019829b14b2d3b64afafb1fb7d3a683").to_vec(), + hex!("80021080f0c4027f5eba380b623a2d3382ab03961b2b7e753e62d3475a6940207db367cc80fde8c5a37120e2f1d987f5302783d22f8ac1b213c580030a7f5b15e706df6262").to_vec(), + hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), + hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), + hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() + ].into_iter().into(), + }; + // Only interested in the parachain head verification part, we skip everything + // else. + let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); + let proof_verification_result = proof + .verify_provider_head_proof_with_state_root::>( + 2_086, + &relay_state_root, + ) + .unwrap(); + assert_eq!( + proof_verification_result.state_root, + hex!("2937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56").into() + ); } #[test] fn verify_provider_head_proof_with_state_root_multi_storage() { - unimplemented!() + // Storage proof generated at Polkadot block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for + // storage keys + // [`0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000`, `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c3b6ff6f7d467b87a9e8030000`] + // ([`paras::heads(2_086)`, `paras::heads(1_000)]`) + let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); + let provider_head_proof = ProviderHeadStateProof { + relay_block_number: 19_663_508, + proof: vec![ + hex!("560cfd6c23b92a7826080000f102e902fb1bd938b2f4fcea70641da8e64e0e11098b92b767279227cdfdc0ae9500da99d27e5f012937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56eacc28c5503a155c4d8bc7ee4797c38e212428cefff0a7ad19b28ebbab793e64080661757261204a207d0800000000056175726101017cda19117c87384aaebfd2ae546771bcfbfe7011a91119932883382cc62be3050d745c9734f422228c7c43d87e6172519019829b14b2d3b64afafb1fb7d3a683").to_vec(), + hex!("56ff6f7d467b87a9e80300009903910331d9f8f427be99ba3b36ad6f66c49b5448e16745fc3cbe08821204e2e94c9abe1ef65e01dc0f3c52d9aaef735eae1aa679e6c3020e993fb3eef8fab9c32cc7b55dfc85362c771d9a07e5b6cf9f8e30b67598c513ca087574ecce0b3e205eb4de8783a4630c0661757261204a207d08000000000452505352906ca2562dd3ddae0ecb7076465e223753e76792653f739d5dfb00ad76a6b3607d4a2ab00405617572610101dadcb6f606d8a71dc6d0d4d20ccc3bd67bae8816c86491b14fa899242cd872f3bf5fe9635d4414f4329a578a0627cf367dcaa3e86beca64a9aaef9afd124c701").to_vec(), + hex!("80021080f0c4027f5eba380b623a2d3382ab03961b2b7e753e62d3475a6940207db367cc80fde8c5a37120e2f1d987f5302783d22f8ac1b213c580030a7f5b15e706df6262").to_vec(), + hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), + hex!("80d510805396188100731505c3fe5f51e7d4a9c6e6e4cd2c50ff6d122f5f091a186b2f9780e69515c0c399ad09a7b5da0afb5a8bbd22c6873b69f9f2da18e26a8bd04c6e9d80d647e804958d947c20337a2ac3714b3eca41be52847542b065da3614230decab806dbb5b1913c89acb68a2e85013c4b7adf37ab010cf9b9d7346348d0ca9aafd4a80702af779edd6e8d659600cbe342947238af804d41589116a3dd7fb48905aeab18076a51b70378cbf602d939a885bbad80c94ee9325398105ec2173324bd7f59b55").to_vec(), + hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), + hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() + ].into_iter().into(), + }; + // Only interested in the parachain head verification part, we skip everything + // else. + let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); + let proof_verification_result = proof + .verify_provider_head_proof_with_state_root::>( + 2_086, + &relay_state_root, + ) + .unwrap(); + assert_eq!( + proof_verification_result.state_root, + hex!("2937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56").into() + ); } #[test] fn verify_provider_head_proof_with_state_root_wrong_relay_hasher() { - unimplemented!() + // Storage proof generated at Polkadot block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for + // storage key + // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000` + // (`paras::heads(2_086)`) + let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); + let provider_head_proof = ProviderHeadStateProof { + relay_block_number: 19_663_508, + proof: vec![ + hex!("560cfd6c23b92a7826080000f102e902fb1bd938b2f4fcea70641da8e64e0e11098b92b767279227cdfdc0ae9500da99d27e5f012937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56eacc28c5503a155c4d8bc7ee4797c38e212428cefff0a7ad19b28ebbab793e64080661757261204a207d0800000000056175726101017cda19117c87384aaebfd2ae546771bcfbfe7011a91119932883382cc62be3050d745c9734f422228c7c43d87e6172519019829b14b2d3b64afafb1fb7d3a683").to_vec(), + hex!("80021080f0c4027f5eba380b623a2d3382ab03961b2b7e753e62d3475a6940207db367cc80fde8c5a37120e2f1d987f5302783d22f8ac1b213c580030a7f5b15e706df6262").to_vec(), + hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), + hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), + hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() + ].into_iter().into(), + }; + let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); + assert_err!( + // Using a different hasher for verification + proof.verify_provider_head_proof_with_state_root::>( + 2_086, + &relay_state_root + ), + Error::ParaHeadMerkleProof(MerkleProofError::InvalidProof) + ); } #[test] fn verify_provider_head_proof_with_state_root_wrong_para_id() { - // Valid proof but on a different storage key than the expected one - unimplemented!() + // Storage proof generated at Polkadot block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for + // storage key + // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c3b6ff6f7d467b87a9e8030000` + // (`paras::heads(1_000)`) + let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); + let provider_head_proof = ProviderHeadStateProof { + relay_block_number: 19_663_508, + proof: vec![ + hex!("56ff6f7d467b87a9e80300009903910331d9f8f427be99ba3b36ad6f66c49b5448e16745fc3cbe08821204e2e94c9abe1ef65e01dc0f3c52d9aaef735eae1aa679e6c3020e993fb3eef8fab9c32cc7b55dfc85362c771d9a07e5b6cf9f8e30b67598c513ca087574ecce0b3e205eb4de8783a4630c0661757261204a207d08000000000452505352906ca2562dd3ddae0ecb7076465e223753e76792653f739d5dfb00ad76a6b3607d4a2ab00405617572610101dadcb6f606d8a71dc6d0d4d20ccc3bd67bae8816c86491b14fa899242cd872f3bf5fe9635d4414f4329a578a0627cf367dcaa3e86beca64a9aaef9afd124c701").to_vec(), + hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), + hex!("80d510805396188100731505c3fe5f51e7d4a9c6e6e4cd2c50ff6d122f5f091a186b2f9780e69515c0c399ad09a7b5da0afb5a8bbd22c6873b69f9f2da18e26a8bd04c6e9d80d647e804958d947c20337a2ac3714b3eca41be52847542b065da3614230decab806dbb5b1913c89acb68a2e85013c4b7adf37ab010cf9b9d7346348d0ca9aafd4a80702af779edd6e8d659600cbe342947238af804d41589116a3dd7fb48905aeab18076a51b70378cbf602d939a885bbad80c94ee9325398105ec2173324bd7f59b55").to_vec(), + hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), + hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() + ].into_iter().into(), + }; + let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); + assert_err!( + proof.verify_provider_head_proof_with_state_root::>( + 2_086, + &relay_state_root + ), + Error::ParaHeadMerkleProof(MerkleProofError::InvalidProof) + ); } #[test] fn verify_provider_head_proof_with_state_root_invalid_proof() { - // Invalid proof for the given storage key - unimplemented!() + // Storage proof generated at Polkadot block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for + // storage key + // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000` + // (`paras::heads(2_086)`) + let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); + let provider_head_proof = ProviderHeadStateProof { + relay_block_number: 19_663_508, + // Last proof component removed + proof: vec![ + hex!("560cfd6c23b92a7826080000f102e902fb1bd938b2f4fcea70641da8e64e0e11098b92b767279227cdfdc0ae9500da99d27e5f012937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56eacc28c5503a155c4d8bc7ee4797c38e212428cefff0a7ad19b28ebbab793e64080661757261204a207d0800000000056175726101017cda19117c87384aaebfd2ae546771bcfbfe7011a91119932883382cc62be3050d745c9734f422228c7c43d87e6172519019829b14b2d3b64afafb1fb7d3a683").to_vec(), + hex!("80021080f0c4027f5eba380b623a2d3382ab03961b2b7e753e62d3475a6940207db367cc80fde8c5a37120e2f1d987f5302783d22f8ac1b213c580030a7f5b15e706df6262").to_vec(), + hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), + hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), + // hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() + ].into_iter().into(), + }; + let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); + assert_err!( + proof.verify_provider_head_proof_with_state_root::>( + 2_086, + &relay_state_root + ), + Error::ParaHeadMerkleProof(MerkleProofError::InvalidProof) + ); } } From 48eb1166b9ff2ff9c648c65b4f73a51f63d23cf9 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 27 Feb 2024 13:15:37 +0100 Subject: [PATCH 13/39] Unit tests for dip_revealed_details_and_unverified_did_signature complete --- .../src/merkle/v0/dip_subject_state/mod.rs | 40 ++++++++++++++++++- .../src/merkle/v0/dip_subject_state/tests.rs | 19 ++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs index 283c0d2245..7de37e7d01 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs @@ -50,6 +50,7 @@ mod tests; /// * `MAX_REVEALED_LEAVES_COUNT`: The maximum number of leaves revealable in /// the proof. #[derive(Debug)] +#[cfg_attr(test, derive(Clone))] pub struct DipRevealedDetailsAndUnverifiedDidSignature< KiltDidKeyId, KiltAccountId, @@ -118,6 +119,43 @@ impl< } } +#[cfg(test)] +impl< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + const MAX_REVEALED_LEAVES_COUNT: u32, + > + DipRevealedDetailsAndUnverifiedDidSignature< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + MAX_REVEALED_LEAVES_COUNT, + > where + KiltDidKeyId: Default, + KiltAccountId: Default, + KiltBlockNumber: Default, + KiltWeb3Name: Default, + KiltLinkableAccountId: Default, + ConsumerBlockNumber: Default, +{ + pub(crate) fn with_signature_time(valid_until: ConsumerBlockNumber) -> Self { + Self { + signature: TimeBoundDidSignature { + valid_until, + ..Default::default() + }, + revealed_leaves: Default::default(), + } + } +} + /// A DIP proof whose information has been verified and whose signature has been /// verified not to be expired, but that yet does not contain information as to /// which of the revealed keys has generated the signature. @@ -131,7 +169,7 @@ impl< /// KILT chain. /// * `MAX_REVEALED_LEAVES_COUNT`: The maximum number of leaves revealable in /// the proof. -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub struct DipRevealedDetailsAndVerifiedDidSignatureFreshness< KiltDidKeyId, KiltAccountId, diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs index b9affc76b2..43e4c3072d 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs @@ -17,14 +17,29 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org mod dip_revealed_details_and_unverified_did_signature { + use frame_support::{assert_err, assert_ok}; + + use crate::{DipRevealedDetailsAndUnverifiedDidSignature, Error}; + #[test] fn verify_signature_time_successful() { - unimplemented!() + let signature = + DipRevealedDetailsAndUnverifiedDidSignature::<(), (), (), (), (), _, 1>::with_signature_time(10u32); + assert_ok!(signature.clone().verify_signature_time(&0)); + assert_ok!(signature.clone().verify_signature_time(&1)); + assert_ok!(signature.clone().verify_signature_time(&9)); + assert_ok!(signature.verify_signature_time(&10)); } #[test] fn verify_signature_time_too_old() { - unimplemented!() + let signature = + DipRevealedDetailsAndUnverifiedDidSignature::<(), (), (), (), (), _, 1>::with_signature_time(10u32); + assert_err!( + signature.clone().verify_signature_time(&11), + Error::InvalidSignatureTime + ); + assert_err!(signature.verify_signature_time(&u32::MAX), Error::InvalidSignatureTime); } } From c6f3e5550286747e23da5cf10b3a7841122a369b Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Tue, 27 Feb 2024 13:52:48 +0100 Subject: [PATCH 14/39] Add unit tests for dip_subject_state --- .../src/merkle/v0/dip_subject_state/tests.rs | 65 ++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs index 43e4c3072d..6b68f10b05 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs @@ -44,13 +44,74 @@ mod dip_revealed_details_and_unverified_did_signature { } mod dip_revealed_details_and_verified_did_signature_freshness { + use did::{ + did_details::{DidPublicKeyDetails, DidVerificationKey}, + DidVerificationKeyRelationship, + }; + use frame_support::assert_err; + use parity_scale_codec::Encode; + use sp_core::{ed25519, ConstU32, Pair}; + use sp_runtime::{AccountId32, BoundedVec}; + + use crate::{ + DipOriginInfo, DipRevealedDetailsAndVerifiedDidSignatureFreshness, Error, RevealedDidKey, + RevealedDidMerkleProofLeaf, + }; + #[test] fn retrieve_signing_leaf_for_payload_successful() { - unimplemented!() + let payload = b"Hello, world!"; + let (did_key_pair, _) = ed25519::Pair::generate(); + let did_auth_key: DidVerificationKey = did_key_pair.public().into(); + let revealed_leaves: BoundedVec, ConstU32<1>> = + vec![RevealedDidKey:: { + id: 0u32, + relationship: DidVerificationKeyRelationship::Authentication.into(), + details: DidPublicKeyDetails { + key: did_auth_key.into(), + block_number: 0u32, + }, + } + .into()] + .try_into() + .unwrap(); + let revealed_details: DipRevealedDetailsAndVerifiedDidSignatureFreshness<_, _, _, _, _, 1> = + DipRevealedDetailsAndVerifiedDidSignatureFreshness { + revealed_leaves: revealed_leaves.clone(), + signature: did_key_pair.sign(&payload.encode()).into(), + }; + assert_eq!( + revealed_details.retrieve_signing_leaf_for_payload(&payload.encode()), + Ok(DipOriginInfo { + signing_leaf_index: 0, + revealed_leaves, + }) + ); } #[test] fn retrieve_signing_leaf_for_payload_no_key_present() { - unimplemented!() + let did_auth_key: DidVerificationKey = ed25519::Public([0u8; 32]).into(); + let revealed_leaves: BoundedVec, ConstU32<1>> = + vec![RevealedDidKey:: { + id: 0u32, + relationship: DidVerificationKeyRelationship::Authentication.into(), + details: DidPublicKeyDetails { + key: did_auth_key.into(), + block_number: 0u32, + }, + } + .into()] + .try_into() + .unwrap(); + let revealed_details: DipRevealedDetailsAndVerifiedDidSignatureFreshness<_, _, _, _, _, 1> = + DipRevealedDetailsAndVerifiedDidSignatureFreshness { + revealed_leaves, + signature: ed25519::Signature([100u8; 64]).into(), + }; + assert_err!( + revealed_details.retrieve_signing_leaf_for_payload(&().encode()), + Error::InvalidDidKeyRevealed + ); } } From 41a1068c0f993eb843ba7117872b8981abebbfd0 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 28 Feb 2024 08:49:28 +0100 Subject: [PATCH 15/39] Complete unit tests for dip_did_proof_with_verified_relay_state_root --- .../src/merkle/v0/provider_state/mod.rs | 41 +++- .../src/merkle/v0/provider_state/tests.rs | 197 ++++++++++++++++-- pallets/pallet-dip-provider/src/traits.rs | 4 +- 3 files changed, 227 insertions(+), 15 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs index d0fc3233c9..5c5d114c17 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs @@ -380,6 +380,45 @@ impl< } } +#[cfg(test)] +impl< + StateRoot, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > + DipDidProofWithVerifiedStateRoot< + StateRoot, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > where + KiltDidKeyId: Default, + KiltAccountId: Default, + KiltBlockNumber: Default, + KiltWeb3Name: Default, + KiltLinkableAccountId: Default, + ConsumerBlockNumber: Default, +{ + pub(crate) fn with_state_root_and_dip_commitment_proof( + provider_state_root: StateRoot, + dip_commitment_proof: DipCommitmentStateProof, + ) -> Self { + Self { + state_root: provider_state_root, + dip_commitment_proof, + dip_proof: Default::default(), + signature: Default::default(), + } + } +} + /// A DIP proof that has had the relaychain state and the DIP commitment /// verified for the provided relaychain block number. /// @@ -394,7 +433,7 @@ impl< /// KILT chain. /// * `ConsumerBlockNumber`: The `BlockNumber` definition of the consumer /// parachain. -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub struct DipDidProofWithVerifiedSubjectCommitment< Commitment, KiltDidKeyId, diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs index b6b9a09cb7..d25b5be7a5 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs @@ -191,36 +191,209 @@ mod parachain_dip_did_proof { } mod dip_did_proof_with_verified_relay_state_root { + use frame_support::{assert_err, construct_runtime, traits::Everything}; + use frame_system::{mocking::MockBlock, EnsureSigned}; + use hex_literal::hex; + use pallet_dip_provider::{DefaultIdentityCommitmentGenerator, DefaultIdentityProvider}; + use sp_core::{crypto::Ss58Codec, ConstU16, ConstU32, ConstU64, H256}; + use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup, Keccak256}, + AccountId32, + }; + + use crate::{state_proofs::MerkleProofError, DipCommitmentStateProof, DipDidProofWithVerifiedStateRoot, Error}; + + construct_runtime!( + pub enum TestProviderRuntime { + System: frame_system, + DipProvider: pallet_dip_provider, + } + ); + + impl frame_system::Config for TestProviderRuntime { + type AccountData = (); + type AccountId = AccountId32; + type BaseCallFilter = Everything; + type Block = MockBlock; + type BlockHashCount = ConstU64<256>; + type BlockLength = (); + type BlockWeights = (); + type DbWeight = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type Lookup = IdentityLookup; + type MaxConsumers = ConstU32<16>; + type Nonce = u64; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = (); + type PalletInfo = PalletInfo; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type SS58Prefix = ConstU16<1>; + type SystemWeightInfo = (); + type Version = (); + } + + impl pallet_dip_provider::Config for TestProviderRuntime { + type CommitOrigin = AccountId32; + type CommitOriginCheck = EnsureSigned; + type Identifier = AccountId32; + type IdentityCommitmentGenerator = DefaultIdentityCommitmentGenerator; + type IdentityProvider = DefaultIdentityProvider; + type ProviderHooks = (); + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + } + #[test] fn verify_dip_commitment_proof_for_subject_successful() { - unimplemented!() + // Storage proof generated at Peregrine block `5_258_991` with hash + // `0xd83da28e40d6e193af832916d2741252955d438c9d17a9f441279085db3e8daf` for + // storage key + // `0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f30d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000` + // (`dipProvider::identityCommitments(4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK, 0)`) + let parachain_state_root: H256 = + hex!("3a27f8d59c8bcc51bf3735ecdc0ce1304127a5b9e707e956e22633179493d55c").into(); + let dip_commitment_proof = DipCommitmentStateProof(vec![ + hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), + hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd8003ab0887cbb70c4e0d8d0f738e4b05732fd8cb5da24fa5f1112e20ba3603d58a80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), + hex!("80ffff808a66c19052add13a202bcd73b546ae0cb70544f166c4a469672c666f0a5f9d8a80b84c2df313e2e749ff7e47eee888d9a023ba0a14a59852f4526b3e4b93b6dcbc807310fd50a0ae630c15e9eb07bda831d6d0cb6044d53a3dafb68e3fdb199fffdf80015ecd5e8af66e3d72ee5cc828c25989ca848e55396cccd9c196a4df1349fb9980a2ec48e449c43cc34954836cc14af398695f6569e301cef5a13eb88a16aa395580fd068d1339506db2893ba54a00a85aa712d68ff98ceeb5f4632f4e53618bb77880a3f173abac33e571e2a66f13127eeec3fb31bb1ae6f4b0fca8e658bbfbb5e52a803084ef6eaf38b821c59b3de92c4679117509b0b031e52ef5a80fdcff72e498ec804f36b8fb07a75463165f1714181009c86a2790685e78abd43220f5ecb194c887802559300c82eef4b21724bba2706cc2815e98cac3993c8d8dc9057b1aaf45ae8d8006571e929d492077d682dbc911934874ec00335029a90bd39e37d6d641e11873800397abe2ea62a374e5f0650c54fb99e8ef825066da798b0f4d729a7281f3575880b35cfb12f77988e1305ba651db7a8efbd43e4e8b057a56736cf6485f3033f481809ab1e406503e3ce63425a294f3f37aa4827b6a4ab38cf7e960a0d3335d79234e80be7c96632aa67491005e607a53bc1ab725fa465e29797bc29973d4cf5f64239b8037fe2a92c86d4c38ff38570b071e994ab86214e43e095dfb6ed142170fdac430").to_vec(), + hex!("be75edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3010880ffe3135a9ee019dbfe4143608c9f4a4291ab827d7d9d055028d556d9cea2fce180eb5d42e7c6f84ac20e0d5ab42008c631b3e87f36d55d0d5053c9fb4f944ef97c").to_vec(), + ].into_iter().into()); + // Only interested in the DIP commitment verification part, we skip everything + // else. + let proof = + DipDidProofWithVerifiedStateRoot::<_, (), (), (), (), (), ()>::with_state_root_and_dip_commitment_proof( + parachain_state_root, + dip_commitment_proof, + ); + let proof_verification_result = proof + .verify_dip_commitment_proof_for_subject::( + &AccountId32::from_ss58check("4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK").unwrap(), + ) + .unwrap(); + assert_eq!( + proof_verification_result.dip_commitment, + hex!("4aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").into() + ); } #[test] fn verify_dip_commitment_proof_for_subject_multi_storage() { - unimplemented!() + // Storage proof generated at Peregrine block `5_264_068` with hash + // `0x44635397de0fd0f4e6329064bd2c8500a6ca2283d904e7f2fbe271cd362224cb` for + // storage keys + // [`0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f30d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000`, '0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f346802a0d131133fa4cac8e6332f14ad28fe8b2ccb9e339f1c36798e918846726e6e983b59dd4fa3101a12dfa1fa4ab9a0000] + // ([`dipProvider::identityCommitments(4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK, 0)`, `dipProvider::identityCommitments(4pebirGcQAJ4nyd5137VuK8TPVW9RXprWvZLQK1wcw2qJvnM, 0)`]) + let parachain_state_root: H256 = + hex!("886585d3c600c51e36e5e9b09c981abdee80fb0f3e5ce127a6de659b8684f168").into(); + let dip_commitment_proof = DipCommitmentStateProof(vec![ + hex!("7f2406802a0d131133fa4cac8e6332f14ad28fe8b2ccb9e339f1c36798e918846726e6e983b59dd4fa3101a12dfa1fa4ab9a000080dbf7e051929e3be2b6ded6fa9f4827a6bb080092487482c581e4e154d4a8f78f").to_vec(), + hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), + hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd80ccbd1321b25f59f4de9cd943c7322b8f2b943e30e510e7f32571250f651015bc80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), + hex!("80ffff808a66c19052add13a202bcd73b546ae0cb70544f166c4a469672c666f0a5f9d8a80b84c2df313e2e749ff7e47eee888d9a023ba0a14a59852f4526b3e4b93b6dcbc80e2f12a87d30577bc3586e4684c34438a779df39f6bee51b098193f1484e7b20f80015ecd5e8af66e3d72ee5cc828c25989ca848e55396cccd9c196a4df1349fb99808587812cb707ea395adbd624fba27708a8b734dd26c75febf4d79f30f775d31f80cf4fdd2b7ee898fa3de2063d08ca5488a65e49b4f21969be56dd22b79729f4ce80f77d231bea6c289f8d969c0a2cc81ec8447efa0747845799e7bc635626801605806830b9c8dadb45b721c323e66aaf4417dd1f2a3b0315c17c7e9bc3a75312677d807368afb2a07ba2ca0ceec6c88e0e3040a39d4c86408f97d2fa0006c39531b4ca802559300c82eef4b21724bba2706cc2815e98cac3993c8d8dc9057b1aaf45ae8d808c1f6312826116f8e9aa52506bfc8b3b4583998f8858213044dac52f3ac1138c803e008fcbfb660c563e9eb278cf78fe3988027713cd9077898c351c41844fefc480002990139706fe0a03fcfc41614c9cec1ae13ddafba4de0630af0b87503d8312809ab1e406503e3ce63425a294f3f37aa4827b6a4ab38cf7e960a0d3335d79234e80be7c96632aa67491005e607a53bc1ab725fa465e29797bc29973d4cf5f64239b8003bce13d1847862ce6f26f6b420ffda9cd9b635c2ec8533f23c7b2d454d66b29").to_vec(), + hex!("be75edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3110880ffe3135a9ee019dbfe4143608c9f4a4291ab827d7d9d055028d556d9cea2fce1804276317882ff464bb21f7fb6b9e20ccee7a1e414608ecb3c8c349dfa286dfd7480eb5d42e7c6f84ac20e0d5ab42008c631b3e87f36d55d0d5053c9fb4f944ef97c").to_vec(), + ].into_iter().into()); + // Only interested in the DIP commitment verification part, we skip everything + // else. + let proof = + DipDidProofWithVerifiedStateRoot::<_, (), (), (), (), (), ()>::with_state_root_and_dip_commitment_proof( + parachain_state_root, + dip_commitment_proof, + ); + let proof_verification_result = proof + .verify_dip_commitment_proof_for_subject::( + &AccountId32::from_ss58check("4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK").unwrap(), + ) + .unwrap(); + assert_eq!( + proof_verification_result.dip_commitment, + hex!("4aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").into() + ); } #[test] fn verify_dip_commitment_proof_for_subject_wrong_provider_hasher() { - unimplemented!() - } - - #[test] - fn verify_dip_commitment_proof_for_subject_wrong_provider_runtime() { - unimplemented!() + // Storage proof generated at Peregrine block `5_258_991` with hash + // `0xd83da28e40d6e193af832916d2741252955d438c9d17a9f441279085db3e8daf` for + // storage key + // `0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f30d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000` + // (`dipProvider::identityCommitments(4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK, 0)`) + let parachain_state_root: H256 = + hex!("3a27f8d59c8bcc51bf3735ecdc0ce1304127a5b9e707e956e22633179493d55c").into(); + let dip_commitment_proof = DipCommitmentStateProof(vec![ + hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), + hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd8003ab0887cbb70c4e0d8d0f738e4b05732fd8cb5da24fa5f1112e20ba3603d58a80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), + hex!("80ffff808a66c19052add13a202bcd73b546ae0cb70544f166c4a469672c666f0a5f9d8a80b84c2df313e2e749ff7e47eee888d9a023ba0a14a59852f4526b3e4b93b6dcbc807310fd50a0ae630c15e9eb07bda831d6d0cb6044d53a3dafb68e3fdb199fffdf80015ecd5e8af66e3d72ee5cc828c25989ca848e55396cccd9c196a4df1349fb9980a2ec48e449c43cc34954836cc14af398695f6569e301cef5a13eb88a16aa395580fd068d1339506db2893ba54a00a85aa712d68ff98ceeb5f4632f4e53618bb77880a3f173abac33e571e2a66f13127eeec3fb31bb1ae6f4b0fca8e658bbfbb5e52a803084ef6eaf38b821c59b3de92c4679117509b0b031e52ef5a80fdcff72e498ec804f36b8fb07a75463165f1714181009c86a2790685e78abd43220f5ecb194c887802559300c82eef4b21724bba2706cc2815e98cac3993c8d8dc9057b1aaf45ae8d8006571e929d492077d682dbc911934874ec00335029a90bd39e37d6d641e11873800397abe2ea62a374e5f0650c54fb99e8ef825066da798b0f4d729a7281f3575880b35cfb12f77988e1305ba651db7a8efbd43e4e8b057a56736cf6485f3033f481809ab1e406503e3ce63425a294f3f37aa4827b6a4ab38cf7e960a0d3335d79234e80be7c96632aa67491005e607a53bc1ab725fa465e29797bc29973d4cf5f64239b8037fe2a92c86d4c38ff38570b071e994ab86214e43e095dfb6ed142170fdac430").to_vec(), + hex!("be75edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3010880ffe3135a9ee019dbfe4143608c9f4a4291ab827d7d9d055028d556d9cea2fce180eb5d42e7c6f84ac20e0d5ab42008c631b3e87f36d55d0d5053c9fb4f944ef97c").to_vec(), + ].into_iter().into()); + // Only interested in the DIP commitment verification part, we skip everything + // else. + let proof = + DipDidProofWithVerifiedStateRoot::<_, (), (), (), (), (), ()>::with_state_root_and_dip_commitment_proof( + parachain_state_root, + dip_commitment_proof, + ); + assert_err!( + proof.verify_dip_commitment_proof_for_subject::( + // We try + &AccountId32::from_ss58check("4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK").unwrap(), + ), + Error::DipCommitmentMerkleProof(MerkleProofError::InvalidProof) + ); } #[test] fn verify_dip_commitment_proof_for_subject_different_subject() { - // Valid proof but on a different storage key than the expected one - unimplemented!() + // Storage proof generated at Peregrine block `5_258_991` with hash + // `0xd83da28e40d6e193af832916d2741252955d438c9d17a9f441279085db3e8daf` for + // storage key + // `0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f30d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000` + // (`dipProvider::identityCommitments(4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK, 0)`) + let parachain_state_root: H256 = + hex!("3a27f8d59c8bcc51bf3735ecdc0ce1304127a5b9e707e956e22633179493d55c").into(); + let dip_commitment_proof = DipCommitmentStateProof(vec![ + hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), + hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd8003ab0887cbb70c4e0d8d0f738e4b05732fd8cb5da24fa5f1112e20ba3603d58a80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), + hex!("80ffff808a66c19052add13a202bcd73b546ae0cb70544f166c4a469672c666f0a5f9d8a80b84c2df313e2e749ff7e47eee888d9a023ba0a14a59852f4526b3e4b93b6dcbc807310fd50a0ae630c15e9eb07bda831d6d0cb6044d53a3dafb68e3fdb199fffdf80015ecd5e8af66e3d72ee5cc828c25989ca848e55396cccd9c196a4df1349fb9980a2ec48e449c43cc34954836cc14af398695f6569e301cef5a13eb88a16aa395580fd068d1339506db2893ba54a00a85aa712d68ff98ceeb5f4632f4e53618bb77880a3f173abac33e571e2a66f13127eeec3fb31bb1ae6f4b0fca8e658bbfbb5e52a803084ef6eaf38b821c59b3de92c4679117509b0b031e52ef5a80fdcff72e498ec804f36b8fb07a75463165f1714181009c86a2790685e78abd43220f5ecb194c887802559300c82eef4b21724bba2706cc2815e98cac3993c8d8dc9057b1aaf45ae8d8006571e929d492077d682dbc911934874ec00335029a90bd39e37d6d641e11873800397abe2ea62a374e5f0650c54fb99e8ef825066da798b0f4d729a7281f3575880b35cfb12f77988e1305ba651db7a8efbd43e4e8b057a56736cf6485f3033f481809ab1e406503e3ce63425a294f3f37aa4827b6a4ab38cf7e960a0d3335d79234e80be7c96632aa67491005e607a53bc1ab725fa465e29797bc29973d4cf5f64239b8037fe2a92c86d4c38ff38570b071e994ab86214e43e095dfb6ed142170fdac430").to_vec(), + hex!("be75edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3010880ffe3135a9ee019dbfe4143608c9f4a4291ab827d7d9d055028d556d9cea2fce180eb5d42e7c6f84ac20e0d5ab42008c631b3e87f36d55d0d5053c9fb4f944ef97c").to_vec(), + ].into_iter().into()); + let proof = + DipDidProofWithVerifiedStateRoot::<_, (), (), (), (), (), ()>::with_state_root_and_dip_commitment_proof( + parachain_state_root, + dip_commitment_proof, + ); + assert_err!( + proof.verify_dip_commitment_proof_for_subject::( + &AccountId32::from_ss58check("4pebirGcQAJ4nyd5137VuK8TPVW9RXprWvZLQK1wcw2qJvnM").unwrap(), + ), + Error::DipCommitmentMerkleProof(MerkleProofError::RequiredLeafNotRevealed) + ); } #[test] fn verify_dip_commitment_proof_for_subject_invalid_proof() { - // Invalid proof for the given storage key - unimplemented!() + let parachain_state_root: H256 = + hex!("3a27f8d59c8bcc51bf3735ecdc0ce1304127a5b9e707e956e22633179493d55c").into(); + let dip_commitment_proof = DipCommitmentStateProof(vec![ + hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), + hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd8003ab0887cbb70c4e0d8d0f738e4b05732fd8cb5da24fa5f1112e20ba3603d58a80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), + hex!("80ffff808a66c19052add13a202bcd73b546ae0cb70544f166c4a469672c666f0a5f9d8a80b84c2df313e2e749ff7e47eee888d9a023ba0a14a59852f4526b3e4b93b6dcbc807310fd50a0ae630c15e9eb07bda831d6d0cb6044d53a3dafb68e3fdb199fffdf80015ecd5e8af66e3d72ee5cc828c25989ca848e55396cccd9c196a4df1349fb9980a2ec48e449c43cc34954836cc14af398695f6569e301cef5a13eb88a16aa395580fd068d1339506db2893ba54a00a85aa712d68ff98ceeb5f4632f4e53618bb77880a3f173abac33e571e2a66f13127eeec3fb31bb1ae6f4b0fca8e658bbfbb5e52a803084ef6eaf38b821c59b3de92c4679117509b0b031e52ef5a80fdcff72e498ec804f36b8fb07a75463165f1714181009c86a2790685e78abd43220f5ecb194c887802559300c82eef4b21724bba2706cc2815e98cac3993c8d8dc9057b1aaf45ae8d8006571e929d492077d682dbc911934874ec00335029a90bd39e37d6d641e11873800397abe2ea62a374e5f0650c54fb99e8ef825066da798b0f4d729a7281f3575880b35cfb12f77988e1305ba651db7a8efbd43e4e8b057a56736cf6485f3033f481809ab1e406503e3ce63425a294f3f37aa4827b6a4ab38cf7e960a0d3335d79234e80be7c96632aa67491005e607a53bc1ab725fa465e29797bc29973d4cf5f64239b8037fe2a92c86d4c38ff38570b071e994ab86214e43e095dfb6ed142170fdac430").to_vec(), + // hex!("be75edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3010880ffe3135a9ee019dbfe4143608c9f4a4291ab827d7d9d055028d556d9cea2fce180eb5d42e7c6f84ac20e0d5ab42008c631b3e87f36d55d0d5053c9fb4f944ef97c").to_vec(), + ].into_iter().into()); + let proof = + DipDidProofWithVerifiedStateRoot::<_, (), (), (), (), (), ()>::with_state_root_and_dip_commitment_proof( + parachain_state_root, + dip_commitment_proof, + ); + assert_err!( + proof.verify_dip_commitment_proof_for_subject::( + &AccountId32::from_ss58check("4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK").unwrap(), + ), + Error::DipCommitmentMerkleProof(MerkleProofError::InvalidProof) + ); } } diff --git a/pallets/pallet-dip-provider/src/traits.rs b/pallets/pallet-dip-provider/src/traits.rs index 5f5369b733..6fc7111de7 100644 --- a/pallets/pallet-dip-provider/src/traits.rs +++ b/pallets/pallet-dip-provider/src/traits.rs @@ -44,7 +44,7 @@ pub mod identity_provision { /// Return the `Default` value of the provided `Identity` type if it /// implements the `Default` trait. - pub struct DefaultIdentityProvider(PhantomData); + pub struct DefaultIdentityProvider(PhantomData); impl IdentityProvider for DefaultIdentityProvider where @@ -91,7 +91,7 @@ pub mod identity_generation { /// Implement the [`IdentityCommitmentGenerator`] trait by returning the /// `Default` value for the `Output` type. - pub struct DefaultIdentityCommitmentGenerator(PhantomData); + pub struct DefaultIdentityCommitmentGenerator(PhantomData); impl IdentityCommitmentGenerator for DefaultIdentityCommitmentGenerator where From e7f19cdefc6bc6a5ac2c852f3a0fc5930c45faa4 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 28 Feb 2024 16:02:12 +0100 Subject: [PATCH 16/39] wip: unit tests for dip_did_proof_with_verified_subject_commitment --- .../src/merkle/v0/dip_subject_state/mod.rs | 2 +- .../src/merkle/v0/provider_state/mod.rs | 33 +++++++++++ .../src/merkle/v0/provider_state/tests.rs | 56 ++++++++++++++++++- 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs index 7de37e7d01..b525945c41 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs @@ -49,7 +49,7 @@ mod tests; /// parachain. /// * `MAX_REVEALED_LEAVES_COUNT`: The maximum number of leaves revealable in /// the proof. -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] #[cfg_attr(test, derive(Clone))] pub struct DipRevealedDetailsAndUnverifiedDidSignature< KiltDidKeyId, diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs index 5c5d114c17..cacc536aa2 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs @@ -567,3 +567,36 @@ impl< }) } } + +#[cfg(test)] +impl< + Commitment, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > + DipDidProofWithVerifiedSubjectCommitment< + Commitment, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > where + ConsumerBlockNumber: Default, +{ + pub(crate) fn with_commitment_and_dip_proof( + commitment: Commitment, + dip_proof: DidMerkleProof, + ) -> Self { + Self { + dip_commitment: commitment, + dip_proof, + signature: TimeBoundDidSignature::default(), + } + } +} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs index d25b5be7a5..64561950bf 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs @@ -398,9 +398,53 @@ mod dip_did_proof_with_verified_relay_state_root { } mod dip_did_proof_with_verified_subject_commitment { + use did::{ + did_details::{DidPublicKeyDetails, DidVerificationKey}, + DidVerificationKeyRelationship, + }; + use frame_support::assert_err; + use hex_literal::hex; + use pallet_did_lookup::linkable_account::LinkableAccountId; + use sp_core::{sr25519, ConstU32, H256}; + use sp_runtime::{traits::BlakeTwo256, AccountId32, BoundedVec}; + + use crate::{ + DidMerkleProof, DipDidProofWithVerifiedSubjectCommitment, Error, RevealedDidKey, RevealedDidMerkleProofLeaf, + }; + + // TODO: Generate a valid DIP proof, and use it here. #[test] fn verify_dip_proof_successful() { - unimplemented!() + // DIP proof generated on Peregrine via the runtime API. + let dip_commitment: H256 = hex!("847b89ef194a872c33bd706e5c0d191bda75f6e3c4964c8531db25e7f0d895e5").into(); + let revealed_leaf: RevealedDidMerkleProofLeaf<_, _, _, BoundedVec>, LinkableAccountId> = + RevealedDidKey:: { + id: hex!("56d7c1e546d4ea7d8f46f3ec7e51892d71a6fc6054b2b7e7d0a32a171f733a59").into(), + relationship: DidVerificationKeyRelationship::Authentication.into(), + details: DidPublicKeyDetails { + key: DidVerificationKey::Sr25519(sr25519::Public(hex!( + "b8e290a7a36f138469957fda2fc7cfa395460fcbdc17f3bf4e5ec41266ee8d00" + ))) + .into(), + block_number: 3, + }, + } + .into(); + let dip_proof = DidMerkleProof { + blinded: vec![hex!("7f0556d7c1e546d4ea7d8f46f3ec7e51892d71a6fc6054b2b7e7d0a32a171f733a59010000").to_vec()] + .into_iter() + .into(), + revealed: vec![revealed_leaf.clone()], + }; + let proof = DipDidProofWithVerifiedSubjectCommitment::<_, _, _, _, _, _, ()>::with_commitment_and_dip_proof( + dip_commitment, + dip_proof, + ); + let proof_verification_result = proof.verify_dip_proof::().unwrap(); + assert_eq!( + proof_verification_result.revealed_leaves.into_inner(), + vec![revealed_leaf] + ); } #[test] @@ -415,6 +459,14 @@ mod dip_did_proof_with_verified_subject_commitment { #[test] fn verify_dip_proof_invalid_proof() { - unimplemented!() + let proof = + DipDidProofWithVerifiedSubjectCommitment::<_, (), (), (), (), (), ()>::with_commitment_and_dip_proof( + H256::default(), + DidMerkleProof { + blinded: Default::default(), + revealed: Default::default(), + }, + ); + assert_err!(proof.verify_dip_proof::(), Error::InvalidDidMerkleProof); } } From b2690acb4c15a74d8a80097972c651923bc4d4fa Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 29 Feb 2024 10:00:12 +0100 Subject: [PATCH 17/39] dip_did_proof_with_verified_subject_commitment unit tests --- .../src/merkle/v0/provider_state/tests.rs | 120 ++++++++++++++++-- 1 file changed, 107 insertions(+), 13 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs index 64561950bf..16b8363781 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs @@ -405,8 +405,11 @@ mod dip_did_proof_with_verified_subject_commitment { use frame_support::assert_err; use hex_literal::hex; use pallet_did_lookup::linkable_account::LinkableAccountId; - use sp_core::{sr25519, ConstU32, H256}; - use sp_runtime::{traits::BlakeTwo256, AccountId32, BoundedVec}; + use sp_core::{ed25519, ConstU32, H256}; + use sp_runtime::{ + traits::{BlakeTwo256, Keccak256}, + AccountId32, BoundedVec, + }; use crate::{ DidMerkleProof, DipDidProofWithVerifiedSubjectCommitment, Error, RevealedDidKey, RevealedDidMerkleProofLeaf, @@ -415,25 +418,38 @@ mod dip_did_proof_with_verified_subject_commitment { // TODO: Generate a valid DIP proof, and use it here. #[test] fn verify_dip_proof_successful() { - // DIP proof generated on Peregrine via the runtime API. - let dip_commitment: H256 = hex!("847b89ef194a872c33bd706e5c0d191bda75f6e3c4964c8531db25e7f0d895e5").into(); + // DIP proof generated on Peregrine via the `dipProvider::generateProof` runtime + // API. + let dip_commitment: H256 = hex!("1997d38bec607be35cab175edc55e2119e0138976021e1f938942c10f9f7b329").into(); let revealed_leaf: RevealedDidMerkleProofLeaf<_, _, _, BoundedVec>, LinkableAccountId> = RevealedDidKey:: { - id: hex!("56d7c1e546d4ea7d8f46f3ec7e51892d71a6fc6054b2b7e7d0a32a171f733a59").into(), + id: hex!("50da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a").into(), relationship: DidVerificationKeyRelationship::Authentication.into(), details: DidPublicKeyDetails { - key: DidVerificationKey::Sr25519(sr25519::Public(hex!( - "b8e290a7a36f138469957fda2fc7cfa395460fcbdc17f3bf4e5ec41266ee8d00" + key: DidVerificationKey::Ed25519(ed25519::Public(hex!( + "43a72e714401762df66b68c26dfbdf2682aaec9f2474eca4613e424a0fbafd3c" ))) .into(), - block_number: 3, + block_number: 0, }, } .into(); let dip_proof = DidMerkleProof { - blinded: vec![hex!("7f0556d7c1e546d4ea7d8f46f3ec7e51892d71a6fc6054b2b7e7d0a32a171f733a59010000").to_vec()] - .into_iter() - .into(), + blinded: vec![ + hex!( + "8027f4809d06d6e9516f8bcbe97b3e1fa94f294b2606a11d00f1162c90bbdbaa0cbc77d480421f140adb34 + 53138eb8c4512f9cff60ee9a62502cbb0ddd30355235c12dbd318001ba7e874784b7c79fdc37d1584ff254 + efb6d167087dcb1227c704fd9f6c21d40080a92c5bdfcfbb286551bc43fb263980bc9148f3645f6bc0743c + 4292b88dc4039f8011e7fd2693a380b14bd3dd83736bec3bbcb7f70c7b7e0aaf30a03d2bbf96bd3b80c5a2 + 1afb7e16c0f8869ca44efbafddef083c89104fe153d0a77698a5aa1eef7d808cf84bd4fa37829f7229d507 + 3cbb504832fc88766def7b06930c5c27f7bf12a080dab6661eac3da9d306e8bbfdffb8ccc901239d8c1664 + 220062a4384224babea0" + ) + .to_vec(), + hex!("7f0400da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a010000").to_vec(), + ] + .into_iter() + .into(), revealed: vec![revealed_leaf.clone()], }; let proof = DipDidProofWithVerifiedSubjectCommitment::<_, _, _, _, _, _, ()>::with_commitment_and_dip_proof( @@ -449,12 +465,90 @@ mod dip_did_proof_with_verified_subject_commitment { #[test] fn verify_dip_proof_wrong_merkle_hasher() { - unimplemented!() + // DIP proof generated on Peregrine via the `dipProvider::generateProof` runtime + // API. + let dip_commitment: H256 = hex!("1997d38bec607be35cab175edc55e2119e0138976021e1f938942c10f9f7b329").into(); + let revealed_leaf: RevealedDidMerkleProofLeaf<_, _, _, BoundedVec>, LinkableAccountId> = + RevealedDidKey:: { + id: hex!("50da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a").into(), + relationship: DidVerificationKeyRelationship::Authentication.into(), + details: DidPublicKeyDetails { + key: DidVerificationKey::Ed25519(ed25519::Public(hex!( + "43a72e714401762df66b68c26dfbdf2682aaec9f2474eca4613e424a0fbafd3c" + ))) + .into(), + block_number: 0, + }, + } + .into(); + let dip_proof = DidMerkleProof { + blinded: vec![ + hex!( + "8027f4809d06d6e9516f8bcbe97b3e1fa94f294b2606a11d00f1162c90bbdbaa0cbc77d480421f140adb34 + 53138eb8c4512f9cff60ee9a62502cbb0ddd30355235c12dbd318001ba7e874784b7c79fdc37d1584ff254 + efb6d167087dcb1227c704fd9f6c21d40080a92c5bdfcfbb286551bc43fb263980bc9148f3645f6bc0743c + 4292b88dc4039f8011e7fd2693a380b14bd3dd83736bec3bbcb7f70c7b7e0aaf30a03d2bbf96bd3b80c5a2 + 1afb7e16c0f8869ca44efbafddef083c89104fe153d0a77698a5aa1eef7d808cf84bd4fa37829f7229d507 + 3cbb504832fc88766def7b06930c5c27f7bf12a080dab6661eac3da9d306e8bbfdffb8ccc901239d8c1664 + 220062a4384224babea0" + ) + .to_vec(), + hex!("7f0400da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a010000").to_vec(), + ] + .into_iter() + .into(), + revealed: vec![revealed_leaf], + }; + let proof = DipDidProofWithVerifiedSubjectCommitment::<_, _, _, _, _, _, ()>::with_commitment_and_dip_proof( + dip_commitment, + dip_proof, + ); + // Different hasher used for verification + assert_err!(proof.verify_dip_proof::(), Error::InvalidDidMerkleProof); } #[test] fn verify_dip_proof_too_many_leaves() { - unimplemented!() + // DIP proof generated on Peregrine via the `dipProvider::generateProof` runtime + // API. + let dip_commitment: H256 = hex!("1997d38bec607be35cab175edc55e2119e0138976021e1f938942c10f9f7b329").into(); + let revealed_leaf: RevealedDidMerkleProofLeaf<_, _, _, BoundedVec>, LinkableAccountId> = + RevealedDidKey:: { + id: hex!("50da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a").into(), + relationship: DidVerificationKeyRelationship::Authentication.into(), + details: DidPublicKeyDetails { + key: DidVerificationKey::Ed25519(ed25519::Public(hex!( + "43a72e714401762df66b68c26dfbdf2682aaec9f2474eca4613e424a0fbafd3c" + ))) + .into(), + block_number: 0, + }, + } + .into(); + let dip_proof = DidMerkleProof { + blinded: vec![ + hex!( + "8027f4809d06d6e9516f8bcbe97b3e1fa94f294b2606a11d00f1162c90bbdbaa0cbc77d480421f140adb34 + 53138eb8c4512f9cff60ee9a62502cbb0ddd30355235c12dbd318001ba7e874784b7c79fdc37d1584ff254 + efb6d167087dcb1227c704fd9f6c21d40080a92c5bdfcfbb286551bc43fb263980bc9148f3645f6bc0743c + 4292b88dc4039f8011e7fd2693a380b14bd3dd83736bec3bbcb7f70c7b7e0aaf30a03d2bbf96bd3b80c5a2 + 1afb7e16c0f8869ca44efbafddef083c89104fe153d0a77698a5aa1eef7d808cf84bd4fa37829f7229d507 + 3cbb504832fc88766def7b06930c5c27f7bf12a080dab6661eac3da9d306e8bbfdffb8ccc901239d8c1664 + 220062a4384224babea0" + ) + .to_vec(), + hex!("7f0400da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a010000").to_vec(), + ] + .into_iter() + .into(), + revealed: vec![revealed_leaf], + }; + let proof = DipDidProofWithVerifiedSubjectCommitment::<_, _, _, _, _, _, ()>::with_commitment_and_dip_proof( + dip_commitment, + dip_proof, + ); + // We set 0 as the maximum limit. + assert_err!(proof.verify_dip_proof::(), Error::TooManyLeavesRevealed); } #[test] From b5de12a950237546677fcf680ea79329e2f3fbf6 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 29 Feb 2024 15:03:39 +0100 Subject: [PATCH 18/39] verify_proof_for_call_against_details_successful skeleton added --- Cargo.lock | 3 + crates/kilt-dip-primitives/Cargo.toml | 3 + .../src/merkle/v0/provider_state/mod.rs | 1 + .../src/verifier/parachain/error.rs | 1 + .../src/verifier/parachain/v0/mock.rs | 243 ++++++++++++++++++ .../src/verifier/parachain/v0/mod.rs | 6 + .../src/verifier/parachain/v0/tests.rs | 58 +++++ dip-template/runtimes/dip-consumer/src/dip.rs | 11 +- pallets/pallet-relay-store/src/lib.rs | 2 +- 9 files changed, 322 insertions(+), 6 deletions(-) create mode 100644 crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs create mode 100644 crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 0de3ce7ab1..dbfc9d0736 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4622,6 +4622,7 @@ name = "kilt-dip-primitives" version = "1.12.0-dev" dependencies = [ "cfg-if", + "cumulus-pallet-parachain-system", "cumulus-primitives-core", "did", "enum-iterator", @@ -4637,6 +4638,8 @@ dependencies = [ "pallet-relay-store", "pallet-web3-names", "parity-scale-codec", + "peregrine-runtime", + "rococo-runtime", "scale-info", "sp-core", "sp-io", diff --git a/crates/kilt-dip-primitives/Cargo.toml b/crates/kilt-dip-primitives/Cargo.toml index 292ac71ce1..78d0fa948a 100644 --- a/crates/kilt-dip-primitives/Cargo.toml +++ b/crates/kilt-dip-primitives/Cargo.toml @@ -43,8 +43,11 @@ sp-trie.workspace = true cumulus-primitives-core.workspace = true [dev-dependencies] +cumulus-pallet-parachain-system = { workspace = true, features = ["std"] } enum-iterator.workspace = true hex-literal.workspace = true +peregrine-runtime = { workspace = true, features = ["std"] } +rococo-runtime = { workspace = true, features = ["std"] } spiritnet-runtime = { workspace = true, features = ["std"] } sp-io = { workspace = true, features = ["std"] } diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs index cacc536aa2..616524f7d6 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs @@ -201,6 +201,7 @@ impl< { let provider_head_storage_key = calculate_parachain_head_storage_key(provider_para_id); // TODO: Figure out why RPC call returns 2 bytes in front which we don't need + //This could be the reason (and the solution): https://substrate.stackexchange.com/a/1891/1795 let provider_header_result = verify_storage_value_proof_with_decoder::<_, RelayHasher, ProviderHeader>( &provider_head_storage_key, *relay_state_root, diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/error.rs b/crates/kilt-dip-primitives/src/verifier/parachain/error.rs index 0eb1f0bcdc..d50cf1bbe0 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/error.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/error.rs @@ -18,6 +18,7 @@ use crate::Error; +#[derive(Debug)] #[cfg_attr(test, derive(enum_iterator::Sequence))] pub enum DipParachainStateProofVerifierError { UnsupportedVersion, diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs new file mode 100644 index 0000000000..71fe13b5a4 --- /dev/null +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs @@ -0,0 +1,243 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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 cumulus_pallet_parachain_system::{ParachainSetCode, RelayNumberStrictlyIncreases}; +use cumulus_primitives_core::ParaId; +use did::{ + did_details::{DidPublicKeyDetails, DidVerificationKey}, + DidVerificationKeyRelationship, KeyIdOf, +}; +use frame_support::{ + construct_runtime, pallet_prelude::ValueQuery, parameter_types, storage_alias, traits::Everything, Twox64Concat, +}; +use frame_system::{mocking::MockBlock, pallet_prelude::BlockNumberFor, EnsureSigned}; +use hex_literal::hex; +use pallet_did_lookup::linkable_account::LinkableAccountId; +use pallet_relay_store::RelayParentInfo; +use pallet_web3_names::Web3NameOf; +use peregrine_runtime::Runtime as PeregrineRuntime; +use rococo_runtime::Runtime as RococoRuntime; +use sp_core::{sr25519, ConstU16, ConstU32, ConstU64, H256}; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + AccountId32, BoundedVec, +}; + +use crate::{ + parachain::v0::{mock::TestRuntime as TestConsumerRuntime, ParachainVerifier}, + traits::DipCallOriginFilter, + DipCommitmentStateProof, ParachainDipDidProof, ProviderHeadStateProof, RelayStateRootsViaRelayStorePallet, + RevealedDidKey, RevealedWeb3Name, TimeBoundDidSignature, +}; + +construct_runtime!( + pub struct TestRuntime { + // Same index as the DIP-consumer template runtime used to generate the cross-chain proof + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system, + RelayStore: pallet_relay_store, + DipConsumer: pallet_dip_consumer, + } +); + +impl frame_system::Config for TestRuntime { + type AccountData = (); + type AccountId = AccountId32; + type BaseCallFilter = Everything; + type Block = MockBlock; + type BlockHashCount = ConstU64<10>; + type BlockLength = (); + type BlockWeights = (); + type DbWeight = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type Lookup = IdentityLookup; + type MaxConsumers = ConstU32<16>; + type Nonce = u64; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = ParachainSetCode; + type PalletInfo = PalletInfo; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type SS58Prefix = ConstU16<1>; + type SystemWeightInfo = (); + type Version = (); +} + +parameter_types! { + pub const ParachainId: ParaId = ParaId::new(2_001); +} + +impl cumulus_pallet_parachain_system::Config for TestRuntime { + type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases; + type DmpMessageHandler = (); + type OnSystemEvent = (); + type OutboundXcmpMessageSource = (); + type ReservedDmpWeight = (); + type ReservedXcmpWeight = (); + type RuntimeEvent = RuntimeEvent; + type SelfParaId = ParachainId; + type XcmpMessageHandler = (); +} + +impl pallet_relay_store::Config for TestRuntime { + type MaxRelayBlocksStored = ConstU32<10>; + type WeightInfo = (); +} + +pub struct FilterNothing; + +impl DipCallOriginFilter for FilterNothing { + type Error = u8; + type OriginInfo = RevealedDidKey< + KeyIdOf, + BlockNumberFor, + ::AccountId, + >; + type Success = (); + + fn check_call_origin_info(_call: &RuntimeCall, _info: &Self::OriginInfo) -> Result { + Ok(()) + } +} + +pub type Verifier = ParachainVerifier< + RococoRuntime, + RelayStateRootsViaRelayStorePallet, + 2_000, + PeregrineRuntime, + FilterNothing, + (), + 64, + 1024, + 64, + 1024, + 64, + 1024, + 64, +>; +impl pallet_dip_consumer::Config for TestRuntime { + type DipCallOriginFilter = Everything; + type DispatchOriginCheck = EnsureSigned; + type Identifier = ::DidIdentifier; + type LocalIdentityInfo = u32; + type ProofVerifier = Verifier; + type RuntimeCall = RuntimeCall; + type RuntimeOrigin = RuntimeOrigin; + type WeightInfo = (); +} + +// It assumes the DID signature is generated over the following payload: +// (system.remark("Hello, world!"), None, +// 4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M, 56, +// 0xfe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f, ()) +#[allow(clippy::type_complexity)] +pub(crate) fn cross_chain_proof() -> ParachainDipDidProof< + BlockNumberFor, + KeyIdOf, + ::AccountId, + BlockNumberFor, + Web3NameOf, + LinkableAccountId, + BlockNumberFor, +> { + ParachainDipDidProof { provider_head_proof: ProviderHeadStateProof { relay_block_number: 21, proof: vec![ + hex!("3703f5a4efb16ffa83d00700005c5197306d02680fa1d14a3b19ba0fa41b17e8949911dda103b1b0476bfc980e").to_vec(), + hex!("790309fd7e1fbcde7136109a7c9d435fac9bd912d8857a7eb6b5a02ada5eef14effd14c9d5f469ad91a7ce17998925ed087b1b0e82d2b213eacdf87eda9bd14bafc7bbbdcd2a3423d2648d844f668a1de5f409dbfbe1c529b6fdf8efa5b8b94c919dcd0c0661757261201d607d080000000004525053528484b480424aa62b5ec40d592c52a3f36bc06afa6b1e8fcf6806dd50c6147304944c05617572610101f4a4dc233d8ddd805ae2e53f987926dd55609fce234019e60bb2b0cd8b70805c5888f3f408cd7c5e39385adef76223445e2473ddeb23760b1863d592281c7182").to_vec(), + hex!("80046480a1736fb82eeef3ae99c2d1dfc79ca72de61d32d379e5accb53bf99203c9c3b2880f6f6801e4b41e2e6d8ec194dba122bfb9eb33feb2545ef5144cea79551f7cc5280d8416fa071a12a1632a04f2cfe01cd9c7beeacc9d90f647cb93d235dd8870e73808c2f1b77b9294abc1a55fc8432f862b4abfa90f9af3a47f138e4d8dfdfee9468").to_vec(), + hex!("80ffff80e4b470c8e610803be35fb30c2297c88daefe2fb9984db06c45b68c441d989f6680fce4c77e35ddc74b02c611a5436c98b6d2fec67ef1d9eb0c706ac06570913aa580594aafb93d9618327a4d0723e4e6ae1c34de455716c3205e665493a88303e3c4809d3100527438cdc0c7b8a19b932fc76e25d7e22b5ef9ca0a0dbcdfeefec9e9238085ab5177d435d816c3143c5a7ffc4bd8929328ec3ec9a8fb6b8ad1ff9eaf08aa80739be177872c5beb6da57440ce6941849b20f0bc344170a48312fa761fa45b3280275ba9412df014f6c2bd421a42b64052417d01defc479406b157ef5733dbf280805b682132c52908705526057f73ab7fccab4af6d72a9805634dd8d3cc53f130d180c2d44d371e5fc1f50227d7491ad65ad049630361cefb4ab1844831237609f08380134bd63183fb7e62530dd82964c89077ec083b5117f24842f8453f6f9fe3d83080afddf55b94871699b66eb154e0b6495121e88337c7b80f86058ddf54ad9e25c3804b438f963950b0230a6bdbe6664bf5a492d1c05a62343dabf14b377024995a1880490ee6b2b446a32bf0bd68d8cdc905688bdc036a5f349ee84deb700f0bcc95a9803b225accc70e19d48fd9b2e3fdec7b185a451556cf50362b056951abf2df89f4806bfdbbf0e0bedcb993b65c9cea1e929a56d78a3b7bc53d1b7ca6fc488e2295ee80d6513cd4e03e5d4dfda76ba48fefe60422081e4f885128b01400ae254fbc48a1").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945f43803b3441f15daa8a53147d69c48eac75356fab581febbb8030520b248c5942a148801f09f47c0d4767dc1ff9ae54ba8f174d9e5fa06b8242368a39481f5fe5a078f3802e2e0716043a02f2f29fdd52922704af194b98545ce5ca832255e8ec41bcdb6480935f8561d684b40c45e36088c7daa1575cc60b54080e3e023ae43db4092287ba505f0e7b9012096b41c4eb3aaf947f6ea4290800004c5f03c716fb8fff3de61a883bb76adb34a204008092e3fee779c209e5562dd0679d5fcb3876ce9ea0b126e14f1f801a50d8c1d8a44c5f0f4993f016e2d2f8e5f43be7bb259486040080cfad4870b13343cea64432d5dc64a59f0a5c6da43817f25d8a72a3900c9cee17").to_vec(), + hex!("9f0b3c252fcb29d88eff4f3de5de4476c350008072c23a8d4d26e772d0e0e0877b3fa481025ba0f8695a5537b7771587bbe5ca60808e11df642368fb86db2a9cd579f9a3bedf50546a1a325f3c4052c037683e3656").to_vec(), + ].into_iter().into() }, dip_commitment_proof: DipCommitmentStateProof(vec![ + hex!("7f440bf19e4ed2927982e234d989e812f3f32da9da135714ded7366de71f9a6bd6620f03ac92421fea3539e7b80a01bc14cc200265029563162101a12dfa1fa4ab9a00008032e9f6961b6f2915ebb3b3fff7ecdee4d11c1dc7c326c7890cd098498da51df1").to_vec(), + hex!("800c8080da28793d083b197f8d92fc3e77f5064436f1d8eea0fbea56ddb936aba6544500806105b92c7c2c540155c67a2782607dace59d3093432f81564d5ada8bff4be04180b2aafe11c416356c5a97e233670962facb2a18944c3bdc4b9e27f1fa67a5bafe").to_vec(), + hex!("80ffff80353e4d164b13c87910044f1b4e76277e404a0ab46a7cd6c33a65aaadc2375ba88007b1390da34b4dce1328430fd924a6e193517a8148dd70a912c0dc2f7f8d2d4c80ade4fe11f1179c11ffdcbfa22755ecb2b1a904b42a8e61838ac5d61b50527e5180e12d12e0e160241a582c5068f11f66364c4421b3444fc3a69da31576a46e93d180e32fd413c5f3f35cf140619d01c260348df629c9581ddb2ffa3ed3a4454611bc80e73af1cd43b13af0d4726e252583bfc4b0e4f159cacfbedeb14669fec54f16d28014e3e0704c9a07636322335a3c663ec9fd9df8b7bf71d6e8183fefecfbfe0e508089e0d83f324b3a94a57e6c9ca7517f7829acf273e063c3b86e876f5f5000dfad808237efee33d7cbf612b36cf8e72b49b7a7ee4d48085dcaf5ffa8b163261a495b80591a4868cf7eafa20b043d709923044e17e7cde25ee7a35b9732af83d346ddf8808ddf2174553f85bc1836060e6ed175ba06730cecc706a30493e8bcfd9823eeca80e36ae624a00ef6eed407fd4d97dfe9980549cc00adeb2f9454c79d73032e10e48085c95ba8d0c7c8734e14270f873eefada04c1c71d6d99d9236772f890c8a74fa80f395b7003a2eb1e39c624b9a707a6cb58c3cb6997932fc80662ae19c785a91f580b5e5172489541dfc581e116554b63de15fddf38ffed2b109394749c20b8f6ce3805256998e8d08896289d5756f1f96ec6d8f4be237654682f91f559a511bf50a75").to_vec(), + hex!("9e75edf06348b4330d1e88564111cb3d3000505f0e7b9012096b41c4eb3aaf947f6ea429080000801109e5a50d25358a1bcff63c57103c8eb73b80885bb28ba9b666503b8669953e").to_vec(), + ].into_iter().into()), dip_proof: crate::DidMerkleProof { blinded: vec![ + hex!("8022000000").to_vec(), + hex!("7f04069d06a63af2662632789148708798b64f753eb007f162a641efbbe572f20e33010000").to_vec(), + hex!("6f0c623964373239616630626365346664303738313630393800").to_vec(), + ].into_iter().into(), revealed: vec![ + RevealedDidKey { + id: hex!("169d06a63af2662632789148708798b64f753eb007f162a641efbbe572f20e33").into(), + relationship: DidVerificationKeyRelationship::Authentication.into(), + details: DidPublicKeyDetails { + key: DidVerificationKey::Sr25519(sr25519::Public(hex!("366de71f9a6bd6620f03ac92421fea3539e7b80a01bc14cc2002650295631621"))).into(), + block_number: 4 + } + }.into(), + RevealedWeb3Name { + web3_name: b"b9d729af0bce4fd07816098".to_vec().try_into().unwrap(), + claimed_at: 4 + }.into() + ] }, signature: TimeBoundDidSignature::new(did::DidSignature::Sr25519(sr25519::Signature(hex!("faf3508b0075d8570bb1a79f7aeba4b08e9ae88f16bb9fc44eaf6f203bad842f75dfc17b114e015c7ccdaa672c359bb066961ba2cbaccf3308dc44e0fee3b28c"))), 56) } +} + +// Aliases requires because the pallet does not expose anything public. +#[storage_alias] +type LatestRelayHeads = StorageMap>; +#[storage_alias] +type LatestBlockHeights = StorageValue>, ValueQuery>; + +#[derive(Default)] +pub(crate) struct ExtBuilder(Option, Vec<(u32, H256)>, Option>); + +impl ExtBuilder { + pub(crate) fn with_genesis_hash(mut self, hash: H256) -> Self { + self.0 = Some(hash); + self + } + pub(crate) fn with_relay_roots(mut self, relay_roots: Vec<(u32, H256)>) -> Self { + self.1 = relay_roots; + self + } + pub(crate) fn with_block_number(mut self, block_number: BlockNumberFor) -> Self { + self.2 = Some(block_number); + self + } + + pub(crate) fn build(self) -> sp_io::TestExternalities { + let mut ext = sp_io::TestExternalities::default(); + + ext.execute_with(|| { + if let Some(genesis_hash) = self.0 { + frame_system::BlockHash::::insert(0, genesis_hash); + } + for (relay_block, relay_root) in self.1 { + LatestRelayHeads::insert( + relay_block, + RelayParentInfo { + relay_parent_storage_root: relay_root, + }, + ); + LatestBlockHeights::mutate(|v| { + v.try_push(relay_block).unwrap_or_else(|_| { + panic!("Failed to push relay block ({:#?}, {:#?})", relay_block, relay_root) + }); + }); + } + if let Some(block_number) = self.2 { + System::set_block_number(block_number); + } + }); + + ext + } +} diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs index d6e1134742..2f5e94c0a4 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs @@ -34,6 +34,12 @@ use crate::{ DipOriginInfo, DipParachainStateProofVerifierError, RevealedDidKey, }; +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + /// Proof verifier configured given a specific KILT runtime implementation. /// /// The generic types diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs new file mode 100644 index 0000000000..24bc26c6f5 --- /dev/null +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs @@ -0,0 +1,58 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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 did::DidIdentifierOf; +use frame_support::assert_ok; +use hex_literal::hex; +use pallet_dip_consumer::traits::IdentityProofVerifier; +use peregrine_runtime::Runtime as PeregrineRuntime; +use sp_core::crypto::Ss58Codec; +use sp_runtime::AccountId32; + +use crate::parachain::v0::mock::{cross_chain_proof, ExtBuilder, RuntimeCall, TestRuntime, Verifier}; + +#[test] +fn verify_proof_for_call_against_details_successful() { + let subject = + DidIdentifierOf::::from_ss58check("4p9S4FrPp4HATybUu6FoBaveQynGWzp8oTpJ5KYyfmYZ9RH4") + .unwrap(); + let submitter = AccountId32::from_ss58check("4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M").unwrap(); + let mut identity_details = Option::::None; + let proof = cross_chain_proof(); + + ExtBuilder::default() + .with_genesis_hash(hex!("fe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f").into()) + .with_relay_roots(vec![( + 21, + hex!("23ed6624753dfc87f0721c867abfa77361636314a60d24e8e85b44072b89c3f6").into(), + )]) + .build() + .execute_with(|| { + assert_ok!( + >::verify_proof_for_call_against_details( + &RuntimeCall::System(frame_system::Call::remark { + remark: b"Hello, world!".to_vec(), + }), + &subject, + &submitter, + &mut identity_details, + proof, + ) + ); + }) +} diff --git a/dip-template/runtimes/dip-consumer/src/dip.rs b/dip-template/runtimes/dip-consumer/src/dip.rs index 1e6ec1daee..31c53e0338 100644 --- a/dip-template/runtimes/dip-consumer/src/dip.rs +++ b/dip-template/runtimes/dip-consumer/src/dip.rs @@ -31,11 +31,12 @@ use sp_std::marker::PhantomData; use crate::{weights, AccountId, DidIdentifier, Runtime, RuntimeCall, RuntimeOrigin}; pub type MerkleProofVerifierOutput = >::VerificationResult; -/// The verifier logic assumes the provider is a sibling KILT parachain, the relaychain is a Rococo relaychain, and -/// that a KILT subject can provide DIP proof that reveal at most 10 DID keys -/// and 10 linked accounts (defaults provided by the -/// `KiltVersionedParachainVerifier` type). Calls that do not pass the -/// [`DipCallFilter`] will be discarded early on in the verification process. +/// The verifier logic assumes the provider is a sibling KILT parachain, the +/// relaychain is a Rococo relaychain, and that a KILT subject can provide DIP +/// proof that reveal at most 10 DID keys and 10 linked accounts (defaults +/// provided by the `KiltVersionedParachainVerifier` type). Calls that do not +/// pass the [`DipCallFilter`] will be discarded early on in the verification +/// process. pub type ProofVerifier = KiltVersionedParachainVerifier< RelaychainRuntime, RelayStateRootsViaRelayStorePallet, diff --git a/pallets/pallet-relay-store/src/lib.rs b/pallets/pallet-relay-store/src/lib.rs index 8ff46be4d5..28cfe0a777 100644 --- a/pallets/pallet-relay-store/src/lib.rs +++ b/pallets/pallet-relay-store/src/lib.rs @@ -35,7 +35,7 @@ mod mock; #[cfg(test)] mod tests; -pub use crate::{default_weights::WeightInfo, pallet::*}; +pub use crate::{default_weights::WeightInfo, pallet::*, relay::*}; #[frame_support::pallet] pub mod pallet { From 18cab49de10379d3fddd979bc47ae3b4ed798ab0 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 29 Feb 2024 15:58:28 +0100 Subject: [PATCH 19/39] wip: full proof verifier unit tests --- crates/kilt-dip-primitives/src/utils.rs | 6 ++ .../src/verifier/parachain/error.rs | 2 +- .../src/verifier/parachain/v0/mock.rs | 23 +++-- .../src/verifier/parachain/v0/tests.rs | 99 ++++++++++++++++++- 4 files changed, 118 insertions(+), 12 deletions(-) diff --git a/crates/kilt-dip-primitives/src/utils.rs b/crates/kilt-dip-primitives/src/utils.rs index e53b8f8e05..b4292fd834 100644 --- a/crates/kilt-dip-primitives/src/utils.rs +++ b/crates/kilt-dip-primitives/src/utils.rs @@ -53,6 +53,12 @@ impl sp_std::ops::Deref for BoundedBlindedValue { } } +impl sp_std::ops::DerefMut for BoundedBlindedValue { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + impl IntoIterator for BoundedBlindedValue { type IntoIter = > as IntoIterator>::IntoIter; type Item = > as IntoIterator>::Item; diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/error.rs b/crates/kilt-dip-primitives/src/verifier/parachain/error.rs index d50cf1bbe0..30104794f8 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/error.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/error.rs @@ -18,7 +18,7 @@ use crate::Error; -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] #[cfg_attr(test, derive(enum_iterator::Sequence))] pub enum DipParachainStateProofVerifierError { UnsupportedVersion, diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs index 71fe13b5a4..bd97df6aa9 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs @@ -118,6 +118,13 @@ impl DipCallOriginFilter for FilterNothing { } } +pub(crate) const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32 = 64; +pub(crate) const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32 = 1024; +pub(crate) const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32 = 64; +pub(crate) const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32 = 1024; +pub(crate) const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32 = 64; +pub(crate) const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32 = 1024; +pub(crate) const MAX_DID_MERKLE_LEAVES_REVEALED: u32 = 64; pub type Verifier = ParachainVerifier< RococoRuntime, RelayStateRootsViaRelayStorePallet, @@ -125,13 +132,13 @@ pub type Verifier = ParachainVerifier< PeregrineRuntime, FilterNothing, (), - 64, - 1024, - 64, - 1024, - 64, - 1024, - 64, + MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, + MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, + MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT, + MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE, + MAX_DID_MERKLE_PROOF_LEAVE_COUNT, + MAX_DID_MERKLE_PROOF_LEAVE_SIZE, + MAX_DID_MERKLE_LEAVES_REVEALED, >; impl pallet_dip_consumer::Config for TestRuntime { type DipCallOriginFilter = Everything; @@ -149,7 +156,7 @@ impl pallet_dip_consumer::Config for TestRuntime { // 4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M, 56, // 0xfe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f, ()) #[allow(clippy::type_complexity)] -pub(crate) fn cross_chain_proof() -> ParachainDipDidProof< +pub(crate) fn correct_cross_chain_proof() -> ParachainDipDidProof< BlockNumberFor, KeyIdOf, ::AccountId, diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs index 24bc26c6f5..651bb006b9 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs @@ -17,14 +17,20 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org use did::DidIdentifierOf; -use frame_support::assert_ok; +use frame_support::{assert_noop, assert_ok}; use hex_literal::hex; use pallet_dip_consumer::traits::IdentityProofVerifier; use peregrine_runtime::Runtime as PeregrineRuntime; use sp_core::crypto::Ss58Codec; use sp_runtime::AccountId32; -use crate::parachain::v0::mock::{cross_chain_proof, ExtBuilder, RuntimeCall, TestRuntime, Verifier}; +use crate::{ + parachain::v0::mock::{ + correct_cross_chain_proof, ExtBuilder, RuntimeCall, TestRuntime, Verifier, MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, + MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, + }, + DipParachainStateProofVerifierError, +}; #[test] fn verify_proof_for_call_against_details_successful() { @@ -33,7 +39,7 @@ fn verify_proof_for_call_against_details_successful() { .unwrap(); let submitter = AccountId32::from_ss58check("4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M").unwrap(); let mut identity_details = Option::::None; - let proof = cross_chain_proof(); + let proof = correct_cross_chain_proof(); ExtBuilder::default() .with_genesis_hash(hex!("fe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f").into()) @@ -54,5 +60,92 @@ fn verify_proof_for_call_against_details_successful() { proof, ) ); + // If details are none, they are inizialited with their default value. + assert_eq!(identity_details, Some(u32::default())); + }) +} + +#[test] +fn verify_proof_for_call_against_details_relay_proof_too_many_leaves() { + let subject = + DidIdentifierOf::::from_ss58check("4p9S4FrPp4HATybUu6FoBaveQynGWzp8oTpJ5KYyfmYZ9RH4") + .unwrap(); + let submitter = AccountId32::from_ss58check("4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M").unwrap(); + let mut identity_details = Option::::None; + let proof = { + let mut proof = correct_cross_chain_proof(); + let leaves_count = proof.provider_head_proof.proof.len(); + // Extend the relaychain proof to include MAX + 1 leaves, causing the proof + // verification to fail + proof.provider_head_proof.proof.extend( + vec![ + vec![0u8; MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE as usize]; + MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT as usize - leaves_count + 1 + ] + .into_iter(), + ); + proof + }; + + ExtBuilder::default() + .with_genesis_hash(hex!("fe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f").into()) + .with_relay_roots(vec![( + 21, + hex!("23ed6624753dfc87f0721c867abfa77361636314a60d24e8e85b44072b89c3f6").into(), + )]) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &RuntimeCall::System(frame_system::Call::remark { + remark: b"Hello, world!".to_vec(), + }), + &subject, + &submitter, + &mut identity_details, + proof, + ), + DipParachainStateProofVerifierError::ProofComponentTooLarge(0) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_relay_proof_leaf_too_large() { + let subject = + DidIdentifierOf::::from_ss58check("4p9S4FrPp4HATybUu6FoBaveQynGWzp8oTpJ5KYyfmYZ9RH4") + .unwrap(); + let submitter = AccountId32::from_ss58check("4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M").unwrap(); + let mut identity_details = Option::::None; + let proof = { + let mut proof = correct_cross_chain_proof(); + let last_leave = proof.provider_head_proof.proof.last_mut().unwrap(); + let last_leave_size = last_leave.len(); + // Extend the last leaf of the relaychain proof to include MAX + 1 bytes, + // causing the proof verification to fail + last_leave.extend(vec![0u8; MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE as usize - last_leave_size + 1].into_iter()); + proof + }; + + ExtBuilder::default() + .with_genesis_hash(hex!("fe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f").into()) + .with_relay_roots(vec![( + 21, + hex!("23ed6624753dfc87f0721c867abfa77361636314a60d24e8e85b44072b89c3f6").into(), + )]) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &RuntimeCall::System(frame_system::Call::remark { + remark: b"Hello, world!".to_vec(), + }), + &subject, + &submitter, + &mut identity_details, + proof, + ), + DipParachainStateProofVerifierError::ProofComponentTooLarge(1) + ); }) } From 674628f989941d93c59adf3b923ce70003c68d63 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 29 Feb 2024 16:11:40 +0100 Subject: [PATCH 20/39] Add missing unit test for pallet-dip-consumer --- pallets/pallet-dip-consumer/src/mock.rs | 16 ++++++++-- .../src/tests/dispatch_as.rs | 29 +++++++++++++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/pallets/pallet-dip-consumer/src/mock.rs b/pallets/pallet-dip-consumer/src/mock.rs index 6799780280..01782df842 100644 --- a/pallets/pallet-dip-consumer/src/mock.rs +++ b/pallets/pallet-dip-consumer/src/mock.rs @@ -27,7 +27,7 @@ use frame_support::{ }; use frame_system::{mocking::MockBlock, EnsureSigned}; -use crate::{traits::IdentityProofVerifier, Config, DipOrigin, EnsureDipOrigin, RuntimeCallOf}; +use crate::{traits::IdentityProofVerifier, Config, DipOrigin, EnsureDipOrigin, IdentityEntries, RuntimeCallOf}; // This mock is used both for benchmarks and unit tests. // For benchmarks, the `system::remark` call must be allowed to be dispatched, @@ -110,6 +110,8 @@ impl Contains for OnlySystemRemarksWithoutEventsAndDidLookupCalls { } } +// Returns success if `Proof` is `true`, and bumps the identity details by one, +// or instanciates them to `Default` if they're `None`. pub struct BooleanProofVerifier; impl IdentityProofVerifier for BooleanProofVerifier { type Error = u16; @@ -120,10 +122,11 @@ impl IdentityProofVerifier for BooleanProofVerifier { _call: &RuntimeCallOf, _subject: &::Identifier, _submitter: &::AccountId, - _identity_details: &mut Option<::LocalIdentityInfo>, + identity_details: &mut Option<::LocalIdentityInfo>, proof: Self::Proof, ) -> Result { if proof { + *identity_details = identity_details.map(|d| Some(d + 1)).unwrap_or(Some(u128::default())); Ok(()) } else { Err(1) @@ -146,13 +149,17 @@ pub(crate) const SUBMITTER: AccountId32 = AccountId32::new([100u8; 32]); pub(crate) const SUBJECT: AccountId32 = AccountId32::new([200u8; 32]); #[derive(Default)] -pub(crate) struct ExtBuilder(Vec<(AccountId32, u64)>); +pub(crate) struct ExtBuilder(Vec<(AccountId32, u64)>, Vec<(AccountId32, u128)>); impl ExtBuilder { pub(crate) fn with_balances(mut self, balances: Vec<(AccountId32, u64)>) -> Self { self.0 = balances; self } + pub(crate) fn with_identity_details(mut self, details: Vec<(AccountId32, u128)>) -> Self { + self.1 = details; + self + } pub(crate) fn build(self) -> sp_io::TestExternalities { let mut ext = sp_io::TestExternalities::default(); @@ -161,6 +168,9 @@ impl ExtBuilder { for (account_id, balance) in self.0 { Balances::make_free_balance_be(&account_id, balance); } + for (subject, details) in self.1 { + IdentityEntries::::insert(subject, details) + } }); ext diff --git a/pallets/pallet-dip-consumer/src/tests/dispatch_as.rs b/pallets/pallet-dip-consumer/src/tests/dispatch_as.rs index 84d6861b86..80387616cf 100644 --- a/pallets/pallet-dip-consumer/src/tests/dispatch_as.rs +++ b/pallets/pallet-dip-consumer/src/tests/dispatch_as.rs @@ -21,17 +21,18 @@ use frame_system::RawOrigin; use crate::{ mock::{ExtBuilder, System, TestRuntime, SUBJECT, SUBMITTER}, - Error, Pallet, + Error, IdentityEntries, Pallet, }; #[test] -fn dispatch_as_successful() { +fn dispatch_as_successful_no_details() { ExtBuilder::default() .with_balances(vec![(SUBMITTER, 10_000)]) .build() .execute_with(|| { // Needed to test event generation. See for more context. frame_system::Pallet::::set_block_number(1); + assert!(IdentityEntries::::get(SUBJECT).is_none()); assert_ok!(Pallet::::dispatch_as( RawOrigin::Signed(SUBMITTER).into(), SUBJECT, @@ -41,6 +42,30 @@ fn dispatch_as_successful() { System::assert_last_event( pallet_did_lookup::Event::::AssociationEstablished(SUBMITTER.into(), SUBJECT).into(), ); + assert_eq!(IdentityEntries::::get(SUBJECT), Some(0)); + }); +} + +#[test] +fn dispatch_as_successful_existing_details() { + ExtBuilder::default() + .with_balances(vec![(SUBMITTER, 10_000)]) + .with_identity_details(vec![(SUBJECT, 100)]) + .build() + .execute_with(|| { + // Needed to test event generation. See for more context. + frame_system::Pallet::::set_block_number(1); + assert_ok!(Pallet::::dispatch_as( + RawOrigin::Signed(SUBMITTER).into(), + SUBJECT, + true, + Box::new(pallet_did_lookup::Call::associate_sender {}.into()) + )); + System::assert_last_event( + pallet_did_lookup::Event::::AssociationEstablished(SUBMITTER.into(), SUBJECT).into(), + ); + // Details have been bumped up by the proof verifier, and correctly stored in the storage. + assert_eq!(IdentityEntries::::get(SUBJECT), Some(101)); }); } From b07065b35fd71142fdcc7d0d74959ab9268f80b6 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 1 Mar 2024 10:37:23 +0100 Subject: [PATCH 21/39] Parachain verifier v0 unit tests complete --- .../src/verifier/parachain/v0/mock.rs | 47 +- .../src/verifier/parachain/v0/tests.rs | 513 +++++++++++++++--- 2 files changed, 486 insertions(+), 74 deletions(-) diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs index bd97df6aa9..50f956bb43 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs @@ -20,7 +20,7 @@ use cumulus_pallet_parachain_system::{ParachainSetCode, RelayNumberStrictlyIncre use cumulus_primitives_core::ParaId; use did::{ did_details::{DidPublicKeyDetails, DidVerificationKey}, - DidVerificationKeyRelationship, KeyIdOf, + DidIdentifierOf, DidVerificationKeyRelationship, KeyIdOf, }; use frame_support::{ construct_runtime, pallet_prelude::ValueQuery, parameter_types, storage_alias, traits::Everything, Twox64Concat, @@ -32,7 +32,7 @@ use pallet_relay_store::RelayParentInfo; use pallet_web3_names::Web3NameOf; use peregrine_runtime::Runtime as PeregrineRuntime; use rococo_runtime::Runtime as RococoRuntime; -use sp_core::{sr25519, ConstU16, ConstU32, ConstU64, H256}; +use sp_core::{crypto::Ss58Codec, sr25519, ConstU16, ConstU32, ConstU64, H256}; use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, AccountId32, BoundedVec, @@ -151,12 +151,41 @@ impl pallet_dip_consumer::Config for TestRuntime { type WeightInfo = (); } -// It assumes the DID signature is generated over the following payload: -// (system.remark("Hello, world!"), None, -// 4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M, 56, -// 0xfe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f, ()) +pub(crate) const RELAY_BLOCK: u32 = 21; +pub(crate) const RELAY_STATE_ROOT: H256 = + H256(hex!("23ed6624753dfc87f0721c867abfa77361636314a60d24e8e85b44072b89c3f6")); +pub(crate) const GENESIS_HASH: H256 = H256(hex!("fe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f")); +pub(crate) const WRONG_GENESIS_HASH: H256 = H256([0; 32]); +pub(crate) const IDENTITY_DETAILS: Option = None; +pub(crate) const WRONG_IDENTITY_DETAILS: Option = Some(u32::MAX); +pub(crate) const SIGNATURE_VALID_UNTIL: BlockNumberFor = 56; +pub(crate) const WRONG_SIGNATURE_VALID_UNTIL: BlockNumberFor = 55; + +pub(crate) fn submitter() -> AccountId32 { + AccountId32::from_ss58check("4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M").unwrap() +} +pub(crate) fn wrong_submitter() -> AccountId32 { + AccountId32::from_ss58check("4pnAJ41mGHGDKCGBGY2zzu1hfvPasPkGAKDgPeprSkxnUmGM").unwrap() +} + +pub(crate) fn subject() -> DidIdentifierOf { + DidIdentifierOf::::from_ss58check("4p9S4FrPp4HATybUu6FoBaveQynGWzp8oTpJ5KYyfmYZ9RH4").unwrap() +} + +pub(crate) fn call() -> RuntimeCall { + RuntimeCall::System(frame_system::Call::remark { + remark: b"Hello, world!".to_vec(), + }) +} +pub(crate) fn wrong_call() -> RuntimeCall { + RuntimeCall::System(frame_system::Call::remark { + remark: b"Wrong payload!".to_vec(), + }) +} + +// Cross-chain proof generated over the details exported above. #[allow(clippy::type_complexity)] -pub(crate) fn correct_cross_chain_proof() -> ParachainDipDidProof< +pub(crate) fn cross_chain_proof_with_authentication_key_and_web3_name() -> ParachainDipDidProof< BlockNumberFor, KeyIdOf, ::AccountId, @@ -165,7 +194,7 @@ pub(crate) fn correct_cross_chain_proof() -> ParachainDipDidProof< LinkableAccountId, BlockNumberFor, > { - ParachainDipDidProof { provider_head_proof: ProviderHeadStateProof { relay_block_number: 21, proof: vec![ + ParachainDipDidProof { provider_head_proof: ProviderHeadStateProof { relay_block_number: RELAY_BLOCK, proof: vec![ hex!("3703f5a4efb16ffa83d00700005c5197306d02680fa1d14a3b19ba0fa41b17e8949911dda103b1b0476bfc980e").to_vec(), hex!("790309fd7e1fbcde7136109a7c9d435fac9bd912d8857a7eb6b5a02ada5eef14effd14c9d5f469ad91a7ce17998925ed087b1b0e82d2b213eacdf87eda9bd14bafc7bbbdcd2a3423d2648d844f668a1de5f409dbfbe1c529b6fdf8efa5b8b94c919dcd0c0661757261201d607d080000000004525053528484b480424aa62b5ec40d592c52a3f36bc06afa6b1e8fcf6806dd50c6147304944c05617572610101f4a4dc233d8ddd805ae2e53f987926dd55609fce234019e60bb2b0cd8b70805c5888f3f408cd7c5e39385adef76223445e2473ddeb23760b1863d592281c7182").to_vec(), hex!("80046480a1736fb82eeef3ae99c2d1dfc79ca72de61d32d379e5accb53bf99203c9c3b2880f6f6801e4b41e2e6d8ec194dba122bfb9eb33feb2545ef5144cea79551f7cc5280d8416fa071a12a1632a04f2cfe01cd9c7beeacc9d90f647cb93d235dd8870e73808c2f1b77b9294abc1a55fc8432f862b4abfa90f9af3a47f138e4d8dfdfee9468").to_vec(), @@ -194,7 +223,7 @@ pub(crate) fn correct_cross_chain_proof() -> ParachainDipDidProof< web3_name: b"b9d729af0bce4fd07816098".to_vec().try_into().unwrap(), claimed_at: 4 }.into() - ] }, signature: TimeBoundDidSignature::new(did::DidSignature::Sr25519(sr25519::Signature(hex!("faf3508b0075d8570bb1a79f7aeba4b08e9ae88f16bb9fc44eaf6f203bad842f75dfc17b114e015c7ccdaa672c359bb066961ba2cbaccf3308dc44e0fee3b28c"))), 56) } + ] }, signature: TimeBoundDidSignature::new(did::DidSignature::Sr25519(sr25519::Signature(hex!("faf3508b0075d8570bb1a79f7aeba4b08e9ae88f16bb9fc44eaf6f203bad842f75dfc17b114e015c7ccdaa672c359bb066961ba2cbaccf3308dc44e0fee3b28c"))), SIGNATURE_VALID_UNTIL) } } // Aliases requires because the pallet does not expose anything public. diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs index 651bb006b9..76a53ee910 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/tests.rs @@ -16,64 +16,51 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org -use did::DidIdentifierOf; use frame_support::{assert_noop, assert_ok}; -use hex_literal::hex; use pallet_dip_consumer::traits::IdentityProofVerifier; -use peregrine_runtime::Runtime as PeregrineRuntime; -use sp_core::crypto::Ss58Codec; use sp_runtime::AccountId32; use crate::{ parachain::v0::mock::{ - correct_cross_chain_proof, ExtBuilder, RuntimeCall, TestRuntime, Verifier, MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, - MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, + call, cross_chain_proof_with_authentication_key_and_web3_name, subject, submitter, wrong_call, wrong_submitter, + ExtBuilder, TestRuntime, Verifier, GENESIS_HASH, IDENTITY_DETAILS, MAX_DID_MERKLE_LEAVES_REVEALED, + MAX_DID_MERKLE_PROOF_LEAVE_COUNT, MAX_DID_MERKLE_PROOF_LEAVE_SIZE, MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT, + MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE, MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, + RELAY_BLOCK, RELAY_STATE_ROOT, WRONG_GENESIS_HASH, WRONG_IDENTITY_DETAILS, WRONG_SIGNATURE_VALID_UNTIL, }, - DipParachainStateProofVerifierError, + state_proofs::MerkleProofError, + DipParachainStateProofVerifierError, Error, RevealedAccountId, }; #[test] fn verify_proof_for_call_against_details_successful() { - let subject = - DidIdentifierOf::::from_ss58check("4p9S4FrPp4HATybUu6FoBaveQynGWzp8oTpJ5KYyfmYZ9RH4") - .unwrap(); - let submitter = AccountId32::from_ss58check("4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M").unwrap(); - let mut identity_details = Option::::None; - let proof = correct_cross_chain_proof(); + let details = &mut IDENTITY_DETAILS.clone(); + let proof = cross_chain_proof_with_authentication_key_and_web3_name(); ExtBuilder::default() - .with_genesis_hash(hex!("fe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f").into()) - .with_relay_roots(vec![( - 21, - hex!("23ed6624753dfc87f0721c867abfa77361636314a60d24e8e85b44072b89c3f6").into(), - )]) + .with_genesis_hash(GENESIS_HASH) + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) .build() .execute_with(|| { assert_ok!( >::verify_proof_for_call_against_details( - &RuntimeCall::System(frame_system::Call::remark { - remark: b"Hello, world!".to_vec(), - }), - &subject, - &submitter, - &mut identity_details, + &call(), + &subject(), + &submitter(), + details, proof, ) ); // If details are none, they are inizialited with their default value. - assert_eq!(identity_details, Some(u32::default())); + assert_eq!(*details, Some(u32::default())); }) } #[test] fn verify_proof_for_call_against_details_relay_proof_too_many_leaves() { - let subject = - DidIdentifierOf::::from_ss58check("4p9S4FrPp4HATybUu6FoBaveQynGWzp8oTpJ5KYyfmYZ9RH4") - .unwrap(); - let submitter = AccountId32::from_ss58check("4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M").unwrap(); - let mut identity_details = Option::::None; + let details = &mut IDENTITY_DETAILS.clone(); let proof = { - let mut proof = correct_cross_chain_proof(); + let mut proof = cross_chain_proof_with_authentication_key_and_web3_name(); let leaves_count = proof.provider_head_proof.proof.len(); // Extend the relaychain proof to include MAX + 1 leaves, causing the proof // verification to fail @@ -87,65 +74,461 @@ fn verify_proof_for_call_against_details_relay_proof_too_many_leaves() { proof }; + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofComponentTooLarge(0) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_relay_proof_leaf_too_large() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = { + let mut proof = cross_chain_proof_with_authentication_key_and_web3_name(); + let last_leave = proof.provider_head_proof.proof.last_mut().unwrap(); + let last_leave_size = last_leave.len(); + // Extend the last leaf of the relaychain proof to include MAX + 1 bytes, + // causing the proof verification to fail + last_leave.extend(vec![0u8; MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE as usize - last_leave_size + 1].into_iter()); + proof + }; + + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofComponentTooLarge(1) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_relay_root_not_found() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = cross_chain_proof_with_authentication_key_and_web3_name(); + + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofVerification(Error::RelayStateRootNotFound) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_relay_proof_invalid() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = { + let mut proof = cross_chain_proof_with_authentication_key_and_web3_name(); + // Reset the provider head proof to an empty proof. + proof.provider_head_proof.proof = Default::default(); + proof + }; + ExtBuilder::default() - .with_genesis_hash(hex!("fe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f").into()) - .with_relay_roots(vec![( - 21, - hex!("23ed6624753dfc87f0721c867abfa77361636314a60d24e8e85b44072b89c3f6").into(), - )]) + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) .build() .execute_with(|| { assert_noop!( >::verify_proof_for_call_against_details( - &RuntimeCall::System(frame_system::Call::remark { - remark: b"Hello, world!".to_vec(), - }), - &subject, - &submitter, - &mut identity_details, + &call(), + &subject(), + &submitter(), + details, proof, ), - DipParachainStateProofVerifierError::ProofComponentTooLarge(0) + DipParachainStateProofVerifierError::ProofVerification(Error::ParaHeadMerkleProof( + MerkleProofError::InvalidProof + )) ); }) } #[test] -fn verify_proof_for_call_against_details_relay_proof_leaf_too_large() { - let subject = - DidIdentifierOf::::from_ss58check("4p9S4FrPp4HATybUu6FoBaveQynGWzp8oTpJ5KYyfmYZ9RH4") - .unwrap(); - let submitter = AccountId32::from_ss58check("4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M").unwrap(); - let mut identity_details = Option::::None; +fn verify_proof_for_call_against_details_parachain_proof_too_many_leaves() { + let details = &mut IDENTITY_DETAILS.clone(); let proof = { - let mut proof = correct_cross_chain_proof(); - let last_leave = proof.provider_head_proof.proof.last_mut().unwrap(); + let mut proof = cross_chain_proof_with_authentication_key_and_web3_name(); + let leaves_count = proof.dip_commitment_proof.0.len(); + // Extend the DIP commitment proof to include MAX + 1 leaves, causing the proof + // verification to fail + proof.dip_commitment_proof.0.extend( + vec![ + vec![0u8; MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE as usize]; + MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT as usize - leaves_count + 1 + ] + .into_iter(), + ); + proof + }; + + ExtBuilder::default() + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofComponentTooLarge(2) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_parachain_proof_leaf_too_large() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = { + let mut proof = cross_chain_proof_with_authentication_key_and_web3_name(); + let last_leave = proof.dip_commitment_proof.0.last_mut().unwrap(); let last_leave_size = last_leave.len(); - // Extend the last leaf of the relaychain proof to include MAX + 1 bytes, + // Extend the last leaf of the parachain proof to include MAX + 1 bytes, // causing the proof verification to fail - last_leave.extend(vec![0u8; MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE as usize - last_leave_size + 1].into_iter()); + last_leave.extend(vec![0u8; MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE as usize - last_leave_size + 1].into_iter()); proof }; ExtBuilder::default() - .with_genesis_hash(hex!("fe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f").into()) - .with_relay_roots(vec![( - 21, - hex!("23ed6624753dfc87f0721c867abfa77361636314a60d24e8e85b44072b89c3f6").into(), - )]) + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofComponentTooLarge(3) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_parachain_proof_invalid() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = { + let mut proof = cross_chain_proof_with_authentication_key_and_web3_name(); + // Reset the DIP commitment proof to an empty proof. + proof.dip_commitment_proof.0 = Default::default(); + proof + }; + + ExtBuilder::default() + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofVerification(Error::DipCommitmentMerkleProof( + MerkleProofError::InvalidProof + )) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_dip_proof_too_many_leaves() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = { + let mut proof = cross_chain_proof_with_authentication_key_and_web3_name(); + let leaves_count = proof.dip_proof.blinded.len(); + // Extend the DIP proof to include MAX + 1 leaves, causing the proof + // verification to fail + proof.dip_proof.blinded.extend( + vec![ + vec![0u8; MAX_DID_MERKLE_PROOF_LEAVE_SIZE as usize]; + MAX_DID_MERKLE_PROOF_LEAVE_COUNT as usize - leaves_count + 1 + ] + .into_iter(), + ); + proof + }; + + ExtBuilder::default() + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofComponentTooLarge(4) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_dip_proof_leaf_too_large() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = { + let mut proof = cross_chain_proof_with_authentication_key_and_web3_name(); + let last_leave = proof.dip_proof.blinded.last_mut().unwrap(); + let last_leave_size = last_leave.len(); + // Extend the last leaf of the parachain proof to include MAX + 1 bytes, + // causing the proof verification to fail + last_leave.extend(vec![0u8; MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE as usize - last_leave_size + 1].into_iter()); + proof + }; + + ExtBuilder::default() + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofComponentTooLarge(5) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_dip_proof_too_many_revealed_keys() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = { + let mut proof = cross_chain_proof_with_authentication_key_and_web3_name(); + let leaves_count = proof.dip_proof.revealed.len(); + // Extend the DIP proof to include MAX + 1 revealed leaves, causing the proof + // verification to fail + proof.dip_proof.revealed.extend( + vec![ + RevealedAccountId(AccountId32::new([100; 32]).into()).into(); + MAX_DID_MERKLE_LEAVES_REVEALED as usize - leaves_count + 1 + ] + .into_iter(), + ); + proof + }; + + ExtBuilder::default() + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofVerification(Error::TooManyLeavesRevealed) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_dip_proof_invalid() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = { + let mut proof = cross_chain_proof_with_authentication_key_and_web3_name(); + // Reset the DIP proof to an empty proof. + proof.dip_proof.blinded = Default::default(); + proof + }; + + ExtBuilder::default() + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofVerification(Error::InvalidDidMerkleProof) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_did_signature_signature_not_fresh() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = cross_chain_proof_with_authentication_key_and_web3_name(); + + ExtBuilder::default() + // We get past the maximum block at which the signature is to be considered valid. + .with_block_number(proof.signature.valid_until + 1) + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofVerification(Error::InvalidSignatureTime) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_did_signature_different_call() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = cross_chain_proof_with_authentication_key_and_web3_name(); + + ExtBuilder::default() + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .with_genesis_hash(GENESIS_HASH) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + // Different encoding for the call, will result in DID signature verification failure. + &wrong_call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofVerification(Error::InvalidDidKeyRevealed) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_did_signature_different_identity_details() { + // Wrong details, will result in DID signature verification failure. + let details = &mut WRONG_IDENTITY_DETAILS.clone(); + let proof = cross_chain_proof_with_authentication_key_and_web3_name(); + + ExtBuilder::default() + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .with_genesis_hash(GENESIS_HASH) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofVerification(Error::InvalidDidKeyRevealed) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_did_signature_different_submitter_address() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = cross_chain_proof_with_authentication_key_and_web3_name(); + + ExtBuilder::default() + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .with_genesis_hash(GENESIS_HASH) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + // Different submitter, will result in DID signature verification failure. + &wrong_submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofVerification(Error::InvalidDidKeyRevealed) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_did_signature_different_signature_expiration() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = { + let mut proof = cross_chain_proof_with_authentication_key_and_web3_name(); + // Different signature expiration, will result in DID signature verification + // failure. + proof.signature.valid_until = WRONG_SIGNATURE_VALID_UNTIL; + proof + }; + + ExtBuilder::default() + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + .with_genesis_hash(GENESIS_HASH) + .build() + .execute_with(|| { + assert_noop!( + >::verify_proof_for_call_against_details( + &call(), + &subject(), + &submitter(), + details, + proof, + ), + DipParachainStateProofVerifierError::ProofVerification(Error::InvalidDidKeyRevealed) + ); + }) +} + +#[test] +fn verify_proof_for_call_against_details_did_signature_different_genesis_hash() { + let details = &mut IDENTITY_DETAILS.clone(); + let proof = cross_chain_proof_with_authentication_key_and_web3_name(); + + ExtBuilder::default() + .with_relay_roots(vec![(RELAY_BLOCK, RELAY_STATE_ROOT)]) + // Different genesis hash, will result in DID signature verification failure. + .with_genesis_hash(WRONG_GENESIS_HASH) .build() .execute_with(|| { assert_noop!( >::verify_proof_for_call_against_details( - &RuntimeCall::System(frame_system::Call::remark { - remark: b"Hello, world!".to_vec(), - }), - &subject, - &submitter, - &mut identity_details, + &call(), + &subject(), + &submitter(), + details, proof, ), - DipParachainStateProofVerifierError::ProofComponentTooLarge(1) + DipParachainStateProofVerifierError::ProofVerification(Error::InvalidDidKeyRevealed) ); }) } From e2f5cdf9df7c89ee7dd6df5e177835c2f62d99c1 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 1 Mar 2024 10:54:39 +0100 Subject: [PATCH 22/39] Add unit tests for utility functons --- crates/kilt-dip-primitives/src/utils.rs | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/crates/kilt-dip-primitives/src/utils.rs b/crates/kilt-dip-primitives/src/utils.rs index b4292fd834..da87c426f0 100644 --- a/crates/kilt-dip-primitives/src/utils.rs +++ b/crates/kilt-dip-primitives/src/utils.rs @@ -99,6 +99,23 @@ pub(crate) fn calculate_parachain_head_storage_key(para_id: u32) -> StorageKey { ) } +#[test] +fn calculate_parachain_head_storage_key_successful_spiritnet_parachain() { + assert_eq!( + calculate_parachain_head_storage_key(2_086).0, + hex_literal::hex!("cd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000") + .to_vec() + ); +} +#[test] +fn calculate_parachain_head_storage_key_successful_peregrine_parachain() { + assert_eq!( + calculate_parachain_head_storage_key(2_000).0, + hex_literal::hex!("cd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c363f5a4efb16ffa83d0070000") + .to_vec() + ); +} + pub(crate) fn calculate_dip_identity_commitment_storage_key_for_runtime( subject: &Runtime::Identifier, version: IdentityCommitmentVersion, @@ -110,3 +127,16 @@ where subject, version, )) } + +#[test] +fn calculate_dip_identity_commitment_storage_key_for_runtime_successful_peregrine_parachain() { + use did::DidIdentifierOf; + use peregrine_runtime::Runtime as PeregrineRuntime; + use sp_core::crypto::Ss58Codec; + + assert_eq!( + calculate_dip_identity_commitment_storage_key_for_runtime::(&DidIdentifierOf::::from_ss58check("4s3jpR7pzrUdhVUqHHdWoBN6oNQHBC7WRo7zsXdjAzQPT7Cf").unwrap(), 0).0, + hex_literal::hex!("b375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f34edc5f456255d7c2b6caebbe9e3adeaaf693a2d198f2881d0b504fc72ed4ac0a7ed24a025fc228ce01a12dfa1fa4ab9a0000") + .to_vec() + ); +} From 6d0f81c51104a6904d7e36a1a0c0a57576c2110e Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 1 Mar 2024 10:59:58 +0100 Subject: [PATCH 23/39] Refactor util functions unit tests --- crates/kilt-dip-primitives/src/utils.rs | 108 +++++++++++++----------- 1 file changed, 61 insertions(+), 47 deletions(-) diff --git a/crates/kilt-dip-primitives/src/utils.rs b/crates/kilt-dip-primitives/src/utils.rs index da87c426f0..8c055f4fc8 100644 --- a/crates/kilt-dip-primitives/src/utils.rs +++ b/crates/kilt-dip-primitives/src/utils.rs @@ -16,10 +16,8 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org -use pallet_dip_provider::IdentityCommitmentVersion; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; -use sp_core::storage::StorageKey; use sp_std::{fmt::Debug, vec::Vec}; /// The output of a type implementing the [`sp_runtime::traits::Hash`] trait. @@ -88,55 +86,71 @@ where } } -pub(crate) fn calculate_parachain_head_storage_key(para_id: u32) -> StorageKey { - StorageKey( - [ - frame_support::storage::storage_prefix(b"Paras", b"Heads").as_slice(), - sp_io::hashing::twox_64(para_id.encode().as_ref()).as_slice(), - para_id.encode().as_slice(), - ] - .concat(), - ) -} +pub(crate) use calculate_parachain_head_storage_key::*; +mod calculate_parachain_head_storage_key { + use parity_scale_codec::Encode; + use sp_core::storage::StorageKey; + + pub(crate) fn calculate_parachain_head_storage_key(para_id: u32) -> StorageKey { + StorageKey( + [ + frame_support::storage::storage_prefix(b"Paras", b"Heads").as_slice(), + sp_io::hashing::twox_64(para_id.encode().as_ref()).as_slice(), + para_id.encode().as_slice(), + ] + .concat(), + ) + } -#[test] -fn calculate_parachain_head_storage_key_successful_spiritnet_parachain() { - assert_eq!( - calculate_parachain_head_storage_key(2_086).0, - hex_literal::hex!("cd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000") + #[test] + fn calculate_parachain_head_storage_key_successful_spiritnet_parachain() { + assert_eq!( + calculate_parachain_head_storage_key(2_086).0, + hex_literal::hex!( + "cd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000" + ) .to_vec() - ); -} -#[test] -fn calculate_parachain_head_storage_key_successful_peregrine_parachain() { - assert_eq!( - calculate_parachain_head_storage_key(2_000).0, - hex_literal::hex!("cd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c363f5a4efb16ffa83d0070000") + ); + } + #[test] + fn calculate_parachain_head_storage_key_successful_peregrine_parachain() { + assert_eq!( + calculate_parachain_head_storage_key(2_000).0, + hex_literal::hex!( + "cd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c363f5a4efb16ffa83d0070000" + ) .to_vec() - ); -} - -pub(crate) fn calculate_dip_identity_commitment_storage_key_for_runtime( - subject: &Runtime::Identifier, - version: IdentityCommitmentVersion, -) -> StorageKey -where - Runtime: pallet_dip_provider::Config, -{ - StorageKey(pallet_dip_provider::IdentityCommitments::::hashed_key_for( - subject, version, - )) + ); + } } -#[test] -fn calculate_dip_identity_commitment_storage_key_for_runtime_successful_peregrine_parachain() { - use did::DidIdentifierOf; - use peregrine_runtime::Runtime as PeregrineRuntime; - use sp_core::crypto::Ss58Codec; +pub(crate) use calculate_dip_identity_commitment_storage_key_for_runtime::*; +mod calculate_dip_identity_commitment_storage_key_for_runtime { + use pallet_dip_provider::IdentityCommitmentVersion; + use sp_core::storage::StorageKey; + + pub(crate) fn calculate_dip_identity_commitment_storage_key_for_runtime( + subject: &Runtime::Identifier, + version: IdentityCommitmentVersion, + ) -> StorageKey + where + Runtime: pallet_dip_provider::Config, + { + StorageKey(pallet_dip_provider::IdentityCommitments::::hashed_key_for( + subject, version, + )) + } - assert_eq!( - calculate_dip_identity_commitment_storage_key_for_runtime::(&DidIdentifierOf::::from_ss58check("4s3jpR7pzrUdhVUqHHdWoBN6oNQHBC7WRo7zsXdjAzQPT7Cf").unwrap(), 0).0, - hex_literal::hex!("b375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f34edc5f456255d7c2b6caebbe9e3adeaaf693a2d198f2881d0b504fc72ed4ac0a7ed24a025fc228ce01a12dfa1fa4ab9a0000") - .to_vec() - ); + #[test] + fn calculate_dip_identity_commitment_storage_key_for_runtime_successful_peregrine_parachain() { + use did::DidIdentifierOf; + use peregrine_runtime::Runtime as PeregrineRuntime; + use sp_core::crypto::Ss58Codec; + + assert_eq!( + calculate_dip_identity_commitment_storage_key_for_runtime::(&DidIdentifierOf::::from_ss58check("4s3jpR7pzrUdhVUqHHdWoBN6oNQHBC7WRo7zsXdjAzQPT7Cf").unwrap(), 0).0, + hex_literal::hex!("b375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f34edc5f456255d7c2b6caebbe9e3adeaaf693a2d198f2881d0b504fc72ed4ac0a7ed24a025fc228ce01a12dfa1fa4ab9a0000") + .to_vec() + ); + } } From b8939cecc42c1a01856a7f037d2282884a216456 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 1 Mar 2024 11:07:42 +0100 Subject: [PATCH 24/39] Minor changes --- pallets/pallet-dip-consumer/src/mock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/pallet-dip-consumer/src/mock.rs b/pallets/pallet-dip-consumer/src/mock.rs index 01782df842..15fc83446d 100644 --- a/pallets/pallet-dip-consumer/src/mock.rs +++ b/pallets/pallet-dip-consumer/src/mock.rs @@ -111,7 +111,7 @@ impl Contains for OnlySystemRemarksWithoutEventsAndDidLookupCalls { } // Returns success if `Proof` is `true`, and bumps the identity details by one, -// or instanciates them to `Default` if they're `None`. +// or instantiates them to `Default` if they're `None`. pub struct BooleanProofVerifier; impl IdentityProofVerifier for BooleanProofVerifier { type Error = u16; From e09f1f1ff45a220ed81a6e328abcdf8e3baec903 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Fri, 1 Mar 2024 11:28:08 +0100 Subject: [PATCH 25/39] Fix Default bounds for test functions --- .../src/merkle/v0/dip_subject_state/mod.rs | 3 --- .../src/merkle/v0/input_common.rs | 21 ++++++++++++++++++- .../src/merkle/v0/provider_state/mod.rs | 6 ------ .../src/merkle/v0/relay_state/mod.rs | 6 ------ 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs index b525945c41..c773e213e1 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs @@ -139,10 +139,7 @@ impl< MAX_REVEALED_LEAVES_COUNT, > where KiltDidKeyId: Default, - KiltAccountId: Default, KiltBlockNumber: Default, - KiltWeb3Name: Default, - KiltLinkableAccountId: Default, ConsumerBlockNumber: Default, { pub(crate) fn with_signature_time(valid_until: ConsumerBlockNumber) -> Self { diff --git a/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs b/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs index 57480b4460..42c14eddd1 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs @@ -69,7 +69,6 @@ impl kilt_support::traits::GetWorstCase for DipCommitmentState /// * `ProviderLinkableAccountId`: The linkable account ID type configured by /// the provider. #[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] -#[cfg_attr(test, derive(Default))] pub struct DidMerkleProof< ProviderDidKeyId, ProviderAccountId, @@ -138,6 +137,26 @@ impl< } } +#[cfg(test)] +impl Default + for DidMerkleProof< + ProviderDidKeyId, + ProviderAccountId, + ProviderBlockNumber, + ProviderWeb3Name, + ProviderLinkableAccountId, + > where + ProviderDidKeyId: Default, + ProviderBlockNumber: Default, +{ + fn default() -> Self { + Self { + revealed: Default::default(), + blinded: Default::default(), + } + } +} + /// A DID signature anchored to a specific block height. /// /// The generic types indicate the following: diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs index 616524f7d6..32d807d100 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs @@ -135,10 +135,7 @@ impl< ConsumerBlockNumber, > where KiltDidKeyId: Default, - KiltAccountId: Default, KiltBlockNumber: Default, - KiltWeb3Name: Default, - KiltLinkableAccountId: Default, ConsumerBlockNumber: Default, { pub(crate) fn with_provider_head_proof(provider_head_proof: ProviderHeadStateProof) -> Self { @@ -401,10 +398,7 @@ impl< ConsumerBlockNumber, > where KiltDidKeyId: Default, - KiltAccountId: Default, KiltBlockNumber: Default, - KiltWeb3Name: Default, - KiltLinkableAccountId: Default, ConsumerBlockNumber: Default, { pub(crate) fn with_state_root_and_dip_commitment_proof( diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs index defd64748d..ef814f215e 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs @@ -172,10 +172,7 @@ impl< > where RelayBlockNumber: Default, KiltDidKeyId: Default, - KiltAccountId: Default, KiltBlockNumber: Default, - KiltWeb3Name: Default, - KiltLinkableAccountId: Default, { pub(crate) fn with_header(header: Header) -> Self { Self { @@ -306,10 +303,7 @@ impl< > where RelayBlockNumber: Default, KiltDidKeyId: Default, - KiltAccountId: Default, KiltBlockNumber: Default, - KiltWeb3Name: Default, - KiltLinkableAccountId: Default, { pub(crate) fn with_relay_state_root_and_provider_head_proof( relay_state_root: StateRoot, From 0139011ea81af9994fb1b65e0c19dc5f915cfa94 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 4 Mar 2024 14:34:46 +0100 Subject: [PATCH 26/39] Fix bug and new test added --- .../src/merkle/v0/dip_subject_state/mod.rs | 23 ++++++---- .../src/merkle/v0/dip_subject_state/tests.rs | 45 ++++++++++++++++++- .../src/merkle/v0/output_common.rs | 38 +++++++++------- .../src/verifier/parachain/mod.rs | 4 +- .../src/verifier/parachain/v0/mock.rs | 10 +++-- .../src/verifier/parachain/v0/mod.rs | 10 ++--- .../src/verifier/relaychain/mod.rs | 4 +- .../src/verifier/relaychain/v0/mod.rs | 10 ++--- 8 files changed, 99 insertions(+), 45 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs index c773e213e1..440e97ddfd 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs @@ -22,6 +22,7 @@ use did::{ }; use sp_core::ConstU32; use sp_runtime::{traits::SaturatedConversion, BoundedVec}; +use sp_std::vec::Vec; use crate::{ merkle::v0::{ @@ -228,9 +229,9 @@ impl< }) ) }); - let maybe_signing_key_index = revealed_verification_keys + let signing_leaves_indices = revealed_verification_keys .enumerate() - .find(|(_, revealed_verification_key)| { + .filter(|(_, revealed_verification_key)| { let RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey { details: DidPublicKeyDetails { @@ -244,11 +245,10 @@ impl< }; verification_key.verify_signature(payload, &self.signature).is_ok() }) - .map(|(index, _)| u32::saturated_from(index)); + .map(|(index, _)| u32::saturated_from(index)) + .collect::>(); - let signing_key_entry = if let Some(index) = maybe_signing_key_index { - (self.revealed_leaves, index) - } else { + if signing_leaves_indices.is_empty() { cfg_if::cfg_if! { if #[cfg(feature = "runtime-benchmarks")] { return Ok(DipOriginInfo::default()); @@ -256,11 +256,16 @@ impl< return Err(Error::InvalidDidKeyRevealed); } } - }; + } + + let signing_leaves_indices_vector = signing_leaves_indices.try_into().map_err(|_| { + log::error!("Should never fail to convert vector of signing leaf indices into BoundedVec."); + Error::Internal + })?; Ok(DipOriginInfo { - revealed_leaves: signing_key_entry.0, - signing_leaf_index: signing_key_entry.1, + revealed_leaves: self.revealed_leaves, + signing_leaves_indices: signing_leaves_indices_vector, }) } } diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs index 6b68f10b05..3845184efb 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs @@ -59,7 +59,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { }; #[test] - fn retrieve_signing_leaf_for_payload_successful() { + fn retrieve_signing_leaf_for_payload_single_leaf_successful() { let payload = b"Hello, world!"; let (did_key_pair, _) = ed25519::Pair::generate(); let did_auth_key: DidVerificationKey = did_key_pair.public().into(); @@ -83,7 +83,48 @@ mod dip_revealed_details_and_verified_did_signature_freshness { assert_eq!( revealed_details.retrieve_signing_leaf_for_payload(&payload.encode()), Ok(DipOriginInfo { - signing_leaf_index: 0, + signing_leaves_indices: vec![0].try_into().unwrap(), + revealed_leaves, + }) + ); + } + + #[test] + fn retrieve_signing_leaf_for_payload_multiple_leaves_successful() { + let payload = b"Hello, world!"; + let (did_key_pair, _) = ed25519::Pair::generate(); + let did_auth_key: DidVerificationKey = did_key_pair.public().into(); + let revealed_leaves: BoundedVec, ConstU32<2>> = vec![ + RevealedDidKey:: { + id: 0u32, + relationship: DidVerificationKeyRelationship::Authentication.into(), + details: DidPublicKeyDetails { + key: did_auth_key.clone().into(), + block_number: 0u32, + }, + } + .into(), + RevealedDidKey:: { + id: 0u32, + relationship: DidVerificationKeyRelationship::AssertionMethod.into(), + details: DidPublicKeyDetails { + key: did_auth_key.into(), + block_number: 0u32, + }, + } + .into(), + ] + .try_into() + .unwrap(); + let revealed_details: DipRevealedDetailsAndVerifiedDidSignatureFreshness<_, _, _, _, _, 2> = + DipRevealedDetailsAndVerifiedDidSignatureFreshness { + revealed_leaves: revealed_leaves.clone(), + signature: did_key_pair.sign(&payload.encode()).into(), + }; + assert_eq!( + revealed_details.retrieve_signing_leaf_for_payload(&payload.encode()), + Ok(DipOriginInfo { + signing_leaves_indices: vec![0, 1].try_into().unwrap(), revealed_leaves, }) ); diff --git a/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs b/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs index f71143f529..96f6775b76 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs @@ -41,8 +41,8 @@ pub struct DipOriginInfo< RevealedDidMerkleProofLeaf, ConstU32, >, - /// The index of the signing leaf from the vector above, - pub(crate) signing_leaf_index: u32, + /// The index of the signing leaves from the vector above. + pub(crate) signing_leaves_indices: BoundedVec>, } impl< @@ -80,19 +80,25 @@ impl< /// Returns a reference to the leaf that signed the cross-chain operation. /// This operation should never fail, so the only error it returns is an /// `Error::Internal` which, anyway, should never happen. - pub fn get_signing_leaf(&self) -> Result<&RevealedDidKey, Error> { - let leaf = &self - .revealed_leaves - .get(usize::saturated_from(self.signing_leaf_index)) - .ok_or_else(|| { - log::error!("Should never fail to retrieve the signing leaf."); - Error::Internal - })?; - let RevealedDidMerkleProofLeaf::DidKey(did_key) = leaf else { - log::error!("Should never fail to convert the signing leaf to a DID Key leaf."); - return Err(Error::Internal); - }; - Ok(did_key) + pub fn get_signing_leaves( + &self, + ) -> Result>, Error> { + let leaves = self + .signing_leaves_indices + .iter() + .map(|index| { + let leaf = self.revealed_leaves.get(usize::saturated_from(*index)).ok_or_else(|| { + log::error!("Should never fail to retrieve the signing leaf at index {:#?}.", index); + Error::Internal + })?; + let RevealedDidMerkleProofLeaf::DidKey(did_key) = leaf else { + log::error!("Should never fail to convert the signing leaf to a DID Key leaf."); + return Err(Error::Internal); + }; + Ok(did_key) + }) + .collect::, _>>()?; + Ok(leaves.into_iter()) } } @@ -134,7 +140,7 @@ impl< .unwrap(); Self { revealed_leaves: bounded_keys, - signing_leaf_index: 0u32, + signing_leaves_indices: Default::default(), } } } diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs index 55e39632f1..811dd84c39 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs @@ -24,7 +24,7 @@ use pallet_dip_provider::traits::IdentityCommitmentGenerator; use pallet_web3_names::Web3NameOf; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; -use sp_std::{fmt::Debug, marker::PhantomData}; +use sp_std::{fmt::Debug, marker::PhantomData, vec::Vec}; use crate::{ merkle::v0::RevealedDidKey, @@ -172,7 +172,7 @@ impl< SignedExtra::Result: Encode, DidCallVerifier: DipCallOriginFilter< RuntimeCallOf, - OriginInfo = RevealedDidKey, BlockNumberFor, KiltRuntime::AccountId>, + OriginInfo = Vec, BlockNumberFor, KiltRuntime::AccountId>>, >, DidCallVerifier::Error: Into, { diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs index 50f956bb43..4198f46495 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs @@ -106,10 +106,12 @@ pub struct FilterNothing; impl DipCallOriginFilter for FilterNothing { type Error = u8; - type OriginInfo = RevealedDidKey< - KeyIdOf, - BlockNumberFor, - ::AccountId, + type OriginInfo = Vec< + RevealedDidKey< + KeyIdOf, + BlockNumberFor, + ::AccountId, + >, >; type Success = (); diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs index 2f5e94c0a4..9028e382a7 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs @@ -25,7 +25,7 @@ use pallet_dip_provider::traits::IdentityCommitmentGenerator; use pallet_web3_names::Web3NameOf; use parity_scale_codec::Encode; use sp_runtime::{traits::Zero, SaturatedConversion}; -use sp_std::marker::PhantomData; +use sp_std::{marker::PhantomData, vec::Vec}; use crate::{ merkle::v0::ParachainDipDidProof, @@ -139,7 +139,7 @@ impl< SignedExtra::Result: Encode, DidCallVerifier: DipCallOriginFilter< RuntimeCallOf, - OriginInfo = RevealedDidKey, BlockNumberFor, KiltRuntime::AccountId>, + OriginInfo = Vec, BlockNumberFor, KiltRuntime::AccountId>>, >, DidCallVerifier::Error: Into, { @@ -244,10 +244,10 @@ impl< .map_err(DipParachainStateProofVerifierError::ProofVerification)?; // 5. Verify the signing key fulfills the requirements - let signing_key = revealed_did_info - .get_signing_leaf() + let signing_keys = revealed_did_info + .get_signing_leaves() .map_err(DipParachainStateProofVerifierError::ProofVerification)?; - DidCallVerifier::check_call_origin_info(call, signing_key) + DidCallVerifier::check_call_origin_info(call, &signing_keys.cloned().collect::>()) .map_err(DipParachainStateProofVerifierError::DidOriginError)?; // 6. Increment the local details diff --git a/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs b/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs index 64cb8ee733..9257920500 100644 --- a/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs @@ -26,7 +26,7 @@ use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_core::U256; use sp_runtime::traits::Hash; -use sp_std::{fmt::Debug, marker::PhantomData}; +use sp_std::{fmt::Debug, marker::PhantomData, vec::Vec}; use crate::{ merkle::v0::RevealedDidKey, @@ -128,7 +128,7 @@ impl< SignedExtra::Result: Encode, DidCallVerifier: DipCallOriginFilter< RuntimeCallOf, - OriginInfo = RevealedDidKey, BlockNumberFor, KiltRuntime::AccountId>, + OriginInfo = Vec, BlockNumberFor, KiltRuntime::AccountId>>, >, DidCallVerifier::Error: Into, { diff --git a/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs index f53ad2db8f..be45fd5183 100644 --- a/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs @@ -26,7 +26,7 @@ use pallet_web3_names::Web3NameOf; use parity_scale_codec::Encode; use sp_core::U256; use sp_runtime::{traits::Zero, SaturatedConversion}; -use sp_std::marker::PhantomData; +use sp_std::{marker::PhantomData, vec::Vec}; use crate::{ traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, @@ -121,7 +121,7 @@ impl< SignedExtra::Result: Encode, DidCallVerifier: DipCallOriginFilter< RuntimeCallOf, - OriginInfo = RevealedDidKey, BlockNumberFor, KiltRuntime::AccountId>, + OriginInfo = Vec, BlockNumberFor, KiltRuntime::AccountId>>, >, DidCallVerifier::Error: Into, { @@ -221,10 +221,10 @@ impl< .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; // 6. Verify the signing key fulfills the requirements - let signing_key = revealed_did_info - .get_signing_leaf() + let signing_keys = revealed_did_info + .get_signing_leaves() .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; - DidCallVerifier::check_call_origin_info(call, signing_key) + DidCallVerifier::check_call_origin_info(call, &signing_keys.cloned().collect::>()) .map_err(DipRelaychainStateProofVerifierError::DidOriginError)?; // 7. Increment the local details From e9f70101223c3125c878f85c0d15f786604dbdd2 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 4 Mar 2024 14:42:19 +0100 Subject: [PATCH 27/39] Add wrong key in test case to test for filtering logic --- .../src/merkle/v0/dip_subject_state/tests.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs index 3845184efb..07e2616be7 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs @@ -94,7 +94,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { let payload = b"Hello, world!"; let (did_key_pair, _) = ed25519::Pair::generate(); let did_auth_key: DidVerificationKey = did_key_pair.public().into(); - let revealed_leaves: BoundedVec, ConstU32<2>> = vec![ + let revealed_leaves: BoundedVec, ConstU32<3>> = vec![ RevealedDidKey:: { id: 0u32, relationship: DidVerificationKeyRelationship::Authentication.into(), @@ -104,6 +104,17 @@ mod dip_revealed_details_and_verified_did_signature_freshness { }, } .into(), + RevealedDidKey:: { + id: 0u32, + relationship: DidVerificationKeyRelationship::CapabilityDelegation.into(), + details: DidPublicKeyDetails { + // This key should be filtered out from the result, since it does not verify successfully for the + // provided payload and signature. + key: DidVerificationKey::from(ed25519::Public([100; 32])).into(), + block_number: 0u32, + }, + } + .into(), RevealedDidKey:: { id: 0u32, relationship: DidVerificationKeyRelationship::AssertionMethod.into(), @@ -116,7 +127,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { ] .try_into() .unwrap(); - let revealed_details: DipRevealedDetailsAndVerifiedDidSignatureFreshness<_, _, _, _, _, 2> = + let revealed_details: DipRevealedDetailsAndVerifiedDidSignatureFreshness<_, _, _, _, _, 3> = DipRevealedDetailsAndVerifiedDidSignatureFreshness { revealed_leaves: revealed_leaves.clone(), signature: did_key_pair.sign(&payload.encode()).into(), @@ -124,7 +135,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { assert_eq!( revealed_details.retrieve_signing_leaf_for_payload(&payload.encode()), Ok(DipOriginInfo { - signing_leaves_indices: vec![0, 1].try_into().unwrap(), + signing_leaves_indices: vec![0, 2].try_into().unwrap(), revealed_leaves, }) ); From ef42867893a1310baf67797b91cc4c52a7207950 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 4 Mar 2024 14:58:45 +0100 Subject: [PATCH 28/39] Rename leaf revelation function --- .../src/merkle/v0/dip_subject_state/mod.rs | 4 ++-- .../src/merkle/v0/dip_subject_state/tests.rs | 12 ++++++------ .../src/merkle/v0/output_common.rs | 17 ++++++++++++++++- .../src/verifier/parachain/v0/mod.rs | 2 +- .../src/verifier/relaychain/v0/mod.rs | 2 +- .../src/dip/merkle/v0/tests/generate_proof.rs | 10 +++++----- 6 files changed, 31 insertions(+), 16 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs index 440e97ddfd..48b6da60bb 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs @@ -204,9 +204,9 @@ impl< KiltDidKeyId: BenchmarkDefault, KiltBlockNumber: BenchmarkDefault, { - /// Iterates over the revealed DID leafs to find the one that generated a + /// Iterates over the revealed DID leaves to find the ones that generated a /// valid signature for the provided payload. - pub fn retrieve_signing_leaf_for_payload( + pub fn retrieve_signing_leaves_for_payload( self, payload: &[u8], ) -> Result< diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs index 07e2616be7..170db0e2ae 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs @@ -59,7 +59,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { }; #[test] - fn retrieve_signing_leaf_for_payload_single_leaf_successful() { + fn retrieve_signing_leaves_for_payload_single_leaf_successful() { let payload = b"Hello, world!"; let (did_key_pair, _) = ed25519::Pair::generate(); let did_auth_key: DidVerificationKey = did_key_pair.public().into(); @@ -81,7 +81,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { signature: did_key_pair.sign(&payload.encode()).into(), }; assert_eq!( - revealed_details.retrieve_signing_leaf_for_payload(&payload.encode()), + revealed_details.retrieve_signing_leaves_for_payload(&payload.encode()), Ok(DipOriginInfo { signing_leaves_indices: vec![0].try_into().unwrap(), revealed_leaves, @@ -90,7 +90,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { } #[test] - fn retrieve_signing_leaf_for_payload_multiple_leaves_successful() { + fn retrieve_signing_leaves_for_payload_multiple_leaves_successful() { let payload = b"Hello, world!"; let (did_key_pair, _) = ed25519::Pair::generate(); let did_auth_key: DidVerificationKey = did_key_pair.public().into(); @@ -133,7 +133,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { signature: did_key_pair.sign(&payload.encode()).into(), }; assert_eq!( - revealed_details.retrieve_signing_leaf_for_payload(&payload.encode()), + revealed_details.retrieve_signing_leaves_for_payload(&payload.encode()), Ok(DipOriginInfo { signing_leaves_indices: vec![0, 2].try_into().unwrap(), revealed_leaves, @@ -142,7 +142,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { } #[test] - fn retrieve_signing_leaf_for_payload_no_key_present() { + fn retrieve_signing_leaves_for_payload_no_key_present() { let did_auth_key: DidVerificationKey = ed25519::Public([0u8; 32]).into(); let revealed_leaves: BoundedVec, ConstU32<1>> = vec![RevealedDidKey:: { @@ -162,7 +162,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { signature: ed25519::Signature([100u8; 64]).into(), }; assert_err!( - revealed_details.retrieve_signing_leaf_for_payload(&().encode()), + revealed_details.retrieve_signing_leaves_for_payload(&().encode()), Error::InvalidDidKeyRevealed ); } diff --git a/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs b/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs index 96f6775b76..502cd1dc43 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs @@ -77,7 +77,22 @@ impl< self.revealed_leaves.iter() } - /// Returns a reference to the leaf that signed the cross-chain operation. + /// Returns an owned iterator over the revealed DID leaves. + pub fn into_iter_leaves( + self, + ) -> impl Iterator< + Item = RevealedDidMerkleProofLeaf< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + >, + > { + self.revealed_leaves.into_iter() + } + + /// Returns a reference to the leaves that signed the cross-chain operation. /// This operation should never fail, so the only error it returns is an /// `Error::Internal` which, anyway, should never happen. pub fn get_signing_leaves( diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs index 9028e382a7..91067f4a2a 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs @@ -240,7 +240,7 @@ impl< .encode(); let revealed_did_info = proof_without_dip_merkle .verify_signature_time(¤t_block_number) - .and_then(|p| p.retrieve_signing_leaf_for_payload(&encoded_payload[..])) + .and_then(|p| p.retrieve_signing_leaves_for_payload(&encoded_payload[..])) .map_err(DipParachainStateProofVerifierError::ProofVerification)?; // 5. Verify the signing key fulfills the requirements diff --git a/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs index be45fd5183..8d319f74f7 100644 --- a/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs @@ -217,7 +217,7 @@ impl< let encoded_payload = (call, &identity_details, submitter, consumer_genesis_hash, signed_extra).encode(); let revealed_did_info = proof_without_dip_merkle .verify_signature_time(¤t_block_number) - .and_then(|p| p.retrieve_signing_leaf_for_payload(&encoded_payload[..])) + .and_then(|p| p.retrieve_signing_leaves_for_payload(&encoded_payload[..])) .map_err(DipRelaychainStateProofVerifierError::ProofVerification)?; // 6. Verify the signing key fulfills the requirements diff --git a/runtimes/common/src/dip/merkle/v0/tests/generate_proof.rs b/runtimes/common/src/dip/merkle/v0/tests/generate_proof.rs index 5948ff4c1c..ea40d90aeb 100644 --- a/runtimes/common/src/dip/merkle/v0/tests/generate_proof.rs +++ b/runtimes/common/src/dip/merkle/v0/tests/generate_proof.rs @@ -83,7 +83,7 @@ fn generate_proof_for_complete_linked_info() { let dip_origin_info = cross_chain_proof .verify_dip_proof::() .and_then(|r| r.verify_signature_time(&50)) - .and_then(|r| r.retrieve_signing_leaf_for_payload(&().encode())) + .and_then(|r| r.retrieve_signing_leaves_for_payload(&().encode())) .unwrap(); // All key agreement keys, plus authentication, attestation, and delegation key, // plus all linked accounts, plus web3name. @@ -185,7 +185,7 @@ fn generate_proof_for_complete_linked_info() { let dip_origin_info = cross_chain_proof .verify_dip_proof::() .and_then(|r| r.verify_signature_time(&50)) - .and_then(|r| r.retrieve_signing_leaf_for_payload(&().encode())) + .and_then(|r| r.retrieve_signing_leaves_for_payload(&().encode())) .unwrap(); // Only the authentication key. let expected_leaves_revealed = 1; @@ -256,7 +256,7 @@ fn generate_proof_for_complete_linked_info() { let dip_origin_info = cross_chain_proof .verify_dip_proof::() .and_then(|r| r.verify_signature_time(&50)) - .and_then(|r| r.retrieve_signing_leaf_for_payload(&().encode())) + .and_then(|r| r.retrieve_signing_leaves_for_payload(&().encode())) .unwrap(); // The authentication key and the web3name. let expected_leaves_revealed = 2; @@ -310,7 +310,7 @@ fn generate_proof_for_complete_linked_info() { let dip_origin_info = cross_chain_proof .verify_dip_proof::() .and_then(|r| r.verify_signature_time(&50)) - .and_then(|r| r.retrieve_signing_leaf_for_payload(&().encode())) + .and_then(|r| r.retrieve_signing_leaves_for_payload(&().encode())) .unwrap(); // The authentication key and the web3name. let expected_leaves_revealed = 2; @@ -446,7 +446,7 @@ fn generate_proof_with_two_keys_with_same_id() { let dip_origin_info = cross_chain_proof .verify_dip_proof::() .and_then(|r| r.verify_signature_time(&50)) - .and_then(|r| r.retrieve_signing_leaf_for_payload(&().encode())) + .and_then(|r| r.retrieve_signing_leaves_for_payload(&().encode())) .unwrap(); // Authentication key and attestation key have the same key ID, but they are // different keys, so there should be 2 leaves. From 137bbdee9a9836b07d6610e4ce6644f7ba0c493d Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Mon, 4 Mar 2024 15:11:25 +0100 Subject: [PATCH 29/39] Fix compilation issues --- dip-template/runtimes/dip-consumer/src/dip.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dip-template/runtimes/dip-consumer/src/dip.rs b/dip-template/runtimes/dip-consumer/src/dip.rs index 31c53e0338..fa7a97516b 100644 --- a/dip-template/runtimes/dip-consumer/src/dip.rs +++ b/dip-template/runtimes/dip-consumer/src/dip.rs @@ -26,7 +26,7 @@ use kilt_dip_primitives::{ use pallet_dip_consumer::traits::IdentityProofVerifier; use rococo_runtime::Runtime as RelaychainRuntime; use sp_core::ConstU32; -use sp_std::marker::PhantomData; +use sp_std::{marker::PhantomData, vec::Vec}; use crate::{weights, AccountId, DidIdentifier, Runtime, RuntimeCall, RuntimeOrigin}; @@ -154,18 +154,18 @@ impl DipCallOriginFilt for DipCallFilter { type Error = DipCallFilterError; - type OriginInfo = RevealedDidKey; + type OriginInfo = Vec>; type Success = (); // Accepts only a DipOrigin for the DidLookup pallet calls. fn check_call_origin_info(call: &RuntimeCall, info: &Self::OriginInfo) -> Result { - let revealed_key_relationship: DidVerificationKeyRelationship = info - .relationship - .try_into() - .map_err(|_| DipCallFilterError::WrongVerificationRelationship)?; let expected_key_relationship = single_key_relationship([call].into_iter()).map_err(|_| DipCallFilterError::BadOrigin)?; - if revealed_key_relationship == expected_key_relationship { + // If any of the keys revealed is of the right relationship, it's ok. + if info + .iter() + .any(|did_key| did_key.relationship == expected_key_relationship.into()) + { Ok(()) } else { Err(DipCallFilterError::WrongVerificationRelationship) From a38b83ae0b99dc54552f7d27df67b5ea78ff8107 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 6 Mar 2024 11:13:50 +0100 Subject: [PATCH 30/39] Explicit Vec type --- .../src/merkle/v0/dip_subject_state/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs index 48b6da60bb..1f7bfcd480 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs @@ -229,7 +229,7 @@ impl< }) ) }); - let signing_leaves_indices = revealed_verification_keys + let signing_leaves_indices: Vec<_> = revealed_verification_keys .enumerate() .filter(|(_, revealed_verification_key)| { let RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey { @@ -246,7 +246,7 @@ impl< verification_key.verify_signature(payload, &self.signature).is_ok() }) .map(|(index, _)| u32::saturated_from(index)) - .collect::>(); + .collect(); if signing_leaves_indices.is_empty() { cfg_if::cfg_if! { From 30c8ec271f03da9e2f01f0e35351f2319bb32f6f Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 6 Mar 2024 11:14:59 +0100 Subject: [PATCH 31/39] Remove explicit params --- .../src/merkle/v0/dip_subject_state/tests.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs index 170db0e2ae..b0d919e551 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs @@ -64,7 +64,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { let (did_key_pair, _) = ed25519::Pair::generate(); let did_auth_key: DidVerificationKey = did_key_pair.public().into(); let revealed_leaves: BoundedVec, ConstU32<1>> = - vec![RevealedDidKey:: { + vec![RevealedDidKey { id: 0u32, relationship: DidVerificationKeyRelationship::Authentication.into(), details: DidPublicKeyDetails { @@ -95,7 +95,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { let (did_key_pair, _) = ed25519::Pair::generate(); let did_auth_key: DidVerificationKey = did_key_pair.public().into(); let revealed_leaves: BoundedVec, ConstU32<3>> = vec![ - RevealedDidKey:: { + RevealedDidKey { id: 0u32, relationship: DidVerificationKeyRelationship::Authentication.into(), details: DidPublicKeyDetails { @@ -104,7 +104,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { }, } .into(), - RevealedDidKey:: { + RevealedDidKey { id: 0u32, relationship: DidVerificationKeyRelationship::CapabilityDelegation.into(), details: DidPublicKeyDetails { @@ -115,7 +115,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { }, } .into(), - RevealedDidKey:: { + RevealedDidKey { id: 0u32, relationship: DidVerificationKeyRelationship::AssertionMethod.into(), details: DidPublicKeyDetails { @@ -145,7 +145,7 @@ mod dip_revealed_details_and_verified_did_signature_freshness { fn retrieve_signing_leaves_for_payload_no_key_present() { let did_auth_key: DidVerificationKey = ed25519::Public([0u8; 32]).into(); let revealed_leaves: BoundedVec, ConstU32<1>> = - vec![RevealedDidKey:: { + vec![RevealedDidKey { id: 0u32, relationship: DidVerificationKeyRelationship::Authentication.into(), details: DidPublicKeyDetails { From 29738f0acb35b16f83cc784be492197318599cdc Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 6 Mar 2024 12:18:31 +0100 Subject: [PATCH 32/39] Refactor test case input --- .../src/merkle/v0/provider_state/tests.rs | 301 +++++------------- 1 file changed, 88 insertions(+), 213 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs index 16b8363781..648f095e9f 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs @@ -30,15 +30,13 @@ mod parachain_dip_did_proof { use crate::{state_proofs::MerkleProofError, Error, ParachainDipDidProof, ProviderHeadStateProof}; - #[test] - fn verify_provider_head_proof_with_state_root_successful() { - // Storage proof generated at Polkadot block `19_663_508` with hash - // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for - // storage key - // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000` - // (`paras::heads(2_086)`) - let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); - let provider_head_proof = ProviderHeadStateProof { + // Storage proof generated at Polkadot block `19_663_508` with hash + // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for + // storage key + // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000` + // (`paras::heads(2_086)`) + fn provider_head_proof() -> (H256, ProviderHeadStateProof) { + (hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(), ProviderHeadStateProof { relay_block_number: 19_663_508, proof: vec![ hex!("560cfd6c23b92a7826080000f102e902fb1bd938b2f4fcea70641da8e64e0e11098b92b767279227cdfdc0ae9500da99d27e5f012937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56eacc28c5503a155c4d8bc7ee4797c38e212428cefff0a7ad19b28ebbab793e64080661757261204a207d0800000000056175726101017cda19117c87384aaebfd2ae546771bcfbfe7011a91119932883382cc62be3050d745c9734f422228c7c43d87e6172519019829b14b2d3b64afafb1fb7d3a683").to_vec(), @@ -48,7 +46,12 @@ mod parachain_dip_did_proof { hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() ].into_iter().into(), - }; + }) + } + + #[test] + fn verify_provider_head_proof_with_state_root_successful() { + let (relay_state_root, provider_head_proof) = provider_head_proof(); // Only interested in the parachain head verification part, we skip everything // else. let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); @@ -102,23 +105,7 @@ mod parachain_dip_did_proof { #[test] fn verify_provider_head_proof_with_state_root_wrong_relay_hasher() { - // Storage proof generated at Polkadot block `19_663_508` with hash - // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for - // storage key - // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000` - // (`paras::heads(2_086)`) - let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); - let provider_head_proof = ProviderHeadStateProof { - relay_block_number: 19_663_508, - proof: vec![ - hex!("560cfd6c23b92a7826080000f102e902fb1bd938b2f4fcea70641da8e64e0e11098b92b767279227cdfdc0ae9500da99d27e5f012937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56eacc28c5503a155c4d8bc7ee4797c38e212428cefff0a7ad19b28ebbab793e64080661757261204a207d0800000000056175726101017cda19117c87384aaebfd2ae546771bcfbfe7011a91119932883382cc62be3050d745c9734f422228c7c43d87e6172519019829b14b2d3b64afafb1fb7d3a683").to_vec(), - hex!("80021080f0c4027f5eba380b623a2d3382ab03961b2b7e753e62d3475a6940207db367cc80fde8c5a37120e2f1d987f5302783d22f8ac1b213c580030a7f5b15e706df6262").to_vec(), - hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), - hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), - hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), - hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() - ].into_iter().into(), - }; + let (relay_state_root, provider_head_proof) = provider_head_proof(); let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); assert_err!( // Using a different hasher for verification @@ -132,27 +119,11 @@ mod parachain_dip_did_proof { #[test] fn verify_provider_head_proof_with_state_root_wrong_para_id() { - // Storage proof generated at Polkadot block `19_663_508` with hash - // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for - // storage key - // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c3b6ff6f7d467b87a9e8030000` - // (`paras::heads(1_000)`) - let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); - let provider_head_proof = ProviderHeadStateProof { - relay_block_number: 19_663_508, - proof: vec![ - hex!("56ff6f7d467b87a9e80300009903910331d9f8f427be99ba3b36ad6f66c49b5448e16745fc3cbe08821204e2e94c9abe1ef65e01dc0f3c52d9aaef735eae1aa679e6c3020e993fb3eef8fab9c32cc7b55dfc85362c771d9a07e5b6cf9f8e30b67598c513ca087574ecce0b3e205eb4de8783a4630c0661757261204a207d08000000000452505352906ca2562dd3ddae0ecb7076465e223753e76792653f739d5dfb00ad76a6b3607d4a2ab00405617572610101dadcb6f606d8a71dc6d0d4d20ccc3bd67bae8816c86491b14fa899242cd872f3bf5fe9635d4414f4329a578a0627cf367dcaa3e86beca64a9aaef9afd124c701").to_vec(), - hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), - hex!("80d510805396188100731505c3fe5f51e7d4a9c6e6e4cd2c50ff6d122f5f091a186b2f9780e69515c0c399ad09a7b5da0afb5a8bbd22c6873b69f9f2da18e26a8bd04c6e9d80d647e804958d947c20337a2ac3714b3eca41be52847542b065da3614230decab806dbb5b1913c89acb68a2e85013c4b7adf37ab010cf9b9d7346348d0ca9aafd4a80702af779edd6e8d659600cbe342947238af804d41589116a3dd7fb48905aeab18076a51b70378cbf602d939a885bbad80c94ee9325398105ec2173324bd7f59b55").to_vec(), - hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), - hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), - hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() - ].into_iter().into(), - }; + let (relay_state_root, provider_head_proof) = provider_head_proof(); let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); assert_err!( proof.verify_provider_head_proof_with_state_root::>( - 2_086, + 1_000, &relay_state_root ), Error::ParaHeadMerkleProof(MerkleProofError::InvalidProof) @@ -161,25 +132,15 @@ mod parachain_dip_did_proof { #[test] fn verify_provider_head_proof_with_state_root_invalid_proof() { - // Storage proof generated at Polkadot block `19_663_508` with hash - // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for - // storage key - // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000` - // (`paras::heads(2_086)`) - let relay_state_root: H256 = hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(); - let provider_head_proof = ProviderHeadStateProof { - relay_block_number: 19_663_508, - // Last proof component removed - proof: vec![ - hex!("560cfd6c23b92a7826080000f102e902fb1bd938b2f4fcea70641da8e64e0e11098b92b767279227cdfdc0ae9500da99d27e5f012937179bfe939750c770f2aa6e84c6b8cf9d0aa9ab852243ceb78e3eeb93fc56eacc28c5503a155c4d8bc7ee4797c38e212428cefff0a7ad19b28ebbab793e64080661757261204a207d0800000000056175726101017cda19117c87384aaebfd2ae546771bcfbfe7011a91119932883382cc62be3050d745c9734f422228c7c43d87e6172519019829b14b2d3b64afafb1fb7d3a683").to_vec(), - hex!("80021080f0c4027f5eba380b623a2d3382ab03961b2b7e753e62d3475a6940207db367cc80fde8c5a37120e2f1d987f5302783d22f8ac1b213c580030a7f5b15e706df6262").to_vec(), - hex!("8004648019885bbc2709cbd3a89f9a8813867f322e5663c99fdea9af3ff2ba0010455d5d8091eb4873541a81f69d22ccd903b864c36c747910eec7433d947e5a61f87eb7db80ca85a51ad63cbcb7a988023f3b082492a6937f9957c029eb34d6d618279d232d8048dcb685fcf3963e7697a630c6ce64ff06f325063bb05e34e679eb01a4e2b644").to_vec(), - hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), - hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), - // hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() - ].into_iter().into(), + let (relay_state_root, provider_head_proof) = provider_head_proof(); + // Remove last part of the blinded component to get an invalid proof + let (_, invalid_blinded_proof) = provider_head_proof.proof.split_last().unwrap(); + let invalid_provider_head_proof = ProviderHeadStateProof { + proof: invalid_blinded_proof.iter().cloned().into(), + ..provider_head_proof }; - let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); + let proof = + ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(invalid_provider_head_proof); assert_err!( proof.verify_provider_head_proof_with_state_root::>( 2_086, @@ -247,21 +208,23 @@ mod dip_did_proof_with_verified_relay_state_root { type WeightInfo = (); } - #[test] - fn verify_dip_commitment_proof_for_subject_successful() { - // Storage proof generated at Peregrine block `5_258_991` with hash - // `0xd83da28e40d6e193af832916d2741252955d438c9d17a9f441279085db3e8daf` for - // storage key - // `0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f30d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000` - // (`dipProvider::identityCommitments(4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK, 0)`) - let parachain_state_root: H256 = - hex!("3a27f8d59c8bcc51bf3735ecdc0ce1304127a5b9e707e956e22633179493d55c").into(); - let dip_commitment_proof = DipCommitmentStateProof(vec![ + // Storage proof generated at Peregrine block `5_258_991` with hash + // `0xd83da28e40d6e193af832916d2741252955d438c9d17a9f441279085db3e8daf` for + // storage key + // `0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f30d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000` + // (`dipProvider::identityCommitments(4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK, 0)`) + fn dip_commitment_proof() -> (H256, DipCommitmentStateProof) { + (hex!("3a27f8d59c8bcc51bf3735ecdc0ce1304127a5b9e707e956e22633179493d55c").into(), DipCommitmentStateProof(vec![ hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd8003ab0887cbb70c4e0d8d0f738e4b05732fd8cb5da24fa5f1112e20ba3603d58a80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), hex!("80ffff808a66c19052add13a202bcd73b546ae0cb70544f166c4a469672c666f0a5f9d8a80b84c2df313e2e749ff7e47eee888d9a023ba0a14a59852f4526b3e4b93b6dcbc807310fd50a0ae630c15e9eb07bda831d6d0cb6044d53a3dafb68e3fdb199fffdf80015ecd5e8af66e3d72ee5cc828c25989ca848e55396cccd9c196a4df1349fb9980a2ec48e449c43cc34954836cc14af398695f6569e301cef5a13eb88a16aa395580fd068d1339506db2893ba54a00a85aa712d68ff98ceeb5f4632f4e53618bb77880a3f173abac33e571e2a66f13127eeec3fb31bb1ae6f4b0fca8e658bbfbb5e52a803084ef6eaf38b821c59b3de92c4679117509b0b031e52ef5a80fdcff72e498ec804f36b8fb07a75463165f1714181009c86a2790685e78abd43220f5ecb194c887802559300c82eef4b21724bba2706cc2815e98cac3993c8d8dc9057b1aaf45ae8d8006571e929d492077d682dbc911934874ec00335029a90bd39e37d6d641e11873800397abe2ea62a374e5f0650c54fb99e8ef825066da798b0f4d729a7281f3575880b35cfb12f77988e1305ba651db7a8efbd43e4e8b057a56736cf6485f3033f481809ab1e406503e3ce63425a294f3f37aa4827b6a4ab38cf7e960a0d3335d79234e80be7c96632aa67491005e607a53bc1ab725fa465e29797bc29973d4cf5f64239b8037fe2a92c86d4c38ff38570b071e994ab86214e43e095dfb6ed142170fdac430").to_vec(), hex!("be75edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3010880ffe3135a9ee019dbfe4143608c9f4a4291ab827d7d9d055028d556d9cea2fce180eb5d42e7c6f84ac20e0d5ab42008c631b3e87f36d55d0d5053c9fb4f944ef97c").to_vec(), - ].into_iter().into()); + ].into_iter().into())) + } + + #[test] + fn verify_dip_commitment_proof_for_subject_successful() { + let (parachain_state_root, dip_commitment_proof) = dip_commitment_proof(); // Only interested in the DIP commitment verification part, we skip everything // else. let proof = @@ -316,19 +279,7 @@ mod dip_did_proof_with_verified_relay_state_root { #[test] fn verify_dip_commitment_proof_for_subject_wrong_provider_hasher() { - // Storage proof generated at Peregrine block `5_258_991` with hash - // `0xd83da28e40d6e193af832916d2741252955d438c9d17a9f441279085db3e8daf` for - // storage key - // `0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f30d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000` - // (`dipProvider::identityCommitments(4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK, 0)`) - let parachain_state_root: H256 = - hex!("3a27f8d59c8bcc51bf3735ecdc0ce1304127a5b9e707e956e22633179493d55c").into(); - let dip_commitment_proof = DipCommitmentStateProof(vec![ - hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), - hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd8003ab0887cbb70c4e0d8d0f738e4b05732fd8cb5da24fa5f1112e20ba3603d58a80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), - hex!("80ffff808a66c19052add13a202bcd73b546ae0cb70544f166c4a469672c666f0a5f9d8a80b84c2df313e2e749ff7e47eee888d9a023ba0a14a59852f4526b3e4b93b6dcbc807310fd50a0ae630c15e9eb07bda831d6d0cb6044d53a3dafb68e3fdb199fffdf80015ecd5e8af66e3d72ee5cc828c25989ca848e55396cccd9c196a4df1349fb9980a2ec48e449c43cc34954836cc14af398695f6569e301cef5a13eb88a16aa395580fd068d1339506db2893ba54a00a85aa712d68ff98ceeb5f4632f4e53618bb77880a3f173abac33e571e2a66f13127eeec3fb31bb1ae6f4b0fca8e658bbfbb5e52a803084ef6eaf38b821c59b3de92c4679117509b0b031e52ef5a80fdcff72e498ec804f36b8fb07a75463165f1714181009c86a2790685e78abd43220f5ecb194c887802559300c82eef4b21724bba2706cc2815e98cac3993c8d8dc9057b1aaf45ae8d8006571e929d492077d682dbc911934874ec00335029a90bd39e37d6d641e11873800397abe2ea62a374e5f0650c54fb99e8ef825066da798b0f4d729a7281f3575880b35cfb12f77988e1305ba651db7a8efbd43e4e8b057a56736cf6485f3033f481809ab1e406503e3ce63425a294f3f37aa4827b6a4ab38cf7e960a0d3335d79234e80be7c96632aa67491005e607a53bc1ab725fa465e29797bc29973d4cf5f64239b8037fe2a92c86d4c38ff38570b071e994ab86214e43e095dfb6ed142170fdac430").to_vec(), - hex!("be75edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3010880ffe3135a9ee019dbfe4143608c9f4a4291ab827d7d9d055028d556d9cea2fce180eb5d42e7c6f84ac20e0d5ab42008c631b3e87f36d55d0d5053c9fb4f944ef97c").to_vec(), - ].into_iter().into()); + let (parachain_state_root, dip_commitment_proof) = dip_commitment_proof(); // Only interested in the DIP commitment verification part, we skip everything // else. let proof = @@ -347,19 +298,7 @@ mod dip_did_proof_with_verified_relay_state_root { #[test] fn verify_dip_commitment_proof_for_subject_different_subject() { - // Storage proof generated at Peregrine block `5_258_991` with hash - // `0xd83da28e40d6e193af832916d2741252955d438c9d17a9f441279085db3e8daf` for - // storage key - // `0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f30d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000` - // (`dipProvider::identityCommitments(4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK, 0)`) - let parachain_state_root: H256 = - hex!("3a27f8d59c8bcc51bf3735ecdc0ce1304127a5b9e707e956e22633179493d55c").into(); - let dip_commitment_proof = DipCommitmentStateProof(vec![ - hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), - hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd8003ab0887cbb70c4e0d8d0f738e4b05732fd8cb5da24fa5f1112e20ba3603d58a80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), - hex!("80ffff808a66c19052add13a202bcd73b546ae0cb70544f166c4a469672c666f0a5f9d8a80b84c2df313e2e749ff7e47eee888d9a023ba0a14a59852f4526b3e4b93b6dcbc807310fd50a0ae630c15e9eb07bda831d6d0cb6044d53a3dafb68e3fdb199fffdf80015ecd5e8af66e3d72ee5cc828c25989ca848e55396cccd9c196a4df1349fb9980a2ec48e449c43cc34954836cc14af398695f6569e301cef5a13eb88a16aa395580fd068d1339506db2893ba54a00a85aa712d68ff98ceeb5f4632f4e53618bb77880a3f173abac33e571e2a66f13127eeec3fb31bb1ae6f4b0fca8e658bbfbb5e52a803084ef6eaf38b821c59b3de92c4679117509b0b031e52ef5a80fdcff72e498ec804f36b8fb07a75463165f1714181009c86a2790685e78abd43220f5ecb194c887802559300c82eef4b21724bba2706cc2815e98cac3993c8d8dc9057b1aaf45ae8d8006571e929d492077d682dbc911934874ec00335029a90bd39e37d6d641e11873800397abe2ea62a374e5f0650c54fb99e8ef825066da798b0f4d729a7281f3575880b35cfb12f77988e1305ba651db7a8efbd43e4e8b057a56736cf6485f3033f481809ab1e406503e3ce63425a294f3f37aa4827b6a4ab38cf7e960a0d3335d79234e80be7c96632aa67491005e607a53bc1ab725fa465e29797bc29973d4cf5f64239b8037fe2a92c86d4c38ff38570b071e994ab86214e43e095dfb6ed142170fdac430").to_vec(), - hex!("be75edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3010880ffe3135a9ee019dbfe4143608c9f4a4291ab827d7d9d055028d556d9cea2fce180eb5d42e7c6f84ac20e0d5ab42008c631b3e87f36d55d0d5053c9fb4f944ef97c").to_vec(), - ].into_iter().into()); + let (parachain_state_root, dip_commitment_proof) = dip_commitment_proof(); let proof = DipDidProofWithVerifiedStateRoot::<_, (), (), (), (), (), ()>::with_state_root_and_dip_commitment_proof( parachain_state_root, @@ -375,18 +314,14 @@ mod dip_did_proof_with_verified_relay_state_root { #[test] fn verify_dip_commitment_proof_for_subject_invalid_proof() { - let parachain_state_root: H256 = - hex!("3a27f8d59c8bcc51bf3735ecdc0ce1304127a5b9e707e956e22633179493d55c").into(); - let dip_commitment_proof = DipCommitmentStateProof(vec![ - hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), - hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd8003ab0887cbb70c4e0d8d0f738e4b05732fd8cb5da24fa5f1112e20ba3603d58a80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), - hex!("80ffff808a66c19052add13a202bcd73b546ae0cb70544f166c4a469672c666f0a5f9d8a80b84c2df313e2e749ff7e47eee888d9a023ba0a14a59852f4526b3e4b93b6dcbc807310fd50a0ae630c15e9eb07bda831d6d0cb6044d53a3dafb68e3fdb199fffdf80015ecd5e8af66e3d72ee5cc828c25989ca848e55396cccd9c196a4df1349fb9980a2ec48e449c43cc34954836cc14af398695f6569e301cef5a13eb88a16aa395580fd068d1339506db2893ba54a00a85aa712d68ff98ceeb5f4632f4e53618bb77880a3f173abac33e571e2a66f13127eeec3fb31bb1ae6f4b0fca8e658bbfbb5e52a803084ef6eaf38b821c59b3de92c4679117509b0b031e52ef5a80fdcff72e498ec804f36b8fb07a75463165f1714181009c86a2790685e78abd43220f5ecb194c887802559300c82eef4b21724bba2706cc2815e98cac3993c8d8dc9057b1aaf45ae8d8006571e929d492077d682dbc911934874ec00335029a90bd39e37d6d641e11873800397abe2ea62a374e5f0650c54fb99e8ef825066da798b0f4d729a7281f3575880b35cfb12f77988e1305ba651db7a8efbd43e4e8b057a56736cf6485f3033f481809ab1e406503e3ce63425a294f3f37aa4827b6a4ab38cf7e960a0d3335d79234e80be7c96632aa67491005e607a53bc1ab725fa465e29797bc29973d4cf5f64239b8037fe2a92c86d4c38ff38570b071e994ab86214e43e095dfb6ed142170fdac430").to_vec(), - // hex!("be75edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3010880ffe3135a9ee019dbfe4143608c9f4a4291ab827d7d9d055028d556d9cea2fce180eb5d42e7c6f84ac20e0d5ab42008c631b3e87f36d55d0d5053c9fb4f944ef97c").to_vec(), - ].into_iter().into()); + let (parachain_state_root, dip_commitment_proof) = dip_commitment_proof(); + // Remove last part of the blinded component to get an invalid proof + let (_, invalid_blinded_proof) = dip_commitment_proof.0.split_last().unwrap(); + let invalid_dip_commitment_proof = DipCommitmentStateProof(invalid_blinded_proof.iter().cloned().into()); let proof = DipDidProofWithVerifiedStateRoot::<_, (), (), (), (), (), ()>::with_state_root_and_dip_commitment_proof( parachain_state_root, - dip_commitment_proof, + invalid_dip_commitment_proof, ); assert_err!( proof.verify_dip_commitment_proof_for_subject::( @@ -411,94 +346,67 @@ mod dip_did_proof_with_verified_subject_commitment { AccountId32, BoundedVec, }; - use crate::{ - DidMerkleProof, DipDidProofWithVerifiedSubjectCommitment, Error, RevealedDidKey, RevealedDidMerkleProofLeaf, - }; + use crate::{DidMerkleProof, DipDidProofWithVerifiedSubjectCommitment, Error, RevealedDidKey}; - // TODO: Generate a valid DIP proof, and use it here. - #[test] - fn verify_dip_proof_successful() { - // DIP proof generated on Peregrine via the `dipProvider::generateProof` runtime - // API. - let dip_commitment: H256 = hex!("1997d38bec607be35cab175edc55e2119e0138976021e1f938942c10f9f7b329").into(); - let revealed_leaf: RevealedDidMerkleProofLeaf<_, _, _, BoundedVec>, LinkableAccountId> = - RevealedDidKey:: { - id: hex!("50da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a").into(), - relationship: DidVerificationKeyRelationship::Authentication.into(), - details: DidPublicKeyDetails { - key: DidVerificationKey::Ed25519(ed25519::Public(hex!( - "43a72e714401762df66b68c26dfbdf2682aaec9f2474eca4613e424a0fbafd3c" - ))) - .into(), - block_number: 0, - }, - } - .into(); - let dip_proof = DidMerkleProof { - blinded: vec![ - hex!( - "8027f4809d06d6e9516f8bcbe97b3e1fa94f294b2606a11d00f1162c90bbdbaa0cbc77d480421f140adb34 + // DIP proof generated on Peregrine via the `dipProvider::generateProof` runtime + // API. + #[allow(clippy::type_complexity)] + fn dip_proof() -> ( + H256, + DidMerkleProof>, LinkableAccountId>, + ) { + ( + hex!("1997d38bec607be35cab175edc55e2119e0138976021e1f938942c10f9f7b329").into(), + DidMerkleProof { + blinded: vec![ + hex!( + "8027f4809d06d6e9516f8bcbe97b3e1fa94f294b2606a11d00f1162c90bbdbaa0cbc77d480421f140adb34 53138eb8c4512f9cff60ee9a62502cbb0ddd30355235c12dbd318001ba7e874784b7c79fdc37d1584ff254 efb6d167087dcb1227c704fd9f6c21d40080a92c5bdfcfbb286551bc43fb263980bc9148f3645f6bc0743c 4292b88dc4039f8011e7fd2693a380b14bd3dd83736bec3bbcb7f70c7b7e0aaf30a03d2bbf96bd3b80c5a2 1afb7e16c0f8869ca44efbafddef083c89104fe153d0a77698a5aa1eef7d808cf84bd4fa37829f7229d507 3cbb504832fc88766def7b06930c5c27f7bf12a080dab6661eac3da9d306e8bbfdffb8ccc901239d8c1664 220062a4384224babea0" - ) - .to_vec(), - hex!("7f0400da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a010000").to_vec(), - ] - .into_iter() - .into(), - revealed: vec![revealed_leaf.clone()], - }; + ) + .to_vec(), + hex!("7f0400da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a010000").to_vec(), + ] + .into_iter() + .into(), + revealed: vec![RevealedDidKey { + id: hex!("50da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a").into(), + relationship: DidVerificationKeyRelationship::Authentication.into(), + details: DidPublicKeyDetails { + key: DidVerificationKey::Ed25519(ed25519::Public(hex!( + "43a72e714401762df66b68c26dfbdf2682aaec9f2474eca4613e424a0fbafd3c" + ))) + .into(), + block_number: 0, + }, + } + .into()], + }, + ) + } + + // TODO: Generate a valid DIP proof, and use it here. + #[test] + fn verify_dip_proof_successful() { + let (dip_commitment, dip_proof) = dip_proof(); let proof = DipDidProofWithVerifiedSubjectCommitment::<_, _, _, _, _, _, ()>::with_commitment_and_dip_proof( dip_commitment, - dip_proof, + dip_proof.clone(), ); let proof_verification_result = proof.verify_dip_proof::().unwrap(); assert_eq!( proof_verification_result.revealed_leaves.into_inner(), - vec![revealed_leaf] + vec![dip_proof.revealed.first().unwrap().to_owned()] ); } #[test] fn verify_dip_proof_wrong_merkle_hasher() { - // DIP proof generated on Peregrine via the `dipProvider::generateProof` runtime - // API. - let dip_commitment: H256 = hex!("1997d38bec607be35cab175edc55e2119e0138976021e1f938942c10f9f7b329").into(); - let revealed_leaf: RevealedDidMerkleProofLeaf<_, _, _, BoundedVec>, LinkableAccountId> = - RevealedDidKey:: { - id: hex!("50da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a").into(), - relationship: DidVerificationKeyRelationship::Authentication.into(), - details: DidPublicKeyDetails { - key: DidVerificationKey::Ed25519(ed25519::Public(hex!( - "43a72e714401762df66b68c26dfbdf2682aaec9f2474eca4613e424a0fbafd3c" - ))) - .into(), - block_number: 0, - }, - } - .into(); - let dip_proof = DidMerkleProof { - blinded: vec![ - hex!( - "8027f4809d06d6e9516f8bcbe97b3e1fa94f294b2606a11d00f1162c90bbdbaa0cbc77d480421f140adb34 - 53138eb8c4512f9cff60ee9a62502cbb0ddd30355235c12dbd318001ba7e874784b7c79fdc37d1584ff254 - efb6d167087dcb1227c704fd9f6c21d40080a92c5bdfcfbb286551bc43fb263980bc9148f3645f6bc0743c - 4292b88dc4039f8011e7fd2693a380b14bd3dd83736bec3bbcb7f70c7b7e0aaf30a03d2bbf96bd3b80c5a2 - 1afb7e16c0f8869ca44efbafddef083c89104fe153d0a77698a5aa1eef7d808cf84bd4fa37829f7229d507 - 3cbb504832fc88766def7b06930c5c27f7bf12a080dab6661eac3da9d306e8bbfdffb8ccc901239d8c1664 - 220062a4384224babea0" - ) - .to_vec(), - hex!("7f0400da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a010000").to_vec(), - ] - .into_iter() - .into(), - revealed: vec![revealed_leaf], - }; + let (dip_commitment, dip_proof) = dip_proof(); let proof = DipDidProofWithVerifiedSubjectCommitment::<_, _, _, _, _, _, ()>::with_commitment_and_dip_proof( dip_commitment, dip_proof, @@ -509,40 +417,7 @@ mod dip_did_proof_with_verified_subject_commitment { #[test] fn verify_dip_proof_too_many_leaves() { - // DIP proof generated on Peregrine via the `dipProvider::generateProof` runtime - // API. - let dip_commitment: H256 = hex!("1997d38bec607be35cab175edc55e2119e0138976021e1f938942c10f9f7b329").into(); - let revealed_leaf: RevealedDidMerkleProofLeaf<_, _, _, BoundedVec>, LinkableAccountId> = - RevealedDidKey:: { - id: hex!("50da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a").into(), - relationship: DidVerificationKeyRelationship::Authentication.into(), - details: DidPublicKeyDetails { - key: DidVerificationKey::Ed25519(ed25519::Public(hex!( - "43a72e714401762df66b68c26dfbdf2682aaec9f2474eca4613e424a0fbafd3c" - ))) - .into(), - block_number: 0, - }, - } - .into(); - let dip_proof = DidMerkleProof { - blinded: vec![ - hex!( - "8027f4809d06d6e9516f8bcbe97b3e1fa94f294b2606a11d00f1162c90bbdbaa0cbc77d480421f140adb34 - 53138eb8c4512f9cff60ee9a62502cbb0ddd30355235c12dbd318001ba7e874784b7c79fdc37d1584ff254 - efb6d167087dcb1227c704fd9f6c21d40080a92c5bdfcfbb286551bc43fb263980bc9148f3645f6bc0743c - 4292b88dc4039f8011e7fd2693a380b14bd3dd83736bec3bbcb7f70c7b7e0aaf30a03d2bbf96bd3b80c5a2 - 1afb7e16c0f8869ca44efbafddef083c89104fe153d0a77698a5aa1eef7d808cf84bd4fa37829f7229d507 - 3cbb504832fc88766def7b06930c5c27f7bf12a080dab6661eac3da9d306e8bbfdffb8ccc901239d8c1664 - 220062a4384224babea0" - ) - .to_vec(), - hex!("7f0400da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a010000").to_vec(), - ] - .into_iter() - .into(), - revealed: vec![revealed_leaf], - }; + let (dip_commitment, dip_proof) = dip_proof(); let proof = DipDidProofWithVerifiedSubjectCommitment::<_, _, _, _, _, _, ()>::with_commitment_and_dip_proof( dip_commitment, dip_proof, From e19e280f493967ade67adc9b8a238d4c61a8b3cf Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 6 Mar 2024 12:20:10 +0100 Subject: [PATCH 33/39] Remove TODO --- .../kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs index 648f095e9f..168cb5df93 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs @@ -315,7 +315,7 @@ mod dip_did_proof_with_verified_relay_state_root { #[test] fn verify_dip_commitment_proof_for_subject_invalid_proof() { let (parachain_state_root, dip_commitment_proof) = dip_commitment_proof(); - // Remove last part of the blinded component to get an invalid proof + // Remove last part of the blinded component to get an invalid proof. let (_, invalid_blinded_proof) = dip_commitment_proof.0.split_last().unwrap(); let invalid_dip_commitment_proof = DipCommitmentStateProof(invalid_blinded_proof.iter().cloned().into()); let proof = @@ -389,7 +389,6 @@ mod dip_did_proof_with_verified_subject_commitment { ) } - // TODO: Generate a valid DIP proof, and use it here. #[test] fn verify_dip_proof_successful() { let (dip_commitment, dip_proof) = dip_proof(); From 8359657a66e801af20adaa258835ebc5fc640eb6 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 6 Mar 2024 13:03:18 +0100 Subject: [PATCH 34/39] Refactor test functions --- .../src/merkle/v0/dip_subject_state/mod.rs | 34 ------ .../src/merkle/v0/dip_subject_state/tests.rs | 35 +++++- .../src/merkle/v0/provider_state/mod.rs | 102 ---------------- .../src/merkle/v0/provider_state/tests.rs | 109 +++++++++++++++++- .../src/merkle/v0/relay_state/mod.rs | 71 ------------ .../src/merkle/v0/relay_state/tests.rs | 85 +++++++++++++- 6 files changed, 225 insertions(+), 211 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs index 1f7bfcd480..247851608f 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs @@ -120,40 +120,6 @@ impl< } } -#[cfg(test)] -impl< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - const MAX_REVEALED_LEAVES_COUNT: u32, - > - DipRevealedDetailsAndUnverifiedDidSignature< - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - MAX_REVEALED_LEAVES_COUNT, - > where - KiltDidKeyId: Default, - KiltBlockNumber: Default, - ConsumerBlockNumber: Default, -{ - pub(crate) fn with_signature_time(valid_until: ConsumerBlockNumber) -> Self { - Self { - signature: TimeBoundDidSignature { - valid_until, - ..Default::default() - }, - revealed_leaves: Default::default(), - } - } -} - /// A DIP proof whose information has been verified and whose signature has been /// verified not to be expired, but that yet does not contain information as to /// which of the revealed keys has generated the signature. diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs index b0d919e551..49f2a8048f 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs @@ -19,7 +19,40 @@ mod dip_revealed_details_and_unverified_did_signature { use frame_support::{assert_err, assert_ok}; - use crate::{DipRevealedDetailsAndUnverifiedDidSignature, Error}; + use crate::{DipRevealedDetailsAndUnverifiedDidSignature, Error, TimeBoundDidSignature}; + + impl< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + const MAX_REVEALED_LEAVES_COUNT: u32, + > + DipRevealedDetailsAndUnverifiedDidSignature< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + MAX_REVEALED_LEAVES_COUNT, + > where + KiltDidKeyId: Default, + KiltBlockNumber: Default, + ConsumerBlockNumber: Default, + { + fn with_signature_time(valid_until: ConsumerBlockNumber) -> Self { + Self { + signature: TimeBoundDidSignature { + valid_until, + ..Default::default() + }, + revealed_leaves: Default::default(), + } + } + } #[test] fn verify_signature_time_successful() { diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs index 32d807d100..7cada4275d 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs @@ -115,39 +115,6 @@ impl< } } -#[cfg(test)] -impl< - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > - ParachainDipDidProof< - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > where - KiltDidKeyId: Default, - KiltBlockNumber: Default, - ConsumerBlockNumber: Default, -{ - pub(crate) fn with_provider_head_proof(provider_head_proof: ProviderHeadStateProof) -> Self { - Self { - provider_head_proof, - dip_commitment_proof: Default::default(), - dip_proof: Default::default(), - signature: Default::default(), - } - } -} - impl< RelayBlockNumber, KiltDidKeyId, @@ -378,42 +345,6 @@ impl< } } -#[cfg(test)] -impl< - StateRoot, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > - DipDidProofWithVerifiedStateRoot< - StateRoot, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > where - KiltDidKeyId: Default, - KiltBlockNumber: Default, - ConsumerBlockNumber: Default, -{ - pub(crate) fn with_state_root_and_dip_commitment_proof( - provider_state_root: StateRoot, - dip_commitment_proof: DipCommitmentStateProof, - ) -> Self { - Self { - state_root: provider_state_root, - dip_commitment_proof, - dip_proof: Default::default(), - signature: Default::default(), - } - } -} - /// A DIP proof that has had the relaychain state and the DIP commitment /// verified for the provided relaychain block number. /// @@ -562,36 +493,3 @@ impl< }) } } - -#[cfg(test)] -impl< - Commitment, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > - DipDidProofWithVerifiedSubjectCommitment< - Commitment, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - ConsumerBlockNumber, - > where - ConsumerBlockNumber: Default, -{ - pub(crate) fn with_commitment_and_dip_proof( - commitment: Commitment, - dip_proof: DidMerkleProof, - ) -> Self { - Self { - dip_commitment: commitment, - dip_proof, - signature: TimeBoundDidSignature::default(), - } - } -} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs index 168cb5df93..7e8e9219de 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs @@ -30,6 +30,38 @@ mod parachain_dip_did_proof { use crate::{state_proofs::MerkleProofError, Error, ParachainDipDidProof, ProviderHeadStateProof}; + impl< + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > + ParachainDipDidProof< + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > where + KiltDidKeyId: Default, + KiltBlockNumber: Default, + ConsumerBlockNumber: Default, + { + fn with_provider_head_proof(provider_head_proof: ProviderHeadStateProof) -> Self { + Self { + provider_head_proof, + dip_commitment_proof: Default::default(), + dip_proof: Default::default(), + signature: Default::default(), + } + } + } + // Storage proof generated at Polkadot block `19_663_508` with hash // `0x6e87866fb4f412e1e691e25d294019a7695d5a756ee7bc8d012c25177b5e1e13` for // storage key @@ -164,6 +196,41 @@ mod dip_did_proof_with_verified_relay_state_root { use crate::{state_proofs::MerkleProofError, DipCommitmentStateProof, DipDidProofWithVerifiedStateRoot, Error}; + impl< + StateRoot, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > + DipDidProofWithVerifiedStateRoot< + StateRoot, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > where + KiltDidKeyId: Default, + KiltBlockNumber: Default, + ConsumerBlockNumber: Default, + { + fn with_state_root_and_dip_commitment_proof( + provider_state_root: StateRoot, + dip_commitment_proof: DipCommitmentStateProof, + ) -> Self { + Self { + state_root: provider_state_root, + dip_commitment_proof, + dip_proof: Default::default(), + signature: Default::default(), + } + } + } + construct_runtime!( pub enum TestProviderRuntime { System: frame_system, @@ -346,7 +413,47 @@ mod dip_did_proof_with_verified_subject_commitment { AccountId32, BoundedVec, }; - use crate::{DidMerkleProof, DipDidProofWithVerifiedSubjectCommitment, Error, RevealedDidKey}; + use crate::{ + DidMerkleProof, DipDidProofWithVerifiedSubjectCommitment, Error, RevealedDidKey, TimeBoundDidSignature, + }; + + impl< + Commitment, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > + DipDidProofWithVerifiedSubjectCommitment< + Commitment, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + > where + ConsumerBlockNumber: Default, + { + fn with_commitment_and_dip_proof( + commitment: Commitment, + dip_proof: DidMerkleProof< + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + >, + ) -> Self { + Self { + dip_commitment: commitment, + dip_proof, + signature: TimeBoundDidSignature::default(), + } + } + } // DIP proof generated on Peregrine via the `dipProvider::generateProof` runtime // API. diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs index ef814f215e..25dee33208 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs @@ -151,40 +151,6 @@ impl< } } -#[cfg(test)] -impl< - RelayBlockNumber: Member + sp_std::hash::Hash + Copy + MaybeDisplay + AtLeast32BitUnsigned + Codec + Into + TryFrom, - RelayHasher: Hash, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - > - RelayDipDidProof< - RelayBlockNumber, - RelayHasher, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - > where - RelayBlockNumber: Default, - KiltDidKeyId: Default, - KiltBlockNumber: Default, -{ - pub(crate) fn with_header(header: Header) -> Self { - Self { - relay_header: header, - dip_commitment_proof: Default::default(), - dip_proof: Default::default(), - provider_head_proof: Default::default(), - signature: Default::default(), - } - } -} - /// A DIP proof submitted to a relaychain consumer that has had the proof header /// verified against a given block hash. /// @@ -281,40 +247,3 @@ impl< ) } } - -#[cfg(test)] -impl< - StateRoot, - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - > - RelayDipDidProofWithVerifiedRelayStateRoot< - StateRoot, - RelayBlockNumber, - KiltDidKeyId, - KiltAccountId, - KiltBlockNumber, - KiltWeb3Name, - KiltLinkableAccountId, - > where - RelayBlockNumber: Default, - KiltDidKeyId: Default, - KiltBlockNumber: Default, -{ - pub(crate) fn with_relay_state_root_and_provider_head_proof( - relay_state_root: StateRoot, - provider_head_proof: ProviderHeadStateProof, - ) -> Self { - Self { - relay_state_root, - provider_head_proof, - dip_commitment_proof: Default::default(), - dip_proof: Default::default(), - signature: Default::default(), - } - } -} diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs index 820848c442..a1df2647f9 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs @@ -19,11 +19,56 @@ mod relay_did_dip_proof { use frame_support::assert_err; use hex_literal::hex; - use sp_core::H256; - use sp_runtime::{generic::Header, traits::BlakeTwo256, Digest, DigestItem}; + use parity_scale_codec::Codec; + use sp_core::{H256, U256}; + use sp_runtime::{ + generic::Header, + traits::{AtLeast32BitUnsigned, BlakeTwo256, Hash, MaybeDisplay, Member}, + Digest, DigestItem, + }; use crate::{Error, RelayDipDidProof}; + impl< + RelayBlockNumber: Member + + sp_std::hash::Hash + + Copy + + MaybeDisplay + + AtLeast32BitUnsigned + + Codec + + Into + + TryFrom, + RelayHasher: Hash, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > + RelayDipDidProof< + RelayBlockNumber, + RelayHasher, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > where + RelayBlockNumber: Default, + KiltDidKeyId: Default, + KiltBlockNumber: Default, + { + fn with_header(header: Header) -> Self { + Self { + relay_header: header, + dip_commitment_proof: Default::default(), + dip_proof: Default::default(), + provider_head_proof: Default::default(), + signature: Default::default(), + } + } + } + #[test] fn verify_relay_header_with_block_hash_successful() { // Polkadot header at block `19_663_508` with hash @@ -88,6 +133,42 @@ mod relay_dip_did_proof_with_verified_relay_state_root { state_proofs::MerkleProofError, Error, ProviderHeadStateProof, RelayDipDidProofWithVerifiedRelayStateRoot, }; + impl< + StateRoot, + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > + RelayDipDidProofWithVerifiedRelayStateRoot< + StateRoot, + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > where + RelayBlockNumber: Default, + KiltDidKeyId: Default, + KiltBlockNumber: Default, + { + fn with_relay_state_root_and_provider_head_proof( + relay_state_root: StateRoot, + provider_head_proof: ProviderHeadStateProof, + ) -> Self { + Self { + relay_state_root, + provider_head_proof, + dip_commitment_proof: Default::default(), + dip_proof: Default::default(), + signature: Default::default(), + } + } + } + #[test] fn verify_provider_head_proof_successful() { // Storage proof generated at Polkadot block `19_663_508` with hash From 740c79d605ad922845caf21311504a9476df4856 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Wed, 6 Mar 2024 13:13:04 +0100 Subject: [PATCH 35/39] Add constants for errors --- .../src/verifier/parachain/v0/mod.rs | 23 +++++++++++----- .../src/verifier/relaychain/v0/mod.rs | 27 ++++++++++++++----- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs index 91067f4a2a..5bbeab6e30 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs @@ -40,6 +40,13 @@ mod mock; #[cfg(test)] mod tests; +const PARACHAIN_HEAD_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 0; +const PARACHAIN_HEAD_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 1; +const DIP_COMMITMENT_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 2; +const DIP_COMMITMENT_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 3; +const DIP_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 4; +const DIP_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 5; + /// Proof verifier configured given a specific KILT runtime implementation. /// /// The generic types @@ -173,7 +180,9 @@ impl< // 1. Verify parachain state is finalized by relay chain and fresh. ensure!( proof.provider_head_proof.proof.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT.saturated_into(), - DipParachainStateProofVerifierError::ProofComponentTooLarge(0) + DipParachainStateProofVerifierError::ProofComponentTooLarge( + PARACHAIN_HEAD_PROOF_TOO_MANY_LEAVES_ERROR_CODE + ) ); ensure!( proof @@ -181,7 +190,7 @@ impl< .proof .iter() .all(|l| l.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE.saturated_into()), - DipParachainStateProofVerifierError::ProofComponentTooLarge(1) + DipParachainStateProofVerifierError::ProofComponentTooLarge(PARACHAIN_HEAD_PROOF_LEAF_TOO_LARGE_ERROR_CODE) ); let proof_without_relaychain = proof .verify_provider_head_proof::>( @@ -193,7 +202,9 @@ impl< ensure!( proof_without_relaychain.dip_commitment_proof.0.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT.saturated_into(), - DipParachainStateProofVerifierError::ProofComponentTooLarge(2) + DipParachainStateProofVerifierError::ProofComponentTooLarge( + DIP_COMMITMENT_PROOF_TOO_MANY_LEAVES_ERROR_CODE + ) ); ensure!( proof_without_relaychain @@ -201,7 +212,7 @@ impl< .0 .iter() .all(|l| l.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE.saturated_into()), - DipParachainStateProofVerifierError::ProofComponentTooLarge(3) + DipParachainStateProofVerifierError::ProofComponentTooLarge(DIP_COMMITMENT_PROOF_LEAF_TOO_LARGE_ERROR_CODE) ); let proof_without_parachain = proof_without_relaychain .verify_dip_commitment_proof_for_subject::(subject) @@ -210,7 +221,7 @@ impl< // 3. Verify DIP Merkle proof. ensure!( proof_without_parachain.dip_proof.blinded.len() <= MAX_DID_MERKLE_PROOF_LEAVE_COUNT.saturated_into(), - DipParachainStateProofVerifierError::ProofComponentTooLarge(4) + DipParachainStateProofVerifierError::ProofComponentTooLarge(DIP_PROOF_TOO_MANY_LEAVES_ERROR_CODE) ); ensure!( proof_without_parachain @@ -218,7 +229,7 @@ impl< .blinded .iter() .all(|l| l.len() <= MAX_DID_MERKLE_PROOF_LEAVE_SIZE.saturated_into()), - DipParachainStateProofVerifierError::ProofComponentTooLarge(5) + DipParachainStateProofVerifierError::ProofComponentTooLarge(DIP_PROOF_LEAF_TOO_LARGE_ERROR_CODE) ); let proof_without_dip_merkle = proof_without_parachain .verify_dip_proof::() diff --git a/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs index 8d319f74f7..a3de44adfb 100644 --- a/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs @@ -34,6 +34,13 @@ use crate::{ DipOriginInfo, DipRelaychainStateProofVerifierError, RelayDipDidProof, RevealedDidKey, }; +const PARACHAIN_HEAD_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 0; +const PARACHAIN_HEAD_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 1; +const DIP_COMMITMENT_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 2; +const DIP_COMMITMENT_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 3; +const DIP_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 4; +const DIP_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 5; + /// Proof verifier configured given a specific KILT runtime implementation. /// /// The generic types are the following: @@ -160,7 +167,9 @@ impl< ensure!( proof_without_header.provider_head_proof.proof.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT.saturated_into(), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(0) + DipRelaychainStateProofVerifierError::ProofComponentTooLarge( + PARACHAIN_HEAD_PROOF_TOO_MANY_LEAVES_ERROR_CODE + ) ); ensure!( proof_without_header @@ -168,7 +177,9 @@ impl< .proof .iter() .all(|l| l.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE.saturated_into()), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(1) + DipRelaychainStateProofVerifierError::ProofComponentTooLarge( + PARACHAIN_HEAD_PROOF_LEAF_TOO_LARGE_ERROR_CODE + ) ); let proof_without_relaychain = proof_without_header .verify_provider_head_proof::>(KILT_PARA_ID) @@ -178,7 +189,9 @@ impl< ensure!( proof_without_relaychain.dip_commitment_proof.0.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT.saturated_into(), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(2) + DipRelaychainStateProofVerifierError::ProofComponentTooLarge( + DIP_COMMITMENT_PROOF_TOO_MANY_LEAVES_ERROR_CODE + ) ); ensure!( proof_without_relaychain @@ -186,7 +199,9 @@ impl< .0 .iter() .all(|l| l.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE.saturated_into()), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(3) + DipRelaychainStateProofVerifierError::ProofComponentTooLarge( + DIP_COMMITMENT_PROOF_LEAF_TOO_LARGE_ERROR_CODE + ) ); let proof_without_parachain = proof_without_relaychain .verify_dip_commitment_proof_for_subject::(subject) @@ -195,7 +210,7 @@ impl< // 4. Verify DIP Merkle proof. ensure!( proof_without_parachain.dip_proof.blinded.len() <= MAX_DID_MERKLE_PROOF_LEAVE_COUNT.saturated_into(), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(4) + DipRelaychainStateProofVerifierError::ProofComponentTooLarge(DIP_PROOF_TOO_MANY_LEAVES_ERROR_CODE) ); ensure!( proof_without_parachain @@ -203,7 +218,7 @@ impl< .blinded .iter() .all(|l| l.len() <= MAX_DID_MERKLE_PROOF_LEAVE_SIZE.saturated_into()), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(5) + DipRelaychainStateProofVerifierError::ProofComponentTooLarge(DIP_PROOF_LEAF_TOO_LARGE_ERROR_CODE) ); let proof_without_dip_merkle = proof_without_parachain .verify_dip_proof::() From c3cf3a2e1f9c6a5a4db1a5d32a0640f6aa7251d7 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 7 Mar 2024 09:47:34 +0100 Subject: [PATCH 36/39] Add get_ to test functions --- .../src/merkle/v0/provider_state/tests.rs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs index 7e8e9219de..481ff5caca 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs @@ -67,7 +67,7 @@ mod parachain_dip_did_proof { // storage key // `0xcd710b30bd2eab0352ddcc26417aa1941b3c252fcb29d88eff4f3de5de4476c32c0cfd6c23b92a7826080000` // (`paras::heads(2_086)`) - fn provider_head_proof() -> (H256, ProviderHeadStateProof) { + fn get_provider_head_proof() -> (H256, ProviderHeadStateProof) { (hex!("623b36bddae282e9fefab4707697171a594fdb27e90fd4ada4ebcc356438b070").into(), ProviderHeadStateProof { relay_block_number: 19_663_508, proof: vec![ @@ -83,7 +83,7 @@ mod parachain_dip_did_proof { #[test] fn verify_provider_head_proof_with_state_root_successful() { - let (relay_state_root, provider_head_proof) = provider_head_proof(); + let (relay_state_root, provider_head_proof) = get_provider_head_proof(); // Only interested in the parachain head verification part, we skip everything // else. let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); @@ -137,7 +137,7 @@ mod parachain_dip_did_proof { #[test] fn verify_provider_head_proof_with_state_root_wrong_relay_hasher() { - let (relay_state_root, provider_head_proof) = provider_head_proof(); + let (relay_state_root, provider_head_proof) = get_provider_head_proof(); let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); assert_err!( // Using a different hasher for verification @@ -151,7 +151,7 @@ mod parachain_dip_did_proof { #[test] fn verify_provider_head_proof_with_state_root_wrong_para_id() { - let (relay_state_root, provider_head_proof) = provider_head_proof(); + let (relay_state_root, provider_head_proof) = get_provider_head_proof(); let proof = ParachainDipDidProof::<_, (), (), _, (), (), ()>::with_provider_head_proof(provider_head_proof); assert_err!( proof.verify_provider_head_proof_with_state_root::>( @@ -164,7 +164,7 @@ mod parachain_dip_did_proof { #[test] fn verify_provider_head_proof_with_state_root_invalid_proof() { - let (relay_state_root, provider_head_proof) = provider_head_proof(); + let (relay_state_root, provider_head_proof) = get_provider_head_proof(); // Remove last part of the blinded component to get an invalid proof let (_, invalid_blinded_proof) = provider_head_proof.proof.split_last().unwrap(); let invalid_provider_head_proof = ProviderHeadStateProof { @@ -280,7 +280,7 @@ mod dip_did_proof_with_verified_relay_state_root { // storage key // `0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f30d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000` // (`dipProvider::identityCommitments(4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK, 0)`) - fn dip_commitment_proof() -> (H256, DipCommitmentStateProof) { + fn get_dip_commitment_proof() -> (H256, DipCommitmentStateProof) { (hex!("3a27f8d59c8bcc51bf3735ecdc0ce1304127a5b9e707e956e22633179493d55c").into(), DipCommitmentStateProof(vec![ hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd8003ab0887cbb70c4e0d8d0f738e4b05732fd8cb5da24fa5f1112e20ba3603d58a80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), @@ -291,7 +291,7 @@ mod dip_did_proof_with_verified_relay_state_root { #[test] fn verify_dip_commitment_proof_for_subject_successful() { - let (parachain_state_root, dip_commitment_proof) = dip_commitment_proof(); + let (parachain_state_root, dip_commitment_proof) = get_dip_commitment_proof(); // Only interested in the DIP commitment verification part, we skip everything // else. let proof = @@ -346,7 +346,7 @@ mod dip_did_proof_with_verified_relay_state_root { #[test] fn verify_dip_commitment_proof_for_subject_wrong_provider_hasher() { - let (parachain_state_root, dip_commitment_proof) = dip_commitment_proof(); + let (parachain_state_root, dip_commitment_proof) = get_dip_commitment_proof(); // Only interested in the DIP commitment verification part, we skip everything // else. let proof = @@ -365,7 +365,7 @@ mod dip_did_proof_with_verified_relay_state_root { #[test] fn verify_dip_commitment_proof_for_subject_different_subject() { - let (parachain_state_root, dip_commitment_proof) = dip_commitment_proof(); + let (parachain_state_root, dip_commitment_proof) = get_dip_commitment_proof(); let proof = DipDidProofWithVerifiedStateRoot::<_, (), (), (), (), (), ()>::with_state_root_and_dip_commitment_proof( parachain_state_root, @@ -381,7 +381,7 @@ mod dip_did_proof_with_verified_relay_state_root { #[test] fn verify_dip_commitment_proof_for_subject_invalid_proof() { - let (parachain_state_root, dip_commitment_proof) = dip_commitment_proof(); + let (parachain_state_root, dip_commitment_proof) = get_dip_commitment_proof(); // Remove last part of the blinded component to get an invalid proof. let (_, invalid_blinded_proof) = dip_commitment_proof.0.split_last().unwrap(); let invalid_dip_commitment_proof = DipCommitmentStateProof(invalid_blinded_proof.iter().cloned().into()); @@ -458,7 +458,7 @@ mod dip_did_proof_with_verified_subject_commitment { // DIP proof generated on Peregrine via the `dipProvider::generateProof` runtime // API. #[allow(clippy::type_complexity)] - fn dip_proof() -> ( + fn get_dip_proof() -> ( H256, DidMerkleProof>, LinkableAccountId>, ) { @@ -498,7 +498,7 @@ mod dip_did_proof_with_verified_subject_commitment { #[test] fn verify_dip_proof_successful() { - let (dip_commitment, dip_proof) = dip_proof(); + let (dip_commitment, dip_proof) = get_dip_proof(); let proof = DipDidProofWithVerifiedSubjectCommitment::<_, _, _, _, _, _, ()>::with_commitment_and_dip_proof( dip_commitment, dip_proof.clone(), @@ -512,7 +512,7 @@ mod dip_did_proof_with_verified_subject_commitment { #[test] fn verify_dip_proof_wrong_merkle_hasher() { - let (dip_commitment, dip_proof) = dip_proof(); + let (dip_commitment, dip_proof) = get_dip_proof(); let proof = DipDidProofWithVerifiedSubjectCommitment::<_, _, _, _, _, _, ()>::with_commitment_and_dip_proof( dip_commitment, dip_proof, @@ -523,7 +523,7 @@ mod dip_did_proof_with_verified_subject_commitment { #[test] fn verify_dip_proof_too_many_leaves() { - let (dip_commitment, dip_proof) = dip_proof(); + let (dip_commitment, dip_proof) = get_dip_proof(); let proof = DipDidProofWithVerifiedSubjectCommitment::<_, _, _, _, _, _, ()>::with_commitment_and_dip_proof( dip_commitment, dip_proof, From 7eacbbae9b3b327b968f0a9f020122254b134e54 Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 7 Mar 2024 11:32:03 +0100 Subject: [PATCH 37/39] Use enum --- .../src/verifier/errors.rs | 27 ++++++++++++++++++ .../kilt-dip-primitives/src/verifier/mod.rs | 2 ++ .../src/verifier/parachain/v0/mod.rs | 28 ++++++++++--------- .../src/verifier/relaychain/v0/mod.rs | 24 ++++++++-------- 4 files changed, 55 insertions(+), 26 deletions(-) create mode 100644 crates/kilt-dip-primitives/src/verifier/errors.rs diff --git a/crates/kilt-dip-primitives/src/verifier/errors.rs b/crates/kilt-dip-primitives/src/verifier/errors.rs new file mode 100644 index 0000000000..8b041a3d1b --- /dev/null +++ b/crates/kilt-dip-primitives/src/verifier/errors.rs @@ -0,0 +1,27 @@ +// KILT Blockchain – https://botlabs.org +// Copyright (C) 2019-2024 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 + +#[repr(u8)] +pub(crate) enum DipProofComponentTooLargeError { + ParachainHeadProofTooManyLeaves = 0, + ParachainHeadProofLeafTooLarge = 1, + DipCommitmentProofTooManyLeaves = 2, + DipCommitmentProofLeafTooLarge = 3, + DipProofTooManyLeaves = 4, + DipProofLeafTooLarge = 5, +} diff --git a/crates/kilt-dip-primitives/src/verifier/mod.rs b/crates/kilt-dip-primitives/src/verifier/mod.rs index 8ef00aad6f..ee210acc75 100644 --- a/crates/kilt-dip-primitives/src/verifier/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/mod.rs @@ -16,6 +16,8 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org +mod errors; + /// Verification logic to integrate a sibling chain as a DIP provider. pub mod parachain; /// Verification logic to integrate a child chain as a DIP provider. diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs index 5bbeab6e30..a3c9fb2c53 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs @@ -31,6 +31,7 @@ use crate::{ merkle::v0::ParachainDipDidProof, traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, utils::OutputOf, + verifier::errors::DipProofComponentTooLargeError, DipOriginInfo, DipParachainStateProofVerifierError, RevealedDidKey, }; @@ -40,13 +41,6 @@ mod mock; #[cfg(test)] mod tests; -const PARACHAIN_HEAD_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 0; -const PARACHAIN_HEAD_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 1; -const DIP_COMMITMENT_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 2; -const DIP_COMMITMENT_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 3; -const DIP_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 4; -const DIP_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 5; - /// Proof verifier configured given a specific KILT runtime implementation. /// /// The generic types @@ -181,7 +175,7 @@ impl< ensure!( proof.provider_head_proof.proof.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT.saturated_into(), DipParachainStateProofVerifierError::ProofComponentTooLarge( - PARACHAIN_HEAD_PROOF_TOO_MANY_LEAVES_ERROR_CODE + DipProofComponentTooLargeError::ParachainHeadProofTooManyLeaves as u8 ) ); ensure!( @@ -190,7 +184,9 @@ impl< .proof .iter() .all(|l| l.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE.saturated_into()), - DipParachainStateProofVerifierError::ProofComponentTooLarge(PARACHAIN_HEAD_PROOF_LEAF_TOO_LARGE_ERROR_CODE) + DipParachainStateProofVerifierError::ProofComponentTooLarge( + DipProofComponentTooLargeError::ParachainHeadProofLeafTooLarge as u8 + ) ); let proof_without_relaychain = proof .verify_provider_head_proof::>( @@ -203,7 +199,7 @@ impl< proof_without_relaychain.dip_commitment_proof.0.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT.saturated_into(), DipParachainStateProofVerifierError::ProofComponentTooLarge( - DIP_COMMITMENT_PROOF_TOO_MANY_LEAVES_ERROR_CODE + DipProofComponentTooLargeError::DipCommitmentProofTooManyLeaves as u8 ) ); ensure!( @@ -212,7 +208,9 @@ impl< .0 .iter() .all(|l| l.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE.saturated_into()), - DipParachainStateProofVerifierError::ProofComponentTooLarge(DIP_COMMITMENT_PROOF_LEAF_TOO_LARGE_ERROR_CODE) + DipParachainStateProofVerifierError::ProofComponentTooLarge( + DipProofComponentTooLargeError::DipCommitmentProofLeafTooLarge as u8 + ) ); let proof_without_parachain = proof_without_relaychain .verify_dip_commitment_proof_for_subject::(subject) @@ -221,7 +219,9 @@ impl< // 3. Verify DIP Merkle proof. ensure!( proof_without_parachain.dip_proof.blinded.len() <= MAX_DID_MERKLE_PROOF_LEAVE_COUNT.saturated_into(), - DipParachainStateProofVerifierError::ProofComponentTooLarge(DIP_PROOF_TOO_MANY_LEAVES_ERROR_CODE) + DipParachainStateProofVerifierError::ProofComponentTooLarge( + DipProofComponentTooLargeError::DipProofTooManyLeaves as u8 + ) ); ensure!( proof_without_parachain @@ -229,7 +229,9 @@ impl< .blinded .iter() .all(|l| l.len() <= MAX_DID_MERKLE_PROOF_LEAVE_SIZE.saturated_into()), - DipParachainStateProofVerifierError::ProofComponentTooLarge(DIP_PROOF_LEAF_TOO_LARGE_ERROR_CODE) + DipParachainStateProofVerifierError::ProofComponentTooLarge( + DipProofComponentTooLargeError::DipProofLeafTooLarge as u8 + ) ); let proof_without_dip_merkle = proof_without_parachain .verify_dip_proof::() diff --git a/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs index a3de44adfb..0dc7af8ac3 100644 --- a/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/relaychain/v0/mod.rs @@ -31,16 +31,10 @@ use sp_std::{marker::PhantomData, vec::Vec}; use crate::{ traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, utils::OutputOf, + verifier::errors::DipProofComponentTooLargeError, DipOriginInfo, DipRelaychainStateProofVerifierError, RelayDipDidProof, RevealedDidKey, }; -const PARACHAIN_HEAD_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 0; -const PARACHAIN_HEAD_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 1; -const DIP_COMMITMENT_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 2; -const DIP_COMMITMENT_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 3; -const DIP_PROOF_TOO_MANY_LEAVES_ERROR_CODE: u8 = 4; -const DIP_PROOF_LEAF_TOO_LARGE_ERROR_CODE: u8 = 5; - /// Proof verifier configured given a specific KILT runtime implementation. /// /// The generic types are the following: @@ -168,7 +162,7 @@ impl< proof_without_header.provider_head_proof.proof.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT.saturated_into(), DipRelaychainStateProofVerifierError::ProofComponentTooLarge( - PARACHAIN_HEAD_PROOF_TOO_MANY_LEAVES_ERROR_CODE + DipProofComponentTooLargeError::ParachainHeadProofTooManyLeaves as u8 ) ); ensure!( @@ -178,7 +172,7 @@ impl< .iter() .all(|l| l.len() <= MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE.saturated_into()), DipRelaychainStateProofVerifierError::ProofComponentTooLarge( - PARACHAIN_HEAD_PROOF_LEAF_TOO_LARGE_ERROR_CODE + DipProofComponentTooLargeError::ParachainHeadProofLeafTooLarge as u8 ) ); let proof_without_relaychain = proof_without_header @@ -190,7 +184,7 @@ impl< proof_without_relaychain.dip_commitment_proof.0.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT.saturated_into(), DipRelaychainStateProofVerifierError::ProofComponentTooLarge( - DIP_COMMITMENT_PROOF_TOO_MANY_LEAVES_ERROR_CODE + DipProofComponentTooLargeError::DipCommitmentProofTooManyLeaves as u8 ) ); ensure!( @@ -200,7 +194,7 @@ impl< .iter() .all(|l| l.len() <= MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE.saturated_into()), DipRelaychainStateProofVerifierError::ProofComponentTooLarge( - DIP_COMMITMENT_PROOF_LEAF_TOO_LARGE_ERROR_CODE + DipProofComponentTooLargeError::DipCommitmentProofLeafTooLarge as u8 ) ); let proof_without_parachain = proof_without_relaychain @@ -210,7 +204,9 @@ impl< // 4. Verify DIP Merkle proof. ensure!( proof_without_parachain.dip_proof.blinded.len() <= MAX_DID_MERKLE_PROOF_LEAVE_COUNT.saturated_into(), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(DIP_PROOF_TOO_MANY_LEAVES_ERROR_CODE) + DipRelaychainStateProofVerifierError::ProofComponentTooLarge( + DipProofComponentTooLargeError::DipProofTooManyLeaves as u8 + ) ); ensure!( proof_without_parachain @@ -218,7 +214,9 @@ impl< .blinded .iter() .all(|l| l.len() <= MAX_DID_MERKLE_PROOF_LEAVE_SIZE.saturated_into()), - DipRelaychainStateProofVerifierError::ProofComponentTooLarge(DIP_PROOF_LEAF_TOO_LARGE_ERROR_CODE) + DipRelaychainStateProofVerifierError::ProofComponentTooLarge( + DipProofComponentTooLargeError::DipProofLeafTooLarge as u8 + ) ); let proof_without_dip_merkle = proof_without_parachain .verify_dip_proof::() From 476c221ccaf4c57f3d153ed8ea9555b755a6394a Mon Sep 17 00:00:00 2001 From: Antonio Antonino Date: Thu, 7 Mar 2024 13:28:40 +0100 Subject: [PATCH 38/39] Rename merkle module --- crates/kilt-dip-primitives/src/lib.rs | 4 ++-- .../kilt-dip-primitives/src/{merkle => merkle_proofs}/mod.rs | 0 .../src/{merkle => merkle_proofs}/v0/dip_subject_state/mod.rs | 2 +- .../{merkle => merkle_proofs}/v0/dip_subject_state/tests.rs | 0 .../src/{merkle => merkle_proofs}/v0/error.rs | 0 .../src/{merkle => merkle_proofs}/v0/input_common.rs | 2 +- .../src/{merkle => merkle_proofs}/v0/mod.rs | 0 .../src/{merkle => merkle_proofs}/v0/output_common.rs | 0 .../src/{merkle => merkle_proofs}/v0/provider_state/mod.rs | 2 +- .../src/{merkle => merkle_proofs}/v0/provider_state/tests.rs | 0 .../src/{merkle => merkle_proofs}/v0/relay_state/mod.rs | 2 +- .../src/{merkle => merkle_proofs}/v0/relay_state/tests.rs | 0 crates/kilt-dip-primitives/src/verifier/parachain/mod.rs | 2 +- crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs | 2 +- crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs | 4 ++-- 15 files changed, 10 insertions(+), 10 deletions(-) rename crates/kilt-dip-primitives/src/{merkle => merkle_proofs}/mod.rs (100%) rename crates/kilt-dip-primitives/src/{merkle => merkle_proofs}/v0/dip_subject_state/mod.rs (99%) rename crates/kilt-dip-primitives/src/{merkle => merkle_proofs}/v0/dip_subject_state/tests.rs (100%) rename crates/kilt-dip-primitives/src/{merkle => merkle_proofs}/v0/error.rs (100%) rename crates/kilt-dip-primitives/src/{merkle => merkle_proofs}/v0/input_common.rs (98%) rename crates/kilt-dip-primitives/src/{merkle => merkle_proofs}/v0/mod.rs (100%) rename crates/kilt-dip-primitives/src/{merkle => merkle_proofs}/v0/output_common.rs (100%) rename crates/kilt-dip-primitives/src/{merkle => merkle_proofs}/v0/provider_state/mod.rs (99%) rename crates/kilt-dip-primitives/src/{merkle => merkle_proofs}/v0/provider_state/tests.rs (100%) rename crates/kilt-dip-primitives/src/{merkle => merkle_proofs}/v0/relay_state/mod.rs (99%) rename crates/kilt-dip-primitives/src/{merkle => merkle_proofs}/v0/relay_state/tests.rs (100%) diff --git a/crates/kilt-dip-primitives/src/lib.rs b/crates/kilt-dip-primitives/src/lib.rs index 30623e96ca..6e87f2ab2c 100644 --- a/crates/kilt-dip-primitives/src/lib.rs +++ b/crates/kilt-dip-primitives/src/lib.rs @@ -27,7 +27,7 @@ #![cfg_attr(not(feature = "std"), no_std)] /// Module to deal with cross-chain Merkle proof as generated by the KILT chain. -pub mod merkle; +pub mod merkle_proofs; /// Module to deal with cross-chain state proofs. pub mod state_proofs; /// Collection of traits used throughout the crate and useful for both providers @@ -38,6 +38,6 @@ pub mod utils; /// deployed both on a sibling parachain and on a parent relaychain. pub mod verifier; -pub use merkle::latest::*; +pub use merkle_proofs::latest::*; pub use traits::RelayStateRootsViaRelayStorePallet; pub use verifier::*; diff --git a/crates/kilt-dip-primitives/src/merkle/mod.rs b/crates/kilt-dip-primitives/src/merkle_proofs/mod.rs similarity index 100% rename from crates/kilt-dip-primitives/src/merkle/mod.rs rename to crates/kilt-dip-primitives/src/merkle_proofs/mod.rs diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/dip_subject_state/mod.rs similarity index 99% rename from crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs rename to crates/kilt-dip-primitives/src/merkle_proofs/v0/dip_subject_state/mod.rs index 247851608f..8206077320 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle_proofs/v0/dip_subject_state/mod.rs @@ -25,7 +25,7 @@ use sp_runtime::{traits::SaturatedConversion, BoundedVec}; use sp_std::vec::Vec; use crate::{ - merkle::v0::{ + merkle_proofs::v0::{ input_common::TimeBoundDidSignature, output_common::{DidKeyRelationship, DipOriginInfo, RevealedDidKey, RevealedDidMerkleProofLeaf}, }, diff --git a/crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/dip_subject_state/tests.rs similarity index 100% rename from crates/kilt-dip-primitives/src/merkle/v0/dip_subject_state/tests.rs rename to crates/kilt-dip-primitives/src/merkle_proofs/v0/dip_subject_state/tests.rs diff --git a/crates/kilt-dip-primitives/src/merkle/v0/error.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/error.rs similarity index 100% rename from crates/kilt-dip-primitives/src/merkle/v0/error.rs rename to crates/kilt-dip-primitives/src/merkle_proofs/v0/error.rs diff --git a/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/input_common.rs similarity index 98% rename from crates/kilt-dip-primitives/src/merkle/v0/input_common.rs rename to crates/kilt-dip-primitives/src/merkle_proofs/v0/input_common.rs index 42c14eddd1..2466276585 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/input_common.rs +++ b/crates/kilt-dip-primitives/src/merkle_proofs/v0/input_common.rs @@ -21,7 +21,7 @@ use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_std::vec::Vec; -use crate::{merkle::v0::output_common::RevealedDidMerkleProofLeaf, utils::BoundedBlindedValue}; +use crate::{merkle_proofs::v0::output_common::RevealedDidMerkleProofLeaf, utils::BoundedBlindedValue}; /// The state proof for a parachain head. /// diff --git a/crates/kilt-dip-primitives/src/merkle/v0/mod.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/mod.rs similarity index 100% rename from crates/kilt-dip-primitives/src/merkle/v0/mod.rs rename to crates/kilt-dip-primitives/src/merkle_proofs/v0/mod.rs diff --git a/crates/kilt-dip-primitives/src/merkle/v0/output_common.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/output_common.rs similarity index 100% rename from crates/kilt-dip-primitives/src/merkle/v0/output_common.rs rename to crates/kilt-dip-primitives/src/merkle_proofs/v0/output_common.rs diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/mod.rs similarity index 99% rename from crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs rename to crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/mod.rs index 7cada4275d..ad548ec05e 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/mod.rs @@ -28,7 +28,7 @@ use sp_std::{fmt::Debug, vec::Vec}; use sp_trie::{verify_trie_proof, LayoutV1}; use crate::{ - merkle::v0::{ + merkle_proofs::v0::{ dip_subject_state::DipRevealedDetailsAndUnverifiedDidSignature, input_common::{DidMerkleProof, DipCommitmentStateProof, ProviderHeadStateProof, TimeBoundDidSignature}, }, diff --git a/crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/tests.rs similarity index 100% rename from crates/kilt-dip-primitives/src/merkle/v0/provider_state/tests.rs rename to crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/tests.rs diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/mod.rs similarity index 99% rename from crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs rename to crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/mod.rs index 25dee33208..9dc4c33ae6 100644 --- a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/mod.rs @@ -25,7 +25,7 @@ use sp_runtime::{ }; use crate::{ - merkle::v0::{ + merkle_proofs::v0::{ input_common::{DidMerkleProof, DipCommitmentStateProof, ProviderHeadStateProof, TimeBoundDidSignature}, provider_state::ParachainDipDidProof, }, diff --git a/crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/tests.rs similarity index 100% rename from crates/kilt-dip-primitives/src/merkle/v0/relay_state/tests.rs rename to crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/tests.rs diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs index 811dd84c39..df0f6da68b 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs @@ -27,7 +27,7 @@ use scale_info::TypeInfo; use sp_std::{fmt::Debug, marker::PhantomData, vec::Vec}; use crate::{ - merkle::v0::RevealedDidKey, + merkle_proofs::v0::RevealedDidKey, traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, utils::OutputOf, DipOriginInfo, ParachainDipDidProof, diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs index a3c9fb2c53..d0e1fc80ff 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mod.rs @@ -28,7 +28,7 @@ use sp_runtime::{traits::Zero, SaturatedConversion}; use sp_std::{marker::PhantomData, vec::Vec}; use crate::{ - merkle::v0::ParachainDipDidProof, + merkle_proofs::v0::ParachainDipDidProof, traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, utils::OutputOf, verifier::errors::DipProofComponentTooLargeError, diff --git a/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs b/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs index 9257920500..d1909153a8 100644 --- a/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs @@ -29,7 +29,7 @@ use sp_runtime::traits::Hash; use sp_std::{fmt::Debug, marker::PhantomData, vec::Vec}; use crate::{ - merkle::v0::RevealedDidKey, + merkle_proofs::v0::RevealedDidKey, traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, utils::OutputOf, DipOriginInfo, @@ -55,7 +55,7 @@ pub enum VersionedRelaychainStateProof< KiltLinkableAccountId, > { V0( - crate::merkle::v0::RelayDipDidProof< + crate::merkle_proofs::v0::RelayDipDidProof< ConsumerBlockNumber, ConsumerBlockHasher, KiltDidKeyId, From 4adad210aa5ca2e668e4183599ed78e70c21ddd7 Mon Sep 17 00:00:00 2001 From: Antonio Date: Thu, 28 Mar 2024 08:32:40 +0100 Subject: [PATCH 39/39] chore: improve benchmark logic (#612) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/KILTprotocol/ticket/issues/3104, based on top of https://github.com/KILTprotocol/kilt-node/pull/611. It fixes the logic for the `dip-consumer` pallet, by delegating the generation of a proof worst case to the proof verifier, which must make sure the proof is indeed the one that requires the most weight to verify, and that it verifies successfully. This also means that each consumer runtime is responsible to implement this method, as there cannot be a "universal" worst proof, as that depends on the use case. The pallet benchmarking logic is now generic enough to make this possible and flexible ✨✨✨ --- Cargo.lock | 4 +- crates/kilt-dip-primitives/Cargo.toml | 3 +- .../merkle_proofs/v0/dip_subject_state/mod.rs | 24 +- .../src/merkle_proofs/v0/input_common.rs | 71 +-- .../merkle_proofs/v0/provider_state/mod.rs | 108 ++-- .../merkle_proofs/v0/provider_state/tests.rs | 71 ++- .../src/merkle_proofs/v0/relay_state/mod.rs | 5 +- .../src/merkle_proofs/v0/relay_state/tests.rs | 10 +- crates/kilt-dip-primitives/src/utils.rs | 69 +-- .../src/verifier/parachain/mod.rs | 61 ++- .../src/verifier/parachain/v0/mock.rs | 60 ++- .../src/verifier/relaychain/mod.rs | 71 ++- dip-template/runtimes/dip-consumer/Cargo.toml | 8 + dip-template/runtimes/dip-consumer/src/dip.rs | 504 +++++++++++++++++- dip-template/runtimes/dip-provider/src/dip.rs | 4 +- dip-template/runtimes/dip-provider/src/lib.rs | 8 +- pallets/did/src/did_details.rs | 7 - pallets/pallet-deposit-storage/src/lib.rs | 10 +- .../pallet-dip-consumer/src/benchmarking.rs | 48 +- pallets/pallet-dip-consumer/src/lib.rs | 3 +- pallets/pallet-dip-consumer/src/mock.rs | 17 + .../pallet-dip-provider/src/benchmarking.rs | 2 +- pallets/pallet-dip-provider/src/lib.rs | 2 +- pallets/pallet-migration/src/benchmarking.rs | 2 +- pallets/pallet-migration/src/mock.rs | 4 +- .../public-credentials/src/benchmarking.rs | 2 +- pallets/public-credentials/src/mock.rs | 4 +- runtimes/common/src/assets.rs | 4 +- runtimes/common/src/dip/did/mod.rs | 4 +- runtimes/common/src/dip/merkle/v0/mod.rs | 5 +- support/src/traits.rs | 12 +- 31 files changed, 826 insertions(+), 381 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dbfc9d0736..50b1f80b04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2496,7 +2496,9 @@ dependencies = [ "frame-system", "frame-system-benchmarking", "frame-system-rpc-runtime-api", + "hex-literal 0.3.4", "kilt-dip-primitives", + "kilt-support", "pallet-aura", "pallet-authorship", "pallet-balances", @@ -2519,6 +2521,7 @@ dependencies = [ "sp-consensus-aura", "sp-core", "sp-inherents", + "sp-io", "sp-offchain", "sp-runtime", "sp-session", @@ -4621,7 +4624,6 @@ dependencies = [ name = "kilt-dip-primitives" version = "1.12.0-dev" dependencies = [ - "cfg-if", "cumulus-pallet-parachain-system", "cumulus-primitives-core", "did", diff --git a/crates/kilt-dip-primitives/Cargo.toml b/crates/kilt-dip-primitives/Cargo.toml index 78d0fa948a..6d5ea8ff39 100644 --- a/crates/kilt-dip-primitives/Cargo.toml +++ b/crates/kilt-dip-primitives/Cargo.toml @@ -14,7 +14,6 @@ version.workspace = true # External dependencies hash-db.workspace = true log.workspace = true -cfg-if.workspace = true # Internal dependencies did.workspace = true @@ -78,5 +77,5 @@ std = [ runtime-benchmarks = [ "kilt-support/runtime-benchmarks", "pallet-dip-consumer/runtime-benchmarks", - "pallet-dip-provider/runtime-benchmarks", + "pallet-dip-provider/runtime-benchmarks" ] diff --git a/crates/kilt-dip-primitives/src/merkle_proofs/v0/dip_subject_state/mod.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/dip_subject_state/mod.rs index 8206077320..b525297407 100644 --- a/crates/kilt-dip-primitives/src/merkle_proofs/v0/dip_subject_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle_proofs/v0/dip_subject_state/mod.rs @@ -20,6 +20,7 @@ use did::{ did_details::{DidPublicKey, DidPublicKeyDetails}, DidSignature, }; +use frame_support::ensure; use sp_core::ConstU32; use sp_runtime::{traits::SaturatedConversion, BoundedVec}; use sp_std::vec::Vec; @@ -29,7 +30,6 @@ use crate::{ input_common::TimeBoundDidSignature, output_common::{DidKeyRelationship, DipOriginInfo, RevealedDidKey, RevealedDidMerkleProofLeaf}, }, - traits::BenchmarkDefault, Error, }; @@ -106,13 +106,7 @@ impl< >, Error, > { - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - let _ = self.signature.valid_until >= *block_number; - } else { - frame_support::ensure!(self.signature.valid_until >= *block_number, Error::InvalidSignatureTime); - } - } + ensure!(self.signature.valid_until >= *block_number, Error::InvalidSignatureTime); Ok(DipRevealedDetailsAndVerifiedDidSignatureFreshness { revealed_leaves: self.revealed_leaves, signature: self.signature.signature, @@ -166,9 +160,7 @@ impl< KiltWeb3Name, KiltLinkableAccountId, MAX_REVEALED_LEAVES_COUNT, - > where - KiltDidKeyId: BenchmarkDefault, - KiltBlockNumber: BenchmarkDefault, + > { /// Iterates over the revealed DID leaves to find the ones that generated a /// valid signature for the provided payload. @@ -214,15 +206,7 @@ impl< .map(|(index, _)| u32::saturated_from(index)) .collect(); - if signing_leaves_indices.is_empty() { - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - return Ok(DipOriginInfo::default()); - } else { - return Err(Error::InvalidDidKeyRevealed); - } - } - } + ensure!(!signing_leaves_indices.is_empty(), Error::InvalidDidKeyRevealed); let signing_leaves_indices_vector = signing_leaves_indices.try_into().map_err(|_| { log::error!("Should never fail to convert vector of signing leaf indices into BoundedVec."); diff --git a/crates/kilt-dip-primitives/src/merkle_proofs/v0/input_common.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/input_common.rs index 2466276585..f9a5d6b5b3 100644 --- a/crates/kilt-dip-primitives/src/merkle_proofs/v0/input_common.rs +++ b/crates/kilt-dip-primitives/src/merkle_proofs/v0/input_common.rs @@ -21,7 +21,7 @@ use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_std::vec::Vec; -use crate::{merkle_proofs::v0::output_common::RevealedDidMerkleProofLeaf, utils::BoundedBlindedValue}; +use crate::merkle_proofs::v0::output_common::RevealedDidMerkleProofLeaf; /// The state proof for a parachain head. /// @@ -31,18 +31,14 @@ use crate::{merkle_proofs::v0::output_common::RevealedDidMerkleProofLeaf, utils: #[cfg_attr(test, derive(Default))] pub struct ProviderHeadStateProof { pub(crate) relay_block_number: RelayBlockNumber, - pub(crate) proof: BoundedBlindedValue, + pub(crate) proof: Vec>, } -#[cfg(feature = "runtime-benchmarks")] -impl kilt_support::traits::GetWorstCase for ProviderHeadStateProof -where - RelayBlockNumber: Default, -{ - fn worst_case(context: Context) -> Self { +impl ProviderHeadStateProof { + pub fn new(relay_block_number: RelayBlockNumber, proof: Vec>) -> Self { Self { - relay_block_number: RelayBlockNumber::default(), - proof: BoundedBlindedValue::worst_case(context), + proof, + relay_block_number, } } } @@ -50,12 +46,11 @@ where /// The state proof for a DIP commitment. #[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] #[cfg_attr(test, derive(Default))] -pub struct DipCommitmentStateProof(pub(crate) BoundedBlindedValue); +pub struct DipCommitmentStateProof(pub(crate) Vec>); -#[cfg(feature = "runtime-benchmarks")] -impl kilt_support::traits::GetWorstCase for DipCommitmentStateProof { - fn worst_case(context: Context) -> Self { - Self(BoundedBlindedValue::worst_case(context)) +impl DipCommitmentStateProof { + pub fn new(proof: Vec>) -> Self { + Self(proof) } } @@ -76,7 +71,7 @@ pub struct DidMerkleProof< ProviderWeb3Name, ProviderLinkableAccountId, > { - pub(crate) blinded: BoundedBlindedValue, + pub(crate) blinded: Vec>, pub(crate) revealed: Vec< RevealedDidMerkleProofLeaf< ProviderDidKeyId, @@ -92,7 +87,7 @@ impl { pub fn new( - blinded: BoundedBlindedValue, + blinded: Vec>, revealed: Vec< RevealedDidMerkleProofLeaf< ProviderDidKeyId, @@ -105,35 +100,17 @@ impl Self { Self { blinded, revealed } } -} -#[cfg(feature = "runtime-benchmarks")] -impl< + pub fn revealed( + &self, + ) -> &[RevealedDidMerkleProofLeaf< ProviderDidKeyId, ProviderAccountId, ProviderBlockNumber, ProviderWeb3Name, ProviderLinkableAccountId, - Context, - > kilt_support::traits::GetWorstCase - for DidMerkleProof< - ProviderDidKeyId, - ProviderAccountId, - ProviderBlockNumber, - ProviderWeb3Name, - ProviderLinkableAccountId, - > where - ProviderDidKeyId: Default + Clone, - ProviderAccountId: Clone, - ProviderBlockNumber: Default + Clone, - ProviderWeb3Name: Clone, - ProviderLinkableAccountId: Clone, -{ - fn worst_case(context: Context) -> Self { - Self { - blinded: BoundedBlindedValue::worst_case(context), - revealed: sp_std::vec![RevealedDidMerkleProofLeaf::default(); 64], - } + >] { + self.revealed.as_ref() } } @@ -188,17 +165,3 @@ where } } } - -#[cfg(feature = "runtime-benchmarks")] -impl kilt_support::traits::GetWorstCase for TimeBoundDidSignature -where - DidSignature: kilt_support::traits::GetWorstCase, - BlockNumber: Default, -{ - fn worst_case(context: Context) -> Self { - Self { - signature: DidSignature::worst_case(context), - valid_until: BlockNumber::default(), - } - } -} diff --git a/crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/mod.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/mod.rs index ad548ec05e..c4e2fe271c 100644 --- a/crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/mod.rs @@ -33,7 +33,7 @@ use crate::{ input_common::{DidMerkleProof, DipCommitmentStateProof, ProviderHeadStateProof, TimeBoundDidSignature}, }, state_proofs::{verify_storage_value_proof, verify_storage_value_proof_with_decoder}, - traits::{BenchmarkDefault, GetWithArg}, + traits::GetWithArg, utils::{ calculate_dip_identity_commitment_storage_key_for_runtime, calculate_parachain_head_storage_key, OutputOf, }, @@ -76,7 +76,6 @@ pub struct ParachainDipDidProof< pub(crate) signature: TimeBoundDidSignature, } -#[cfg(feature = "runtime-benchmarks")] impl< RelayBlockNumber, KiltDidKeyId, @@ -85,9 +84,8 @@ impl< KiltWeb3Name, KiltLinkableAccountId, ConsumerBlockNumber, - Context, - > kilt_support::traits::GetWorstCase - for ParachainDipDidProof< + > + ParachainDipDidProof< RelayBlockNumber, KiltDidKeyId, KiltAccountId, @@ -95,24 +93,39 @@ impl< KiltWeb3Name, KiltLinkableAccountId, ConsumerBlockNumber, - > where - RelayBlockNumber: Default, - KiltDidKeyId: Default + Clone, - KiltAccountId: Clone, - KiltBlockNumber: Default + Clone, - KiltWeb3Name: Clone, - KiltLinkableAccountId: Clone, - ConsumerBlockNumber: Default, - Context: Clone, + > { - fn worst_case(context: Context) -> Self { + pub fn new( + provider_head_proof: ProviderHeadStateProof, + dip_commitment_proof: DipCommitmentStateProof, + dip_proof: DidMerkleProof, + signature: TimeBoundDidSignature, + ) -> Self { Self { - provider_head_proof: ProviderHeadStateProof::worst_case(context.clone()), - dip_commitment_proof: DipCommitmentStateProof::worst_case(context.clone()), - dip_proof: DidMerkleProof::worst_case(context.clone()), - signature: TimeBoundDidSignature::worst_case(context), + dip_commitment_proof, + dip_proof, + provider_head_proof, + signature, } } + + pub fn provider_head_proof(&self) -> &ProviderHeadStateProof { + &self.provider_head_proof + } + + pub fn dip_commitment_proof(&self) -> &DipCommitmentStateProof { + &self.dip_commitment_proof + } + + pub fn dip_proof( + &self, + ) -> &DidMerkleProof { + &self.dip_proof + } + + pub fn signature(&self) -> &TimeBoundDidSignature { + &self.signature + } } impl< @@ -132,8 +145,7 @@ impl< KiltWeb3Name, KiltLinkableAccountId, ConsumerBlockNumber, - > where - KiltBlockNumber: BenchmarkDefault, + > { /// Verifies the head data of the state proof for the provider with the /// given para ID and relaychain state root. @@ -166,7 +178,7 @@ impl< let provider_head_storage_key = calculate_parachain_head_storage_key(provider_para_id); // TODO: Figure out why RPC call returns 2 bytes in front which we don't need //This could be the reason (and the solution): https://substrate.stackexchange.com/a/1891/1795 - let provider_header_result = verify_storage_value_proof_with_decoder::<_, RelayHasher, ProviderHeader>( + let provider_header = verify_storage_value_proof_with_decoder::<_, RelayHasher, ProviderHeader>( &provider_head_storage_key, *relay_state_root, self.provider_head_proof.proof, @@ -177,14 +189,8 @@ impl< let mut trimmed_input = &input[2..]; ProviderHeader::decode(&mut trimmed_input).ok() }, - ); - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - let provider_header = provider_header_result.unwrap_or_else(|_| ProviderHeader::new(::Number::default(), ::Hash::default(), ::Hash::default(), ::Hash::default(), sp_runtime::Digest::default())); - } else { - let provider_header = provider_header_result.map_err(Error::ParaHeadMerkleProof)?; - } - } + ) + .map_err(Error::ParaHeadMerkleProof)?; Ok(DipDidProofWithVerifiedStateRoot { state_root: *provider_header.state_root(), dip_commitment_proof: self.dip_commitment_proof, @@ -225,14 +231,8 @@ impl< StateRootStore: GetWithArg>>, ProviderHeader: Decode + HeaderT, Number = KiltBlockNumber>, { - let relay_state_root = StateRootStore::get(&self.provider_head_proof.relay_block_number); - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - let relay_state_root = relay_state_root.unwrap_or_default(); - } else { - let relay_state_root = relay_state_root.ok_or(Error::RelayStateRootNotFound)?; - } - } + let relay_state_root = + StateRootStore::get(&self.provider_head_proof.relay_block_number).ok_or(Error::RelayStateRootNotFound)?; self.verify_provider_head_proof_with_state_root::( provider_para_id, &relay_state_root, @@ -320,23 +320,15 @@ impl< StateRoot: Ord, ParachainHasher: Hash, ProviderRuntime: pallet_dip_provider::Config, - IdentityCommitmentOf: BenchmarkDefault, { let dip_commitment_storage_key = calculate_dip_identity_commitment_storage_key_for_runtime::(subject, 0); - let dip_commitment_result = - verify_storage_value_proof::<_, ParachainHasher, IdentityCommitmentOf>( - &dip_commitment_storage_key, - self.state_root, - self.dip_commitment_proof.0, - ); - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - let dip_commitment = dip_commitment_result.unwrap_or_default(); - } else { - let dip_commitment = dip_commitment_result.map_err(Error::DipCommitmentMerkleProof)?; - } - } + let dip_commitment = verify_storage_value_proof::<_, ParachainHasher, IdentityCommitmentOf>( + &dip_commitment_storage_key, + self.state_root, + self.dip_commitment_proof.0, + ) + .map_err(Error::DipCommitmentMerkleProof)?; Ok(DipDidProofWithVerifiedSubjectCommitment { dip_commitment, dip_proof: self.dip_proof, @@ -469,19 +461,13 @@ impl< .iter() .map(|revealed_leaf| (revealed_leaf.encoded_key(), Some(revealed_leaf.encoded_value()))) .collect::>(); - let proof_verification_result = verify_trie_proof::, _, _, _>( + verify_trie_proof::, _, _, _>( &self.dip_commitment, self.dip_proof.blinded.as_slice(), proof_leaves_key_value_pairs.as_slice(), - ); + ) + .map_err(|_| Error::InvalidDidMerkleProof)?; - cfg_if::cfg_if! { - if #[cfg(feature = "runtime-benchmarks")] { - drop(proof_verification_result); - } else { - proof_verification_result.map_err(|_| Error::InvalidDidMerkleProof)?; - } - } let revealed_leaves = BoundedVec::try_from(self.dip_proof.revealed).map_err(|_| { log::error!("Should not fail to construct BoundedVec since bounds were checked before."); Error::Internal diff --git a/crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/tests.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/tests.rs index 481ff5caca..cf3fdf8ab5 100644 --- a/crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle_proofs/v0/provider_state/tests.rs @@ -77,7 +77,7 @@ mod parachain_dip_did_proof { hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() - ].into_iter().into(), + ], }) } @@ -118,7 +118,7 @@ mod parachain_dip_did_proof { hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() - ].into_iter().into(), + ], }; // Only interested in the parachain head verification part, we skip everything // else. @@ -168,7 +168,7 @@ mod parachain_dip_did_proof { // Remove last part of the blinded component to get an invalid proof let (_, invalid_blinded_proof) = provider_head_proof.proof.split_last().unwrap(); let invalid_provider_head_proof = ProviderHeadStateProof { - proof: invalid_blinded_proof.iter().cloned().into(), + proof: invalid_blinded_proof.to_owned(), ..provider_head_proof }; let proof = @@ -275,18 +275,17 @@ mod dip_did_proof_with_verified_relay_state_root { type WeightInfo = (); } - // Storage proof generated at Peregrine block `5_258_991` with hash - // `0xd83da28e40d6e193af832916d2741252955d438c9d17a9f441279085db3e8daf` for - // storage key - // `0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f30d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000` - // (`dipProvider::identityCommitments(4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK, 0)`) + // Storage proof generated at local Peregrine instance (with new storage hasher) + // for storage key + // `0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f366a25a7fa9282d4c8e07cfeb5ec4b0f44cec8bb650a6e6ff111f30916b9ca56a4542f70764e95d7ceb6736d981b2d95d01a12dfa1fa4ab9a0000` + // (`dipProvider::identityCommitments(4pevjN6chwUqWPVaoUF6naRmZyrA4XWfdK8nLQLEjufgW55c, 0)`) fn get_dip_commitment_proof() -> (H256, DipCommitmentStateProof) { - (hex!("3a27f8d59c8bcc51bf3735ecdc0ce1304127a5b9e707e956e22633179493d55c").into(), DipCommitmentStateProof(vec![ - hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), - hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd8003ab0887cbb70c4e0d8d0f738e4b05732fd8cb5da24fa5f1112e20ba3603d58a80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), - hex!("80ffff808a66c19052add13a202bcd73b546ae0cb70544f166c4a469672c666f0a5f9d8a80b84c2df313e2e749ff7e47eee888d9a023ba0a14a59852f4526b3e4b93b6dcbc807310fd50a0ae630c15e9eb07bda831d6d0cb6044d53a3dafb68e3fdb199fffdf80015ecd5e8af66e3d72ee5cc828c25989ca848e55396cccd9c196a4df1349fb9980a2ec48e449c43cc34954836cc14af398695f6569e301cef5a13eb88a16aa395580fd068d1339506db2893ba54a00a85aa712d68ff98ceeb5f4632f4e53618bb77880a3f173abac33e571e2a66f13127eeec3fb31bb1ae6f4b0fca8e658bbfbb5e52a803084ef6eaf38b821c59b3de92c4679117509b0b031e52ef5a80fdcff72e498ec804f36b8fb07a75463165f1714181009c86a2790685e78abd43220f5ecb194c887802559300c82eef4b21724bba2706cc2815e98cac3993c8d8dc9057b1aaf45ae8d8006571e929d492077d682dbc911934874ec00335029a90bd39e37d6d641e11873800397abe2ea62a374e5f0650c54fb99e8ef825066da798b0f4d729a7281f3575880b35cfb12f77988e1305ba651db7a8efbd43e4e8b057a56736cf6485f3033f481809ab1e406503e3ce63425a294f3f37aa4827b6a4ab38cf7e960a0d3335d79234e80be7c96632aa67491005e607a53bc1ab725fa465e29797bc29973d4cf5f64239b8037fe2a92c86d4c38ff38570b071e994ab86214e43e095dfb6ed142170fdac430").to_vec(), - hex!("be75edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3010880ffe3135a9ee019dbfe4143608c9f4a4291ab827d7d9d055028d556d9cea2fce180eb5d42e7c6f84ac20e0d5ab42008c631b3e87f36d55d0d5053c9fb4f944ef97c").to_vec(), - ].into_iter().into())) + (hex!("0757487b9dda09be65eae2e4ffeff8de52e66d5187d064f31e24fac44be9f4f7").into(), DipCommitmentStateProof(vec![ + hex!("7f540bf19e4ed2927982e234d989e812f3f366a25a7fa9282d4c8e07cfeb5ec4b0f44cec8bb650a6e6ff111f30916b9ca56a4542f70764e95d7ceb6736d981b2d95d01a12dfa1fa4ab9a00008051b175db0cd3a4071aaa1cdde8f3cc562b9618961d8a80ed77981ec98b91da45").to_vec(), + hex!("800c8080da28793d083b197f8d92fc3e77f5064436f1d8eea0fbea56ddb936aba654450080667f196f66a258b7e851925a9fca0e787fa2080ade3ec203fe940a85a4ef68b080b2aafe11c416356c5a97e233670962facb2a18944c3bdc4b9e27f1fa67a5bafe").to_vec(), + hex!("80ffff80353e4d164b13c87910044f1b4e76277e404a0ab46a7cd6c33a65aaadc2375ba88007b1390da34b4dce1328430fd924a6e193517a8148dd70a912c0dc2f7f8d2d4c803d402a5fdb0bf83f4f6da28178dc3d3b61d639a4c5733d8eaa79b3a159d9a79f80303acb9eafad3fe6028cf2abca4c824bf48af2b7241920ddf31b37d7921ee932802fd5e075dd0ae75eb64c49c178294214311140bc7c62763c839bedfac51cfa3180048fcfdbc81e0bb059327959a95b003093bf9b04e3918eebe0ac05aae2af93bb8014e3e0704c9a07636322335a3c663ec9fd9df8b7bf71d6e8183fefecfbfe0e50808e788bf3aaaea24abc0ee6d00eb102be955c07bd2b134e24cde6bdfbd922fdcf80deb1dbe09dc8972faeb0de3f080bfbb9d688dcf63906c91db762cc20cbf1e761804ee6ab85272b59bf8715509ccdcdbc038eb7ab7c13552f0eedbdc64bb1ccbacf808d42b27ca13475581cb35914e531fc84820bac04a5c6260b18adc6403c9d78d3807282321f53526da2c8f33500a0c90c75f95972c3c28366033c3f2c38beaaadc2804b74323792921a9cd34cd56a233f5768e3732bb41c157789371b110c5248446f80f395b7003a2eb1e39c624b9a707a6cb58c3cb6997932fc80662ae19c785a91f580b5e5172489541dfc581e116554b63de15fddf38ffed2b109394749c20b8f6ce3805a64908ec1ee443f9cff1793aa18d683308ae1bbd100498b5420e34c9a3c59de").to_vec(), + hex!("9e75edf06348b4330d1e88564111cb3d3000505f0e7b9012096b41c4eb3aaf947f6ea429080000806ad99dcfd0f2738b39c05d53a22890f969ba700ab74676cde1b3658e6a1d3b28").to_vec(), + ])) } #[test] @@ -301,31 +300,31 @@ mod dip_did_proof_with_verified_relay_state_root { ); let proof_verification_result = proof .verify_dip_commitment_proof_for_subject::( - &AccountId32::from_ss58check("4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK").unwrap(), + &AccountId32::from_ss58check("4pevjN6chwUqWPVaoUF6naRmZyrA4XWfdK8nLQLEjufgW55c").unwrap(), ) .unwrap(); assert_eq!( proof_verification_result.dip_commitment, - hex!("4aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").into() + hex!("51b175db0cd3a4071aaa1cdde8f3cc562b9618961d8a80ed77981ec98b91da45").into() ); } #[test] fn verify_dip_commitment_proof_for_subject_multi_storage() { - // Storage proof generated at Peregrine block `5_264_068` with hash - // `0x44635397de0fd0f4e6329064bd2c8500a6ca2283d904e7f2fbe271cd362224cb` for - // storage keys - // [`0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f30d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000`, '0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f346802a0d131133fa4cac8e6332f14ad28fe8b2ccb9e339f1c36798e918846726e6e983b59dd4fa3101a12dfa1fa4ab9a0000] - // ([`dipProvider::identityCommitments(4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK, 0)`, `dipProvider::identityCommitments(4pebirGcQAJ4nyd5137VuK8TPVW9RXprWvZLQK1wcw2qJvnM, 0)`]) + // Storage proof generated at local Peregrine instance (with new storage hasher) + // for storage keys + // [`0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f366a25a7fa9282d4c8e07cfeb5ec4b0f44cec8bb650a6e6ff111f30916b9ca56a4542f70764e95d7ceb6736d981b2d95d01a12dfa1fa4ab9a0000`, '0xb375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3324b39c02c5b89191d516a1cb2438497d68f8ab82a2af4df66983a1fd0992711686c0fbf8ff8437552365e26f488c17c01a12dfa1fa4ab9a0000] + // ([`dipProvider::identityCommitments(4pevjN6chwUqWPVaoUF6naRmZyrA4XWfdK8nLQLEjufgW55c, 0)`, `dipProvider::identityCommitments(4smPiDNt9eLaJCe6uq1hGG3kWEmB3ooMpbGbSp1VF9D2vwEg, 0)`]) let parachain_state_root: H256 = - hex!("886585d3c600c51e36e5e9b09c981abdee80fb0f3e5ce127a6de659b8684f168").into(); + hex!("506f0aa6af2e04874ab94835b359ab97a9cca1d1773777b5004da93ffd08a088").into(); let dip_commitment_proof = DipCommitmentStateProof(vec![ - hex!("7f2406802a0d131133fa4cac8e6332f14ad28fe8b2ccb9e339f1c36798e918846726e6e983b59dd4fa3101a12dfa1fa4ab9a000080dbf7e051929e3be2b6ded6fa9f4827a6bb080092487482c581e4e154d4a8f78f").to_vec(), - hex!("7f240d1c9ddb0ba4c0507243fb24936031b342ed12d34ad897938af6739bf519bdc2f101d67bf7dac85501a12dfa1fa4ab9a0000804aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").to_vec(), - hex!("800c808052d9b1ca86bf39ca4b7d574a5bcea35625200b5ff30c4517f7f361c67376e7fd80ccbd1321b25f59f4de9cd943c7322b8f2b943e30e510e7f32571250f651015bc80873d542c3a85337b597f63fc7a89837909196a9f0823625af4e2c18cc5274b56").to_vec(), - hex!("80ffff808a66c19052add13a202bcd73b546ae0cb70544f166c4a469672c666f0a5f9d8a80b84c2df313e2e749ff7e47eee888d9a023ba0a14a59852f4526b3e4b93b6dcbc80e2f12a87d30577bc3586e4684c34438a779df39f6bee51b098193f1484e7b20f80015ecd5e8af66e3d72ee5cc828c25989ca848e55396cccd9c196a4df1349fb99808587812cb707ea395adbd624fba27708a8b734dd26c75febf4d79f30f775d31f80cf4fdd2b7ee898fa3de2063d08ca5488a65e49b4f21969be56dd22b79729f4ce80f77d231bea6c289f8d969c0a2cc81ec8447efa0747845799e7bc635626801605806830b9c8dadb45b721c323e66aaf4417dd1f2a3b0315c17c7e9bc3a75312677d807368afb2a07ba2ca0ceec6c88e0e3040a39d4c86408f97d2fa0006c39531b4ca802559300c82eef4b21724bba2706cc2815e98cac3993c8d8dc9057b1aaf45ae8d808c1f6312826116f8e9aa52506bfc8b3b4583998f8858213044dac52f3ac1138c803e008fcbfb660c563e9eb278cf78fe3988027713cd9077898c351c41844fefc480002990139706fe0a03fcfc41614c9cec1ae13ddafba4de0630af0b87503d8312809ab1e406503e3ce63425a294f3f37aa4827b6a4ab38cf7e960a0d3335d79234e80be7c96632aa67491005e607a53bc1ab725fa465e29797bc29973d4cf5f64239b8003bce13d1847862ce6f26f6b420ffda9cd9b635c2ec8533f23c7b2d454d66b29").to_vec(), - hex!("be75edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f3110880ffe3135a9ee019dbfe4143608c9f4a4291ab827d7d9d055028d556d9cea2fce1804276317882ff464bb21f7fb6b9e20ccee7a1e414608ecb3c8c349dfa286dfd7480eb5d42e7c6f84ac20e0d5ab42008c631b3e87f36d55d0d5053c9fb4f944ef97c").to_vec(), - ].into_iter().into()); + hex!("7f34024b39c02c5b89191d516a1cb2438497d68f8ab82a2af4df66983a1fd0992711686c0fbf8ff8437552365e26f488c17c01a12dfa1fa4ab9a0000806e5f8a286a025f2631fc7e903f16f4732de04623a411da2abda7c81eb7a42e31").to_vec(), + hex!("7f3406a25a7fa9282d4c8e07cfeb5ec4b0f44cec8bb650a6e6ff111f30916b9ca56a4542f70764e95d7ceb6736d981b2d95d01a12dfa1fa4ab9a00008051b175db0cd3a4071aaa1cdde8f3cc562b9618961d8a80ed77981ec98b91da45").to_vec(), + hex!("800c8080da28793d083b197f8d92fc3e77f5064436f1d8eea0fbea56ddb936aba6544500802ac01dbcb6bbdd9e784796b03fa804e22e6c7d552e6432d2e782c78f1fd62ed080b2aafe11c416356c5a97e233670962facb2a18944c3bdc4b9e27f1fa67a5bafe").to_vec(), + hex!("80ffff80353e4d164b13c87910044f1b4e76277e404a0ab46a7cd6c33a65aaadc2375ba88007b1390da34b4dce1328430fd924a6e193517a8148dd70a912c0dc2f7f8d2d4c8056524aa90f9d9955e0f11cb65a3301b3feec8236f6c506f60851cd9182f6dabe809ce9739227a80b74d58ca2731bb7c95fef30c44badeaed70d4cae8ece37b875180f42657aef3c7a9da89d7fa2ead23197e6c7a0d9a56224c30a23d5e72af213b568011c66e7235c652b25a2599a23850ab0b2c45aa6adc8d0340956aeb06f677780e8014e3e0704c9a07636322335a3c663ec9fd9df8b7bf71d6e8183fefecfbfe0e50801f8da04e41cb0e58c2899f258c3606a4f8a9029ce7dd2831fe2f18748714e1b08063a92863797f3ff47d446998ab380abf3e19f9ad052378a890c969e3665ccfc480ac8fc0b324e4a48b6995b1ace16c16896f31a7d342fdd8c2812aebc74b3b1b2080f567d19109fd00674a7d71a364d5036670bd8413170968a2cd7e204ee9762b1d809183d04fbdc18d7dd79fe20d07131563bef1b21aa5cb6861a2dab4fb6173cbe3802588aac7065dd9e759283fcbf53a0c3696e5669564f92ee17d0ea9fabfe9e82880f395b7003a2eb1e39c624b9a707a6cb58c3cb6997932fc80662ae19c785a91f580b5e5172489541dfc581e116554b63de15fddf38ffed2b109394749c20b8f6ce38019dd7bc351b0ddab367f9c10a27d0dad1669e16af8a8a58c577ce0b2fb26ce8d").to_vec(), + hex!("9e75edf06348b4330d1e88564111cb3d3000505f0e7b9012096b41c4eb3aaf947f6ea429080000803cfa8887e3f3605330a40b74e99d031b21aeba65d2ef7f35c24a5cefab5291f1").to_vec(), + hex!("9f0bf19e4ed2927982e234d989e812f3f3480080f3fd8dffe32bd8f539044baf30efd07801d87ea5280154588c3abd3e325f578d8048f06290dfec2596fa70eaca62ea496d3dc0cd2f51fd40c61b58d7e5b476eebd").to_vec(), + ]); // Only interested in the DIP commitment verification part, we skip everything // else. let proof = @@ -335,12 +334,12 @@ mod dip_did_proof_with_verified_relay_state_root { ); let proof_verification_result = proof .verify_dip_commitment_proof_for_subject::( - &AccountId32::from_ss58check("4qVtUbkD2xqp9cqGDjViPpFPesJNdfoJvGeSUgturBxAPyBK").unwrap(), + &AccountId32::from_ss58check("4pevjN6chwUqWPVaoUF6naRmZyrA4XWfdK8nLQLEjufgW55c").unwrap(), ) .unwrap(); assert_eq!( proof_verification_result.dip_commitment, - hex!("4aba9a5555257d6477fc5a74aaad1eaa24543e7eb1b4ac5ff1c00a50f6e63b3e").into() + hex!("51b175db0cd3a4071aaa1cdde8f3cc562b9618961d8a80ed77981ec98b91da45").into() ); } @@ -373,7 +372,7 @@ mod dip_did_proof_with_verified_relay_state_root { ); assert_err!( proof.verify_dip_commitment_proof_for_subject::( - &AccountId32::from_ss58check("4pebirGcQAJ4nyd5137VuK8TPVW9RXprWvZLQK1wcw2qJvnM").unwrap(), + &AccountId32::from_ss58check("4smPiDNt9eLaJCe6uq1hGG3kWEmB3ooMpbGbSp1VF9D2vwEg").unwrap(), ), Error::DipCommitmentMerkleProof(MerkleProofError::RequiredLeafNotRevealed) ); @@ -384,7 +383,7 @@ mod dip_did_proof_with_verified_relay_state_root { let (parachain_state_root, dip_commitment_proof) = get_dip_commitment_proof(); // Remove last part of the blinded component to get an invalid proof. let (_, invalid_blinded_proof) = dip_commitment_proof.0.split_last().unwrap(); - let invalid_dip_commitment_proof = DipCommitmentStateProof(invalid_blinded_proof.iter().cloned().into()); + let invalid_dip_commitment_proof = DipCommitmentStateProof(invalid_blinded_proof.to_owned()); let proof = DipDidProofWithVerifiedStateRoot::<_, (), (), (), (), (), ()>::with_state_root_and_dip_commitment_proof( parachain_state_root, @@ -477,9 +476,7 @@ mod dip_did_proof_with_verified_subject_commitment { ) .to_vec(), hex!("7f0400da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a010000").to_vec(), - ] - .into_iter() - .into(), + ], revealed: vec![RevealedDidKey { id: hex!("50da6646d21f19b4d7d9f80d5beb103fbef7f4bb95eb94e0c02552175b1bff3a").into(), relationship: DidVerificationKeyRelationship::Authentication.into(), @@ -536,9 +533,9 @@ mod dip_did_proof_with_verified_subject_commitment { fn verify_dip_proof_invalid_proof() { let proof = DipDidProofWithVerifiedSubjectCommitment::<_, (), (), (), (), (), ()>::with_commitment_and_dip_proof( - H256::default(), + H256([100; 32]), DidMerkleProof { - blinded: Default::default(), + blinded: vec![vec![100; 32]], revealed: Default::default(), }, ); diff --git a/crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/mod.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/mod.rs index 9dc4c33ae6..5a08bc9dce 100644 --- a/crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/mod.rs +++ b/crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/mod.rs @@ -29,7 +29,7 @@ use crate::{ input_common::{DidMerkleProof, DipCommitmentStateProof, ProviderHeadStateProof, TimeBoundDidSignature}, provider_state::ParachainDipDidProof, }, - traits::{BenchmarkDefault, GetWithArg}, + traits::GetWithArg, utils::OutputOf, DipDidProofWithVerifiedStateRoot, Error, }; @@ -204,8 +204,7 @@ impl< KiltBlockNumber, KiltWeb3Name, KiltLinkableAccountId, - > where - KiltBlockNumber: BenchmarkDefault, + > { /// Verifies the head data of the state proof for the provider with the /// given para ID. diff --git a/crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/tests.rs b/crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/tests.rs index a1df2647f9..42aef97c56 100644 --- a/crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/tests.rs +++ b/crates/kilt-dip-primitives/src/merkle_proofs/v0/relay_state/tests.rs @@ -186,7 +186,7 @@ mod relay_dip_did_proof_with_verified_relay_state_root { hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() - ].into_iter().into(), + ], }; // Only interested in the parachain head verification part, we skip everything // else. @@ -219,7 +219,7 @@ mod relay_dip_did_proof_with_verified_relay_state_root { hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() - ].into_iter().into(), + ], }; // Only interested in the parachain head verification part, we skip everything // else. @@ -250,7 +250,7 @@ mod relay_dip_did_proof_with_verified_relay_state_root { hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() - ].into_iter().into(), + ], }; let proof = RelayDipDidProofWithVerifiedRelayStateRoot::<_, _, (), (), _, (), ()>::with_relay_state_root_and_provider_head_proof(relay_state_root, provider_head_proof); assert_err!( @@ -277,7 +277,7 @@ mod relay_dip_did_proof_with_verified_relay_state_root { hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() - ].into_iter().into(), + ], }; let proof = RelayDipDidProofWithVerifiedRelayStateRoot::<_, _, (), (), _, (), ()>::with_relay_state_root_and_provider_head_proof(relay_state_root, provider_head_proof); assert_err!( @@ -304,7 +304,7 @@ mod relay_dip_did_proof_with_verified_relay_state_root { hex!("80ffff8003ff6c42a935aca27c743910dbb62aae8009854a21741d74080abb406c26b1f58084a7c1351a2986c948c9a111c955d0f8635e4bd305c24f9b6680405fdce955a180ed003737744c7fba94d0c2cb57f96e7bf3310d9c7a285ae789e25af8b79091b38017a0734a39f27a75f6f648bca2facca2381325b529d32bcf82e75aaf6b7d82dd8042e2e666a38ce9fdbe60164d0c3a351ce06c931931d2cd6650378c1ad691c21480d0cc4967746360ee3895a6937608d7f36674426928790cb8ca7426289ad74469804e8940ff6b30dfb0f92341c3a738f262bed9ca03de9b868eb99cfc282aa7786780acda22345d4597dfe6fd831509b944254e26a00fd56e77bc2cb780c0775a520a808c0dae720727cec94dbc853812332bfd6d5f2cc5e287bcd1e5efc530053dbd2280a16a8184b9f2e555d4991995fd479b1ee7b35653f2215f74f822436dbbb2331580984648137ae9c8ecf33f878cedffdba73fb4282ba3ec033102aa6d7442466517801132afeed824c180373b2450b32c72c84a21cdfddbe0f1bf8e76d6958963669580357f2107df0a82f2605f90e39c5665bdf69e1d6222bc425f8390bde67c1d414780c4e048c8dc0ea614a190375a1b215c8e8ff5f5098cd43a93d59be907a2258a74807ad4cd868c49acc40e389d45a1e7e7629e666972ed747c67b607b07f637c1f0b8021bbaa444a77faac92b771c0e1b19162ace64b5ce745892d3ce59f820cba2dc7").to_vec(), hex!("9e710b30bd2eab0352ddcc26417aa1945fd3802284b6ec6d4b3138fca93d003a58421ba947ecbc14c39e76572061105bbc568b809f8b23e74053dd98b58424e102ba5ac16f028714ec16a61522011fe6e16771ff80ed3e43ac278948816e8c9e8adda2dbeefe552702cf8144fd9b50e0b8db99bfcf80694abb8b23315ab79cdb22ca6826e867a9157415a832ad38f376dd819107d3ea80b9aee043e378f8313e68a6030679ccf3880fa1e7ab19b6244b5c262b7a152f004c5f03c716fb8fff3de61a883bb76adb34a2040080f15f37adeb10597dac54c2c65393277b2ca62aa27b2d16a23a78a4cc55ef15bb8008a0c609ab4888f02c2545c002153297c2641c5a7b4f3d8e25c634e721f80bea80b6617c764df278313c426c46961ccde8ee7a03f9007b74bc8bc6c49d1583cf7d801c9a4a3457ad4a568dd4c9abe231304689c9bec78be932ef0a2d30690ca428848059ef8bbe3a06c98792f41b3e0a6cdf1f157d9be85e12a7c1daf9c30f969daba4").to_vec(), // hex!("9f0b3c252fcb29d88eff4f3de5de4476c3ffbf805254dc9131b269f3bbbb71f58a76a5034b2bc2faaab0d1cf45c3819dc6e69740804bc059c3d96f627e09a3b6c0f9851d902f84ac68006617289ac0b7d0a272b36280d97e2394406f94be4266da29b6fe7f3178059525eaf3c9b540064389af020bf180636959b43018d3ff8a55246d5874a16c93e85bd2a58c82ebfc1b54dd9b2a7d0780d3c1a10188200f31459d722f7efc693736d1a36af5644fd949b2e411d7942597800328f24d0485b9701135913a569f6ccbf261a05d055183abf3e4ecb4e4375b7c80f3229cd59de7b1e604f110cbcf814466f2d2973e9bdb6c106a662c576e0820e480b66b29cbd45f93602dbc9f1175407c6f69bd686d23dd22a8f0dfe9cff08843ad80ddb2d426c0c546068b429e77253e0a8a32e818151f5fc031e899a0f6acad157580ea7fb3cad8e128cc295194658016f4865ef37501e5759fb4f15cb2ecb689e85e80e9f3cac1b25842da7fbaf947952dc30329a1d19037ab21baed3851acbee629f6800d898e2a4a6ee9969a233c4741e4441c0fe393104b3cfc5adcf348f3ef20fc7480ac6c622536e593ae3c9d423a461faafc7abbf01ecb129e69d66f3382eaf484dc80c7ba3cadffaea5acd013dba51c96129ae93ea6cd45f3930e4302f5b100f6deae806f29f805e30029363e42381d6609ecb6837411bd6fd676c0a37621a3b5588101").to_vec() - ].into_iter().into(), + ], }; let proof = RelayDipDidProofWithVerifiedRelayStateRoot::<_, _, (), (), _, (), ()>::with_relay_state_root_and_provider_head_proof(relay_state_root, provider_head_proof); assert_err!( diff --git a/crates/kilt-dip-primitives/src/utils.rs b/crates/kilt-dip-primitives/src/utils.rs index 8c055f4fc8..2ceca62e8d 100644 --- a/crates/kilt-dip-primitives/src/utils.rs +++ b/crates/kilt-dip-primitives/src/utils.rs @@ -16,76 +16,9 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org -use parity_scale_codec::{Decode, Encode}; -use scale_info::TypeInfo; -use sp_std::{fmt::Debug, vec::Vec}; - /// The output of a type implementing the [`sp_runtime::traits::Hash`] trait. pub type OutputOf = ::Output; -/// The vector of vectors that implements a statically-configured maximum length -/// without requiring const generics, used in benchmarking worst cases. -#[derive(Encode, Decode, PartialEq, Eq, PartialOrd, Ord, Debug, TypeInfo, Clone)] -pub struct BoundedBlindedValue(Vec>); - -impl BoundedBlindedValue { - pub fn into_inner(self) -> Vec> { - self.0 - } -} - -impl From for BoundedBlindedValue -where - C: Iterator>, -{ - fn from(value: C) -> Self { - Self(value.into_iter().collect()) - } -} - -impl sp_std::ops::Deref for BoundedBlindedValue { - type Target = Vec>; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl sp_std::ops::DerefMut for BoundedBlindedValue { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl IntoIterator for BoundedBlindedValue { - type IntoIter = > as IntoIterator>::IntoIter; - type Item = > as IntoIterator>::Item; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -#[cfg(feature = "runtime-benchmarks")] -impl kilt_support::traits::GetWorstCase for BoundedBlindedValue -where - T: Default + Clone, -{ - fn worst_case(_context: Context) -> Self { - Self(sp_std::vec![sp_std::vec![T::default(); 128]; 64]) - } -} - -#[cfg(any(test, feature = "runtime-benchmarks"))] -impl Default for BoundedBlindedValue -where - T: Default + Clone, -{ - fn default() -> Self { - Self(sp_std::vec![sp_std::vec![T::default(); 128]; 64]) - } -} - pub(crate) use calculate_parachain_head_storage_key::*; mod calculate_parachain_head_storage_key { use parity_scale_codec::Encode; @@ -149,7 +82,7 @@ mod calculate_dip_identity_commitment_storage_key_for_runtime { assert_eq!( calculate_dip_identity_commitment_storage_key_for_runtime::(&DidIdentifierOf::::from_ss58check("4s3jpR7pzrUdhVUqHHdWoBN6oNQHBC7WRo7zsXdjAzQPT7Cf").unwrap(), 0).0, - hex_literal::hex!("b375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f34edc5f456255d7c2b6caebbe9e3adeaaf693a2d198f2881d0b504fc72ed4ac0a7ed24a025fc228ce01a12dfa1fa4ab9a0000") + hex_literal::hex!("b375edf06348b4330d1e88564111cb3d5bf19e4ed2927982e234d989e812f3f314c9211b34c8b43b2a18d67d5c96de9cb6caebbe9e3adeaaf693a2d198f2881d0b504fc72ed4ac0a7ed24a025fc228ce01a12dfa1fa4ab9a0000") .to_vec() ); } diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs index df0f6da68b..4ca660b573 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/mod.rs @@ -65,7 +65,6 @@ pub enum VersionedDipParachainStateProof< ), } -#[cfg(feature = "runtime-benchmarks")] impl< RelayBlockNumber, KiltDidKeyId, @@ -74,8 +73,18 @@ impl< KiltWeb3Name, KiltLinkableAccountId, ConsumerBlockNumber, - Context, - > kilt_support::traits::GetWorstCase + > + From< + ParachainDipDidProof< + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + >, + > for VersionedDipParachainStateProof< RelayBlockNumber, KiltDidKeyId, @@ -84,21 +93,31 @@ impl< KiltWeb3Name, KiltLinkableAccountId, ConsumerBlockNumber, - > where - RelayBlockNumber: Default, - KiltDidKeyId: Default + Clone, - KiltAccountId: Clone, - KiltBlockNumber: Default + Clone, - KiltWeb3Name: Clone, - KiltLinkableAccountId: Clone, - ConsumerBlockNumber: Default, - Context: Clone, + > { - fn worst_case(context: Context) -> Self { - Self::V0(ParachainDipDidProof::worst_case(context)) + fn from( + value: ParachainDipDidProof< + RelayBlockNumber, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + ConsumerBlockNumber, + >, + ) -> Self { + Self::V0(value) } } +pub const DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32 = 128; +pub const DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32 = 1024; +pub const DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32 = 128; +pub const DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32 = 1024; +pub const DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32 = 128; +pub const DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32 = 1024; +pub const DEFAULT_MAX_DID_MERKLE_LEAVES_REVEALED: u32 = 128; + /// Versioned proof verifier. For version-specific description, refer to each /// verifier's documentation. pub struct KiltVersionedParachainVerifier< @@ -108,13 +127,13 @@ pub struct KiltVersionedParachainVerifier< KiltRuntime, DidCallVerifier, SignedExtra = (), - const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32 = 64, - const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32 = 1024, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32 = 64, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32 = 1024, - const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32 = 64, - const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32 = 1024, - const MAX_DID_MERKLE_LEAVES_REVEALED: u32 = 64, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32 = DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32 = DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32 = DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32 = DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE, + const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32 = DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_COUNT, + const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32 = DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_SIZE, + const MAX_DID_MERKLE_LEAVES_REVEALED: u32 = DEFAULT_MAX_DID_MERKLE_LEAVES_REVEALED, >( PhantomData<( RelaychainRuntime, diff --git a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs index 4198f46495..2c852981ab 100644 --- a/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs +++ b/crates/kilt-dip-primitives/src/verifier/parachain/v0/mock.rs @@ -153,25 +153,25 @@ impl pallet_dip_consumer::Config for TestRuntime { type WeightInfo = (); } -pub(crate) const RELAY_BLOCK: u32 = 21; +pub(crate) const RELAY_BLOCK: u32 = 421; pub(crate) const RELAY_STATE_ROOT: H256 = - H256(hex!("23ed6624753dfc87f0721c867abfa77361636314a60d24e8e85b44072b89c3f6")); -pub(crate) const GENESIS_HASH: H256 = H256(hex!("fe0821e1c03846bdff40df39019205b2dce56dd0ccbff6f042d68832a56d358f")); + H256(hex!("6adf8dbf20e1b78f85f6ffe4775640f935d0d8ed38acab327be81089fd90d82d")); +pub(crate) const GENESIS_HASH: H256 = H256(hex!("74f8cd2f3764f676a5e67c45a641ce1025548c6cddcf524a663a9c0aaf7fbee2")); pub(crate) const WRONG_GENESIS_HASH: H256 = H256([0; 32]); pub(crate) const IDENTITY_DETAILS: Option = None; pub(crate) const WRONG_IDENTITY_DETAILS: Option = Some(u32::MAX); -pub(crate) const SIGNATURE_VALID_UNTIL: BlockNumberFor = 56; -pub(crate) const WRONG_SIGNATURE_VALID_UNTIL: BlockNumberFor = 55; +pub(crate) const SIGNATURE_VALID_UNTIL: BlockNumberFor = 199; +pub(crate) const WRONG_SIGNATURE_VALID_UNTIL: BlockNumberFor = 198; pub(crate) fn submitter() -> AccountId32 { - AccountId32::from_ss58check("4qbGXy3VNCxRywCooPHBCiqqC8eBCi8R61FhKMhQgfe6Pi7M").unwrap() + AccountId32::from_ss58check("4qgGXhqTwQmi5CaAhR5s2QpsiUzwrdeksoZG5AusPMpaYqP2").unwrap() } pub(crate) fn wrong_submitter() -> AccountId32 { AccountId32::from_ss58check("4pnAJ41mGHGDKCGBGY2zzu1hfvPasPkGAKDgPeprSkxnUmGM").unwrap() } pub(crate) fn subject() -> DidIdentifierOf { - DidIdentifierOf::::from_ss58check("4p9S4FrPp4HATybUu6FoBaveQynGWzp8oTpJ5KYyfmYZ9RH4").unwrap() + DidIdentifierOf::::from_ss58check("4rTs9KCbLf28yUVsMo5t39ssfW4rPsaqq2UqeZi3hwYLpg3Q").unwrap() } pub(crate) fn call() -> RuntimeCall { @@ -197,35 +197,37 @@ pub(crate) fn cross_chain_proof_with_authentication_key_and_web3_name() -> Parac BlockNumberFor, > { ParachainDipDidProof { provider_head_proof: ProviderHeadStateProof { relay_block_number: RELAY_BLOCK, proof: vec![ - hex!("3703f5a4efb16ffa83d00700005c5197306d02680fa1d14a3b19ba0fa41b17e8949911dda103b1b0476bfc980e").to_vec(), - hex!("790309fd7e1fbcde7136109a7c9d435fac9bd912d8857a7eb6b5a02ada5eef14effd14c9d5f469ad91a7ce17998925ed087b1b0e82d2b213eacdf87eda9bd14bafc7bbbdcd2a3423d2648d844f668a1de5f409dbfbe1c529b6fdf8efa5b8b94c919dcd0c0661757261201d607d080000000004525053528484b480424aa62b5ec40d592c52a3f36bc06afa6b1e8fcf6806dd50c6147304944c05617572610101f4a4dc233d8ddd805ae2e53f987926dd55609fce234019e60bb2b0cd8b70805c5888f3f408cd7c5e39385adef76223445e2473ddeb23760b1863d592281c7182").to_vec(), - hex!("80046480a1736fb82eeef3ae99c2d1dfc79ca72de61d32d379e5accb53bf99203c9c3b2880f6f6801e4b41e2e6d8ec194dba122bfb9eb33feb2545ef5144cea79551f7cc5280d8416fa071a12a1632a04f2cfe01cd9c7beeacc9d90f647cb93d235dd8870e73808c2f1b77b9294abc1a55fc8432f862b4abfa90f9af3a47f138e4d8dfdfee9468").to_vec(), - hex!("80ffff80e4b470c8e610803be35fb30c2297c88daefe2fb9984db06c45b68c441d989f6680fce4c77e35ddc74b02c611a5436c98b6d2fec67ef1d9eb0c706ac06570913aa580594aafb93d9618327a4d0723e4e6ae1c34de455716c3205e665493a88303e3c4809d3100527438cdc0c7b8a19b932fc76e25d7e22b5ef9ca0a0dbcdfeefec9e9238085ab5177d435d816c3143c5a7ffc4bd8929328ec3ec9a8fb6b8ad1ff9eaf08aa80739be177872c5beb6da57440ce6941849b20f0bc344170a48312fa761fa45b3280275ba9412df014f6c2bd421a42b64052417d01defc479406b157ef5733dbf280805b682132c52908705526057f73ab7fccab4af6d72a9805634dd8d3cc53f130d180c2d44d371e5fc1f50227d7491ad65ad049630361cefb4ab1844831237609f08380134bd63183fb7e62530dd82964c89077ec083b5117f24842f8453f6f9fe3d83080afddf55b94871699b66eb154e0b6495121e88337c7b80f86058ddf54ad9e25c3804b438f963950b0230a6bdbe6664bf5a492d1c05a62343dabf14b377024995a1880490ee6b2b446a32bf0bd68d8cdc905688bdc036a5f349ee84deb700f0bcc95a9803b225accc70e19d48fd9b2e3fdec7b185a451556cf50362b056951abf2df89f4806bfdbbf0e0bedcb993b65c9cea1e929a56d78a3b7bc53d1b7ca6fc488e2295ee80d6513cd4e03e5d4dfda76ba48fefe60422081e4f885128b01400ae254fbc48a1").to_vec(), - hex!("9e710b30bd2eab0352ddcc26417aa1945f43803b3441f15daa8a53147d69c48eac75356fab581febbb8030520b248c5942a148801f09f47c0d4767dc1ff9ae54ba8f174d9e5fa06b8242368a39481f5fe5a078f3802e2e0716043a02f2f29fdd52922704af194b98545ce5ca832255e8ec41bcdb6480935f8561d684b40c45e36088c7daa1575cc60b54080e3e023ae43db4092287ba505f0e7b9012096b41c4eb3aaf947f6ea4290800004c5f03c716fb8fff3de61a883bb76adb34a204008092e3fee779c209e5562dd0679d5fcb3876ce9ea0b126e14f1f801a50d8c1d8a44c5f0f4993f016e2d2f8e5f43be7bb259486040080cfad4870b13343cea64432d5dc64a59f0a5c6da43817f25d8a72a3900c9cee17").to_vec(), - hex!("9f0b3c252fcb29d88eff4f3de5de4476c350008072c23a8d4d26e772d0e0e0877b3fa481025ba0f8695a5537b7771587bbe5ca60808e11df642368fb86db2a9cd579f9a3bedf50546a1a325f3c4052c037683e3656").to_vec(), - ].into_iter().into() }, dip_commitment_proof: DipCommitmentStateProof(vec![ - hex!("7f440bf19e4ed2927982e234d989e812f3f32da9da135714ded7366de71f9a6bd6620f03ac92421fea3539e7b80a01bc14cc200265029563162101a12dfa1fa4ab9a00008032e9f6961b6f2915ebb3b3fff7ecdee4d11c1dc7c326c7890cd098498da51df1").to_vec(), - hex!("800c8080da28793d083b197f8d92fc3e77f5064436f1d8eea0fbea56ddb936aba6544500806105b92c7c2c540155c67a2782607dace59d3093432f81564d5ada8bff4be04180b2aafe11c416356c5a97e233670962facb2a18944c3bdc4b9e27f1fa67a5bafe").to_vec(), - hex!("80ffff80353e4d164b13c87910044f1b4e76277e404a0ab46a7cd6c33a65aaadc2375ba88007b1390da34b4dce1328430fd924a6e193517a8148dd70a912c0dc2f7f8d2d4c80ade4fe11f1179c11ffdcbfa22755ecb2b1a904b42a8e61838ac5d61b50527e5180e12d12e0e160241a582c5068f11f66364c4421b3444fc3a69da31576a46e93d180e32fd413c5f3f35cf140619d01c260348df629c9581ddb2ffa3ed3a4454611bc80e73af1cd43b13af0d4726e252583bfc4b0e4f159cacfbedeb14669fec54f16d28014e3e0704c9a07636322335a3c663ec9fd9df8b7bf71d6e8183fefecfbfe0e508089e0d83f324b3a94a57e6c9ca7517f7829acf273e063c3b86e876f5f5000dfad808237efee33d7cbf612b36cf8e72b49b7a7ee4d48085dcaf5ffa8b163261a495b80591a4868cf7eafa20b043d709923044e17e7cde25ee7a35b9732af83d346ddf8808ddf2174553f85bc1836060e6ed175ba06730cecc706a30493e8bcfd9823eeca80e36ae624a00ef6eed407fd4d97dfe9980549cc00adeb2f9454c79d73032e10e48085c95ba8d0c7c8734e14270f873eefada04c1c71d6d99d9236772f890c8a74fa80f395b7003a2eb1e39c624b9a707a6cb58c3cb6997932fc80662ae19c785a91f580b5e5172489541dfc581e116554b63de15fddf38ffed2b109394749c20b8f6ce3805256998e8d08896289d5756f1f96ec6d8f4be237654682f91f559a511bf50a75").to_vec(), - hex!("9e75edf06348b4330d1e88564111cb3d3000505f0e7b9012096b41c4eb3aaf947f6ea429080000801109e5a50d25358a1bcff63c57103c8eb73b80885bb28ba9b666503b8669953e").to_vec(), - ].into_iter().into()), dip_proof: crate::DidMerkleProof { blinded: vec![ - hex!("8022000000").to_vec(), - hex!("7f04069d06a63af2662632789148708798b64f753eb007f162a641efbbe572f20e33010000").to_vec(), - hex!("6f0c623964373239616630626365346664303738313630393800").to_vec(), - ].into_iter().into(), revealed: vec![ + hex!("3703f5a4efb16ffa83d0070000da00d3541403539d4256de2db65d713afc8aedc8abede84d5dc4014019605d94").to_vec(), + hex!("8004648031b60c9237ed343094831987f2bec10b211621255ad0b440cf161fa820d30db480f6f6801e4b41e2e6d8ec194dba122bfb9eb33feb2545ef5144cea79551f7cc52801287b410de904c199ac477f0d317d3a4b9a45b5424236719bbe2b2f0736a505a80c2160c2830b22a1eb05c14f6a9e20639de8f9e21dcd0e621ca18540027f89ba5").to_vec(), + hex!("80ffff80d8655205caee5e0a6b74cdf5b1adc20aea610833ad71da05d3143031b5744be58015f6db81af2768203cf235fa69602e86dd51d963cbaf2e93e3d08a7a71436ac280f48da460759e201ca3c3b9127a366e235ecdbb721c7fdd02673544b39c1a0e7180095af3328f28eb7c21cf96129f628930323efd14acb42e674600f4542a2347e980e277a338d70d91f2da9e3fcdd516aadfaa1e9aa3c91080a74d1580bf033d524d80eb47b9f01723d00dbf42a4227b4b217f2bf928240d54e2f57b32b73f088158fa80c8b5d1d00527c8ba24530642a1f9049ee21ccd7d2923158e31bdb16b1e16b9ed805b682132c52908705526057f73ab7fccab4af6d72a9805634dd8d3cc53f130d180c2d44d371e5fc1f50227d7491ad65ad049630361cefb4ab1844831237609f08380a6a172370370c5b197e769e205270d4e0a36d5d8c300384ad3a04b97f7167a188036f5935fe1e0440c815666c5d68304f0723de7be305845935ab7220dd222ef868040f4d528d1dcbfb62dbc70e0c242402975b6b4009001aec75a1239f23d5650b9809d95d41f288555f74a76e2d8ec9691d240a8d9a9a57851c85e2e390d0fba659780f5528af32ddc75ed1e91e25b644e0d9fc506d1828fe5876beca37860c51b884a806bfdbbf0e0bedcb993b65c9cea1e929a56d78a3b7bc53d1b7ca6fc488e2295ee80e9810f66374c83abcac91f2c4e0b6592dab9bea79e432c469a65efc0488e93d0").to_vec(), + hex!("8103bc05984bd8e93876468ac91f85d3a6afca02e9729db00c0214032d745bcf0d5a4502b7819c39bf85ecf59d380c6b36e0542d8f5f587756fdadc94058c345804ef2f92f35250cbd9abe38f049145ec553be0b232b6b705a7bd95fe6f0134106e0b5440c0661757261209c1e7e0800000000045250535288dba69c63177375777ef2360d7023a05e5af585aa6a1be07aac94cfb0c3979cc88d0605617572610101266c2da415cf67bc39e13f754f212eaba3839d7d5aea0c42376e00e3c376572c1ba3cb1e156ea8b3a3a6dae589a1d62a861f0247487391452b2d0f10862ea780").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945f43803b3441f15daa8a53147d69c48eac75356fab581febbb8030520b248c5942a14880ec1d5ee4349a9c6f534ce103adef97bc85a794ba786d51bd75d2fe2bc9826134802e2e0716043a02f2f29fdd52922704af194b98545ce5ca832255e8ec41bcdb6480a0718fee6fd849f63aebd00a6e9d09e984d70549c0b5475b16c244090876e628505f0e7b9012096b41c4eb3aaf947f6ea4290800004c5f03c716fb8fff3de61a883bb76adb34a20400808aefdc67024312a782a33b24ee2d1bfa728e3842db64274191fa9a4f0f7a56744c5f0f4993f016e2d2f8e5f43be7bb259486040080949e352413ff8a43f35e73a6077d7a87a2de45fb6ce9bc40ad3717bdbf7a5708").to_vec(), + hex!("9f0b3c252fcb29d88eff4f3de5de4476c3500080680174266144346b8929a369c75acac037ac3b4edfde15b308cddfa28b7def8e805e009b7041665711ae523d4eab10f4cc0b3c7d8f0283381899b208aa42435ba3").to_vec(), + ] }, dip_commitment_proof: DipCommitmentStateProof(vec![ + hex!("7f3200658e5d6cfde41fac5eadc5b800e29cf53cf19360e5cac6055254c77d91a79701381c47e03e17c3284aa85edc851e01a12dfa1fa4ab9a0000802e1cdab36fe7e9ffaa624f5d86fa18b9809536271f60d4363b0bbf672c240f68").to_vec(), + hex!("800c8080da28793d083b197f8d92fc3e77f5064436f1d8eea0fbea56ddb936aba654450080738fe375d48815633f8040a1f7c6311aba813d535b0f23b37e5139c85c6b4f0880b2aafe11c416356c5a97e233670962facb2a18944c3bdc4b9e27f1fa67a5bafe").to_vec(), + hex!("80ffff80353e4d164b13c87910044f1b4e76277e404a0ab46a7cd6c33a65aaadc2375ba88007b1390da34b4dce1328430fd924a6e193517a8148dd70a912c0dc2f7f8d2d4c806322b31235b002ea35614d4eaa1282246a5cefe4a625e5265170d93f2adb9a64802407df9dc8f440a6f8ee7cde4b162e5406ffb5c2a4c99de693bcd20350cc74e0806b313ff9ef1a351bfcc5351cc3b42f8a4fdf1b4a612c350a970677ab3adc91308077be4f344b7438aec6d87a6a29089d64db3dcab9fcec7b91ee4eb37b8afc56c98014e3e0704c9a07636322335a3c663ec9fd9df8b7bf71d6e8183fefecfbfe0e508021d9b25eb4eb0be974f964ba45a39182e42c74034baa38b7499bf7eab8253533804d54f9f6624640788154e78f39dd9b535ba37be663a4ff7b9423bc28637c9f0c8035f638d2e64e75369bba87d0c8aaecf3374294d77818a299ce98dd7d7ff208ee8070de6b035f859c70b5df439f7793eaeca3d858b04dfe70d0a08b1ca06571e87d804aaaff272d09c1b5593870282b1f09e12e8ad325794662edc4a12c02bfd853a880f341940454f25e0b2c93b674eaca644f4ecdd9ace1c3955197f222fda677eebf80f395b7003a2eb1e39c624b9a707a6cb58c3cb6997932fc80662ae19c785a91f580b5e5172489541dfc581e116554b63de15fddf38ffed2b109394749c20b8f6ce3801c763d73cb3d67092a0f18f421080b782403b0a95b6c92bd8dc60e80baf2b1a5").to_vec(), + hex!("810210108082cadebddb74d7ea90430a7205294eedaafa180228e73bd9849228dbabbf32698025b425162cc535f40a255ba9be090e12d1b50aa8a6ec0b108acb60ec048268da").to_vec(), + hex!("9e75edf06348b4330d1e88564111cb3d3000505f0e7b9012096b41c4eb3aaf947f6ea429080000803e5de95874c4bbe730354a3a777b39be54d6141653673cda856be1d5a8893c78").to_vec(), + hex!("9f0bf19e4ed2927982e234d989e812f3f348008028e4e828a83fd632d6d17fa940bb289ef8d04c1c154ecbf583d677460bef22128048f06290dfec2596fa70eaca62ea496d3dc0cd2f51fd40c61b58d7e5b476eebd").to_vec(), + ]), dip_proof: crate::DidMerkleProof { blinded: vec![ + hex!("8020040000").to_vec(), + hex!("6f0c396636316435353033376335383836623033393636633900").to_vec(), + hex!("7f04099e99fc7ce5529bc72a0846778d0f62137ddcbab51a1af2d3e91752962d91b4010000").to_vec(), + ], revealed: vec![ RevealedDidKey { - id: hex!("169d06a63af2662632789148708798b64f753eb007f162a641efbbe572f20e33").into(), + id: hex!("a99e99fc7ce5529bc72a0846778d0f62137ddcbab51a1af2d3e91752962d91b4").into(), relationship: DidVerificationKeyRelationship::Authentication.into(), details: DidPublicKeyDetails { - key: DidVerificationKey::Sr25519(sr25519::Public(hex!("366de71f9a6bd6620f03ac92421fea3539e7b80a01bc14cc2002650295631621"))).into(), - block_number: 4 + key: DidVerificationKey::Sr25519(sr25519::Public(hex!("9cf53cf19360e5cac6055254c77d91a79701381c47e03e17c3284aa85edc851e"))).into(), + block_number: 144 } }.into(), RevealedWeb3Name { - web3_name: b"b9d729af0bce4fd07816098".to_vec().try_into().unwrap(), - claimed_at: 4 + web3_name: b"9f61d55037c5886b03966c9".to_vec().try_into().unwrap(), + claimed_at: 144 }.into() - ] }, signature: TimeBoundDidSignature::new(did::DidSignature::Sr25519(sr25519::Signature(hex!("faf3508b0075d8570bb1a79f7aeba4b08e9ae88f16bb9fc44eaf6f203bad842f75dfc17b114e015c7ccdaa672c359bb066961ba2cbaccf3308dc44e0fee3b28c"))), SIGNATURE_VALID_UNTIL) } + ] }, signature: TimeBoundDidSignature::new(did::DidSignature::Sr25519(sr25519::Signature(hex!("3cd5e72f04d248e5155bfdabb94c308a88368db63a8a0cafc15fb3204a709b07da028cf85bd450d9a2bdb6679f2b07ac69188101185ab3acd9f41419cbfb3c81"))), SIGNATURE_VALID_UNTIL) } } // Aliases requires because the pallet does not expose anything public. diff --git a/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs b/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs index d1909153a8..e3d98bd74c 100644 --- a/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs +++ b/crates/kilt-dip-primitives/src/verifier/relaychain/mod.rs @@ -32,7 +32,7 @@ use crate::{ merkle_proofs::v0::RevealedDidKey, traits::{DipCallOriginFilter, GetWithArg, GetWithoutArg, Incrementable}, utils::OutputOf, - DipOriginInfo, + DipOriginInfo, RelayDipDidProof, }; pub mod v0; @@ -55,7 +55,7 @@ pub enum VersionedRelaychainStateProof< KiltLinkableAccountId, > { V0( - crate::merkle_proofs::v0::RelayDipDidProof< + RelayDipDidProof< ConsumerBlockNumber, ConsumerBlockHasher, KiltDidKeyId, @@ -67,6 +67,59 @@ pub enum VersionedRelaychainStateProof< ), } +impl< + ConsumerBlockNumber: Copy + Into + TryFrom, + ConsumerBlockHasher: Hash, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > + From< + RelayDipDidProof< + ConsumerBlockNumber, + ConsumerBlockHasher, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + >, + > + for VersionedRelaychainStateProof< + ConsumerBlockNumber, + ConsumerBlockHasher, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + > +{ + fn from( + value: RelayDipDidProof< + ConsumerBlockNumber, + ConsumerBlockHasher, + KiltDidKeyId, + KiltAccountId, + KiltBlockNumber, + KiltWeb3Name, + KiltLinkableAccountId, + >, + ) -> Self { + Self::V0(value) + } +} + +pub const DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32 = 128; +pub const DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32 = 1024; +pub const DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32 = 128; +pub const DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32 = 1024; +pub const DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32 = 128; +pub const DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32 = 1024; +pub const DEFAULT_MAX_DID_MERKLE_LEAVES_REVEALED: u32 = 128; + /// Versioned proof verifier. For version-specific description, refer to each /// verifier's documentation. pub struct KiltVersionedRelaychainVerifier< @@ -75,13 +128,13 @@ pub struct KiltVersionedRelaychainVerifier< KiltRuntime, DidCallVerifier, SignedExtra = (), - const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32 = 64, - const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32 = 128, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32 = 64, - const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32 = 128, - const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32 = 64, - const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32 = 128, - const MAX_DID_MERKLE_LEAVES_REVEALED: u32 = 64, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT: u32 = DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, + const MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE: u32 = DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT: u32 = DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT, + const MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE: u32 = DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE, + const MAX_DID_MERKLE_PROOF_LEAVE_COUNT: u32 = DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_COUNT, + const MAX_DID_MERKLE_PROOF_LEAVE_SIZE: u32 = DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_SIZE, + const MAX_DID_MERKLE_LEAVES_REVEALED: u32 = DEFAULT_MAX_DID_MERKLE_LEAVES_REVEALED, >(#[allow(clippy::type_complexity)] PhantomData<(ConsumerBlockHashStore, KiltRuntime, DidCallVerifier, SignedExtra)>); impl< diff --git a/dip-template/runtimes/dip-consumer/Cargo.toml b/dip-template/runtimes/dip-consumer/Cargo.toml index 5a2986fbd5..cb7a7c4267 100644 --- a/dip-template/runtimes/dip-consumer/Cargo.toml +++ b/dip-template/runtimes/dip-consumer/Cargo.toml @@ -13,6 +13,9 @@ version.workspace = true [build-dependencies] substrate-wasm-builder.workspace = true +[dev-dependencies] +sp-io = {workspace = true, features = ["std"]} + [dependencies] parity-scale-codec = {workspace = true, features = ["derive"]} scale-info = {workspace = true, features = ["derive"]} @@ -66,6 +69,8 @@ rococo-runtime.workspace = true # Benchmarks frame-benchmarking = {workspace = true, optional = true} frame-system-benchmarking = {workspace = true, optional = true} +kilt-support = { workspace = true, optional = true } +hex-literal = { workspace = true, optional = true } [features] default = [ @@ -114,6 +119,7 @@ std = [ "rococo-runtime/std", "frame-benchmarking?/std", "frame-system-benchmarking?/std", + "kilt-support?/std", ] runtime-benchmarks = [ @@ -133,4 +139,6 @@ runtime-benchmarks = [ "rococo-runtime/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", + "kilt-support/runtime-benchmarks", + "hex-literal" ] diff --git a/dip-template/runtimes/dip-consumer/src/dip.rs b/dip-template/runtimes/dip-consumer/src/dip.rs index fa7a97516b..91a0dbbfab 100644 --- a/dip-template/runtimes/dip-consumer/src/dip.rs +++ b/dip-template/runtimes/dip-consumer/src/dip.rs @@ -17,11 +17,19 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org use did::{DidVerificationKeyRelationship, KeyIdOf}; -use dip_provider_runtime_template::{AccountId as ProviderAccountId, Runtime as ProviderRuntime}; +use dip_provider_runtime_template::{ + AccountId as ProviderAccountId, Runtime as ProviderRuntime, MAX_PUBLIC_KEYS_PER_DID, MAX_REVEALABLE_LINKED_ACCOUNTS, +}; use frame_support::traits::Contains; use frame_system::{pallet_prelude::BlockNumberFor, EnsureSigned}; use kilt_dip_primitives::{ - traits::DipCallOriginFilter, KiltVersionedParachainVerifier, RelayStateRootsViaRelayStorePallet, RevealedDidKey, + parachain::{ + DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_COUNT, DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_SIZE, + DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT, DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE, + DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, + }, + traits::DipCallOriginFilter, + KiltVersionedParachainVerifier, RelayStateRootsViaRelayStorePallet, RevealedDidKey, }; use pallet_dip_consumer::traits::IdentityProofVerifier; use rococo_runtime::Runtime as RelaychainRuntime; @@ -30,20 +38,494 @@ use sp_std::{marker::PhantomData, vec::Vec}; use crate::{weights, AccountId, DidIdentifier, Runtime, RuntimeCall, RuntimeOrigin}; -pub type MerkleProofVerifierOutput = >::VerificationResult; -/// The verifier logic assumes the provider is a sibling KILT parachain, the -/// relaychain is a Rococo relaychain, and that a KILT subject can provide DIP -/// proof that reveal at most 10 DID keys and 10 linked accounts (defaults -/// provided by the `KiltVersionedParachainVerifier` type). Calls that do not -/// pass the [`DipCallFilter`] will be discarded early on in the verification -/// process. -pub type ProofVerifier = KiltVersionedParachainVerifier< +// +1 for the web3name. +const MAX_PROVIDER_REVEALABLE_KEYS_COUNT: u32 = MAX_PUBLIC_KEYS_PER_DID + MAX_REVEALABLE_LINKED_ACCOUNTS + 1; + +/// The verifier logic is tied to the provider template runtime definition. +pub type ProviderTemplateProofVerifier = KiltVersionedParachainVerifier< RelaychainRuntime, RelayStateRootsViaRelayStorePallet, 2_000, ProviderRuntime, DipCallFilter, BlockNumberFor, ProviderAccountId>, + (), + DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_COUNT, + DEFAULT_MAX_PROVIDER_HEAD_PROOF_LEAVE_SIZE, + DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_COUNT, + DEFAULT_MAX_DIP_COMMITMENT_PROOF_LEAVE_SIZE, + DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_COUNT, + DEFAULT_MAX_DID_MERKLE_PROOF_LEAVE_SIZE, + MAX_PROVIDER_REVEALABLE_KEYS_COUNT, >; +pub type MerkleProofVerifierInput = >::Proof; +pub type MerkleProofVerifierOutput = + >::VerificationResult; +// Wrapper around the verifier to implement the `GetWorstCase` trait (required +// due to orphan rule). +pub struct ProviderTemplateProofVerifierWrapper; + +// Delegate verification logic to the specialized version of +// `KiltVersionedParachainVerifier`. +impl IdentityProofVerifier for ProviderTemplateProofVerifierWrapper { + type Error = >::Error; + type Proof = MerkleProofVerifierInput; + type VerificationResult = MerkleProofVerifierOutput; + + fn verify_proof_for_call_against_details( + call: &pallet_dip_consumer::RuntimeCallOf, + subject: &::Identifier, + submitter: &::AccountId, + identity_details: &mut Option<::LocalIdentityInfo>, + proof: Self::Proof, + ) -> Result { + >::verify_proof_for_call_against_details( + call, + subject, + submitter, + identity_details, + proof, + ) + } +} + +// Implement worst-case logic for this specific verifier. +#[cfg(feature = "runtime-benchmarks")] +impl kilt_support::traits::GetWorstCase for ProviderTemplateProofVerifierWrapper { + type Output = pallet_dip_consumer::benchmarking::WorstCaseOf; + + fn worst_case(_context: ()) -> Self::Output { + use did::{ + did_details::{DidEncryptionKey, DidPublicKeyDetails, DidVerificationKey}, + DidSignature, + }; + use frame_support::{pallet_prelude::ValueQuery, storage_alias, Twox64Concat}; + use hex_literal::hex; + use kilt_dip_primitives::{ + DidKeyRelationship, DidMerkleProof, DipCommitmentStateProof, ParachainDipDidProof, ProviderHeadStateProof, + RevealedAccountId, RevealedWeb3Name, TimeBoundDidSignature, + }; + use pallet_dip_consumer::benchmarking::WorstCaseOf; + use pallet_relay_store::RelayParentInfo; + use sp_core::{ed25519, sr25519, H256}; + use sp_runtime::AccountId32; + use sp_std::vec; + + #[storage_alias] + type BlockHash = StorageMap< + System, + Twox64Concat, + BlockNumberFor, + ::Hash, + ValueQuery, + >; + #[storage_alias] + type LatestRelayHeads = StorageMap>; + + const PROOF_RELAY_BLOCK: u32 = 589; + + let provider_head_state_proof = ProviderHeadStateProof::new(PROOF_RELAY_BLOCK, vec![ + hex!("3703f5a4efb16ffa83d007000088e2fdf5c9b8f94277579ae683ead98aae1e06facab1d301144a0271157399ee").to_vec(), + hex!("8004648031b60c9237ed343094831987f2bec10b211621255ad0b440cf161fa820d30db480f6f6801e4b41e2e6d8ec194dba122bfb9eb33feb2545ef5144cea79551f7cc5280bfc5f17f5701ebcd8a25d9e08a90343321779f9c335471d0b22c2686bd57d9c0800ad654b674c2cd45843018e4083f71d892f9463aab9920f166d47499aecc3e1d").to_vec(), + hex!("80ffff8002af9d53d0fe38d916e77086562a2af535ec94a36494384d66273d2339604f2380c5801068e98806370ad5939ba17df962ca6c5e7a7b06b34def0bd9a286f3349780173d3299944e3f85dac5b2c2ecb3f1f13f26df47f38c25d937077d0f344caa0780521bb76b6b176fa67e1f40de0f8cdf439ef8dc3e6ca5e483055eeba380bc7b7a809a6d265f539abd682eb0f593cd3c0006367a48bc4a4bd7eb6b755bc48b187c9f8039c39d126632e3b9af053befe643119111fb627077145ebf8ab8277f4e791f6a80646452cc2e74ebf3311ffcdfcaa4bdbd0b31c19d6fc777be9f7a4f5808d96cc2805b682132c52908705526057f73ab7fccab4af6d72a9805634dd8d3cc53f130d180c2d44d371e5fc1f50227d7491ad65ad049630361cefb4ab1844831237609f08380fe93a2a86fd60f3c6b30051cec7e5e72d331b6f4b6fc142834eac567e6a3aca1808b058239988689d9aa6cb8721760371dce42f384ec0f95771555e195320d3e18800ff113df26dc01f6916caf9728ad8ddf2d278362ab63312ec47e40e63ac7ac9880603666dff2710c1262571a56902a9bae2066026f57a9499c98ef56a700abf94c808c1356abbbc74f6009a7b95604976482b2b4573ba58a14072283b5ca5b37bafa806bfdbbf0e0bedcb993b65c9cea1e929a56d78a3b7bc53d1b7ca6fc488e2295ee801f25bd16505bdd55875b871aa63dc73faff8929e8010ca2b535868849af770ed").to_vec(), + hex!("810338345b941f7b5396da7c8a8ee4a561ea107105bc488887d68344fa716bc271a691030290b49b480f77d69ceb87a8b854012d2f704508d735c7a5e03df7a098869e2b6391949b5d132b311d09614c6bcf46b282c8dee37128faef7f10353ec1f310c40c066175726120f01e7e0800000000045250535288db2cb81d66fb9974bab34f6375abcb3531524bec8f7f20c09cea921e9eae84092d09056175726101017a967f2b9621cdaaf8860e8887f82f950580bd90f366382092452b019a71217039afdf809b48809cfe00b68a958ff74bb38b070216f90d10ffad2d1aa665bc82").to_vec(), + hex!("9e710b30bd2eab0352ddcc26417aa1945f43803b3441f15daa8a53147d69c48eac75356fab581febbb8030520b248c5942a148804dbeecdd4792782a820b4f713c58dece06bd69e8fcb9b506fe052a24eb7eb0eb802e2e0716043a02f2f29fdd52922704af194b98545ce5ca832255e8ec41bcdb6480a0718fee6fd849f63aebd00a6e9d09e984d70549c0b5475b16c244090876e628505f0e7b9012096b41c4eb3aaf947f6ea4290800004c5f03c716fb8fff3de61a883bb76adb34a20400808aefdc67024312a782a33b24ee2d1bfa728e3842db64274191fa9a4f0f7a56744c5f0f4993f016e2d2f8e5f43be7bb259486040080949e352413ff8a43f35e73a6077d7a87a2de45fb6ce9bc40ad3717bdbf7a5708").to_vec(), + hex!("9f0b3c252fcb29d88eff4f3de5de4476c3500080d94a128016b9dd6dce1aca270b09fa36eeb8227e134f24b89ca7bde76723c44c808f4595bab11d5f07ca595107dbae994cd82279c9b5e437230d387e2be69c49bd").to_vec(), + ]); + let dip_commitment_proof = DipCommitmentStateProof::new(vec![ + hex!("7f340f4ac20413f4e00f0a9eaae0343e8e56e68a94309d0adee950b6a63a0a141a3166c15e8ef25c301531f75e25086fe05a01a12dfa1fa4ab9a000080dc96078e1aa097ade1ee470e32ebdd2e6f5808cbfa62f1a625cc21b88677c272").to_vec(), + hex!("800c8080da28793d083b197f8d92fc3e77f5064436f1d8eea0fbea56ddb936aba654450080a1588f087b233f3494cdc5cdf5147d6dbfa9651bd2974f5e82b3b00dcbfdc0f18081acf868c884e3bbeb26e53acb3a2e4eca7bd36b22d30e0cffb36ed0c48305bb").to_vec(), + hex!("80ffff80353e4d164b13c87910044f1b4e76277e404a0ab46a7cd6c33a65aaadc2375ba88007b1390da34b4dce1328430fd924a6e193517a8148dd70a912c0dc2f7f8d2d4c80f0a8aefb3eb62ec86937a4e49657b03d7de0588ad6bb795a4ebb0b5654d9e63880fef940f449f15a0e6fa92eeac30b55e5a69d939d85dfc9e6b75545ea5fb5b6f680048e707e1b93570f4506833da06205a54a4e7ff36092237904359e7461fd44d38020f7b28bc23361dcfa7b988a30f92202a9fd05d783f27b89f304c41eeca500958014e3e0704c9a07636322335a3c663ec9fd9df8b7bf71d6e8183fefecfbfe0e5080259cb4cd05acf09d7a9d7e9935585ff95670dc498cfc365c25b217d66b985f28802943cf2440d02afc0e2a7fb7567af93eba7d83bba93e8e8d7dc4abe20544cb53802b320a7ee167d52bd32ffcd3d94312f8d17c0eadeb2840c0b448de09ac54e3e7803ee8e59b8b261a960b3d00106c36cecfa42b5f72dac70d37530f1958a080da8080b6d9076aa2cd7e8700fb5a5b3ef182975c6515077195c911748da5d21434220e800eaec11c028f926112839db018f6de72c505168b910bbe589d8c83ebdc4fca8d80f395b7003a2eb1e39c624b9a707a6cb58c3cb6997932fc80662ae19c785a91f580b5e5172489541dfc581e116554b63de15fddf38ffed2b109394749c20b8f6ce380949007eae7367a82ee80988be32c8f8f6d936593122a6576d186ba6be490b5bb").to_vec(), + hex!("9e75edf06348b4330d1e88564111cb3d3000505f0e7b9012096b41c4eb3aaf947f6ea42908000080f20e8f088dd913ee6a53e72e9de980ad8256cb48c3718f8080c0efeeb43e64cd").to_vec(), + hex!("9f0bf19e4ed2927982e234d989e812f3f348408028e4e828a83fd632d6d17fa940bb289ef8d04c1c154ecbf583d677460bef22128048f06290dfec2596fa70eaca62ea496d3dc0cd2f51fd40c61b58d7e5b476eebd80c898c636c42ebafd67de87f4ebe2e79a6de88441d420e423dba761169752355b").to_vec(), + ]); + let dip_proof = DidMerkleProof::new( + vec![ + hex!("80bf2f000000000000000000000000").to_vec(), + hex!("800281000000").to_vec(), + hex!("809697000000000000000000").to_vec(), + hex!("7f000207da77a11b67f17653408a8d6cf85d10b3f366c7e7be82f3b30a8eb935c66c00").to_vec(), + hex!("7f0000acfd57871165f2330ca49a4ddafabc52698bc894c899d6368107056ee90c2200").to_vec(), + hex!("7f000afc8c7501fd42bd62db9953e4c54bdf154ff9f5255ebd362b2b795a271b3a7b00").to_vec(), + hex!("8002020000").to_vec(), + hex!("7edb492c2503f35d8b783e6d077875aedf473c502c3f641c5c87dad957e3f98b00").to_vec(), + hex!("7e1dfe90617727b1c2c2d4a570b6e7d042b228c62eba1aeb0f1d43a99d2ee88300").to_vec(), + hex!("7f0006ad76d64191ec2a4bfee79fadbb7085fa8ccfb7a590cb91b0f3ebd7ec943df900").to_vec(), + hex!("7f0008fd1a85f17803a48501005e8fc59bb69ede7407062f83f1a950b917951f9bba00").to_vec(), + hex!("7f0007beb4c2f6b8b2143dcec8771011006b6380ab3a65530ebc849a6a518e4f586000").to_vec(), + hex!("7f000ceb4ca89584fa1bbb95318204596d8f883101dfeb6b8ebfa61f3a2d081789fe00").to_vec(), + hex!("7f0007a3e3a7ffb4e10170a73b41039e7298b67ae2fe1d7b8cbfbcb9a19122c51e4b00").to_vec(), + hex!("7f01c204f1ff9fb3da19442271d014cf3fafa761d4f624d718e729efba11065e300000").to_vec(), + hex!("7f014c3e671d00ed67683177268a1aae0f7faf290e4754730bb8b0fff18243cc600000").to_vec(), + hex!("802120000000").to_vec(), + hex!("7f036e6b1fa2d0ac6b81387fce6eb985b760f70a43a6d8e0c3f9e78c8a9d9e548e010100").to_vec(), + hex!("7f01ffb682b21cd48217b4010102721378f80e0463cbfbd5a39b0f08b4801d57520000").to_vec(), + hex!("7f01bf0e5f1c3a6536b9b6c7cd2da10e0dfaba631f50ed16a115b6dc53ba1ff2060000").to_vec(), + hex!("7f020af4abba9639e828f74df06a5729504ac2ab50e417065f717ed66ee85d1ff88f0000").to_vec(), + hex!("8000110000").to_vec(), + hex!("7f01ca9fef5649916accf658e00f703dc2d66bca2fe39b3daa24bbbb096a18bdbf0000").to_vec(), + hex!("7f017939667bd5080dd837a5187381b02e5944960f73a364fc3499d39ed10ba47d0000").to_vec(), + hex!("7f020f5333e95049a79201ad8be14bc94440590a41402384ee141b4f17be5b94e57f0000").to_vec(), + hex!("800250000000").to_vec(), + hex!("7f010abbb2522022332bec89495323df12567b5abe2f8fcc2e3da40756bfbb7b5e0000").to_vec(), + hex!("6e353639396133633537343834316234653335336433373700").to_vec(), + hex!("7f0314c0826d524d79a17cb5bc5fd61f9b2d364c9af73a5db87408f389e83afcdf010300").to_vec(), + hex!("8000030000").to_vec(), + hex!("7f03e54fc7807f8c1cbd6e3dac9f3291096e7a2d8ab879934edb402f320a3d46a0010000").to_vec(), + hex!("7f0194423645f905c2ecc8d07b89babe374ebf761c2b4676c95a749ae7f3f840720000").to_vec(), + hex!("7f02058867de4a252085d0a8a1078b6d72b8adf1912565bac7733be05b4bf3cbb4ae0000").to_vec(), + hex!("805800000000").to_vec(), + hex!("7f0131acdacf05ed4d81448e501ff82a979ddfe90342b62c2d439df8b2bdf6f56a0000").to_vec(), + hex!("7f0198d9c99157dc9b19fbe30fa8057f0337cfa0b2e23181081b20137f0a2bba5d0000").to_vec(), + hex!("7f01091a1d3dbf3b1f12c41cf1b4e9c7cf59039aa6407e3010f32d5079ceba07a30000").to_vec(), + hex!("7f020e59e300e930fa773ef7b8ed42a07c77c2913650a8323caa2fd143ecbb75bfac0000").to_vec(), + hex!("7f020a4664e1571d22e18e0d45969da0479cbfb8b2bc5fb37850719f7f7fa506267d0000").to_vec(), + hex!("7f020522e1a7e2ae92f98383e9ff7eb0fbb5baaf09999db7c4161652d3e233af0d140000").to_vec(), + ], + vec![ + RevealedDidKey { + id: hex!("78e54fc7807f8c1cbd6e3dac9f3291096e7a2d8ab879934edb402f320a3d46a0").into(), + relationship: DidVerificationKeyRelationship::Authentication.into(), + details: DidPublicKeyDetails { + key: DidVerificationKey::Sr25519(sr25519::Public(hex!( + "e68a94309d0adee950b6a63a0a141a3166c15e8ef25c301531f75e25086fe05a" + ))) + .into(), + block_number: 227u64, + }, + } + .into(), + RevealedDidKey { + id: hex!("08c204f1ff9fb3da19442271d014cf3fafa761d4f624d718e729efba11065e30").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "bd09a314a5f66ad2c56639140862bfaad56071044c78e41ba4756ab21147b824" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("0f4c3e671d00ed67683177268a1aae0f7faf290e4754730bb8b0fff18243cc60").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "e503588f6016e08c7ff79c7e74817ecd264b2a97707998748527ef7766819e27" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("15ffb682b21cd48217b4010102721378f80e0463cbfbd5a39b0f08b4801d5752").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "ac95eb8c17f951bb9ae41d19fa9dac75342c6b9b901be6da6a5f42265b491635" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("1dbf0e5f1c3a6536b9b6c7cd2da10e0dfaba631f50ed16a115b6dc53ba1ff206").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "c102dfa2aa8b9ed85e5a67c0612bcf6a3b702ad10fab937881bf57e8a344eb5c" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("2af4abba9639e828f74df06a5729504ac2ab50e417065f717ed66ee85d1ff88f").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "89d45b096b0cd8163dc18bd0bf74399c933116f9de79bda845f00d27b3f2c657" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("38ca9fef5649916accf658e00f703dc2d66bca2fe39b3daa24bbbb096a18bdbf").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "5ce39370f803bea2f945a82e97a06bdea1d340a210dba62f865077018c45cb16" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("3c7939667bd5080dd837a5187381b02e5944960f73a364fc3499d39ed10ba47d").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "f675a09e224219c63b3e33b067ff0b2dc1584c504f1908ed2518d5cceae20347" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("4f5333e95049a79201ad8be14bc94440590a41402384ee141b4f17be5b94e57f").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "7849c1371c98d2bc940df61b22b5094124eaa82151c85068b97f2a37e5abd713" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("510abbb2522022332bec89495323df12567b5abe2f8fcc2e3da40756bfbb7b5e").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "581f2d1e3988a7cf7a695bf77485aa06473b9a67b077df3171dcc15e4d88f521" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("7994423645f905c2ecc8d07b89babe374ebf761c2b4676c95a749ae7f3f84072").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "82545402deeffdc4a6c8d53f8b2442f54e4ec5ed0c26f59d8089300699b7a40a" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("858867de4a252085d0a8a1078b6d72b8adf1912565bac7733be05b4bf3cbb4ae").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "f201c6ca5bb324698e6e1fcebeef42f34f66fd62cd183df1149892a7dcf7cb48" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("9331acdacf05ed4d81448e501ff82a979ddfe90342b62c2d439df8b2bdf6f56a").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "baa2ab5a4663e440b13417864b043ce18af6990f5d1563afdb0e2fec040aed3f" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("9498d9c99157dc9b19fbe30fa8057f0337cfa0b2e23181081b20137f0a2bba5d").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "3f6fb782a6809668998634e264abe3ecc97f15b8f726b86c6a5024fec1d39e53" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("96091a1d3dbf3b1f12c41cf1b4e9c7cf59039aa6407e3010f32d5079ceba07a3").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "de2f7b17ca8a01055027dc2d424ef9b01c0df98ae42fea41a462f84e447ca230" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("ae59e300e930fa773ef7b8ed42a07c77c2913650a8323caa2fd143ecbb75bfac").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "755bdbb3dc4f43d8b3a8c8b19f07bc362ab9015fe3276b3f64439f9ec67e8b0f" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("ba4664e1571d22e18e0d45969da0479cbfb8b2bc5fb37850719f7f7fa506267d").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "bdeaf31cab91d67cea1c6b3f64fa9e9e66826e271e01690f181851d8831e4317" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("d522e1a7e2ae92f98383e9ff7eb0fbb5baaf09999db7c4161652d3e233af0d14").into(), + relationship: DidKeyRelationship::Encryption, + details: DidPublicKeyDetails { + key: DidEncryptionKey::X25519(hex!( + "cb7cb8c59b2784b87d2270ab4e41f661b4626590954dbd3400208eb1f958f77e" + )) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("106e6b1fa2d0ac6b81387fce6eb985b760f70a43a6d8e0c3f9e78c8a9d9e548e").into(), + relationship: DidVerificationKeyRelationship::CapabilityDelegation.into(), + details: DidPublicKeyDetails { + key: DidVerificationKey::Ed25519(ed25519::Public(hex!( + "39985b639d8d21629190f2a310b0e2b935894a6261e45ba58f0fbf2bd6c0c832" + ))) + .into(), + block_number: 227, + }, + } + .into(), + RevealedDidKey { + id: hex!("5e14c0826d524d79a17cb5bc5fd61f9b2d364c9af73a5db87408f389e83afcdf").into(), + relationship: DidVerificationKeyRelationship::AssertionMethod.into(), + details: DidPublicKeyDetails { + key: DidVerificationKey::Ed25519(ed25519::Public(hex!( + "6c89991144954da6d916f88e59ce0c52bc2dcea2e7edd065e750234ebbb8d8eb" + ))) + .into(), + block_number: 227, + }, + } + .into(), + RevealedAccountId( + AccountId32::new(hex!("a7beb4c2f6b8b2143dcec8771011006b6380ab3a65530ebc849a6a518e4f5860")).into(), + ) + .into(), + RevealedAccountId( + AccountId32::new(hex!("86ad76d64191ec2a4bfee79fadbb7085fa8ccfb7a590cb91b0f3ebd7ec943df9")).into(), + ) + .into(), + RevealedAccountId( + AccountId32::new(hex!("791dfe90617727b1c2c2d4a570b6e7d042b228c62eba1aeb0f1d43a99d2ee883")).into(), + ) + .into(), + RevealedAccountId( + AccountId32::new(hex!("71db492c2503f35d8b783e6d077875aedf473c502c3f641c5c87dad957e3f98b")).into(), + ) + .into(), + RevealedAccountId( + AccountId32::new(hex!("f7a3e3a7ffb4e10170a73b41039e7298b67ae2fe1d7b8cbfbcb9a19122c51e4b")).into(), + ) + .into(), + RevealedAccountId( + AccountId32::new(hex!("20acfd57871165f2330ca49a4ddafabc52698bc894c899d6368107056ee90c22")).into(), + ) + .into(), + RevealedAccountId( + AccountId32::new(hex!("1207da77a11b67f17653408a8d6cf85d10b3f366c7e7be82f3b30a8eb935c66c")).into(), + ) + .into(), + RevealedAccountId( + AccountId32::new(hex!("98fd1a85f17803a48501005e8fc59bb69ede7407062f83f1a950b917951f9bba")).into(), + ) + .into(), + RevealedAccountId( + AccountId32::new(hex!("cceb4ca89584fa1bbb95318204596d8f883101dfeb6b8ebfa61f3a2d081789fe")).into(), + ) + .into(), + RevealedAccountId( + AccountId32::new(hex!("4afc8c7501fd42bd62db9953e4c54bdf154ff9f5255ebd362b2b795a271b3a7b")).into(), + ) + .into(), + RevealedWeb3Name { + web3_name: b"5699a3c574841b4e353d377".to_vec().try_into().unwrap(), + claimed_at: 227, + } + .into(), + ], + ); + let signature = TimeBoundDidSignature::new(DidSignature::Sr25519(sr25519::Signature(hex!("1ca20d39357dba602862e6b6371887c6b1ec46c86ead3c92178cca814e3ff45f7fd6a58395d422b53b6e1d1ab7be5944dbc2c6e640ecfac67c02a218607cc881"))), 282 as BlockNumberFor); + let proof = ParachainDipDidProof::new(provider_head_state_proof, dip_commitment_proof, dip_proof, signature); + + BlockHash::insert( + 0, + H256(hex!("74f8cd2f3764f676a5e67c45a641ce1025548c6cddcf524a663a9c0aaf7fbee2")), + ); + LatestRelayHeads::insert( + PROOF_RELAY_BLOCK, + RelayParentInfo { + relay_parent_storage_root: H256(hex!( + "29575e65f298648588bc53a45346098e89a99c7330f53d93a899efbb24ddfb69" + )), + }, + ); + + WorstCaseOf { + proof: proof.into(), + call: pallet_postit::Call::post { + text: b"Hello, world!".to_vec().try_into().unwrap(), + } + .into(), + // 4t8M197K3r1xygdVNoRLRBCpWf6G58VcWTKQUiv5kbJiQhvs + subject: DidIdentifier::new(hex!("e68a94309d0adee950b6a63a0a141a3166c15e8ef25c301531f75e25086fe05a")), + // 4rBcMBgT7HzH9NaTpgcBT8AfDUmJjRWiiYGpsqa19CJTSHL3 + submitter: AccountId::new(hex!("908f818bebf2db6d64d86cce811d2133e2d9c9ac447c6c5cc61b23ab04e1fc30")), + } + } +} + +#[cfg(all(test, feature = "runtime-benchmarks"))] +mod worst_case_tests { + use kilt_dip_primitives::VersionedDipParachainStateProof; + use kilt_support::traits::GetWorstCase; + use pallet_dip_consumer::benchmarking::WorstCaseOf; + + use crate::{dip::MAX_PROVIDER_REVEALABLE_KEYS_COUNT, ProviderTemplateProofVerifierWrapper}; + + // Test that the worst case actually refers to the worst case that the provider + // can generate. + #[test] + fn worst_case_max_limits() { + sp_io::TestExternalities::default().execute_with(|| { + let WorstCaseOf { proof, .. } = ::worst_case(()); + let VersionedDipParachainStateProof::V0(proof) = proof; + // We test that the worst case reveals the maximum number of leaves revealable. + // This is required since the worst case is generated elsewhere and used here as + // a fixture. + sp_io::TestExternalities::default().execute_with(|| { + assert_eq!( + proof.dip_proof().revealed().len(), + MAX_PROVIDER_REVEALABLE_KEYS_COUNT as usize + ); + }); + }); + } +} impl pallet_dip_consumer::Config for Runtime { type DipCallOriginFilter = PreliminaryDipOriginFilter; @@ -56,7 +538,7 @@ impl pallet_dip_consumer::Config for Runtime { // that two cross-chain operations targeting the same chain and with the same // nonce cannot be both successfully evaluated. type LocalIdentityInfo = u128; - type ProofVerifier = ProofVerifier; + type ProofVerifier = ProviderTemplateProofVerifierWrapper; type RuntimeCall = RuntimeCall; type RuntimeOrigin = RuntimeOrigin; type WeightInfo = weights::pallet_dip_consumer::WeightInfo; diff --git a/dip-template/runtimes/dip-provider/src/dip.rs b/dip-template/runtimes/dip-provider/src/dip.rs index 4480940671..72f8998de3 100644 --- a/dip-template/runtimes/dip-provider/src/dip.rs +++ b/dip-template/runtimes/dip-provider/src/dip.rs @@ -34,7 +34,7 @@ use crate::{ weights, AccountId, Balances, DidIdentifier, Runtime, RuntimeEvent, RuntimeHoldReason, }; -const MAX_LINKED_ACCOUNTS: u32 = 20; +pub const MAX_REVEALABLE_LINKED_ACCOUNTS: u32 = 10; pub mod runtime_api { use super::*; @@ -243,7 +243,7 @@ impl pallet_dip_provider::Config for Runtime { type IdentityCommitmentGenerator = DidMerkleRootGenerator; // Identity info is defined as the collection of DID keys, linked accounts, and // the optional web3name of a given DID subject. - type IdentityProvider = LinkedDidInfoProvider; + type IdentityProvider = LinkedDidInfoProvider; type ProviderHooks = deposit::DepositCollectorHooks; type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pallet_dip_provider::WeightInfo; diff --git a/dip-template/runtimes/dip-provider/src/lib.rs b/dip-template/runtimes/dip-provider/src/lib.rs index 36d7e0a548..d312f55149 100644 --- a/dip-template/runtimes/dip-provider/src/lib.rs +++ b/dip-template/runtimes/dip-provider/src/lib.rs @@ -376,11 +376,13 @@ impl did::DeriveDidCallAuthorizationVerificationKeyRelationship for RuntimeCall } } +pub const MAX_PUBLIC_KEYS_PER_DID: u32 = 20; +const MAX_TOTAL_KEY_AGREEMENT_KEYS: u32 = MAX_PUBLIC_KEYS_PER_DID - 1; parameter_types! { #[derive(Debug, Clone, Eq, PartialEq)] - pub const MaxTotalKeyAgreementKeys: u32 = 50; + pub const MaxTotalKeyAgreementKeys: u32 = MAX_TOTAL_KEY_AGREEMENT_KEYS; #[derive(Debug, Clone, Eq, PartialEq, TypeInfo, Encode, Decode)] - pub const MaxNewKeyAgreementKeys: u32 = 50; + pub const MaxNewKeyAgreementKeys: u32 = MAX_TOTAL_KEY_AGREEMENT_KEYS; } impl did::Config for Runtime { @@ -397,7 +399,7 @@ impl did::Config for Runtime { type MaxNumberOfServicesPerDid = ConstU32<1>; type MaxNumberOfTypesPerService = ConstU32<1>; type MaxNumberOfUrlsPerService = ConstU32<1>; - type MaxPublicKeysPerDid = ConstU32<53>; + type MaxPublicKeysPerDid = ConstU32; type MaxServiceIdLength = ConstU32<100>; type MaxServiceTypeLength = ConstU32<100>; type MaxServiceUrlLength = ConstU32<100>; diff --git a/pallets/did/src/did_details.rs b/pallets/did/src/did_details.rs index d28291f96d..29a2a24bdc 100644 --- a/pallets/did/src/did_details.rs +++ b/pallets/did/src/did_details.rs @@ -191,13 +191,6 @@ impl From for DidSignature { } } -#[cfg(feature = "runtime-benchmarks")] -impl kilt_support::traits::GetWorstCase for DidSignature { - fn worst_case(_context: Context) -> Self { - Self::Sr25519(sp_core::sr25519::Signature::from_raw([0u8; 64])) - } -} - pub trait DidVerifiableIdentifier { /// Allows a verifiable identifier to verify a signature it produces and /// return the public key diff --git a/pallets/pallet-deposit-storage/src/lib.rs b/pallets/pallet-deposit-storage/src/lib.rs index 0e05c2bcbf..4953223a38 100644 --- a/pallets/pallet-deposit-storage/src/lib.rs +++ b/pallets/pallet-deposit-storage/src/lib.rs @@ -149,8 +149,14 @@ pub mod pallet { /// deposit instance. #[pallet::storage] #[pallet::getter(fn deposits)] - pub(crate) type Deposits = - StorageDoubleMap<_, Twox64Concat, ::Namespace, Twox64Concat, DepositKeyOf, DepositEntryOf>; + pub(crate) type Deposits = StorageDoubleMap< + _, + Blake2_128Concat, + ::Namespace, + Blake2_128Concat, + DepositKeyOf, + DepositEntryOf, + >; #[pallet::pallet] #[pallet::storage_version(STORAGE_VERSION)] diff --git a/pallets/pallet-dip-consumer/src/benchmarking.rs b/pallets/pallet-dip-consumer/src/benchmarking.rs index 0052ebbb0d..3a998bf9ca 100644 --- a/pallets/pallet-dip-consumer/src/benchmarking.rs +++ b/pallets/pallet-dip-consumer/src/benchmarking.rs @@ -16,50 +16,42 @@ // If you feel like getting in touch with us, you can do so at info@botlabs.org -use crate::{traits::IdentityProofVerifier, Call, Config, IdentityEntries, Pallet}; +use crate::{Config, IdentityProofOf, RuntimeCallOf}; use frame_benchmarking::v2::*; -use frame_system::RawOrigin; -use kilt_support::{ - benchmark::IdentityContext, - traits::{GetWorstCase, Instanciate}, -}; + +pub struct WorstCaseOf { + pub submitter: T::AccountId, + pub subject: T::Identifier, + pub proof: IdentityProofOf, + pub call: RuntimeCallOf, +} #[benchmarks( where - T::AccountId: Instanciate, - T::Identifier: Instanciate, - <::ProofVerifier as IdentityProofVerifier>::Proof: GetWorstCase>, - ::RuntimeCall: From>, + T::ProofVerifier: GetWorstCase>, + ::RuntimeCall: From>, )] mod benchmarks { + use frame_system::RawOrigin; + use kilt_support::traits::GetWorstCase; + use sp_std::{boxed::Box, vec}; - use super::*; - - type IdentityContextOf = - IdentityContext<::Identifier, ::AccountId>; + use crate::{benchmarking::WorstCaseOf, Call, Config, IdentityEntries, Pallet}; #[benchmark] fn dispatch_as() { - let submitter = T::AccountId::new(1); - let subject = T::Identifier::new(1); - - let context = IdentityContext:: { - did: subject.clone(), - submitter: submitter.clone(), - }; + let WorstCaseOf { + submitter, + subject, + proof, + call, + } = ::worst_case(()); assert!(IdentityEntries::::get(&subject).is_none()); let origin = RawOrigin::Signed(submitter); - - let call: ::RuntimeCall = frame_system::Call::::remark { remark: vec![] }.into(); - let boxed_call = Box::from(call); - let proof = <<::ProofVerifier as IdentityProofVerifier>::Proof as GetWorstCase< - IdentityContextOf, - >>::worst_case(context); - let origin = ::RuntimeOrigin::from(origin); #[extrinsic_call] diff --git a/pallets/pallet-dip-consumer/src/lib.rs b/pallets/pallet-dip-consumer/src/lib.rs index 5122e0b7ff..ab72c18e7b 100644 --- a/pallets/pallet-dip-consumer/src/lib.rs +++ b/pallets/pallet-dip-consumer/src/lib.rs @@ -44,7 +44,6 @@ pub mod pallet { dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}, pallet_prelude::*, traits::{Contains, EnsureOriginWithArg}, - Twox64Concat, }; use frame_system::pallet_prelude::*; use parity_scale_codec::{FullCodec, MaxEncodedLen}; @@ -111,7 +110,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn identity_proofs)] pub(crate) type IdentityEntries = - StorageMap<_, Twox64Concat, ::Identifier, ::LocalIdentityInfo>; + StorageMap<_, Blake2_128Concat, ::Identifier, ::LocalIdentityInfo>; #[pallet::pallet] #[pallet::storage_version(STORAGE_VERSION)] diff --git a/pallets/pallet-dip-consumer/src/mock.rs b/pallets/pallet-dip-consumer/src/mock.rs index 15fc83446d..c83ebb897d 100644 --- a/pallets/pallet-dip-consumer/src/mock.rs +++ b/pallets/pallet-dip-consumer/src/mock.rs @@ -134,6 +134,23 @@ impl IdentityProofVerifier for BooleanProofVerifier { } } +#[cfg(feature = "runtime-benchmarks")] +impl kilt_support::traits::GetWorstCase for BooleanProofVerifier { + type Output = crate::benchmarking::WorstCaseOf; + + fn worst_case(_context: ()) -> Self::Output { + crate::benchmarking::WorstCaseOf { + call: frame_system::Call::remark { + remark: b"Hello!".to_vec(), + } + .into(), + proof: true, + subject: AccountId32::new([100; 32]), + submitter: AccountId32::new([200; 32]), + } + } +} + impl crate::Config for TestRuntime { type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; diff --git a/pallets/pallet-dip-provider/src/benchmarking.rs b/pallets/pallet-dip-provider/src/benchmarking.rs index a0dcbe4f7f..31aa3e2e84 100644 --- a/pallets/pallet-dip-provider/src/benchmarking.rs +++ b/pallets/pallet-dip-provider/src/benchmarking.rs @@ -28,7 +28,7 @@ use kilt_support::{ T::CommitOriginCheck: GenerateBenchmarkOrigin, T::AccountId: Instanciate, T::Identifier: Instanciate, - <::IdentityProvider as IdentityProvider>::Success: GetWorstCase> + <::IdentityProvider as IdentityProvider>::Success: GetWorstCase, Output = <::IdentityProvider as IdentityProvider>::Success> )] mod benchmarks { diff --git a/pallets/pallet-dip-provider/src/lib.rs b/pallets/pallet-dip-provider/src/lib.rs index 75ad0e4c51..311649319d 100644 --- a/pallets/pallet-dip-provider/src/lib.rs +++ b/pallets/pallet-dip-provider/src/lib.rs @@ -91,7 +91,7 @@ pub mod pallet { #[pallet::getter(fn identity_commitments)] pub type IdentityCommitments = StorageDoubleMap< _, - Twox64Concat, + Blake2_128Concat, ::Identifier, Twox64Concat, IdentityCommitmentVersion, diff --git a/pallets/pallet-migration/src/benchmarking.rs b/pallets/pallet-migration/src/benchmarking.rs index 5f221d48a8..598b7b864c 100644 --- a/pallets/pallet-migration/src/benchmarking.rs +++ b/pallets/pallet-migration/src/benchmarking.rs @@ -71,7 +71,7 @@ benchmarks! { ::AccountId: From, ::EnsureOrigin: GenerateBenchmarkOrigin<::RuntimeOrigin, T::AccountId, ::AttesterId>, BlockNumberFor: From, - ::SubjectId: GetWorstCase + sp_std::fmt::Debug + Into> , + ::SubjectId: GetWorstCase::SubjectId> + sp_std::fmt::Debug + Into> , T: ctype::Config::AttesterId>, ::DelegationNodeId: From, ::DelegationEntityId: From, diff --git a/pallets/pallet-migration/src/mock.rs b/pallets/pallet-migration/src/mock.rs index bbf3ba6b80..4a21c99c60 100644 --- a/pallets/pallet-migration/src/mock.rs +++ b/pallets/pallet-migration/src/mock.rs @@ -377,7 +377,9 @@ pub mod runtime { #[cfg(feature = "runtime-benchmarks")] impl kilt_support::traits::GetWorstCase for TestSubjectId { // Only used for benchmark testing, not really relevant. - fn worst_case(_context: Context) -> Self { + type Output = Self; + + fn worst_case(_context: Context) -> Self::Output { crate::mock::TestSubjectId::default() } } diff --git a/pallets/public-credentials/src/benchmarking.rs b/pallets/public-credentials/src/benchmarking.rs index 4a6113f7c5..3fbbdd63c8 100644 --- a/pallets/public-credentials/src/benchmarking.rs +++ b/pallets/public-credentials/src/benchmarking.rs @@ -59,7 +59,7 @@ benchmarks! { T: Config, T: ctype::Config, ::EnsureOrigin: GenerateBenchmarkOrigin, - ::SubjectId: GetWorstCase + Into> + sp_std::fmt::Debug, + ::SubjectId: GetWorstCase::SubjectId> + Into> + sp_std::fmt::Debug, ::CredentialId: Default, BlockNumberFor: From, ::Currency: Mutate, diff --git a/pallets/public-credentials/src/mock.rs b/pallets/public-credentials/src/mock.rs index 18655b3e22..a444563031 100644 --- a/pallets/public-credentials/src/mock.rs +++ b/pallets/public-credentials/src/mock.rs @@ -249,7 +249,9 @@ pub(crate) mod runtime { #[cfg(feature = "runtime-benchmarks")] impl kilt_support::traits::GetWorstCase for TestSubjectId { // Only used for benchmark testing, not really relevant. - fn worst_case(_context: Context) -> Self { + type Output = Self; + + fn worst_case(_context: Context) -> Self::Output { crate::mock::TestSubjectId::default() } } diff --git a/runtimes/common/src/assets.rs b/runtimes/common/src/assets.rs index 855e09e157..21787709c5 100644 --- a/runtimes/common/src/assets.rs +++ b/runtimes/common/src/assets.rs @@ -105,7 +105,9 @@ mod benchmarks { } impl kilt_support::traits::GetWorstCase for AssetDid { - fn worst_case(_context: Context) -> Self { + type Output = Self; + + fn worst_case(_context: Context) -> Self::Output { // Returns the worst case for an AssetDID, which is represented by the longest // identifier according to the spec. Self::try_from( diff --git a/runtimes/common/src/dip/did/mod.rs b/runtimes/common/src/dip/did/mod.rs index 660fc945d5..a8533aafd3 100644 --- a/runtimes/common/src/dip/did/mod.rs +++ b/runtimes/common/src/dip/did/mod.rs @@ -175,7 +175,9 @@ where ::AccountId: Into + From, ::AccountId: AsRef<[u8; 32]> + From<[u8; 32]>, { - fn worst_case(context: IdentityContext) -> Self { + type Output = Self; + + fn worst_case(context: IdentityContext) -> Self::Output { use did::{ did_details::DidVerificationKey, mock_utils::{generate_base_did_creation_details, get_key_agreement_keys}, diff --git a/runtimes/common/src/dip/merkle/v0/mod.rs b/runtimes/common/src/dip/merkle/v0/mod.rs index fdb66b959b..591c7e43de 100644 --- a/runtimes/common/src/dip/merkle/v0/mod.rs +++ b/runtimes/common/src/dip/merkle/v0/mod.rs @@ -313,10 +313,7 @@ where Ok(CompleteMerkleProof { root, - proof: DidMerkleProofOf::::new( - proof.into_iter().into(), - leaves.into_iter().flatten().collect::>(), - ), + proof: DidMerkleProofOf::::new(proof, leaves.into_iter().flatten().collect::>()), }) } diff --git a/support/src/traits.rs b/support/src/traits.rs index 5b6cf4a226..535fc65f9c 100644 --- a/support/src/traits.rs +++ b/support/src/traits.rs @@ -82,24 +82,28 @@ pub trait GenerateBenchmarkOrigin { /// only when running benchmarks. #[cfg(feature = "runtime-benchmarks")] pub trait GetWorstCase { - fn worst_case(context: Context) -> Self; + type Output; + fn worst_case(context: Context) -> Self::Output; } #[cfg(feature = "runtime-benchmarks")] impl GetWorstCase for u32 { - fn worst_case(_context: T) -> Self { + type Output = Self; + fn worst_case(_context: T) -> Self::Output { u32::MAX } } #[cfg(feature = "runtime-benchmarks")] impl GetWorstCase for () { - fn worst_case(_context: T) -> Self {} + type Output = Self; + fn worst_case(_context: T) -> Self::Output {} } #[cfg(feature = "runtime-benchmarks")] impl GetWorstCase for bool { - fn worst_case(_context: T) -> Self { + type Output = Self; + fn worst_case(_context: T) -> Self::Output { true } }