diff --git a/crates/phactory/api/src/ecall_args.rs b/crates/phactory/api/src/ecall_args.rs index dbaead1b20..6f3b8f23b6 100644 --- a/crates/phactory/api/src/ecall_args.rs +++ b/crates/phactory/api/src/ecall_args.rs @@ -45,6 +45,9 @@ pub struct InitArgs { /// The timeout of getting the attestation report. pub ra_timeout: Duration, + + /// The max retry times of getting the attestation report. + pub ra_max_retries: u32, } pub use phala_git_revision::git_revision; diff --git a/crates/phactory/src/prpc_service.rs b/crates/phactory/src/prpc_service.rs index 4687c01d09..982ac84527 100644 --- a/crates/phactory/src/prpc_service.rs +++ b/crates/phactory/src/prpc_service.rs @@ -564,6 +564,7 @@ impl Phactory self.attestation_provider, &runtime_info_hash, self.args.ra_timeout, + self.args.ra_max_retries, )?; cached_resp.attestation = Some(report); } @@ -1235,16 +1236,26 @@ fn create_attestation_report_on( attestation_provider: Option, data: &[u8], timeout: Duration, + max_retries: u32, ) -> RpcResult { - let encoded_report = - match platform.create_attestation_report(attestation_provider, data, timeout) { + let mut tried = 0; + let encoded_report = loop { + break match platform.create_attestation_report(attestation_provider, data, timeout) { Ok(r) => r, Err(e) => { let message = format!("Failed to create attestation report: {e:?}"); error!("{}", message); - return Err(from_display(message)); + if tried >= max_retries { + return Err(from_display(message)); + } + let sleep_secs = (1 << tried).min(8); + info!("Retrying after {} seconds...", sleep_secs); + std::thread::sleep(Duration::from_secs(sleep_secs)); + tried += 1; + continue; } }; + }; Ok(pb::Attestation { version: 1, provider: serde_json::to_string(&attestation_provider).unwrap(), @@ -1625,6 +1636,7 @@ impl PhactoryApi for Rpc attestation_provider, &worker_key_hash, phactory.args.ra_timeout, + phactory.args.ra_max_retries, )?) } else { info!("Omit RA report in workerkey response in dev mode"); @@ -1682,6 +1694,7 @@ impl PhactoryApi for Rpc Some(AttestationProvider::Ias), &handler_hash, phactory.args.ra_timeout, + phactory.args.ra_max_retries, )?) } else { info!("Omit client RA report for dev mode challenge"); diff --git a/standalone/pruntime/src/main.rs b/standalone/pruntime/src/main.rs index 01716a5a85..9347264863 100644 --- a/standalone/pruntime/src/main.rs +++ b/standalone/pruntime/src/main.rs @@ -87,6 +87,10 @@ struct Args { /// The timeout of getting the attestation report. (in seconds) #[arg(long, value_parser = parse_duration, default_value = "8s")] ra_timeout: Duration, + + /// The max retry times of getting the attestation report. + #[arg(long, value_parser = parse_duration, default_value = "1")] + ra_max_retries: u32, } #[rocket::main] @@ -153,6 +157,7 @@ async fn serve(sgx: bool) -> Result<(), rocket::Error> { safe_mode_level: args.safe_mode_level, no_rcu: args.no_rcu, ra_timeout: args.ra_timeout, + ra_max_retries: args.ra_max_retries, } }; info!("init_args: {:#?}", init_args);