Host-side coherence check for one input's shard proofs: every shard must carry the same `env_hash`, the ranges must tile `[0, total)` exactly, and failures are summed. Returns this input's failure count. (The agg guest can't yet parse leaf publics from the proof blob, so this is enforced here.)
( label: &str, publics: &[ShardPublics], total: u32, )
| 732 | /// `cover` (its `covered()` target addresses): `merkle_root_canonical` over the |
| 733 | /// addresses, exactly as the guest computes it. Used host-side to re-derive the |
| 734 | /// expected per-child subject *from the env* (not from the proof) so the final |
| 735 | /// aggregate's committed subject can be checked against the env it should cover. |
| 736 | fn subject_of_cover(cover: &[[u8; 32]]) -> ix_common::address::Address { |
| 737 | use ix_common::address::Address; |
| 738 | let leaves: Vec<Address> = cover |
| 739 | .iter() |
| 740 | .map(|b| Address::from_slice(b).expect("cover address")) |
| 741 | .collect(); |
| 742 | ixon::merkle::merkle_root_canonical(&leaves) |
| 743 | .unwrap_or_else(ixon::merkle::zero_address) |
| 744 | } |
| 745 | |
| 746 | /// Partition `n` items into chunks of at most `arity` each, avoiding |
| 747 | /// any chunk of size exactly 1 (which would make agg-of-1 a no-op). |
| 748 | /// When the trailing remainder is 1, it's merged into the previous |
| 749 | /// chunk so the smallest chunk produced is size 2. Returns half-open |
| 750 | /// `(start, end)` index ranges. |
| 751 | fn tree_partition(n: usize, arity: usize) -> Vec<(usize, usize)> { |
| 752 | if n <= arity { |
| 753 | return vec![(0, n)]; |
| 754 | } |
| 755 | let mut ranges: Vec<(usize, usize)> = Vec::new(); |
| 756 | let mut i = 0; |
| 757 | while i + arity <= n { |
| 758 | ranges.push((i, i + arity)); |
| 759 | i += arity; |
| 760 | } |
| 761 | let remainder = n - i; |
| 762 | if remainder == 1 { |
| 763 | // Merge the singleton into the previous chunk so the agg guest |
| 764 | // never gets called with just one proof (which would be agg-of-1 |
| 765 | // pure overhead). |