use std::{
collections::BTreeMap,
fmt::{self, Debug, Display, Formatter},
fs::File,
sync::Arc,
};
use datasize::DataSize;
use itertools::Itertools;
use serde::Serialize;
use casper_types::{
execution::Effects, Block, EraId, FinalitySignature, FinalitySignatureV2, NextUpgrade,
PublicKey, Timestamp, Transaction, TransactionHash, U512,
};
use crate::{
components::{
consensus::{ClContext, ProposedBlock},
diagnostics_port::FileSerializer,
fetcher::FetchItem,
gossiper::GossipItem,
network::blocklist::BlocklistJustification,
},
effect::Responder,
failpoints::FailpointActivation,
types::{FinalizedBlock, MetaBlock, NodeId},
utils::Source,
};
#[derive(Serialize)]
#[must_use]
pub(crate) enum ControlAnnouncement {
ShutdownDueToUserRequest,
ShutdownForUpgrade,
ShutdownAfterCatchingUp,
FatalError {
file: &'static str,
line: u32,
msg: String,
},
QueueDumpRequest {
#[serde(skip)]
dump_format: QueueDumpFormat,
finished: Responder<()>,
},
ActivateFailpoint {
activation: FailpointActivation,
},
}
impl Debug for ControlAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
ControlAnnouncement::ShutdownDueToUserRequest => write!(f, "ShutdownDueToUserRequest"),
ControlAnnouncement::ShutdownForUpgrade => write!(f, "ShutdownForUpgrade"),
ControlAnnouncement::ShutdownAfterCatchingUp => write!(f, "ShutdownAfterCatchingUp"),
ControlAnnouncement::FatalError { file, line, msg } => f
.debug_struct("FatalError")
.field("file", file)
.field("line", line)
.field("msg", msg)
.finish(),
ControlAnnouncement::QueueDumpRequest { .. } => {
f.debug_struct("QueueDump").finish_non_exhaustive()
}
ControlAnnouncement::ActivateFailpoint { activation } => f
.debug_struct("ActivateFailpoint")
.field("activation", activation)
.finish(),
}
}
}
impl Display for ControlAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
ControlAnnouncement::ShutdownDueToUserRequest => {
write!(f, "shutdown due to user request")
}
ControlAnnouncement::ShutdownForUpgrade => write!(f, "shutdown for upgrade"),
ControlAnnouncement::ShutdownAfterCatchingUp => write!(f, "shutdown after catching up"),
ControlAnnouncement::FatalError { file, line, msg } => {
write!(f, "fatal error [{}:{}]: {}", file, line, msg)
}
ControlAnnouncement::QueueDumpRequest { .. } => {
write!(f, "dump event queue")
}
ControlAnnouncement::ActivateFailpoint { activation } => {
write!(f, "failpoint activation: {}", activation)
}
}
}
}
#[derive(Serialize, Debug)]
#[must_use]
pub(crate) struct FatalAnnouncement {
pub(crate) file: &'static str,
pub(crate) line: u32,
pub(crate) msg: String,
}
impl Display for FatalAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "fatal error [{}:{}]: {}", self.file, self.line, self.msg)
}
}
#[derive(DataSize, Serialize, Debug)]
pub(crate) struct MetaBlockAnnouncement(pub(crate) MetaBlock);
impl Display for MetaBlockAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"announcement for meta block {} at height {}",
self.0.hash(),
self.0.height(),
)
}
}
#[derive(DataSize, Serialize, Debug)]
pub(crate) struct UnexecutedBlockAnnouncement(pub(crate) u64);
impl Display for UnexecutedBlockAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"announcement for unexecuted finalized block at height {}",
self.0,
)
}
}
#[derive(Serialize)]
pub(crate) enum QueueDumpFormat {
Serde(#[serde(skip)] FileSerializer),
Debug(#[serde(skip)] File),
}
impl QueueDumpFormat {
pub(crate) fn serde(serializer: FileSerializer) -> Self {
QueueDumpFormat::Serde(serializer)
}
pub(crate) fn debug(file: File) -> Self {
QueueDumpFormat::Debug(file)
}
}
#[derive(Debug, Serialize)]
pub(crate) enum TransactionAcceptorAnnouncement {
AcceptedNewTransaction {
transaction: Arc<Transaction>,
source: Source,
},
InvalidTransaction {
transaction: Transaction,
source: Source,
},
}
impl Display for TransactionAcceptorAnnouncement {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self {
TransactionAcceptorAnnouncement::AcceptedNewTransaction {
transaction,
source,
} => write!(
formatter,
"accepted new transaction {} from {}",
transaction.hash(),
source
),
TransactionAcceptorAnnouncement::InvalidTransaction {
transaction,
source,
} => {
write!(
formatter,
"invalid transaction {} from {}",
transaction.hash(),
source
)
}
}
}
}
#[derive(Debug, Serialize)]
pub(crate) enum TransactionBufferAnnouncement {
TransactionsExpired(Vec<TransactionHash>),
}
impl Display for TransactionBufferAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
TransactionBufferAnnouncement::TransactionsExpired(hashes) => {
write!(f, "pruned hashes: {}", hashes.iter().join(", "))
}
}
}
}
#[derive(Debug)]
pub(crate) enum ConsensusAnnouncement {
Proposed(Box<ProposedBlock<ClContext>>),
Finalized(Box<FinalizedBlock>),
Fault {
era_id: EraId,
public_key: Box<PublicKey>,
timestamp: Timestamp,
},
}
impl Display for ConsensusAnnouncement {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self {
ConsensusAnnouncement::Proposed(block) => {
write!(formatter, "proposed block payload {}", block)
}
ConsensusAnnouncement::Finalized(block) => {
write!(formatter, "finalized block payload {}", block)
}
ConsensusAnnouncement::Fault {
era_id,
public_key,
timestamp,
} => write!(
formatter,
"Validator fault with public key: {} has been identified at time: {} in {}",
public_key, timestamp, era_id,
),
}
}
}
#[derive(Debug, Serialize)]
pub(crate) enum PeerBehaviorAnnouncement {
OffenseCommitted {
offender: Box<NodeId>,
justification: Box<BlocklistJustification>,
},
}
impl Display for PeerBehaviorAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
PeerBehaviorAnnouncement::OffenseCommitted {
offender,
justification,
} => {
write!(f, "peer {} committed offense: {}", offender, justification)
}
}
}
}
#[derive(Debug)]
pub(crate) enum GossiperAnnouncement<T: GossipItem> {
GossipReceived { item_id: T::Id, sender: NodeId },
NewCompleteItem(T::Id),
NewItemBody { item: Box<T>, sender: NodeId },
FinishedGossiping(T::Id),
}
impl<T: GossipItem> Display for GossiperAnnouncement<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
GossiperAnnouncement::GossipReceived { item_id, sender } => {
write!(f, "new gossiped item {} from sender {}", item_id, sender)
}
GossiperAnnouncement::NewCompleteItem(item) => write!(f, "new complete item {}", item),
GossiperAnnouncement::NewItemBody { item, sender } => {
write!(f, "new item body {} from {}", item.gossip_id(), sender)
}
GossiperAnnouncement::FinishedGossiping(item_id) => {
write!(f, "finished gossiping {}", item_id)
}
}
}
}
#[derive(Debug, Serialize)]
pub(crate) struct UpgradeWatcherAnnouncement(pub(crate) Option<NextUpgrade>);
impl Display for UpgradeWatcherAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match &self.0 {
Some(next_upgrade) => write!(f, "read {}", next_upgrade),
None => write!(f, "no upgrade staged"),
}
}
}
#[derive(Debug, Serialize)]
pub(crate) enum ContractRuntimeAnnouncement {
CommitStepSuccess {
era_id: EraId,
effects: Effects,
},
UpcomingEraValidators {
era_that_is_ending: EraId,
upcoming_era_validators: BTreeMap<EraId, BTreeMap<PublicKey, U512>>,
},
NextEraGasPrice {
era_id: EraId,
next_era_gas_price: u8,
},
}
impl Display for ContractRuntimeAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
ContractRuntimeAnnouncement::CommitStepSuccess { era_id, .. } => {
write!(f, "commit step completed for {}", era_id)
}
ContractRuntimeAnnouncement::UpcomingEraValidators {
era_that_is_ending, ..
} => {
write!(
f,
"upcoming era validators after current {}.",
era_that_is_ending,
)
}
ContractRuntimeAnnouncement::NextEraGasPrice {
era_id,
next_era_gas_price,
} => {
write!(
f,
"Calculated gas price {} for era {}",
next_era_gas_price, era_id
)
}
}
}
}
#[derive(Debug, Serialize)]
pub(crate) enum BlockAccumulatorAnnouncement {
AcceptedNewFinalitySignature {
finality_signature: Box<FinalitySignatureV2>,
},
}
impl Display for BlockAccumulatorAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
BlockAccumulatorAnnouncement::AcceptedNewFinalitySignature { finality_signature } => {
write!(
f,
"finality signature {} accepted",
finality_signature.gossip_id()
)
}
}
}
}
#[derive(Debug, Serialize)]
pub(crate) struct FetchedNewBlockAnnouncement {
pub(crate) block: Arc<Block>,
pub(crate) peer: NodeId,
}
impl Display for FetchedNewBlockAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"new block {} fetched from {}",
self.block.fetch_id(),
self.peer
)
}
}
#[derive(Debug, Serialize)]
pub(crate) struct FetchedNewFinalitySignatureAnnouncement {
pub(crate) finality_signature: Box<FinalitySignature>,
pub(crate) peer: NodeId,
}
impl Display for FetchedNewFinalitySignatureAnnouncement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"new finality signature {} fetched from {}",
self.finality_signature.fetch_id(),
self.peer
)
}
}