1use std::sync::Arc;
2
3use arrow::array::builder;
4use arrow::datatypes::{DataType, Field, Fields, Schema};
5use arrow::record_batch::RecordBatch;
6
7pub fn blocks_schema() -> Schema {
8 Schema::new(vec![
9 Field::new("slot", DataType::UInt64, true),
10 Field::new("hash", DataType::Binary, true),
11 Field::new("parent_slot", DataType::UInt64, true),
12 Field::new("parent_hash", DataType::Binary, true),
13 Field::new("height", DataType::UInt64, true),
14 Field::new("timestamp", DataType::Int64, true),
15 ])
16}
17
18pub fn rewards_schema() -> Schema {
19 Schema::new(vec![
20 Field::new("block_slot", DataType::UInt64, true),
21 Field::new("block_hash", DataType::Binary, true),
22 Field::new("pubkey", DataType::Binary, true),
23 Field::new("lamports", DataType::Int64, true),
24 Field::new("post_balance", DataType::UInt64, true),
25 Field::new("reward_type", DataType::Utf8, true),
26 Field::new("commission", DataType::UInt8, true),
27 ])
28}
29
30pub fn token_balances_schema() -> Schema {
31 Schema::new(vec![
32 Field::new("block_slot", DataType::UInt64, true),
33 Field::new("block_hash", DataType::Binary, true),
34 Field::new("transaction_index", DataType::UInt32, true),
35 Field::new("account", DataType::Binary, true),
36 Field::new("pre_mint", DataType::Binary, true),
37 Field::new("post_mint", DataType::Binary, true),
38 Field::new("pre_decimals", DataType::UInt16, true),
39 Field::new("post_decimals", DataType::UInt16, true),
40 Field::new("pre_program_id", DataType::Binary, true),
41 Field::new("post_program_id", DataType::Binary, true),
42 Field::new("pre_owner", DataType::Binary, true),
43 Field::new("post_owner", DataType::Binary, true),
44 Field::new("pre_amount", DataType::UInt64, true),
45 Field::new("post_amount", DataType::UInt64, true),
46 ])
47}
48
49pub fn balances_schema() -> Schema {
50 Schema::new(vec![
51 Field::new("block_slot", DataType::UInt64, true),
52 Field::new("block_hash", DataType::Binary, true),
53 Field::new("transaction_index", DataType::UInt32, true),
54 Field::new("account", DataType::Binary, true),
55 Field::new("pre", DataType::UInt64, true),
56 Field::new("post", DataType::UInt64, true),
57 ])
58}
59
60pub fn logs_schema() -> Schema {
61 Schema::new(vec![
62 Field::new("block_slot", DataType::UInt64, true),
63 Field::new("block_hash", DataType::Binary, true),
64 Field::new("transaction_index", DataType::UInt32, true),
65 Field::new("log_index", DataType::UInt32, true),
66 Field::new(
67 "instruction_address",
68 DataType::List(Arc::new(Field::new("item", DataType::UInt32, true))),
69 true,
70 ),
71 Field::new("program_id", DataType::Binary, true),
72 Field::new("kind", DataType::Utf8, true),
73 Field::new("message", DataType::Utf8, true),
74 ])
75}
76
77pub fn transactions_schema() -> Schema {
78 Schema::new(vec![
79 Field::new("block_slot", DataType::UInt64, true),
80 Field::new("block_hash", DataType::Binary, true),
81 Field::new("transaction_index", DataType::UInt32, true),
82 Field::new("signature", DataType::Binary, true),
83 Field::new("version", DataType::Int8, true),
84 Field::new(
85 "account_keys",
86 DataType::List(Arc::new(Field::new("item", DataType::Binary, true))),
87 true,
88 ),
89 Field::new(
90 "address_table_lookups",
91 DataType::List(Arc::new(Field::new(
92 "item",
93 address_table_lookup_dt(),
94 true,
95 ))),
96 true,
97 ),
98 Field::new("num_readonly_signed_accounts", DataType::UInt32, true),
99 Field::new("num_readonly_unsigned_accounts", DataType::UInt32, true),
100 Field::new("num_required_signatures", DataType::UInt32, true),
101 Field::new("recent_blockhash", DataType::Binary, true),
102 Field::new(
103 "signatures",
104 DataType::List(Arc::new(Field::new("item", DataType::Binary, true))),
105 true,
106 ),
107 Field::new("err", DataType::Utf8, true),
109 Field::new("fee", DataType::UInt64, true),
110 Field::new("compute_units_consumed", DataType::UInt64, true),
111 Field::new(
112 "loaded_readonly_addresses",
113 DataType::List(Arc::new(Field::new("item", DataType::Binary, true))),
114 true,
115 ),
116 Field::new(
117 "loaded_writable_addresses",
118 DataType::List(Arc::new(Field::new("item", DataType::Binary, true))),
119 true,
120 ),
121 Field::new("fee_payer", DataType::Binary, true),
122 Field::new("has_dropped_log_messages", DataType::Boolean, true),
123 ])
124}
125
126fn address_table_lookup_dt() -> DataType {
127 DataType::Struct(Fields::from(vec![
128 Arc::new(Field::new("account_key", DataType::Binary, true)),
129 Arc::new(Field::new(
130 "writable_indexes",
131 DataType::List(Arc::new(Field::new("item", DataType::UInt64, true))),
132 true,
133 )),
134 Arc::new(Field::new(
135 "readonly_indexes",
136 DataType::List(Arc::new(Field::new("item", DataType::UInt64, true))),
137 true,
138 )),
139 ]))
140}
141
142pub fn instructions_schema() -> Schema {
143 Schema::new(vec![
144 Field::new("block_slot", DataType::UInt64, true),
145 Field::new("block_hash", DataType::Binary, true),
146 Field::new("transaction_index", DataType::UInt32, true),
147 Field::new(
148 "instruction_address",
149 DataType::List(Arc::new(Field::new("item", DataType::UInt32, true))),
150 true,
151 ),
152 Field::new("program_id", DataType::Binary, true),
153 Field::new("a0", DataType::Binary, true),
154 Field::new("a1", DataType::Binary, true),
155 Field::new("a2", DataType::Binary, true),
156 Field::new("a3", DataType::Binary, true),
157 Field::new("a4", DataType::Binary, true),
158 Field::new("a5", DataType::Binary, true),
159 Field::new("a6", DataType::Binary, true),
160 Field::new("a7", DataType::Binary, true),
161 Field::new("a8", DataType::Binary, true),
162 Field::new("a9", DataType::Binary, true),
163 Field::new(
165 "rest_of_accounts",
166 DataType::List(Arc::new(Field::new("item", DataType::Binary, true))),
167 true,
168 ),
169 Field::new("data", DataType::Binary, true),
170 Field::new("d1", DataType::Binary, true),
171 Field::new("d2", DataType::Binary, true),
172 Field::new("d4", DataType::Binary, true),
173 Field::new("d8", DataType::Binary, true),
174 Field::new("error", DataType::Utf8, true),
175 Field::new("compute_units_consumed", DataType::UInt64, true),
176 Field::new("is_committed", DataType::Boolean, true),
177 Field::new("has_dropped_log_messages", DataType::Boolean, true),
178 ])
179}
180
181#[derive(Default)]
182pub struct BlocksBuilder {
183 pub slot: builder::UInt64Builder,
184 pub hash: builder::BinaryBuilder,
185 pub parent_slot: builder::UInt64Builder,
186 pub parent_hash: builder::BinaryBuilder,
187 pub height: builder::UInt64Builder,
188 pub timestamp: builder::Int64Builder,
189}
190
191impl BlocksBuilder {
192 pub fn finish(mut self) -> RecordBatch {
193 RecordBatch::try_new(
194 Arc::new(blocks_schema()),
195 vec![
196 Arc::new(self.slot.finish()),
197 Arc::new(self.hash.finish()),
198 Arc::new(self.parent_slot.finish()),
199 Arc::new(self.parent_hash.finish()),
200 Arc::new(self.height.finish()),
201 Arc::new(self.timestamp.finish()),
202 ],
203 )
204 .unwrap()
205 }
206}
207
208#[derive(Default)]
209pub struct RewardsBuilder {
210 pub block_slot: builder::UInt64Builder,
211 pub block_hash: builder::BinaryBuilder,
212 pub pubkey: builder::BinaryBuilder,
213 pub lamports: builder::Int64Builder,
214 pub post_balance: builder::UInt64Builder,
215 pub reward_type: builder::StringBuilder,
216 pub commission: builder::UInt8Builder,
217}
218
219impl RewardsBuilder {
220 pub fn finish(mut self) -> RecordBatch {
221 RecordBatch::try_new(
222 Arc::new(rewards_schema()),
223 vec![
224 Arc::new(self.block_slot.finish()),
225 Arc::new(self.block_hash.finish()),
226 Arc::new(self.pubkey.finish()),
227 Arc::new(self.lamports.finish()),
228 Arc::new(self.post_balance.finish()),
229 Arc::new(self.reward_type.finish()),
230 Arc::new(self.commission.finish()),
231 ],
232 )
233 .unwrap()
234 }
235}
236
237#[derive(Default)]
238pub struct TokenBalancesBuilder {
239 pub block_slot: builder::UInt64Builder,
240 pub block_hash: builder::BinaryBuilder,
241 pub transaction_index: builder::UInt32Builder,
242 pub account: builder::BinaryBuilder,
243 pub pre_mint: builder::BinaryBuilder,
244 pub post_mint: builder::BinaryBuilder,
245 pub pre_decimals: builder::UInt16Builder,
246 pub post_decimals: builder::UInt16Builder,
247 pub pre_program_id: builder::BinaryBuilder,
248 pub post_program_id: builder::BinaryBuilder,
249 pub pre_owner: builder::BinaryBuilder,
250 pub post_owner: builder::BinaryBuilder,
251 pub pre_amount: builder::UInt64Builder,
252 pub post_amount: builder::UInt64Builder,
253}
254
255impl TokenBalancesBuilder {
256 pub fn finish(mut self) -> RecordBatch {
257 RecordBatch::try_new(
258 Arc::new(token_balances_schema()),
259 vec![
260 Arc::new(self.block_slot.finish()),
261 Arc::new(self.block_hash.finish()),
262 Arc::new(self.transaction_index.finish()),
263 Arc::new(self.account.finish()),
264 Arc::new(self.pre_mint.finish()),
265 Arc::new(self.post_mint.finish()),
266 Arc::new(self.pre_decimals.finish()),
267 Arc::new(self.post_decimals.finish()),
268 Arc::new(self.pre_program_id.finish()),
269 Arc::new(self.post_program_id.finish()),
270 Arc::new(self.pre_owner.finish()),
271 Arc::new(self.post_owner.finish()),
272 Arc::new(self.pre_amount.finish()),
273 Arc::new(self.post_amount.finish()),
274 ],
275 )
276 .unwrap()
277 }
278}
279
280#[derive(Default)]
281pub struct BalancesBuilder {
282 pub block_slot: builder::UInt64Builder,
283 pub block_hash: builder::BinaryBuilder,
284 pub transaction_index: builder::UInt32Builder,
285 pub account: builder::BinaryBuilder,
286 pub pre: builder::UInt64Builder,
287 pub post: builder::UInt64Builder,
288}
289
290impl BalancesBuilder {
291 pub fn finish(mut self) -> RecordBatch {
292 RecordBatch::try_new(
293 Arc::new(balances_schema()),
294 vec![
295 Arc::new(self.block_slot.finish()),
296 Arc::new(self.block_hash.finish()),
297 Arc::new(self.transaction_index.finish()),
298 Arc::new(self.account.finish()),
299 Arc::new(self.pre.finish()),
300 Arc::new(self.post.finish()),
301 ],
302 )
303 .unwrap()
304 }
305}
306
307#[derive(Default)]
308pub struct LogsBuilder {
309 pub block_slot: builder::UInt64Builder,
310 pub block_hash: builder::BinaryBuilder,
311 pub transaction_index: builder::UInt32Builder,
312 pub log_index: builder::UInt32Builder,
313 pub instruction_address: builder::ListBuilder<builder::UInt32Builder>,
314 pub program_id: builder::BinaryBuilder,
315 pub kind: builder::StringBuilder,
316 pub message: builder::StringBuilder,
317}
318
319impl LogsBuilder {
320 pub fn finish(mut self) -> RecordBatch {
321 RecordBatch::try_new(
322 Arc::new(logs_schema()),
323 vec![
324 Arc::new(self.block_slot.finish()),
325 Arc::new(self.block_hash.finish()),
326 Arc::new(self.transaction_index.finish()),
327 Arc::new(self.log_index.finish()),
328 Arc::new(self.instruction_address.finish()),
329 Arc::new(self.program_id.finish()),
330 Arc::new(self.kind.finish()),
331 Arc::new(self.message.finish()),
332 ],
333 )
334 .unwrap()
335 }
336}
337
338#[derive(Default)]
339pub struct TransactionsBuilder {
340 pub block_slot: builder::UInt64Builder,
341 pub block_hash: builder::BinaryBuilder,
342 pub transaction_index: builder::UInt32Builder,
343 pub signature: builder::BinaryBuilder,
344 pub version: builder::Int8Builder,
345 pub account_keys: builder::ListBuilder<builder::BinaryBuilder>,
346 pub address_table_lookups: AddressTableLookupsBuilder,
347 pub num_readonly_signed_accounts: builder::UInt32Builder,
348 pub num_readonly_unsigned_accounts: builder::UInt32Builder,
349 pub num_required_signatures: builder::UInt32Builder,
350 pub recent_blockhash: builder::BinaryBuilder,
351 pub signatures: builder::ListBuilder<builder::BinaryBuilder>,
352 pub err: builder::StringBuilder,
353 pub fee: builder::UInt64Builder,
354 pub compute_units_consumed: builder::UInt64Builder,
355 pub loaded_readonly_addresses: builder::ListBuilder<builder::BinaryBuilder>,
356 pub loaded_writable_addresses: builder::ListBuilder<builder::BinaryBuilder>,
357 pub fee_payer: builder::BinaryBuilder,
358 pub has_dropped_log_messages: builder::BooleanBuilder,
359}
360
361pub struct AddressTableLookupsBuilder(pub builder::ListBuilder<builder::StructBuilder>);
362
363impl Default for AddressTableLookupsBuilder {
364 fn default() -> Self {
365 Self(builder::ListBuilder::new(builder::StructBuilder::new(
366 match address_table_lookup_dt() {
367 DataType::Struct(fields) => fields,
368 _ => unreachable!(),
369 },
370 vec![
371 Box::new(builder::BinaryBuilder::default()),
372 Box::new(builder::ListBuilder::new(builder::UInt64Builder::default())),
373 Box::new(builder::ListBuilder::new(builder::UInt64Builder::default())),
374 ],
375 )))
376 }
377}
378
379impl TransactionsBuilder {
380 pub fn finish(mut self) -> RecordBatch {
381 RecordBatch::try_new(
382 Arc::new(transactions_schema()),
383 vec![
384 Arc::new(self.block_slot.finish()),
385 Arc::new(self.block_hash.finish()),
386 Arc::new(self.transaction_index.finish()),
387 Arc::new(self.signature.finish()),
388 Arc::new(self.version.finish()),
389 Arc::new(self.account_keys.finish()),
390 Arc::new(self.address_table_lookups.0.finish()),
391 Arc::new(self.num_readonly_signed_accounts.finish()),
392 Arc::new(self.num_readonly_unsigned_accounts.finish()),
393 Arc::new(self.num_required_signatures.finish()),
394 Arc::new(self.recent_blockhash.finish()),
395 Arc::new(self.signatures.finish()),
396 Arc::new(self.err.finish()),
397 Arc::new(self.fee.finish()),
398 Arc::new(self.compute_units_consumed.finish()),
399 Arc::new(self.loaded_readonly_addresses.finish()),
400 Arc::new(self.loaded_writable_addresses.finish()),
401 Arc::new(self.fee_payer.finish()),
402 Arc::new(self.has_dropped_log_messages.finish()),
403 ],
404 )
405 .unwrap()
406 }
407}
408
409#[derive(Default)]
410pub struct InstructionsBuilder {
411 pub block_slot: builder::UInt64Builder,
412 pub block_hash: builder::BinaryBuilder,
413 pub transaction_index: builder::UInt32Builder,
414 pub instruction_address: builder::ListBuilder<builder::UInt32Builder>,
415 pub program_id: builder::BinaryBuilder,
416 pub a0: builder::BinaryBuilder,
417 pub a1: builder::BinaryBuilder,
418 pub a2: builder::BinaryBuilder,
419 pub a3: builder::BinaryBuilder,
420 pub a4: builder::BinaryBuilder,
421 pub a5: builder::BinaryBuilder,
422 pub a6: builder::BinaryBuilder,
423 pub a7: builder::BinaryBuilder,
424 pub a8: builder::BinaryBuilder,
425 pub a9: builder::BinaryBuilder,
426 pub rest_of_accounts: builder::ListBuilder<builder::BinaryBuilder>,
427 pub data: builder::BinaryBuilder,
428 pub d1: builder::BinaryBuilder,
429 pub d2: builder::BinaryBuilder,
430 pub d4: builder::BinaryBuilder,
431 pub d8: builder::BinaryBuilder,
432 pub error: builder::StringBuilder,
433 pub compute_units_consumed: builder::UInt64Builder,
434 pub is_committed: builder::BooleanBuilder,
435 pub has_dropped_log_messages: builder::BooleanBuilder,
436}
437
438impl InstructionsBuilder {
439 pub fn finish(mut self) -> RecordBatch {
440 RecordBatch::try_new(
441 Arc::new(instructions_schema()),
442 vec![
443 Arc::new(self.block_slot.finish()),
444 Arc::new(self.block_hash.finish()),
445 Arc::new(self.transaction_index.finish()),
446 Arc::new(self.instruction_address.finish()),
447 Arc::new(self.program_id.finish()),
448 Arc::new(self.a0.finish()),
449 Arc::new(self.a1.finish()),
450 Arc::new(self.a2.finish()),
451 Arc::new(self.a3.finish()),
452 Arc::new(self.a4.finish()),
453 Arc::new(self.a5.finish()),
454 Arc::new(self.a6.finish()),
455 Arc::new(self.a7.finish()),
456 Arc::new(self.a8.finish()),
457 Arc::new(self.a9.finish()),
458 Arc::new(self.rest_of_accounts.finish()),
459 Arc::new(self.data.finish()),
460 Arc::new(self.d1.finish()),
461 Arc::new(self.d2.finish()),
462 Arc::new(self.d4.finish()),
463 Arc::new(self.d8.finish()),
464 Arc::new(self.error.finish()),
465 Arc::new(self.compute_units_consumed.finish()),
466 Arc::new(self.is_committed.finish()),
467 Arc::new(self.has_dropped_log_messages.finish()),
468 ],
469 )
470 .unwrap()
471 }
472}
473
474#[cfg(test)]
475mod tests {
476 use super::*;
477
478 #[test]
479 fn smoke() {
480 BlocksBuilder::default().finish();
481 RewardsBuilder::default().finish();
482 TokenBalancesBuilder::default().finish();
483 BalancesBuilder::default().finish();
484 LogsBuilder::default().finish();
485 TransactionsBuilder::default().finish();
486 InstructionsBuilder::default().finish();
487 }
488}