Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@ FROM paritytech/ci-unified:bullseye-1.70.0 as builder
WORKDIR /build

ARG FEATURES=default
ARG BINARY=kilt-parachain

COPY . .

RUN cargo build --locked --release --features $FEATURES
RUN cargo build --locked --release --features $FEATURES -p $BINARY

# ===== SECOND STAGE ======

FROM docker.io/library/ubuntu:20.04
LABEL description="This is the 2nd stage: a very small image where we copy the kilt-parachain binary."

ARG NODE_TYPE=kilt-parachain
ARG BINARY=kilt-parachain

COPY --from=builder /build/target/release/$NODE_TYPE /usr/local/bin/node-executable
LABEL description="This is the 2nd stage: a very small image where we copy the ${BINARY} binary."

COPY --from=builder /build/target/release/$BINARY /usr/local/bin/node-executable

RUN useradd -m -u 1000 -U -s /bin/sh -d /node node && \
mkdir -p /node/.local/share/node && \
Expand Down
38 changes: 36 additions & 2 deletions crates/kilt-dip-support/src/did.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

// If you feel like getting in touch with us, you can do so at info@botlabs.org

//! Module to deal with cross-chain KILT DIDs.

use did::{
did_details::{DidPublicKey, DidPublicKeyDetails, DidVerificationKey},
DidSignature, DidVerificationKeyRelationship,
Expand All @@ -32,15 +34,24 @@ use crate::{
traits::{Bump, DidSignatureVerifierContext, DipCallOriginFilter},
};

/// Type returned by the Merkle proof verifier component of the DIP consumer
/// after verifying a DIP Merkle proof.
#[derive(Encode, Decode, RuntimeDebug, Clone, Eq, PartialEq, TypeInfo)]
pub(crate) struct RevealedDidKeysAndSignature<RevealedDidKeys, BlockNumber> {
/// The keys revelaed in the Merkle proof.
pub merkle_leaves: RevealedDidKeys,
/// The [`DIDSignature`] + consumer chain block number to which the DID
/// signature is anchored.
pub did_signature: TimeBoundDidSignature<BlockNumber>,
}

/// A DID signature anchored to a specific block heigth.
#[derive(Encode, Decode, RuntimeDebug, Clone, Eq, PartialEq, TypeInfo)]
pub struct TimeBoundDidSignature<BlockNumber> {
/// The signature.
pub signature: DidSignature,
/// The block number, in the context of the local executor, to which the
/// signature is anchored.
pub block_number: BlockNumber,
}

Expand All @@ -62,6 +73,30 @@ impl From<RevealedDidKeysSignatureAndCallVerifierError> for u8 {
}
}

