cfx_parity_trace_types/
trace_types.rsuse super::{action_types::Action, filter::TraceFilter};
use cfx_bytes::Bytes;
use cfx_internal_common::{DatabaseDecodable, DatabaseEncodable};
use cfx_types::{Bloom, Space, H256, U256, U64};
use malloc_size_of_derive::MallocSizeOf;
use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
use rlp_derive::{RlpDecodable, RlpEncodable};
#[derive(Debug, PartialEq, Clone, MallocSizeOf)]
pub struct ExecTrace {
    #[ignore_malloc_size_of = "ignored for performance reason"]
    pub action: Action,
    pub valid: bool,
}
impl ExecTrace {
    pub fn bloom(&self) -> Bloom { self.action.bloom() }
}
impl Encodable for ExecTrace {
    fn rlp_append(&self, s: &mut RlpStream) {
        s.begin_list(2);
        s.append(&self.action);
        s.append(&self.valid);
    }
}
impl Decodable for ExecTrace {
    fn decode(d: &Rlp) -> Result<Self, DecoderError> {
        match d.item_count()? {
            1 => Ok(ExecTrace {
                action: d.val_at(0)?,
                valid: true,
            }),
            2 => Ok(ExecTrace {
                action: d.val_at(0)?,
                valid: d.val_at(1)?,
            }),
            _ => Err(DecoderError::RlpInvalidLength),
        }
    }
}
pub struct LocalizedTrace {
    pub action: Action,
    pub valid: bool,
    pub epoch_hash: H256,
    pub epoch_number: U256,
    pub block_hash: H256,
    pub transaction_position: U64,
    pub transaction_hash: H256,
}
#[derive(Debug, PartialEq, Clone, RlpEncodable, RlpDecodable, MallocSizeOf)]
pub struct TransactionExecTraces(pub Vec<ExecTrace>);
impl From<Vec<ExecTrace>> for TransactionExecTraces {
    fn from(v: Vec<ExecTrace>) -> Self { TransactionExecTraces(v) }
}
impl TransactionExecTraces {
    pub fn bloom(&self) -> Bloom {
        self.0
            .iter()
            .fold(Default::default(), |bloom, trace| bloom | trace.bloom())
    }
    pub fn filter_space(self, space: Space) -> Self {
        Self(
            TraceFilter::space_filter(space)
                .filter_traces(self)
                .unwrap_or(vec![]),
        )
    }
}
impl Into<Vec<ExecTrace>> for TransactionExecTraces {
    fn into(self) -> Vec<ExecTrace> { self.0 }
}
#[derive(
    Debug, PartialEq, Clone, Default, RlpEncodable, RlpDecodable, MallocSizeOf,
)]
pub struct BlockExecTraces(pub Vec<TransactionExecTraces>);
impl From<Vec<TransactionExecTraces>> for BlockExecTraces {
    fn from(v: Vec<TransactionExecTraces>) -> Self { BlockExecTraces(v) }
}
impl BlockExecTraces {
    pub fn bloom(&self) -> Bloom {
        self.0.iter().fold(Default::default(), |bloom, tx_traces| {
            bloom | tx_traces.bloom()
        })
    }
    pub fn filter_space(self, space: Space) -> Self {
        Self(
            self.0
                .into_iter()
                .map(|tx_trace| tx_trace.filter_space(space))
                .collect(),
        )
    }
}
impl Into<Vec<TransactionExecTraces>> for BlockExecTraces {
    fn into(self) -> Vec<TransactionExecTraces> { self.0 }
}
impl DatabaseDecodable for BlockExecTraces {
    fn db_decode(bytes: &[u8]) -> Result<Self, DecoderError> {
        rlp::decode(bytes)
    }
}
impl DatabaseEncodable for BlockExecTraces {
    fn db_encode(&self) -> Bytes { rlp::encode(self) }
}