Skip to main content

traverse_runtime/trace/
private.rs

1//! Private (access-controlled) trace entry.
2
3use serde::{Deserialize, Serialize};
4use sha2::{Digest, Sha256};
5use std::fmt::Write as _;
6
7/// An access-controlled private trace entry that links to a [`super::public::PublicTraceEntry`]
8/// via `trace_id`.
9///
10/// Raw inputs and outputs are never stored; only SHA-256 hashes.
11#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
12pub struct PrivateTraceEntry {
13    /// Links to the `id` field of the corresponding [`super::public::PublicTraceEntry`].
14    pub trace_id: String,
15    /// SHA-256 hex digest of the serialized inputs.
16    pub inputs_hash: String,
17    /// SHA-256 hex digest of the serialized outputs.
18    pub outputs_hash: String,
19    /// Measured resource usage in milliseconds.
20    pub resource_usage_ms: u64,
21}
22
23impl PrivateTraceEntry {
24    /// Creates a new [`PrivateTraceEntry`], hashing `inputs` and `outputs` with SHA-256.
25    #[must_use]
26    pub fn new(trace_id: String, inputs: &str, outputs: &str, resource_usage_ms: u64) -> Self {
27        Self {
28            trace_id,
29            inputs_hash: sha256_hex(inputs),
30            outputs_hash: sha256_hex(outputs),
31            resource_usage_ms,
32        }
33    }
34}
35
36/// Returns the lowercase hex-encoded SHA-256 digest of `data`.
37fn sha256_hex(data: &str) -> String {
38    let mut hasher = Sha256::new();
39    hasher.update(data.as_bytes());
40    hasher
41        .finalize()
42        .iter()
43        .fold(String::new(), |mut acc, byte| {
44            let _ = write!(acc, "{byte:02x}");
45            acc
46        })
47}