From 6c8054c9d1b05a6e7cc70d750d0cf6f40e74a59c Mon Sep 17 00:00:00 2001 From: "will.li" <120463031+higherordertech@users.noreply.github.com> Date: Fri, 13 Sep 2024 21:08:43 +1000 Subject: [PATCH] P 1006 all identities vc (#3059) * feat: P-1006 add new VC LinkedIdentities * revert commitId of core-primitives in lock file for bitacross-worker --------- Co-authored-by: higherordertech --- tee-worker/Cargo.lock | 12 +- .../litentry/request_vc_subcommands.rs | 2 + .../interfaces/vc/definitions.ts | 1 + tee-worker/enclave-runtime/Cargo.lock | 12 +- .../core/assertion-build-v2/src/lib.rs | 1 + .../src/linked_identities/mod.rs | 110 ++++++++++++++++++ .../litentry/core/credentials-v2/src/lib.rs | 1 + .../src/linked_identities/mod.rs | 48 ++++++++ .../core/credentials/src/credential_schema.rs | 2 + .../receiver/src/handler/assertion.rs | 2 + tee-worker/service/src/prometheus_metrics.rs | 1 + .../common/utils/vc-helper.ts | 8 ++ 12 files changed, 188 insertions(+), 12 deletions(-) create mode 100644 tee-worker/litentry/core/assertion-build-v2/src/linked_identities/mod.rs create mode 100644 tee-worker/litentry/core/credentials-v2/src/linked_identities/mod.rs diff --git a/tee-worker/Cargo.lock b/tee-worker/Cargo.lock index 0a9fd4f4ea..03a9dff942 100644 --- a/tee-worker/Cargo.lock +++ b/tee-worker/Cargo.lock @@ -875,7 +875,7 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "core-primitives" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" dependencies = [ "base58", "frame-support", @@ -4988,7 +4988,7 @@ dependencies = [ [[package]] name = "litentry-hex-utils" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" dependencies = [ "hex", ] @@ -5000,7 +5000,7 @@ version = "0.1.0" [[package]] name = "litentry-macros" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" [[package]] name = "litentry-primitives" @@ -5030,7 +5030,7 @@ dependencies = [ [[package]] name = "litentry-proc-macros" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" dependencies = [ "cargo_toml", "proc-macro2", @@ -6016,7 +6016,7 @@ dependencies = [ [[package]] name = "pallet-parachain-staking" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" dependencies = [ "core-primitives", "frame-support", @@ -6083,7 +6083,7 @@ dependencies = [ [[package]] name = "pallet-teebag" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" dependencies = [ "base64 0.13.1", "chrono 0.4.38", diff --git a/tee-worker/cli/src/trusted_base_cli/commands/litentry/request_vc_subcommands.rs b/tee-worker/cli/src/trusted_base_cli/commands/litentry/request_vc_subcommands.rs index 832b8636f8..be58a6653e 100644 --- a/tee-worker/cli/src/trusted_base_cli/commands/litentry/request_vc_subcommands.rs +++ b/tee-worker/cli/src/trusted_base_cli/commands/litentry/request_vc_subcommands.rs @@ -53,6 +53,7 @@ pub enum Command { #[clap(subcommand)] NftHolder(NftHolderCommand), Dynamic(DynamicArg), + LinkedIdentities, } #[derive(Args, Debug)] @@ -492,6 +493,7 @@ impl Command { return_log: arg.return_log.unwrap_or_default(), })) }, + Command::LinkedIdentities => Ok(LinkedIdentities), } } } diff --git a/tee-worker/client-api/parachain-api/prepare-build/interfaces/vc/definitions.ts b/tee-worker/client-api/parachain-api/prepare-build/interfaces/vc/definitions.ts index 210d4038ea..bc8c4ad89d 100644 --- a/tee-worker/client-api/parachain-api/prepare-build/interfaces/vc/definitions.ts +++ b/tee-worker/client-api/parachain-api/prepare-build/interfaces/vc/definitions.ts @@ -35,6 +35,7 @@ export default { PlatformUser: "PlatformUserType", NftHolder: "Web3NftType", Dynamic: "DynamicParams", + LinkedIdentities: "Null", }, }, AssertionSupportedNetwork: { diff --git a/tee-worker/enclave-runtime/Cargo.lock b/tee-worker/enclave-runtime/Cargo.lock index 3cb495b83b..7146d0862a 100644 --- a/tee-worker/enclave-runtime/Cargo.lock +++ b/tee-worker/enclave-runtime/Cargo.lock @@ -600,7 +600,7 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "core-primitives" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" dependencies = [ "base58", "frame-support", @@ -3358,7 +3358,7 @@ dependencies = [ [[package]] name = "litentry-hex-utils" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" dependencies = [ "hex", ] @@ -3370,7 +3370,7 @@ version = "0.1.0" [[package]] name = "litentry-macros" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" [[package]] name = "litentry-primitives" @@ -3408,7 +3408,7 @@ dependencies = [ [[package]] name = "litentry-proc-macros" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" dependencies = [ "cargo_toml", "proc-macro2", @@ -3801,7 +3801,7 @@ dependencies = [ [[package]] name = "pallet-parachain-staking" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" dependencies = [ "core-primitives", "frame-support", @@ -3868,7 +3868,7 @@ dependencies = [ [[package]] name = "pallet-teebag" version = "0.1.0" -source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#ea133d42f915d6e3cbbc51304f534d0b9f42e5d3" +source = "git+https://github.com/litentry/litentry-parachain?branch=release-v0.9.19#d2249ff0f8a4b20e590c5cd2c0f68baa79e13aa4" dependencies = [ "base64 0.13.1", "chrono 0.4.31", diff --git a/tee-worker/litentry/core/assertion-build-v2/src/lib.rs b/tee-worker/litentry/core/assertion-build-v2/src/lib.rs index ef5b56095d..1124633f46 100644 --- a/tee-worker/litentry/core/assertion-build-v2/src/lib.rs +++ b/tee-worker/litentry/core/assertion-build-v2/src/lib.rs @@ -41,6 +41,7 @@ use lc_assertion_build::{transpose_identity, Result}; use lc_service::DataProviderConfig; use log::*; +pub mod linked_identities; pub mod nft_holder; pub mod platform_user; pub mod token_holding_amount; diff --git a/tee-worker/litentry/core/assertion-build-v2/src/linked_identities/mod.rs b/tee-worker/litentry/core/assertion-build-v2/src/linked_identities/mod.rs new file mode 100644 index 0000000000..0e925a4a3a --- /dev/null +++ b/tee-worker/litentry/core/assertion-build-v2/src/linked_identities/mod.rs @@ -0,0 +1,110 @@ +// Copyright 2020-2024 Trust Computing GmbH. +// This file is part of Litentry. +// +// Litentry 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. +// +// Litentry 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 Litentry. If not, see . + +#[cfg(all(feature = "std", feature = "sgx"))] +compile_error!("feature \"std\" and feature \"sgx\" cannot be enabled at the same time"); + +#[cfg(all(not(feature = "std"), feature = "sgx"))] +extern crate sgx_tstd as std; + +use lc_credentials_v2::{ + linked_identities::LinkedIdentitiesAssertionUpdate, Credential, IssuerRuntimeVersion, +}; +use lc_stf_task_sender::AssertionBuildRequest; + +use crate::*; + +pub fn build(req: &AssertionBuildRequest) -> Result { + let identities = req + .identities + .iter() + .filter_map(|identity| identity.0.to_did().ok()) + .collect::>(); + + let runtime_version = IssuerRuntimeVersion { + parachain: req.parachain_runtime_version, + sidechain: req.sidechain_runtime_version, + }; + + match Credential::new(&req.who, &req.shard, &runtime_version) { + Ok(mut credential_unsigned) => { + credential_unsigned.update_linked_identities_assertion(identities); + Ok(credential_unsigned) + }, + Err(e) => { + error!("Generate unsigned credential failed {:?}", e); + Err(Error::RequestVCFailed(Assertion::LinkedIdentities, e.into_error_detail())) + }, + } +} + +#[cfg(test)] +mod tests { + use super::*; + use itp_stf_primitives::types::ShardIdentifier; + use itp_types::AccountId; + use lc_credentials_v2::assertion_logic::{AssertionLogic, Op}; + use litentry_primitives::{Identity, IdentityNetworkTuple, IdentityString}; + + #[test] + fn build_linked_identities_works() { + let mut identities: Vec = vec![ + (Identity::Substrate([0; 32].into()), vec![]), + (Identity::Evm([0; 20].into()), vec![]), + (Identity::Bitcoin([0; 33].into()), vec![]), + (Identity::Solana([0; 32].into()), vec![]), + (Identity::Discord(IdentityString::new("discord_handle".as_bytes().to_vec())), vec![]), + (Identity::Twitter(IdentityString::new("twitter_handle".as_bytes().to_vec())), vec![]), + (Identity::Github(IdentityString::new("github_handle".as_bytes().to_vec())), vec![]), + ]; + + let req = AssertionBuildRequest { + shard: ShardIdentifier::default(), + signer: AccountId::from([0; 32]), + who: AccountId::from([0; 32]).into(), + assertion: Assertion::LinkedIdentities, + identities, + top_hash: Default::default(), + parachain_block_number: 0u32, + sidechain_block_number: 0u32, + parachain_runtime_version: 0u32, + sidechain_runtime_version: 0u32, + maybe_key: None, + should_create_id_graph: false, + req_ext_hash: Default::default(), + }; + + match build(&req) { + Ok(credential) => { + log::info!("build linked_identities done"); + assert_eq!( + *(credential.credential_subject.assertions.first().unwrap()), + AssertionLogic::And { + items: vec![Box::new(AssertionLogic::Item { + src: "$identities".into(), + op: Op::Equal, + dst: "[\"did:litentry:substrate:0x0000000000000000000000000000000000000000000000000000000000000000\",\"did:litentry:evm:0x0000000000000000000000000000000000000000\",\"did:litentry:bitcoin:0x000000000000000000000000000000000000000000000000000000000000000000\",\"did:litentry:solana:11111111111111111111111111111111\",\"did:litentry:discord:discord_handle\",\"did:litentry:twitter:twitter_handle\",\"did:litentry:github:github_handle\"]".into() + })] + } + ); + assert_eq!(*(credential.credential_subject.values.first().unwrap()), true); + }, + Err(e) => { + panic!("build linked_identities failed with error {:?}", e); + }, + } + } +} diff --git a/tee-worker/litentry/core/credentials-v2/src/lib.rs b/tee-worker/litentry/core/credentials-v2/src/lib.rs index a831cd4302..876782a400 100644 --- a/tee-worker/litentry/core/credentials-v2/src/lib.rs +++ b/tee-worker/litentry/core/credentials-v2/src/lib.rs @@ -30,6 +30,7 @@ compile_error!("feature \"std\" and feature \"sgx\" cannot be enabled at the sam // TODO migration to v2 in the future pub use lc_credentials::{assertion_logic, Credential, IssuerRuntimeVersion}; +pub mod linked_identities; pub mod nft_holder; pub mod platform_user; pub mod token_holding_amount; diff --git a/tee-worker/litentry/core/credentials-v2/src/linked_identities/mod.rs b/tee-worker/litentry/core/credentials-v2/src/linked_identities/mod.rs new file mode 100644 index 0000000000..812687b1c6 --- /dev/null +++ b/tee-worker/litentry/core/credentials-v2/src/linked_identities/mod.rs @@ -0,0 +1,48 @@ +// Copyright 2020-2024 Trust Computing GmbH. +// This file is part of Litentry. +// +// Litentry 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. +// +// Litentry 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 Litentry. If not, see . + +#[cfg(all(feature = "std", feature = "sgx"))] +compile_error!("feature \"std\" and feature \"sgx\" cannot be enabled at the same time"); + +#[cfg(all(not(feature = "std"), feature = "sgx"))] +extern crate sgx_tstd as std; + +use lc_credentials::{ + assertion_logic::{AssertionLogic, Op}, + Credential, +}; +use std::{string::String, vec::Vec}; + +const TYPE: &str = "Linked web2/web3 identities"; +const DESCRIPTION: &str = "All web2 and web3 identities you linked"; + +pub trait LinkedIdentitiesAssertionUpdate { + fn update_linked_identities_assertion(&mut self, identities: Vec); +} + +impl LinkedIdentitiesAssertionUpdate for Credential { + fn update_linked_identities_assertion(&mut self, identities: Vec) { + self.add_subject_info(DESCRIPTION, TYPE); + + let mut assertion = AssertionLogic::new_and(); + let dst = format!("[\"{}\"]", identities.join("\",\"")); + assertion = + assertion.add_item(AssertionLogic::new_item("$identities", Op::Equal, dst.as_str())); + + self.credential_subject.assertions.push(assertion); + self.credential_subject.values.push(true); + } +} diff --git a/tee-worker/litentry/core/credentials/src/credential_schema.rs b/tee-worker/litentry/core/credentials/src/credential_schema.rs index 282861d912..e0604271fb 100644 --- a/tee-worker/litentry/core/credentials/src/credential_schema.rs +++ b/tee-worker/litentry/core/credentials/src/credential_schema.rs @@ -115,5 +115,7 @@ pub fn get_schema_url(assertion: &Assertion) -> Option { Some(format!("{BASE_URL}/25-token-holding-amount/1-1-4.json")), Assertion::Dynamic(..) => None, + + Assertion::LinkedIdentities => Some(format!("{BASE_URL}/27-linked-identities/1-0-0.json")), } } diff --git a/tee-worker/litentry/core/stf-task/receiver/src/handler/assertion.rs b/tee-worker/litentry/core/stf-task/receiver/src/handler/assertion.rs index 9d1d1b31a9..d8db0a464d 100644 --- a/tee-worker/litentry/core/stf-task/receiver/src/handler/assertion.rs +++ b/tee-worker/litentry/core/stf-task/receiver/src/handler/assertion.rs @@ -207,6 +207,8 @@ where vc_logs = Some(result.1); Ok(result.0) }, + + Assertion::LinkedIdentities => lc_assertion_build_v2::linked_identities::build(req), }?; // post-process the credential diff --git a/tee-worker/service/src/prometheus_metrics.rs b/tee-worker/service/src/prometheus_metrics.rs index 69235686ec..45fc234a14 100644 --- a/tee-worker/service/src/prometheus_metrics.rs +++ b/tee-worker/service/src/prometheus_metrics.rs @@ -329,6 +329,7 @@ fn assertion_to_string(assertion: Assertion) -> String { Assertion::Dynamic(param) => { format!("DynamicAssertion({:?})", param.smart_contract_id) }, + Assertion::LinkedIdentities => "LinkedIdentities".into(), }; assertion } diff --git a/tee-worker/ts-tests/integration-tests/common/utils/vc-helper.ts b/tee-worker/ts-tests/integration-tests/common/utils/vc-helper.ts index 0ef87b7065..a58f906594 100644 --- a/tee-worker/ts-tests/integration-tests/common/utils/vc-helper.ts +++ b/tee-worker/ts-tests/integration-tests/common/utils/vc-helper.ts @@ -345,4 +345,12 @@ export const mockAssertions = [ WeirdoGhostGangHolder: [], }, }, + + // LinkedIdentities + { + description: 'All web2 and web3 identities you linked', + assertion: { + LinkedIdentities: [], + }, + }, ];