diff --git a/Cargo.lock b/Cargo.lock index e7b5978311..9e28c4cfb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3282,6 +3282,14 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "rofl-containers" +version = "0.1.0" +dependencies = [ + "base64", + "oasis-runtime-sdk", +] + [[package]] name = "rofl-utils" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index fe30e0714a..fb3b7e9c61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ members = [ # ROFL. "rofl-utils", + "rofl-containers", # Test runtimes. "tests/runtimes/benchmarking", diff --git a/rofl-containers/Cargo.toml b/rofl-containers/Cargo.toml new file mode 100644 index 0000000000..866d93f9bf --- /dev/null +++ b/rofl-containers/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "rofl-containers" +version = "0.1.0" +edition = "2021" + +[dependencies] +# Oasis SDK. +oasis-runtime-sdk = { path = "../runtime-sdk", features = ["tdx"] } + +# Third party. +base64 = "0.22.1" diff --git a/rofl-containers/src/main.rs b/rofl-containers/src/main.rs new file mode 100644 index 0000000000..792338614e --- /dev/null +++ b/rofl-containers/src/main.rs @@ -0,0 +1,40 @@ +use std::env; + +use base64::prelude::*; +use oasis_runtime_sdk::{cbor, modules::rofl::app::prelude::*}; + +/// A generic container-based ROFL application. +struct ContainersApp; + +#[async_trait] +impl App for ContainersApp { + const VERSION: Version = sdk::version_from_cargo!(); + + fn id() -> AppId { + // Fetch application ID from the ROFL_APP_ID environment variable. + // This would usually be passed via the kernel cmdline. + AppId::from_bech32(&env::var("ROFL_APP_ID").expect("Must configure ROFL_APP_ID.")) + .expect("Corrupted ROFL_APP_ID (must be Bech32-encoded ROFL app ID).") + } + + fn consensus_trust_root() -> Option { + // Fetch consensus trust root from the ROFL_CONSENSUS_TRUST_ROOT environment variable. + // This would usually be passed via the kernel cmdline. + let raw_trust_root = env::var("ROFL_CONSENSUS_TRUST_ROOT") + .expect("Must configure ROFL_CONSENSUS_TRUST_ROOT."); + cbor::from_slice( + &BASE64_STANDARD + .decode(raw_trust_root) + .expect("Corrupted ROFL_CONSENSUS_TRUST_ROOT (must be Base64-encoded CBOR)."), + ) + .expect("Corrupted ROFL_CONSENSUS_TRUST_ROOT (must be Base64-encoded CBOR).") + } + + async fn run(self: Arc, _env: Environment) { + // TODO: Start the REST API server. + } +} + +fn main() { + ContainersApp.start(); +} diff --git a/runtime-sdk/src/modules/rofl/app/mod.rs b/runtime-sdk/src/modules/rofl/app/mod.rs index c77f0189b3..e7085886ec 100644 --- a/runtime-sdk/src/modules/rofl/app/mod.rs +++ b/runtime-sdk/src/modules/rofl/app/mod.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use anyhow::Result; use async_trait::async_trait; +use base64::prelude::*; use tokio::sync::mpsc; use crate::{ @@ -38,11 +39,28 @@ pub trait App: Send + Sync + 'static { const VERSION: version::Version; /// Identifier of the application (used for registrations). - fn id() -> AppId; + fn id() -> AppId { + // By default we fetch the application identifier from the build-time environment. + AppId::from_bech32( + option_env!("ROFL_APP_ID").expect("Override App::id or specify ROFL_APP_ID."), + ) + .expect("Corrupted ROFL_APP_ID (must be Bech32-encoded ROFL app ID).") + } /// Return the consensus layer trust root for this runtime; if `None`, consensus layer integrity /// verification will not be performed. - fn consensus_trust_root() -> Option; + fn consensus_trust_root() -> Option { + // By default we fetch the trust root from the build-time environment. + option_env!("ROFL_CONSENSUS_TRUST_ROOT").map(|raw_trust_root| { + // Parse from base64-encoded CBOR. + cbor::from_slice( + &BASE64_STANDARD + .decode(raw_trust_root) + .expect("Corrupted ROFL_CONSENSUS_TRUST_ROOT (must be Base64-encoded CBOR)."), + ) + .expect("Corrupted ROFL_CONSENSUS_TRUST_ROOT (must be Base64-encoded CBOR).") + }) + } /// Create a new unsigned transaction. fn new_transaction(&self, method: &str, body: B) -> transaction::Transaction