use std::mem::size_of;
use saddle_admission::{
GeneratedAllocatorCost, GeneratedBuildCostClass, GeneratedBuildTopologyConstant,
GeneratedCalibrationConstant, GeneratedResourceDimension, GeneratedSupportLimit,
RuntimeBuildCapacitySourceLeaf, RuntimeCapacityCalibrationSourceLeaf,
};
const TARGET: &str = "x86_64-unknown-linux-gnu";
const RUST: (u16, u16, u16) = (1, 85, 0);
const TOKIO: (u16, u16, u16) = (1, 53, 1);
const SUPPORT: [usize; 4] = [8, 128, 128, 64];
const FIXED_OWNERS: [usize; 3] = [1, 2, 3];
#[doc(hidden)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct RuntimeCapacityComponentProof {
identity: [u8; 32],
support: [usize; 4],
fixed_owners: [usize; 3],
}
#[doc(hidden)]
pub const fn runtime_capacity_component_proof() -> RuntimeCapacityComponentProof {
RuntimeCapacityComponentProof {
identity: [0xb1; 32],
support: SUPPORT,
fixed_owners: FIXED_OWNERS,
}
}
impl RuntimeCapacityComponentProof {
#[doc(hidden)]
pub const fn identity(self) -> [u8; 32] {
self.identity
}
}
#[doc(hidden)]
pub trait RuntimeBuildCalibrationAttestation: Sized {
fn common_identities(&self) -> [[u8; 32]; 3];
fn owner_generation(&self) -> u64;
fn approved(&self) -> bool;
fn reproducible(&self) -> bool;
fn conservative(&self) -> bool;
fn target(&self) -> &'static str;
fn target_identity(&self) -> [u8; 32];
fn rust_version(&self) -> (u16, u16, u16);
fn rust_identity(&self) -> [u8; 32];
fn tokio_version(&self) -> (u16, u16, u16);
fn tokio_identity(&self) -> [u8; 32];
fn libc_identity(&self) -> [u8; 32];
fn kernel_identity(&self) -> [u8; 32];
fn allocator_identity(&self) -> [u8; 32];
fn source_identity(&self) -> [u8; 32];
fn build_config_identity(&self) -> [u8; 32];
fn binary_artifact_identity(&self) -> [u8; 32];
fn route_facts_identity(&self) -> [u8; 32];
fn raw_measurements_identity(&self) -> [u8; 32];
fn measurement_harness_identity(&self) -> [u8; 32];
fn schema_identity(&self) -> [u8; 32];
fn algorithm_identity(&self) -> [u8; 32];
fn signature_identity(&self) -> [u8; 32];
fn calibration_manifest_identity(&self) -> [u8; 32];
fn component_proof_identity(&self) -> [u8; 32];
fn measurement_repetitions(&self) -> u32;
fn costs(&self) -> [[usize; 7]; 5];
fn allocator_costs(&self) -> [usize; 2];
fn entry_reserve_per_request(&self) -> usize;
fn system_estimate_bytes(&self) -> usize;
fn logical_safety_margin_bytes(&self) -> usize;
}
#[doc(hidden)]
pub struct RuntimeLayoutSeal {
_private: (),
}
#[doc(hidden)]
#[derive(Debug)]
pub struct RuntimeRouteLayout {
route_identity: u64,
framework_bytes: usize,
task_storage_bytes: usize,
response_carrier_bytes: usize,
entry_bytes: usize,
}
impl RuntimeLayoutSeal {
#[doc(hidden)]
pub fn measure<Task, Framework, Response, Entry>(
&self,
route_identity: u64,
) -> Result<RuntimeRouteLayout, RuntimeCapacityLeafError> {
let entry = size_of::<Entry>();
let framework = size_of::<Framework>()
.checked_add(entry)
.ok_or(RuntimeCapacityLeafError::Overflow)?;
let route = RuntimeRouteLayout {
route_identity,
framework_bytes: framework,
task_storage_bytes: size_of::<Task>(),
response_carrier_bytes: size_of::<Response>(),
entry_bytes: entry,
};
if route_identity == 0
|| route.framework_bytes == 0
|| route.task_storage_bytes == 0
|| route.response_carrier_bytes == 0
|| route.entry_bytes == 0
{
return Err(RuntimeCapacityLeafError::InvalidLayout);
}
Ok(route)
}
}
#[doc(hidden)]
pub trait RuntimeMonomorphizedLayoutSource: Sized {
fn common_identities(&self) -> [[u8; 32]; 3];
fn owner_generation(&self) -> u64;
fn solver_schema_identity(&self) -> [u8; 32];
fn admission_layout_identity(&self) -> [u8; 32];
fn measure(
self,
seal: RuntimeLayoutSeal,
) -> Result<Box<[RuntimeRouteLayout]>, RuntimeCapacityLeafError>;
}
#[doc(hidden)]
#[derive(Debug)]
pub struct VerifiedRuntimeBuildCapacityLeaf {
leaf_identity: [u8; 32],
common: [[u8; 32]; 3],
generation: u64,
expected_calibration_provenance: [[u8; 32]; 9],
solver_schema_identity: [u8; 32],
admission_layout_identity: [u8; 32],
costs: [[usize; 7]; 5],
support: [usize; 4],
topology: [usize; 3],
routes: Box<[RuntimeRouteLayout]>,
}
#[doc(hidden)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum RuntimeCapacityLeafError {
Unapproved,
UnsupportedBuild,
MissingIdentity,
ForeignIdentity,
InvalidFact,
InvalidLayout,
DuplicateRoute,
Overflow,
}
#[doc(hidden)]
#[derive(Debug)]
pub struct VerifiedRuntimeBuildCalibrationOwner {
leaf_identity: [u8; 32],
common: [[u8; 32]; 3],
generation: u64,
provenance: [[u8; 32]; 9],
component_proof_identity: [u8; 32],
costs: [[usize; 7]; 5],
allocator: [usize; 2],
entry: usize,
system: usize,
margin: usize,
}
#[doc(hidden)]
pub fn verify_runtime_build_calibration<A: RuntimeBuildCalibrationAttestation>(
attestation: A,
) -> Result<VerifiedRuntimeBuildCalibrationOwner, RuntimeCapacityLeafError> {
if !attestation.approved() || !attestation.reproducible() || !attestation.conservative() {
return Err(RuntimeCapacityLeafError::Unapproved);
}
if attestation.target() != TARGET
|| attestation.rust_version() != RUST
|| attestation.tokio_version() != TOKIO
{
return Err(RuntimeCapacityLeafError::UnsupportedBuild);
}
let common = attestation.common_identities();
let provenance = [
attestation.source_identity(),
attestation.build_config_identity(),
attestation.target_identity(),
attestation.rust_identity(),
attestation.tokio_identity(),
attestation.libc_identity(),
attestation.allocator_identity(),
attestation.binary_artifact_identity(),
attestation.calibration_manifest_identity(),
];
let identities = [
provenance[0],
provenance[1],
provenance[2],
provenance[3],
provenance[4],
provenance[5],
provenance[6],
provenance[7],
provenance[8],
attestation.kernel_identity(),
attestation.route_facts_identity(),
attestation.raw_measurements_identity(),
attestation.measurement_harness_identity(),
attestation.schema_identity(),
attestation.algorithm_identity(),
attestation.signature_identity(),
attestation.calibration_manifest_identity(),
attestation.component_proof_identity(),
common[0],
common[1],
common[2],
];
if identities.contains(&[0; 32]) {
return Err(RuntimeCapacityLeafError::MissingIdentity);
}
if attestation.owner_generation() == 0
|| attestation.measurement_repetitions() < 2
|| attestation.calibration_manifest_identity() == attestation.binary_artifact_identity()
|| common[0] != attestation.build_config_identity()
|| common[1] != attestation.binary_artifact_identity()
|| common[2] != attestation.route_facts_identity()
{
return Err(RuntimeCapacityLeafError::InvalidFact);
}
let costs = attestation.costs();
let allocator = attestation.allocator_costs();
let entry = attestation.entry_reserve_per_request();
let system = attestation.system_estimate_bytes();
let margin = attestation.logical_safety_margin_bytes();
if costs.iter().flatten().all(|value| *value == 0)
|| allocator.contains(&0)
|| entry == 0
|| system == 0
|| margin == 0
{
return Err(RuntimeCapacityLeafError::InvalidFact);
}
Ok(VerifiedRuntimeBuildCalibrationOwner {
leaf_identity: attestation.calibration_manifest_identity(),
common,
generation: attestation.owner_generation(),
provenance,
component_proof_identity: attestation.component_proof_identity(),
costs,
allocator,
entry,
system,
margin,
})
}
#[doc(hidden)]
pub fn verify_runtime_capacity_leaf<L>(
component: RuntimeCapacityComponentProof,
calibration: VerifiedRuntimeBuildCalibrationOwner,
layouts: L,
) -> Result<
(
VerifiedRuntimeBuildCapacityLeaf,
VerifiedRuntimeBuildCalibrationOwner,
),
RuntimeCapacityLeafError,
>
where
L: RuntimeMonomorphizedLayoutSource,
{
let common = layouts.common_identities();
if common.contains(&[0; 32]) {
return Err(RuntimeCapacityLeafError::MissingIdentity);
}
if calibration.component_proof_identity != component.identity
|| common != calibration.common
|| layouts.owner_generation() != calibration.generation
{
return Err(RuntimeCapacityLeafError::ForeignIdentity);
}
let generation = layouts.owner_generation();
let solver_schema_identity = layouts.solver_schema_identity();
let admission_layout_identity = layouts.admission_layout_identity();
if generation == 0 {
return Err(RuntimeCapacityLeafError::InvalidFact);
}
let routes = layouts.measure(RuntimeLayoutSeal { _private: () })?;
if routes.is_empty() {
return Err(RuntimeCapacityLeafError::InvalidLayout);
}
for (index, route) in routes.iter().enumerate() {
if routes[..index]
.iter()
.any(|known| known.route_identity == route.route_identity)
{
return Err(RuntimeCapacityLeafError::DuplicateRoute);
}
}
let entry = routes
.iter()
.map(|route| route.entry_bytes)
.max()
.ok_or(RuntimeCapacityLeafError::InvalidLayout)?;
let costs = calibration.costs;
if entry != calibration.entry
|| costs.iter().flatten().all(|value| *value == 0)
|| costs[0][3] != component.fixed_owners[0] + component.fixed_owners[1]
|| costs[0][4] != component.fixed_owners[2]
{
return Err(RuntimeCapacityLeafError::InvalidFact);
}
let build = VerifiedRuntimeBuildCapacityLeaf {
leaf_identity: [0xb2; 32],
common,
generation,
expected_calibration_provenance: calibration.provenance,
solver_schema_identity,
admission_layout_identity,
costs,
support: component.support,
topology: component.fixed_owners,
routes,
};
if build.solver_schema_identity == [0; 32] || build.admission_layout_identity == [0; 32] {
return Err(RuntimeCapacityLeafError::MissingIdentity);
}
Ok((build, calibration))
}
impl RuntimeBuildCapacitySourceLeaf for VerifiedRuntimeBuildCapacityLeaf {
fn leaf_identity(&self) -> [u8; 32] {
self.leaf_identity
}
fn common_identities(&self) -> [[u8; 32]; 3] {
self.common
}
fn owner_generation(&self) -> u64 {
self.generation
}
fn component_proof_identity(&self) -> [u8; 32] {
runtime_capacity_component_proof().identity()
}
fn expected_calibration_provenance(&self) -> [[u8; 32]; 9] {
self.expected_calibration_provenance
}
fn solver_schema_identity(&self) -> [u8; 32] {
self.solver_schema_identity
}
fn admission_layout_identity(&self) -> [u8; 32] {
self.admission_layout_identity
}
fn cost(
&self,
class: GeneratedBuildCostClass,
dimension: GeneratedResourceDimension,
) -> Option<usize> {
Some(self.costs[class as usize][dimension as usize])
}
fn support_limit(&self, limit: GeneratedSupportLimit) -> Option<usize> {
Some(self.support[limit as usize])
}
fn topology_constant(&self, constant: GeneratedBuildTopologyConstant) -> Option<usize> {
Some(self.topology[constant as usize])
}
fn route_count(&self) -> usize {
self.routes.len()
}
fn route_identity(&self, index: usize) -> Option<u64> {
self.routes.get(index).map(|v| v.route_identity)
}
fn framework_bytes(&self, index: usize) -> Option<usize> {
self.routes.get(index).map(|v| v.framework_bytes)
}
fn task_storage_bytes(&self, index: usize) -> Option<usize> {
self.routes.get(index).map(|v| v.task_storage_bytes)
}
fn response_carrier_bytes(&self, index: usize) -> Option<usize> {
self.routes.get(index).map(|v| v.response_carrier_bytes)
}
}
impl RuntimeCapacityCalibrationSourceLeaf for VerifiedRuntimeBuildCalibrationOwner {
fn leaf_identity(&self) -> [u8; 32] {
self.leaf_identity
}
fn common_identities(&self) -> [[u8; 32]; 3] {
self.common
}
fn owner_generation(&self) -> u64 {
self.generation
}
fn calibration_provenance(&self) -> [[u8; 32]; 9] {
self.provenance
}
fn fixed_cost(&self, dimension: GeneratedResourceDimension) -> Option<usize> {
Some(self.costs[0][dimension as usize])
}
fn allocator_cost(&self, cost: GeneratedAllocatorCost) -> Option<usize> {
Some(
self.allocator[match cost {
GeneratedAllocatorCost::IdleLiveRequested => 0,
GeneratedAllocatorCost::MeasurementMargin => 1,
}],
)
}
fn calibrated_constant(&self, constant: GeneratedCalibrationConstant) -> Option<usize> {
Some([self.entry, self.system, self.margin][constant as usize])
}
}
#[cfg(test)]
mod tests {
use super::*;
const COMMON: [[u8; 32]; 3] = [[4; 32], [5; 32], [6; 32]];
struct Calibration {
approved: bool,
component: [u8; 32],
}
impl RuntimeBuildCalibrationAttestation for Calibration {
fn common_identities(&self) -> [[u8; 32]; 3] {
COMMON
}
fn owner_generation(&self) -> u64 {
1
}
fn approved(&self) -> bool {
self.approved
}
fn reproducible(&self) -> bool {
true
}
fn conservative(&self) -> bool {
true
}
fn target(&self) -> &'static str {
TARGET
}
fn target_identity(&self) -> [u8; 32] {
[14; 32]
}
fn rust_version(&self) -> (u16, u16, u16) {
RUST
}
fn rust_identity(&self) -> [u8; 32] {
[15; 32]
}
fn tokio_version(&self) -> (u16, u16, u16) {
TOKIO
}
fn tokio_identity(&self) -> [u8; 32] {
[16; 32]
}
fn libc_identity(&self) -> [u8; 32] {
[1; 32]
}
fn kernel_identity(&self) -> [u8; 32] {
[8; 32]
}
fn allocator_identity(&self) -> [u8; 32] {
[2; 32]
}
fn source_identity(&self) -> [u8; 32] {
[3; 32]
}
fn build_config_identity(&self) -> [u8; 32] {
COMMON[0]
}
fn binary_artifact_identity(&self) -> [u8; 32] {
COMMON[1]
}
fn route_facts_identity(&self) -> [u8; 32] {
COMMON[2]
}
fn raw_measurements_identity(&self) -> [u8; 32] {
[9; 32]
}
fn measurement_harness_identity(&self) -> [u8; 32] {
[10; 32]
}
fn schema_identity(&self) -> [u8; 32] {
[11; 32]
}
fn algorithm_identity(&self) -> [u8; 32] {
[12; 32]
}
fn signature_identity(&self) -> [u8; 32] {
[13; 32]
}
fn calibration_manifest_identity(&self) -> [u8; 32] {
[7; 32]
}
fn component_proof_identity(&self) -> [u8; 32] {
self.component
}
fn measurement_repetitions(&self) -> u32 {
3
}
fn costs(&self) -> [[usize; 7]; 5] {
[
[0, 10_000, 10_000, 3, 3, 0, 0],
[1, 1, 1, 0, 0, 0, 0],
[0, 10, 10, 1, 1, 0, 0],
[0, 10, 10, 1, 1, 0, 0],
[0, 10, 10, 0, 0, 1, 1],
]
}
fn allocator_costs(&self) -> [usize; 2] {
[100, 100]
}
fn entry_reserve_per_request(&self) -> usize {
64
}
fn system_estimate_bytes(&self) -> usize {
10
}
fn logical_safety_margin_bytes(&self) -> usize {
10
}
}
struct Layouts;
impl RuntimeMonomorphizedLayoutSource for Layouts {
fn common_identities(&self) -> [[u8; 32]; 3] {
COMMON
}
fn owner_generation(&self) -> u64 {
1
}
fn solver_schema_identity(&self) -> [u8; 32] {
[17; 32]
}
fn admission_layout_identity(&self) -> [u8; 32] {
[18; 32]
}
fn measure(
self,
seal: RuntimeLayoutSeal,
) -> Result<Box<[RuntimeRouteLayout]>, RuntimeCapacityLeafError> {
Ok(
vec![seal.measure::<[u8; 128], [u8; 192], [u8; 16], [u8; 64]>(9)?]
.into_boxed_slice(),
)
}
}
fn calibration() -> Calibration {
Calibration {
approved: true,
component: runtime_capacity_component_proof().identity(),
}
}
#[test]
fn two_sources_form_one_private_linear_leaf() {
let calibration = verify_runtime_build_calibration(calibration()).unwrap();
let (leaf, calibration) =
verify_runtime_capacity_leaf(runtime_capacity_component_proof(), calibration, Layouts)
.unwrap();
assert_eq!(
leaf.support_limit(GeneratedSupportLimit::ActiveRequests),
Some(128)
);
assert_eq!(
calibration.calibrated_constant(GeneratedCalibrationConstant::EntryReservePerRequest),
Some(64),
);
assert_eq!(leaf.framework_bytes(0), Some(256));
assert_ne!(calibration.leaf_identity(), COMMON[1]);
}
#[test]
fn unapproved_and_foreign_component_fail_before_leaf_issue() {
let mut denied = calibration();
denied.approved = false;
assert_eq!(
verify_runtime_build_calibration(denied).unwrap_err(),
RuntimeCapacityLeafError::Unapproved
);
let mut foreign = calibration();
foreign.component = [0xff; 32];
let foreign = verify_runtime_build_calibration(foreign).unwrap();
assert_eq!(
verify_runtime_capacity_leaf(runtime_capacity_component_proof(), foreign, Layouts)
.unwrap_err(),
RuntimeCapacityLeafError::ForeignIdentity
);
}
}