Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up STF request_vc call #3050

Merged
merged 9 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,6 @@ jobs:
- test_name: lit-di-evm-identity-test
- test_name: lit-di-bitcoin-identity-test
- test_name: lit-di-solana-identity-test
- test_name: lit-di-vc-test
- test_name: lit-dr-vc-test
- test_name: lit-parentchain-nonce
- test_name: lit-test-failed-parentchain-extrinsic
Expand Down Expand Up @@ -831,7 +830,6 @@ jobs:
- test_name: lit-di-evm-identity-multiworker-test
- test_name: lit-di-solana-identity-multiworker-test
- test_name: lit-di-substrate-identity-multiworker-test
- test_name: lit-di-vc-multiworker-test
- test_name: lit-dr-vc-multiworker-test
- test_name: lit-resume-worker
name: ${{ matrix.test_name }}
Expand Down
124 changes: 11 additions & 113 deletions tee-worker/app-libs/stf/src/trusted_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,12 @@ use sp_core::{H160, U256};

#[cfg(feature = "evm")]
use crate::evm_helpers::{create_code_hash, evm_create2_address, evm_create_address};
#[cfg(feature = "development")]
use crate::helpers::ensure_enclave_signer_or_alice;
use crate::{
format,
helpers::{enclave_signer_account, ensure_enclave_signer_account, ensure_self},
trusted_call_result::{
ActivateIdentityResult, DeactivateIdentityResult, RequestVCResult,
SetIdentityNetworksResult, TrustedCallResult,
ActivateIdentityResult, DeactivateIdentityResult, SetIdentityNetworksResult,
TrustedCallResult,
},
Arc, Getter, String, ToString, Vec,
};
Expand All @@ -39,9 +37,7 @@ pub use ita_sgx_runtime::{
Balance, IDGraph, Index, ParentchainInstanceLitentry, ParentchainInstanceTargetA,
ParentchainInstanceTargetB, ParentchainLitentry, Runtime, System, VERSION as SIDECHAIN_VERSION,
};
use itp_node_api::metadata::{
pallet_system::SystemConstants, provider::AccessNodeMetadata, NodeMetadataTrait,
};
use itp_node_api::metadata::{provider::AccessNodeMetadata, NodeMetadataTrait};
use itp_node_api_metadata::{pallet_imp::IMPCallIndexes, pallet_vcmp::VCMPCallIndexes};
use itp_stf_interface::ExecuteCall;
use itp_stf_primitives::{
Expand Down Expand Up @@ -133,14 +129,12 @@ pub enum TrustedCall {
H256,
),
#[codec(index = 21)]
request_vc_callback(Identity, Identity, Assertion, Vec<u8>, Option<RequestAesKey>, bool, H256),
#[codec(index = 22)]
handle_imp_error(Identity, Option<Identity>, IMPError, H256),
#[codec(index = 23)]
#[codec(index = 22)]
handle_vcmp_error(Identity, Option<Identity>, VCMPError, H256),
#[codec(index = 24)]
#[codec(index = 23)]
send_erroneous_parentchain_call(Identity),
#[codec(index = 25)]
#[codec(index = 24)]
maybe_create_id_graph(Identity, Identity),

// original integritee trusted calls, starting from index 50
Expand Down Expand Up @@ -223,7 +217,6 @@ impl TrustedCall {
Self::request_vc(sender_identity, ..) => sender_identity,
Self::set_identity_networks(sender_identity, ..) => sender_identity,
Self::link_identity_callback(sender_identity, ..) => sender_identity,
Self::request_vc_callback(sender_identity, ..) => sender_identity,
Self::handle_imp_error(sender_identity, ..) => sender_identity,
Self::handle_vcmp_error(sender_identity, ..) => sender_identity,
Self::send_erroneous_parentchain_call(sender_identity) => sender_identity,
Expand All @@ -239,7 +232,6 @@ impl TrustedCall {
Self::link_identity(..) => "link_identity",
Self::request_vc(..) => "request_vc",
Self::link_identity_callback(..) => "link_identity_callback",
Self::request_vc_callback(..) => "request_vc_callback",
Self::handle_vcmp_error(..) => "handle_vcmp_error",
Self::handle_imp_error(..) => "handle_imp_error",
Self::deactivate_identity(..) => "deactivate_identity",
Expand Down Expand Up @@ -663,6 +655,7 @@ where
debug!("remove_identity, who: {}", account_id_to_string(&who));

let account = signer.to_account_id().ok_or(Self::Error::InvalidAccount)?;
use crate::helpers::ensure_enclave_signer_or_alice;
ensure!(
ensure_enclave_signer_or_alice(&account),
StfError::RemoveIdentityFailed(ErrorDetail::UnauthorizedSigner)
Expand Down Expand Up @@ -781,109 +774,14 @@ where
maybe_key,
req_ext_hash,
),
TrustedCall::request_vc(signer, who, assertion, maybe_key, req_ext_hash) => {
debug!(
"request_vc, who: {}, assertion: {:?}",
account_id_to_string(&who),
assertion
);

let parachain_runtime_version =
node_metadata_repo.get_from_metadata(|m| m.system_version())??.spec_version;
let sidechain_runtime_version = SIDECHAIN_VERSION.spec_version;

Self::request_vc_internal(
signer.to_account_id().ok_or(Self::Error::InvalidAccount)?,
who.clone(),
assertion,
top_hash,
req_ext_hash,
maybe_key,
shard,
parachain_runtime_version,
sidechain_runtime_version,
)
.map_err(|e| {
debug!("pushing error event ... error: {}", e);
push_call_vcmp_some_error(
calls,
node_metadata_repo,
Some(who),
e.to_vcmp_error(),
req_ext_hash,
);
e
})?;
Ok(TrustedCallResult::Streamed)
TrustedCall::request_vc(_signer, _who, _assertion, _maybe_key, _req_ext_hash) => {
error!("deprecated, please use author_requestVc instead");
Ok(TrustedCallResult::Empty)
},
TrustedCall::request_batch_vc(..) => {
error!(
"TrustedCall::request_batch_vc is not supported here. Will be removed later."
);
error!("deprecated, please use author_requestVc instead");
Ok(TrustedCallResult::Empty)
},
TrustedCall::request_vc_callback(
signer,
who,
assertion,
vc_payload,
maybe_key,
should_create_id_graph,
req_ext_hash,
) => {
debug!(
"request_vc_callback, who: {}, should_create_id_graph: {}, assertion: {:?}",
account_id_to_string(&who),
should_create_id_graph,
assertion
);

Self::request_vc_callback_internal(
signer.to_account_id().ok_or(Self::Error::InvalidAccount)?,
who.clone(),
assertion.clone(),
should_create_id_graph,
)
.map_err(|e| {
debug!("pushing error event ... error: {}", e);
push_call_vcmp_some_error(
calls,
node_metadata_repo.clone(),
Some(who.clone()),
e.to_vcmp_error(),
req_ext_hash,
);
e
})?;

debug!("pushing vc_issued event ...");
let call_index =
node_metadata_repo.get_from_metadata(|m| m.vc_issued_call_indexes())??;

// IDGraph hash can't be `None` as we should have created it otherwise
let id_graph_hash: H256 = IMT::id_graph_hash(&who).ok_or(StfError::EmptyIDGraph)?;
let mutated_id_graph =
if should_create_id_graph { IMT::id_graph(&who) } else { Vec::new() };

calls.push(ParentchainCall::Litentry(OpaqueCall::from_tuple(&(
call_index,
who,
assertion,
id_graph_hash,
req_ext_hash,
))));

if let Some(key) = maybe_key {
Ok(TrustedCallResult::RequestVC(RequestVCResult {
vc_payload: aes_encrypt_default(&key, &vc_payload),
vc_logs: None,
pre_mutated_id_graph: aes_encrypt_default(&key, &mutated_id_graph.encode()),
pre_id_graph_hash: id_graph_hash,
}))
} else {
Ok(TrustedCallResult::Empty)
}
},
TrustedCall::set_identity_networks(
signer,
who,
Expand Down
126 changes: 7 additions & 119 deletions tee-worker/app-libs/stf/src/trusted_call_litentry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,13 @@ extern crate sgx_tstd as std;

use super::*;
use crate::{
helpers::{
ensure_enclave_signer_account, ensure_enclave_signer_or_self, get_expected_raw_message,
verify_web3_identity,
},
helpers::{ensure_enclave_signer_or_self, get_expected_raw_message, verify_web3_identity},
trusted_call_result::{LinkIdentityResult, TrustedCallResult},
Arc, Vec,
};
use codec::Encode;
use frame_support::{dispatch::UnfilteredDispatchable, ensure, sp_runtime::traits::One};
use ita_sgx_runtime::{
pallet_imt::{get_eligible_identities, IdentityContext},
BlockNumber, ParentchainLitentry, RuntimeOrigin, System,
};
use frame_support::{dispatch::UnfilteredDispatchable, ensure};
use ita_sgx_runtime::{RuntimeOrigin, System};
use itp_node_api::metadata::NodeMetadataTrait;
use itp_node_api_metadata::pallet_imp::IMPCallIndexes;
use itp_node_api_metadata_provider::AccessNodeMetadata;
Expand All @@ -42,18 +36,12 @@ use itp_stf_primitives::{
use itp_types::{parentchain::ParentchainCall, OpaqueCall, H256};
use itp_utils::stringify::account_id_to_string;
use lc_stf_task_sender::{
AssertionBuildRequest, RequestType, SendStfRequest, StfRequestSender,
Web2IdentityVerificationRequest,
RequestType, SendStfRequest, StfRequestSender, Web2IdentityVerificationRequest,
};
use litentry_macros::if_development_or;
use litentry_primitives::{
Assertion, ErrorDetail, Identity, RequestAesKey, ValidationData, Web3Network,
};
use litentry_primitives::{ErrorDetail, Identity, RequestAesKey, ValidationData, Web3Network};
use log::*;

#[cfg(feature = "development")]
use crate::helpers::{ensure_alice, ensure_enclave_signer_or_alice};

impl TrustedCallSigned {
#[allow(clippy::too_many_arguments)]
pub fn link_identity_internal(
Expand Down Expand Up @@ -150,89 +138,6 @@ impl TrustedCallSigned {
Ok(())
}

#[allow(clippy::too_many_arguments)]
pub fn request_vc_internal(
signer: AccountId,
who: Identity,
assertion: Assertion,
top_hash: H256,
req_ext_hash: H256,
maybe_key: Option<RequestAesKey>,
shard: &ShardIdentifier,
parachain_runtime_version: u32,
sidechain_runtime_version: u32,
) -> StfResult<()> {
match assertion {
// the signer will be checked inside A13, as we don't seem to have access to ocall_api here
Assertion::A13(_) => (),
_ => if_development_or!(
ensure!(
ensure_enclave_signer_or_self(&signer, who.to_account_id())
|| ensure_alice(&signer),
StfError::RequestVCFailed(assertion, ErrorDetail::UnauthorizedSigner)
),
ensure!(
ensure_enclave_signer_or_self(&signer, who.to_account_id()),
StfError::RequestVCFailed(assertion, ErrorDetail::UnauthorizedSigner)
)
),
}

let mut id_graph = IMT::id_graph(&who);
let mut should_create_id_graph = false;
if id_graph.is_empty() {
// create a "virtual" IDGraph now for VC building, the "real" IDGraph will be created
// in `request_vc_callback` when a VC is guaranteed to be issued
//
// we don't mutate the IDGraph here as the transaction is **not** atomic: imagine the VC
// building fails (e.g. due to data provider error), the client won't expect the IDGraph
// to be updated, they can't get the latest IDGraph hash either
//
// we are safe to use `default_web3networks` and `Active` as IDGraph would be non-empty otherwise
id_graph.push((
who.clone(),
IdentityContext::new(BlockNumber::one(), who.default_web3networks()),
));
should_create_id_graph = true;
}
let assertion_networks = assertion.get_supported_web3networks();
let identities = get_eligible_identities(
id_graph.as_ref(),
assertion_networks,
assertion.skip_identity_filtering(),
);

ensure!(
!identities.is_empty(),
StfError::RequestVCFailed(assertion, ErrorDetail::NoEligibleIdentity)
);

let parachain_block_number = ParentchainLitentry::block_number();
let sidechain_block_number = System::block_number();

let assertion_build: RequestType = AssertionBuildRequest {
shard: *shard,
signer,
who,
assertion: assertion.clone(),
identities,
top_hash,
parachain_block_number,
sidechain_block_number,
parachain_runtime_version,
sidechain_runtime_version,
maybe_key,
should_create_id_graph,
req_ext_hash,
}
.into();
let sender = StfRequestSender::new();
sender.send_stf_request(assertion_build).map_err(|e| {
error!("[RequestVc] : {:?}", e);
StfError::RequestVCFailed(assertion, ErrorDetail::SendStfRequestFailed)
})
}

pub fn link_identity_callback_internal(
signer: AccountId,
who: Identity,
Expand All @@ -241,13 +146,15 @@ impl TrustedCallSigned {
) -> StfResult<()> {
if_development_or!(
{
use crate::helpers::ensure_enclave_signer_or_alice;
// In non-prod: we allow to use `Alice` as the dummy signer
ensure!(
ensure_enclave_signer_or_alice(&signer),
StfError::LinkIdentityFailed(ErrorDetail::UnauthorizedSigner)
);
},
{
use crate::helpers::ensure_enclave_signer_account;
// In prod: the signer has to be enclave_signer_account, as this TrustedCall can only be constructed internally
ensure_enclave_signer_account(&signer)
.map_err(|_| StfError::LinkIdentityFailed(ErrorDetail::UnauthorizedSigner))?;
Expand All @@ -260,25 +167,6 @@ impl TrustedCallSigned {
Ok(())
}

pub fn request_vc_callback_internal(
signer: AccountId,
who: Identity,
assertion: Assertion,
should_create_id_graph: bool,
) -> StfResult<()> {
// important! The signer has to be enclave_signer_account, as this TrustedCall can only be constructed internally
ensure_enclave_signer_account(&signer).map_err(|_| {
StfError::RequestVCFailed(assertion.clone(), ErrorDetail::UnauthorizedSigner)
})?;

if should_create_id_graph {
IMT::maybe_create_id_graph(&who)
.map_err(|e| StfError::RequestVCFailed(assertion, e.into()))?;
}

Ok(())
}

// common handler for both web2 and web3 identity verification
#[allow(clippy::too_many_arguments)]
pub fn handle_link_identity_callback<NodeMetadataRepository>(
Expand Down
Loading
Loading