use crate::{
block::Block,
common::{Payload, Round},
quorum_cert::QuorumCert,
vote_proposal::VoteProposal,
};
use aptos_crypto::hash::HashValue;
use aptos_types::{
account_address::AccountAddress,
block_info::BlockInfo,
contract_event::ContractEvent,
transaction::{Transaction, TransactionStatus},
};
use executor_types::StateComputeResult;
use std::fmt::{Debug, Display, Formatter};
#[derive(Clone, Eq, PartialEq)]
pub struct ExecutedBlock {
block: Block,
state_compute_result: StateComputeResult,
}
impl Debug for ExecutedBlock {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "{}", self)
}
}
impl Display for ExecutedBlock {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "{}", self.block())
}
}
impl ExecutedBlock {
pub fn new(block: Block, state_compute_result: StateComputeResult) -> Self {
Self {
block,
state_compute_result,
}
}
pub fn block(&self) -> &Block {
&self.block
}
pub fn id(&self) -> HashValue {
self.block().id()
}
pub fn epoch(&self) -> u64 {
self.block.epoch()
}
pub fn payload(&self) -> Option<&Payload> {
self.block().payload()
}
pub fn parent_id(&self) -> HashValue {
self.quorum_cert().certified_block().id()
}
pub fn quorum_cert(&self) -> &QuorumCert {
self.block().quorum_cert()
}
pub fn round(&self) -> Round {
self.block().round()
}
pub fn timestamp_usecs(&self) -> u64 {
self.block().timestamp_usecs()
}
pub fn compute_result(&self) -> &StateComputeResult {
&self.state_compute_result
}
pub fn block_info(&self) -> BlockInfo {
self.block().gen_block_info(
self.compute_result().root_hash(),
self.compute_result().version(),
self.compute_result().epoch_state().clone(),
)
}
pub fn vote_proposal(&self, decoupled_execution: bool) -> VoteProposal {
VoteProposal::new(
self.compute_result().extension_proof(),
self.block.clone(),
self.compute_result().epoch_state().clone(),
decoupled_execution,
)
}
pub fn transactions_to_commit(&self, validators: &[AccountAddress]) -> Vec<Transaction> {
if self.is_reconfiguration_suffix() {
return vec![];
}
itertools::zip_eq(
self.block.transactions_to_execute(validators),
self.state_compute_result.compute_status(),
)
.filter_map(|(txn, status)| match status {
TransactionStatus::Keep(_) => Some(txn),
_ => None,
})
.collect()
}
pub fn reconfig_event(&self) -> Vec<ContractEvent> {
if self.is_reconfiguration_suffix() {
return vec![];
}
self.state_compute_result.reconfig_events().to_vec()
}
pub fn is_reconfiguration_suffix(&self) -> bool {
self.state_compute_result.has_reconfiguration()
&& self.state_compute_result.compute_status().is_empty()
}
}