executor_types/
processed_vm_output.rs1#![forbid(unsafe_code)]
9
10use crate::{ExecutedTrees, StateComputeResult};
11use diem_crypto::{hash::EventAccumulatorHasher, HashValue};
12use diem_types::{
13 block_info::PivotBlockDecision,
14 contract_event::ContractEvent,
15 epoch_state::EpochState,
16 proof::accumulator::InMemoryAccumulator,
17 term_state::PosState,
18 transaction::{TransactionStatus, Version},
19};
20use std::sync::Arc;
21
22#[derive(Clone, Debug)]
26pub struct TransactionData {
27 events: Vec<ContractEvent>,
29
30 status: TransactionStatus,
32
33 event_tree: Arc<InMemoryAccumulator<EventAccumulatorHasher>>,
36
37 gas_used: u64,
39
40 txn_info_hash: Option<HashValue>,
43}
44
45impl TransactionData {
46 pub fn new(
47 events: Vec<ContractEvent>, status: TransactionStatus,
48 event_tree: Arc<InMemoryAccumulator<EventAccumulatorHasher>>,
49 gas_used: u64, txn_info_hash: Option<HashValue>,
50 ) -> Self {
51 TransactionData {
52 events,
53 status,
54 event_tree,
55 gas_used,
56 txn_info_hash,
57 }
58 }
59
60 pub fn events(&self) -> &[ContractEvent] { &self.events }
61
62 pub fn status(&self) -> &TransactionStatus { &self.status }
63
64 pub fn event_root_hash(&self) -> HashValue { self.event_tree.root_hash() }
65
66 pub fn gas_used(&self) -> u64 { self.gas_used }
67
68 pub fn txn_info_hash(&self) -> Option<HashValue> { self.txn_info_hash }
69}
70
71#[derive(Debug, Clone)]
74pub struct ProcessedVMOutput {
75 transaction_data: Vec<TransactionData>,
77
78 executed_trees: ExecutedTrees,
81
82 epoch_state: Option<EpochState>,
85
86 pivot_block: Option<PivotBlockDecision>,
88}
89
90impl ProcessedVMOutput {
91 pub fn new(
92 transaction_data: Vec<TransactionData>, executed_trees: ExecutedTrees,
93 epoch_state: Option<EpochState>,
94 pivot_block: Option<PivotBlockDecision>,
95 ) -> Self {
96 ProcessedVMOutput {
97 transaction_data,
98 executed_trees,
99 epoch_state,
100 pivot_block,
101 }
102 }
103
104 pub fn transaction_data(&self) -> &[TransactionData] {
105 &self.transaction_data
106 }
107
108 pub fn executed_trees(&self) -> &ExecutedTrees { &self.executed_trees }
109
110 pub fn accu_root(&self) -> HashValue { self.executed_trees().state_id() }
111
112 pub fn version(&self) -> Option<Version> { self.executed_trees().version() }
113
114 pub fn epoch_state(&self) -> &Option<EpochState> { &self.epoch_state }
115
116 pub fn pivot_block(&self) -> &Option<PivotBlockDecision> {
117 &self.pivot_block
118 }
119
120 pub fn has_reconfiguration(&self) -> bool { self.epoch_state.is_some() }
121
122 pub fn compute_result(
123 &self, parent_frozen_subtree_roots: Vec<HashValue>,
124 parent_num_leaves: u64,
125 ) -> StateComputeResult {
126 let txn_accu = self.executed_trees().txn_accumulator();
127 StateComputeResult::new(
132 if parent_num_leaves == 0 {
133 self.accu_root()
134 } else {
135 Default::default()
136 },
137 txn_accu.frozen_subtree_roots().clone(),
138 txn_accu.num_leaves(),
139 parent_frozen_subtree_roots,
140 parent_num_leaves,
141 self.epoch_state.clone(),
142 self.transaction_data()
143 .iter()
144 .map(|txn_data| txn_data.status())
145 .cloned()
146 .collect(),
147 self.transaction_data()
148 .iter()
149 .filter_map(|x| x.txn_info_hash())
150 .collect(),
151 self.pivot_block().clone(),
152 )
153 }
154
155 pub fn replace_pos_state(&mut self, new_pos_state: PosState) {
156 self.executed_trees.pos_state = new_pos_state;
157 }
158
159 pub fn set_pos_state_skipped(&mut self) {
160 self.executed_trees.set_pos_state_skipped(true);
161 }
162}