diff --git a/Cargo.lock b/Cargo.lock
index 5c153d92cc..85ca535051 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",
@@ -2899,6 +2902,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"
@@ -4601,9 +4624,10 @@ dependencies = [
name = "kilt-dip-primitives"
version = "1.13.0-dev"
dependencies = [
- "cfg-if",
+ "cumulus-pallet-parachain-system",
"cumulus-primitives-core",
"did",
+ "enum-iterator",
"frame-support",
"frame-system",
"hash-db",
@@ -4616,6 +4640,8 @@ dependencies = [
"pallet-relay-store",
"pallet-web3-names",
"parity-scale-codec",
+ "peregrine-runtime",
+ "rococo-runtime",
"scale-info",
"sp-core",
"sp-io",
@@ -4623,6 +4649,7 @@ dependencies = [
"sp-state-machine",
"sp-std",
"sp-trie",
+ "spiritnet-runtime",
]
[[package]]
@@ -6581,6 +6608,8 @@ dependencies = [
"frame-support",
"frame-system",
"kilt-support",
+ "pallet-balances",
+ "pallet-did-lookup",
"parity-scale-codec",
"scale-info",
"sp-io",
@@ -7091,6 +7120,7 @@ dependencies = [
"sp-keystore",
"sp-runtime",
"sp-std",
+ "sp-trie",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index 48a43bcd5e..7e17e3cd67 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..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
@@ -43,7 +42,12 @@ 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"] }
[features]
@@ -73,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/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/v0.rs b/crates/kilt-dip-primitives/src/merkle/v0.rs
deleted file mode 100644
index a5719e4c84..0000000000
--- a/crates/kilt-dip-primitives/src/merkle/v0.rs
+++ /dev/null
@@ -1,1341 +0,0 @@
-// 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
-
-//! 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, MerkleProofError},
- traits::{BenchmarkDefault, GetWithArg},
- utils::{
- calculate_dip_identity_commitment_storage_key_for_runtime, calculate_parachain_head_storage_key,
- BoundedBlindedValue, OutputOf,
- },
-};
-
-/// 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(),
- }
- }
-}
-
-#[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:
-/// * `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