1use polars_arrow::array::{BinaryArray, StaticArray, UInt64Array, UInt8Array, Utf8Array};
2
3use crate::{
4 ArrowBatch,
6};
7
8use hyperfuel_format::{
9 BlockHeader, Input, InputType, Output, OutputType, Receipt, ReceiptType, Transaction,
10 TransactionStatus, TransactionType,
11};
12
13pub trait FromArrow: Sized {
15 fn from_arrow(batch: &ArrowBatch) -> Vec<Self>;
17}
18
19fn map_binary<'a, T>(i: usize, arr: Option<&'a BinaryArray<i32>>) -> Option<T>
20where
21 T: TryFrom<&'a [u8]>,
22 <T as TryFrom<&'a [u8]>>::Error: std::fmt::Debug,
23{
24 arr.and_then(|arr| arr.get(i).map(|v| v.try_into().unwrap()))
25}
26
27impl FromArrow for BlockHeader {
30 fn from_arrow(batch: &ArrowBatch) -> Vec<Self> {
31 let id = batch.column::<BinaryArray<i32>>("id").ok();
32 let da_height = batch.column::<UInt64Array>("da_height").ok();
33 let transactions_count = batch.column::<UInt64Array>("transactions_count").ok();
34 let consensus_parameters_version = batch
35 .column::<UInt64Array>("consensus_parameters_version")
36 .ok();
37 let state_transition_bytecode_version = batch
38 .column::<UInt64Array>("state_transition_bytecode_version")
39 .ok();
40 let message_receipt_count = batch.column::<UInt64Array>("message_receipt_count").ok();
41 let transactions_root = batch.column::<BinaryArray<i32>>("transactions_root").ok();
42 let message_outbox_root = batch.column::<BinaryArray<i32>>("message_outbox_root").ok();
43 let event_inbox_root = batch.column::<BinaryArray<i32>>("event_inbox_root").ok();
44 let height = batch.column::<UInt64Array>("height").ok();
45 let prev_root = batch.column::<BinaryArray<i32>>("prev_root").ok();
46 let time = batch.column::<UInt64Array>("time").ok();
47 let application_hash = batch.column::<BinaryArray<i32>>("application_hash").ok();
48
49 (0..batch.chunk.len())
50 .map(|idx| Self {
51 id: map_binary(idx, id).unwrap(),
52 da_height: da_height
53 .and_then(|arr| arr.get(idx).map(|v| v.into()))
54 .expect("Construct from_arrow da_height"),
55 transactions_count: transactions_count
56 .and_then(|arr| arr.get(idx).map(|v| v.into()))
57 .expect("Construct from_arrow transactions_count"),
58 consensus_parameters_version: consensus_parameters_version
59 .and_then(|arr| arr.get(idx).map(|v| v.into()))
60 .expect("Construct from_arrow da_height"),
61 state_transition_bytecode_version: state_transition_bytecode_version
62 .and_then(|arr| arr.get(idx).map(|v| v.into()))
63 .expect("Construct from_arrow state_transition_bytecode_version"),
64 message_receipt_count: message_receipt_count
65 .and_then(|arr| arr.get(idx).map(|v| v.into()))
66 .expect("Construct from_arrow message_receipt_count"),
67 transactions_root: map_binary(idx, transactions_root)
68 .expect("Construct from_arrow transactions_root"),
69 message_outbox_root: map_binary(idx, message_outbox_root)
70 .expect("Construct from_arrow message_outbox_root"),
71 event_inbox_root: map_binary(idx, event_inbox_root)
72 .expect("Construct from_arrow event_inbox_root"),
73 height: height
74 .and_then(|arr| arr.get(idx).map(|v| v.into()))
75 .expect("Construct from_arrow height"),
76 prev_root: map_binary(idx, prev_root).expect("Construct from_arrow prev_root"),
77 time: time
78 .and_then(|arr| arr.get(idx).map(|v| v.into()))
79 .expect("Construct from_arrow time"),
80 application_hash: map_binary(idx, application_hash)
81 .expect("Construct from_arrow application_hash"),
82 })
83 .collect()
84 }
85}
86
87impl FromArrow for Transaction {
88 fn from_arrow(batch: &ArrowBatch) -> Vec<Self> {
89 let block_height = batch.column::<UInt64Array>("block_height").ok();
90 let id = batch.column::<BinaryArray<i32>>("id").ok();
91 let input_asset_ids = batch.column::<BinaryArray<i32>>("input_asset_ids").ok();
92 let input_contracts = batch.column::<BinaryArray<i32>>("input_contracts").ok();
93 let input_contract_utxo_id = batch
94 .column::<BinaryArray<i32>>("input_contract_utxo_id")
95 .ok();
96 let input_contract_balance_root = batch
97 .column::<BinaryArray<i32>>("input_contract_balance_root")
98 .ok();
99 let input_contract_state_root = batch
100 .column::<BinaryArray<i32>>("input_contract_state_root")
101 .ok();
102 let input_contract_tx_pointer_block_height = batch
103 .column::<UInt64Array>("input_contract_tx_pointer_block_height")
104 .ok();
105 let input_contract_tx_pointer_tx_index = batch
106 .column::<UInt64Array>("input_contract_tx_pointer_tx_index")
107 .ok();
108 let input_contract = batch.column::<BinaryArray<i32>>("input_contract").ok();
109 let policies_tip = batch.column::<UInt64Array>("policies_tip").ok();
110 let policies_witness_limit = batch.column::<UInt64Array>("policies_witness_limit").ok();
111 let policies_maturity = batch.column::<UInt64Array>("policies_maturity").ok();
112 let policies_max_fee = batch.column::<UInt64Array>("policies_max_fee").ok();
113 let script_gas_limit = batch.column::<UInt64Array>("script_gas_limit").ok();
114 let maturity = batch.column::<UInt64Array>("maturity").ok();
115 let mint_amount = batch.column::<UInt64Array>("mint_amount").ok();
116 let mint_asset_id = batch.column::<BinaryArray<i32>>("mint_asset_id").ok();
117 let mint_gas_price = batch.column::<UInt64Array>("mint_gas_price").ok();
118 let tx_pointer_block_height = batch.column::<UInt64Array>("tx_pointer_block_height").ok();
119 let tx_pointer_tx_index = batch.column::<UInt64Array>("tx_pointer_tx_index").ok();
120 let tx_type = batch.column::<UInt8Array>("tx_type").ok();
121 let output_contract_input_index = batch
122 .column::<UInt64Array>("output_contract_input_index")
123 .ok();
124 let output_contract_balance_root = batch
125 .column::<BinaryArray<i32>>("output_contract_balance_root")
126 .ok();
127 let output_contract_state_root = batch
128 .column::<BinaryArray<i32>>("output_contract_state_root")
129 .ok();
130 let witnesses = batch.column::<BinaryArray<i32>>("witnesses").ok();
131 let receipts_root = batch.column::<BinaryArray<i32>>("receipts_root").ok();
132 let status = batch.column::<UInt8Array>("status").ok();
133 let time = batch.column::<UInt64Array>("time").ok();
134 let reason = batch.column::<Utf8Array<i32>>("reason").ok();
135 let script = batch.column::<BinaryArray<i32>>("script").ok();
136 let script_data = batch.column::<BinaryArray<i32>>("script_data").ok();
137 let bytecode_witness_index = batch.column::<UInt64Array>("bytecode_witness_index").ok();
138 let bytecode_root = batch.column::<BinaryArray<i32>>("bytecode_root").ok();
139 let subsection_index = batch.column::<UInt64Array>("subsection_index").ok();
140 let subsections_number = batch.column::<UInt64Array>("subsections_number").ok();
141 let proof_set = batch.column::<BinaryArray<i32>>("proof_set").ok();
142 let consensus_parameters_upgrade_purpose_witness_index = batch
143 .column::<UInt64Array>("consensus_parameters_upgrade_purpose_witness_index")
144 .ok();
145 let consensus_parameters_upgrade_purpose_checksum = batch
146 .column::<BinaryArray<i32>>("consensus_parameters_upgrade_purpose_checksum")
147 .ok();
148 let state_transition_upgrade_purpose_root = batch
149 .column::<BinaryArray<i32>>("state_transition_upgrade_purpose_root")
150 .ok();
151 let salt = batch.column::<BinaryArray<i32>>("salt").ok();
152
153 (0..batch.chunk.len())
154 .map(|idx| Self {
155 block_height: block_height
156 .and_then(|arr| arr.get(idx).map(|v| v.into()))
157 .expect("Construct from_arrow block_height"),
158 id: map_binary(idx, id).unwrap(),
159 input_asset_ids: input_asset_ids
160 .and_then(|arr| arr.get(idx).map(|v| bincode::deserialize(v).unwrap())),
161 input_contracts: input_contracts
162 .and_then(|arr| arr.get(idx).map(|v| bincode::deserialize(v).unwrap())),
163 input_contract_utxo_id: map_binary(idx, input_contract_utxo_id),
164 input_contract_balance_root: map_binary(idx, input_contract_balance_root),
165 input_contract_state_root: map_binary(idx, input_contract_state_root),
166 input_contract_tx_pointer_block_height: input_contract_tx_pointer_block_height
167 .and_then(|arr| arr.get(idx).map(|v| v.into())),
168 input_contract_tx_pointer_tx_index: input_contract_tx_pointer_tx_index
169 .and_then(|arr| arr.get(idx).map(|v| v.into())),
170 input_contract: map_binary(idx, input_contract),
171 policies_tip: policies_tip.and_then(|arr| arr.get(idx).map(|v| v.into())),
172 policies_witness_limit: policies_witness_limit
173 .and_then(|arr| arr.get(idx).map(|v| v.into())),
174 policies_maturity: policies_maturity.and_then(|arr| arr.get(idx).map(|v| v.into())),
175 policies_max_fee: policies_max_fee.and_then(|arr| arr.get(idx).map(|v| v.into())),
176 script_gas_limit: script_gas_limit.and_then(|arr| arr.get(idx).map(|v| v.into())),
177 maturity: maturity.and_then(|arr| arr.get(idx).map(|v| v.into())),
178 mint_amount: mint_amount.and_then(|arr| arr.get(idx).map(|v| v.into())),
179 mint_asset_id: map_binary(idx, mint_asset_id),
180 mint_gas_price: mint_gas_price.and_then(|arr| arr.get(idx).map(|v| v.into())),
181 tx_pointer_block_height: tx_pointer_block_height
182 .and_then(|arr| arr.get(idx).map(|v| v.into())),
183 tx_pointer_tx_index: tx_pointer_tx_index
184 .and_then(|arr| arr.get(idx).map(|v| v.into())),
185 tx_type: tx_type
186 .and_then(|arr| arr.get(idx).map(TransactionType::from))
187 .expect("Construct from_arrow tx_type"),
188 output_contract_input_index: output_contract_input_index
189 .and_then(|arr| arr.get(idx).map(|v| v.into())),
190 output_contract_balance_root: map_binary(idx, output_contract_balance_root),
191 output_contract_state_root: map_binary(idx, output_contract_state_root),
192 witnesses: map_binary(idx, witnesses),
193 receipts_root: map_binary(idx, receipts_root),
194 status: status
195 .and_then(|arr| arr.get(idx).map(|v| TransactionStatus::from_u8(v).unwrap()))
196 .expect("Construct from_arrow status"),
197 time: time
198 .and_then(|arr| arr.get(idx).map(|v| v.into()))
199 .expect("Construct from_arrow time"),
200 reason: reason.and_then(|arr| arr.get(idx).map(|v| v.to_owned())),
201 script: map_binary(idx, script),
202 script_data: map_binary(idx, script_data),
203 bytecode_witness_index: bytecode_witness_index
204 .and_then(|arr| arr.get(idx).map(|v| v.into())),
205 bytecode_root: map_binary(idx, bytecode_root),
206 subsection_index: subsection_index.and_then(|arr| arr.get(idx).map(|v| v.into())),
207 subsections_number: subsections_number
208 .and_then(|arr| arr.get(idx).map(|v| v.into())),
209 proof_set: map_binary(idx, proof_set),
210 consensus_parameters_upgrade_purpose_witness_index:
211 consensus_parameters_upgrade_purpose_witness_index
212 .and_then(|arr| arr.get(idx).map(|v| v.into())),
213 consensus_parameters_upgrade_purpose_checksum: map_binary(
214 idx,
215 consensus_parameters_upgrade_purpose_checksum,
216 ),
217 state_transition_upgrade_purpose_root: map_binary(
218 idx,
219 state_transition_upgrade_purpose_root,
220 ),
221 salt: map_binary(idx, salt),
222 })
223 .collect()
224 }
225}
226
227impl FromArrow for Receipt {
228 fn from_arrow(batch: &ArrowBatch) -> Vec<Self> {
229 let receipt_index = batch.column::<UInt64Array>("receipt_index").ok();
230 let root_contract_id = batch.column::<BinaryArray<i32>>("root_contract_id").ok();
231 let tx_id = batch.column::<BinaryArray<i32>>("tx_id").ok();
232 let tx_status = batch.column::<UInt8Array>("tx_status").ok();
233 let tx_type = batch.column::<UInt8Array>("tx_type").ok();
234 let block_height = batch.column::<UInt64Array>("block_height").ok();
235 let pc = batch.column::<UInt64Array>("pc").ok();
236 let is = batch.column::<UInt64Array>("is").ok();
237 let to = batch.column::<BinaryArray<i32>>("to").ok();
238 let to_address = batch.column::<BinaryArray<i32>>("to_address").ok();
239 let amount = batch.column::<UInt64Array>("amount").ok();
240 let asset_id = batch.column::<BinaryArray<i32>>("asset_id").ok();
241 let gas = batch.column::<UInt64Array>("gas").ok();
242 let param1 = batch.column::<UInt64Array>("param1").ok();
243 let param2 = batch.column::<UInt64Array>("param2").ok();
244 let val = batch.column::<UInt64Array>("val").ok();
245 let ptr = batch.column::<UInt64Array>("ptr").ok();
246 let digest = batch.column::<BinaryArray<i32>>("digest").ok();
247 let reason = batch.column::<UInt64Array>("reason").ok();
248 let ra = batch.column::<UInt64Array>("ra").ok();
249 let rb = batch.column::<UInt64Array>("rb").ok();
250 let rc = batch.column::<UInt64Array>("rc").ok();
251 let rd = batch.column::<UInt64Array>("rd").ok();
252 let len = batch.column::<UInt64Array>("len").ok();
253 let receipt_type = batch.column::<UInt8Array>("receipt_type").ok();
254 let result = batch.column::<UInt64Array>("result").ok();
255 let gas_used = batch.column::<UInt64Array>("gas_used").ok();
256 let data = batch.column::<BinaryArray<i32>>("data").ok();
257 let sender = batch.column::<BinaryArray<i32>>("sender").ok();
258 let recipient = batch.column::<BinaryArray<i32>>("recipient").ok();
259 let nonce = batch.column::<UInt64Array>("nonce").ok();
260 let contract_id = batch.column::<BinaryArray<i32>>("contract_id").ok();
261 let sub_id = batch.column::<BinaryArray<i32>>("sub_id").ok();
262
263 (0..batch.chunk.len())
264 .map(|idx| Self {
265 receipt_index: receipt_index
266 .and_then(|arr| arr.get(idx).map(|v| v.into()))
267 .expect("Construct from_arrow receipt_index"),
268 root_contract_id: map_binary(idx, root_contract_id),
269 tx_id: map_binary(idx, tx_id).expect("Construct from_arrow tx_id"),
270 tx_status: tx_status
271 .and_then(|arr| arr.get(idx).map(|v| TransactionStatus::from_u8(v).unwrap()))
272 .expect("Construct from_arrow tx_status"),
273 tx_type: tx_type
274 .and_then(|arr| arr.get(idx).map(TransactionType))
275 .expect("Construct from_arrow tx_type"),
276 block_height: block_height
277 .and_then(|arr| arr.get(idx).map(|v| v.into()))
278 .expect("Construct from_arrow block_height"),
279 pc: pc.and_then(|arr| arr.get(idx).map(|v| v.into())),
280 is: is.and_then(|arr| arr.get(idx).map(|v| v.into())),
281 to: map_binary(idx, to),
282 to_address: map_binary(idx, to_address),
283 amount: amount.and_then(|arr| arr.get(idx).map(|v| v.into())),
284 asset_id: map_binary(idx, asset_id),
285 gas: gas.and_then(|arr| arr.get(idx).map(|v| v.into())),
286 param1: param1.and_then(|arr| arr.get(idx).map(|v| v.into())),
287 param2: param2.and_then(|arr| arr.get(idx).map(|v| v.into())),
288 val: val.and_then(|arr| arr.get(idx).map(|v| v.into())),
289 ptr: ptr.and_then(|arr| arr.get(idx).map(|v| v.into())),
290 digest: map_binary(idx, digest),
291 reason: reason.and_then(|arr| arr.get(idx).map(|v| v.into())),
292 ra: ra.and_then(|arr| arr.get(idx).map(|v| v.into())),
293 rb: rb.and_then(|arr| arr.get(idx).map(|v| v.into())),
294 rc: rc.and_then(|arr| arr.get(idx).map(|v| v.into())),
295 rd: rd.and_then(|arr| arr.get(idx).map(|v| v.into())),
296 len: len.and_then(|arr| arr.get(idx).map(|v| v.into())),
297 receipt_type: receipt_type
298 .and_then(|arr| arr.get(idx).map(|v| ReceiptType::from_u8(v).unwrap()))
299 .expect("Construct from_arrow receipt_type"),
300 result: result.and_then(|arr| arr.get(idx).map(|v| v.into())),
301 gas_used: gas_used.and_then(|arr| arr.get(idx).map(|v| v.into())),
302 data: map_binary(idx, data),
303 sender: map_binary(idx, sender),
304 recipient: map_binary(idx, recipient),
305 nonce: nonce.and_then(|arr| arr.get(idx).map(|v| v.into())),
306 contract_id: map_binary(idx, contract_id),
307 sub_id: map_binary(idx, sub_id),
308 })
309 .collect()
310 }
311}
312
313impl FromArrow for Input {
314 fn from_arrow(batch: &ArrowBatch) -> Vec<Self> {
315 let tx_id = batch.column::<BinaryArray<i32>>("tx_id").ok();
316 let tx_status = batch.column::<UInt8Array>("tx_status").ok();
317 let tx_type = batch.column::<UInt8Array>("tx_type").ok();
318 let block_height = batch.column::<UInt64Array>("block_height").ok();
319 let input_type = batch.column::<UInt8Array>("input_type").ok();
320 let utxo_id = batch.column::<BinaryArray<i32>>("utxo_id").ok();
321 let owner = batch.column::<BinaryArray<i32>>("owner").ok();
322 let amount = batch.column::<UInt64Array>("amount").ok();
323 let asset_id = batch.column::<BinaryArray<i32>>("asset_id").ok();
324 let tx_pointer_block_height = batch.column::<UInt64Array>("tx_pointer_block_height").ok();
325 let tx_pointer_tx_index = batch.column::<UInt64Array>("tx_pointer_tx_index").ok();
326 let witness_index = batch.column::<UInt64Array>("witness_index").ok();
327 let predicate_gas_used = batch.column::<UInt64Array>("predicate_gas_used").ok();
328 let predicate = batch.column::<BinaryArray<i32>>("predicate").ok();
329 let predicate_data = batch.column::<BinaryArray<i32>>("predicate_data").ok();
330 let balance_root = batch.column::<BinaryArray<i32>>("balance_root").ok();
331 let state_root = batch.column::<BinaryArray<i32>>("state_root").ok();
332 let contract = batch.column::<BinaryArray<i32>>("contract").ok();
333 let sender = batch.column::<BinaryArray<i32>>("sender").ok();
334 let recipient = batch.column::<BinaryArray<i32>>("recipient").ok();
335 let nonce = batch.column::<BinaryArray<i32>>("nonce").ok();
336 let data = batch.column::<BinaryArray<i32>>("data").ok();
337
338 (0..batch.chunk.len())
339 .map(|idx| Self {
340 tx_id: map_binary(idx, tx_id).unwrap(),
341 tx_status: tx_status
342 .and_then(|arr| arr.get(idx).map(|v| TransactionStatus::from_u8(v).unwrap()))
343 .expect("Construct from_arrow tx_status"),
344 tx_type: tx_type
345 .and_then(|arr| arr.get(idx).map(TransactionType))
346 .expect("Construct from_arrow tx_type"),
347 block_height: block_height
348 .and_then(|arr| arr.get(idx).map(|v| v.into()))
349 .expect("Construct from_arrow block_height"),
350 input_type: input_type
351 .and_then(|arr| arr.get(idx).map(|v| InputType::from_u8(v).unwrap()))
352 .expect("Construct from_arrow input_type"),
353 utxo_id: map_binary(idx, utxo_id),
354 owner: map_binary(idx, owner),
355 amount: amount.and_then(|arr| arr.get(idx).map(|v| v.into())),
356 asset_id: map_binary(idx, asset_id),
357 tx_pointer_block_height: tx_pointer_block_height
358 .and_then(|arr| arr.get(idx).map(|v| v.into())),
359 tx_pointer_tx_index: tx_pointer_tx_index
360 .and_then(|arr| arr.get(idx).map(|v| v.into())),
361 witness_index: witness_index.and_then(|arr| arr.get(idx).map(|v| v.into())),
362 predicate_gas_used: predicate_gas_used
363 .and_then(|arr| arr.get(idx).map(|v| v.into())),
364 predicate: map_binary(idx, predicate),
365 predicate_data: map_binary(idx, predicate_data),
366 balance_root: map_binary(idx, balance_root),
367 state_root: map_binary(idx, state_root),
368 contract: map_binary(idx, contract),
369 sender: map_binary(idx, sender),
370 recipient: map_binary(idx, recipient),
371 nonce: map_binary(idx, nonce),
372 data: map_binary(idx, data),
373 })
374 .collect()
375 }
376}
377
378impl FromArrow for Output {
379 fn from_arrow(batch: &ArrowBatch) -> Vec<Self> {
380 let tx_id = batch.column::<BinaryArray<i32>>("tx_id").ok();
381 let tx_status = batch.column::<UInt8Array>("tx_status").ok();
382 let tx_type = batch.column::<UInt8Array>("tx_type").ok();
383 let block_height = batch.column::<UInt64Array>("block_height").ok();
384 let output_type = batch.column::<UInt8Array>("output_type").ok();
385 let to = batch.column::<BinaryArray<i32>>("to").ok();
386 let amount = batch.column::<UInt64Array>("amount").ok();
387 let asset_id = batch.column::<BinaryArray<i32>>("asset_id").ok();
388 let input_index = batch.column::<UInt64Array>("input_index").ok();
389 let balance_root = batch.column::<BinaryArray<i32>>("balance_root").ok();
390 let state_root = batch.column::<BinaryArray<i32>>("state_root").ok();
391 let contract = batch.column::<BinaryArray<i32>>("contract").ok();
392
393 (0..batch.chunk.len())
394 .map(|idx| Self {
395 tx_id: map_binary(idx, tx_id).unwrap(),
396 tx_status: tx_status
397 .and_then(|arr| arr.get(idx).map(|v| TransactionStatus::from_u8(v).unwrap()))
398 .expect("Construct from_arrow tx_status"),
399 tx_type: tx_type
400 .and_then(|arr| arr.get(idx).map(TransactionType))
401 .expect("Construct from_arrow tx_type"),
402 block_height: block_height
403 .and_then(|arr| arr.get(idx).map(|v| v.into()))
404 .expect("Construct from_arrow block_height"),
405 output_type: output_type
406 .and_then(|arr| arr.get(idx).map(|v| OutputType::from_u8(v).unwrap()))
407 .expect("Construct from_arrow output_type"),
408 to: map_binary(idx, to),
409 amount: amount.and_then(|arr| arr.get(idx).map(|v| v.into())),
410 asset_id: map_binary(idx, asset_id),
411 input_index: input_index.and_then(|arr| arr.get(idx).map(|v| v.into())),
412 balance_root: map_binary(idx, balance_root),
413 state_root: map_binary(idx, state_root),
414 contract: map_binary(idx, contract),
415 })
416 .collect()
417 }
418}