From 3fb4a6b47c9998a504726e1b4776689ad16ccb0c Mon Sep 17 00:00:00 2001 From: ytqaljn <2716693942@qq.com> Date: Mon, 11 Dec 2023 23:13:55 -0800 Subject: [PATCH] feat: tee independent registration function --- pallets/audit/src/lib.rs | 10 +++ pallets/file-bank/src/lib.rs | 25 +++++- pallets/tee-worker/src/lib.rs | 130 +++++++++++++++++++++++++------- pallets/tee-worker/src/types.rs | 12 ++- 4 files changed, 143 insertions(+), 34 deletions(-) diff --git a/pallets/audit/src/lib.rs b/pallets/audit/src/lib.rs index 3e4a299a..849479d6 100644 --- a/pallets/audit/src/lib.rs +++ b/pallets/audit/src/lib.rs @@ -279,6 +279,8 @@ pub mod pallet { RandomErr, UnSubmitted, + + TeeNoPermission, } //Relevant time nodes for storage challenges @@ -518,6 +520,10 @@ pub mod pallet { tee_signature: _, } = &challenge_info.miner_snapshot; + ensure!( + T::TeeWorkerHandler::can_verify(&tee_acc), + Error::::TeeNoPermission + ); let verify_idle_info = VerifyIdleResultInfo:: { miner: sender.clone(), miner_prove: total_prove_hash.clone(), @@ -630,6 +636,10 @@ pub mod pallet { tee_signature: _, } = challenge_info.miner_snapshot; + ensure!( + T::TeeWorkerHandler::can_verify(&tee_acc), + Error::::TeeNoPermission + ); let verify_service_info = VerifyServiceResultInfo:: { miner: sender.clone(), tee_acc: tee_acc.clone(), diff --git a/pallets/file-bank/src/lib.rs b/pallets/file-bank/src/lib.rs index b9474fd2..37118a28 100755 --- a/pallets/file-bank/src/lib.rs +++ b/pallets/file-bank/src/lib.rs @@ -262,6 +262,8 @@ pub mod pallet { VerifyTeeSigFailed, InsufficientReplaceable, + + TeeNoPermission, } #[pallet::storage] @@ -659,12 +661,20 @@ pub mod pallet { origin: OriginFor, idle_sig_info: SpaceProofInfo>, tee_sig: TeeRsaSignature, + tee_acc: AccountOf, ) -> DispatchResult { let sender = ensure_signed(origin)?; - let original = idle_sig_info.encode(); + ensure!( + T::TeeWorkerHandler::can_cert(&tee_acc), + Error::::TeeNoPermission + ); + let idle_sig_info_encode = idle_sig_info.encode(); + let tee_acc_encode = tee_acc.encode(); + let mut original = Vec::new(); + original.extend_from_slice(&idle_sig_info_encode); + original.extend_from_slice(&tee_acc_encode); let original = sp_io::hashing::sha2_256(&original); - let tee_puk = T::TeeWorkerHandler::get_tee_publickey()?; ensure!(verify_rsa(&tee_puk, &original, &tee_sig), Error::::VerifyTeeSigFailed); @@ -741,10 +751,19 @@ pub mod pallet { origin: OriginFor, idle_sig_info: SpaceProofInfo>, tee_sig: TeeRsaSignature, + tee_acc: AccountOf, ) -> DispatchResult { let sender = ensure_signed(origin)?; - let original = idle_sig_info.encode(); + ensure!( + T::TeeWorkerHandler::can_cert(&tee_acc), + Error::::TeeNoPermission + ); + let idle_sig_info_encode = idle_sig_info.encode(); + let tee_acc_encode = tee_acc.encode(); + let mut original = Vec::new(); + original.extend_from_slice(&idle_sig_info_encode); + original.extend_from_slice(&tee_acc_encode); let original = sp_io::hashing::sha2_256(&original); let tee_puk = T::TeeWorkerHandler::get_tee_publickey()?; diff --git a/pallets/tee-worker/src/lib.rs b/pallets/tee-worker/src/lib.rs index af1e5915..e8d5549b 100644 --- a/pallets/tee-worker/src/lib.rs +++ b/pallets/tee-worker/src/lib.rs @@ -83,7 +83,7 @@ pub mod pallet { //Already registered AlreadyRegistration, //Not a controller account - NotController, + NotStash, //The scheduled error report has been reported once AlreadyReport, //Boundedvec conversion error @@ -104,14 +104,24 @@ pub mod pallet { Existed, CesealRejected, + InvalidIASSigningCert, + InvalidReport, + InvalidQuoteStatus, + BadIASReport, + OutdatedIASReport, + UnknownQuoteBodyFormat, + InvalidCesealInfoHash, + NoneAttestationDisabled, + + WrongTeeType, } #[pallet::storage] @@ -131,6 +141,10 @@ pub mod pallet { #[pallet::getter(fn mr_enclave_whitelist)] pub(super) type MrEnclaveWhitelist = StorageValue<_, BoundedVec<[u8; 64], T::MaxWhitelist>, ValueQuery>; + #[pallet::storage] + #[pallet::getter(fn validation_type_list)] + pub(super) type ValidationTypeList = StorageValue<_, BoundedVec, T::SchedulerMaximum>, ValueQuery>; + #[pallet::pallet] pub struct Pallet(_); #[pallet::call] @@ -152,20 +166,26 @@ pub mod pallet { #[pallet::weight(::WeightInfo::registration_scheduler())] pub fn register( origin: OriginFor, - stash_account: AccountOf, + worker_account: AccountOf, + stash_account: Option>, peer_id: PeerId, podr2_pbk: Podr2Key, sgx_attestation_report: SgxAttestationReport, end_point: EndPoint, + tee_type: TeeType, ) -> DispatchResult { let sender = ensure_signed(origin)?; //Even if the primary key is not present here, panic will not be caused - let acc = >::bonded(&stash_account) - .ok_or(Error::::NotBond)?; - if sender != acc { - Err(Error::::NotController)?; - } - ensure!(!TeeWorkerMap::::contains_key(&sender), Error::::AlreadyRegistration); + match &stash_account { + Some(acc) => { + ensure!(&sender == acc, Error::::NotStash); + let _ = >::bonded(acc).ok_or(Error::::NotBond)?; + ensure!(tee_type == TeeType::Verifier || tee_type == TeeType::Full, Error::::WrongTeeType); + }, + None => ensure!(tee_type == TeeType::Certifier || tee_type == TeeType::Marker, Error::::WrongTeeType), + }; + + ensure!(!TeeWorkerMap::::contains_key(&worker_account), Error::::AlreadyRegistration); let attestation = Attestation::SgxIas { ra_report: sgx_attestation_report.report_json_raw.to_vec(), @@ -176,12 +196,14 @@ pub mod pallet { }; // Validate RA report & embedded user data + let worker_account_encode = worker_account.encode(); let mut identity = Vec::new(); identity.extend_from_slice(&peer_id); identity.extend_from_slice(&podr2_pbk); identity.extend_from_slice(&end_point); + identity.extend_from_slice(&worker_account_encode); let now = T::UnixTime::now().as_secs(); - + let _ = IasValidator::validate( &attestation, &sp_io::hashing::sha2_256(&identity), @@ -191,19 +213,26 @@ pub mod pallet { ).map_err(Into::>::into)?; let tee_worker_info = TeeWorkerInfo:: { - controller_account: sender.clone(), peer_id: peer_id.clone(), - stash_account: stash_account, + bond_stash: stash_account, end_point, + tee_type: tee_type.clone(), }; + if tee_type == TeeType::Full || tee_type == TeeType::Verifier { + ValidationTypeList::::mutate(|tee_list| -> DispatchResult { + tee_list.try_push(worker_account.clone()).map_err(|_| Error::::BoundedVecError)?; + Ok(()) + })?; + } + if TeeWorkerMap::::count() == 0 { >::put(podr2_pbk); } - TeeWorkerMap::::insert(&sender, tee_worker_info); + TeeWorkerMap::::insert(&worker_account, tee_worker_info); - Self::deposit_event(Event::::RegistrationTeeWorker { acc: sender, peer_id: peer_id }); + Self::deposit_event(Event::::RegistrationTeeWorker { acc: worker_account, peer_id: peer_id }); Ok(()) } @@ -244,6 +273,13 @@ pub mod pallet { pub fn exit(origin: OriginFor) -> DispatchResult { let sender = ensure_signed(origin)?; + let tee_info = TeeWorkerMap::::try_get(&sender).map_err(|_| Error::::Overflow)?; + if tee_info.tee_type == TeeType::Full || tee_info.tee_type == TeeType::Verifier { + ValidationTypeList::::mutate(|tee_list| { + tee_list.retain(|tee_acc| *tee_acc != sender.clone()); + }); + } + TeeWorkerMap::::remove(&sender); if TeeWorkerMap::::count() == 0 { @@ -272,18 +308,19 @@ pub mod pallet { #[pallet::weight(::WeightInfo::registration_scheduler())] pub fn force_register( origin: OriginFor, - stash_account: AccountOf, + stash_account: Option>, controller_account: AccountOf, peer_id: PeerId, end_point: EndPoint, + tee_type: TeeType, ) -> DispatchResult { let _ = ensure_root(origin)?; let tee_worker_info = TeeWorkerInfo:: { - controller_account: controller_account.clone(), peer_id: peer_id.clone(), - stash_account: stash_account, + bond_stash: stash_account, end_point, + tee_type: tee_type, }; TeeWorkerMap::::insert(&controller_account, tee_worker_info); @@ -309,37 +346,72 @@ pub mod pallet { } } pub trait TeeWorkerHandler { + fn can_tag(acc: &AccountId) -> bool; + fn can_verify(acc: &AccountId) -> bool; + fn can_cert(acc: &AccountId) -> bool; fn contains_scheduler(acc: AccountId) -> bool; + fn is_bonded(acc: AccountId) -> bool; fn punish_scheduler(acc: AccountId) -> DispatchResult; - fn get_first_controller() -> Result; fn get_controller_list() -> Vec; fn get_tee_publickey() -> Result; } impl TeeWorkerHandler<::AccountId> for Pallet { + fn can_tag(acc: &AccountOf) -> bool { + if let Ok(tee_info) = TeeWorkerMap::::try_get(&acc) { + if TeeType::Marker == tee_info.tee_type || TeeType::Full == tee_info.tee_type { + return true; + } + } + + false + } + + fn can_verify(acc: &AccountOf) -> bool { + if let Ok(tee_info) = TeeWorkerMap::::try_get(acc) { + if TeeType::Verifier == tee_info.tee_type || TeeType::Full == tee_info.tee_type { + return true; + } + } + + false + } + + fn can_cert(acc: &AccountOf) -> bool { + if let Ok(tee_info) = TeeWorkerMap::::try_get(acc) { + if TeeType::Certifier == tee_info.tee_type || TeeType::Full == tee_info.tee_type { + return true; + } + } + + false + } + fn contains_scheduler(acc: ::AccountId) -> bool { TeeWorkerMap::::contains_key(&acc) } + fn is_bonded(acc: AccountOf) -> bool { + if let Ok(tee_info) = TeeWorkerMap::::try_get(&acc) { + let result = tee_info.bond_stash.is_some(); + return result; + } + + false + } + fn punish_scheduler(acc: ::AccountId) -> DispatchResult { let tee_worker = TeeWorkerMap::::try_get(&acc).map_err(|_| Error::::NonTeeWorker)?; - pallet_cess_staking::slashing::slash_scheduler::(&tee_worker.stash_account); - T::CreditCounter::record_punishment(&tee_worker.stash_account)?; + if let Some(stash_account) = tee_worker.bond_stash { + pallet_cess_staking::slashing::slash_scheduler::(&stash_account); + T::CreditCounter::record_punishment(&stash_account)?; + } Ok(()) } - fn get_first_controller() -> Result<::AccountId, DispatchError> { - let (controller_acc, _) = TeeWorkerMap::::iter().next().ok_or(Error::::NonTeeWorker)?; - return Ok(controller_acc); - } - fn get_controller_list() -> Vec> { - let mut acc_list: Vec> = Default::default(); - - for (acc, _) in >::iter() { - acc_list.push(acc); - } + let acc_list = >::get().to_vec(); acc_list } diff --git a/pallets/tee-worker/src/types.rs b/pallets/tee-worker/src/types.rs index 95f394d1..995bcde4 100644 --- a/pallets/tee-worker/src/types.rs +++ b/pallets/tee-worker/src/types.rs @@ -4,10 +4,10 @@ use super::*; #[scale_info(skip_type_params(T))] #[codec(mel_bound())] pub struct TeeWorkerInfo { - pub controller_account: AccountOf, pub peer_id: PeerId, - pub stash_account: AccountOf, + pub bond_stash: Option>, pub end_point: EndPoint, + pub tee_type: TeeType, } #[derive(PartialEq, Eq, Encode, Decode, Clone, RuntimeDebug, Default, MaxEncodedLen, TypeInfo)] @@ -15,4 +15,12 @@ pub struct SgxAttestationReport { pub report_json_raw: Report, pub sign: ReportSign, pub cert_der: Cert, +} + +#[derive(PartialEq, Eq, Encode, Decode, Clone, RuntimeDebug, MaxEncodedLen, TypeInfo)] +pub enum TeeType { + Full, + Certifier, + Verifier, + Marker, } \ No newline at end of file