use std::{
collections::HashMap,
fmt::{self, Display, Formatter},
};
use datasize::DataSize;
use serde::{Deserialize, Serialize};
use super::{event::DeployType, BlockHeight, FinalizationQueue};
use crate::{
types::{DeployHash, DeployHeader, Timestamp},
Chainspec,
};
#[derive(Clone, DataSize, Debug, Deserialize, Serialize)]
pub struct BlockProposerDeploySets {
pub(super) pending: HashMap<DeployHash, DeployType>,
pub(super) finalized_deploys: HashMap<DeployHash, DeployHeader>,
pub(super) next_finalized: BlockHeight,
pub(super) finalization_queue: FinalizationQueue,
}
impl Default for BlockProposerDeploySets {
fn default() -> Self {
let pending = HashMap::new();
let finalized_deploys = Default::default();
let next_finalized = Default::default();
let finalization_queue = Default::default();
BlockProposerDeploySets {
pending,
finalized_deploys,
next_finalized,
finalization_queue,
}
}
}
impl BlockProposerDeploySets {
pub(super) fn with_next_finalized(self, next_finalized: BlockHeight) -> Self {
BlockProposerDeploySets {
next_finalized,
..self
}
}
}
impl Display for BlockProposerDeploySets {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(
f,
"(pending:{}, finalized:{})",
self.pending.len(),
self.finalized_deploys.len()
)
}
}
pub fn create_storage_key(chainspec: &Chainspec) -> Vec<u8> {
format!(
"block_proposer_deploy_sets:version={},chain_name={}",
chainspec.genesis.protocol_version, chainspec.genesis.name
)
.into()
}
impl BlockProposerDeploySets {
pub(crate) fn prune(&mut self, current_instant: Timestamp) -> usize {
let pending = prune_pending_deploys(&mut self.pending, current_instant);
let finalized = prune_deploys(&mut self.finalized_deploys, current_instant);
pending + finalized
}
}
pub(super) fn prune_deploys(
deploys: &mut HashMap<DeployHash, DeployHeader>,
current_instant: Timestamp,
) -> usize {
let initial_len = deploys.len();
deploys.retain(|_hash, header| !header.expired(current_instant));
initial_len - deploys.len()
}
pub(super) fn prune_pending_deploys(
deploys: &mut HashMap<DeployHash, DeployType>,
current_instant: Timestamp,
) -> usize {
let initial_len = deploys.len();
deploys.retain(|_hash, wrapper| !wrapper.header().expired(current_instant));
initial_len - deploys.len()
}