Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sozo): remove the need of world_block #2863

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 125 additions & 85 deletions bin/sozo/src/commands/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use std::sync::Arc;
use anyhow::Result;
use clap::Args;
use colored::Colorize;
use dojo_world::contracts::abigen::world::{self, Event as WorldEvent};
use dojo_world::contracts::abigen::world::{ self, Event as WorldEvent };
use dojo_world::diff::WorldDiff;
use scarb::core::Config;
use sozo_ops::model;
use sozo_scarbext::WorkspaceExt;
use starknet::core::types::{BlockId, BlockTag, EventFilter, Felt};
use starknet::core::types::{ BlockId, BlockTag, EventFilter, Felt };
use starknet::core::utils::starknet_keccak;
use starknet::providers::Provider;

Expand Down Expand Up @@ -50,40 +50,55 @@ pub struct EventsArgs {
#[command(flatten)]
pub starknet: StarknetOptions,
}

const BLOCK_LIMIT: u64 = 50_000; // Maximum block range to process in one iteration
impl EventsArgs {
pub fn run(self, config: &Config) -> Result<()> {
config.tokio_handle().block_on(async {
let ws = scarb::ops::read_workspace(config.manifest_path(), config)?;
let profile_config = ws.load_profile_config()?;

let (world_diff, provider, _) =
utils::get_world_diff_and_provider(self.starknet, self.world, &ws).await?;
let (world_diff, provider, _) = utils::get_world_diff_and_provider(
self.starknet,
self.world,
&ws
).await?;

let provider = Arc::new(provider);

let from_block = if let Some(world_block) =
profile_config.env.as_ref().and_then(|e| e.world_block)
{
Some(BlockId::Number(world_block))
} else {
self.from_block.map(BlockId::Number)
};
let from_block = self.from_block.unwrap_or(0);
let to_block = self.to_block.unwrap_or(u64::MAX);

if from_block >= to_block {
anyhow::bail!("Invalid block range: from_block >= to_block");
}


let mut current_start = from_block;
let continuation_token = None;

let to_block = self.to_block.map(BlockId::Number);
let keys = self
.events
.map(|e| vec![e.iter().map(|event| starknet_keccak(event.as_bytes())).collect()]);
while current_start < to_block {
let current_end = (current_start + BLOCK_LIMIT).min(to_block);
let keys = self.events.clone().map(|e|
vec![
e
.iter()
.map(|event| starknet_keccak(event.as_bytes()))
.collect()
]
);

let event_filter = EventFilter {
from_block,
to_block,
from_block: Some(BlockId::Number(current_start)),
to_block: Some(BlockId::Number(current_end)),
address: Some(world_diff.world_info.address),
keys,
};

let res =
provider.get_events(event_filter, self.continuation_token, self.chunk_size).await?;
let res = provider.get_events(
event_filter,
continuation_token.clone(),
self.chunk_size
).await?;

for event in &res.events {
match world::Event::try_from(event) {
Expand All @@ -93,10 +108,8 @@ impl EventsArgs {
&world_diff,
event.block_number,
event.transaction_hash,
&provider,
)
.await
.unwrap_or_else(|e| {
&provider
).await.unwrap_or_else(|e| {
tracing::error!(?e, "Failed to process event: {:?}", ev);
});
}
Expand All @@ -108,11 +121,21 @@ impl EventsArgs {
}
}
}


// Update continuation token or block range
let continuation_token = res.continuation_token.clone();
if continuation_token.is_none() {
current_start = current_end + 1;
}

if let Some(continuation_token) = res.continuation_token {
println!("Continuation token: {:?}", continuation_token);
// Log continuation token if present
if let Some(token) = &continuation_token {
println!("Continuation token: {:?}", token);
println!("----------------------------------------------");
}
}


Ok(())
})
Expand All @@ -125,13 +148,15 @@ async fn match_event<P: Provider + Send + Sync>(
world_diff: &WorldDiff,
block_number: Option<u64>,
transaction_hash: Felt,
provider: P,
provider: P
) -> Result<()> {
// Get a mapping of all the known selectors and their addresses.
let contract_addresses_from_selector = world_diff.get_contracts_addresses();
// Do a reverse mapping to retrieve a contract selector from it's address.
let contract_selectors_from_address: HashMap<Felt, Felt> =
contract_addresses_from_selector.into_iter().map(|(s, a)| (a, s)).collect();
let contract_selectors_from_address: HashMap<Felt, Felt> = contract_addresses_from_selector
.into_iter()
.map(|(s, a)| (a, s))
.collect();
// Finally, cache all the known tags by creating them once for each selector.
let mut tags = HashMap::new();
for (s, r) in world_diff.resources.iter() {
Expand All @@ -145,55 +170,66 @@ async fn match_event<P: Provider + Send + Sync>(
};

let (name, content) = match event {
WorldEvent::WorldSpawned(e) => (
"World spawned".to_string(),
format!("Creator address: {:?}\nWorld class hash: {:#066x}", e.creator, e.class_hash.0),
),
WorldEvent::WorldSpawned(e) =>
(
"World spawned".to_string(),
format!(
"Creator address: {:?}\nWorld class hash: {:#066x}",
e.creator,
e.class_hash.0
),
),
WorldEvent::WorldUpgraded(e) => {
("World upgraded".to_string(), format!("World class hash: {:#066x}", e.class_hash.0))
}
WorldEvent::NamespaceRegistered(e) => {
("Namespace registered".to_string(), format!("Namespace: {}", e.namespace.to_string()?))
}
WorldEvent::ModelRegistered(e) => (
"Model registered".to_string(),
format!(
"Namespace: {}\nName: {}\nClass hash: {:#066x}\nAddress: {:#066x}",
e.namespace.to_string()?,
e.name.to_string()?,
e.class_hash.0,
e.address.0
WorldEvent::ModelRegistered(e) =>
(
"Model registered".to_string(),
format!(
"Namespace: {}\nName: {}\nClass hash: {:#066x}\nAddress: {:#066x}",
e.namespace.to_string()?,
e.name.to_string()?,
e.class_hash.0,
e.address.0
),
),
),
WorldEvent::EventRegistered(e) => (
"Event registered".to_string(),
format!(
"Namespace: {}\nName: {}\nClass hash: {:#066x}\nAddress: {:#066x}",
e.namespace.to_string()?,
e.name.to_string()?,
e.class_hash.0,
e.address.0
WorldEvent::EventRegistered(e) =>
(
"Event registered".to_string(),
format!(
"Namespace: {}\nName: {}\nClass hash: {:#066x}\nAddress: {:#066x}",
e.namespace.to_string()?,
e.name.to_string()?,
e.class_hash.0,
e.address.0
),
),
),
WorldEvent::ContractRegistered(e) => (
"Contract registered".to_string(),
format!(
"Namespace: {}\nName: {}\nClass hash: {:#066x}\nAddress: {:#066x}\nSalt: {:#066x}",
e.namespace.to_string()?,
e.name.to_string()?,
e.class_hash.0,
e.address.0,
e.salt
WorldEvent::ContractRegistered(e) =>
(
"Contract registered".to_string(),
format!(
"Namespace: {}\nName: {}\nClass hash: {:#066x}\nAddress: {:#066x}\nSalt: {:#066x}",
e.namespace.to_string()?,
e.name.to_string()?,
e.class_hash.0,
e.address.0,
e.salt
),
),
),
WorldEvent::ModelUpgraded(e) => {
let tag = tags.get(&e.selector).unwrap();
(
format!("Model upgraded ({})", tag),
format!(
"Selector: {:#066x}\nClass hash: {:#066x}\nAddress: {:#066x}\nPrev address: \
{:#066x}",
e.selector, e.class_hash.0, e.address.0, e.prev_address.0
e.selector,
e.class_hash.0,
e.address.0,
e.prev_address.0
),
)
}
Expand All @@ -204,15 +240,18 @@ async fn match_event<P: Provider + Send + Sync>(
format!(
"Selector: {:#066x}\nClass hash: {:#066x}\nAddress: {:#066x}\nPrev address: \
{:#066x}",
e.selector, e.class_hash.0, e.address.0, e.prev_address.0
e.selector,
e.class_hash.0,
e.address.0,
e.prev_address.0
),
)
}
WorldEvent::ContractUpgraded(e) => {
let tag = tags.get(&e.selector).unwrap();
(
format!("Contract upgraded ({})", tag),
format!("Selector: {:#066x}\nClass hash: {:#066x}", e.selector, e.class_hash.0,),
format!("Selector: {:#066x}\nClass hash: {:#066x}", e.selector, e.class_hash.0),
)
}
WorldEvent::ContractInitialized(e) => {
Expand All @@ -232,12 +271,13 @@ async fn match_event<P: Provider + Send + Sync>(
}
WorldEvent::WriterUpdated(e) => {
let tag = tags.get(&e.resource).unwrap();
let grantee =
if let Some(selector) = contract_selectors_from_address.get(&e.contract.into()) {
tags.get(selector).unwrap().to_string()
} else {
format!("{:#066x}", e.contract.0)
};
let grantee = if
let Some(selector) = contract_selectors_from_address.get(&e.contract.into())
{
tags.get(selector).unwrap().to_string()
} else {
format!("{:#066x}", e.contract.0)
};

(
"Writer updated".to_string(),
Expand All @@ -246,12 +286,13 @@ async fn match_event<P: Provider + Send + Sync>(
}
WorldEvent::OwnerUpdated(e) => {
let tag = tags.get(&e.resource).unwrap();
let grantee =
if let Some(selector) = contract_selectors_from_address.get(&e.contract.into()) {
tags.get(selector).unwrap().to_string()
} else {
format!("{:#066x}", e.contract.0)
};
let grantee = if
let Some(selector) = contract_selectors_from_address.get(&e.contract.into())
{
tags.get(selector).unwrap().to_string()
} else {
format!("{:#066x}", e.contract.0)
};

(
"Owner updated".to_string(),
Expand All @@ -265,9 +306,8 @@ async fn match_event<P: Provider + Send + Sync>(
e.keys.clone(),
world_diff.world_info.address,
provider,
block_id,
)
.await?;
block_id
).await?;

(
format!("Store set record ({})", tag),
Expand Down Expand Up @@ -302,7 +342,7 @@ async fn match_event<P: Provider + Send + Sync>(
.iter()
.map(|v| format!("{:#066x}", v))
.collect::<Vec<String>>()
.join(", "),
.join(", ")
),
)
}
Expand All @@ -321,21 +361,21 @@ async fn match_event<P: Provider + Send + Sync>(
.iter()
.map(|v| format!("{:#066x}", v))
.collect::<Vec<String>>()
.join(", "),
.join(", ")
),
)
}
WorldEvent::StoreDelRecord(e) => {
let tag = tags.get(&e.selector).unwrap();
(
format!("Store del record ({})", tag),
format!("Selector: {:#066x}\nEntity ID: {:#066x}", e.selector, e.entity_id,),
format!("Selector: {:#066x}\nEntity ID: {:#066x}", e.selector, e.entity_id),
)
}
WorldEvent::EventEmitted(e) => {
let tag = tags.get(&e.selector).unwrap();
let contract_tag = if let Some(selector) =
contract_selectors_from_address.get(&e.system_address.into())
let contract_tag = if
let Some(selector) = contract_selectors_from_address.get(&e.system_address.into())
{
tags.get(selector).unwrap().to_string()
} else {
Expand All @@ -359,7 +399,7 @@ async fn match_event<P: Provider + Send + Sync>(
.iter()
.map(|v| format!("{:#066x}", v))
.collect::<Vec<String>>()
.join(", "),
.join(", ")
),
)
}
Expand Down
Loading