iota_analytics_indexer/handlers/
move_call_handler.rs1use std::sync::Arc;
6
7use anyhow::Result;
8use iota_data_ingestion_core::Worker;
9use iota_sdk_types::ObjectId;
10use iota_types::{full_checkpoint_content::CheckpointData, transaction::TransactionDataAPI};
11use tokio::sync::Mutex;
12
13use crate::{FileType, handlers::AnalyticsHandler, tables::MoveCallEntry};
14
15pub struct MoveCallHandler {
16 state: Mutex<State>,
17}
18
19struct State {
20 move_calls: Vec<MoveCallEntry>,
21}
22
23#[async_trait::async_trait]
24impl Worker for MoveCallHandler {
25 type Message = ();
26 type Error = anyhow::Error;
27
28 async fn process_checkpoint(
29 &self,
30 checkpoint_data: Arc<CheckpointData>,
31 ) -> Result<Self::Message, Self::Error> {
32 let CheckpointData {
33 checkpoint_summary,
34 transactions: checkpoint_transactions,
35 ..
36 } = checkpoint_data.as_ref();
37 let mut state = self.state.lock().await;
38 for checkpoint_transaction in checkpoint_transactions {
39 let move_calls = checkpoint_transaction
40 .transaction
41 .transaction_data()
42 .move_calls();
43 self.process_move_calls(
44 checkpoint_summary.epoch,
45 checkpoint_summary.sequence_number,
46 checkpoint_summary.timestamp_ms,
47 checkpoint_transaction.transaction.digest().to_base58(),
48 &move_calls,
49 &mut state,
50 );
51 }
52 Ok(())
53 }
54}
55
56#[async_trait::async_trait]
57impl AnalyticsHandler<MoveCallEntry> for MoveCallHandler {
58 async fn read(&self) -> Result<Vec<MoveCallEntry>> {
59 let mut state = self.state.lock().await;
60 let cloned = state.move_calls.clone();
61 state.move_calls.clear();
62 Ok(cloned)
63 }
64
65 fn file_type(&self) -> Result<FileType> {
66 Ok(FileType::MoveCall)
67 }
68
69 fn name(&self) -> &str {
70 "move_call"
71 }
72}
73
74impl MoveCallHandler {
75 pub fn new() -> Self {
76 let state = State { move_calls: vec![] };
77 Self {
78 state: Mutex::new(state),
79 }
80 }
81 fn process_move_calls(
82 &self,
83 epoch: u64,
84 checkpoint: u64,
85 timestamp_ms: u64,
86 transaction_digest: String,
87 move_calls: &[(&ObjectId, &str, &str)],
88 state: &mut State,
89 ) {
90 for (package, module, function) in move_calls.iter() {
91 let entry = MoveCallEntry {
92 transaction_digest: transaction_digest.clone(),
93 checkpoint,
94 epoch,
95 timestamp_ms,
96 package: package.to_string(),
97 module: module.to_string(),
98 function: function.to_string(),
99 };
100 state.move_calls.push(entry);
101 }
102 }
103}