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: IntoLogData #666

Merged
merged 3 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
fix: add encode_log_data and encode_log
  • Loading branch information
prestwich committed Jun 17, 2024
commit 1b93a8dba596ae3c75acaae7342605639b7870d0
38 changes: 34 additions & 4 deletions crates/dyn-abi/src/dynamic/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ use alloy_primitives::{LogData, B256};
/// logs.
#[derive(Clone, Debug, PartialEq)]
pub struct DynSolEvent {
/// The event signature hash, if any.
pub(crate) topic_0: Option<B256>,
/// The indexed types.
pub(crate) indexed: Vec<DynSolType>,
/// The un-indexed types.
pub(crate) body: DynSolType,
}

Expand Down Expand Up @@ -103,11 +106,11 @@ impl DynSolEvent {
}
}

Ok(DecodedEvent { indexed, body })
Ok(DecodedEvent { signature_hash: self.topic_0, indexed, body })
}

/// Decode the event from the given log info.
pub fn decode_log(&self, log: &LogData, validate: bool) -> Result<DecodedEvent> {
pub fn decode_log_data(&self, log: &LogData, validate: bool) -> Result<DecodedEvent> {
self.decode_log_parts(log.topics().iter().copied(), &log.data, validate)
}

Expand All @@ -130,12 +133,39 @@ impl DynSolEvent {
/// A decoded dynamic ABI event.
#[derive(Clone, Debug, PartialEq)]
pub struct DecodedEvent {
/// The hashes event_signature (if any)
#[doc(alias = "topic_0")]
pub signature_hash: Option<B256>,
/// The indexed values, in order.
pub indexed: Vec<DynSolValue>,
/// The un-indexed values, in order.
pub body: Vec<DynSolValue>,
}

impl DecodedEvent {
/// True if anonymous. False if not.
pub const fn is_anonymous(&self) -> bool {
self.signature_hash.is_none()
}

/// Re-encode the event as a log.
pub fn encode_log_data(&self) -> LogData {
debug_assert!(
self.indexed.len() + self.signature_hash.is_some() as usize <= 4,
"too many indexed values"
);

LogData::new_unchecked(
self.signature_hash
.iter()
.copied()
.chain(self.indexed.iter().flat_map(DynSolValue::as_word).map(B256::from))
.collect(),
DynSolValue::encode_seq(&self.body).into(),
)
}
}

#[cfg(test)]
mod test {
use alloy_primitives::{address, b256, bytes, U256};
Expand All @@ -150,7 +180,7 @@ mod test {
indexed: vec![],
body: DynSolType::Tuple(vec![DynSolType::Uint(256)]),
};
event.decode_log(&log, true).unwrap();
event.decode_log_data(&log, true).unwrap();
}

#[test]
Expand All @@ -174,7 +204,7 @@ mod test {
])]),
};

let decoded = event.decode_log(&log, true).unwrap();
let decoded = event.decode_log_data(&log, true).unwrap();
assert_eq!(
decoded.indexed,
vec![DynSolValue::Address(address!("0000000000000000000000000000000000012321"))]
Expand Down
5 changes: 3 additions & 2 deletions crates/sol-macro-expander/src/expand/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,17 +812,18 @@ impl<'a> CallLikeExpander<'a> {
});

let into_impl = {
let variants: Vec<_> = events.iter().map(e_name).collect();
let variants = events.iter().map(e_name);
let v2 = variants.clone();
quote! {
#[automatically_derived]
impl alloy_sol_types::private::IntoLogData for #name {
fn to_log_data(&self) -> alloy_sol_types::private::LogData {
match self {#(
Self::#variants(ref inner) =>
Self::#variants(inner) =>
alloy_sol_types::private::IntoLogData::to_log_data(inner),
)*}
}

fn into_log_data(self) -> alloy_sol_types::private::LogData {
prestwich marked this conversation as resolved.
Show resolved Hide resolved
match self {#(
Self::#v2(inner) =>
Expand Down
19 changes: 8 additions & 11 deletions crates/sol-macro-expander/src/expand/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,25 +197,22 @@ pub(super) fn expand(cx: &ExpCtxt<'_>, event: &ItemEvent) -> Result<TokenStream>
}

#[automatically_derived]
impl alloy_sol_types::private::IntoLogData for #name
{
fn to_log_data(&self) -> alloy_sol_types::private::LogData {
From::from(self)
}
impl alloy_sol_types::private::IntoLogData for #name {
fn to_log_data(&self) -> alloy_sol_types::private::LogData {
From::from(self)
}

fn into_log_data(self) -> alloy_sol_types::private::LogData {
From::from(&self)
}
fn into_log_data(self) -> alloy_sol_types::private::LogData {
From::from(&self)
}
prestwich marked this conversation as resolved.
Show resolved Hide resolved
}


#[automatically_derived]
impl From<&#name> for alloy_sol_types::private::LogData {
#[inline]
fn from(this: &#name) -> alloy_sol_types::private::LogData {
let topics = alloy_sol_types::SolEvent::encode_topics(this).into_iter().map(|t| t.into()).collect();
let data = alloy_sol_types::SolEvent::encode_data(this).into();
alloy_sol_types::private::LogData::new_unchecked(topics, data)
alloy_sol_types::SolEvent::encode_log_data(this)
}
}

Expand Down
16 changes: 15 additions & 1 deletion crates/sol-types/src/types/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
Result, SolType, Word,
};
use alloc::vec::Vec;
use alloy_primitives::{FixedBytes, IntoLogData, Log, LogData, B256};
use alloy_primitives::{FixedBytes, Log, LogData, B256};

mod topic;
pub use topic::EventTopic;
Expand Down Expand Up @@ -122,6 +122,20 @@ pub trait SolEvent: Sized {
out
}

/// Encode this event to a [`LogData`].
fn encode_log_data(&self) -> LogData {
LogData::new_unchecked(
self.encode_topics().into_iter().map(Into::into).collect(),
self.encode_data().into(),
)
}

/// Transform ca [`Log`] containing this event into a [`Log`] containing
/// [`LogData`].
fn encode_log(log: &Log<Self>) -> Log<LogData> {
Log { address: log.address, data: log.data.encode_log_data() }
}

/// Decode the topics of this event from the given data.
#[inline]
fn decode_topics<I, D>(topics: I) -> Result<<Self::TopicList as SolType>::RustType>
Expand Down