Conversation
fa9a4fe to
a9a4e69
Compare
leongross
left a comment
There was a problem hiding this comment.
Note from a personal discussion with @chrysh: This only comes into effect if the orchestrator cannot block. Then, we need to incrementally verify one chunk at a time in the main loop.
We will further discuss this architectural decision and conclude whether we merge it as is.
| /// sleeps. An empty payload is a fault, never a vacuous | ||
| /// `Authenticated`. |
There was a problem hiding this comment.
| /// sleeps. An empty payload is a fault, never a vacuous | |
| /// `Authenticated`. | |
| /// sleeps. An empty payload is a fault. |
| /// the verifier, ready for a new [`start`](IncrementalVerifier::start). | ||
| #[derive(Debug)] | ||
| pub enum PollOutcome<S: VerifySession> { | ||
| /// One chunk processed. `done` bytes so far out of `total`. |
There was a problem hiding this comment.
Not a fan of done here; it implies duality, done or not done. I think we had this somewhere before, did we replace it with count?
| /// begin hashing a candidate image; the returned [`VerifySession`] does | ||
| /// the actual work one bounded step at a time. |
There was a problem hiding this comment.
I am confused about the wording. Here you say we hash the images, and later you say we verify the signature? Should this component do both, or is there a mix-up?
| /// The complete image authenticated (signature and policy checks | ||
| /// passed). | ||
| Authenticated(S::Verifier), |
There was a problem hiding this comment.
In the module description, you say, that this tracks the hashing, which makes sense with the gradual byte supply. How does this couple with signature verification?
| let payload = SlicePayload(&[0xAA; 10]); | ||
| let session = ChunkedVerifier.start(); | ||
|
|
||
| // 4 bytes, 4 bytes, 2 bytes = 3 Processing steps, then verdict. | ||
| let PollOutcome::Processing { | ||
| session, | ||
| done: 4, | ||
| total: 10, | ||
| } = session.poll(&payload) |
There was a problem hiding this comment.
potential future offset drift with hardcoded constant sizes
The update path hashes megabytes of payload; a synchronous verify would
stall the single-threaded runtime. IncrementalVerifier and VerifySession
split that work into bounded, non-blocking steps.
start() consumes the verifier into a VerifySession. Each poll() consumes
the session: Processing returns it inside the variant for the next call,
while Authenticated, Rejected, and Fault return the verifier for reuse.
Polling after a verdict is unrepresentable because the session is gone.
abandon() discards mid-session state and returns the verifier.
Processing { done, total } reports byte-level progress. Faults
(unreadable payload, crypto error) are the Fault variant, not a verdict:
Fault means the check did not run, Rejected means it ran and the image
failed.
Assisted-by: Claude
a9a4e69 to
9b64e79
Compare
TL;DR: Polled verification trait for the update pump, consuming-session
design so post-verdict poll is a compile error.
Part of 9elements#8.
Summary
Trait-only PR. Adds
IncrementalVerifierandVerifySessiontoorchestrator-capabilities: polled, chunked image verification so theupdate pump never blocks on hashing megabytes of payload.
start()consumes the verifier into aVerifySession. Eachpoll()consumes the session:
Processingreturns it inside the variant for thenext call, terminal outcomes return the verifier for reuse. A retained
verdict would be unsafe because
poll()takes a payload reference percall, so a swapped payload could get a stale result. The consuming design
makes that unrepresentable.
This diverges from
Updatable(implicit-start, poll-on-self). MigratingUpdatableto the same session shape is a follow-up once its consumersexist (the pump needs to land first so we can migrate callers).
Driver composition (the adapter that wraps a crypto backend behind this
trait, wired into the update pump) follows in a stacked PR.
Effect::AuthenticateUpdateremains stubbed in the SM until then.Assisted-by: Claude