pub struct AuditRecord {
pub device_id: String,
pub sequence: u64,
pub timestamp_ms: u64,
pub payload_hash: Hash32,
pub signature: Signature64,
pub prev_record_hash: Hash32,
pub object_ref: String,
}Fields§
§device_id: String§sequence: u64§timestamp_ms: u64§payload_hash: Hash32§signature: Signature64§prev_record_hash: Hash32§object_ref: StringImplementations§
Source§impl AuditRecord
impl AuditRecord
Sourcepub fn hash(&self) -> Hash32
pub fn hash(&self) -> Hash32
Examples found in repository?
examples/lift_inspection_flow.rs (line 40)
7fn main() {
8 let device_id = "lift-01";
9 let signing_key = SigningKey::from_bytes(&[1u8; 32]);
10 let verifying_key = signing_key.verifying_key();
11
12 let mut service = IngestService::new(
13 IngestState::default(),
14 InMemoryRawDataStore::default(),
15 InMemoryAuditLedger::default(),
16 InMemoryOperationLog::default(),
17 );
18 service.register_device(device_id, verifying_key);
19
20 let payloads = [
21 b"check=door,status=ok" as &[u8],
22 b"check=vibration,status=ok",
23 b"check=emergency_brake,status=ok",
24 ];
25
26 let mut prev_hash = AuditRecord::zero_hash();
27 let mut records = Vec::new();
28
29 for (index, payload) in payloads.iter().enumerate() {
30 let sequence = (index as u64) + 1;
31 let record = build_signed_record(
32 device_id,
33 sequence,
34 1_700_000_000_000 + sequence,
35 payload,
36 prev_hash,
37 format!("s3://bucket/{device_id}/inspection-{sequence}.bin"),
38 &signing_key,
39 );
40 prev_hash = record.hash();
41 records.push(record);
42 }
43
44 for record in &records {
45 service
46 .ingest(record.clone(), payloads[record.sequence as usize - 1])
47 .expect("ingest should succeed");
48 }
49
50 println!("Stored {} audit records", service.audit_ledger().records().len());
51
52 let tampered_payload = b"tampered";
53 let tampered_record = build_signed_record(
54 device_id,
55 4,
56 1_700_000_000_004,
57 tampered_payload,
58 prev_hash,
59 "s3://bucket/lift-01/inspection-4.bin",
60 &signing_key,
61 );
62 let mut tampered = tampered_record;
63 tampered.payload_hash[0] ^= 0x01;
64
65 let result = service.ingest(tampered, tampered_payload);
66 assert!(result.is_err(), "tampered record should be rejected");
67 println!("Tampered record rejected: {:?}", result.unwrap_err());
68
69 println!("Operation log entries: {}", service.operation_log().entries().len());
70 for entry in service.operation_log().entries() {
71 println!(" {:?} device={} seq={} msg={}", entry.decision, entry.device_id, entry.sequence, entry.message);
72 }
73}Sourcepub fn zero_hash() -> Hash32
pub fn zero_hash() -> Hash32
Examples found in repository?
examples/lift_inspection_flow.rs (line 26)
7fn main() {
8 let device_id = "lift-01";
9 let signing_key = SigningKey::from_bytes(&[1u8; 32]);
10 let verifying_key = signing_key.verifying_key();
11
12 let mut service = IngestService::new(
13 IngestState::default(),
14 InMemoryRawDataStore::default(),
15 InMemoryAuditLedger::default(),
16 InMemoryOperationLog::default(),
17 );
18 service.register_device(device_id, verifying_key);
19
20 let payloads = [
21 b"check=door,status=ok" as &[u8],
22 b"check=vibration,status=ok",
23 b"check=emergency_brake,status=ok",
24 ];
25
26 let mut prev_hash = AuditRecord::zero_hash();
27 let mut records = Vec::new();
28
29 for (index, payload) in payloads.iter().enumerate() {
30 let sequence = (index as u64) + 1;
31 let record = build_signed_record(
32 device_id,
33 sequence,
34 1_700_000_000_000 + sequence,
35 payload,
36 prev_hash,
37 format!("s3://bucket/{device_id}/inspection-{sequence}.bin"),
38 &signing_key,
39 );
40 prev_hash = record.hash();
41 records.push(record);
42 }
43
44 for record in &records {
45 service
46 .ingest(record.clone(), payloads[record.sequence as usize - 1])
47 .expect("ingest should succeed");
48 }
49
50 println!("Stored {} audit records", service.audit_ledger().records().len());
51
52 let tampered_payload = b"tampered";
53 let tampered_record = build_signed_record(
54 device_id,
55 4,
56 1_700_000_000_004,
57 tampered_payload,
58 prev_hash,
59 "s3://bucket/lift-01/inspection-4.bin",
60 &signing_key,
61 );
62 let mut tampered = tampered_record;
63 tampered.payload_hash[0] ^= 0x01;
64
65 let result = service.ingest(tampered, tampered_payload);
66 assert!(result.is_err(), "tampered record should be rejected");
67 println!("Tampered record rejected: {:?}", result.unwrap_err());
68
69 println!("Operation log entries: {}", service.operation_log().entries().len());
70 for entry in service.operation_log().entries() {
71 println!(" {:?} device={} seq={} msg={}", entry.decision, entry.device_id, entry.sequence, entry.message);
72 }
73}Trait Implementations§
Source§impl Clone for AuditRecord
impl Clone for AuditRecord
Source§fn clone(&self) -> AuditRecord
fn clone(&self) -> AuditRecord
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for AuditRecord
impl Debug for AuditRecord
Source§impl<'de> Deserialize<'de> for AuditRecord
impl<'de> Deserialize<'de> for AuditRecord
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
Source§impl PartialEq for AuditRecord
impl PartialEq for AuditRecord
Source§impl Serialize for AuditRecord
impl Serialize for AuditRecord
impl Eq for AuditRecord
impl StructuralPartialEq for AuditRecord
Auto Trait Implementations§
impl Freeze for AuditRecord
impl RefUnwindSafe for AuditRecord
impl Send for AuditRecord
impl Sync for AuditRecord
impl Unpin for AuditRecord
impl UnsafeUnpin for AuditRecord
impl UnwindSafe for AuditRecord
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more