1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//! A controlled Go snapshot claim whose every field family a proof can change.
//!
//! The builder exists so a coverage proof can hold one family byte-identical
//! while it perturbs another. It delegates to the production constructor and
//! returns only the opaque value, so it can neither state a second hashing rule
//! nor expose digest bytes.
use std::path::PathBuf;
use super::fingerprint::{
GoEdgeClaim, GoModuleClaim, GoSnapshotClaims, GoSnapshotFingerprint, GoSourceClaim, GoUnitClaim,
};
/// One admitted module, as a proof states it.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GoModuleFingerprintClaim {
/// The module path its own manifest declares.
pub path: String,
/// The module's repository-relative directory.
pub directory: String,
/// The module's repository-relative manifest.
pub manifest: String,
/// How many replacement hops separate it from the main module.
pub depth: u32,
}
/// One package unit's identity and source membership, as a proof states them.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GoUnitFingerprintClaim {
/// The snapshot-local index of the module holding the unit.
pub module: u32,
/// The stable token of the unit's compilation context.
pub context: String,
/// The import path the unit's directory has inside its module.
pub import_path: String,
/// The package clause the unit's sources declare.
pub package_name: String,
/// The unit's repository-relative directory.
pub directory: String,
/// The sorted repository-relative sources the unit instantiates.
pub sources: Vec<String>,
}
/// One local dependency edge, as a proof states it.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GoEdgeFingerprintClaim {
/// The snapshot-local index of the requiring module.
pub source: u32,
/// The snapshot-local index of the required module.
pub target: u32,
/// The module path the requirement names.
pub module_path: String,
/// The version the requirement names.
pub version: String,
}
/// One snapshotted source's path, digest, and predicates, as a proof states
/// them.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GoSourceFingerprintClaim {
/// The normalized repository-relative path.
pub path: String,
/// SHA-256 of the exact bytes the snapshot read.
pub digest: [u8; 32],
/// The stable tokens of every retained build predicate.
pub predicates: Vec<String>,
}
/// Everything one stated Go snapshot claims, ready to be perturbed.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GoSnapshotFingerprintClaim {
/// The canonical repository root.
pub root: PathBuf,
/// Every admitted module, in snapshot order.
pub modules: Vec<GoModuleFingerprintClaim>,
/// Every package unit, in snapshot order.
pub units: Vec<GoUnitFingerprintClaim>,
/// Every local dependency edge, in snapshot order.
pub edges: Vec<GoEdgeFingerprintClaim>,
/// Every distinct source, in snapshot order.
pub sources: Vec<GoSourceFingerprintClaim>,
}
impl GoSnapshotFingerprintClaim {
/// The opaque identity these stated claims produce.
pub fn fingerprint(&self) -> GoSnapshotFingerprint {
let modules: Box<[GoModuleClaim<'_>]> = self.modules.iter().map(stated_module).collect();
let memberships: Box<[Box<[&str]>]> = self
.units
.iter()
.map(|unit| unit.sources.iter().map(String::as_str).collect())
.collect();
let units: Box<[GoUnitClaim<'_>]> = self
.units
.iter()
.zip(&memberships)
.map(|(unit, sources)| stated_unit(unit, sources))
.collect();
let edges: Box<[GoEdgeClaim<'_>]> = self.edges.iter().map(stated_edge).collect();
let predicates: Box<[Box<[&str]>]> = self
.sources
.iter()
.map(|source| source.predicates.iter().map(String::as_str).collect())
.collect();
let sources: Box<[GoSourceClaim<'_>]> = self
.sources
.iter()
.zip(&predicates)
.map(|(source, predicates)| stated_source(source, predicates))
.collect();
GoSnapshotFingerprint::from_claims(&GoSnapshotClaims {
root: &self.root,
modules: &modules,
units: &units,
edges: &edges,
sources: &sources,
})
}
}
fn stated_module(module: &GoModuleFingerprintClaim) -> GoModuleClaim<'_> {
GoModuleClaim {
path: &module.path,
directory: &module.directory,
manifest: &module.manifest,
depth: module.depth,
}
}
fn stated_unit<'a>(unit: &'a GoUnitFingerprintClaim, sources: &'a [&'a str]) -> GoUnitClaim<'a> {
GoUnitClaim {
module: unit.module,
context: &unit.context,
import_path: &unit.import_path,
package_name: &unit.package_name,
directory: &unit.directory,
sources,
}
}
fn stated_edge(edge: &GoEdgeFingerprintClaim) -> GoEdgeClaim<'_> {
GoEdgeClaim {
source: edge.source,
target: edge.target,
module_path: &edge.module_path,
version: &edge.version,
}
}
fn stated_source<'a>(
source: &'a GoSourceFingerprintClaim,
predicates: &'a [&'a str],
) -> GoSourceClaim<'a> {
GoSourceClaim {
path: &source.path,
digest: &source.digest,
predicates,
}
}