ingest/
reader.rs

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}