/// Split validators into quality/poor lists based on their block production over the given `epoch`
Split validators into quality/poor lists based on their block production over the given `epoch`
Split validators into quality / poor lists based on their block production over the given ` epoch `
fn classify_block_producers(
    rpc_client: &RpcClient,
    config: &Config,
    epoch: Epoch,
) -> Result<(HashSet<Pubkey>, HashSet<Pubkey>), Box<dyn error::Error>> {
    let epoch_schedule = rpc_client.get_epoch_schedule()?;
    let first_slot_in_epoch = epoch_schedule.get_first_slot_in_epoch(epoch);
    let last_slot_in_epoch = epoch_schedule.get_last_slot_in_epoch(epoch);
    let minimum_ledger_slot = rpc_client.minimum_ledger_slot()?;
    if minimum_ledger_slot >= last_slot_in_epoch {
        return Err(format!(
            "Minimum ledger slot is newer than the last epoch: {} > {}",
            minimum_ledger_slot, last_slot_in_epoch
        )
        .into());
    }
    let first_slot = if minimum_ledger_slot > first_slot_in_epoch {
        minimum_ledger_slot
    } else {
        first_slot_in_epoch
    };
    let confirmed_blocks = rpc_client.get_confirmed_blocks(first_slot, Some(last_slot_in_epoch))?;
    let confirmed_blocks: HashSet<Slot> = HashSet::from_iter(confirmed_blocks.into_iter());
    let mut poor_block_producers = HashSet::new();
    let mut quality_block_producers = HashSet::new();
    let leader_schedule = rpc_client.get_leader_schedule(Some(first_slot))?.unwrap();
    for (validator_identity, relative_slots) in leader_schedule {
        let mut validator_blocks = 0;
        let mut validator_slots = 0;
        for relative_slot in relative_slots {
            let slot = first_slot_in_epoch + relative_slot as Slot;
            if slot >= first_slot {
                validator_slots += 1;
                if confirmed_blocks.contains(&slot) {
                    validator_blocks += 1;
                }
            }
        }
        trace!(
            "Validator {} produced {} blocks in {} slots",
            validator_identity,
            validator_blocks,
            validator_slots
        );
        if validator_slots > 0 {
            let validator_identity = Pubkey::from_str(&validator_identity)?;
            if validator_blocks * 100 / validator_slots >= config.quality_block_producer_percentage
            {
                quality_block_producers.insert(validator_identity);
            } else {
                poor_block_producers.insert(validator_identity);
            }
        }
    }
    info!("quality_block_producers: {}", quality_block_producers.len());
    trace!("quality_block_producers: {:?}", quality_block_producers);
    info!("poor_block_producers: {}", poor_block_producers.len());
    trace!("poor_block_producers: {:?}", poor_block_producers);
    Ok((quality_block_producers, poor_block_producers))
}
fn classify_block_producers ( rpc_client : & RpcClient , config : & Config , epoch : Epoch , ) -> Result < ( HashSet < Pubkey > , HashSet < Pubkey > ) , Box < dyn error :: Error > > { let epoch_schedule = rpc_client . get_epoch_schedule ( ) ? ; let first_slot_in_epoch = epoch_schedule . get_first_slot_in_epoch ( epoch ) ; let last_slot_in_epoch = epoch_schedule . get_last_slot_in_epoch ( epoch ) ; let minimum_ledger_slot = rpc_client . minimum_ledger_slot ( ) ? ; if minimum_ledger_slot >= last_slot_in_epoch { return Err ( format ! ( " " minimum_ledger_slot last_slot_in_epoch ) . into ( ) ) ; } let first_slot = if minimum_ledger_slot > first_slot_in_epoch { minimum_ledger_slot } else { first_slot_in_epoch } ; let confirmed_blocks = rpc_client . get_confirmed_blocks ( first_slot , Some ( last_slot_in_epoch ) ) ? ; let confirmed_blocks : HashSet < Slot > = HashSet :: from_iter ( confirmed_blocks . into_iter ( ) ) ; let mut poor_block_producers = HashSet :: new ( ) ; let mut quality_block_producers = HashSet :: new ( ) ; let leader_schedule = rpc_client . get_leader_schedule ( Some ( first_slot ) ) ? . unwrap ( ) ; for ( validator_identity , relative_slots ) in leader_schedule { let mut validator_blocks = 0 ; let mut validator_slots = 0 ; for relative_slot in relative_slots { let slot = first_slot_in_epoch + relative_slot as Slot ; if slot >= first_slot { validator_slots += 1 ; if confirmed_blocks . contains ( & slot ) { validator_blocks += 1 ; } } } trace ! ( " " validator_identity validator_blocks validator_slots ) ; if validator_slots > 0 { let validator_identity = Pubkey :: from_str ( & validator_identity ) ? ; if validator_blocks * 100 / validator_slots >= config . quality_block_producer_percentage { quality_block_producers . insert ( validator_identity ) ; } else { poor_block_producers . insert ( validator_identity ) ; } } } info ! ( " " quality_block_producers len ( ) ) ; trace ! ( " " quality_block_producers ) ; info ! ( " " poor_block_producers len ( ) ) ; trace ! ( " " poor_block_producers ) ; Ok ( ( quality_block_producers , poor_block_producers ) ) }
Split validators into quality/poor lists based on their block production over the given `epoch`
Split validators into quality / poor lists based on their block production over the given ` epoch `
rpc_client
&RpcClient
config
&Config
epoch
Epoch