Skip to content

Commit

Permalink
add event manager logic
Browse files Browse the repository at this point in the history
  • Loading branch information
glihm committed Sep 13, 2023
1 parent 625333a commit a123adc
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 65 deletions.
25 changes: 19 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ async fn main() -> Result<()> {
let sn_client = StarknetClient::new(&rpc_provider.clone())?;
let storage = storage::init_default();
let block_manager = BlockManager::new(&storage, &sn_client);
let event_manager = EventManager::new(&storage, &sn_client);
let mut event_manager = EventManager::new(&storage, &sn_client);
let mut collection_manager = CollectionManager::new(&storage, &sn_client);

let (from_block, to_block, poll_head_of_chain) = block_manager.get_block_range();
Expand All @@ -48,6 +48,8 @@ async fn main() -> Result<()> {
continue;
}

let block_ts = sn_client.block_time(BlockId::Number(current_u64)).await?;

let blocks_events = sn_client
.fetch_events(
BlockId::Number(current_u64),
Expand All @@ -69,17 +71,28 @@ async fn main() -> Result<()> {
}
};

let contract_type = contract_info.r#type;
if contract_type == ContractType::Other {
continue;
}

log::debug!(
"Contract type [{:#064x}] : {}",
contract_address,
contract_info.r#type.to_string()
contract_type.to_string()
);

if contract_info.r#type == ContractType::Other {
continue;
}
let _token_id = match event_manager
.format_event(&e, contract_type, block_ts)
.await
{
Ok(token_id) => token_id,
Err(err) => {
log::error!("Can't format event {:?}\nevent: {:?}", err, e);
continue;
}
};

// event_manager.identify_event(e, block_timestamp, contract_info);
// token_manager.register_token(...);
}
}
Expand Down
96 changes: 64 additions & 32 deletions src/managers/event_manager.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::ContractType;
use anyhow::{anyhow, Result};
use ark_starknet::client2::StarknetClient;
use ark_storage::storage_manager::StorageManager;
Expand All @@ -9,6 +10,8 @@ use starknet::macros::selector;
#[derive(Debug)]
pub struct EventManager<'a, T: StorageManager> {
storage: &'a T,

Check warning on line 12 in src/managers/event_manager.rs

View workflow job for this annotation

GitHub Actions / clippy

fields `storage` and `client` are never read

