Build the manifest from a profile and a shard assignment (shard id in `0..num_shards` per block id).
(
profile: &BlockProfile,
shard_of: &[u32],
num_shards: usize,
)
| 1289 | pub num_shards: u32, |
| 1290 | pub shards: Vec<ShardInfo>, |
| 1291 | /// Total cross-shard ingress bytes (the km1 objective). |
| 1292 | pub total_cross_ingress: u128, |
| 1293 | /// The bisection tree over the shard ids, for proof aggregation. `None` on |
| 1294 | /// manifests written before this section existed (the prover then falls back |
| 1295 | /// to a flat tree-fold). Set by [`Self::with_tree`]. |
| 1296 | pub tree: Option<AggNode>, |
| 1297 | } |
| 1298 | |
| 1299 | impl ShardManifest { |
| 1300 | /// Build the manifest from a profile and a shard assignment (shard id in |
| 1301 | /// `0..num_shards` per block id). |
| 1302 | pub fn build( |
| 1303 | profile: &BlockProfile, |
| 1304 | shard_of: &[u32], |
| 1305 | num_shards: usize, |
| 1306 | ) -> ShardManifest { |
| 1307 | let mut members: Vec<Vec<u32>> = vec![Vec::new(); num_shards]; |
| 1308 | for (b, &s) in shard_of.iter().enumerate() { |
| 1309 | members[s as usize].push(b as u32); |
| 1310 | } |
| 1311 | // Distinct foreign blocks per shard. |
| 1312 | let mut foreign: Vec<FxHashSet<u32>> = |
| 1313 | vec![FxHashSet::default(); num_shards]; |
| 1314 | for b in 0..profile.num_blocks() as u32 { |
| 1315 | let s = shard_of[b as usize] as usize; |
| 1316 | for &p in profile.producers(b) { |
| 1317 | if shard_of[p as usize] as usize != s { |
| 1318 | foreign[s].insert(p); |
| 1319 | } |
| 1320 | } |
| 1321 | } |
| 1322 | let mut shards = Vec::with_capacity(num_shards); |
| 1323 | let mut total_cross: u128 = 0; |
| 1324 | for s in 0..num_shards { |
| 1325 | let blocks: Vec<Address> = |
| 1326 | members[s].iter().map(|&b| profile.block(b).addr.clone()).collect(); |
| 1327 | let heartbeats: u64 = |
| 1328 | members[s].iter().map(|&b| profile.block(b).heartbeats).sum(); |
| 1329 | let own_size: u64 = members[s] |
| 1330 | .iter() |
| 1331 | .map(|&b| u64::from(profile.block(b).serialized_size)) |
| 1332 | .sum(); |
| 1333 | let mut fb: Vec<u32> = foreign[s].iter().copied().collect(); |
| 1334 | fb.sort_unstable(); |
| 1335 | let cross_ingress: u64 = |
| 1336 | fb.iter().map(|&p| u64::from(profile.block(p).serialized_size)).sum(); |
| 1337 | total_cross += u128::from(cross_ingress); |
| 1338 | let foreign_blocks: Vec<Address> = |
| 1339 | fb.iter().map(|&p| profile.block(p).addr.clone()).collect(); |
| 1340 | shards.push(ShardInfo { |
| 1341 | id: s as u32, |
| 1342 | blocks, |
| 1343 | heartbeats, |
| 1344 | own_size, |
| 1345 | foreign_blocks, |
| 1346 | cross_ingress, |
| 1347 | assumption_root: None, |
| 1348 | }); |