use dig_protocol::Bytes32;
use serde::{Deserialize, Serialize};
use crate::bonds::BondEscrow;
use crate::constants::{MAX_APPEALS_PER_BLOCK, MAX_SLASH_PROPOSALS_PER_BLOCK};
use crate::error::SlashingError;
use crate::manager::{SlashingManager, SlashingResult};
use crate::remark::appeal_wire::parse_slash_appeals_from_conditions;
use crate::remark::evidence_wire::parse_slashing_evidence_from_conditions;
use crate::traits::{EffectiveBalanceView, ProposerView, RewardPayout, ValidatorView};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct BlockAdmissionReport {
pub admitted_evidences: Vec<(Bytes32, SlashingResult)>,
pub rejected_evidences: Vec<(Bytes32, SlashingError)>,
pub admitted_appeals: Vec<Bytes32>,
pub rejected_appeals: Vec<(Bytes32, SlashingError)>,
pub cap_dropped_evidences: usize,
pub cap_dropped_appeals: usize,
}
#[allow(clippy::too_many_arguments)]
pub fn process_block_admissions<P>(
payloads: &[P],
manager: &mut SlashingManager,
validator_set: &mut dyn ValidatorView,
effective_balances: &dyn EffectiveBalanceView,
bond_escrow: &mut dyn BondEscrow,
reward_payout: &mut dyn RewardPayout,
proposer: &dyn ProposerView,
network_id: &Bytes32,
) -> BlockAdmissionReport
where
P: AsRef<[u8]>,
{
let mut report = BlockAdmissionReport::default();
let mut evidences = parse_slashing_evidence_from_conditions(payloads);
let mut appeals = parse_slash_appeals_from_conditions(payloads);
if evidences.len() > MAX_SLASH_PROPOSALS_PER_BLOCK {
report.cap_dropped_evidences = evidences.len() - MAX_SLASH_PROPOSALS_PER_BLOCK;
evidences.truncate(MAX_SLASH_PROPOSALS_PER_BLOCK);
}
if appeals.len() > MAX_APPEALS_PER_BLOCK {
report.cap_dropped_appeals = appeals.len() - MAX_APPEALS_PER_BLOCK;
appeals.truncate(MAX_APPEALS_PER_BLOCK);
}
for ev in evidences {
let evidence_hash = ev.hash();
match manager.submit_evidence(
ev,
validator_set,
effective_balances,
bond_escrow,
reward_payout,
proposer,
network_id,
) {
Ok(result) => report.admitted_evidences.push((evidence_hash, result)),
Err(err) => report.rejected_evidences.push((evidence_hash, err)),
}
}
for ap in appeals {
let appeal_hash = ap.hash();
match manager.submit_appeal(&ap, bond_escrow) {
Ok(()) => report.admitted_appeals.push(appeal_hash),
Err(err) => report.rejected_appeals.push((appeal_hash, err)),
}
}
report
}