1use crate::{
2 execution::{Output, Progress, Seed, Transaction, Value},
3 Identity, NAMESPACE,
4};
5use bytes::{Buf, BufMut};
6use commonware_codec::{EncodeSize, Error, Read, ReadExt, ReadRangeExt, Write};
7use commonware_consensus::aggregation::types::Certificate;
8use commonware_cryptography::{
9 bls12381::primitives::variant::MinSig, ed25519::PublicKey, sha256::Digest, Digestible, Sha256,
10};
11use commonware_storage::{
12 adb::{verify::verify_proof_and_extract_digests, verify_multi_proof, verify_proof},
13 mmr::{hasher::Standard, verification::Proof},
14 store::operation::{Keyless, Variable},
15};
16
17pub const MAX_SUBMISSION_TRANSACTIONS: usize = 128;
19
20pub enum Query {
21 Latest,
22 Index(u64),
23}
24
25impl Write for Query {
26 fn write(&self, writer: &mut impl BufMut) {
27 match self {
28 Query::Latest => 0u8.write(writer),
29 Query::Index(index) => {
30 1u8.write(writer);
31 index.write(writer);
32 }
33 }
34 }
35}
36
37impl Read for Query {
38 type Cfg = ();
39
40 fn read_cfg(reader: &mut impl Buf, _: &Self::Cfg) -> Result<Self, Error> {
41 let kind = u8::read(reader)?;
42 match kind {
43 0 => Ok(Query::Latest),
44 1 => Ok(Query::Index(u64::read(reader)?)),
45 _ => Err(Error::InvalidEnum(kind)),
46 }
47 }
48}
49
50impl EncodeSize for Query {
51 fn encode_size(&self) -> usize {
52 1 + match self {
53 Query::Latest => 0,
54 Query::Index(index) => index.encode_size(),
55 }
56 }
57}
58
59#[derive(Clone, Eq, PartialEq, Debug)]
60pub struct Summary {
61 pub progress: Progress,
62 pub certificate: Certificate<MinSig, Digest>,
63 pub state_proof: Proof<Digest>,
64 pub state_proof_ops: Vec<Variable<Digest, Value>>,
65 pub events_proof: Proof<Digest>,
66 pub events_proof_ops: Vec<Keyless<Output>>,
67}
68
69impl Summary {
70 #[allow(clippy::type_complexity)]
73 pub fn verify(&self, identity: &Identity) -> Option<(Vec<(u64, Digest)>, Vec<(u64, Digest)>)> {
74 if !self.certificate.verify(NAMESPACE, identity) {
76 return None;
77 }
78 if self.progress.digest() != self.certificate.item.digest {
79 return None;
80 }
81
82 if self.progress.state_start_op + self.state_proof_ops.len() as u64
84 != self.progress.state_end_op
85 {
86 return None;
87 }
88 let mut hasher = Standard::<Sha256>::new();
89 let Ok(state_proof_digests) = verify_proof_and_extract_digests(
90 &mut hasher,
91 &self.state_proof,
92 self.progress.state_start_op,
93 &self.state_proof_ops,
94 &self.progress.state_root,
95 ) else {
96 return None;
97 };
98
99 if self.progress.events_start_op + self.events_proof_ops.len() as u64
101 != self.progress.events_end_op
102 {
103 return None;
104 }
105 let Ok(events_proof_digests) = verify_proof_and_extract_digests(
106 &mut hasher,
107 &self.events_proof,
108 self.progress.events_start_op,
109 &self.events_proof_ops,
110 &self.progress.events_root,
111 ) else {
112 return None;
113 };
114
115 Some((state_proof_digests, events_proof_digests))
116 }
117}
118
119impl Write for Summary {
120 fn write(&self, writer: &mut impl BufMut) {
121 self.progress.write(writer);
122 self.certificate.write(writer);
123 self.state_proof.write(writer);
124 self.state_proof_ops.write(writer);
125 self.events_proof.write(writer);
126 self.events_proof_ops.write(writer);
127 }
128}
129
130impl Read for Summary {
131 type Cfg = ();
132
133 fn read_cfg(reader: &mut impl Buf, _: &Self::Cfg) -> Result<Self, Error> {
134 let progress = Progress::read(reader)?;
135 let certificate = Certificate::read(reader)?;
136 let state_proof = Proof::read_cfg(reader, &500)?;
137 let state_proof_ops = Vec::read_range(reader, 0..=500)?;
138 let events_proof = Proof::read_cfg(reader, &500)?;
139 let events_proof_ops = Vec::read_range(reader, 0..=500)?;
140 Ok(Self {
141 progress,
142 certificate,
143 state_proof,
144 state_proof_ops,
145 events_proof,
146 events_proof_ops,
147 })
148 }
149}
150
151impl EncodeSize for Summary {
152 fn encode_size(&self) -> usize {
153 self.progress.encode_size()
154 + self.certificate.encode_size()
155 + self.state_proof.encode_size()
156 + self.state_proof_ops.encode_size()
157 + self.events_proof.encode_size()
158 + self.events_proof_ops.encode_size()
159 }
160}
161
162#[derive(Clone, Eq, PartialEq, Debug)]
163pub struct Events {
164 pub progress: Progress,
165 pub certificate: Certificate<MinSig, Digest>,
166 pub events_proof: Proof<Digest>,
167 pub events_proof_ops: Vec<Keyless<Output>>,
168}
169
170impl Events {
171 pub fn verify(&self, identity: &Identity) -> bool {
172 if !self.certificate.verify(NAMESPACE, identity) {
174 return false;
175 }
176 if self.progress.digest() != self.certificate.item.digest {
177 return false;
178 }
179
180 if self.progress.events_start_op + self.events_proof_ops.len() as u64
182 != self.progress.events_end_op
183 {
184 return false;
185 }
186 let mut hasher = Standard::<Sha256>::new();
187 verify_proof(
188 &mut hasher,
189 &self.events_proof,
190 self.progress.events_start_op,
191 &self.events_proof_ops,
192 &self.progress.events_root,
193 )
194 }
195}
196impl Write for Events {
197 fn write(&self, writer: &mut impl BufMut) {
198 self.progress.write(writer);
199 self.certificate.write(writer);
200 self.events_proof.write(writer);
201 self.events_proof_ops.write(writer);
202 }
203}
204
205impl Read for Events {
206 type Cfg = ();
207
208 fn read_cfg(reader: &mut impl Buf, _: &Self::Cfg) -> Result<Self, Error> {
209 let progress = Progress::read(reader)?;
210 let certificate = Certificate::read(reader)?;
211 let events_proof = Proof::read_cfg(reader, &500)?;
212 let events_proof_ops = Vec::read_range(reader, 0..=500)?;
213 Ok(Self {
214 progress,
215 certificate,
216 events_proof,
217 events_proof_ops,
218 })
219 }
220}
221
222impl EncodeSize for Events {
223 fn encode_size(&self) -> usize {
224 self.progress.encode_size()
225 + self.certificate.encode_size()
226 + self.events_proof.encode_size()
227 + self.events_proof_ops.encode_size()
228 }
229}
230
231pub struct Lookup {
232 pub progress: Progress,
233 pub certificate: Certificate<MinSig, Digest>,
234 pub proof: Proof<Digest>,
235 pub location: u64,
236 pub operation: Variable<Digest, Value>,
237}
238
239impl Lookup {
240 pub fn verify(&self, identity: &Identity) -> bool {
241 if !self.certificate.verify(NAMESPACE, identity) {
243 return false;
244 }
245 if self.progress.digest() != self.certificate.item.digest {
246 return false;
247 }
248
249 let mut hasher = Standard::<Sha256>::new();
251 verify_proof(
252 &mut hasher,
253 &self.proof,
254 self.location,
255 std::slice::from_ref(&self.operation),
256 &self.progress.state_root,
257 )
258 }
259}
260
261impl Write for Lookup {
262 fn write(&self, writer: &mut impl BufMut) {
263 self.progress.write(writer);
264 self.certificate.write(writer);
265 self.proof.write(writer);
266 self.location.write(writer);
267 self.operation.write(writer);
268 }
269}
270
271impl Read for Lookup {
272 type Cfg = ();
273
274 fn read_cfg(reader: &mut impl Buf, _: &Self::Cfg) -> Result<Self, Error> {
275 let progress = Progress::read(reader)?;
276 let certificate = Certificate::read(reader)?;
277 let proof = Proof::read_cfg(reader, &500)?;
278 let location = u64::read(reader)?;
279 let operation = Variable::read(reader)?;
280 Ok(Self {
281 progress,
282 certificate,
283 proof,
284 location,
285 operation,
286 })
287 }
288}
289
290impl EncodeSize for Lookup {
291 fn encode_size(&self) -> usize {
292 self.progress.encode_size()
293 + self.certificate.encode_size()
294 + self.proof.encode_size()
295 + self.location.encode_size()
296 + self.operation.encode_size()
297 }
298}
299
300#[derive(Clone, Debug)]
301pub struct FilteredEvents {
302 pub progress: Progress,
303 pub certificate: Certificate<MinSig, Digest>,
304 pub events_proof: Proof<Digest>,
305 pub events_proof_ops: Vec<(u64, Keyless<Output>)>,
306}
307
308impl FilteredEvents {
309 pub fn verify(&self, identity: &Identity) -> bool {
310 if !self.certificate.verify(NAMESPACE, identity) {
312 return false;
313 }
314 if self.progress.digest() != self.certificate.item.digest {
315 return false;
316 }
317
318 for (loc, _) in &self.events_proof_ops {
320 if *loc < self.progress.events_start_op || *loc > self.progress.events_end_op {
321 return false;
322 }
323 }
324
325 let mut hasher = Standard::<Sha256>::new();
327 verify_multi_proof(
328 &mut hasher,
329 &self.events_proof,
330 &self.events_proof_ops,
331 &self.progress.events_root,
332 )
333 }
334}
335
336impl Write for FilteredEvents {
337 fn write(&self, writer: &mut impl BufMut) {
338 self.progress.write(writer);
339 self.certificate.write(writer);
340 self.events_proof.write(writer);
341 self.events_proof_ops.write(writer);
342 }
343}
344
345impl Read for FilteredEvents {
346 type Cfg = ();
347
348 fn read_cfg(reader: &mut impl Buf, _: &Self::Cfg) -> Result<Self, Error> {
349 let progress = Progress::read(reader)?;
350 let certificate = Certificate::read(reader)?;
351 let events_proof = Proof::read_cfg(reader, &500)?;
352 let events_proof_ops = Vec::read_range(reader, 0..=500)?;
353 Ok(Self {
354 progress,
355 certificate,
356 events_proof,
357 events_proof_ops,
358 })
359 }
360}
361
362impl EncodeSize for FilteredEvents {
363 fn encode_size(&self) -> usize {
364 self.progress.encode_size()
365 + self.certificate.encode_size()
366 + self.events_proof.encode_size()
367 + self.events_proof_ops.encode_size()
368 }
369}
370
371#[derive(Clone, Debug)]
372#[allow(clippy::large_enum_variant)]
373pub enum Update {
374 Seed(Seed),
375 Events(Events),
376 FilteredEvents(FilteredEvents),
377}
378
379impl Write for Update {
380 fn write(&self, writer: &mut impl BufMut) {
381 match self {
382 Update::Seed(seed) => {
383 0u8.write(writer);
384 seed.write(writer);
385 }
386 Update::Events(events) => {
387 1u8.write(writer);
388 events.write(writer);
389 }
390 Update::FilteredEvents(events) => {
391 2u8.write(writer);
392 events.write(writer);
393 }
394 }
395 }
396}
397
398impl Read for Update {
399 type Cfg = ();
400
401 fn read_cfg(reader: &mut impl Buf, _: &Self::Cfg) -> Result<Self, Error> {
402 let kind = u8::read(reader)?;
403 match kind {
404 0 => Ok(Update::Seed(Seed::read(reader)?)),
405 1 => Ok(Update::Events(Events::read(reader)?)),
406 2 => Ok(Update::FilteredEvents(FilteredEvents::read(reader)?)),
407 _ => Err(Error::InvalidEnum(kind)),
408 }
409 }
410}
411
412impl EncodeSize for Update {
413 fn encode_size(&self) -> usize {
414 1 + match self {
415 Update::Seed(seed) => seed.encode_size(),
416 Update::Events(events) => events.encode_size(),
417 Update::FilteredEvents(events) => events.encode_size(),
418 }
419 }
420}
421
422#[derive(Clone, Debug)]
423#[allow(clippy::large_enum_variant)]
424pub enum Submission {
425 Seed(Seed),
426 Transactions(Vec<Transaction>),
427 Summary(Summary),
428}
429
430impl Write for Submission {
431 fn write(&self, writer: &mut impl BufMut) {
432 match self {
433 Submission::Seed(seed) => {
434 0u8.write(writer);
435 seed.write(writer);
436 }
437 Submission::Transactions(txs) => {
438 1u8.write(writer);
439 txs.write(writer);
440 }
441 Submission::Summary(summary) => {
442 2u8.write(writer);
443 summary.write(writer);
444 }
445 }
446 }
447}
448
449impl Read for Submission {
450 type Cfg = ();
451
452 fn read_cfg(reader: &mut impl Buf, _: &Self::Cfg) -> Result<Self, Error> {
453 let kind = u8::read(reader)?;
454 match kind {
455 0 => Ok(Submission::Seed(Seed::read(reader)?)),
456 1 => Ok(Submission::Transactions(Vec::read_range(
457 reader,
458 1..=MAX_SUBMISSION_TRANSACTIONS,
459 )?)),
460 2 => Ok(Submission::Summary(Summary::read(reader)?)),
461 _ => Err(Error::InvalidEnum(kind)),
462 }
463 }
464}
465
466impl EncodeSize for Submission {
467 fn encode_size(&self) -> usize {
468 1 + match self {
469 Submission::Seed(seed) => seed.encode_size(),
470 Submission::Transactions(txs) => txs.encode_size(),
471 Submission::Summary(summary) => summary.encode_size(),
472 }
473 }
474}
475
476#[derive(Clone, Debug, Hash, Eq, PartialEq)]
478#[allow(clippy::large_enum_variant)]
479pub enum UpdatesFilter {
480 All,
482 Account(PublicKey),
484}
485
486impl Write for UpdatesFilter {
487 fn write(&self, writer: &mut impl BufMut) {
488 match self {
489 UpdatesFilter::All => 0u8.write(writer),
490 UpdatesFilter::Account(key) => {
491 1u8.write(writer);
492 key.write(writer);
493 }
494 }
495 }
496}
497
498impl Read for UpdatesFilter {
499 type Cfg = ();
500
501 fn read_cfg(reader: &mut impl Buf, _: &Self::Cfg) -> Result<Self, Error> {
502 let kind = u8::read(reader)?;
503 match kind {
504 0 => Ok(UpdatesFilter::All),
505 1 => Ok(UpdatesFilter::Account(PublicKey::read(reader)?)),
506 _ => Err(Error::InvalidEnum(kind)),
507 }
508 }
509}
510
511impl EncodeSize for UpdatesFilter {
512 fn encode_size(&self) -> usize {
513 1 + match self {
514 UpdatesFilter::All => 0,
515 UpdatesFilter::Account(key) => key.encode_size(),
516 }
517 }
518}
519
520#[derive(Clone, Debug)]
521pub struct Pending {
522 pub transactions: Vec<Transaction>,
523}
524
525impl Write for Pending {
526 fn write(&self, writer: &mut impl BufMut) {
527 self.transactions.write(writer);
528 }
529}
530
531impl Read for Pending {
532 type Cfg = ();
533
534 fn read_cfg(reader: &mut impl Buf, _: &Self::Cfg) -> Result<Self, Error> {
535 let transactions = Vec::<Transaction>::read_range(reader, 1..=MAX_SUBMISSION_TRANSACTIONS)?;
536 Ok(Self { transactions })
537 }
538}
539
540impl EncodeSize for Pending {
541 fn encode_size(&self) -> usize {
542 self.transactions.encode_size()
543 }
544}