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(papyrus_base_layer): start implementing eth events api #2845

Merged
merged 1 commit into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion .github/actions/install_rust/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ runs:
with:
cache-base: main(-v[0-9].*)?
inherit-toolchain: true
bins: [email protected].0, cargo-machete
bins: [email protected].3, cargo-machete
# Install additional non-default toolchains (for rustfmt for example), NOP if input omitted.
channel: ${{ inputs.extra_rust_toolchains }}
env:
Expand Down
18 changes: 9 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ alloy-dyn-abi = "0.8.3"
alloy-json-rpc = "0.3.5"
alloy-primitives = "0.8.3"
alloy-provider = "0.3.5"
alloy-rpc-types-eth = "0.3.5"
alloy-sol-types = "0.8.3"
alloy-transport = "0.3.5"
alloy-transport-http = "0.3.5"
Expand Down
2 changes: 1 addition & 1 deletion crates/papyrus_base_layer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ alloy-dyn-abi.workspace = true
alloy-json-rpc.workspace = true
alloy-primitives.workspace = true
alloy-provider.workspace = true
alloy-rpc-types-eth.workspace = true
alloy-sol-types = { workspace = true, features = ["json"] }
alloy-transport.workspace = true
alloy-transport-http.workspace = true
async-trait.workspace = true
ethers.workspace = true
papyrus_config.workspace = true
serde.workspace = true
serde_json.workspace = true
starknet-types-core.workspace = true
starknet_api.workspace = true
tar = { workspace = true, optional = true }
Expand Down
79 changes: 79 additions & 0 deletions crates/papyrus_base_layer/src/eth_events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use std::sync::Arc;

use alloy_primitives::{Address as EthereumContractAddress, U256};
use alloy_rpc_types_eth::Log;
use alloy_sol_types::SolEventInterface;
use starknet_api::core::{EntryPointSelector, Nonce};
use starknet_api::transaction::fields::Calldata;
use starknet_types_core::felt::Felt;

use crate::ethereum_base_layer_contract::{
EthereumBaseLayerError,
EthereumBaseLayerResult,
Starknet,
};
use crate::{EventData, L1Event};

impl TryFrom<Log> for L1Event {
type Error = EthereumBaseLayerError;

fn try_from(log: Log) -> EthereumBaseLayerResult<Self> {
let validate = true;
let log = log.inner;

let event = Starknet::StarknetEvents::decode_log(&log, validate)?.data;
match event {
Starknet::StarknetEvents::LogMessageToL2(_event) => {
todo!()
}
Starknet::StarknetEvents::ConsumedMessageToL2(_event) => {
todo!()
}
Starknet::StarknetEvents::MessageToL2Canceled(event) => {
Ok(L1Event::MessageToL2Canceled(event.try_into()?))
}
Starknet::StarknetEvents::MessageToL2CancellationStarted(_event) => {
todo!()
}
_ => Err(EthereumBaseLayerError::UnhandledL1Event(log)),
}
}
}

impl TryFrom<Starknet::MessageToL2Canceled> for EventData {
type Error = EthereumBaseLayerError;

fn try_from(event: Starknet::MessageToL2Canceled) -> EthereumBaseLayerResult<Self> {
create_l1_event_data(
event.fromAddress,
event.toAddress,
event.selector,
&event.payload,
event.nonce,
)
}
}

pub fn create_l1_event_data(
from_address: EthereumContractAddress,
to_address: U256,
selector: U256,
payload: &[U256],
nonce: U256,
) -> EthereumBaseLayerResult<EventData> {
Ok(EventData {
from_address: Felt::from_bytes_be_slice(from_address.0.as_slice())
.try_into()
.map_err(EthereumBaseLayerError::StarknetApiParsingError)?,
to_address: felt_from_u256(to_address)
.try_into()
.map_err(EthereumBaseLayerError::StarknetApiParsingError)?,
entry_point_selector: EntryPointSelector(felt_from_u256(selector)),
payload: Calldata(Arc::new(payload.iter().map(|&x| felt_from_u256(x)).collect())),
nonce: Nonce(felt_from_u256(nonce)),
})
}

pub fn felt_from_u256(num: U256) -> Felt {
Felt::from_bytes_be(&num.to_be_bytes())
}
29 changes: 18 additions & 11 deletions crates/papyrus_base_layer/src/ethereum_base_layer_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ use std::future::IntoFuture;

use alloy_dyn_abi::SolType;
use alloy_json_rpc::RpcError;
pub(crate) use alloy_primitives::Address as EthereumContractAddress;
use alloy_primitives::Address as EthereumContractAddress;
use alloy_provider::network::Ethereum;
use alloy_provider::{Provider, ProviderBuilder, RootProvider};
use alloy_rpc_types_eth::{BlockNumberOrTag, Filter as EthEventFilter};
use alloy_sol_types::{sol, sol_data};
use alloy_transport::TransportErrorKind;
use alloy_transport_http::{Client, Http};
Expand All @@ -15,12 +16,12 @@ use papyrus_config::{ParamPath, ParamPrivacyInput, SerializationType, Serialized
use serde::{Deserialize, Serialize};
use starknet_api::block::{BlockHash, BlockHashAndNumber, BlockNumber};
use starknet_api::hash::StarkHash;
use starknet_types_core::felt;
use starknet_api::StarknetApiError;
use url::Url;

use crate::{BaseLayerContract, L1Event};

type EthereumBaseLayerResult<T> = Result<T, EthereumBaseLayerError>;
pub type EthereumBaseLayerResult<T> = Result<T, EthereumBaseLayerError>;

// Wraps the Starknet contract with a type that implements its interface, and is aware of its
// events.
Expand Down Expand Up @@ -81,11 +82,17 @@ impl BaseLayerContract for EthereumBaseLayerContract {

async fn events(
&self,
_from_block: u64,
_until_block: u64,
_event_identifiers: &[&str],
from_block: u64,
until_block: u64,
events: &[&str],
) -> EthereumBaseLayerResult<Vec<L1Event>> {
todo!("Implmeneted in a subsequent commit")
let filter = EthEventFilter::new()
.from_block(BlockNumberOrTag::Number(from_block))
.events(events)
.to_block(until_block);

let matching_logs = self.contract.provider().get_logs(&filter).await?;
matching_logs.into_iter().map(TryInto::try_into).collect()
}

async fn latest_l1_block_number(&self, finality: u64) -> EthereumBaseLayerResult<Option<u64>> {
Expand All @@ -98,13 +105,13 @@ pub enum EthereumBaseLayerError {
#[error(transparent)]
Contract(#[from] alloy_contract::Error),
#[error(transparent)]
FeltParseError(#[from] felt::FromStrError),
#[error(transparent)]
RpcError(#[from] RpcError<TransportErrorKind>),
#[error(transparent)]
Serde(#[from] serde_json::Error),
#[error(transparent)]
TypeError(#[from] alloy_sol_types::Error),
#[error("{0}")]
StarknetApiParsingError(StarknetApiError),
#[error("{0:?}")]
UnhandledL1Event(alloy_primitives::Log),
}

#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
Expand Down
2 changes: 2 additions & 0 deletions crates/papyrus_base_layer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use starknet_api::transaction::L1HandlerTransaction;

pub mod ethereum_base_layer_contract;

pub(crate) mod eth_events;

#[cfg(any(feature = "testing", test))]
pub mod test_utils;

Expand Down
Loading