pub fn into_shreds(
    chunks: impl IntoIterator<Item = DuplicateShred>,
    leader: impl LeaderScheduleFn,
) -> Result<(Shred, Shred), Error> {
    let mut chunks = chunks.into_iter();
    let DuplicateShred {
        slot,
        shred_index,
        shred_type,
        num_chunks,
        chunk_index,
        chunk,
        ..
    } = chunks.next().ok_or(Error::InvalidDuplicateShreds)?;
    let slot_leader = leader(slot).ok_or(Error::UnknownSlotLeader)?;
    let check_chunk = check_chunk(slot, shred_index, shred_type, num_chunks);
    let mut data = HashMap::new();
    data.insert(chunk_index, chunk);
    for chunk in chunks {
        check_chunk(&chunk)?;
        match data.entry(chunk.chunk_index) {
            Entry::Vacant(entry) => {
                entry.insert(chunk.chunk);
            }
            Entry::Occupied(entry) => {
                if *entry.get() != chunk.chunk {
                    return Err(Error::DataChunkMismatch);
                }
            }
        }
    }
    if data.len() != num_chunks as usize {
        return Err(Error::MissingDataChunk);
    }
    let data = (0..num_chunks).map(|k| data.remove(&k).unwrap()).concat();
    let proof: DuplicateSlotProof = bincode::deserialize(&data)?;
    if proof.shred1 == proof.shred2 {
        return Err(Error::InvalidDuplicateSlotProof);
    }
    let shred1 = Shred::new_from_serialized_shred(proof.shred1)?;
    let shred2 = Shred::new_from_serialized_shred(proof.shred2)?;
    if shred1.slot() != slot || shred2.slot() != slot {
        Err(Error::SlotMismatch)
    } else if shred1.index() != shred_index || shred2.index() != shred_index {
        Err(Error::ShredIndexMismatch)
    } else if shred1.shred_type() != shred_type || shred2.shred_type() != shred_type {
        Err(Error::ShredTypeMismatch)
    } else if shred1.payload == shred2.payload {
        Err(Error::InvalidDuplicateShreds)
    } else if !shred1.verify(&slot_leader) || !shred2.verify(&slot_leader) {
        Err(Error::InvalidSignature)
    } else {
        Ok((shred1, shred2))
    }
}
/// Reconstructs the duplicate shreds from chunks of DuplicateShred.
Reconstructs the duplicate shreds from chunks of DuplicateShred.
Reconstructs the duplicate shreds from chunks of DuplicateShred .
pub fn into_shreds(
    chunks: impl IntoIterator<Item = DuplicateShred>,
    leader: impl LeaderScheduleFn,
) -> Result<(Shred, Shred), Error> {
    let mut chunks = chunks.into_iter();
    let DuplicateShred {
        slot,
        shred_index,
        shred_type,
        num_chunks,
        chunk_index,
        chunk,
        ..
    } = chunks.next().ok_or(Error::InvalidDuplicateShreds)?;
    let slot_leader = leader(slot).ok_or(Error::UnknownSlotLeader)?;
    let check_chunk = check_chunk(slot, shred_index, shred_type, num_chunks);
    let mut data = HashMap::new();
    data.insert(chunk_index, chunk);
    for chunk in chunks {
        check_chunk(&chunk)?;
        match data.entry(chunk.chunk_index) {
            Entry::Vacant(entry) => {
                entry.insert(chunk.chunk);
            }
            Entry::Occupied(entry) => {
                if *entry.get() != chunk.chunk {
                    return Err(Error::DataChunkMismatch);
                }
            }
        }
    }
    if data.len() != num_chunks as usize {
        return Err(Error::MissingDataChunk);
    }
    let data = (0..num_chunks).map(|k| data.remove(&k).unwrap()).concat();
    let proof: DuplicateSlotProof = bincode::deserialize(&data)?;
    if proof.shred1 == proof.shred2 {
        return Err(Error::InvalidDuplicateSlotProof);
    }
    let shred1 = Shred::new_from_serialized_shred(proof.shred1)?;
    let shred2 = Shred::new_from_serialized_shred(proof.shred2)?;
    if shred1.slot() != slot || shred2.slot() != slot {
        Err(Error::SlotMismatch)
    } else if shred1.index() != shred_index || shred2.index() != shred_index {
        Err(Error::ShredIndexMismatch)
    } else if shred1.shred_type() != shred_type || shred2.shred_type() != shred_type {
        Err(Error::ShredTypeMismatch)
    } else if shred1.payload == shred2.payload {
        Err(Error::InvalidDuplicateShreds)
    } else if !shred1.verify(&slot_leader) || !shred2.verify(&slot_leader) {
        Err(Error::InvalidSignature)
    } else {
        Ok((shred1, shred2))
    }
}
pub fn into_shreds ( chunks : impl IntoIterator < Item = DuplicateShred > , leader : impl LeaderScheduleFn , ) -> Result < ( Shred , Shred ) , Error > { let mut chunks = chunks . into_iter ( ) ; let DuplicateShred { slot , shred_index , shred_type , num_chunks , chunk_index , chunk , .. } = chunks . next ( ) . ok_or ( Error :: InvalidDuplicateShreds ) ? ; let slot_leader = leader ( slot ) . ok_or ( Error :: UnknownSlotLeader ) ? ; let check_chunk = check_chunk ( slot , shred_index , shred_type , num_chunks ) ; let mut data = HashMap :: new ( ) ; data . insert ( chunk_index , chunk ) ; for chunk in chunks { check_chunk ( & chunk ) ? ; match data . entry ( chunk . chunk_index ) { Entry :: Vacant ( entry ) => { entry . insert ( chunk . chunk ) ; } Entry :: Occupied ( entry ) => { if * entry . get ( ) != chunk . chunk { return Err ( Error :: DataChunkMismatch ) ; } } } } if data . len ( ) != num_chunks as usize { return Err ( Error :: MissingDataChunk ) ; } let data = ( 0 .. num_chunks ) . map ( | k | data . remove ( & k ) . unwrap ( ) ) . concat ( ) ; let proof : DuplicateSlotProof = bincode :: deserialize ( & data ) ? ; if proof . shred1 == proof . shred2 { return Err ( Error :: InvalidDuplicateSlotProof ) ; } let shred1 = Shred :: new_from_serialized_shred ( proof . shred1 ) ? ; let shred2 = Shred :: new_from_serialized_shred ( proof . shred2 ) ? ; if shred1 . slot ( ) != slot || shred2 . slot ( ) != slot { Err ( Error :: SlotMismatch ) } else if shred1 . index ( ) != shred_index || shred2 . index ( ) != shred_index { Err ( Error :: ShredIndexMismatch ) } else if shred1 . shred_type ( ) != shred_type || shred2 . shred_type ( ) != shred_type { Err ( Error :: ShredTypeMismatch ) } else if shred1 . payload == shred2 . payload { Err ( Error :: InvalidDuplicateShreds ) } else if ! shred1 . verify ( & slot_leader ) || ! shred2 . verify ( & slot_leader ) { Err ( Error :: InvalidSignature ) } else { Ok ( ( shred1 , shred2 ) ) } }
Reconstructs the duplicate shreds from chunks of DuplicateShred.
Reconstructs the duplicate shreds from chunks of DuplicateShred .
chunks
impl IntoIterator<Item = DuplicateShred>
leader
impl LeaderScheduleFn