1use stellar_xdr::next::{LedgerCloseMeta, TransactionEnvelope, GeneralizedTransactionSet, TransactionPhase, TxSetComponent, TransactionResultMeta, SorobanTransactionMeta, TransactionMeta, ContractEvent};
2
3use crate::{MetaResult, BufReaderError};
4
5#[derive(thiserror::Error, Debug, Clone)]
6pub enum ReaderError {
7 #[error("Error while reading meta result {0}")]
8 MetaResult(BufReaderError)
9
10}
11
12pub struct LedgerCloseMetaReader;
13
14impl LedgerCloseMetaReader {
15
16 pub fn ledegr_sequence(result: &MetaResult) -> Result<u32, ReaderError> {
17 let meta = MetaResultReader::read_meta(result)?;
18
19 match meta {
20 LedgerCloseMeta::V0(v0) => {
21 Ok(v0.ledger_header.header.ledger_seq)
22 }
23 LedgerCloseMeta::V1(v1) => {
24 Ok(v1.ledger_header.header.ledger_seq)
25 }
26
27 }
28 }
29
30 pub fn ledger_hash(result: &MetaResult) -> Result<[u8; 32], ReaderError> {
31 let meta = MetaResultReader::read_meta(result)?;
32
33 match meta {
34 LedgerCloseMeta::V0(v0) => {
35 Ok(v0.ledger_header.hash.0)
36 }
37 LedgerCloseMeta::V1(v1) => {
38 Ok(v1.ledger_header.hash.0)
39 }
40
41 }
42 }
43
44 pub fn previous_ledger_hash(result: &MetaResult) -> Result<[u8; 32], ReaderError> {
45 let meta = MetaResultReader::read_meta(result)?;
46
47 match meta {
48 LedgerCloseMeta::V0(v0) => {
49 Ok(v0.ledger_header.header.previous_ledger_hash.0)
50 }
51 LedgerCloseMeta::V1(v1) => {
52 Ok(v1.ledger_header.header.previous_ledger_hash.0)
53 }
54
55 }
56 }
57
58 pub fn protocol_version(result: &MetaResult) -> Result<u32, ReaderError> {
59 let meta = MetaResultReader::read_meta(result)?;
60
61 match meta {
62 LedgerCloseMeta::V0(v0) => {
63 Ok(v0.ledger_header.header.ledger_version)
64 }
65 LedgerCloseMeta::V1(v1) => {
66 Ok(v1.ledger_header.header.ledger_version)
67 }
68
69 }
70 }
71
72 pub fn bucket_list_hash(result: &MetaResult) -> Result<[u8; 32], ReaderError> {
73 let meta = MetaResultReader::read_meta(result)?;
74
75 match meta {
76 LedgerCloseMeta::V0(v0) => {
77 Ok(v0.ledger_header.header.bucket_list_hash.0)
78 }
79 LedgerCloseMeta::V1(v1) => {
80 Ok(v1.ledger_header.header.bucket_list_hash.0)
81 }
82
83 }
84 }
85
86 pub fn count_transactions(result: &MetaResult) -> Result<usize, ReaderError> {
87 let meta = MetaResultReader::read_meta(result)?;
88
89 match meta {
90 LedgerCloseMeta::V0(v0) => {
91 Ok(v0.tx_processing.len())
92 }
93 LedgerCloseMeta::V1(v1) => {
94 Ok(v1.tx_processing.len())
95 }
96
97 }
98 }
99
100 pub fn transaction_envelopes(result: &MetaResult) -> Result<Vec<TransactionEnvelope>, ReaderError> {
101 let meta = MetaResultReader::read_meta(result)?;
102
103 match meta {
104 LedgerCloseMeta::V0(v0) => Ok(v0.tx_set.txs.to_vec()),
105 LedgerCloseMeta::V1(v1) => {
106 let mut envelopes = Vec::with_capacity(Self::count_transactions(result)?);
107
108 match &v1.tx_set {
109 GeneralizedTransactionSet::V1(v1) => {
110 for phase in v1.phases.iter() {
111 match phase {
112 TransactionPhase::V0(v0) => {
113 for component in v0.iter() {
114 match component {
115 TxSetComponent::TxsetCompTxsMaybeDiscountedFee(txset) => {
116 envelopes.append(&mut txset.txs.to_vec())
117 }
118 }
119 }
120 }
121 }
122 }
123 }
124
125 }
126 Ok(envelopes)
127 }
128
129 }
130 }
131
132 pub fn transaction_metas(result: &MetaResult) -> Result<Vec<TransactionResultMeta>, ReaderError> {
133 let meta = MetaResultReader::read_meta(result)?;
134
135 match meta {
136 LedgerCloseMeta::V0(v0) => Ok(v0.tx_processing.to_vec()),
137 LedgerCloseMeta::V1(v1) => Ok(v1.tx_processing.to_vec()),
138 }
139 }
140
141 pub fn soroban_metas(result: &MetaResult) -> Result<Vec<SorobanTransactionMeta>, ReaderError> {
142 let mut soroban_metas = Vec::new();
143
144 for result_meta in Self::transaction_metas(result)? {
145 match result_meta.tx_apply_processing {
146 TransactionMeta::V0(_) => {
147 ()
148 }
149
150 TransactionMeta::V1(_) => {
151 ()
152 }
153
154 TransactionMeta::V2(_) => {
155 ()
156 }
157
158 TransactionMeta::V3(v3) => {
159 if let Some(soroban_meta) = v3.soroban_meta {
160 soroban_metas.push(soroban_meta)
161 }
162 }
163 }
164 }
165
166 Ok(soroban_metas)
167 }
168
169 pub fn soroban_events(result: &MetaResult) -> Result<Vec<ContractEvent>, ReaderError> {
170 let soroban_metas = Self::soroban_metas(result)?;
171 let mut contract_events = Vec::new();
172 for meta in soroban_metas {
173 contract_events.append(&mut meta.events.to_vec())
174 }
175
176 Ok(contract_events)
177 }
178
179}
180
181pub struct MetaResultReader;
182
183impl MetaResultReader {
184 pub fn read_meta(result: &MetaResult) -> Result<&LedgerCloseMeta, ReaderError> {
185 if let Some(meta) = &result.ledger_close_meta {
186 Ok(&meta.ledger_close_meta)
187 } else {
188 Err(ReaderError::MetaResult(result.err.clone().unwrap()))
189 }
190 }
191}