Skip to content

Commit

Permalink
Merge pull request #1524 from Phala-Network/dcap-handover
Browse files Browse the repository at this point in the history
pruntime: Implement dcap key handover
  • Loading branch information
kvinwang authored Feb 26, 2024
2 parents 3ec0e5b + 44d64c5 commit dfa3605
Show file tree
Hide file tree
Showing 16 changed files with 1,269 additions and 711 deletions.
1,365 changes: 697 additions & 668 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,13 @@ sp-runtime-interface = { git = "https://github.com/paritytech/polkadot-sdk.git",
pink-extension = { path = "crates/pink/pink-extension" }
pink-extension-runtime = { path = "crates/pink/pink-extension-runtime" }

# The substrate dependencies use old version of crypto crates. Some of them, listed below, hard require subtle=v2.4
# but latest rustls requires subtle v2.5 which cause it conflict. Ideally, substrate should upgrade it's dependencies
# to latest version.
# Here we patch the old crates to use subtle v2.5 as a workaround.
aes-gcm = { git = "https://github.com/kvinwang/AEADs.git", branch = "subtle-v2.5"}
crypto-mac = { git = "https://github.com/kvinwang/rust-crypto-traits.git", branch = "subtle-v2.5" }
universal-hash = { git = "https://github.com/kvinwang/rust-crypto-traits.git", branch = "subtle-v2.5" }

[patch."https://github.com/paritytech/polkadot-sdk.git"]
sc-consensus-grandpa = { git = "https://github.com/Phala-Network/polkadot-sdk.git", branch = "phala-patch-polkadot-v1.5.0" }
2 changes: 2 additions & 0 deletions crates/phactory/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ once_cell = "1"
im = "15"
scale-info = { version = "2.10.0", default-features = false, features = ["derive"] }
this-crate = { path = "../this-crate" }
phala-nts = { git = "https://github.com/Phala-Network/phala-nts.git", branch = "lib" }
futures = "0.3"

[dev-dependencies]
insta = "1.7.2"
Expand Down
2 changes: 1 addition & 1 deletion crates/phactory/api/proto
Submodule proto updated 1 files
+31 −0 pruntime_rpc.proto
8 changes: 7 additions & 1 deletion crates/phactory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::{
light_validation::LightValidation,
};
use phactory_api::contracts::QueryError;
use phala_types::contract::ContractQueryError;
use phala_types::{contract::ContractQueryError, DcapHandoverChallenge};
use sidevm_env::messages::{QueryError as SidevmQueryError, QueryResponse};
use std::{
borrow::Cow,
Expand Down Expand Up @@ -88,6 +88,7 @@ pub mod contracts;
mod cryptography;
mod im_helpers;
mod light_validation;
mod nts;
mod prpc_service;
mod secret_channel;
mod storage;
Expand Down Expand Up @@ -280,6 +281,10 @@ pub struct Phactory<Platform> {
#[serde(skip)]
handover_last_challenge: Option<HandoverChallenge<chain::BlockNumber>>,

#[codec(skip)]
#[serde(skip)]
dcap_handover_last_challenge: Option<DcapHandoverChallenge<chain::BlockNumber>>,

#[codec(skip)]
#[serde(skip)]
#[serde(default = "Instant::now")]
Expand Down Expand Up @@ -394,6 +399,7 @@ impl<Platform: pal::Platform> Phactory<Platform> {
signed_endpoints: None,
handover_ecdh_key: None,
handover_last_challenge: None,
dcap_handover_last_challenge: None,
last_checkpoint: Instant::now(),
query_scheduler: Default::default(),
netconfig: Default::default(),
Expand Down
62 changes: 62 additions & 0 deletions crates/phactory/src/nts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use anyhow::{Context, Result};

use phala_nts::{get_time, NtpResult};

/// Ref: https://github.com/jauderho/nts-servers/
const TRUSTED_NTS_SERVERS: &[&str] = &[
"time.cloudflare.com",
"gps.ntp.br",
"a.st1.ntp.br",
"paris.time.system76.com",
"ntp3.fau.de",
"ptbtime1.ptb.de",
"ntppool1.time.nl",
"nts.netnod.se",
];

/// Get time from NTS servers
pub(crate) async fn nts_get_time_secs(servers: &[String]) -> Result<u64> {
const TIMEOUT_SECS: u64 = 5;
let mut futures = Vec::new();
if servers.is_empty() {
for server in TRUSTED_NTS_SERVERS.iter() {
futures.push(get_time_timeout(server, TIMEOUT_SECS));
}
} else {
for server in servers.iter() {
futures.push(get_time_timeout(server, TIMEOUT_SECS));
}
}
info!("Requesting time from {} servers", futures.len());
let results = futures::future::join_all(futures)
.await
.into_iter()
.filter_map(|r| r.ok())
.map(|r| r.receive_time_duration().as_secs())
.collect::<Vec<_>>();
info!("Got time from {} servers", results.len());
validate_results(results).context("Failed to get time from NTS servers")
}

fn validate_results(results: Vec<u64>) -> Result<u64> {
const MIN_RESULTS: usize = 2;
const MAX_VARIANCE: u64 = 60;
if results.len() < MIN_RESULTS {
anyhow::bail!("Not enough results");
}
let average = results.iter().sum::<u64>() / results.len() as u64;
let max_diff = results
.iter()
.map(|r| (*r as i64 - average as i64).unsigned_abs())
.max()
.unwrap_or_default();
if max_diff > MAX_VARIANCE {
anyhow::bail!("Time difference is too large: {}", max_diff);
}
Ok(average)
}

async fn get_time_timeout(server: &str, timeout: u64) -> Result<NtpResult> {
let timeout = std::time::Duration::from_secs(timeout);
tokio::time::timeout(timeout, get_time(server, None)).await?
}
Loading

0 comments on commit dfa3605

Please sign in to comment.