/// Proof verifier that tries to verify a DID signature over a given payload by
/// using one of the DID keys revealed in the Merkle proof. This verifier is to
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// typically be used in conjunction with a verifier that takes a user-provided
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// input Merkle proof, verifies it, and transforms it into a struct that this
/// and other verifiers can easily consume, e.g., a list of DID keys.
/// The generic types indicate the following:
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// * `Call`: The call to be dispatched on the local chain after verifying the
/// DID signature.
/// * `Submitter`: The blockchain account (**not** the identity subject)
/// submitting the cross-chain transaction (and paying for its execution
/// fees).
/// * `DidLocalDetails`: Any information associated to the identity subject that
/// is stored locally, e.g., under the `IdentityEntries` map of the
/// `pallet-dip-consumer` pallet.
/// * `MerkleProofEntries`: The type returned by the Merkle proof verifier that
/// includes the identity parts revealed in the Merkle proof.
/// * `ContextProvider`: Provides additional local context (e.g., current block
/// number) to verify the DID signature.
/// * `RemoteKeyId`: Definition of a DID key ID as specified by the provider.
/// * `RemoteAccountId`: Definition of a linked account ID as specified by the
/// provider.
/// * `RemoteBlockNumber`: Definition of a block number on the provider chain.
/// * `CallVerifier`: A type specifying whether the provided `Call` can be
/// dispatched with the information provided in the DIP proof.
pub(crate) struct RevealedDidKeysSignatureAndCallVerifier<
Call,
Submitter,
Expand Down Expand Up @@ -121,7 +156,6 @@ impl<
CallVerifier:
DipCallOriginFilter<Call, OriginInfo = (DidVerificationKey<RemoteAccountId>, DidVerificationKeyRelationship)>,
{
#[allow(clippy::result_unit_err)]
pub(crate) fn verify_did_signature_for_call(
call: &Call,
submitter: &Submitter,
Expand All @@ -131,7 +165,7 @@ impl<
(DidVerificationKey<RemoteAccountId>, DidVerificationKeyRelationship),
RevealedDidKeysSignatureAndCallVerifierError,
> {
let block_number = ContextProvider::block_number();
let block_number = ContextProvider::current_block_number();
let is_signature_fresh = if let Some(blocks_ago_from_now) =
block_number.checked_sub(&merkle_revealed_did_signature.did_signature.block_number)
{
Expand Down
154 changes: 141 additions & 13 deletions crates/kilt-dip-support/src/export/child.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,17 @@ use crate::{
merkle::{DidMerkleProofVerifierError, RevealedDidMerkleProofLeaf, RevealedDidMerkleProofLeaves},
state_proofs::{parachain::DipIdentityCommitmentProofVerifierError, relay_chain::ParachainHeadProofVerifierError},
traits::{
Bump, DidSignatureVerifierContext, DipCallOriginFilter, HistoricalBlockRegistry, ProviderParachainStateInfo,
Bump, DidSignatureVerifierContext, DipCallOriginFilter, HistoricalBlockRegistry, ProviderParachainStorageInfo,
RelayChainStorageInfo,
},
utils::OutputOf,
FrameSystemDidSignatureContext, ProviderParachainStateInfoViaProviderPallet,
};

/// A KILT-specific DIP identity proof for a parent consumer that supports
/// versioning.
///
/// For more info, refer to the version-specific proofs.
#[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo, Clone)]
#[non_exhaustive]
pub enum VersionedChildParachainDipStateProof<
Expand Down Expand Up @@ -118,8 +122,49 @@ where
}
}

// Implements the same `IdentityProvider` trait, but it is internally configured
// by receiving the runtime definitions of both the provider and the receiver.
/// Proof verifier configured given a specific KILT runtime implementation.
///
/// It is a specialization of the
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// [`GenericVersionedDipChildProviderStateProofVerifier`] type, with
/// configurations derived from the provided KILT runtime.
///
/// The generic types
/// indicate the following:
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// * `KiltRuntime`: A KILT runtime definition.
/// * `KiltParachainId`: The ID of the specific KILT parachain instance.
/// * `RelayChainInfo`: The type providing information about the consumer
/// (relay)chain.
/// * `KiltDipMerkleHasher`: The hashing algorithm used by the KILT parachain
/// for the generation of the DIP identity commitment.
/// * `LocalDidCallVerifier`: 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.
/// * `MAX_REVEALED_KEYS_COUNT`: Max number of DID keys that the verifier will
/// accept being revealed as part of the DIP identity proof.
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// * `MAX_REVEALED_ACCOUNTS_COUNT`: Max number of linked accounts that the
/// verifier will accept being revealed as part of the DIP identity proof.
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// * `MAX_DID_SIGNATURE_DURATION`: Max number of blocks a cross-chain DID
/// signature is considered fresh.
///
/// It specializes the [`GenericVersionedDipChildProviderStateProofVerifier`]
/// type by using the following types for its generics:
/// * `RelayChainInfo`: The provided `RelayChainInfo`.
/// * `ChildProviderParachainId`: The provided `KiltParachainId`.
/// * `ChildProviderStateInfo`: The
/// [`ProviderParachainStateInfoViaProviderPallet`] type configured with the
/// provided `KiltRuntime`.
/// * `ProviderDipMerkleHasher`: The provided `KiltDipMerkleHasher`.
/// * `ProviderDidKeyId`: The [`KeyIdOf`] type configured with the provided
/// `KiltRuntime`.
/// * `ProviderAccountId`: The `KiltRuntime::AccountId` type.
/// * `ProviderWeb3Name`: The `KiltRuntime::Web3Name` type.
/// * `ProviderLinkedAccountId`: The [`LinkableAccountId`] type.
/// * `MAX_REVEALED_KEYS_COUNT`: The provided `MAX_REVEALED_KEYS_COUNT`.
/// * `MAX_REVEALED_ACCOUNTS_COUNT`: The provided `MAX_REVEALED_ACCOUNTS_COUNT`.
/// * `LocalContextProvider`: The [`FrameSystemDidSignatureContext`] type
/// configured with the provided `KiltRuntime` and
/// `MAX_DID_SIGNATURE_DURATION`.
/// * `LocalDidCallVerifier`: The provided `LocalDidCallVerifier`.
pub struct KiltVersionedChildProviderVerifier<
KiltRuntime,
KiltParachainId,
Expand Down Expand Up @@ -258,10 +303,15 @@ impl<
}
}

