executor_types/
processed_vm_output.rs1#![forbid(unsafe_code)]
9
10use crate::{ExecutedTrees, StateComputeResult};
11use diem_crypto::{hash::EventAccumulatorHasher, HashValue};
12use diem_types::{
13 account_address::AccountAddress,
14 account_state_blob::AccountStateBlob,
15 block_info::PivotBlockDecision,
16 contract_event::ContractEvent,
17 epoch_state::EpochState,
18 proof::accumulator::InMemoryAccumulator,
19 term_state::PosState,
20 transaction::{TransactionStatus, Version},
21};
22use std::{collections::HashMap, sync::Arc};
23
24#[derive(Clone, Debug)]
28pub struct TransactionData {
29 account_blobs: HashMap<AccountAddress, AccountStateBlob>,
35
36 events: Vec<ContractEvent>,
38
39 status: TransactionStatus,
41
42 state_root_hash: HashValue,
44
45 event_tree: Arc<InMemoryAccumulator<EventAccumulatorHasher>>,
48
49 gas_used: u64,
51
52 txn_info_hash: Option<HashValue>,
55}
56
57impl TransactionData {
58 pub fn new(
59 account_blobs: HashMap<AccountAddress, AccountStateBlob>,
60 events: Vec<ContractEvent>, status: TransactionStatus,
61 state_root_hash: HashValue,
62 event_tree: Arc<InMemoryAccumulator<EventAccumulatorHasher>>,
63 gas_used: u64, txn_info_hash: Option<HashValue>,
64 ) -> Self {
65 TransactionData {
66 account_blobs,
67 events,
68 status,
69 state_root_hash,
70 event_tree,
71 gas_used,
72 txn_info_hash,
73 }
74 }
75
76 pub fn account_blobs(&self) -> &HashMap<AccountAddress, AccountStateBlob> {
77 &self.account_blobs
78 }
79
80 pub fn events(&self) -> &[ContractEvent] { &self.events }
81
82 pub fn status(&self) -> &TransactionStatus { &self.status }
83
84 pub fn state_root_hash(&self) -> HashValue { self.state_root_hash }
85
86 pub fn event_root_hash(&self) -> HashValue { self.event_tree.root_hash() }
87
88 pub fn gas_used(&self) -> u64 { self.gas_used }
89
90 pub fn txn_info_hash(&self) -> Option<HashValue> { self.txn_info_hash }
91}
92
93#[derive(Debug, Clone)]
96pub struct ProcessedVMOutput {
97 transaction_data: Vec<TransactionData>,
99
100 executed_trees: ExecutedTrees,
103
104 epoch_state: Option<EpochState>,
107
108 pivot_block: Option<PivotBlockDecision>,
110}
111
112impl ProcessedVMOutput {
113 pub fn new(
114 transaction_data: Vec<TransactionData>, executed_trees: ExecutedTrees,
115 epoch_state: Option<EpochState>,
116 pivot_block: Option<PivotBlockDecision>,
117 ) -> Self {
118 ProcessedVMOutput {
119 transaction_data,
120 executed_trees,
121 epoch_state,
122 pivot_block,
123 }
124 }
125
126 pub fn transaction_data(&self) -> &[TransactionData] {
127 &self.transaction_data
128 }
129
130 pub fn executed_trees(&self) -> &ExecutedTrees { &self.executed_trees }
131
132 pub fn accu_root(&self) -> HashValue { self.executed_trees().state_id() }
133
134 pub fn version(&self) -> Option<Version> { self.executed_trees().version() }
135
136 pub fn epoch_state(&self) -> &Option<EpochState> { &self.epoch_state }
137
138 pub fn pivot_block(&self) -> &Option<PivotBlockDecision> {
139 &self.pivot_block
140 }
141
142 pub fn has_reconfiguration(&self) -> bool { self.epoch_state.is_some() }
143
144 pub fn compute_result(
145 &self, parent_frozen_subtree_roots: Vec<HashValue>,
146 parent_num_leaves: u64,
147 ) -> StateComputeResult {
148 let txn_accu = self.executed_trees().txn_accumulator();
149 StateComputeResult::new(
154 if parent_num_leaves == 0 {
155 self.accu_root()
156 } else {
157 Default::default()
158 },
159 txn_accu.frozen_subtree_roots().clone(),
160 txn_accu.num_leaves(),
161 parent_frozen_subtree_roots,
162 parent_num_leaves,
163 self.epoch_state.clone(),
164 self.transaction_data()
165 .iter()
166 .map(|txn_data| txn_data.status())
167 .cloned()
168 .collect(),
169 self.transaction_data()
170 .iter()
171 .filter_map(|x| x.txn_info_hash())
172 .collect(),
173 self.pivot_block().clone(),
174 )
175 }
176
177 pub fn replace_pos_state(&mut self, new_pos_state: PosState) {
178 self.executed_trees.pos_state = new_pos_state;
179 }
180
181 pub fn set_pos_state_skipped(&mut self) {
182 self.executed_trees.set_pos_state_skipped(true);
183 }
184}