diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 395331915f..9eb17c948f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -692,10 +692,7 @@ jobs: fail-fast: false matrix: include: - - test_name: demo-shielding-unshielding-multiworker - - test_name: demo-direct-call # Litentry - - test_name: lit-set-heartbeat-timeout - test_name: lit-ii-vc-test - test_name: lit-ii-identity-test - test_name: lit-di-substrate-identity-test diff --git a/bitacross-worker/Cargo.lock b/bitacross-worker/Cargo.lock index 0402c9e279..6695ba9514 100644 --- a/bitacross-worker/Cargo.lock +++ b/bitacross-worker/Cargo.lock @@ -9035,6 +9035,32 @@ dependencies = [ "sp-std 5.0.0", ] +[[package]] +name = "pallet-teebag" +version = "0.1.0" +dependencies = [ + "base64 0.13.1", + "chrono 0.4.26", + "der 0.6.1", + "frame-support", + "frame-system", + "hex 0.4.3", + "log 0.4.20", + "pallet-balances", + "pallet-timestamp", + "parity-scale-codec", + "ring 0.16.20", + "rustls-webpki", + "scale-info", + "serde 1.0.193", + "serde_json 1.0.103", + "sp-core", + "sp-io 7.0.0 (git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42)", + "sp-runtime", + "sp-std 5.0.0", + "x509-cert", +] + [[package]] name = "pallet-teeracle" version = "0.1.0" @@ -10907,6 +10933,7 @@ dependencies = [ "pallet-session", "pallet-sidechain", "pallet-sudo", + "pallet-teebag", "pallet-teeracle", "pallet-teerex", "pallet-timestamp", @@ -11035,6 +11062,7 @@ dependencies = [ "pallet-group", "pallet-membership", "pallet-multisig", + "pallet-teebag", "pallet-teerex", "pallet-transaction-payment", "pallet-treasury", diff --git a/bitacross-worker/enclave-runtime/Cargo.lock b/bitacross-worker/enclave-runtime/Cargo.lock index ae5936ad0b..81ba58674d 100644 --- a/bitacross-worker/enclave-runtime/Cargo.lock +++ b/bitacross-worker/enclave-runtime/Cargo.lock @@ -32,7 +32,7 @@ dependencies = [ "derive_more", "either", "frame-metadata", - "hex", + "hex 0.4.3", "log", "parity-scale-codec", "scale-bits", @@ -248,6 +248,49 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "bc-task-receiver" +version = "0.1.0" +dependencies = [ + "bc-task-sender", + "frame-support", + "futures 0.3.8", + "hex 0.4.0", + "ita-sgx-runtime", + "ita-stf", + "itp-enclave-metrics", + "itp-extrinsics-factory", + "itp-node-api", + "itp-ocall-api", + "itp-sgx-crypto", + "itp-sgx-externalities", + "itp-stf-executor", + "itp-stf-state-handler", + "itp-storage", + "itp-top-pool-author", + "itp-types", + "itp-utils", + "litentry-primitives", + "log", + "parity-scale-codec", + "sgx_tstd", + "sp-core", + "thiserror", + "threadpool", +] + +[[package]] +name = "bc-task-sender" +version = "0.1.0" +dependencies = [ + "futures 0.3.8", + "lazy_static", + "litentry-primitives", + "log", + "parity-scale-codec", + "sgx_tstd", +] + [[package]] name = "bech32" version = "0.10.0-beta" @@ -803,7 +846,7 @@ checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" dependencies = [ "curve25519-dalek 3.2.0", "hashbrown 0.12.3", - "hex", + "hex 0.4.3", "rand_core 0.6.4", "sha2 0.9.9", "zeroize", @@ -838,12 +881,13 @@ name = "enclave-runtime" version = "0.0.1" dependencies = [ "array-bytes 6.1.0", + "bc-task-receiver", "cid", "derive_more", "env_logger", "frame-support", "frame-system", - "hex", + "hex 0.4.3", "ipfs-unixfs", "ita-parentchain-interface", "ita-sgx-runtime", @@ -1169,7 +1213,7 @@ name = "fp-account" version = "1.0.0-dev" source = "git+https://github.com/integritee-network/frontier.git?branch=bar/polkadot-v0.9.42#a5a5e1e6ec08cd542a6084c310863150fb8841b1" dependencies = [ - "hex", + "hex 0.4.3", "libsecp256k1", "log", "parity-scale-codec", @@ -1185,7 +1229,7 @@ name = "fp-account" version = "1.0.0-dev" source = "git+https://github.com/paritytech/frontier?branch=polkadot-v0.9.42#2499d18c936edbcb7fcb711827db7abb9b4f4da4" dependencies = [ - "hex", + "hex 0.4.3", "libsecp256k1", "log", "parity-scale-codec", @@ -1629,6 +1673,14 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "hex" +version = "0.4.0" +source = "git+https://github.com/mesalock-linux/rust-hex-sgx?tag=sgx_1.1.3#ee3266cd29b9f9c2eb69af9487f55c4f09c38f2b" +dependencies = [ + "sgx_tstd", +] + [[package]] name = "hex" version = "0.4.3" @@ -1850,7 +1902,7 @@ version = "0.9.0" dependencies = [ "frame-support", "frame-system", - "hex", + "hex 0.4.3", "hex-literal", "ita-sgx-runtime", "itp-hashing", @@ -2120,7 +2172,7 @@ dependencies = [ "base64 0.13.0 (git+https://github.com/mesalock-linux/rust-base64-sgx?rev=sgx_1.1.3)", "bit-vec", "chrono 0.4.11", - "hex", + "hex 0.4.3", "httparse", "itertools 0.10.5", "itp-ocall-api", @@ -2336,7 +2388,7 @@ dependencies = [ name = "itp-stf-executor" version = "0.9.0" dependencies = [ - "hex", + "hex 0.4.3", "itc-parentchain-test", "itp-enclave-metrics", "itp-node-api", @@ -2448,7 +2500,7 @@ dependencies = [ name = "itp-test" version = "0.9.0" dependencies = [ - "hex", + "hex 0.4.3", "itp-node-api", "itp-node-api-metadata-provider", "itp-ocall-api", @@ -2547,7 +2599,7 @@ dependencies = [ name = "itp-utils" version = "0.9.0" dependencies = [ - "hex", + "hex 0.4.3", "litentry-hex-utils", "parity-scale-codec", ] @@ -2658,7 +2710,7 @@ name = "its-consensus-slots" version = "0.9.0" dependencies = [ "derive_more", - "hex", + "hex 0.4.3", "itp-settings", "itp-sgx-externalities", "itp-stf-state-handler", @@ -2694,6 +2746,7 @@ dependencies = [ name = "its-rpc-handler" version = "0.9.0" dependencies = [ + "bc-task-sender", "futures 0.3.8", "itp-rpc", "itp-stf-primitives", @@ -2891,7 +2944,7 @@ dependencies = [ name = "litentry-hex-utils" version = "0.9.12" dependencies = [ - "hex", + "hex 0.4.3", ] [[package]] @@ -2904,7 +2957,7 @@ version = "0.1.0" dependencies = [ "bitcoin", "core-primitives", - "hex", + "hex 0.4.3", "itp-sgx-crypto", "itp-utils", "litentry-hex-utils", @@ -3202,7 +3255,7 @@ dependencies = [ "fp-evm 3.0.0-dev (git+https://github.com/integritee-network/frontier.git?branch=bar/polkadot-v0.9.42)", "frame-support", "frame-system", - "hex", + "hex 0.4.3", "impl-trait-for-tuples", "log", "parity-scale-codec", @@ -3224,7 +3277,7 @@ dependencies = [ "fp-evm 3.0.0-dev (git+https://github.com/paritytech/frontier?branch=polkadot-v0.9.42)", "frame-support", "frame-system", - "hex", + "hex 0.4.3", "hex-literal", "impl-trait-for-tuples", "log", @@ -4742,7 +4795,7 @@ dependencies = [ "async-trait", "derive_more", "frame-metadata", - "hex", + "hex 0.4.3", "log", "maybe-async", "parity-scale-codec", @@ -4879,6 +4932,14 @@ dependencies = [ "sgx_tstd", ] +[[package]] +name = "threadpool" +version = "1.8.0" +source = "git+https://github.com/mesalock-linux/rust-threadpool-sgx?tag=sgx_1.1.3#098d98a85b7e2b02e2bb451a3dec0b027017ff4c" +dependencies = [ + "sgx_tstd", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -5043,7 +5104,7 @@ checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ "byteorder 1.4.3", "crunchy", - "hex", + "hex 0.4.3", "static_assertions", ] diff --git a/node/src/chain_specs/rococo.rs b/node/src/chain_specs/rococo.rs index 0e6742ce9d..973640a429 100644 --- a/node/src/chain_specs/rococo.rs +++ b/node/src/chain_specs/rococo.rs @@ -19,8 +19,8 @@ use cumulus_primitives_core::ParaId; use rococo_parachain_runtime::{ AccountId, AuraId, Balance, BalancesConfig, CouncilMembershipConfig, GenesisConfig, ParachainInfoConfig, ParachainStakingConfig, PolkadotXcmConfig, SessionConfig, SudoConfig, - SystemConfig, TechnicalCommitteeMembershipConfig, TeebagConfig, TeerexConfig, - VCManagementConfig, UNIT, WASM_BINARY, + SystemConfig, TechnicalCommitteeMembershipConfig, TeebagConfig, TeebagOperationalMode, + TeerexConfig, VCManagementConfig, UNIT, WASM_BINARY, }; use sc_service::ChainType; use sc_telemetry::TelemetryEndpoints; @@ -253,7 +253,7 @@ fn generate_genesis( teebag: TeebagConfig { allow_sgx_debug_mode: true, admin: Some(root_key), - mode: Default::default(), + mode: TeebagOperationalMode::Development, }, } } diff --git a/pallets/teebag/src/lib.rs b/pallets/teebag/src/lib.rs index 577ee3f9a0..ecdc96deaa 100644 --- a/pallets/teebag/src/lib.rs +++ b/pallets/teebag/src/lib.rs @@ -30,9 +30,10 @@ use sp_runtime::traits::{CheckedSub, SaturatedConversion}; use sp_std::{prelude::*, str}; mod sgx_verify; -use sgx_verify::{ - deserialize_enclave_identity, deserialize_tcb_info, extract_certs, verify_certificate_chain, - verify_dcap_quote, verify_ias_report, SgxReport, +pub use sgx_verify::{ + deserialize_enclave_identity, deserialize_tcb_info, extract_certs, + extract_tcb_info_from_raw_dcap_quote, verify_certificate_chain, verify_dcap_quote, + verify_ias_report, SgxReport, }; pub use pallet::*; @@ -64,6 +65,10 @@ pub mod pallet { type MomentsPerDay: Get; /// The origin who can set the admin account type SetAdminOrigin: EnsureOrigin; + /// Maximum number of enclave identifiers allowed to be registered for a specific + /// `worker_type` + #[pallet::constant] + type MaxEnclaveIdentifier: Get; } // TODO: maybe add more sidechain lifecycle events @@ -76,10 +81,6 @@ pub mod pallet { AdminSet { new_admin: Option, }, - MaxEnclaveCountSet { - worker_type: WorkerType, - new_count: u64, - }, EnclaveAdded { who: T::AccountId, worker_type: WorkerType, @@ -130,6 +131,12 @@ pub mod pallet { InvalidSgxMode, /// The enclave doesn't exist. EnclaveNotExist, + /// The enclave identifier doesn't exist. + EnclaveIdentifierNotExist, + /// The enclave identifier already exists. + EnclaveIdentifierAlreadyExist, + /// when we try to re-register an existing enclave with a differnet worker type + WorkerTypeNotAllowed, /// The shard doesn't match the enclave. WrongMrenclaveForShard, /// The worker url is too long. @@ -143,16 +150,10 @@ pub mod pallet { ScheduledEnclaveNotExist, /// Enclave not in the scheduled list, therefore unexpected. EnclaveNotInSchedule, - /// The provided collateral data is invalid + /// The provided collateral data is invalid. CollateralInvalid, - /// The number of `extra_topics` passed to `publish_hash` exceeds the limit. - TooManyTopics, - /// The length of the `data` passed to `publish_hash` exceeds the limit. - DataTooLong, - /// max_enclave_count overflows - MaxEnclaveCountOverflow, - /// max_enclave_count underflows (than 0 or currently registered enclave count) - MaxEnclaveCountUnderflow, + /// MaxEnclaveIdentifier overflow. + MaxEnclaveIdentifierOverflow, /// A proposed block is unexpected. ReceivedUnexpectedSidechainBlock, /// The value for the next finalization candidate is invalid. @@ -167,25 +168,22 @@ pub mod pallet { #[pallet::getter(fn mode)] pub type Mode = StorageValue<_, OperationalMode, ValueQuery>; - #[pallet::type_value] - pub fn DefaultMaxEnclaveCount() -> u64 { - 3 - } - + // records the enclave identifier list for each worker_type + // T::AccountId is used as identifier as it's unique for each enclave #[pallet::storage] - #[pallet::getter(fn max_enclave_count)] - pub type MaxEnclaveCount = - StorageMap<_, Blake2_128Concat, WorkerType, u64, ValueQuery, DefaultMaxEnclaveCount>; - - #[pallet::storage] - #[pallet::getter(fn enclave_count)] - pub type EnclaveCount = StorageMap<_, Blake2_128Concat, WorkerType, u64, ValueQuery>; + #[pallet::getter(fn enclave_identifier)] + pub type EnclaveIdentifier = StorageMap< + _, + Blake2_128Concat, + WorkerType, + BoundedVec, + ValueQuery, + >; // registry that holds all registered enclaves, using T::AccountId as the key // having `worker_type` and `mrenclave` in each `Enclave` instance might seem a bit redundant, // but it increases flexibility where we **could** allow the same type of worker to have - // different mrenclaves - e.g. when more than one version of an enclave is permitted in TEE-node - // cluster. + // distinct mrenclaves: e.g. when multiple versions of enclave are permitted in TEE cluster. // // It simplifies the lookup a bit too, otherwise we might need several storages. #[pallet::storage] @@ -225,11 +223,6 @@ pub mod pallet { pub type ScheduledEnclave = StorageMap<_, Blake2_128Concat, (WorkerType, SidechainBlockNumber), MrEnclave>; - #[pallet::storage] - #[pallet::getter(fn worker_for_shard)] - pub type WorkerForShard = - StorageMap<_, Blake2_128Concat, ShardIdentifier, T::AccountId, OptionQuery>; - #[pallet::storage] #[pallet::getter(fn latest_sidechain_block_confirmation)] pub type LatestSidechainBlockConfirmation = @@ -304,24 +297,6 @@ pub mod pallet { #[pallet::call_index(2)] #[pallet::weight((195_000_000, DispatchClass::Normal, Pays::No))] - pub fn set_max_enclave_count( - origin: OriginFor, - worker_type: WorkerType, - new_count: u64, - ) -> DispatchResultWithPostInfo { - Self::ensure_admin_or_root(origin)?; - ensure!( - new_count > Self::max_enclave_count(worker_type), - Error::::MaxEnclaveCountUnderflow - ); - - MaxEnclaveCount::::insert(worker_type, new_count); - Self::deposit_event(Event::MaxEnclaveCountSet { worker_type, new_count }); - Ok(Pays::No.into()) - } - - #[pallet::call_index(3)] - #[pallet::weight((195_000_000, DispatchClass::Normal, Pays::No))] pub fn force_add_enclave( origin: OriginFor, who: T::AccountId, @@ -332,7 +307,7 @@ pub mod pallet { Ok(Pays::No.into()) } - #[pallet::call_index(4)] + #[pallet::call_index(3)] #[pallet::weight((195_000_000, DispatchClass::Normal, Pays::No))] pub fn force_remove_enclave( origin: OriginFor, @@ -343,7 +318,7 @@ pub mod pallet { Ok(Pays::No.into()) } - #[pallet::call_index(5)] + #[pallet::call_index(4)] #[pallet::weight((195_000_000, DispatchClass::Normal, Pays::No))] pub fn force_remove_enclave_by_mrenclave( origin: OriginFor, @@ -368,7 +343,7 @@ pub mod pallet { Ok(Pays::No.into()) } - #[pallet::call_index(6)] + #[pallet::call_index(5)] #[pallet::weight((195_000_000, DispatchClass::Normal, Pays::No))] pub fn force_remove_enclave_by_worker_type( origin: OriginFor, @@ -394,7 +369,7 @@ pub mod pallet { Ok(Pays::No.into()) } - #[pallet::call_index(7)] + #[pallet::call_index(6)] #[pallet::weight((195_000_000, DispatchClass::Normal, Pays::No))] pub fn set_scheduled_enclave( origin: OriginFor, @@ -412,7 +387,7 @@ pub mod pallet { Ok(().into()) } - #[pallet::call_index(8)] + #[pallet::call_index(7)] #[pallet::weight((195_000_000, DispatchClass::Normal, Pays::No))] pub fn remove_scheduled_enclave( origin: OriginFor, @@ -432,7 +407,7 @@ pub mod pallet { Ok(().into()) } - #[pallet::call_index(9)] + #[pallet::call_index(8)] #[pallet::weight((195_000_000, DispatchClass::Normal, Pays::Yes))] pub fn register_enclave( origin: OriginFor, @@ -447,13 +422,12 @@ pub mod pallet { ensure!(worker_url.len() <= MAX_URL_LEN, Error::::EnclaveUrlTooLong); - let mut enclave = Enclave::new( - worker_type, - worker_url, - shielding_pubkey, - vc_pubkey, - attestation_type, - ); + let mut enclave = Enclave::new(worker_type) + .with_url(worker_url) + .with_shielding_pubkey(shielding_pubkey) + .with_vc_pubkey(vc_pubkey) + .with_attestation_type(attestation_type); + match attestation_type { AttestationType::Ignore => { ensure!( @@ -493,12 +467,11 @@ pub mod pallet { }, OperationalMode::Development => (), }; - enclave.register_timestamp = Self::now().saturated_into(); Self::add_enclave(&sender, &enclave)?; Ok(().into()) } - #[pallet::call_index(10)] + #[pallet::call_index(9)] #[pallet::weight((195_000_000, DispatchClass::Normal, Pays::Yes))] pub fn unregister_enclave(origin: OriginFor) -> DispatchResultWithPostInfo { let sender = ensure_signed(origin)?; @@ -506,7 +479,7 @@ pub mod pallet { Ok(().into()) } - #[pallet::call_index(11)] + #[pallet::call_index(10)] #[pallet::weight((195_000_000, DispatchClass::Normal, Pays::No))] pub fn register_quoting_enclave( origin: OriginFor, @@ -522,7 +495,7 @@ pub mod pallet { Ok(().into()) } - #[pallet::call_index(12)] + #[pallet::call_index(11)] #[pallet::weight((195_000_000, DispatchClass::Normal, Pays::No))] pub fn register_tcb_info( origin: OriginFor, @@ -596,13 +569,15 @@ pub mod pallet { sender_enclave.last_seen_timestamp = Self::now().saturated_into(); // Simple logic for now: only accept blocks from first registered enclave. - let primary_enclave = Self::primary_enclave(sender_enclave.worker_type) - .ok_or(Error::::EnclaveNotExist)?; - - if sender_enclave.register_timestamp > primary_enclave.register_timestamp { + let primary_enclave_identifier = + EnclaveIdentifier::::get(sender_enclave.worker_type) + .get(0) + .cloned() + .ok_or(Error::::EnclaveIdentifierNotExist)?; + if sender != primary_enclave_identifier { log::debug!( - "Ignore block confirmation from registered enclave with timestamp {}", - sender_enclave.register_timestamp + "Ignore block confirmation from non primary enclave identifier: {:?}, primary: {:?}", + sender, primary_enclave_identifier ); return Ok(().into()) } @@ -640,40 +615,20 @@ impl Pallet { Ok(().into()) } - fn increment_count(worker_type: WorkerType) -> Result<(), DispatchErrorWithPostInfo> { - let count = Self::enclave_count(worker_type); - ensure!(count < Self::max_enclave_count(worker_type), Error::::MaxEnclaveCountOverflow); - - EnclaveCount::::insert( - worker_type, - count.checked_add(1u64).ok_or(Error::::MaxEnclaveCountOverflow)?, - ); - - Ok(()) + fn add_enclave_identifier(worker_type: WorkerType, who: &T::AccountId) -> Result<(), Error> { + EnclaveIdentifier::::try_mutate(worker_type, |v| { + ensure!(!v.contains(who), Error::::EnclaveIdentifierAlreadyExist); + v.try_push(who.clone()).map_err(|_| Error::::MaxEnclaveIdentifierOverflow) + }) } - fn decrement_count(worker_type: WorkerType) -> Result<(), DispatchErrorWithPostInfo> { - let count = Self::enclave_count(worker_type); - EnclaveCount::::insert( - worker_type, - count.checked_sub(1u64).ok_or(Error::::MaxEnclaveCountUnderflow)?, - ); - - Ok(()) - } - - pub fn add_enclave(sender: &T::AccountId, enclave: &Enclave) -> DispatchResultWithPostInfo { + pub fn add_enclave(sender: &T::AccountId, enclave: &Enclave) -> Result<(), Error> { match EnclaveRegistry::::get(sender) { - Some(old_enclave) => { - if old_enclave.worker_type != enclave.worker_type { - // a tricky situation - we are re-registering the enclave with a different - // worker type - Self::decrement_count(old_enclave.worker_type)?; - Self::increment_count(enclave.worker_type)?; - } - // else - do nothing - }, - None => Self::increment_count(enclave.worker_type)?, + Some(old_enclave) => ensure!( + old_enclave.worker_type == enclave.worker_type, + Error::::WorkerTypeNotAllowed + ), + None => Self::add_enclave_identifier(enclave.worker_type, sender)?, }; EnclaveRegistry::::insert(sender, enclave); Self::deposit_event(Event::::EnclaveAdded { @@ -681,29 +636,25 @@ impl Pallet { worker_type: enclave.worker_type, url: enclave.url.clone(), }); - Ok(().into()) + Ok(()) } fn remove_enclave(sender: &T::AccountId) -> DispatchResultWithPostInfo { let enclave = EnclaveRegistry::::get(sender).ok_or(Error::::EnclaveNotExist)?; - let count = EnclaveCount::::get(enclave.worker_type); - EnclaveCount::::insert( - enclave.worker_type, - count.checked_sub(1u64).ok_or(Error::::MaxEnclaveCountOverflow)?, - ); + EnclaveIdentifier::::try_mutate(enclave.worker_type, |v| { + ensure!(v.contains(sender), Error::::EnclaveIdentifierNotExist); + v.retain(|e| e != sender); + Ok::<(), DispatchErrorWithPostInfo>(()) + })?; EnclaveRegistry::::remove(sender); Self::deposit_event(Event::::EnclaveRemoved { who: sender.clone() }); Ok(().into()) } - pub fn primary_enclave(worker_type: WorkerType) -> Option { - let mut enclaves = EnclaveRegistry::::iter_values() - .filter(|e| e.worker_type == worker_type) - .collect::>(); - enclaves.sort_by(|a, b| Ord::cmp(&a.register_timestamp, &b.register_timestamp)); - enclaves.get(0).cloned() + pub fn enclave_count(worker_type: WorkerType) -> u32 { + EnclaveIdentifier::::get(worker_type).iter().count() as u32 } fn verify_ias( @@ -810,7 +761,6 @@ impl Pallet { confirmation: SidechainBlockConfirmation, ) { LatestSidechainBlockConfirmation::::insert(shard, confirmation); - WorkerForShard::::insert(shard, sender.clone()); Self::deposit_event(Event::SidechainBlockFinalized { who: sender, sidechain_block_number: confirmation.block_number, diff --git a/pallets/teebag/src/mock.rs b/pallets/teebag/src/mock.rs index bcaac7e06f..945948cdda 100644 --- a/pallets/teebag/src/mock.rs +++ b/pallets/teebag/src/mock.rs @@ -24,7 +24,7 @@ use frame_support::{ }; use frame_system as system; use frame_system::EnsureRoot; -use sp_core::H256; +use sp_core::{ConstU32, H256}; use sp_keyring::AccountKeyring; use sp_runtime::{ generic, @@ -136,6 +136,7 @@ impl pallet_teebag::Config for Test { type RuntimeEvent = RuntimeEvent; type MomentsPerDay = MomentsPerDay; type SetAdminOrigin = EnsureRoot; + type MaxEnclaveIdentifier = ConstU32<1>; } // This function basically just builds a genesis storage key/value store according to diff --git a/pallets/teebag/src/sgx_verify/collateral.rs b/pallets/teebag/src/sgx_verify/collateral.rs index 76f9ad5e0c..53f3c55af4 100644 --- a/pallets/teebag/src/sgx_verify/collateral.rs +++ b/pallets/teebag/src/sgx_verify/collateral.rs @@ -15,7 +15,6 @@ */ -#![cfg_attr(not(feature = "std"), no_std)] pub extern crate alloc; use crate::{Fmspc, MrSigner, Pcesvn, QeTcb, QuotingEnclave, TcbInfoOnChain, TcbVersionStatus}; diff --git a/pallets/teebag/src/sgx_verify/mod.rs b/pallets/teebag/src/sgx_verify/mod.rs index 32b0ff6af8..9572fd879a 100644 --- a/pallets/teebag/src/sgx_verify/mod.rs +++ b/pallets/teebag/src/sgx_verify/mod.rs @@ -28,7 +28,6 @@ //! //! * https://download.01.org/intel-sgx/linux-1.5/docs/Intel_SGX_Developer_Guide.pdf -#![cfg_attr(not(feature = "std"), no_std)] pub extern crate alloc; use self::{ diff --git a/pallets/teebag/src/tests.rs b/pallets/teebag/src/tests.rs index 937cf27c8f..4930c9d2fd 100644 --- a/pallets/teebag/src/tests.rs +++ b/pallets/teebag/src/tests.rs @@ -19,7 +19,7 @@ #![allow(dead_code, unused_imports)] use crate::{ mock::*, AttestationType, DcapProvider, Enclave, EnclaveRegistry, Error, Event as TeebagEvent, - MaxEnclaveCount, ScheduledEnclave, SgxBuildMode, WorkerType, H256, + ScheduledEnclave, SgxBuildMode, WorkerType, H256, }; use frame_support::{assert_noop, assert_ok}; use hex_literal::hex; @@ -29,8 +29,12 @@ use test_utils::{get_signer, ias::consts::*}; const VALID_TIMESTAMP: Moment = 1671606747000; +fn alice() -> AccountId32 { + AccountKeyring::Alice.to_account_id() +} + fn default_enclave() -> Enclave { - Enclave::default() + Enclave::new(WorkerType::Identity) .with_attestation_type(AttestationType::Ignore) .with_url(URL.to_vec()) .with_last_seen_timestamp(pallet_timestamp::Pallet::::now()) @@ -84,7 +88,7 @@ fn register_enclave_dev_works_with_no_scheduled_enclave() { new_test_ext(true).execute_with(|| { // it works with no entry in scheduled_enclave assert_ok!(Teebag::register_enclave( - RuntimeOrigin::signed(AccountKeyring::Alice.to_account_id()), + RuntimeOrigin::signed(alice()), Default::default(), TEST4_MRENCLAVE.to_vec(), URL.to_vec(), @@ -97,10 +101,7 @@ fn register_enclave_dev_works_with_no_scheduled_enclave() { assert_eq!(Teebag::enclave_count(WorkerType::Identity), 1); assert_eq!(Teebag::enclave_count(WorkerType::BitAcross), 0); - assert_eq!( - EnclaveRegistry::::get(AccountKeyring::Alice.to_account_id()).unwrap(), - enclave - ); + assert_eq!(EnclaveRegistry::::get(alice()).unwrap(), enclave); }) } @@ -123,7 +124,6 @@ fn register_enclave_dev_works_with_sgx_build_mode_debug() { let enclave = default_enclave() .with_mrenclave(TEST4_MRENCLAVE) .with_last_seen_timestamp(TEST4_TIMESTAMP) - .with_register_timestamp(TEST4_TIMESTAMP) .with_sgx_build_mode(SgxBuildMode::Debug) .with_attestation_type(AttestationType::Ias); @@ -216,7 +216,7 @@ fn register_dcap_enclave_works() { fn register_enclave_prod_works_with_sgx_build_mode_debug() { new_test_ext(false).execute_with(|| { assert_ok!(Teebag::set_scheduled_enclave( - RuntimeOrigin::signed(AccountKeyring::Alice.to_account_id()), + RuntimeOrigin::signed(alice()), WorkerType::Identity, 0, TEST4_MRENCLAVE @@ -237,7 +237,6 @@ fn register_enclave_prod_works_with_sgx_build_mode_debug() { let enclave = default_enclave() .with_mrenclave(TEST4_MRENCLAVE) .with_last_seen_timestamp(TEST4_TIMESTAMP) - .with_register_timestamp(TEST4_TIMESTAMP) .with_sgx_build_mode(SgxBuildMode::Debug) .with_attestation_type(AttestationType::Ias); @@ -251,7 +250,7 @@ fn register_enclave_prod_works_with_sgx_build_mode_debug() { fn register_enclave_prod_works_with_sgx_build_mode_production() { new_test_ext(false).execute_with(|| { assert_ok!(Teebag::set_scheduled_enclave( - RuntimeOrigin::signed(AccountKeyring::Alice.to_account_id()), + RuntimeOrigin::signed(alice()), WorkerType::Identity, 0, TEST8_MRENCLAVE @@ -272,7 +271,6 @@ fn register_enclave_prod_works_with_sgx_build_mode_production() { let enclave = default_enclave() .with_mrenclave(TEST8_MRENCLAVE) .with_last_seen_timestamp(TEST8_TIMESTAMP) - .with_register_timestamp(TEST8_TIMESTAMP) .with_sgx_build_mode(SgxBuildMode::Production) .with_attestation_type(AttestationType::Ias); @@ -287,7 +285,7 @@ fn register_enclave_prod_fails_with_wrong_attestation_type() { new_test_ext(false).execute_with(|| { assert_noop!( Teebag::register_enclave( - RuntimeOrigin::signed(AccountKeyring::Alice.to_account_id()), + RuntimeOrigin::signed(alice()), Default::default(), TEST4_MRENCLAVE.to_vec(), URL.to_vec(), @@ -323,7 +321,6 @@ fn register_enclave_prod_fails_with_no_scheduled_enclave() { #[test] fn register_enclave_prod_fails_with_max_limit_reached() { new_test_ext(false).execute_with(|| { - MaxEnclaveCount::::insert(WorkerType::BitAcross, 1u64); ScheduledEnclave::::insert((WorkerType::BitAcross, 0), TEST5_MRENCLAVE); ScheduledEnclave::::insert((WorkerType::BitAcross, 1), TEST6_MRENCLAVE); ScheduledEnclave::::insert((WorkerType::Identity, 0), TEST5_MRENCLAVE); @@ -353,11 +350,27 @@ fn register_enclave_prod_fails_with_max_limit_reached() { None, AttestationType::Ias, ), - Error::::MaxEnclaveCountOverflow + Error::::MaxEnclaveIdentifierOverflow ); - // re-register them as WorkerType::Identity should work though + // re-register them as WorkerType::Identity is not allowed Timestamp::set_timestamp(TEST5_TIMESTAMP); + assert_noop!( + Teebag::register_enclave( + RuntimeOrigin::signed(signer5.clone()), + WorkerType::Identity, + TEST5_CERT.to_vec(), + URL.to_vec(), + None, + None, + AttestationType::Ias, + ), + Error::::WorkerTypeNotAllowed + ); + + // remove and re-register it should work + assert_ok!(Teebag::force_remove_enclave(RuntimeOrigin::signed(alice()), signer5.clone(),)); + assert_ok!(Teebag::register_enclave( RuntimeOrigin::signed(signer5), WorkerType::Identity, @@ -369,20 +382,21 @@ fn register_enclave_prod_fails_with_max_limit_reached() { )); Timestamp::set_timestamp(TEST6_TIMESTAMP); - assert_ok!(Teebag::register_enclave( - RuntimeOrigin::signed(signer6), - WorkerType::Identity, - TEST6_CERT.to_vec(), - URL.to_vec(), - None, - None, - AttestationType::Ias, - )); + assert_noop!( + Teebag::register_enclave( + RuntimeOrigin::signed(signer6), + WorkerType::Identity, + TEST6_CERT.to_vec(), + URL.to_vec(), + None, + None, + AttestationType::Ias, + ), + Error::::MaxEnclaveIdentifierOverflow + ); - assert_eq!(Teebag::enclave_count(WorkerType::Identity), 2); + assert_eq!(Teebag::enclave_count(WorkerType::Identity), 1); assert_eq!(Teebag::enclave_count(WorkerType::BitAcross), 0); - assert_eq!(Teebag::max_enclave_count(WorkerType::Identity), 3); - assert_eq!(Teebag::max_enclave_count(WorkerType::BitAcross), 1); }) } diff --git a/pallets/teebag/src/types.rs b/pallets/teebag/src/types.rs index a8f1bc6b50..c54421b546 100644 --- a/pallets/teebag/src/types.rs +++ b/pallets/teebag/src/types.rs @@ -96,12 +96,11 @@ pub struct SidechainBlockConfirmation { pub block_header_hash: H256, } -#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Default, PartialEq, Eq, RuntimeDebug, TypeInfo)] pub struct Enclave { pub worker_type: WorkerType, pub mrenclave: MrEnclave, pub last_seen_timestamp: u64, // unix epoch in milliseconds when it's last seen - pub register_timestamp: u64, // unix epoch in milliseconds when it's registered pub url: Vec, // utf8 encoded url pub shielding_pubkey: Option>, // JSON serialised enclave shielding pub key pub vc_pubkey: Option>, @@ -110,21 +109,8 @@ pub struct Enclave { } impl Enclave { - pub fn new( - worker_type: WorkerType, - url: Vec, - shielding_pubkey: Option>, - vc_pubkey: Option>, - attestation_type: AttestationType, - ) -> Self { - Enclave { - worker_type, - url, - shielding_pubkey, - vc_pubkey, - attestation_type, - ..Default::default() - } + pub fn new(worker_type: WorkerType) -> Self { + Enclave { worker_type, ..Default::default() } } pub fn with_mrenclave(mut self, mrenclave: MrEnclave) -> Self { @@ -137,6 +123,16 @@ impl Enclave { self } + pub fn with_shielding_pubkey(mut self, shielding_pubkey: Option>) -> Self { + self.shielding_pubkey = shielding_pubkey; + self + } + + pub fn with_vc_pubkey(mut self, vc_pubkey: Option>) -> Self { + self.vc_pubkey = vc_pubkey; + self + } + pub fn with_last_seen_timestamp(mut self, t: u64) -> Self { self.last_seen_timestamp = t; self @@ -151,11 +147,6 @@ impl Enclave { self.sgx_build_mode = sgx_build_mode; self } - - pub fn with_register_timestamp(mut self, t: u64) -> Self { - self.register_timestamp = t; - self - } } // use the name `RsaRequest` to differentiate from `AesRequest` (see aes_request.rs in diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index 627a32d369..999043c0e9 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -41,7 +41,7 @@ use runtime_common::EnsureEnclaveSigner; // for TEE pub use pallet_balances::Call as BalancesCall; pub use pallet_sidechain; -pub use pallet_teebag; +pub use pallet_teebag::{self, OperationalMode as TeebagOperationalMode}; pub use pallet_teeracle; pub use pallet_teerex; @@ -1029,6 +1029,7 @@ impl pallet_teebag::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MomentsPerDay = MomentsPerDay; type SetAdminOrigin = EnsureRootOrHalfCouncil; + type MaxEnclaveIdentifier = ConstU32<3>; } impl pallet_identity_management::Config for Runtime { diff --git a/scripts/ts-utils/setup-enclave.ts b/scripts/ts-utils/setup-enclave.ts index f4e989c358..829ce280a7 100644 --- a/scripts/ts-utils/setup-enclave.ts +++ b/scripts/ts-utils/setup-enclave.ts @@ -31,11 +31,11 @@ async function transfer(api: any, Alice: any) { }); }); } -async function setTeerexAdmin(api: any, Alice: any) { +async function teebagSetAdmin(api: any, Alice: any) { return new Promise(async (resolve, reject) => { // Note: The hardcoded address is that of Alice on dev chain await api.tx.sudo - .sudo(api.tx.teerex.setAdmin("esqZdrqhgH8zy1wqYh1aLKoRyoRWLFbX9M62eKfaTAoK67pJ5")) + .sudo(api.tx.teebag.setAdmin("esqZdrqhgH8zy1wqYh1aLKoRyoRWLFbX9M62eKfaTAoK67pJ5")) .signAndSend(Alice, ({ status, events, dispatchError }) => { if (status.isInBlock || status.isFinalized) { if (dispatchError) { @@ -47,23 +47,23 @@ async function setTeerexAdmin(api: any, Alice: any) { const { docs, name, section } = decoded; console.log(colors.red(`${section}.${name}: ${docs.join(" ")}`)); - reject("updateScheduledEnclave failed"); + reject("teebag.setAdmin failed"); } else { // Other, CannotLookup, BadOrigin, no extra info console.log(dispatchError.toString()); - reject("updateScheduledEnclave failed"); + reject("teebag.setAdmin failed"); } } else { - console.log(colors.green("updateScheduledEnclave completed")); - resolve("updateScheduledEnclave done"); + console.log(colors.green("teebag.setAdmin completed")); + resolve("teebag.setAdmin done"); } } }); }); } -async function updateScheduledEnclave(api: any, Alice: any, block: any) { +async function teebagSetScheduledEnclave(api: any, Alice: any, block: any) { return new Promise(async (resolve, reject) => { - await api.tx.teerex.updateScheduledEnclave(block, hexToU8a(`0x${mrenclave}`)) + await api.tx.teebag.setScheduledEnclave("Identity", block, hexToU8a(`0x${mrenclave}`)) .signAndSend(Alice, ({ status, events, dispatchError }) => { if (status.isInBlock || status.isFinalized) { if (dispatchError) { @@ -75,15 +75,15 @@ async function updateScheduledEnclave(api: any, Alice: any, block: any) { const { docs, name, section } = decoded; console.log(colors.red(`${section}.${name}: ${docs.join(" ")}`)); - reject("updateScheduledEnclave failed"); + reject("teebag.setScheduledEnclave failed"); } else { // Other, CannotLookup, BadOrigin, no extra info console.log(dispatchError.toString()); - reject("updateScheduledEnclave failed"); + reject("teebag.setScheduledEnclave failed"); } } else { - console.log(colors.green("updateScheduledEnclave completed")); - resolve("updateScheduledEnclave done"); + console.log(colors.green("teebag.setScheduledEnclave completed")); + resolve("teebag.setScheduledEnclave done"); } } }); @@ -100,8 +100,8 @@ async function main() { const Alice = keyring.addFromUri("//Alice", { name: "Alice default" }); await transfer(defaultAPI, Alice); - await setTeerexAdmin(defaultAPI, Alice); - await updateScheduledEnclave(defaultAPI, Alice, block); + await teebagSetAdmin(defaultAPI, Alice); + await teebagSetScheduledEnclave(defaultAPI, Alice, block); console.log(colors.green("done")); process.exit(); diff --git a/tee-worker/Cargo.lock b/tee-worker/Cargo.lock index b3a43d3533..fdd91b00d3 100644 --- a/tee-worker/Cargo.lock +++ b/tee-worker/Cargo.lock @@ -4829,7 +4829,6 @@ dependencies = [ "serde_json 1.0.103", "sgx_crypto_helper", "sp-core", - "teerex-primitives", "thiserror 1.0.44", "url 2.4.0", "ws", @@ -4998,6 +4997,7 @@ dependencies = [ "itp-storage", "itp-types", "log 0.4.20", + "pallet-teebag", "parity-scale-codec", "serde_json 1.0.103", "sgx_crypto_helper", @@ -5005,7 +5005,6 @@ dependencies = [ "sgx_urts", "sp-core", "sp-runtime", - "teerex-primitives", "thiserror 1.0.44", ] @@ -5206,7 +5205,6 @@ name = "itp-sgx-runtime-primitives" version = "0.9.0" dependencies = [ "frame-system", - "litentry-primitives", "pallet-balances", "sp-core", "sp-runtime", @@ -5354,10 +5352,10 @@ dependencies = [ "itp-stf-primitives", "itp-stf-state-handler", "itp-storage", - "itp-teerex-storage", "itp-time-utils", "itp-types", "jsonrpc-core 18.0.0 (git+https://github.com/scs/jsonrpc?branch=no_std_v18)", + "lc-teebag-storage", "litentry-primitives", "log 0.4.20", "parity-scale-codec", @@ -5618,6 +5616,7 @@ dependencies = [ "itc-rpc-client", "itp-node-api", "itp-test", + "itp-types", "its-primitives", "its-rpc-handler", "its-storage", @@ -5734,12 +5733,11 @@ name = "its-validateer-fetch" version = "0.9.0" dependencies = [ "derive_more", - "frame-support", "itc-parentchain-test", "itp-ocall-api", - "itp-teerex-storage", "itp-test", "itp-types", + "lc-teebag-storage", "parity-scale-codec", "sp-core", "sp-runtime", @@ -6405,6 +6403,15 @@ dependencies = [ "url 2.4.0", ] +[[package]] +name = "lc-teebag-storage" +version = "0.1.0" +dependencies = [ + "itp-storage", + "itp-types", + "sp-std 5.0.0", +] + [[package]] name = "lc-vc-task-receiver" version = "0.1.0" @@ -7151,6 +7158,7 @@ dependencies = [ "litentry-hex-utils", "log 0.4.20", "pallet-evm 6.0.0-dev (git+https://github.com/integritee-network/frontier.git?branch=bar/polkadot-v0.9.42)", + "pallet-teebag", "parity-scale-codec", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (git+https://github.com/mesalock-linux/rand-sgx?tag=sgx_1.1.3)", @@ -7165,7 +7173,6 @@ dependencies = [ "sp-std 5.0.0", "strum 0.26.1", "strum_macros 0.26.1", - "teerex-primitives", ] [[package]] @@ -7235,7 +7242,6 @@ dependencies = [ "serde 1.0.193", "serde_derive 1.0.193", "serde_json 1.0.103", - "sgx-verify", "sgx_crypto_helper", "sgx_types", "sp-consensus-grandpa", @@ -7243,7 +7249,6 @@ dependencies = [ "sp-keyring", "sp-runtime", "substrate-api-client", - "teerex-primitives", "thiserror 1.0.44", "tokio", "warp", diff --git a/tee-worker/app-libs/parentchain-interface/src/indirect_calls/litentry/scheduled_enclave.rs b/tee-worker/app-libs/parentchain-interface/src/indirect_calls/litentry/scheduled_enclave.rs index f2ae695c9e..5e6069b1a9 100644 --- a/tee-worker/app-libs/parentchain-interface/src/indirect_calls/litentry/scheduled_enclave.rs +++ b/tee-worker/app-libs/parentchain-interface/src/indirect_calls/litentry/scheduled_enclave.rs @@ -21,29 +21,35 @@ use itc_parentchain_indirect_calls_executor::{ IndirectDispatch, }; use itp_stf_primitives::traits::IndirectExecutor; -use itp_types::{MrEnclave, SidechainBlockNumber}; +use itp_types::{MrEnclave, SidechainBlockNumber, WorkerType}; use lc_scheduled_enclave::{ScheduledEnclaveUpdater, GLOBAL_SCHEDULED_ENCLAVE}; -use log::debug; +use log::*; #[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] -pub struct UpdateScheduledEnclaveArgs { +pub struct SetScheduledEnclaveArgs { + worker_type: WorkerType, sbn: codec::Compact, mrenclave: MrEnclave, } impl> - IndirectDispatch for UpdateScheduledEnclaveArgs + IndirectDispatch for SetScheduledEnclaveArgs { type Args = (); fn dispatch(&self, _executor: &Executor, _args: Self::Args) -> Result<()> { - debug!("execute indirect call: UpdateScheduledEnclave, sidechain_block_number: {:?}, mrenclave: {:?}", self.sbn, self.mrenclave); - GLOBAL_SCHEDULED_ENCLAVE.update(self.sbn.into(), self.mrenclave)?; + debug!("execute indirect call: SetScheduledEnclave, worker_type: {:?}, sidechain_block_number: {:?}, mrenclave: {:?}", self.worker_type, self.sbn, self.mrenclave); + if self.worker_type == WorkerType::Identity { + GLOBAL_SCHEDULED_ENCLAVE.update(self.sbn.into(), self.mrenclave)?; + } else { + warn!("Ignore SetScheduledEnclave due to wrong worker_type"); + } Ok(()) } } #[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] pub struct RemoveScheduledEnclaveArgs { + worker_type: WorkerType, sbn: codec::Compact, } @@ -53,10 +59,15 @@ impl> type Args = (); fn dispatch(&self, _executor: &Executor, _args: Self::Args) -> Result<()> { debug!( - "execute indirect call: RemoveScheduledEnclave, sidechain_block_number: {:?}", + "execute indirect call: RemoveScheduledEnclave, worker_type: {:?}, sidechain_block_number: {:?}", + self.worker_type, self.sbn ); - GLOBAL_SCHEDULED_ENCLAVE.remove(self.sbn.into())?; + if self.worker_type == WorkerType::Identity { + GLOBAL_SCHEDULED_ENCLAVE.remove(self.sbn.into())?; + } else { + warn!("Ignore RemoveScheduledEnclave due to wrong worker_type"); + } Ok(()) } } diff --git a/tee-worker/app-libs/parentchain-interface/src/indirect_calls/mod.rs b/tee-worker/app-libs/parentchain-interface/src/indirect_calls/mod.rs index 7b65f61b30..d14caeeb20 100644 --- a/tee-worker/app-libs/parentchain-interface/src/indirect_calls/mod.rs +++ b/tee-worker/app-libs/parentchain-interface/src/indirect_calls/mod.rs @@ -26,7 +26,7 @@ pub use litentry::{ deactivate_identity::DeactivateIdentityArgs, link_identity::LinkIdentityArgs, request_vc::RequestVCArgs, - scheduled_enclave::{RemoveScheduledEnclaveArgs, UpdateScheduledEnclaveArgs}, + scheduled_enclave::{RemoveScheduledEnclaveArgs, SetScheduledEnclaveArgs}, }; pub use shield_funds::ShieldFundsArgs; pub use transfer_to_alice_shields_funds::{TransferToAliceShieldsFundsArgs, ALICE_ACCOUNT_ID}; diff --git a/tee-worker/app-libs/parentchain-interface/src/integritee/mod.rs b/tee-worker/app-libs/parentchain-interface/src/integritee/mod.rs index 5dc036b76a..05803f81ac 100644 --- a/tee-worker/app-libs/parentchain-interface/src/integritee/mod.rs +++ b/tee-worker/app-libs/parentchain-interface/src/integritee/mod.rs @@ -23,7 +23,7 @@ use crate::{ decode_and_log_error, indirect_calls::{ ActivateIdentityArgs, DeactivateIdentityArgs, InvokeArgs, LinkIdentityArgs, - RemoveScheduledEnclaveArgs, RequestVCArgs, ShieldFundsArgs, UpdateScheduledEnclaveArgs, + RemoveScheduledEnclaveArgs, RequestVCArgs, SetScheduledEnclaveArgs, ShieldFundsArgs, }, integritee::extrinsic_parser::ParseExtrinsic, }; @@ -63,7 +63,7 @@ pub enum IndirectCall { #[codec(index = 5)] RequestVC(RequestVCArgs, Option>, H256), #[codec(index = 6)] - UpdateScheduledEnclave(UpdateScheduledEnclaveArgs), + SetScheduledEnclave(SetScheduledEnclaveArgs), #[codec(index = 7)] RemoveScheduledEnclave(RemoveScheduledEnclaveArgs), #[codec(index = 8)] @@ -88,7 +88,7 @@ impl> activate_identity.dispatch(executor, (address.clone(), *hash)), IndirectCall::RequestVC(request_vc, address, hash) => request_vc.dispatch(executor, (address.clone(), *hash)), - IndirectCall::UpdateScheduledEnclave(update_enclave_args) => + IndirectCall::SetScheduledEnclave(update_enclave_args) => update_enclave_args.dispatch(executor, ()), IndirectCall::RemoveScheduledEnclave(remove_enclave_args) => remove_enclave_args.dispatch(executor, ()), @@ -143,11 +143,7 @@ where "[ShieldFundsAndInvokeFilter] attempting to execute indirect call with index {:?}", index ); - if index == metadata.shield_funds_call_indexes().ok()? { - log::debug!("executing shield funds call"); - let args = decode_and_log_error::(call_args)?; - Some(IndirectCall::ShieldFunds(args)) - } else if index == metadata.invoke_call_indexes().ok()? { + if index == metadata.post_opaque_task_call_indexes().ok()? { log::debug!("executing invoke call"); let args = decode_and_log_error::(call_args)?; Some(IndirectCall::Invoke(args)) @@ -168,10 +164,10 @@ where let args = decode_and_log_error::(call_args)?; let hashed_extrinsic = xt.hashed_extrinsic; Some(IndirectCall::RequestVC(args, address, hashed_extrinsic)) - } else if index == metadata.update_scheduled_enclave().ok()? { - let args = decode_and_log_error::(call_args)?; - Some(IndirectCall::UpdateScheduledEnclave(args)) - } else if index == metadata.remove_scheduled_enclave().ok()? { + } else if index == metadata.set_scheduled_enclave_call_indexes().ok()? { + let args = decode_and_log_error::(call_args)?; + Some(IndirectCall::SetScheduledEnclave(args)) + } else if index == metadata.remove_scheduled_enclave_call_indexes().ok()? { let args = decode_and_log_error::(call_args)?; Some(IndirectCall::RemoveScheduledEnclave(args)) } else if index == metadata.batch_all_call_indexes().ok()? { @@ -193,10 +189,7 @@ fn parse_batch_all( log::debug!("Received BatchAll including {} calls", call_count.len()); for _i in 0..call_count.len() { let index: CallIndex = Decode::decode(call_args).ok()?; - if index == metadata.shield_funds_call_indexes().ok()? { - let args = decode_and_log_error::(call_args)?; - calls.push(IndirectCall::ShieldFunds(args)) - } else if index == metadata.invoke_call_indexes().ok()? { + if index == metadata.post_opaque_task_call_indexes().ok()? { let args = decode_and_log_error::(call_args)?; calls.push(IndirectCall::Invoke(args)) } else if index == metadata.link_identity_call_indexes().ok()? { @@ -215,10 +208,10 @@ fn parse_batch_all( let args = decode_and_log_error::(call_args)?; let hashed_extrinsic = hash; calls.push(IndirectCall::RequestVC(args, address.clone(), hashed_extrinsic)) - } else if index == metadata.update_scheduled_enclave().ok()? { - let args = decode_and_log_error::(call_args)?; - calls.push(IndirectCall::UpdateScheduledEnclave(args)) - } else if index == metadata.remove_scheduled_enclave().ok()? { + } else if index == metadata.set_scheduled_enclave_call_indexes().ok()? { + let args = decode_and_log_error::(call_args)?; + calls.push(IndirectCall::SetScheduledEnclave(args)) + } else if index == metadata.remove_scheduled_enclave_call_indexes().ok()? { let args = decode_and_log_error::(call_args)?; calls.push(IndirectCall::RemoveScheduledEnclave(args)) } diff --git a/tee-worker/app-libs/sgx-runtime/src/lib.rs b/tee-worker/app-libs/sgx-runtime/src/lib.rs index 0c2c5f715a..8130ab5e44 100644 --- a/tee-worker/app-libs/sgx-runtime/src/lib.rs +++ b/tee-worker/app-libs/sgx-runtime/src/lib.rs @@ -57,8 +57,7 @@ use sp_version::RuntimeVersion; pub use itp_sgx_runtime_primitives::{ constants::SLOT_DURATION, types::{ - AccountData, AccountId, Address, Balance, BlockNumber, ConvertAccountId, Hash, Header, - Index, SgxParentchainTypeConverter, Signature, + AccountData, AccountId, Address, Balance, BlockNumber, Hash, Header, Index, Signature, }, }; diff --git a/tee-worker/app-libs/stf/src/trusted_call.rs b/tee-worker/app-libs/stf/src/trusted_call.rs index d18f18dd86..725e8ee2fa 100644 --- a/tee-worker/app-libs/stf/src/trusted_call.rs +++ b/tee-worker/app-libs/stf/src/trusted_call.rs @@ -43,7 +43,7 @@ pub use ita_sgx_runtime::{Balance, IDGraph, Index, Runtime, System}; use itp_node_api::metadata::{provider::AccessNodeMetadata, NodeMetadataTrait}; use itp_node_api_metadata::{ pallet_balances::BalancesCallIndexes, pallet_imp::IMPCallIndexes, - pallet_proxy::ProxyCallIndexes, pallet_teerex::TeerexCallIndexes, pallet_vcmp::VCMPCallIndexes, + pallet_proxy::ProxyCallIndexes, pallet_vcmp::VCMPCallIndexes, }; use itp_stf_interface::{ExecuteCall, SHARD_VAULT_KEY}; pub use itp_stf_primitives::{ @@ -377,7 +377,6 @@ where node_metadata_repo: Arc, ) -> Result { let sender = self.call.sender_identity().clone(); - let call_hash = blake2_256(&self.call.encode()); let account_id: AccountId = sender.to_account_id().ok_or(Self::Error::InvalidAccount)?; let system_nonce = System::account_nonce(&account_id); ensure!(self.nonce == system_nonce, Self::Error::InvalidNonce(self.nonce, system_nonce)); @@ -524,16 +523,7 @@ where debug!("balance_shield({}, {})", account_id_to_string(&who), value); shield_funds(who, value)?; - // Send proof of execution on chain. - calls.push(ParentchainCall::Litentry(OpaqueCall::from_tuple(&( - node_metadata_repo - .get_from_metadata(|m| m.publish_hash_call_indexes()) - .map_err(|_| StfError::InvalidMetadata)? - .map_err(|_| StfError::InvalidMetadata)?, - call_hash, - Vec::::new(), - b"shielded some funds!".to_vec(), - )))); + // Litentry: we don't have publish_hash call in teebag Ok(TrustedCallResult::Empty) }, #[cfg(feature = "evm")] diff --git a/tee-worker/cli/lit_parentchain_nonce.sh b/tee-worker/cli/lit_parentchain_nonce.sh index 34c6419892..a89eaef9db 100755 --- a/tee-worker/cli/lit_parentchain_nonce.sh +++ b/tee-worker/cli/lit_parentchain_nonce.sh @@ -62,7 +62,7 @@ ${CLIENT} trusted --mrenclave $MRENCLAVE --direct send-erroneous-parentchain-cal echo "" sleep 20 -# wait for 10 `ProcessedParentchainBlock` events, which should take around 2 min (1 worker) +# wait for 10 `ParentchainBlockProcessed` events, which should take around 2 min (1 worker) # if the incoming parentchain extrinsic is blocked (due to the wrong nonce), there won't be # such many events. set -e diff --git a/tee-worker/cli/src/base_cli/commands/listen.rs b/tee-worker/cli/src/base_cli/commands/listen.rs index 27a9b15811..734ffb9af8 100644 --- a/tee-worker/cli/src/base_cli/commands/listen.rs +++ b/tee-worker/cli/src/base_cli/commands/listen.rs @@ -73,70 +73,55 @@ impl ListenCommand { }, } }, - RuntimeEvent::Teerex(ee) => { - println!(">>>>>>>>>> integritee teerex event: {:?}", ee); + RuntimeEvent::Teebag(ee) => { + println!(">>>>>>>>>> litentry teebag event: {:?}", ee); count += 1; match &ee { - my_node_runtime::pallet_teerex::Event::AddedEnclave( - accountid, + my_node_runtime::pallet_teebag::Event::EnclaveAdded { + who, + worker_type, url, - ) => { + } => { println!( - "AddedEnclave: {:?} at url {}", - accountid, + "EnclaveAdded: {:?} [{:?}] at url {}", + who, + worker_type, String::from_utf8(url.to_vec()) .unwrap_or_else(|_| "error".to_string()) ); }, - my_node_runtime::pallet_teerex::Event::RemovedEnclave( - accountid, - ) => { - println!("RemovedEnclave: {:?}", accountid); + my_node_runtime::pallet_teebag::Event::EnclaveRemoved { + who, + } => { + println!("EnclaveRemoved: {:?}", who); }, - my_node_runtime::pallet_teerex::Event::Forwarded(shard) => { + my_node_runtime::pallet_teebag::Event::OpaqueTaskPosted { shard } => { println!( - "Forwarded request for shard {}", + "OpaqueTaskPosted for shard {}", shard.encode().to_base58() ); }, - my_node_runtime::pallet_teerex::Event::ProcessedParentchainBlock( - accountid, - block_hash, - merkle_root, + my_node_runtime::pallet_teebag::Event::ParentchainBlockProcessed { + who, block_number, - ) => { + block_hash, + task_merkle_root, + } => { println!( - "ProcessedParentchainBlock from {} with hash {:?}, number {} and merkle root {:?}", - accountid, block_hash, merkle_root, block_number + "ParentchainBlockProcessed from {} with hash {:?}, number {} and merkle root {:?}", + who, block_hash, block_number, task_merkle_root ); }, - my_node_runtime::pallet_teerex::Event::ShieldFunds( - incognito_account, - ) => { - println!("ShieldFunds for {:?}", incognito_account); - }, - my_node_runtime::pallet_teerex::Event::UnshieldedFunds( - public_account, - ) => { - println!("UnshieldFunds for {:?}", public_account); - }, - _ => debug!("ignoring unsupported teerex event: {:?}", ee), - } - }, - RuntimeEvent::Sidechain(ee) => { - println!(">>>>>>>>>> integritee sidechain event: {:?}", ee); - count += 1; - match &ee { - my_node_runtime::pallet_sidechain::Event::ProposedSidechainBlock( - accountid, - block_hash, - ) => { + my_node_runtime::pallet_teebag::Event::SidechainBlockFinalized { + who, + sidechain_block_number, + } => { println!( - "ProposedSidechainBlock from {} with hash {:?}", - accountid, block_hash + "SidechainBlockFinalized from {} with number {:?}", + who, sidechain_block_number ); }, - _ => debug!("ignoring unsupported sidechain event: {:?}", ee), + _ => debug!("ignoring unsupported teebag event: {:?}", ee), } }, _ => debug!("ignoring unsupported module event: {:?}", evr.event), diff --git a/tee-worker/cli/src/base_cli/mod.rs b/tee-worker/cli/src/base_cli/mod.rs index 7270dd8dbb..a42888e4bf 100644 --- a/tee-worker/cli/src/base_cli/mod.rs +++ b/tee-worker/cli/src/base_cli/mod.rs @@ -35,7 +35,8 @@ use base58::ToBase58; use chrono::{DateTime, Utc}; use clap::Subcommand; use itc_rpc_client::direct_client::DirectApi; -use itp_node_api::api_client::PalletTeerexApi; +use itp_node_api::api_client::PalletTeebagApi; +use itp_types::WorkerType; use sp_core::crypto::Ss58Codec; use sp_keystore::Keystore; use std::{ @@ -178,29 +179,22 @@ fn print_sgx_metadata_raw(cli: &Cli) -> CliResult { fn list_workers(cli: &Cli) -> CliResult { let api = get_chain_api(cli); - let wcount = api.enclave_count(None).unwrap(); - println!("number of workers registered: {}", wcount); - - let mut mr_enclaves = Vec::with_capacity(wcount as usize); - - for w in 1..=wcount { - let enclave = api.enclave(w, None).unwrap(); - if enclave.is_none() { - println!("error reading enclave data"); - continue - }; - let enclave = enclave.unwrap(); - let timestamp = - DateTime::::from(UNIX_EPOCH + Duration::from_millis(enclave.timestamp)); - let mr_enclave = enclave.mr_enclave.to_base58(); - println!("Enclave {}", w); - println!(" AccountId: {}", enclave.pubkey.to_ss58check()); - println!(" MRENCLAVE: {}", mr_enclave); - println!(" RA timestamp: {}", timestamp); - println!(" URL: {}", enclave.url); - - mr_enclaves.push(mr_enclave); - } + let enclaves = api.all_enclaves(WorkerType::Identity, None).unwrap(); + println!("number of enclaves registered: {}", enclaves.len()); + + let mr_enclaves = enclaves + .iter() + .map(|enclave| { + println!("Enclave"); + println!(" MRENCLAVE: {}", enclave.mrenclave.to_base58()); + let timestamp = DateTime::::from( + UNIX_EPOCH + Duration::from_millis(enclave.last_seen_timestamp), + ); + println!(" Last seen: {}", timestamp); + println!(" URL: {}", String::from_utf8_lossy(enclave.url.as_slice())); + enclave.mrenclave.to_base58() + }) + .collect(); Ok(CliResultOk::MrEnclaveBase58 { mr_enclaves }) } diff --git a/tee-worker/client-api/parachain-api/prepare-build/interfaces/sidechain/definitions.ts b/tee-worker/client-api/parachain-api/prepare-build/interfaces/sidechain/definitions.ts index c111ab837b..86364ad00c 100644 --- a/tee-worker/client-api/parachain-api/prepare-build/interfaces/sidechain/definitions.ts +++ b/tee-worker/client-api/parachain-api/prepare-build/interfaces/sidechain/definitions.ts @@ -79,7 +79,6 @@ export default { NoEligibleIdentity: "Null", }, }, - // teerex ShardIdentifier: "H256", }, }; diff --git a/tee-worker/core-primitives/enclave-api/Cargo.toml b/tee-worker/core-primitives/enclave-api/Cargo.toml index c9dfaa9dff..b0541b1136 100644 --- a/tee-worker/core-primitives/enclave-api/Cargo.toml +++ b/tee-worker/core-primitives/enclave-api/Cargo.toml @@ -26,7 +26,7 @@ itp-storage = { path = "../storage" } itp-types = { path = "../types" } # litentry -teerex-primitives = { path = "../../../primitives/teerex", default-features = false } +pallet-teebag = { path = "../../../pallets/teebag", default-features = false } [features] default = [] diff --git a/tee-worker/core-primitives/enclave-api/src/enclave_base.rs b/tee-worker/core-primitives/enclave-api/src/enclave_base.rs index 4e79a6f902..b0f9dcb047 100644 --- a/tee-worker/core-primitives/enclave-api/src/enclave_base.rs +++ b/tee-worker/core-primitives/enclave-api/src/enclave_base.rs @@ -21,9 +21,9 @@ use codec::Decode; use core::fmt::Debug; use itc_parentchain::primitives::{ParentchainId, ParentchainInitParams}; use itp_types::ShardIdentifier; +use pallet_teebag::EnclaveFingerprint; use sgx_crypto_helper::rsa3072::Rsa3072PubKey; use sp_core::ed25519; -use teerex_primitives::EnclaveFingerprint; /// Trait for base/common Enclave API functions pub trait EnclaveBase: Send + Sync + 'static { @@ -97,10 +97,10 @@ mod impl_ffi { }; use itp_types::ShardIdentifier; use log::*; + use pallet_teebag::EnclaveFingerprint; use sgx_crypto_helper::rsa3072::Rsa3072PubKey; use sgx_types::*; use sp_core::ed25519; - use teerex_primitives::EnclaveFingerprint; impl EnclaveBase for Enclave { fn init( diff --git a/tee-worker/core-primitives/enclave-api/src/remote_attestation.rs b/tee-worker/core-primitives/enclave-api/src/remote_attestation.rs index 9aa32cb631..30a765da32 100644 --- a/tee-worker/core-primitives/enclave-api/src/remote_attestation.rs +++ b/tee-worker/core-primitives/enclave-api/src/remote_attestation.rs @@ -18,8 +18,8 @@ use crate::EnclaveResult; use itp_types::ShardIdentifier; +use pallet_teebag::Fmspc; use sgx_types::*; -use teerex_primitives::Fmspc; /// Struct that unites all relevant data reported by the QVE pub struct QveReport { @@ -128,8 +128,8 @@ mod impl_ffi { use itp_settings::worker::EXTRINSIC_MAX_SIZE; use itp_types::ShardIdentifier; use log::*; + use pallet_teebag::Fmspc; use sgx_types::*; - use teerex_primitives::Fmspc; const OS_SYSTEM_PATH: &str = "/usr/lib/x86_64-linux-gnu/"; const C_STRING_ENDING: &str = "\0"; diff --git a/tee-worker/core-primitives/node-api/api-client-extensions/src/lib.rs b/tee-worker/core-primitives/node-api/api-client-extensions/src/lib.rs index 2829b53c1c..e6e7c3757e 100644 --- a/tee-worker/core-primitives/node-api/api-client-extensions/src/lib.rs +++ b/tee-worker/core-primitives/node-api/api-client-extensions/src/lib.rs @@ -21,12 +21,17 @@ pub use substrate_api_client::{api::Error as ApiClientError, rpc::TungsteniteRpc pub mod account; pub mod chain; -pub mod pallet_teeracle; +pub mod pallet_teebag; + +// TODO: part of P-487 - these will be removed anyway so I haven't spent time adjust them + +// pub mod pallet_teeracle; pub mod pallet_teerex; pub use account::*; pub use chain::*; -pub use pallet_teeracle::*; +pub use pallet_teebag::*; +// pub use pallet_teeracle::*; pub use pallet_teerex::*; pub type ApiResult = Result; diff --git a/tee-worker/core-primitives/node-api/api-client-extensions/src/pallet_teebag.rs b/tee-worker/core-primitives/node-api/api-client-extensions/src/pallet_teebag.rs new file mode 100644 index 0000000000..e243091ca5 --- /dev/null +++ b/tee-worker/core-primitives/node-api/api-client-extensions/src/pallet_teebag.rs @@ -0,0 +1,134 @@ +// 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 . + +use crate::ApiResult; +use itp_api_client_types::{traits::GetStorage, Api, Config, Request}; +use itp_types::{AccountId, Enclave, ShardIdentifier, WorkerType}; + +pub const TEEBAG: &str = "Teebag"; + +/// ApiClient extension that enables communication with the `teebag` pallet. +pub trait PalletTeebagApi { + type Hash; + + fn enclave( + &self, + account: &AccountId, + at_block: Option, + ) -> ApiResult>; + fn enclave_count( + &self, + worker_type: WorkerType, + at_block: Option, + ) -> ApiResult; + fn primary_enclave_identifier_for_shard( + &self, + worker_type: WorkerType, + shard: &ShardIdentifier, + at_block: Option, + ) -> ApiResult>; + fn primary_enclave_for_shard( + &self, + worker_type: WorkerType, + shard: &ShardIdentifier, + at_block: Option, + ) -> ApiResult>; + fn all_enclaves( + &self, + worker_type: WorkerType, + at_block: Option, + ) -> ApiResult>; +} + +impl PalletTeebagApi for Api +where + RuntimeConfig: Config, + Client: Request, +{ + type Hash = RuntimeConfig::Hash; + + fn enclave( + &self, + account: &AccountId, + at_block: Option, + ) -> ApiResult> { + self.get_storage_map(TEEBAG, "EnclaveRegistry", account, at_block) + } + + fn enclave_count( + &self, + worker_type: WorkerType, + at_block: Option, + ) -> ApiResult { + // Vec<> and BoundedVec<> have the same encoding, thus they are used interchangeably + let identifiers: Vec = self + .get_storage_map(TEEBAG, "EnclaveIdentifier", worker_type, at_block)? + .unwrap_or_default(); + Ok(identifiers.len() as u64) + } + + // please note we don't use dedicated on-chain storage for this (like the upstream `WorkerForShard`) + // so this API will always return the "first" registered and qualified enclave. + // Wheter it meets our needs needs to be further evaluated + fn primary_enclave_identifier_for_shard( + &self, + worker_type: WorkerType, + shard: &ShardIdentifier, + at_block: Option, + ) -> ApiResult> { + let identifiers: Vec = self + .get_storage_map(TEEBAG, "EnclaveIdentifier", worker_type, at_block)? + .unwrap_or_default(); + let mut maybe_account: Option = None; + for account in identifiers { + match self.enclave(&account, at_block)? { + Some(e) => + if e.mrenclave == shard.as_ref() { + maybe_account = Some(account.clone()); + break + }, + None => continue, + } + } + Ok(maybe_account) + } + + fn primary_enclave_for_shard( + &self, + worker_type: WorkerType, + shard: &ShardIdentifier, + at_block: Option, + ) -> ApiResult> { + self.primary_enclave_identifier_for_shard(worker_type, shard, at_block)? + .map_or_else(|| Ok(None), |account| self.enclave(&account, at_block)) + } + + fn all_enclaves( + &self, + worker_type: WorkerType, + at_block: Option, + ) -> ApiResult> { + let identifiers: Vec = self + .get_storage_map(TEEBAG, "EnclaveIdentifier", worker_type, at_block)? + .unwrap_or_default(); + + let enclaves = identifiers + .into_iter() + .filter_map(|account| self.enclave(&account, at_block).ok()?) + .collect(); + Ok(enclaves) + } +} diff --git a/tee-worker/core-primitives/node-api/metadata/src/lib.rs b/tee-worker/core-primitives/node-api/metadata/src/lib.rs index 0a069c0277..956255578d 100644 --- a/tee-worker/core-primitives/node-api/metadata/src/lib.rs +++ b/tee-worker/core-primitives/node-api/metadata/src/lib.rs @@ -21,9 +21,9 @@ use crate::{ error::Result, pallet_balances::BalancesCallIndexes, pallet_imp::IMPCallIndexes, - pallet_proxy::ProxyCallIndexes, pallet_sidechain::SidechainCallIndexes, - pallet_system::SystemSs58Prefix, pallet_teerex::TeerexCallIndexes, - pallet_utility::UtilityCallIndexes, pallet_vcmp::VCMPCallIndexes, + pallet_proxy::ProxyCallIndexes, pallet_system::SystemSs58Prefix, + pallet_teebag::TeebagCallIndexes, pallet_utility::UtilityCallIndexes, + pallet_vcmp::VCMPCallIndexes, }; use codec::{Decode, Encode}; use sp_core::storage::StorageKey; @@ -35,10 +35,8 @@ pub mod error; pub mod pallet_balances; pub mod pallet_imp; pub mod pallet_proxy; -pub mod pallet_sidechain; pub mod pallet_system; -pub mod pallet_teeracle; -pub mod pallet_teerex; +pub mod pallet_teebag; pub mod pallet_utility; pub mod pallet_vcmp; pub mod runtime_call; @@ -47,8 +45,7 @@ pub mod runtime_call; pub mod metadata_mocks; pub trait NodeMetadataTrait: - TeerexCallIndexes - + SidechainCallIndexes + TeebagCallIndexes + IMPCallIndexes + VCMPCallIndexes + SystemSs58Prefix @@ -57,9 +54,9 @@ pub trait NodeMetadataTrait: + BalancesCallIndexes { } + impl< - T: TeerexCallIndexes - + SidechainCallIndexes + T: TeebagCallIndexes + IMPCallIndexes + VCMPCallIndexes + SystemSs58Prefix diff --git a/tee-worker/core-primitives/node-api/metadata/src/metadata_mocks.rs b/tee-worker/core-primitives/node-api/metadata/src/metadata_mocks.rs index cdf24e4fcc..458e893759 100644 --- a/tee-worker/core-primitives/node-api/metadata/src/metadata_mocks.rs +++ b/tee-worker/core-primitives/node-api/metadata/src/metadata_mocks.rs @@ -1,7 +1,7 @@ /* Copyright 2021 Integritee AG and Supercomputing Systems AG - Licensed under the Apache License, Version 2.0 (the "License"); + Licensed under the Apache License, Version 2.0 (the "License); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -17,9 +17,9 @@ use crate::{ error::Result, pallet_balances::BalancesCallIndexes, pallet_imp::IMPCallIndexes, - pallet_proxy::ProxyCallIndexes, pallet_sidechain::SidechainCallIndexes, - pallet_system::SystemSs58Prefix, pallet_teerex::TeerexCallIndexes, - pallet_utility::UtilityCallIndexes, pallet_vcmp::VCMPCallIndexes, runtime_call::RuntimeCall, + pallet_proxy::ProxyCallIndexes, pallet_system::SystemSs58Prefix, + pallet_teebag::TeebagCallIndexes, pallet_utility::UtilityCallIndexes, + pallet_vcmp::VCMPCallIndexes, runtime_call::RuntimeCall, }; use codec::{Decode, Encode}; @@ -35,23 +35,18 @@ impl TryFrom for Metadata { #[derive(Default, Encode, Decode, Debug, Clone)] pub struct NodeMetadataMock { - teerex_module: u8, + // litentry + // teebag + teebag_module: u8, + set_scheduled_enclave: u8, + remove_scheduled_enclave: u8, register_enclave: u8, - unregister_sovereign_enclave: u8, - unregister_proxied_enclave: u8, + unregister_enclave: u8, register_quoting_enclave: u8, register_tcb_info: u8, - enclave_bridge_module: u8, - invoke: u8, - confirm_processed_parentchain_block: u8, - shield_funds: u8, - unshield_funds: u8, - publish_hash: u8, - update_shard_config: u8, - sidechain_module: u8, - // litentry - update_scheduled_enclave: u8, - remove_scheduled_enclave: u8, + post_opaque_task: u8, + parentchain_block_processed: u8, + sidechain_block_imported: u8, // IMP imp_module: u8, imp_link_identity: u8, @@ -76,7 +71,6 @@ pub struct NodeMetadataMock { utility_dispatch_as: u8, utility_force_batch: u8, - imported_sidechain_block: u8, proxy_module: u8, add_proxy: u8, proxy: u8, @@ -91,23 +85,17 @@ pub struct NodeMetadataMock { impl NodeMetadataMock { pub fn new() -> Self { NodeMetadataMock { - teerex_module: 50u8, - register_enclave: 0u8, - unregister_sovereign_enclave: 1u8, - unregister_proxied_enclave: 2u8, - register_quoting_enclave: 3, - register_tcb_info: 4, - enclave_bridge_module: 54u8, - invoke: 0u8, - confirm_processed_parentchain_block: 1u8, - shield_funds: 2u8, - unshield_funds: 3u8, - publish_hash: 4u8, - update_shard_config: 5u8, - sidechain_module: 53u8, // litentry - update_scheduled_enclave: 10u8, - remove_scheduled_enclave: 11u8, + teebag_module: 50u8, + set_scheduled_enclave: 0u8, + remove_scheduled_enclave: 1u8, + register_enclave: 2u8, + unregister_enclave: 3u8, + register_quoting_enclave: 4u8, + register_tcb_info: 5u8, + post_opaque_task: 6u8, + parentchain_block_processed: 7u8, + sidechain_block_imported: 8u8, imp_module: 64u8, imp_link_identity: 1u8, @@ -132,7 +120,6 @@ impl NodeMetadataMock { utility_dispatch_as: 3u8, utility_force_batch: 4u8, - imported_sidechain_block: 0u8, proxy_module: 7u8, add_proxy: 1u8, proxy: 0u8, @@ -146,63 +133,33 @@ impl NodeMetadataMock { } } -impl TeerexCallIndexes for NodeMetadataMock { - fn register_enclave_call_indexes(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.register_enclave]) +impl TeebagCallIndexes for NodeMetadataMock { + fn set_scheduled_enclave_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.teebag_module, self.set_scheduled_enclave]) } - - fn unregister_sovereign_enclave_call_indexes(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.unregister_sovereign_enclave]) + fn remove_scheduled_enclave_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.teebag_module, self.remove_scheduled_enclave]) } - - fn unregister_proxied_enclave_call_indexes(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.unregister_proxied_enclave]) + fn register_enclave_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.teebag_module, self.register_enclave]) + } + fn unregister_enclave_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.teebag_module, self.unregister_enclave]) } - fn register_quoting_enclave_call_indexes(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.register_quoting_enclave]) + Ok([self.teebag_module, self.register_quoting_enclave]) } - fn register_tcb_info_call_indexes(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.register_tcb_info]) - } - - fn invoke_call_indexes(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.invoke]) + Ok([self.teebag_module, self.register_tcb_info]) } - - fn confirm_processed_parentchain_block_call_indexes(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.confirm_processed_parentchain_block]) - } - - fn shield_funds_call_indexes(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.shield_funds]) + fn post_opaque_task_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.teebag_module, self.post_opaque_task]) } - - fn unshield_funds_call_indexes(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.unshield_funds]) + fn parentchain_block_processed_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.teebag_module, self.parentchain_block_processed]) } - - fn publish_hash_call_indexes(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.publish_hash]) - } - - // fn update_shard_config_call_indexes(&self) -> Result<[u8; 2]> { - // Ok([self.teerex_module, self.update_shard_config]) - // } - - fn update_scheduled_enclave(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.update_scheduled_enclave]) - } - - fn remove_scheduled_enclave(&self) -> Result<[u8; 2]> { - Ok([self.teerex_module, self.remove_scheduled_enclave]) - } -} - -impl SidechainCallIndexes for NodeMetadataMock { - fn confirm_imported_sidechain_block_indexes(&self) -> Result<[u8; 2]> { - Ok([self.sidechain_module, self.imported_sidechain_block]) + fn sidechain_block_imported_call_indexes(&self) -> Result<[u8; 2]> { + Ok([self.teebag_module, self.sidechain_block_imported]) } } diff --git a/tee-worker/core-primitives/node-api/metadata/src/pallet_teebag.rs b/tee-worker/core-primitives/node-api/metadata/src/pallet_teebag.rs new file mode 100644 index 0000000000..0dc73cfb25 --- /dev/null +++ b/tee-worker/core-primitives/node-api/metadata/src/pallet_teebag.rs @@ -0,0 +1,71 @@ +/* + Copyright 2021 Integritee AG and Supercomputing Systems AG + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ +use crate::{error::Result, NodeMetadata}; + +/// Pallet' name: +pub const TEEBAG: &str = "Teebag"; + +// we only list the extrinsics that we care +pub trait TeebagCallIndexes { + fn set_scheduled_enclave_call_indexes(&self) -> Result<[u8; 2]>; + + fn remove_scheduled_enclave_call_indexes(&self) -> Result<[u8; 2]>; + + fn register_enclave_call_indexes(&self) -> Result<[u8; 2]>; + + fn unregister_enclave_call_indexes(&self) -> Result<[u8; 2]>; + + fn register_quoting_enclave_call_indexes(&self) -> Result<[u8; 2]>; + + fn register_tcb_info_call_indexes(&self) -> Result<[u8; 2]>; + + fn post_opaque_task_call_indexes(&self) -> Result<[u8; 2]>; + + fn parentchain_block_processed_call_indexes(&self) -> Result<[u8; 2]>; + + fn sidechain_block_imported_call_indexes(&self) -> Result<[u8; 2]>; +} + +impl TeebagCallIndexes for NodeMetadata { + fn set_scheduled_enclave_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(TEEBAG, "set_scheduled_enclave") + } + fn remove_scheduled_enclave_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(TEEBAG, "remove_scheduled_enclave") + } + fn register_enclave_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(TEEBAG, "register_enclave") + } + fn unregister_enclave_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(TEEBAG, "unregister_enclave") + } + fn register_quoting_enclave_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(TEEBAG, "register_quoting_enclave") + } + fn register_tcb_info_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(TEEBAG, "register_tcb_info") + } + fn post_opaque_task_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(TEEBAG, "post_opaque_task") + } + fn parentchain_block_processed_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(TEEBAG, "parentchain_block_processed") + } + fn sidechain_block_imported_call_indexes(&self) -> Result<[u8; 2]> { + self.call_indexes(TEEBAG, "sidechain_block_imported") + } +} diff --git a/tee-worker/core-primitives/sgx-runtime-primitives/Cargo.toml b/tee-worker/core-primitives/sgx-runtime-primitives/Cargo.toml index 8ec87045fa..5290e8da32 100644 --- a/tee-worker/core-primitives/sgx-runtime-primitives/Cargo.toml +++ b/tee-worker/core-primitives/sgx-runtime-primitives/Cargo.toml @@ -12,9 +12,6 @@ pallet-balances = { default-features = false, git = "https://github.com/parityte sp-core = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -# litentry -litentry-primitives = { path = "../../litentry/primitives", default-features = false } - [features] default = ["std"] std = [ @@ -22,6 +19,4 @@ std = [ "pallet-balances/std", "sp-core/std", "sp-runtime/std", - # litentry - "litentry-primitives/std", ] diff --git a/tee-worker/core-primitives/sgx-runtime-primitives/src/types.rs b/tee-worker/core-primitives/sgx-runtime-primitives/src/types.rs index bad667791e..035ae982b8 100644 --- a/tee-worker/core-primitives/sgx-runtime-primitives/src/types.rs +++ b/tee-worker/core-primitives/sgx-runtime-primitives/src/types.rs @@ -21,8 +21,6 @@ use sp_runtime::{ MultiSignature, OpaqueExtrinsic, }; -use litentry_primitives::ParentchainAccountId; - /// The address format for describing accounts. pub type Address = sp_runtime::MultiAddress; /// Block header type as expected by this sgx-runtime. @@ -66,21 +64,3 @@ pub type Block = BlockG; pub type SignedBlock = SignedBlockG; pub type BlockHash = sp_core::H256; pub type ShardIdentifier = sp_core::H256; - -// litentry -pub trait ConvertAccountId { - type Input; - type Output; - fn convert(input: Self::Input) -> Self::Output; -} - -pub struct SgxParentchainTypeConverter; - -impl ConvertAccountId for SgxParentchainTypeConverter { - type Input = AccountId; - type Output = ParentchainAccountId; - fn convert(a: AccountId) -> ParentchainAccountId { - // it's an identity converter - a as ParentchainAccountId - } -} diff --git a/tee-worker/core-primitives/test/Cargo.toml b/tee-worker/core-primitives/test/Cargo.toml index ff82183e77..92466e8615 100644 --- a/tee-worker/core-primitives/test/Cargo.toml +++ b/tee-worker/core-primitives/test/Cargo.toml @@ -29,12 +29,12 @@ itp-stf-interface = { path = "../stf-interface", default-features = false } itp-stf-primitives = { path = "../stf-primitives", default-features = false } itp-stf-state-handler = { path = "../stf-state-handler", default-features = false } itp-storage = { path = "../storage", default-features = false } -itp-teerex-storage = { path = "../teerex-storage", default-features = false } itp-time-utils = { path = "../time-utils", default-features = false } itp-types = { path = "../types", default-features = false, features = ["test"] } # litentry hex = { version = "0.4.3", default-features = false } +lc-teebag-storage = { path = "../../litentry/core/teebag-storage", default-features = false } litentry-primitives = { path = "../../litentry/primitives", default-features = false } [features] @@ -50,7 +50,6 @@ std = [ "itp-stf-primitives/std", "itp-stf-state-handler/std", "itp-storage/std", - "itp-teerex-storage/std", "itp-time-utils/std", "itp-types/std", "log/std", @@ -59,6 +58,7 @@ std = [ "sp-runtime/std", "sp-std/std", "litentry-primitives/std", + "lc-teebag-storage/std", ] sgx = [ "itp-node-api/sgx", diff --git a/tee-worker/core-primitives/test/src/mock/onchain_mock.rs b/tee-worker/core-primitives/test/src/mock/onchain_mock.rs index 22744289b5..a0163f8df0 100644 --- a/tee-worker/core-primitives/test/src/mock/onchain_mock.rs +++ b/tee-worker/core-primitives/test/src/mock/onchain_mock.rs @@ -23,14 +23,14 @@ use itp_ocall_api::{ EnclaveSidechainOCallApi, }; use itp_storage::Error::StorageValueUnavailable; -use itp_teerex_storage::{TeeRexStorage, TeerexStorageKeys}; use itp_types::{ - parentchain::ParentchainId, storage::StorageEntryVerified, BlockHash, Enclave, ShardIdentifier, - WorkerRequest, WorkerResponse, + parentchain::ParentchainId, storage::StorageEntryVerified, AccountId, BlockHash, + ShardIdentifier, WorkerRequest, WorkerResponse, WorkerType, }; +use lc_teebag_storage::{TeebagStorage, TeebagStorageKeys}; use sgx_types::*; use sp_core::H256; -use sp_runtime::{traits::Header as HeaderTrait, AccountId32, OpaqueExtrinsic}; +use sp_runtime::{traits::Header as HeaderTrait, OpaqueExtrinsic}; use sp_std::prelude::*; use std::{collections::HashMap, string::String}; @@ -55,11 +55,15 @@ impl OnchainMock { pub fn add_validateer_set>( mut self, header: &Header, - set: Option>, + set: Option>, ) -> Self { - let set = set.unwrap_or_else(validateer_set); - self.insert_at_header(header, TeeRexStorage::enclave_count(), (set.len() as u64).encode()); - self.with_storage_entries_at_header(header, into_key_value_storage(set)) + let set: Vec = set.unwrap_or_else(validateer_set); + self.insert_at_header( + header, + TeebagStorage::enclave_identifier(WorkerType::Identity), + set.encode(), + ); + self } pub fn with_mr_enclave(mut self, mr_enclave: [u8; SGX_HASH_SIZE]) -> Self { @@ -224,20 +228,11 @@ impl EnclaveOnChainOCallApi for OnchainMock { } } -pub fn validateer_set() -> Vec { - let default_enclave = Enclave::new( - AccountId32::from([0; 32]), - Default::default(), - Default::default(), - Default::default(), - ); - vec![default_enclave.clone(), default_enclave.clone(), default_enclave.clone(), default_enclave] -} - -fn into_key_value_storage(validateers: Vec) -> Vec<(Vec, Enclave)> { - validateers - .into_iter() - .enumerate() - .map(|(i, e)| (TeeRexStorage::enclave(i as u64 + 1), e)) - .collect() +pub fn validateer_set() -> Vec { + vec![ + AccountId::from([0; 32]), + AccountId::from([1; 32]), + AccountId::from([2; 32]), + AccountId::from([3; 32]), + ] } diff --git a/tee-worker/core-primitives/types/src/lib.rs b/tee-worker/core-primitives/types/src/lib.rs index 911282e427..e04dcaf02e 100644 --- a/tee-worker/core-primitives/types/src/lib.rs +++ b/tee-worker/core-primitives/types/src/lib.rs @@ -37,12 +37,13 @@ pub type PalletString = Vec; pub type PalletString = String; pub use itp_sgx_runtime_primitives::types::*; -pub use litentry_primitives::{Assertion, DecryptableRequest}; +pub use litentry_primitives::{ + Assertion, AttestationType, DecryptableRequest, Enclave, EnclaveFingerprint, MrEnclave, + WorkerType, +}; pub use sp_core::{crypto::AccountId32 as AccountId, H256}; pub type IpfsHash = [u8; 46]; -pub type MrEnclave = [u8; 32]; - pub type CallIndex = [u8; 2]; // pallet teerex @@ -50,7 +51,7 @@ pub type ConfirmCallFn = (CallIndex, ShardIdentifier, H256, Vec); pub type ShieldFundsFn = (CallIndex, Vec, Balance, ShardIdentifier); pub type CallWorkerFn = (CallIndex, RsaRequest); -pub type UpdateScheduledEnclaveFn = (CallIndex, SidechainBlockNumber, MrEnclave); +pub type SetScheduledEnclaveFn = (CallIndex, SidechainBlockNumber, MrEnclave); pub type RemoveScheduledEnclaveFn = (CallIndex, SidechainBlockNumber); // pallet IMP @@ -67,8 +68,6 @@ pub type ActivateIdentityFn = (CallIndex, DeactivateIdentityParams); pub type RequestVCParams = (ShardIdentifier, Assertion); pub type RequestVCFn = (CallIndex, RequestVCParams); -pub type Enclave = EnclaveGen; - /// Simple blob to hold an encoded call #[derive(Debug, PartialEq, Eq, Clone, Default)] pub struct OpaqueCall(pub Vec); @@ -108,23 +107,6 @@ impl DecryptableRequest for RsaRequest { } } -// Todo: move this improved enclave definition into a primitives crate in the pallet_teerex repo. -#[derive(Encode, Decode, Clone, PartialEq, sp_core::RuntimeDebug)] -pub struct EnclaveGen { - pub pubkey: AccountId, - // FIXME: this is redundant information - pub mr_enclave: [u8; 32], - pub timestamp: u64, - // unix epoch in milliseconds - pub url: PalletString, // utf8 encoded url -} - -impl EnclaveGen { - pub fn new(pubkey: AccountId, mr_enclave: [u8; 32], timestamp: u64, url: PalletString) -> Self { - Self { pubkey, mr_enclave, timestamp, url } - } -} - #[derive(Debug, Clone, PartialEq, Encode, Decode, Eq)] pub enum DirectRequestStatus { /// Direct request was successfully executed diff --git a/tee-worker/core/parentchain/indirect-calls-executor/src/executor.rs b/tee-worker/core/parentchain/indirect-calls-executor/src/executor.rs index 0c2dbcf74c..7132b0bdeb 100644 --- a/tee-worker/core/parentchain/indirect-calls-executor/src/executor.rs +++ b/tee-worker/core/parentchain/indirect-calls-executor/src/executor.rs @@ -29,7 +29,7 @@ use binary_merkle_tree::merkle_root; use codec::{Decode, Encode}; use core::marker::PhantomData; use itp_node_api::metadata::{ - pallet_teerex::TeerexCallIndexes, provider::AccessNodeMetadata, NodeMetadataTrait, + pallet_teebag::TeebagCallIndexes, provider::AccessNodeMetadata, NodeMetadataTrait, }; use itp_sgx_crypto::{key_repository::AccessKey, ShieldingCryptoDecrypt, ShieldingCryptoEncrypt}; use itp_stf_executor::traits::{StfEnclaveSigning, StfShardVaultQuery}; @@ -217,10 +217,10 @@ impl< ParentchainBlock: ParentchainBlockTrait, { let call = self.node_meta_data_provider.get_from_metadata(|meta_data| { - meta_data.confirm_processed_parentchain_block_call_indexes() + meta_data.parentchain_block_processed_call_indexes() })??; let root: H256 = merkle_root::(extrinsics); - trace!("prepared confirm_processed_parentchain_block() call for block {:?} with index {:?} and merkle root {}", block_number, call, root); + trace!("prepared parentchain_block_processed() call for block {:?} with index {:?} and merkle root {}", block_number, call, root); // Litentry: we don't include `shard` in the extrinsic parameter to be backwards compatible, // however, we should not forget it in case we need it later Ok(OpaqueCall::from_tuple(&(call, block_hash, block_number, root))) @@ -366,41 +366,6 @@ mod test { assert_eq!(1, top_pool_author.pending_tops(shard_id()).unwrap().len()); } - #[test] - fn shielding_call_can_be_added_to_pool_successfully() { - let _ = env_logger::builder().is_test(true).try_init(); - - let mr_enclave = [33u8; 32]; - let (indirect_calls_executor, top_pool_author, shielding_key_repo) = - test_fixtures(mr_enclave.clone(), NodeMetadataMock::new()); - let shielding_key = shielding_key_repo.retrieve_key().unwrap(); - - let opaque_extrinsic = OpaqueExtrinsic::from_bytes( - shield_funds_unchecked_extrinsic(&shielding_key).encode().as_slice(), - ) - .unwrap(); - - let parentchain_block = ParentchainBlockBuilder::default() - .with_extrinsics(vec![opaque_extrinsic]) - .build(); - - indirect_calls_executor - .execute_indirect_calls_in_extrinsics(&parentchain_block, &Vec::new()) - .unwrap(); - - assert_eq!(1, top_pool_author.pending_tops(shard_id()).unwrap().len()); - let submitted_extrinsic = - top_pool_author.pending_tops(shard_id()).unwrap().first().cloned().unwrap(); - let decrypted_extrinsic = shielding_key.decrypt(&submitted_extrinsic).unwrap(); - let decoded_operation = TrustedOperation::::decode( - &mut decrypted_extrinsic.as_slice(), - ) - .unwrap(); - assert_matches!(decoded_operation, TrustedOperation::indirect_call(_)); - let trusted_call_signed = decoded_operation.to_call().unwrap(); - assert!(trusted_call_signed.verify_signature(&mr_enclave, &shard_id())); - } - #[test] fn ensure_empty_extrinsic_vec_triggers_zero_filled_merkle_root() { // given @@ -409,11 +374,10 @@ mod test { let block_hash = H256::from([1; 32]); let extrinsics = Vec::new(); - let confirm_processed_parentchain_block_indexes = - dummy_metadata.confirm_processed_parentchain_block_call_indexes().unwrap(); + let parentchain_block_processed_call_indexes = + dummy_metadata.parentchain_block_processed_call_indexes().unwrap(); let expected_call = - (confirm_processed_parentchain_block_indexes, block_hash, 1u32, H256::default()) - .encode(); + (parentchain_block_processed_call_indexes, block_hash, 1u32, H256::default()).encode(); // when let call = indirect_calls_executor @@ -432,12 +396,11 @@ mod test { let block_hash = H256::from([1; 32]); let extrinsics = vec![H256::from([4; 32]), H256::from([9; 32])]; - let confirm_processed_parentchain_block_indexes = - dummy_metadata.confirm_processed_parentchain_block_call_indexes().unwrap(); + let parentchain_block_processed_call_indexes = + dummy_metadata.parentchain_block_processed_call_indexes().unwrap(); let zero_root_call = - (confirm_processed_parentchain_block_indexes, block_hash, 1u32, H256::default()) - .encode(); + (parentchain_block_processed_call_indexes, block_hash, 1u32, H256::default()).encode(); // when let call = indirect_calls_executor @@ -448,25 +411,10 @@ mod test { assert_ne!(call.0, zero_root_call); } - fn shield_funds_unchecked_extrinsic( - shielding_key: &ShieldingCryptoMock, - ) -> ParentchainUncheckedExtrinsic { - let target_account = shielding_key.encrypt(&AccountId::new([2u8; 32]).encode()).unwrap(); - let dummy_metadata = NodeMetadataMock::new(); - - let shield_funds_indexes = dummy_metadata.shield_funds_call_indexes().unwrap(); - ParentchainUncheckedExtrinsic::::new_signed( - (shield_funds_indexes, target_account, 1000u128, shard_id()), - MultiAddress::Address32([1u8; 32]), - MultiSignature::Ed25519(default_signature()), - default_extrinsic_params().signed_extra(), - ) - } - fn invoke_unchecked_extrinsic() -> ParentchainUncheckedExtrinsic { let request = RsaRequest::new(shard_id(), vec![1u8, 2u8]); let dummy_metadata = NodeMetadataMock::new(); - let call_worker_indexes = dummy_metadata.invoke_call_indexes().unwrap(); + let call_worker_indexes = dummy_metadata.post_opaque_task_call_indexes().unwrap(); ParentchainUncheckedExtrinsic::::new_signed( (call_worker_indexes, request), diff --git a/tee-worker/core/parentchain/indirect-calls-executor/src/mock.rs b/tee-worker/core/parentchain/indirect-calls-executor/src/mock.rs index 38189f44d8..57c1645cc2 100644 --- a/tee-worker/core/parentchain/indirect-calls-executor/src/mock.rs +++ b/tee-worker/core/parentchain/indirect-calls-executor/src/mock.rs @@ -58,11 +58,7 @@ where "[ShieldFundsAndInvokeFilter] attempting to execute indirect call with index {:?}", index ); - if index == metadata.shield_funds_call_indexes().ok()? { - log::debug!("executing shield funds call"); - let args = ShieldFundsArgs::decode(call_args).unwrap(); - Some(IndirectCall::ShieldFunds(args)) - } else if index == metadata.invoke_call_indexes().ok()? { + if index == metadata.post_opaque_task_call_indexes().ok()? { log::debug!("executing invoke call"); let args = InvokeArgs::decode(call_args).unwrap(); Some(IndirectCall::Invoke(args)) diff --git a/tee-worker/core/rpc-client/Cargo.toml b/tee-worker/core/rpc-client/Cargo.toml index fc06593ed3..1f2b3ff104 100644 --- a/tee-worker/core/rpc-client/Cargo.toml +++ b/tee-worker/core/rpc-client/Cargo.toml @@ -31,7 +31,6 @@ itp-utils = { path = "../../core-primitives/utils" } ita-stf = { path = "../../app-libs/stf" } itp-stf-primitives = { path = "../../core-primitives/stf-primitives" } litentry-primitives = { path = "../../litentry/primitives", default-features = false } -teerex-primitives = { path = "../../../primitives/teerex", default-features = false } [dev-dependencies] env_logger = "0.9.0" diff --git a/tee-worker/core/rpc-client/src/direct_client.rs b/tee-worker/core/rpc-client/src/direct_client.rs index 7814b0e7e3..f5fad98dc2 100644 --- a/tee-worker/core/rpc-client/src/direct_client.rs +++ b/tee-worker/core/rpc-client/src/direct_client.rs @@ -17,6 +17,7 @@ //! Interface for direct access to a workers rpc. +pub use crate::error::{Error, Result}; use crate::ws_client::{WsClient, WsClientControl}; use base58::ToBase58; use codec::{Decode, Encode}; @@ -25,7 +26,7 @@ use ita_stf::{Getter, PublicGetter}; use itp_api_client_types::Metadata; use itp_rpc::{Id, RpcRequest, RpcResponse, RpcReturnValue}; use itp_stf_primitives::types::{AccountId, ShardIdentifier}; -use itp_types::{DirectRequestStatus, RsaRequest}; +use itp_types::{DirectRequestStatus, MrEnclave, RsaRequest}; use itp_utils::{FromHexPrefixed, ToHexPrefixed}; use litentry_primitives::Identity; use log::*; @@ -39,9 +40,6 @@ use std::{ thread, thread::JoinHandle, }; -use teerex_primitives::MrEnclave; - -pub use crate::error::{Error, Result}; #[derive(Clone)] pub struct DirectClient { diff --git a/tee-worker/core/rpc-client/src/mock.rs b/tee-worker/core/rpc-client/src/mock.rs index 8f582ecc27..bffb003e65 100644 --- a/tee-worker/core/rpc-client/src/mock.rs +++ b/tee-worker/core/rpc-client/src/mock.rs @@ -23,10 +23,10 @@ use frame_metadata::RuntimeMetadataPrefixed; use ita_stf::H256; use itp_api_client_types::Metadata; use itp_stf_primitives::types::{AccountId, ShardIdentifier}; +use itp_types::MrEnclave; use litentry_primitives::Identity; use sgx_crypto_helper::rsa3072::Rsa3072PubKey; use std::{sync::mpsc::Sender as MpscSender, thread::JoinHandle}; -use teerex_primitives::MrEnclave; #[derive(Clone, Default)] pub struct DirectClientMock { diff --git a/tee-worker/enclave-runtime/Cargo.lock b/tee-worker/enclave-runtime/Cargo.lock index 136db05d22..f5cd1bddbc 100644 --- a/tee-worker/enclave-runtime/Cargo.lock +++ b/tee-worker/enclave-runtime/Cargo.lock @@ -545,6 +545,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "num-traits 0.2.16", + "serde 1.0.193", ] [[package]] @@ -737,6 +738,17 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "der_derive", + "flagset", +] + [[package]] name = "der" version = "0.7.8" @@ -747,6 +759,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ef71ddb5b3a1f53dee24817c8f70dfa1cb29e804c18d88c228d4bc9c86ee3b9" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote 1.0.33", + "syn 1.0.109", +] + [[package]] name = "derive-syn-parse" version = "0.1.5" @@ -807,7 +831,7 @@ version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ - "der", + "der 0.7.8", "digest 0.10.7", "elliptic-curve", "rfc6979", @@ -937,7 +961,7 @@ dependencies = [ "sgx_types", "sp-core", "sp-runtime", - "teerex-primitives 0.1.0 (git+https://github.com/integritee-network/pallets.git?branch=sdk-v0.12.0-polkadot-v0.9.42)", + "teerex-primitives", "webpki", ] @@ -1173,6 +1197,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "flagset" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a7e408202050813e6f1d9addadcaafef3dca7530c7ddfb005d4081cce6779" + [[package]] name = "fnv" version = "1.0.6" @@ -2396,7 +2426,6 @@ name = "itp-sgx-runtime-primitives" version = "0.9.0" dependencies = [ "frame-system", - "litentry-primitives", "pallet-balances", "sp-core", "sp-runtime", @@ -2514,14 +2543,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "itp-teerex-storage" -version = "0.9.0" -dependencies = [ - "itp-storage", - "sp-std", -] - [[package]] name = "itp-test" version = "0.9.0" @@ -2536,10 +2557,10 @@ dependencies = [ "itp-stf-primitives", "itp-stf-state-handler", "itp-storage", - "itp-teerex-storage", "itp-time-utils", "itp-types", "jsonrpc-core", + "lc-teebag-storage", "litentry-primitives", "log", "parity-scale-codec", @@ -2825,10 +2846,9 @@ name = "its-validateer-fetch" version = "0.9.0" dependencies = [ "derive_more", - "frame-support", "itp-ocall-api", - "itp-teerex-storage", "itp-types", + "lc-teebag-storage", "parity-scale-codec", "sp-core", "sp-runtime", @@ -2837,9 +2857,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.65" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -3122,6 +3142,15 @@ dependencies = [ "url", ] +[[package]] +name = "lc-teebag-storage" +version = "0.1.0" +dependencies = [ + "itp-storage", + "itp-types", + "sp-std", +] + [[package]] name = "lc-vc-task-receiver" version = "0.1.0" @@ -3257,6 +3286,7 @@ dependencies = [ "litentry-hex-utils", "log", "pallet-evm 6.0.0-dev (git+https://github.com/integritee-network/frontier.git?branch=bar/polkadot-v0.9.42)", + "pallet-teebag", "parity-scale-codec", "rand 0.7.3", "ring 0.16.20", @@ -3270,7 +3300,6 @@ dependencies = [ "sp-std", "strum", "strum_macros", - "teerex-primitives 0.1.0", ] [[package]] @@ -3687,6 +3716,31 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-teebag" +version = "0.1.0" +dependencies = [ + "base64 0.13.1", + "chrono 0.4.31", + "der 0.6.1", + "frame-support", + "frame-system", + "hex 0.4.3", + "log", + "pallet-timestamp", + "parity-scale-codec", + "ring 0.16.20", + "rustls-webpki", + "scale-info", + "serde 1.0.193", + "serde_json 1.0.107", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "x509-cert", +] + [[package]] name = "pallet-timestamp" version = "4.0.0-dev" @@ -4065,7 +4119,7 @@ dependencies = [ "cc", "sgx_tstd", "spin", - "untrusted", + "untrusted 0.7.1", ] [[package]] @@ -4078,7 +4132,7 @@ dependencies = [ "libc", "once_cell 1.18.0", "spin", - "untrusted", + "untrusted 0.7.1", "web-sys", "winapi", ] @@ -4177,6 +4231,22 @@ dependencies = [ "webpki", ] +[[package]] +name = "rustls-pki-types" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47003264dea418db67060fa420ad16d0d2f8f0a0360d825c00e177ac52cb5d8" + +[[package]] +name = "rustls-webpki" +version = "0.102.0-alpha.3" +source = "git+https://github.com/rustls/webpki?rev=da923ed#da923edaab56f599971e58773617fb574cd019dc" +dependencies = [ + "ring 0.16.20", + "rustls-pki-types", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -4303,7 +4373,7 @@ source = "git+https://github.com/mesalock-linux/sct.rs?branch=mesalock_sgx#c4d85 dependencies = [ "ring 0.16.19", "sgx_tstd", - "untrusted", + "untrusted 0.7.1", ] [[package]] @@ -4313,7 +4383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", - "der", + "der 0.7.8", "generic-array 0.14.7", "subtle", "zeroize", @@ -5131,6 +5201,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "der 0.6.1", +] + [[package]] name = "ss58-registry" version = "1.43.0" @@ -5282,16 +5361,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" -[[package]] -name = "teerex-primitives" -version = "0.1.0" -dependencies = [ - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-std", -] - [[package]] name = "teerex-primitives" version = "0.1.0" @@ -5576,6 +5645,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.1.1" @@ -5609,9 +5684,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.88" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -5619,9 +5694,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.88" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", @@ -5634,9 +5709,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.88" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote 1.0.33", "wasm-bindgen-macro-support", @@ -5644,9 +5719,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.88" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote 1.0.33", @@ -5657,15 +5732,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.88" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "web-sys" -version = "0.3.65" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ "js-sys", "wasm-bindgen", @@ -5678,7 +5753,7 @@ source = "git+https://github.com/mesalock-linux/webpki?branch=mesalock_sgx#8dbe6 dependencies = [ "ring 0.16.19", "sgx_tstd", - "untrusted", + "untrusted 0.7.1", ] [[package]] @@ -5739,6 +5814,18 @@ dependencies = [ "tap", ] +[[package]] +name = "x509-cert" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d224a125dec5adda27d0346b9cae9794830279c4f9c27e4ab0b6c408d54012" +dependencies = [ + "const-oid", + "der 0.6.1", + "flagset", + "spki", +] + [[package]] name = "yasna" version = "0.3.1" diff --git a/tee-worker/enclave-runtime/src/attestation.rs b/tee-worker/enclave-runtime/src/attestation.rs index 7702cd8f0f..59810d8abd 100644 --- a/tee-worker/enclave-runtime/src/attestation.rs +++ b/tee-worker/enclave-runtime/src/attestation.rs @@ -42,7 +42,7 @@ use itp_attestation_handler::{AttestationHandler, RemoteAttestationType, SgxQlQv use itp_component_container::ComponentGetter; use itp_extrinsics_factory::CreateExtrinsics; use itp_node_api::metadata::{ - pallet_teerex::TeerexCallIndexes, + pallet_teebag::TeebagCallIndexes, provider::{AccessNodeMetadata, Error as MetadataProviderError}, Error as MetadataError, }; @@ -51,7 +51,7 @@ use itp_settings::worker::MR_ENCLAVE_SIZE; use itp_sgx_crypto::{ ed25519_derivation::DeriveEd25519, key_repository::AccessKey, Error as SgxCryptoError, }; -use itp_types::OpaqueCall; +use itp_types::{AttestationType, OpaqueCall, WorkerType}; use itp_utils::write_slice_and_whitespace_pad; use log::*; use sgx_types::*; @@ -142,7 +142,8 @@ pub unsafe extern "C" fn generate_ias_ra_extrinsic( } let mut url_slice = slice::from_raw_parts(w_url, w_url_size as usize); let url = match String::decode(&mut url_slice) { - Ok(url) => url, + // Litentry: the teebag extrinsic expects an URL with plain utf8 encoded Vec, not string scale-encoded + Ok(url) => url.as_bytes().to_vec(), Err(_) => return EnclaveError::Other("Could not decode url slice to a valid String".into()).into(), }; @@ -178,7 +179,8 @@ pub unsafe extern "C" fn generate_dcap_ra_extrinsic( } let mut url_slice = slice::from_raw_parts(w_url, w_url_size as usize); let url = match String::decode(&mut url_slice) { - Ok(url) => url, + // Litentry: the teebag extrinsic expects an URL with plain utf8 encoded Vec, not string scale-encoded + Ok(url) => url.as_bytes().to_vec(), Err(_) => return EnclaveError::Other("Could not decode url slice to a valid String".into()).into(), }; @@ -204,7 +206,7 @@ pub unsafe extern "C" fn generate_dcap_ra_extrinsic( } pub fn generate_dcap_ra_extrinsic_internal( - url: String, + url: Vec, skip_ra: bool, quoting_enclave_target_info: Option<&sgx_target_info_t>, quote_size: Option<&u32>, @@ -287,7 +289,8 @@ pub unsafe extern "C" fn generate_dcap_ra_extrinsic_from_quote( } let mut url_slice = slice::from_raw_parts(w_url, w_url_size as usize); let url = match String::decode(&mut url_slice) { - Ok(url) => url, + // Litentry: the teebag extrinsic expects an URL with plain utf8 encoded Vec, not string scale-encoded + Ok(url) => url.as_bytes().to_vec(), Err(_) => return EnclaveError::Other("Could not decode url slice to a valid String".into()).into(), }; @@ -311,7 +314,7 @@ pub unsafe extern "C" fn generate_dcap_ra_extrinsic_from_quote( } pub fn generate_dcap_ra_extrinsic_from_quote_internal( - url: String, + url: Vec, quote: &[u8], ) -> EnclaveResult { let node_metadata_repo = get_node_metadata_repository_from_integritee_solo_or_parachain()?; @@ -324,15 +327,24 @@ pub fn generate_dcap_ra_extrinsic_from_quote_internal( let shielding_pubkey = get_shielding_pubkey()?; let vc_pubkey = get_vc_pubkey()?; + let attestation_type = AttestationType::Dcap(Default::default()); // skip_ra should be false here already - let call = OpaqueCall::from_tuple(&(call_ids, quote, url, shielding_pubkey, vc_pubkey)); + let call = OpaqueCall::from_tuple(&( + call_ids, + WorkerType::Identity, + quote, + url, + shielding_pubkey, + vc_pubkey, + attestation_type, + )); info!(" [Enclave] Compose register enclave got extrinsic, returning"); create_extrinsics(call) } pub fn generate_dcap_skip_ra_extrinsic_from_mr_enclave( - url: String, + url: Vec, quote: &[u8], ) -> EnclaveResult { let node_metadata_repo = get_node_metadata_repository_from_integritee_solo_or_parachain()?; @@ -346,25 +358,34 @@ pub fn generate_dcap_skip_ra_extrinsic_from_mr_enclave( let shielding_pubkey = get_shielding_pubkey()?; let vc_pubkey = get_vc_pubkey()?; - let call = OpaqueCall::from_tuple(&(call_ids, quote, url, shielding_pubkey, vc_pubkey)); + let call = OpaqueCall::from_tuple(&( + call_ids, + WorkerType::Identity, + quote, + url, + shielding_pubkey, + vc_pubkey, + AttestationType::Ignore, + )); info!(" [Enclave] Compose register enclave (skip-ra) got extrinsic, returning"); create_extrinsics(call) } fn generate_ias_ra_extrinsic_internal( - url: String, + url: Vec, skip_ra: bool, ) -> EnclaveResult { let attestation_handler = GLOBAL_ATTESTATION_HANDLER_COMPONENT.get()?; let cert_der = attestation_handler.generate_ias_ra_cert(skip_ra)?; - generate_ias_ra_extrinsic_from_der_cert_internal(url, &cert_der) + generate_ias_ra_extrinsic_from_der_cert_internal(url, &cert_der, skip_ra) } pub fn generate_ias_ra_extrinsic_from_der_cert_internal( - url: String, + url: Vec, cert_der: &[u8], + skip_ra: bool, ) -> EnclaveResult { let node_metadata_repo = get_node_metadata_repository_from_integritee_solo_or_parachain()?; @@ -375,8 +396,17 @@ pub fn generate_ias_ra_extrinsic_from_der_cert_internal( let shielding_pubkey = get_shielding_pubkey()?; let vc_pubkey = get_vc_pubkey()?; + let attestation_type = if skip_ra { AttestationType::Ignore } else { AttestationType::Ias }; - let call = OpaqueCall::from_tuple(&(call_ids, cert_der, url, shielding_pubkey, vc_pubkey)); + let call = OpaqueCall::from_tuple(&( + call_ids, + WorkerType::Identity, + cert_der, + url, + shielding_pubkey, + vc_pubkey, + attestation_type, + )); create_extrinsics(call) } diff --git a/tee-worker/enclave-runtime/src/rpc/worker_api_direct.rs b/tee-worker/enclave-runtime/src/rpc/worker_api_direct.rs index 93b9370d57..e02f775f0d 100644 --- a/tee-worker/enclave-runtime/src/rpc/worker_api_direct.rs +++ b/tee-worker/enclave-runtime/src/rpc/worker_api_direct.rs @@ -339,8 +339,8 @@ where if_not_production!({ use itp_types::{MrEnclave, SidechainBlockNumber}; - // state_updateScheduledEnclave, params: sidechainBlockNumber, hex encoded mrenclave - io.add_sync_method("state_updateScheduledEnclave", move |params: Params| { + // state_setScheduledEnclave, params: sidechainBlockNumber, hex encoded mrenclave + io.add_sync_method("state_setScheduledEnclave", move |params: Params| { match params.parse::<(SidechainBlockNumber, String)>() { Ok((bn, mrenclave)) => return match hex::decode(&mrenclave) { @@ -492,8 +492,11 @@ fn forward_dcap_quote_inner(params: Params) -> Result { litentry_hex_utils::decode_hex(param).map_err(|e| format!("{:?}", e))?; let url = String::new(); - let ext = generate_dcap_ra_extrinsic_from_quote_internal(url, &encoded_quote_to_forward) - .map_err(|e| format!("{:?}", e))?; + let ext = generate_dcap_ra_extrinsic_from_quote_internal( + url.as_bytes().to_vec(), + &encoded_quote_to_forward, + ) + .map_err(|e| format!("{:?}", e))?; let validator_access = get_validator_accessor_from_integritee_solo_or_parachain() .map_err(|e| format!("{:?}", e))?; @@ -522,8 +525,12 @@ fn attesteer_forward_ias_attestation_report_inner( litentry_hex_utils::decode_hex(param).map_err(|e| format!("{:?}", e))?; let url = String::new(); - let ext = generate_ias_ra_extrinsic_from_der_cert_internal(url, &ias_attestation_report) - .map_err(|e| format!("{:?}", e))?; + let ext = generate_ias_ra_extrinsic_from_der_cert_internal( + url.as_bytes().to_vec(), + &ias_attestation_report, + false, + ) + .map_err(|e| format!("{:?}", e))?; let validator_access = get_validator_accessor_from_integritee_solo_or_parachain() .map_err(|e| format!("{:?}", e))?; diff --git a/tee-worker/enclave-runtime/src/test/fixtures/components.rs b/tee-worker/enclave-runtime/src/test/fixtures/components.rs index dd1237672d..34f3606010 100644 --- a/tee-worker/enclave-runtime/src/test/fixtures/components.rs +++ b/tee-worker/enclave-runtime/src/test/fixtures/components.rs @@ -27,7 +27,7 @@ use itp_stf_primitives::{ }; use itp_top_pool::pool::Options as PoolOptions; use itp_top_pool_author::api::SidechainApi; -use itp_types::{Block as ParentchainBlock, Enclave, ShardIdentifier}; +use itp_types::{Block as ParentchainBlock, ShardIdentifier}; use sp_core::{ed25519, Pair, H256}; use sp_runtime::traits::Header as HeaderTrait; use std::{boxed::Box, sync::Arc, vec::Vec}; @@ -41,13 +41,7 @@ pub(crate) fn create_ocall_api>( header: &Header, signer: &TestSigner, ) -> Arc { - let enclave_validateer = Enclave::new( - signer.public().into(), - Default::default(), - Default::default(), - Default::default(), - ); - Arc::new(TestOCallApi::default().add_validateer_set(header, Some(vec![enclave_validateer]))) + Arc::new(TestOCallApi::default().add_validateer_set(header, Some(vec![signer.public().into()]))) } pub(crate) fn encrypt_trusted_operation( diff --git a/tee-worker/enclave-runtime/src/test/tests_main.rs b/tee-worker/enclave-runtime/src/test/tests_main.rs index 64416fb0dd..a4e0b0e94b 100644 --- a/tee-worker/enclave-runtime/src/test/tests_main.rs +++ b/tee-worker/enclave-runtime/src/test/tests_main.rs @@ -143,7 +143,8 @@ pub extern "C" fn test_main_entrance() -> size_t { sidechain_aura_tests::produce_sidechain_block_and_import_it, sidechain_event_tests::ensure_events_get_reset_upon_block_proposal, top_pool_tests::process_indirect_call_in_top_pool, - top_pool_tests::submit_shielding_call_to_top_pool, + // TODO: Litentry disables it for now (P-494) + // top_pool_tests::submit_shielding_call_to_top_pool, // tls_ra unit tests tls_ra::seal_handler::test::seal_shielding_key_works, tls_ra::seal_handler::test::seal_shielding_key_fails_for_invalid_key, diff --git a/tee-worker/enclave-runtime/src/test/top_pool_tests.rs b/tee-worker/enclave-runtime/src/test/top_pool_tests.rs index 22776fbd39..21c86ce3a2 100644 --- a/tee-worker/enclave-runtime/src/test/top_pool_tests.rs +++ b/tee-worker/enclave-runtime/src/test/top_pool_tests.rs @@ -48,7 +48,7 @@ use itp_node_api::{ }, metadata::{metadata_mocks::NodeMetadataMock, provider::NodeMetadataRepository}, }; -use itp_node_api_metadata::pallet_teerex::TeerexCallIndexes; +use itp_node_api_metadata::pallet_teebag::TeebagCallIndexes; use itp_ocall_api::EnclaveAttestationOCallApi; use itp_sgx_crypto::ShieldingCryptoEncrypt; use itp_stf_executor::enclave_signer::StfEnclaveSigner; @@ -59,9 +59,7 @@ use itp_top_pool_author::{ top_filter::{AllowAllTopsFilter, DirectCallsOnlyFilter}, traits::AuthorApi, }; -use itp_types::{ - parentchain::Address, AccountId, Block, RsaRequest, ShardIdentifier, ShieldFundsFn, H256, -}; +use itp_types::{parentchain::Address, Block, CallWorkerFn, RsaRequest, ShardIdentifier, H256}; use jsonrpc_core::futures::executor; use litentry_primitives::Identity; use log::*; @@ -107,6 +105,10 @@ pub fn process_indirect_call_in_top_pool() { assert_eq!(1, top_pool_author.get_pending_trusted_calls(shard_id).len()); } +/* + +// TODO: use our trusted call for testing - see P-494 + pub fn submit_shielding_call_to_top_pool() { let _ = env_logger::builder().is_test(true).try_init(); @@ -159,7 +161,7 @@ pub fn submit_shielding_call_to_top_pool() { shielding_key_repo, enclave_signer, top_pool_author.clone(), node_meta_data_repository ); - let block_with_shielding_call = create_shielding_call_extrinsic(shard_id, &shielding_key); + let block_with_shielding_call = create_opaque_call_extrinsic(shard_id, &shielding_key); let _ = indirect_calls_executor .execute_indirect_calls_in_extrinsics(&block_with_shielding_call, &Vec::new()) @@ -171,6 +173,7 @@ pub fn submit_shielding_call_to_top_pool() { let trusted_call = trusted_operation.to_call().unwrap(); assert!(trusted_call.verify_signature(&mr_enclave.m, &shard_id)); } +*/ fn encrypted_indirect_call< AttestationApi: EnclaveAttestationOCallApi, @@ -194,11 +197,10 @@ fn encrypted_indirect_call< encrypt_trusted_operation(shielding_key, &trusted_operation) } -fn create_shielding_call_extrinsic( - shard: ShardIdentifier, - shielding_key: &ShieldingKey, +fn create_opaque_call_extrinsic( + _shard: ShardIdentifier, + _shielding_key: &ShieldingKey, ) -> Block { - let target_account = shielding_key.encrypt(&AccountId::new([2u8; 32]).encode()).unwrap(); let test_signer = ed25519::Pair::from_seed(b"33345678901234567890123456789012"); let signature = test_signer.sign(&[0u8]); @@ -212,15 +214,10 @@ fn create_shielding_call_extrinsic( let dummy_node_metadata = NodeMetadataMock::new(); - let shield_funds_indexes = dummy_node_metadata.shield_funds_call_indexes().unwrap(); + let call_index = dummy_node_metadata.post_opaque_task_call_indexes().unwrap(); let opaque_extrinsic = OpaqueExtrinsic::from_bytes( - ParentchainUncheckedExtrinsic::::new_signed( - ( - shield_funds_indexes, - target_account, - ita_stf::test_genesis::SECOND_ENDOWED_ACC_FUNDS, - shard, - ), + ParentchainUncheckedExtrinsic::::new_signed( + (call_index, RsaRequest::default()), Address::Address32([1u8; 32]), MultiSignature::Ed25519(signature), default_extra_for_test.signed_extra(), diff --git a/tee-worker/litentry/core/teebag-storage/Cargo.toml b/tee-worker/litentry/core/teebag-storage/Cargo.toml new file mode 100644 index 0000000000..c68b9e0d5e --- /dev/null +++ b/tee-worker/litentry/core/teebag-storage/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "lc-teebag-storage" +version = "0.1.0" +authors = ['Trust Computing GmbH '] +edition = "2021" + +[dependencies] +itp-storage = { path = "../../../core-primitives/storage", default-features = false } +itp-types = { path = "../../../core-primitives/types", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42", default-features = false } + +[features] +default = ["std"] +std = [ + "sp-std/std", + "itp-storage/std", + "itp-types/std", +] diff --git a/tee-worker/litentry/core/teebag-storage/src/lib.rs b/tee-worker/litentry/core/teebag-storage/src/lib.rs new file mode 100644 index 0000000000..3f931d9f7e --- /dev/null +++ b/tee-worker/litentry/core/teebag-storage/src/lib.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_attr(not(feature = "std"), no_std)] + +use itp_storage::{storage_map_key, StorageHasher}; +use itp_types::WorkerType; +use sp_std::prelude::Vec; + +pub struct TeebagStorage; + +pub trait StoragePrefix { + fn prefix() -> &'static str; +} + +impl StoragePrefix for TeebagStorage { + fn prefix() -> &'static str { + "Teebag" + } +} + +pub trait TeebagStorageKeys { + fn enclave_identifier(worker_type: WorkerType) -> Vec; +} + +impl TeebagStorageKeys for S { + fn enclave_identifier(worker_type: WorkerType) -> Vec { + storage_map_key( + Self::prefix(), + "EnclaveIdentifier", + &worker_type, + &StorageHasher::Blake2_128Concat, + ) + } +} diff --git a/tee-worker/litentry/primitives/Cargo.toml b/tee-worker/litentry/primitives/Cargo.toml index 076b5aab29..14c1d6da3e 100644 --- a/tee-worker/litentry/primitives/Cargo.toml +++ b/tee-worker/litentry/primitives/Cargo.toml @@ -31,8 +31,8 @@ sgx_tstd = { git = "https://github.com/apache/teaclave-sgx-sdk.git", branch = "m itp-sgx-crypto = { path = "../../core-primitives/sgx/crypto", default-features = false } itp-utils = { path = "../../core-primitives/utils", default-features = false } litentry-hex-utils = { path = "../../../primitives/hex", default-features = false } +pallet-teebag = { path = "../../../pallets/teebag", default-features = false } parentchain-primitives = { package = "core-primitives", path = "../../../primitives/core", default-features = false } -teerex-primitives = { path = "../../../primitives/teerex", default-features = false } [dev-dependencies] base64 = { version = "0.13", features = ["alloc"] } @@ -59,7 +59,7 @@ std = [ "sp-runtime/std", "ring/std", "parentchain-primitives/std", - "teerex-primitives/std", + "pallet-teebag/std", "rand", "log/std", "bitcoin/std", diff --git a/tee-worker/litentry/primitives/src/aes_request.rs b/tee-worker/litentry/primitives/src/aes_request.rs index 998d642837..e15c88e40b 100644 --- a/tee-worker/litentry/primitives/src/aes_request.rs +++ b/tee-worker/litentry/primitives/src/aes_request.rs @@ -17,7 +17,7 @@ #[cfg(all(not(feature = "std"), feature = "sgx"))] extern crate sgx_tstd as std; -/// A morphling of itp_types::RsaRequest which stems from teerex_primitives::RsaRequest +/// A morphling of itp_types::RsaRequest which stems from teebag::RsaRequest /// /// Instead of encrypting the TrustedCallSigned with the TEE's shielding key, we encrypt /// it with a 32-byte ephemeral AES key which is generated from the client's side, and diff --git a/tee-worker/litentry/primitives/src/lib.rs b/tee-worker/litentry/primitives/src/lib.rs index af8137c463..82b9c77c64 100644 --- a/tee-worker/litentry/primitives/src/lib.rs +++ b/tee-worker/litentry/primitives/src/lib.rs @@ -43,6 +43,10 @@ use codec::{Decode, Encode, MaxEncodedLen}; use itp_sgx_crypto::ShieldingCryptoDecrypt; use litentry_hex_utils::hex_encode; use log::error; +pub use pallet_teebag::{ + decl_rsa_request, extract_tcb_info_from_raw_dcap_quote, AttestationType, Enclave, + EnclaveFingerprint, MrEnclave, ShardIdentifier, SidechainBlockNumber, WorkerType, +}; pub use parentchain_primitives::{ all_bitcoin_web3networks, all_evm_web3networks, all_substrate_web3networks, all_web3networks, identity::*, AccountId as ParentchainAccountId, AchainableAmount, AchainableAmountHolding, @@ -64,7 +68,6 @@ use sp_io::{ }; use sp_runtime::traits::Verify; use std::string::{String, ToString}; -pub use teerex_primitives::{decl_rsa_request, ShardIdentifier, SidechainBlockNumber}; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; diff --git a/tee-worker/service/Cargo.toml b/tee-worker/service/Cargo.toml index 8363903079..c391b81179 100644 --- a/tee-worker/service/Cargo.toml +++ b/tee-worker/service/Cargo.toml @@ -78,8 +78,6 @@ litentry-hex-utils = { path = "../../primitives/hex", default-features = false } litentry-macros = { path = "../../primitives/core/macros", default-features = false } litentry-primitives = { path = "../litentry/primitives" } my-node-runtime = { package = "rococo-parachain-runtime", path = "../../runtime/rococo" } -sgx-verify = { path = "../../pallets/teerex/sgx-verify", default-features = false } -teerex-primitives = { path = "../../primitives/teerex", default-features = false } [features] default = [] diff --git a/tee-worker/service/src/main_impl.rs b/tee-worker/service/src/main_impl.rs index 3e660cefc2..a44fb49c97 100644 --- a/tee-worker/service/src/main_impl.rs +++ b/tee-worker/service/src/main_impl.rs @@ -39,7 +39,7 @@ use itp_enclave_api::{ teeracle_api::TeeracleApi, }; use itp_node_api::{ - api_client::{AccountApi, PalletTeerexApi, ParentchainApi}, + api_client::{AccountApi, PalletTeebagApi, ParentchainApi}, metadata::NodeMetadata, node_api_factory::{CreateNodeApi, NodeApiFactory}, }; @@ -51,6 +51,7 @@ use its_primitives::types::block::SignedBlock as SignedSidechainBlock; use its_storage::{interface::FetchBlocks, BlockPruner, SidechainStorageLock}; use lc_data_providers::DataProviderConfig; use litentry_macros::if_production_or; +use litentry_primitives::{Enclave as TeebagEnclave, ShardIdentifier, WorkerType}; use log::*; use my_node_runtime::{Hash, Header, RuntimeEvent}; use regex::Regex; @@ -61,10 +62,9 @@ use substrate_api_client::{ ac_primitives::serde_impls::StorageKey, api::XtStatus, rpc::HandleSubscription, storage_key, GetChainInfo, GetStorage, SubmitAndWatch, SubscribeChain, SubscribeEvents, }; -use teerex_primitives::{Enclave as TeerexEnclave, ShardIdentifier}; #[cfg(feature = "dcap")] -use sgx_verify::extract_tcb_info_from_raw_dcap_quote; +use litentry_primitives::extract_tcb_info_from_raw_dcap_quote; use itc_parentchain::primitives::ParentchainId; use itp_enclave_api::Enclave; @@ -521,86 +521,51 @@ fn start_worker( #[cfg(feature = "dcap")] let register_xt = move || enclave2.generate_dcap_ra_extrinsic(&trusted_url2, skip_ra).unwrap(); - let mut register_enclave_xt_header: Option
= None; - let mut we_are_primary_validateer: bool = false; - let send_register_xt = move || { println!("[+] Send register enclave extrinsic"); send_extrinsic(register_xt(), &node_api2, &tee_accountid2, is_development_mode) }; - // litentry: check if the enclave is already registered - // TODO: revisit the registration process (P-10) - match litentry_rpc_api.get_keys(storage_key("Teerex", "EnclaveRegistry"), None) { - Ok(Some(keys)) => { - let trusted_url = trusted_url.as_bytes().to_vec(); - let mrenclave = mrenclave.0.to_vec(); - let mut found = false; - for key in keys { - let key = if key.starts_with("0x") { - let bytes = &key.as_bytes()[b"0x".len()..]; - hex::decode(bytes).unwrap() - } else { - hex::decode(key.as_bytes()).unwrap() - }; - match litentry_rpc_api.get_storage_by_key::>>( - StorageKey(key.clone()), - None, - ) { - Ok(Some(value)) => { - if value.mr_enclave.to_vec() == mrenclave && value.url == trusted_url { - // After calling the perform_ra function, the nonce will be incremented by 1, - // so enclave is already registered, we should reset the nonce_cache - let nonce = - litentry_rpc_api.get_account_next_index(&tee_accountid).unwrap(); - enclave - .set_nonce(nonce, ParentchainId::Litentry) - .expect("Could not set nonce of enclave. Returning here..."); - found = true; - info!("fond enclave: {:?}", value); - break - } - }, - Ok(None) => { - warn!("not found from key: {:?}", key); - }, - Err(_) => {}, - } - } - if !found { - // Todo: Can't unwrap here because the extrinsic is for some reason not found in the block - // even if it was successful: https://github.com/scs/substrate-api-client/issues/624. - let register_enclave_block_hash = send_register_xt(); - let api_register_enclave_xt_header = - litentry_rpc_api.get_header(register_enclave_block_hash).unwrap().unwrap(); - - // TODO: #1451: Fix api-client type hacks - // TODO(Litentry): keep an eye on it - it's a hacky way to convert `SubstrateHeader` to `Header` - let header = - Header::decode(&mut api_register_enclave_xt_header.encode().as_slice()) - .expect("Can decode previously encoded header; qed"); - - println!( - "[+] Enclave registered at block number: {:?}, hash: {:?}", - header.number(), - header.hash() - ); + // Litentry: send the registration extrinsic regardless of being registered or not, + // the reason is the mrenclave could change in between, so we rely on the + // on-chain logic to handle everything. + // this is the same behavior as upstream + let register_enclave_block_hash = + send_register_xt().expect("enclave RA registration must be successful to continue"); + + let api_register_enclave_xt_header = + litentry_rpc_api.get_header(Some(register_enclave_block_hash)).unwrap().unwrap(); + + // TODO: #1451: Fix api-client type hacks + let register_enclave_xt_header = + Header::decode(&mut api_register_enclave_xt_header.encode().as_slice()) + .expect("Can decode previously encoded header; qed"); + + println!( + "[+] Enclave registered at block number: {:?}, hash: {:?}", + register_enclave_xt_header.number(), + register_enclave_xt_header.hash() + ); - register_enclave_xt_header = Some(header); - } - }, - _ => panic!("unknown error"), - } + // double-check + let my_enclave = litentry_rpc_api + .enclave(&tee_accountid, None) + .unwrap() + .expect("our enclave should be registered at this point"); + trace!("verified that our enclave is registered: {:?}", my_enclave); - if let Some(register_enclave_xt_header) = register_enclave_xt_header.clone() { - we_are_primary_validateer = - we_are_primary_worker(&litentry_rpc_api, ®ister_enclave_xt_header).unwrap(); - } + let is_primary_enclave = match litentry_rpc_api + .primary_enclave_identifier_for_shard(WorkerType::Identity, shard, None) + .unwrap() + { + Some(account) => account == tee_accountid, + None => false, + }; - if we_are_primary_validateer { - println!("[+] We are the primary worker"); + if is_primary_enclave { + println!("[+] We are the primary enclave"); } else { - println!("[+] We are NOT the primary worker"); + println!("[+] We are NOT the primary enclave"); } initialization_handler.registered_on_parentchain(); @@ -652,7 +617,7 @@ fn start_worker( let last_synced_header = sidechain_init_block_production( enclave.clone(), register_enclave_xt_header, - we_are_primary_validateer, + is_primary_enclave, parentchain_handler.clone(), sidechain_storage, &last_synced_header, @@ -664,7 +629,7 @@ fn start_worker( start_parentchain_header_subscription_thread(parentchain_handler, last_synced_header); - init_provided_shard_vault(shard, &enclave, we_are_primary_validateer); + init_provided_shard_vault(shard, &enclave, is_primary_enclave); spawn_worker_for_shard_polling(shard, litentry_rpc_api.clone(), initialization_handler); }, @@ -707,14 +672,14 @@ fn start_worker( fn init_provided_shard_vault( shard: &ShardIdentifier, enclave: &Arc, - we_are_primary_validateer: bool, + is_primary_enclave: bool, ) { if let Ok(shard_vault) = enclave.get_ecc_vault_pubkey(shard) { println!( "[Litentry] shard vault account is already initialized in state: {}", shard_vault.to_ss58check() ); - } else if we_are_primary_validateer { + } else if is_primary_enclave { println!("[Litentry] initializing proxied shard vault account now"); enclave.init_proxied_shard_vault(shard, &ParentchainId::Litentry).unwrap(); println!( @@ -824,9 +789,8 @@ where } /// Start polling loop to wait until we have a worker for a shard registered on -/// the parentchain (TEEREX WorkerForShard). This is the pre-requisite to be +/// the parentchain (TEEBAG EnclaveIdentifier). This is the pre-requisite to be /// considered initialized and ready for the next worker to start (in sidechain mode only). -/// considered initialized and ready for the next worker to start. fn spawn_worker_for_shard_polling( shard: &ShardIdentifier, node_api: ParentchainApi, @@ -840,7 +804,11 @@ fn spawn_worker_for_shard_polling( loop { info!("Polling for worker for shard ({} seconds interval)", POLL_INTERVAL_SECS); - if let Ok(Some(_enclave)) = node_api.worker_for_shard(&shard_for_initialized, None) { + if let Ok(Some(_account)) = node_api.primary_enclave_identifier_for_shard( + WorkerType::Identity, + &shard_for_initialized, + None, + ) { // Set that the service is initialized. initialization_handler.worker_for_shard_registered(); println!("[+] Found `WorkerForShard` on parentchain state",); @@ -1053,13 +1021,3 @@ pub fn enclave_account(enclave_api: &E) -> AccountId32 { trace!("[+] Got ed25519 account of TEE = {}", tee_public.to_ss58check()); AccountId32::from(*tee_public.as_array_ref()) } - -/// Checks if we are the first validateer to register on the parentchain. -fn we_are_primary_worker( - node_api: &ParentchainApi, - register_enclave_xt_header: &Header, -) -> Result { - let enclave_count_of_previous_block = - node_api.enclave_count(Some(*register_enclave_xt_header.parent_hash()))?; - Ok(enclave_count_of_previous_block == 0) -} diff --git a/tee-worker/service/src/sidechain_setup.rs b/tee-worker/service/src/sidechain_setup.rs index a499c85fed..55a17cdbe1 100644 --- a/tee-worker/service/src/sidechain_setup.rs +++ b/tee-worker/service/src/sidechain_setup.rs @@ -57,7 +57,7 @@ pub(crate) fn sidechain_start_untrusted_rpc_server( #[allow(clippy::too_many_arguments)] pub(crate) fn sidechain_init_block_production( enclave: Arc, - register_enclave_xt_header: Option
, + register_enclave_xt_header: Header, we_are_primary_validateer: bool, parentchain_handler: Arc, sidechain_storage: Arc, @@ -80,7 +80,7 @@ where ); updated_header = Some(parentchain_handler.sync_and_import_parentchain_until( last_synced_header, - ®ister_enclave_xt_header.unwrap(), + ®ister_enclave_xt_header, overriden_start_block, )?); } diff --git a/tee-worker/service/src/sync_state.rs b/tee-worker/service/src/sync_state.rs index 21d2d4d7e0..29bb91fd5b 100644 --- a/tee-worker/service/src/sync_state.rs +++ b/tee-worker/service/src/sync_state.rs @@ -26,15 +26,15 @@ use itp_enclave_api::{ enclave_base::EnclaveBase, remote_attestation::{RemoteAttestation, TlsRemoteAttestation}, }; -use itp_node_api::api_client::PalletTeerexApi; +use itp_node_api::api_client::PalletTeebagApi; use itp_settings::worker_mode::{ProvideWorkerMode, WorkerMode}; -use itp_types::ShardIdentifier; +use itp_types::{ShardIdentifier, WorkerType}; use sgx_types::sgx_quote_sign_type_t; use std::string::String; pub(crate) fn sync_state< E: TlsRemoteAttestation + EnclaveBase + RemoteAttestation, - NodeApi: PalletTeerexApi, + NodeApi: PalletTeebagApi, WorkerModeProvider: ProvideWorkerMode, >( node_api: &NodeApi, @@ -70,30 +70,32 @@ pub(crate) fn sync_state< /// Note: The sidechainblock author will only change whenever a new parentchain block is /// produced. And even then, it might be the same as the last block. So if several workers /// are started in a timely manner, they will all get the same url. -async fn get_author_url_of_last_finalized_sidechain_block( +async fn get_author_url_of_last_finalized_sidechain_block( node_api: &NodeApi, shard: &ShardIdentifier, ) -> Result { let enclave = node_api - .worker_for_shard(shard, None)? + .primary_enclave_for_shard(WorkerType::Identity, shard, None)? .ok_or_else(|| Error::NoWorkerForShardFound(*shard))?; - let worker_api_direct = DirectWorkerApi::new(enclave.url); + let worker_api_direct = + DirectWorkerApi::new(String::from_utf8_lossy(enclave.url.as_slice()).to_string()); Ok(worker_api_direct.get_mu_ra_url()?) } /// Returns the url of the first Enclave that matches our own MRENCLAVE. /// /// This should be run before we register ourselves as enclave, to ensure we don't get our own url. -async fn get_enclave_url_of_first_registered( +async fn get_enclave_url_of_first_registered( node_api: &NodeApi, enclave_api: &EnclaveApi, ) -> Result { - let self_mr_enclave = enclave_api.get_fingerprint()?; + let self_mrenclave = enclave_api.get_fingerprint()?; let first_enclave = node_api - .all_enclaves(None)? + .all_enclaves(WorkerType::Identity, None)? .into_iter() - .find(|e| e.mr_enclave == self_mr_enclave.to_fixed_bytes()) + .find(|e| e.mrenclave == self_mrenclave.to_fixed_bytes()) .ok_or(Error::NoPeerWorkerFound)?; - let worker_api_direct = DirectWorkerApi::new(first_enclave.url); + let worker_api_direct = + DirectWorkerApi::new(String::from_utf8_lossy(first_enclave.url.as_slice()).to_string()); Ok(worker_api_direct.get_mu_ra_url()?) } diff --git a/tee-worker/service/src/tests/mock.rs b/tee-worker/service/src/tests/mock.rs index 0587669dc4..a36ae0a5ce 100644 --- a/tee-worker/service/src/tests/mock.rs +++ b/tee-worker/service/src/tests/mock.rs @@ -15,8 +15,8 @@ */ -use itp_node_api::api_client::{ApiResult, PalletTeerexApi}; -use itp_types::{Enclave, MrEnclave, ShardIdentifier, H256 as Hash}; +use itp_node_api::api_client::{ApiResult, PalletTeebagApi}; +use itp_types::{AccountId, Enclave, MrEnclave, ShardIdentifier, WorkerType, H256 as Hash}; use std::collections::HashSet; pub struct TestNodeApi; @@ -26,43 +26,44 @@ pub const W2_URL: &str = "127.0.0.1:33333"; pub fn enclaves() -> Vec { vec![ - Enclave::new([0; 32].into(), [1; 32], 1, format!("wss://{}", W1_URL)), - Enclave::new([2; 32].into(), [3; 32], 2, format!("wss://{}", W2_URL)), + Enclave::new(WorkerType::Identity).with_url(W1_URL.into()), + Enclave::new(WorkerType::Identity).with_url(W2_URL.into()), ] } -impl PalletTeerexApi for TestNodeApi { +impl PalletTeebagApi for TestNodeApi { type Hash = Hash; - fn enclave(&self, index: u64, _at_block: Option) -> ApiResult> { - Ok(Some(enclaves().remove(index as usize))) + fn enclave(&self, _account: &AccountId, _at_block: Option) -> ApiResult> { + unreachable!() } - fn enclave_count(&self, _at_block: Option) -> ApiResult { + fn enclave_count(&self, _worker_type: WorkerType, _at_block: Option) -> ApiResult { unreachable!() } - fn all_enclaves(&self, _at_block: Option) -> ApiResult> { + fn all_enclaves( + &self, + _worker_type: WorkerType, + _at_block: Option, + ) -> ApiResult> { Ok(enclaves()) } - fn worker_for_shard( + fn primary_enclave_identifier_for_shard( &self, - _: &ShardIdentifier, - _at_block: Option, - ) -> ApiResult> { + worker_type: WorkerType, + shard: &ShardIdentifier, + at_block: Option, + ) -> ApiResult> { unreachable!() } - fn latest_ipfs_hash( + + fn primary_enclave_for_shard( &self, - _: &ShardIdentifier, - _at_block: Option, - ) -> ApiResult> { + worker_type: WorkerType, + shard: &ShardIdentifier, + at_block: Option, + ) -> ApiResult> { unreachable!() } - - fn all_scheduled_mrenclaves(&self, _at_block: Option) -> ApiResult> { - let enclaves = enclaves(); - let mr_enclaves: HashSet<_> = enclaves.into_iter().map(|e| e.mr_enclave).collect(); - Ok(mr_enclaves.into_iter().collect()) - } } diff --git a/tee-worker/service/src/tests/mocks/enclave_api_mock.rs b/tee-worker/service/src/tests/mocks/enclave_api_mock.rs index af27dd3fae..e9b5d4c884 100644 --- a/tee-worker/service/src/tests/mocks/enclave_api_mock.rs +++ b/tee-worker/service/src/tests/mocks/enclave_api_mock.rs @@ -24,10 +24,9 @@ use itc_parentchain::primitives::{ use itp_enclave_api::{enclave_base::EnclaveBase, sidechain::Sidechain, EnclaveResult}; use itp_settings::worker::MR_ENCLAVE_SIZE; use itp_storage::StorageProof; -use itp_types::ShardIdentifier; +use itp_types::{EnclaveFingerprint, ShardIdentifier}; use sgx_crypto_helper::rsa3072::Rsa3072PubKey; use sp_core::ed25519; -use teerex_primitives::EnclaveFingerprint; /// mock for EnclaveBase - use in tests pub struct EnclaveMock; diff --git a/tee-worker/service/src/worker.rs b/tee-worker/service/src/worker.rs index 638e4f081b..9f96b2a94f 100644 --- a/tee-worker/service/src/worker.rs +++ b/tee-worker/service/src/worker.rs @@ -25,13 +25,14 @@ use async_trait::async_trait; use codec::{Decode, Encode}; use itc_rpc_client::direct_client::{DirectApi, DirectClient as DirectWorkerApi}; use itp_enclave_api::enclave_base::EnclaveBase; -use itp_node_api::{api_client::PalletTeerexApi, node_api_factory::CreateNodeApi}; +use itp_node_api::{api_client::PalletTeebagApi, node_api_factory::CreateNodeApi}; use its_primitives::types::SignedBlock as SignedSidechainBlock; use its_rpc_handler::constants::RPC_METHOD_NAME_IMPORT_BLOCKS; use jsonrpsee::{ types::{to_json_value, traits::Client}, ws_client::WsClientBuilder, }; +use litentry_primitives::WorkerType; use log::*; use std::{ collections::HashSet, @@ -187,11 +188,11 @@ where .node_api_factory .create_api() .map_err(|e| Error::Custom(format!("Failed to create NodeApi: {:?}", e).into()))?; - let enclaves = node_api.all_enclaves(None)?; + let enclaves = node_api.all_enclaves(WorkerType::Identity, None)?; let mut peer_urls = HashSet::::new(); for enclave in enclaves { // FIXME: This is temporary only, as block broadcasting should be moved to trusted ws server. - let enclave_url = enclave.url.clone(); + let enclave_url = String::from_utf8_lossy(enclave.url.as_slice()).to_string(); let worker_api_direct = DirectWorkerApi::new(enclave_url.clone()); match worker_api_direct.get_untrusted_worker_url() { Ok(untrusted_worker_url) => { diff --git a/tee-worker/sidechain/consensus/aura/src/lib.rs b/tee-worker/sidechain/consensus/aura/src/lib.rs index 2ca8b88edb..4114852c73 100644 --- a/tee-worker/sidechain/consensus/aura/src/lib.rs +++ b/tee-worker/sidechain/consensus/aura/src/lib.rs @@ -47,7 +47,7 @@ use its_primitives::{ use its_validateer_fetch::ValidateerFetch; use lc_scheduled_enclave::ScheduledEnclaveUpdater; use litentry_hex_utils::hex_encode; -use sp_core::ByteArray; +use sp_core::crypto::UncheckedFrom; use sp_runtime::{ app_crypto::{sp_core::H256, Pair}, generic::SignedBlock as SignedParentchainBlock, @@ -189,6 +189,7 @@ impl< StateHandler, > where AuthorityPair: Pair, + AuthorityPair::Public: UncheckedFrom<[u8; 32]>, // todo: Relax hash trait bound, but this needs a change to some other parts in the code. ParentchainBlock: ParentchainBlockTrait, E: Environment, @@ -222,7 +223,6 @@ impl< fn epoch_data( &self, header: &ParentchainBlock::Header, - _shard: ShardIdentifierFor, _slot: Slot, ) -> Result { authorities::<_, AuthorityPair, ParentchainBlock::Header>(&self.ocall_api, header) @@ -391,13 +391,14 @@ fn authorities( where ValidateerFetcher: ValidateerFetch + EnclaveOnChainOCallApi, P: Pair, + P::Public: UncheckedFrom<[u8; 32]>, ParentchainHeader: ParentchainHeaderTrait, { Ok(ocall_api - .current_validateers(header) + .current_validateers::(header) .map_err(|e| ConsensusError::CouldNotGetAuthorities(e.to_string()))? - .into_iter() - .filter_map(|e| AuthorityId::

::from_slice(e.pubkey.as_ref()).ok()) + .iter() + .map(|account| P::Public::unchecked_from(*account.as_ref())) .collect()) } @@ -411,14 +412,14 @@ pub enum AnyImportTrigger { mod tests { use super::*; use crate::test::{ - fixtures::{types::TestAura, validateer, SLOT_DURATION}, + fixtures::{types::TestAura, SLOT_DURATION}, mocks::environment_mock::{EnvironmentMock, OutdatedBlockEnvironmentMock}, }; use itc_parentchain_block_import_dispatcher::trigger_parentchain_block_import_mock::TriggerParentchainBlockImportMock; use itc_parentchain_test::{ParentchainBlockBuilder, ParentchainHeaderBuilder}; use itp_test::mock::{handle_state_mock::HandleStateMock, onchain_mock::OnchainMock}; use itp_types::{ - Block as ParentchainBlock, Enclave, Header as ParentchainHeader, ShardIdentifier, + AccountId, Block as ParentchainBlock, Header as ParentchainHeader, ShardIdentifier, SignedBlock as SignedParentchainBlock, }; use its_consensus_slots::PerShardSlotWorkerScheduler; @@ -483,8 +484,8 @@ mod tests { vec![Keyring::Alice.public(), Keyring::Bob.public(), Keyring::Charlie.public()] } - fn create_validateer_set_from_publics(authorities: Vec) -> Vec { - authorities.iter().map(|a| validateer(a.clone().into())).collect() + fn create_validateer_set_from_publics(authorities: Vec) -> Vec { + authorities.iter().map(|a| AccountId::from(a.clone())).collect() } fn onchain_mock( diff --git a/tee-worker/sidechain/consensus/aura/src/test/block_importer_tests.rs b/tee-worker/sidechain/consensus/aura/src/test/block_importer_tests.rs index 447aa18c62..be23004cf0 100644 --- a/tee-worker/sidechain/consensus/aura/src/test/block_importer_tests.rs +++ b/tee-worker/sidechain/consensus/aura/src/test/block_importer_tests.rs @@ -87,10 +87,10 @@ fn test_fixtures( ) -> (TestBlockImporter, Arc, Arc) { let state_handler = Arc::new(HandleStateMock::from_shard(shard()).unwrap()); let top_pool_author = Arc::new(TestTopPoolAuthor::default()); - let ocall_api = Arc::new(OnchainMock::default().add_validateer_set( - parentchain_header, - Some(vec![validateer(Keyring::Alice.public().into())]), - )); + let ocall_api = Arc::new( + OnchainMock::default() + .add_validateer_set(parentchain_header, Some(vec![Keyring::Alice.public().into()])), + ); let state_key_repository = Arc::new(TestStateKeyRepo::new(state_key())); let peer_updater_mock = Arc::new(PeerUpdaterMock {}); diff --git a/tee-worker/sidechain/consensus/aura/src/test/fixtures/mod.rs b/tee-worker/sidechain/consensus/aura/src/test/fixtures/mod.rs index 54d47324fa..de85405549 100644 --- a/tee-worker/sidechain/consensus/aura/src/test/fixtures/mod.rs +++ b/tee-worker/sidechain/consensus/aura/src/test/fixtures/mod.rs @@ -23,5 +23,5 @@ use std::time::Duration; pub const SLOT_DURATION: Duration = Duration::from_millis(300); pub fn validateer(account: AccountId) -> Enclave { - Enclave::new(account, Default::default(), Default::default(), Default::default()) + Enclave::default() } diff --git a/tee-worker/sidechain/consensus/aura/src/verifier.rs b/tee-worker/sidechain/consensus/aura/src/verifier.rs index 0c1f64b138..121cef58eb 100644 --- a/tee-worker/sidechain/consensus/aura/src/verifier.rs +++ b/tee-worker/sidechain/consensus/aura/src/verifier.rs @@ -24,6 +24,7 @@ use its_primitives::{ types::block::BlockHash, }; use its_validateer_fetch::ValidateerFetch; +use sp_core::crypto::UncheckedFrom; use sp_runtime::{app_crypto::Pair, traits::Block as ParentchainBlockTrait}; use std::{fmt::Debug, time::Duration}; @@ -57,7 +58,7 @@ impl for AuraVerifier where AuthorityPair: Pair, - AuthorityPair::Public: Debug, + AuthorityPair::Public: Debug + UncheckedFrom<[u8; 32]>, // todo: Relax hash trait bound, but this needs a change to some other parts in the code. ParentchainBlock: ParentchainBlockTrait, SignedSidechainBlock: SignedSidechainBlockTrait + 'static, diff --git a/tee-worker/sidechain/consensus/common/src/block_import_confirmation_handler.rs b/tee-worker/sidechain/consensus/common/src/block_import_confirmation_handler.rs index be93feb51c..ee2b5f3ede 100644 --- a/tee-worker/sidechain/consensus/common/src/block_import_confirmation_handler.rs +++ b/tee-worker/sidechain/consensus/common/src/block_import_confirmation_handler.rs @@ -20,7 +20,7 @@ use itc_parentchain_light_client::{ concurrent_access::ValidatorAccess, BlockNumberOps, ExtrinsicSender, NumberFor, }; use itp_extrinsics_factory::CreateExtrinsics; -use itp_node_api_metadata::{pallet_sidechain::SidechainCallIndexes, NodeMetadataTrait}; +use itp_node_api_metadata::{pallet_teebag::TeebagCallIndexes, NodeMetadataTrait}; use itp_node_api_metadata_provider::AccessNodeMetadata; use itp_settings::worker::BLOCK_NUMBER_FINALIZATION_DIFF; use itp_types::{OpaqueCall, ShardIdentifier}; @@ -102,7 +102,7 @@ impl< fn confirm_import(&self, header: &SidechainHeader, shard: &ShardIdentifier) -> Result<()> { let call = self .metadata_repository - .get_from_metadata(|m| m.confirm_imported_sidechain_block_indexes()) + .get_from_metadata(|m| m.sidechain_block_imported_call_indexes()) .map_err(|e| Error::Other(e.into()))? .map_err(|e| Error::Other(format!("{:?}", e).into()))?; diff --git a/tee-worker/sidechain/consensus/slots/src/lib.rs b/tee-worker/sidechain/consensus/slots/src/lib.rs index e09e55b1d6..c27f9d2450 100644 --- a/tee-worker/sidechain/consensus/slots/src/lib.rs +++ b/tee-worker/sidechain/consensus/slots/src/lib.rs @@ -206,7 +206,6 @@ pub trait SimpleSlotWorker { fn epoch_data( &self, header: &ParentchainBlock::Header, - shard: ShardIdentifierFor, slot: Slot, ) -> Result; @@ -329,7 +328,7 @@ pub trait SimpleSlotWorker { maybe_latest_target_b_parentchain_header.clone().map(|h| *h.number()) ); - let epoch_data = match self.epoch_data(&latest_integritee_parentchain_header, shard, slot) { + let epoch_data = match self.epoch_data(&latest_integritee_parentchain_header, slot) { Ok(epoch_data) => epoch_data, Err(e) => { warn!( diff --git a/tee-worker/sidechain/consensus/slots/src/mocks.rs b/tee-worker/sidechain/consensus/slots/src/mocks.rs index c84467640d..72d6f9fee8 100644 --- a/tee-worker/sidechain/consensus/slots/src/mocks.rs +++ b/tee-worker/sidechain/consensus/slots/src/mocks.rs @@ -70,12 +70,7 @@ where todo!() } - fn epoch_data( - &self, - _header: &B::Header, - _shard: ShardIdentifierFor, - _slot: Slot, - ) -> Result { + fn epoch_data(&self, _header: &B::Header, _slot: Slot) -> Result { todo!() } diff --git a/tee-worker/sidechain/peer-fetch/Cargo.toml b/tee-worker/sidechain/peer-fetch/Cargo.toml index 63e2612d91..66c10302c9 100644 --- a/tee-worker/sidechain/peer-fetch/Cargo.toml +++ b/tee-worker/sidechain/peer-fetch/Cargo.toml @@ -16,6 +16,7 @@ thiserror = { version = "1.0" } # local itc-rpc-client = { path = "../../core/rpc-client" } itp-node-api = { path = "../../core-primitives/node-api" } +itp-types = { path = "../../core-primitives/types" } its-primitives = { path = "../primitives" } its-rpc-handler = { path = "../rpc-handler" } its-storage = { path = "../storage" } diff --git a/tee-worker/sidechain/peer-fetch/src/untrusted_peer_fetch.rs b/tee-worker/sidechain/peer-fetch/src/untrusted_peer_fetch.rs index 7ff9434103..488590f761 100644 --- a/tee-worker/sidechain/peer-fetch/src/untrusted_peer_fetch.rs +++ b/tee-worker/sidechain/peer-fetch/src/untrusted_peer_fetch.rs @@ -17,7 +17,8 @@ use crate::error::{Error, Result}; use itc_rpc_client::direct_client::{DirectApi, DirectClient as DirectWorkerApi}; -use itp_node_api::{api_client::PalletTeerexApi, node_api_factory::CreateNodeApi}; +use itp_node_api::{api_client::PalletTeebagApi, node_api_factory::CreateNodeApi}; +use itp_types::WorkerType; use its_primitives::types::ShardIdentifier; use std::sync::Arc; @@ -50,10 +51,11 @@ where let node_api = self.node_api_factory.create_api()?; let validateer = node_api - .worker_for_shard(shard, None)? + .primary_enclave_for_shard(WorkerType::Identity, shard, None)? .ok_or_else(|| Error::NoPeerFoundForShard(*shard))?; - let trusted_worker_client = DirectWorkerApi::new(validateer.url); + let trusted_worker_client = + DirectWorkerApi::new(String::from_utf8_lossy(validateer.url.as_slice()).to_string()); Ok(trusted_worker_client.get_untrusted_worker_url()?) } } diff --git a/tee-worker/sidechain/validateer-fetch/Cargo.toml b/tee-worker/sidechain/validateer-fetch/Cargo.toml index 7aca2dbf7a..2df88400d5 100644 --- a/tee-worker/sidechain/validateer-fetch/Cargo.toml +++ b/tee-worker/sidechain/validateer-fetch/Cargo.toml @@ -15,11 +15,8 @@ sp-std = { default-features = false, git = "https://github.com/paritytech/substr # local deps itp-ocall-api = { path = "../../core-primitives/ocall-api", default-features = false } -itp-teerex-storage = { path = "../../core-primitives/teerex-storage", default-features = false } itp-types = { path = "../../core-primitives/types", default-features = false } - -# litentry -frame-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +lc-teebag-storage = { path = "../../litentry/core/teebag-storage", default-features = false } [features] default = ["std"] @@ -30,7 +27,7 @@ std = [ "sp-std/std", "itp-types/std", "itp-ocall-api/std", - "frame-support/std", + "lc-teebag-storage/std", ] [dev-dependencies] diff --git a/tee-worker/sidechain/validateer-fetch/src/validateer.rs b/tee-worker/sidechain/validateer-fetch/src/validateer.rs index 4af8d86274..37373c0f32 100644 --- a/tee-worker/sidechain/validateer-fetch/src/validateer.rs +++ b/tee-worker/sidechain/validateer-fetch/src/validateer.rs @@ -16,10 +16,9 @@ */ use crate::error::{Error, Result}; -use frame_support::ensure; use itp_ocall_api::EnclaveOnChainOCallApi; -use itp_teerex_storage::{TeeRexStorage, TeerexStorageKeys}; -use itp_types::{parentchain::ParentchainId, Enclave}; +use itp_types::{parentchain::ParentchainId, AccountId, WorkerType}; +use lc_teebag_storage::{TeebagStorage, TeebagStorageKeys}; use sp_core::H256; use sp_runtime::traits::Header as HeaderT; use sp_std::prelude::Vec; @@ -28,7 +27,8 @@ pub trait ValidateerFetch { fn current_validateers>( &self, latest_header: &Header, - ) -> Result>; + ) -> Result>; + fn validateer_count>(&self, latest_header: &Header) -> Result; } @@ -37,31 +37,21 @@ impl ValidateerFetch for OnchainStorage fn current_validateers>( &self, header: &Header, - ) -> Result> { - let count = self.validateer_count(header)?; - - let mut hashes = Vec::with_capacity(count as usize); - for i in 1..=count { - hashes.push(TeeRexStorage::enclave(i)) - } - - let enclaves: Vec = self - .get_multiple_storages_verified(hashes, header, &ParentchainId::Litentry)? - .into_iter() - .filter_map(|e| e.into_tuple().1) - .collect(); - ensure!( - enclaves.len() == count as usize, - Error::Other("Found less validateers onchain than validateer count") - ); - Ok(enclaves) + ) -> Result> { + let identifiers = self + .get_storage_verified( + TeebagStorage::enclave_identifier(WorkerType::Identity), + header, + &ParentchainId::Litentry, + )? + .into_tuple() + .1 + .ok_or_else(|| Error::Other("Could not get validateer list from chain"))?; + Ok(identifiers) } fn validateer_count>(&self, header: &Header) -> Result { - self.get_storage_verified(TeeRexStorage::enclave_count(), header, &ParentchainId::Litentry)? - .into_tuple() - .1 - .ok_or_else(|| Error::Other("Could not get validateer count from chain")) + Ok(self.current_validateers::

(header)?.len() as u64) } } @@ -84,21 +74,7 @@ mod tests { pub fn get_validateer_set_works() { let header = ParentchainHeaderBuilder::default().build(); let mock = OnchainMock::default().add_validateer_set(&header, None); - let validateers = validateer_set(); - assert_eq!(mock.current_validateers(&header).unwrap(), validateers); } - - #[test] - pub fn if_validateer_count_bigger_than_returned_validateers_return_err() { - let header = ParentchainHeaderBuilder::default().build(); - let mut mock = OnchainMock::default().add_validateer_set(&header, None); - mock.insert_at_header(&header, TeeRexStorage::enclave_count(), 5u64.encode()); - - assert_eq!( - mock.current_validateers(&header).unwrap_err().to_string(), - "Found less validateers onchain than validateer count".to_string() - ); - } } diff --git a/tee-worker/ts-tests/integration-tests/common/utils/assertion.ts b/tee-worker/ts-tests/integration-tests/common/utils/assertion.ts index 54e4c91906..7a28ebf5a4 100644 --- a/tee-worker/ts-tests/integration-tests/common/utils/assertion.ts +++ b/tee-worker/ts-tests/integration-tests/common/utils/assertion.ts @@ -6,7 +6,7 @@ import { assert, expect } from 'chai'; import * as ed from '@noble/ed25519'; import { parseIdGraph } from './identity-helper'; import type { PalletIdentityManagementTeeError } from 'sidechain-api'; -import { TeerexPrimitivesEnclave, CorePrimitivesIdentity } from 'parachain-api'; +import { PalletTeebagEnclave, CorePrimitivesIdentity } from 'parachain-api'; import type { IntegrationTestContext } from '../common-types'; import { getIdGraphHash } from '../di-utils'; import type { HexString } from '@polkadot/util/types'; @@ -135,14 +135,17 @@ export async function checkErrorDetail(events: Event[], expectedDetail: string) } export async function verifySignature(data: any, index: HexString, proofJson: any, api: ApiPromise) { - const count = await api.query.teerex.enclaveCount(); - const enclaveRegistry = (await api.query.teerex.enclaveRegistry(count)) as unknown as TeerexPrimitivesEnclave; + const enclaveIdentifier = api.createType('Vec', await api.query.teebag.enclaveIdentifier('Identity')); + const primaryEnclave = ( + await api.query.teebag.enclaveRegistry(enclaveIdentifier[0]) + ).toHuman() as unknown as PalletTeebagEnclave; // Check vc index expect(index).to.be.eq(data.id); const signature = Buffer.from(hexToU8a(`0x${proofJson.proofValue}`)); const message = Buffer.from(data.issuer.mrenclave); - const vcPubkey = Buffer.from(hexToU8a(enclaveRegistry.toHuman()['vcPubkey'] as HexString)); + const vcPubkeyBytes = api.createType('Option', primaryEnclave.vcPubkey).unwrap(); + const vcPubkey = Buffer.from(hexToU8a(vcPubkeyBytes.toHex())); const isValid = await ed.verify(signature, message, vcPubkey); @@ -277,19 +280,20 @@ export async function assertVc(context: IntegrationTestContext, subject: CorePri const { proof, ...vcWithoutProof } = vcPayloadJson; // step 5 - // prepare teerex enclave registry data for further checks + // prepare teebag enclave registry data for further checks const parachainBlockHash = await context.api.query.system.blockHash(vcPayloadJson.parachainBlockNumber); const apiAtVcIssuedBlock = await context.api.at(parachainBlockHash); - const enclaveCount = await apiAtVcIssuedBlock.query.teerex.enclaveCount(); - - const lastRegisteredEnclave = (await apiAtVcIssuedBlock.query.teerex.enclaveRegistry(enclaveCount)) - .value as TeerexPrimitivesEnclave; + const enclaveIdentifier = await apiAtVcIssuedBlock.query.teebag.enclaveIdentifier('Identity'); + const lastRegisteredEnclave = ( + await apiAtVcIssuedBlock.query.teebag.enclaveRegistry(enclaveIdentifier[enclaveIdentifier.length - 1]) + ).unwrap(); // step 6 // check vc signature const signature = Buffer.from(hexToU8a(`0x${proof.proofValue}`)); const message = Buffer.from(JSON.stringify(vcWithoutProof)); - const vcPubkey = Buffer.from(lastRegisteredEnclave.vcPubkey.value); + const vcPubkeyBytes = context.api.createType('Option', lastRegisteredEnclave.vcPubkey).unwrap(); + const vcPubkey = Buffer.from(hexToU8a(vcPubkeyBytes.toHex())); const signatureStatus = await ed.verify(signature, message, vcPubkey); assert.isTrue(signatureStatus, 'Check Vc signature error: signature should be valid'); @@ -297,7 +301,7 @@ export async function assertVc(context: IntegrationTestContext, subject: CorePri // step 7 // check VC mrenclave with enclave's mrenclave from registry assert.equal( - base58.encode(lastRegisteredEnclave.mrEnclave), + base58.encode(lastRegisteredEnclave.mrenclave), vcPayloadJson.issuer.mrenclave, 'Check VC mrenclave: it should equals enclaves mrenclave from parachains enclave registry' ); @@ -305,7 +309,7 @@ export async function assertVc(context: IntegrationTestContext, subject: CorePri // step 8 // check vc issuer id assert.equal( - `did:litentry:substrate:${lastRegisteredEnclave.vcPubkey.value.toHex()}`, + `did:litentry:substrate:${vcPubkeyBytes.toHex()}`, vcPayloadJson.issuer.id, 'Check VC id: it should equals enclaves pubkey from parachains enclave registry' ); diff --git a/tee-worker/ts-tests/integration-tests/common/utils/context.ts b/tee-worker/ts-tests/integration-tests/common/utils/context.ts index 2903aa1227..4b9d5d9d26 100644 --- a/tee-worker/ts-tests/integration-tests/common/utils/context.ts +++ b/tee-worker/ts-tests/integration-tests/common/utils/context.ts @@ -1,6 +1,7 @@ -import { WsProvider, ApiPromise, TeerexPrimitivesEnclave } from 'parachain-api'; +import { WsProvider, ApiPromise } from 'parachain-api'; import { Keyring } from '@polkadot/api'; import { cryptoWaitReady } from '@polkadot/util-crypto'; +import { hexToString } from '@polkadot/util'; import { ethers } from 'ethers'; import WebSocketAsPromised from 'websocket-as-promised'; import WebSocket from 'ws'; @@ -85,28 +86,24 @@ export async function getEnclave(api: ApiPromise): Promise<{ mrEnclave: HexString; teeShieldingKey: KeyObject; }> { - const count = await api.query.teerex.enclaveCount(); + const enclaveIdentifier = api.createType('Vec', await api.query.teebag.enclaveIdentifier('Identity')); + const primaryEnclave = (await api.query.teebag.enclaveRegistry(enclaveIdentifier[0])).unwrap(); - const enclaveRegistry = ( - await api.query.teerex.enclaveRegistry(count) - ).toHuman() as unknown as TeerexPrimitivesEnclave; + const shieldingPubkeyBytes = api.createType('Option', primaryEnclave.shieldingPubkey).unwrap(); + const shieldingPubkey = hexToString(shieldingPubkeyBytes.toHex()); const teeShieldingKey = crypto.createPublicKey({ key: { alg: 'RSA-OAEP-256', kty: 'RSA', use: 'enc', - n: Buffer.from(JSON.parse(enclaveRegistry.shieldingKey as unknown as HexString).n.reverse()).toString( - 'base64url' - ), - e: Buffer.from(JSON.parse(enclaveRegistry.shieldingKey as unknown as HexString).e.reverse()).toString( - 'base64url' - ), + n: Buffer.from(JSON.parse(shieldingPubkey).n.reverse()).toString('base64url'), + e: Buffer.from(JSON.parse(shieldingPubkey).e.reverse()).toString('base64url'), }, format: 'jwk', }); //@TODO mrEnclave should verify from storage - const mrEnclave = enclaveRegistry.mrEnclave as unknown as HexString; + const mrEnclave = primaryEnclave.mrenclave.toHex(); return { mrEnclave, teeShieldingKey, diff --git a/tee-worker/ts-tests/integration-tests/vc.issuer.attest.example.ts b/tee-worker/ts-tests/integration-tests/vc.issuer.attest.example.ts index 3e25a7b1b7..1945a06f92 100644 --- a/tee-worker/ts-tests/integration-tests/vc.issuer.attest.example.ts +++ b/tee-worker/ts-tests/integration-tests/vc.issuer.attest.example.ts @@ -69,11 +69,10 @@ const vc = { * */ const enclaveRegistry = { - pubkey: 'jcPcHgptXWGsTAefDqW7GpbX8LYrNVEYLLKihV3RsizqSga1Z', - mrEnclave: '0x168b47aceff04e8cd20f4606a7eb255ffc1981cd3b8ba1d44face858f9a4c25b', - timestamp: '1,677,164,874,078', + mrenclave: '0x168b47aceff04e8cd20f4606a7eb255ffc1981cd3b8ba1d44face858f9a4c25b', + lastSeen: '1,677,164,874,078', url: 'wss://localhost:2000', - shieldingKey: + shieldingPubkey: '{n:[189,64,222,165,185,105,241,193,170,87,19,231,76,95,247,110,231,7,196,65,135,231,55,75,60,58,158,23,77,230,154,23,203,167,163,219,18,113,83,23,172,131,29,222,200,73,217,159,155,120,217,194,74,33,79,99,88,227,2,242,225,141,116,231,89,68,119,109,183,56,135,70,151,177,245,199,196,222,193,33,28,47,252,83,240,120,238,81,99,154,219,75,84,108,96,199,108,42,64,70,217,164,89,81,156,188,168,181,169,228,21,140,90,18,126,77,50,31,19,149,26,86,160,108,197,78,134,19,54,25,89,80,239,106,95,226,42,109,202,54,158,128,224,243,1,197,209,131,48,1,208,207,48,197,66,44,203,76,113,150,100,73,81,17,94,153,217,11,14,193,230,43,207,24,236,200,207,15,63,16,75,173,191,245,127,191,186,18,111,111,90,24,177,167,177,7,61,94,60,161,130,242,31,210,158,152,31,35,202,80,179,138,219,244,139,19,60,134,108,94,151,228,224,22,29,139,21,241,71,221,65,145,210,108,80,0,76,137,98,128,107,224,16,32,135,232,168,150,9,225,30,120,17,176,26,2,8,100,185,121,158,67,89,110,130,126,122,113,248,169,73,27,52,90,109,66,249,255,161,105,174,129,163,7,14,180,63,178,218,81,86,108,116,118,81,185,248,231,84,150,13,140,49,239,103,44,119,97,37,30,13,230,100,73,24,229,178,3,89,14,26,155,245,254,12,152,7,72,209,209,24,224,5,131,144,124,254,204,209,138,57,196,176,244,231,185,190,187,118,215,46,45,57,81,238,163,11,152,73,217,252,9,77,95,86,4,201,34,68,88,235,103,15,120,159,134,5,182,83,122,128,111,160,141],e:[1,0,0,1]}', vcPubkey: '0xde17d6daedb66ec9f5e096cc0317bd6cbf881c0d8273e54105ee7c22a2e48648', sgxMode: 'Debug', @@ -95,7 +94,7 @@ function checkIssuerAttestation() { console.log(' [IssuerAttestation] mrEnclaveFromVc: ', mrEnclaveFromVc); // Fetch mrEnclave from parachain - const mrEnclaveFromParachain = enclaveRegistry.mrEnclave; + const mrEnclaveFromParachain = enclaveRegistry.mrenclave; console.log(' [IssuerAttestation] mrEnclaveFromParachain: ', mrEnclaveFromParachain); // >>>0. Check mrEnclave diff --git a/tee-worker/ts-tests/stress/src/litentry-api.ts b/tee-worker/ts-tests/stress/src/litentry-api.ts index af3b425aed..7f8e9f79a1 100644 --- a/tee-worker/ts-tests/stress/src/litentry-api.ts +++ b/tee-worker/ts-tests/stress/src/litentry-api.ts @@ -8,6 +8,7 @@ import { u8aToHex, u8aConcat, stringToU8a, + hexToString, } from '@polkadot/util'; import { blake2AsHex } from '@polkadot/util-crypto'; import crypto, { KeyObject, createPublicKey } from 'crypto'; @@ -341,27 +342,25 @@ export async function getEnclave(api: ParachainApiPromise): Promise<{ mrEnclave: `0x${string}`; teeShieldingKey: KeyObject; }> { - const count = await api.query.teerex.enclaveCount(); + const enclaveIdentifier = api.createType('Vec', await api.query.teebag.enclaveIdentifier('Identity')); + const primaryEnclave = (await api.query.teebag.enclaveRegistry(enclaveIdentifier[0])).unwrap(); - const res = (await api.query.teerex.enclaveRegistry(count)).toHuman() as { - mrEnclave: `0x${string}`; - shieldingKey: `0x${string}`; - vcPubkey: `0x${string}`; - sgxMetadata: object; - }; + const shieldingPubkeyBytes = api.createType('Option', primaryEnclave.shieldingPubkey).unwrap(); + const shieldingPubkey = hexToString(shieldingPubkeyBytes.toHex()); const teeShieldingKey = crypto.createPublicKey({ key: { alg: 'RSA-OAEP-256', kty: 'RSA', use: 'enc', - n: Buffer.from(JSON.parse(res.shieldingKey).n.reverse()).toString('base64url'), - e: Buffer.from(JSON.parse(res.shieldingKey).e.reverse()).toString('base64url'), + n: Buffer.from(JSON.parse(shieldingPubkey).n.reverse()).toString('base64url'), + e: Buffer.from(JSON.parse(shieldingPubkey).e.reverse()).toString('base64url'), }, format: 'jwk', }); //@TODO mrEnclave should verify from storage - const mrEnclave = res.mrEnclave; + const mrEnclave = primaryEnclave.mrenclave.toHex(); + return { mrEnclave, teeShieldingKey, diff --git a/tee-worker/ts-tests/worker/resuming_worker.test.ts b/tee-worker/ts-tests/worker/resuming_worker.test.ts index f5a7f49c1d..0e3060de9d 100644 --- a/tee-worker/ts-tests/worker/resuming_worker.test.ts +++ b/tee-worker/ts-tests/worker/resuming_worker.test.ts @@ -141,7 +141,7 @@ async function spawnWorkerJob( let shard: HexString | undefined = undefined; const job = spawn( - `./litentry-worker`, + `RUST_LOG=info ./litentry-worker`, [generateWorkerCommandArguments(command, nodeConfig, workerConfig)], { cwd: workingDir, diff --git a/ts-tests/common/setup/setup-enclave.ts b/ts-tests/common/setup/setup-enclave.ts index 36faf3db7b..818236a978 100644 --- a/ts-tests/common/setup/setup-enclave.ts +++ b/ts-tests/common/setup/setup-enclave.ts @@ -11,17 +11,17 @@ async function setAliceAsAdmin(api: ApiPromise, config: any) { const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); - const tx = api.tx.sudo.sudo(api.tx.teerex.setAdmin('esqZdrqhgH8zy1wqYh1aLKoRyoRWLFbX9M62eKfaTAoK67pJ5')); + const tx = api.tx.sudo.sudo(api.tx.teebag.setAdmin('esqZdrqhgH8zy1wqYh1aLKoRyoRWLFbX9M62eKfaTAoK67pJ5')); - console.log(`Setting Alice as Admin for Teerex`); + console.log(`Setting Alice as Admin for Teebag`); return signAndSend(tx, alice); } -async function updateScheduledEnclave(api: ApiPromise, config: any) { +async function setScheduledEnclave(api: ApiPromise, config: any) { const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); - const tx = api.tx.teerex.updateScheduledEnclave(block, hexToU8a(`0x${mrenclave}`)); + const tx = api.tx.teebag.setScheduledEnclave('Identity', block, hexToU8a(`0x${mrenclave}`)); console.log('Schedule Enclave Extrinsic sent'); return signAndSend(tx, alice); @@ -37,7 +37,7 @@ async function updateScheduledEnclave(api: ApiPromise, config: any) { }); await setAliceAsAdmin(api, config); - await updateScheduledEnclave(api, config); + await setScheduledEnclave(api, config); await api.disconnect(); provider.on('disconnected', () => { diff --git a/ts-tests/common/setup/skip-schedule-enclave-check.ts b/ts-tests/common/setup/teebag-set-dev-mode.ts similarity index 68% rename from ts-tests/common/setup/skip-schedule-enclave-check.ts rename to ts-tests/common/setup/teebag-set-dev-mode.ts index 47e150d6d5..fc41a5c1dd 100644 --- a/ts-tests/common/setup/skip-schedule-enclave-check.ts +++ b/ts-tests/common/setup/teebag-set-dev-mode.ts @@ -1,29 +1,25 @@ import '@polkadot/api-augment'; import { ApiPromise, Keyring, WsProvider } from '@polkadot/api'; import { loadConfig, signAndSend } from '../utils'; -import { hexToU8a } from '@polkadot/util'; - -const mrenclave = process.argv[2]; -const block = process.argv[3]; async function setAliceAsAdmin(api: ApiPromise, config: any) { // Get keyring of Alice, who is also the sudo in dev chain spec const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); - const tx = api.tx.sudo.sudo(api.tx.teerex.setAdmin('esqZdrqhgH8zy1wqYh1aLKoRyoRWLFbX9M62eKfaTAoK67pJ5')); + const tx = api.tx.sudo.sudo(api.tx.teebag.setAdmin('esqZdrqhgH8zy1wqYh1aLKoRyoRWLFbX9M62eKfaTAoK67pJ5')); - console.log(`Setting Alice as Admin for Teerex`); + console.log(`Setting Alice as Admin for Teebag`); return signAndSend(tx, alice); } -async function updateSkipScheduledEnclaveCheck(api: ApiPromise, config: any) { +async function setDevelopmentMode(api: ApiPromise, config: any) { const keyring = new Keyring({ type: 'sr25519' }); const alice = keyring.addFromUri('//Alice'); - const tx = api.tx.teerex.setSkipScheduledEnclaveCheck(true); + const tx = api.tx.teebag.setMode('Development'); - console.log('set Skip Schedule Enclave Extrinsic sent'); + console.log('set development mode Extrinsic sent'); return signAndSend(tx, alice); } @@ -37,7 +33,7 @@ async function updateSkipScheduledEnclaveCheck(api: ApiPromise, config: any) { }); await setAliceAsAdmin(api, config); - await updateSkipScheduledEnclaveCheck(api, config); + await setDevelopmentMode(api, config); await api.disconnect(); provider.on('disconnected', () => {