use massa_models::address::ExecutionAddressCycleInfo;
use massa_models::endorsement::EndorsementId;
use massa_models::operation::OperationId;
use massa_models::slot::{IndexedSlot, Slot};
use massa_models::{address::Address, amount::Amount, block_id::BlockId};
use serde::{Deserialize, Serialize};
use crate::slot::SlotAmount;
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AddressInfo {
pub address: Address,
pub thread: u8,
pub final_balance: Amount,
pub final_roll_count: u64,
pub final_datastore_keys: Vec<Vec<u8>>,
pub candidate_balance: Amount,
pub candidate_roll_count: u64,
pub candidate_datastore_keys: Vec<Vec<u8>>,
pub deferred_credits: Vec<SlotAmount>,
pub next_block_draws: Vec<Slot>,
pub next_endorsement_draws: Vec<IndexedSlot>,
pub created_blocks: Vec<BlockId>,
pub created_operations: Vec<OperationId>,
pub created_endorsements: Vec<EndorsementId>,
pub cycle_infos: Vec<ExecutionAddressCycleInfo>,
}
impl std::fmt::Display for AddressInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "Address {} (thread {}):", self.address, self.thread)?;
writeln!(
f,
"\tBalance: final={}, candidate={}",
self.final_balance, self.candidate_balance
)?;
writeln!(
f,
"\tRolls: final={}, candidate={}",
self.final_roll_count, self.candidate_roll_count
)?;
write!(f, "\tLocked coins:")?;
if self.deferred_credits.is_empty() {
writeln!(f, "0")?;
} else {
for slot_amount in &self.deferred_credits {
writeln!(
f,
"\t\t{} locked coins will be unlocked at slot {}",
slot_amount.amount, slot_amount.slot
)?;
}
}
writeln!(f, "\tCycle infos:")?;
for cycle_info in &self.cycle_infos {
writeln!(
f,
"\t\tCycle {} ({}): produced {} and missed {} blocks{}",
cycle_info.cycle,
if cycle_info.is_final {
"final"
} else {
"candidate"
},
cycle_info.ok_count,
cycle_info.nok_count,
match cycle_info.active_rolls {
Some(rolls) => format!(" with {} active rolls", rolls),
None => "".into(),
},
)?;
}
Ok(())
}
}
impl AddressInfo {
pub fn compact(&self) -> CompactAddressInfo {
CompactAddressInfo {
address: self.address,
thread: self.thread,
active_rolls: self
.cycle_infos
.last()
.and_then(|c| c.active_rolls)
.unwrap_or_default(),
final_rolls: self.final_roll_count,
candidate_rolls: self.candidate_roll_count,
final_balance: self.final_balance,
candidate_balance: self.candidate_balance,
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CompactAddressInfo {
pub address: Address,
pub thread: u8,
pub candidate_rolls: u64,
pub final_rolls: u64,
pub active_rolls: u64,
pub final_balance: Amount,
pub candidate_balance: Amount,
}
impl std::fmt::Display for CompactAddressInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "Address: {} (thread {}):", self.address, self.thread)?;
writeln!(
f,
"\tBalance: final={}, candidate={}",
self.final_balance, self.candidate_balance
)?;
writeln!(
f,
"\tRolls: active={}, final={}, candidate={}",
self.active_rolls, self.final_rolls, self.candidate_rolls
)?;
Ok(())
}
}
#[derive(Debug, Deserialize, Clone, Serialize)]
pub struct AddressFilter {
pub address: Address,
pub is_final: bool,
}
impl std::fmt::Display for AddressFilter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Address: {:?}", self.address)?;
if self.is_final {
write!(f, " (Final)")
} else {
write!(f, " (Candidate)")
}
}
}