Skip to main content

amiss_bootstrap/
result.rs

1const PASS: &[u8] = b"amiss/bootstrap-result-v1 pass\n";
2const BLOCK: &[u8] = b"amiss/bootstrap-result-v1 block\n";
3const MISSING_OUTPUT: &[u8] = b"amiss/bootstrap-result-v1 missing-output\n";
4const TIMEOUT: &[u8] = b"amiss/bootstrap-result-v1 timeout\n";
5const OVERSIZED_OUTPUT: &[u8] = b"amiss/bootstrap-result-v1 oversized-output\n";
6const TAMPERED_RUNTIME: &[u8] = b"amiss/bootstrap-result-v1 tampered-runtime\n";
7const UNAVAILABLE: &[u8] = b"amiss/bootstrap-result-v1 unavailable\n";
8
9/// Maximum size of one bootstrap result record.
10pub const RESULT_BYTES: u64 = 64;
11
12const RECORDS: [(BootstrapResult, &[u8], i32); 7] = [
13    (BootstrapResult::Pass, PASS, 0),
14    (BootstrapResult::Block, BLOCK, 1),
15    (BootstrapResult::MissingOutput, MISSING_OUTPUT, 2),
16    (BootstrapResult::Timeout, TIMEOUT, 2),
17    (BootstrapResult::OversizedOutput, OVERSIZED_OUTPUT, 2),
18    (BootstrapResult::TamperedRuntime, TAMPERED_RUNTIME, 2),
19    (BootstrapResult::Unavailable, UNAVAILABLE, 2),
20];
21
22/// The closed outcome written by one trusted bootstrap process.
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub enum BootstrapResult {
25    Pass,
26    Block,
27    MissingOutput,
28    Timeout,
29    OversizedOutput,
30    TamperedRuntime,
31    Unavailable,
32}
33
34/// Returns the exact versioned record for one result.
35#[must_use]
36pub fn result_bytes(result: BootstrapResult) -> &'static [u8] {
37    record(result).0
38}
39
40/// Returns the required process exit code for one result record.
41#[must_use]
42pub fn result_exit_code(result: BootstrapResult) -> i32 {
43    record(result).1
44}
45
46fn record(result: BootstrapResult) -> (&'static [u8], i32) {
47    RECORDS
48        .iter()
49        .find_map(|(candidate, bytes, exit_code)| {
50            (*candidate == result).then_some((*bytes, *exit_code))
51        })
52        .unwrap_or((UNAVAILABLE, 2))
53}
54
55/// Parses one exact result record. Whitespace and unknown versions are not
56/// accepted.
57#[must_use]
58pub fn parse_result(bytes: &[u8]) -> Option<BootstrapResult> {
59    RECORDS
60        .iter()
61        .find_map(|(result, record, _)| (*record == bytes).then_some(*result))
62}