warning: fields `storage` and `client` are never read --> src/managers/event_manager.rs:12:5 | 11 | pub struct EventManager<'a, T: StorageManager> { | ------------ fields in this struct 12 | storage: &'a T, | ^^^^^^^ ... 16 | client: &'a StarknetClient, | ^^^^^^ | = note: `EventManager` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
// I am not sure we gain a lot by having it here. As a temporary
// value will be on the stack, which is way faster that accessing the heap.
token_event: TokenEvent,
client: &'a StarknetClient,
}
Expand All @@ -28,57 +31,86 @@ impl<'a, T: StorageManager> EventManager<'a, T> {
return Some(vec![vec![selector!("Transfer")]]);

Check warning on line 31 in src/managers/event_manager.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/managers/event_manager.rs:31:9 | 31 | return Some(vec![vec![selector!("Transfer")]]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return = note: `#[warn(clippy::needless_return)]` on by default help: remove `return` | 31 - return Some(vec![vec![selector!("Transfer")]]); 31 + Some(vec![vec![selector!("Transfer")]]) |
}

pub fn reset_event(&mut self) {
self.token_event = TokenEvent::default();
}

pub fn format_event(
/// Formats a token event based on the event content.
/// Returns the token_id if the event were identified,
/// an Err otherwise.
pub async fn format_event(
&mut self,
event: &EmittedEvent,
contract_type: &str,
contract_type: ContractType,
timestamp: u64,
) -> Result<()> {
if event.data.len() < 4 {
return Err(anyhow!("Invalid event data"));
}
) -> Result<TokenId> {
self.reset_event();

// As cairo didn't have keys before, we first check if the data
// contains the info. If not, we check into the keys, skipping the first
// element which is the selector.
let event_info = if let Some(d_info) = Self::get_event_info_from_felts(&event.data) {
d_info
} else if let Some(k_info) = Self::get_event_info_from_felts(&event.keys[1..]) {
k_info
} else {
log::warn!("Can't find event data into this event");
return Err(anyhow!("Can't format event"));
};

let (from, to, token_id) = event_info;

self.token_event.from_address_field_element = event.data[0];
self.token_event.from_address = format!("{:#064x}", event.data[0]);
self.token_event.to_address_field_element = event.data[1];
self.token_event.to_address = format!("{:#064x}", event.data[1]);
// TODO: why do we need this entry 2 times for the felt and the string?
self.token_event.from_address_field_element = from;
self.token_event.from_address = format!("{:#064x}", from);
self.token_event.to_address_field_element = to;
self.token_event.to_address = format!("{:#064x}", to);
self.token_event.contract_address = format!("{:#064x}", event.from_address);
self.token_event.transaction_hash = format!("{:#064x}", event.transaction_hash);
self.token_event.token_id = TokenId {
low: event.data[2],
high: event.data[3],
};
self.token_event.token_id = token_id.clone();
self.token_event.formated_token_id = self.token_event.token_id.format();
self.token_event.block_number = event.block_number;
self.token_event.timestamp = timestamp;
self.token_event.contract_type = contract_type.to_string();
self.token_event.event_type = self.get_event_type();
Ok(())
}
self.token_event.event_type = Self::get_event_type(from, to);

pub fn get_event(&self) -> &TokenEvent {
&self.token_event
info!("Event identified: {:?}", self.token_event.event_type);

// TODO: self.storage.register_event(self.token_event);
// TODO: check depending on event type if it's a create/update etc...?

Ok(token_id)
}

pub fn get_event_type(&mut self) -> EventType {
if self.token_event.from_address_field_element == FieldElement::ZERO {
info!("EVENT MANAGER: Mint detected");
pub fn get_event_type(from: FieldElement, to: FieldElement) -> EventType {
if from == FieldElement::ZERO {
EventType::Mint
} else if self.token_event.to_address_field_element == FieldElement::ZERO {
info!("EVENT MANAGER: Burn detected");
} else if to == FieldElement::ZERO {
EventType::Burn
} else {
info!("EVENT MANAGER: Transfer detected");
EventType::Transfer
}
}

pub fn create_event(&self) -> Result<()> {
self.storage.create_event(&self.token_event);
Ok(())
/// Returns the event info from vector of felts.
/// Event info are (from, to, token_id).
///
/// This methods considers that the info of the
/// event is starting at index 0 of the input vector.
fn get_event_info_from_felts(
felts: &[FieldElement],
) -> Option<(FieldElement, FieldElement, TokenId)> {
if felts.len() < 4 {
return None;
}
let from = felts[0];
let to = felts[1];

let token_id = TokenId {
low: felts[2],
high: felts[3],
};

Some((from, to, token_id))
}

fn reset_event(&mut self) {
self.token_event = TokenEvent::default();
}
}
54 changes: 27 additions & 27 deletions src/transfer.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
use crate::managers::event_manager::EventManager;
use crate::managers::token_manager::TokenManager;
use anyhow::Result;
use ark_storage::storage_manager::StorageManager;
use ark_storage::types::EventType;
use starknet::core::types::EmittedEvent;
// use crate::managers::event_manager::EventManager;
// use crate::managers::token_manager::TokenManager;
// use anyhow::Result;
// use ark_storage::storage_manager::StorageManager;
// use ark_storage::types::EventType;
// use starknet::core::types::EmittedEvent;

pub async fn process_transfer<'a, T: StorageManager>(
event: &EmittedEvent,
contract_type: &str,
timestamp: u64,
token_manager: &mut TokenManager<'a, T>,
event_manager: &mut EventManager<'a, T>,
) -> Result<()> {
event_manager.format_event(event, contract_type, timestamp)?;
event_manager.create_event()?;
// pub async fn process_transfer<'a, T: StorageManager>(
// event: &EmittedEvent,
// contract_type: &str,
// timestamp: u64,
// token_manager: &mut TokenManager<'a, T>,
// event_manager: &mut EventManager<'a, T>,
// ) -> Result<()> {
// event_manager.format_event(event, contract_type, timestamp)?;
// event_manager.create_event()?;

let token_event = event_manager.get_event();
token_manager.format_token_from_event(token_event);
// let token_event = event_manager.get_event();
// token_manager.format_token_from_event(token_event);

if token_event.event_type == EventType::Mint {
token_manager.create_token()?;
} else {
// TODO update token owner
// token_manager.update_token_owner()?;
}
// if token_event.event_type == EventType::Mint {
// token_manager.create_token()?;
// } else {
// // TODO update token owner
// // token_manager.update_token_owner()?;
// }

token_manager.reset_token();
event_manager.reset_event();
Ok(())
}
// token_manager.reset_token();
// event_manager.reset_event();
// Ok(())
// }

0 comments on commit a123adc

Please sign in to comment.