// More generic version compared to `VersionedChildKiltProviderVerifier`, to be
// used in cases in which it is not possible or not desirable to depend on the
// whole provider runtime definition. Hence, required types must be filled in
// manually.
/// Generic proof verifier for KILT-specific DIP identity proofs of different
/// versions coming from a child provider running one of the available KILT
/// runtimes.
///
/// It expects the DIP proof to be a [`VersionedChildParachainDipStateProof`],
/// and returns [`RevealedDidMerkleProofLeaves`] if the proof is successfully
/// verified.
///
/// For more info, refer to the version-specific proof identifiers.
pub struct GenericVersionedDipChildProviderStateProofVerifier<
RelayChainInfo,
ChildProviderParachainId,
Expand Down Expand Up @@ -346,8 +396,10 @@ impl<

ChildProviderParachainId: Get<RelayChainInfo::ParaId>,

ChildProviderStateInfo:
ProviderParachainStateInfo<Identifier = ConsumerRuntime::Identifier, Commitment = ProviderDipMerkleHasher::Out>,
ChildProviderStateInfo: ProviderParachainStorageInfo<
Identifier = ConsumerRuntime::Identifier,
Commitment = ProviderDipMerkleHasher::Out,
>,
OutputOf<ChildProviderStateInfo::Hasher>: Ord + From<OutputOf<<RelayChainInfo as RelayChainStorageInfo>::Hasher>>,
ChildProviderStateInfo::BlockNumber: Parameter + 'static,
ChildProviderStateInfo::Commitment: Decode,
Expand Down Expand Up @@ -431,7 +483,7 @@ pub mod latest {
pub use super::v0::ChildParachainDipStateProof;
}

