Skip to content

Commit

Permalink
Template runtimes comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ntn-x2 committed Nov 22, 2023
1 parent 1ff6044 commit 17b3ec4
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 1 deletion.
2 changes: 1 addition & 1 deletion crates/kilt-dip-support/src/state_proofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ pub(super) mod relay_chain {
RelayChainState::BlockNumber: Copy + Into<U256> + TryFrom<U256> + HasCompact,
RelayChainState::Key: AsRef<[u8]>,
{
/// Given a relaychain state root provided by the [`RelayChainState`]
/// Given a relaychain state root provided by the `RelayChainState`
/// generic type, verify a state proof for the parachain with the
/// provided ID.
#[allow(clippy::result_unit_err)]
Expand Down
24 changes: 24 additions & 0 deletions dip-template/runtimes/dip-consumer/src/dip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ use sp_runtime::traits::BlakeTwo256;
use crate::{AccountId, DidIdentifier, Runtime, RuntimeCall, RuntimeOrigin};

pub type MerkleProofVerifierOutput = <ProofVerifier as IdentityProofVerifier<Runtime>>::VerificationResult;
/// The verifier logic assumes the provider is a sibling KILT parachain, and
/// that a KILT subject can provide DIP proof that reveal at most 10 DID keys
/// and 10 linked accounts. Calls that do not pass the [`DipCallFilter`] will be
/// discarded early on in the verification process.
pub type ProofVerifier = KiltVersionedSiblingProviderVerifier<
ProviderRuntime,
ConstU32<2_000>,
Expand All @@ -43,14 +47,22 @@ pub type ProofVerifier = KiltVersionedSiblingProviderVerifier<

impl pallet_dip_consumer::Config for Runtime {
type DipCallOriginFilter = PreliminaryDipOriginFilter;
// Any signed origin can submit a cross-chain DIP tx, since subject
// authentication (and optional binding to the tx submitter) is performed in the
// DIP proof verification step.
type DispatchOriginCheck = EnsureSigned<AccountId>;
type Identifier = DidIdentifier;
// Local identity info contains a simple `u128` representing a nonce. This means
// that two cross-chain operations targeting the same chain and having the same
// nonce cannot be both successfully evaluated.
type LocalIdentityInfo = u128;
type ProofVerifier = ProofVerifier;
type RuntimeCall = RuntimeCall;
type RuntimeOrigin = RuntimeOrigin;
}

/// A preliminary DID call filter that only allows dispatching of extrinsics
/// from the [`pallet_postit::Pallet`] pallet.
pub struct PreliminaryDipOriginFilter;

impl Contains<RuntimeCall> for PreliminaryDipOriginFilter {
Expand All @@ -65,6 +77,9 @@ impl Contains<RuntimeCall> for PreliminaryDipOriginFilter {
}
}

/// Calls to the [`pallet_postit::Pallet`] pallet or batches containing only
/// calls to the [`pallet_postit::Pallet`] pallet will go through if authorized
/// by a DID's authentication key. Everything else will fail.
fn derive_verification_key_relationship(call: &RuntimeCall) -> Option<DidVerificationKeyRelationship> {
match call {
RuntimeCall::PostIt { .. } => Some(DidVerificationKeyRelationship::Authentication),
Expand Down Expand Up @@ -97,11 +112,18 @@ fn single_key_relationship<'a>(
})
}

/// Errors generated by calls that do not pass the filter.
pub enum DipCallFilterError {
/// The call cannot be dispatched with the provided origin.
BadOrigin,
/// The call could be dispatched with the provided origin, but it has been
/// authorized with the wrong DID key.
WrongVerificationRelationship,
}

/// A call filter that requires calls to the [`pallet_postit::Pallet`] pallet to
/// be authorized with a DID signature generated with a key of a given
/// verification relationship.
pub struct DipCallFilter;

impl DipCallOriginFilter<RuntimeCall> for DipCallFilter {
Expand All @@ -122,5 +144,7 @@ impl DipCallOriginFilter<RuntimeCall> for DipCallFilter {
}

impl pallet_relay_store::Config for Runtime {
// The pallet stores the last 100 relaychain state roots, making state proofs
// valid for at most 100 * 6 = 600 seconds.
type MaxRelayBlocksStored = ConstU32<100>;
}
11 changes: 11 additions & 0 deletions dip-template/runtimes/dip-consumer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@

// If you feel like getting in touch with us, you can do so at [email protected]

//! Runtime template of a Decentralized Identity Provider (DIP) consumer, which
//! does not itself include any identity-related pallets, but only the
//! [`pallet_dip_consumer::Pallet`] pallet (configured to work with the
//! [`dip_provider_runtime_template::Runtime`] template runtime), the
//! [`pallet_relay_store::Pallet`] pallet to keep track of finalized relaychain
//! state roots, and the example [`pallet_postit::Pallet`], which allows any
//! entity that can be identified with a username (e.g., a web3name carried over
//! from the provider chain) to post a message on chain, reply to another
//! on-chain message (including another reply), or like a message and/or any of
//! its replies.

#![cfg_attr(not(feature = "std"), no_std)]
#![recursion_limit = "256"]

Expand Down
7 changes: 7 additions & 0 deletions dip-template/runtimes/dip-consumer/src/origin_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_core::RuntimeDebug;

/// An origin adapter which is used to make sure that a given [`DipOrigin`]
/// contains, among other things, a web3name. If a pallet extrinsic that
/// requires this origin is called with a DIP proof that does not revealed the
/// web3name linked to the subject, the extrinsic will fail with a `BadOrigin`
/// error.
pub struct EnsureDipOriginAdapter;

impl EnsureOrigin<RuntimeOrigin> for EnsureDipOriginAdapter {
Expand All @@ -40,6 +45,8 @@ impl EnsureOrigin<RuntimeOrigin> for EnsureDipOriginAdapter {
}
}

/// A wrapper around a [`DipOrigin`] that makes sure the origin has a web3name,
/// or else the origin is invalid.
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub struct DipOriginAdapter(DipOrigin<DidIdentifier, AccountId, MerkleProofVerifierOutput>);

Expand Down
28 changes: 28 additions & 0 deletions dip-template/runtimes/dip-provider/src/dip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,21 @@ use crate::{
pub mod runtime_api {
use super::*;

/// Parameters for a DIP proof request.
#[derive(Encode, Decode, TypeInfo)]
pub struct DipProofRequest {
/// The subject identifier for which to generate the DIP proof.
pub(crate) identifier: DidIdentifier,
/// The DIP version.
pub(crate) version: IdentityCommitmentVersion,
/// The DID key IDs of the subject's DID Document to reveal in the DIP
/// proof.
pub(crate) keys: Vec<KeyIdOf<Runtime>>,
/// The list of accounts linked to the subject's DID to reveal in the
/// DIP proof.
pub(crate) accounts: Vec<LinkableAccountId>,
/// A flag indicating whether the web3name claimed by the DID subject
/// should revealed in the DIP proof.
pub(crate) should_include_web3_name: bool,
}

Expand Down Expand Up @@ -70,6 +79,8 @@ pub mod deposit {
DipProvider,
}

/// The namespace to use in the [`pallet_deposit_storage::Pallet`] to store
/// all deposits related to DIP commitments.
pub struct DipProviderDepositNamespace;

impl Get<DepositNamespaces> for DipProviderDepositNamespace {
Expand All @@ -78,8 +89,11 @@ pub mod deposit {
}
}

/// The amount of tokens locked for each identity commitment.
pub const DEPOSIT_AMOUNT: Balance = 2 * UNIT;

/// The additional logic to execute whenever a deposit is removed by its
/// owner directly via the [`pallet_deposit_storage::Pallet`] pallet.
pub type DepositCollectorHooks =
FixedDepositCollectorViaDepositsPallet<DipProviderDepositNamespace, ConstU128<DEPOSIT_AMOUNT>>;

Expand All @@ -97,6 +111,11 @@ pub mod deposit {
}
}

/// The logic to execute whenever an identity commitment is generated and
/// stored in the [`pallet_dip_provider::Pallet`] pallet.
///
/// Upon storing and removing identity commitments, this hook will reserve
/// or release deposits from the [`pallet_deposit_storage::Pallet`] pallet.
pub struct DepositHooks;

impl DepositStorageHooks<Runtime> for DepositHooks {
Expand Down Expand Up @@ -126,7 +145,10 @@ pub mod deposit {
}

impl pallet_deposit_storage::Config for Runtime {
// Any signed origin can submit the tx, which will go through only if the
// deposit payer matches the signed origin.
type CheckOrigin = EnsureSigned<AccountId>;
// The balances pallet is used to reserve/unreserve tokens.
type Currency = Balances;
type DepositHooks = DepositHooks;
type MaxKeyLength = ConstU32<256>;
Expand All @@ -136,10 +158,16 @@ impl pallet_deposit_storage::Config for Runtime {
}

impl pallet_dip_provider::Config for Runtime {
// Only DID origins can submit the commitment identity tx, which will go through
// only if the DID in the origin matches the identifier specified in the tx.
type CommitOriginCheck = EnsureDidOrigin<DidIdentifier, AccountId>;
type CommitOrigin = DidRawOrigin<DidIdentifier, AccountId>;
type Identifier = DidIdentifier;
// The identity commitment is defined as the Merkle root of the linked identity
// info, as specified by the [`LinkedDidInfoProvider`].
type IdentityCommitmentGenerator = DidMerkleRootGenerator<Runtime>;
// 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 ProviderHooks = deposit::DepositCollectorHooks;
type RuntimeEvent = RuntimeEvent;
Expand Down
6 changes: 6 additions & 0 deletions dip-template/runtimes/dip-provider/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@

// If you feel like getting in touch with us, you can do so at [email protected]

//! Runtime template of a Decentralized Identity Provider (DIP) provider, which
//! includes, beyond system pallets, [`did::Pallet`],
//! [`pallet_web3_names::Pallet`], and [`pallet_did_lookup::Pallet`] pallets, as
//! well as the [`pallet_dip_provider::Pallet`] pallet and the
//! [`pallet_deposit_storage::Pallet`] pallet.

#![cfg_attr(not(feature = "std"), no_std)]
#![recursion_limit = "256"]

Expand Down
2 changes: 2 additions & 0 deletions runtime-api/dip-provider/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
use parity_scale_codec::Codec;

sp_api::decl_runtime_apis! {
/// Runtime API to generate a DIP proof with the provided parameters.
pub trait DipProvider<ProofRequest, Success, Error> where
ProofRequest: Codec,
Success: Codec,
Error: Codec,
{
/// Generate a DIP proof with the parameters specified in the request.
fn generate_proof(request: ProofRequest) -> Result<Success, Error>;
}
}

0 comments on commit 17b3ec4

Please sign in to comment.