mod v0 {
pub mod v0 {
use super::*;

use parity_scale_codec::Codec;
Expand All @@ -457,24 +509,101 @@ mod v0 {
},
traits::{
Bump, DidSignatureVerifierContext, DipCallOriginFilter, HistoricalBlockRegistry,
ProviderParachainStateInfo, RelayChainStorageInfo,
ProviderParachainStorageInfo, RelayChainStorageInfo,
},
utils::OutputOf,
};

/// The expected format of a cross-chain DIP identity proof when the
/// identity information is being bridged from a provider that is a child of
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// the chain where the information is being consumed (i.e., consumer
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// chain).
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
pub struct ChildParachainDipStateProof<
ParentBlockHeight: Copy + Into<U256> + TryFrom<U256>,
ParentBlockHasher: Hash,
DipMerkleProofBlindedValues,
DipMerkleProofRevealedLeaf,
> {
/// The state proof for the given parachain head.
para_state_root: ParachainRootStateProof<ParentBlockHeight>,
/// The relaychain header for the relaychain block specified in the
/// `para_state_root`.
relay_header: Header<ParentBlockHeight, ParentBlockHasher>,
/// The raw state proof for the DIP commitment of the given subject.
dip_identity_commitment: Vec<Vec<u8>>,
/// The cross-chain DID signature.
did: DipMerkleProofAndDidSignature<DipMerkleProofBlindedValues, DipMerkleProofRevealedLeaf, ParentBlockHeight>,
}

/// Generic proof verifier for KILT-specific DIP identity proofs coming from
/// a child provider running one of the available KILT runtimes.
/// The proof verification step is performed on every request, and this
/// specific verifier has no knowledge of caching or storing state about the
/// subject. It only takes the provided
/// `ConsumerRuntime::LocalIdentityInfo` and bumps it up if the proof is
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// successfully verified, to prevent replay attacks. If additional logic is
/// to be stored under the `ConsumerRuntime::LocalIdentityInfo` entry, a
/// different verifier or a wrapper around this verifier must be built.
///
/// It expects the DIP proof to be a
/// [`VersionedChildParachainDipStateProof`], and returns
/// [`RevealedDidMerkleProofLeaves`] if the proof is successfully verified.
/// This information is then made availabe as an origin to the downstream
/// call being dispatched.
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
///
/// The verifier performs the following steps:
/// 1. Verifies the state proof about the state root of the relaychain block
/// at the provided height. The state root is retrieved from the provided
/// relaychain header, which is checked to be the header of a
/// previously-finalized relaychain block.
/// 2. Verifies the state proof about the DIP commitment value on the
/// provider parachain at the block finalized at the given relaychain
/// block, using the relay state root validated in the previous step.
/// 3. Verifies the DIP Merkle proof revealing parts of the subject's DID
/// Document against the retrieved DIP commitment validated in the
/// previous step.
/// 4. Verifies the cross-chain DID signature over the payload composed by
/// the SCALE-encoded tuple of `(C, D, S, B, G, E)`, with:
/// * `C`: The `RuntimeCall` to dispatch after performing DIP
/// verification.
/// * `D`: The local details associated to the DID subject as stored in
/// the [`pallet_dip_consumer`] `IdentityEntries` storage map.
/// * `S`: The tx submitter's address.
/// * `B`: The block number of the consumer chain provided in the
/// cross-chain DID signature.
/// * `G`: The genesis hash of the consumer chain.
/// * `E`: Any additional information provided by the
/// `LocalContextProvider` implementation.
/// The generic types
/// indicate the following:
/// * `RelayChainInfo`: The type providing information about the consumer
/// (relay)chain.
/// * `ChildProviderParachainId`: The parachain ID of the provider KILT
/// child parachain.
/// * `ChildProviderStateInfo`: The type providing storage and state
/// information about the provider KILT child parachain.
/// * `ProviderDipMerkleHasher`: The hashing algorithm used by the KILT
/// parachain for the generation of the DIP identity commitment.
/// * `ProviderDidKeyId`: The runtime type of a DID key ID as defined by the
/// KILT child parachain.
/// * `ProviderAccountId`: The runtime type of an account ID as defined by
/// the KILT child parachain.
/// * `ProviderWeb3Name`: The runtime type of a web3name as defined by the
/// KILT child parachain.
/// * `ProviderLinkedAccountId`: The runtime type of a linked account ID as
/// defined by the KILT child parachain.
/// * `MAX_REVEALED_KEYS_COUNT`: Max number of DID keys that the verifier
/// will accept being revealed as part of the DIP identity proof.
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// * `MAX_REVEALED_ACCOUNTS_COUNT`: Max number of linked accounts that the
/// verifier will accept being revealed as part of the DIP identity proof.
Comment thread
ntn-x2 marked this conversation as resolved.
Outdated
/// * `LocalContextProvider`: The type providing context of the consumer
/// chain (e.g., current block number) for the sake of cross-chain DID
/// signature verification.
/// * `LocalDidCallVerifier`: 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.
pub struct DipChildProviderStateProofVerifier<
RelayChainInfo,
ChildProviderParachainId,
Expand Down Expand Up @@ -559,7 +688,7 @@ mod v0 {

ChildProviderParachainId: Get<RelayChainInfo::ParaId>,

ChildProviderStateInfo: ProviderParachainStateInfo<
ChildProviderStateInfo: ProviderParachainStorageInfo<
Identifier = ConsumerRuntime::Identifier,
Commitment = ProviderDipMerkleHasher::Out,
>,
Expand Down Expand Up @@ -629,7 +758,6 @@ mod v0 {
// 1.2 If so, extract the state root from the header
let state_root_at_height = proof.relay_header.state_root;

// FIXME: Compilation error
// 2. Verify relay chain proof
let provider_parachain_header =
ParachainHeadProofVerifier::<RelayChainInfo>::verify_proof_for_parachain_with_root(
Expand Down
5 changes: 5 additions & 0 deletions crates/kilt-dip-support/src/export/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,18 @@ pub mod v0 {

#[derive(Encode, Decode, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, TypeInfo, Clone)]
pub struct ParachainRootStateProof<RelayBlockHeight> {
/// The relaychain block height for which the proof has been generated.
pub(crate) relay_block_height: RelayBlockHeight,
/// The raw state proof.
pub(crate) proof: Vec<Vec<u8>>,
}

#[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo, Clone)]
pub struct DipMerkleProofAndDidSignature<BlindedValues, Leaf, BlockNumber> {
/// The DIP Merkle proof revealing some leaves about the DID subject's
/// identity.
pub(crate) leaves: DidMerkleProof<BlindedValues, Leaf>,
/// The cross-chain DID signature.
pub(crate) signature: TimeBoundDidSignature<BlockNumber>,
}
}
2 changes: 2 additions & 0 deletions crates/kilt-dip-support/src/export/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

// If you feel like getting in touch with us, you can do so at info@botlabs.org

/// Verification logic to integrate a child chain as a DIP provider.
pub mod child;
/// Verification logic to integrate a sibling chain as a DIP provider.
pub mod sibling;

mod common;
Expand Down
Loading