Skip to content

Commit

Permalink
Remove event topics length limit; refactor tuple code into separate f…
Browse files Browse the repository at this point in the history
…ile (#1263)

### What

Resolves #480
Plus a minor enhancement to `impl_topics_for_tuple` for tuple up to size
13.

### Why
The event topics length limit was a residual from an earlier design,
where the limit was set to 4, matching with what's in Ethereum. Since
then the length limit has been removed, but sdk has not been updated, so
the user still can only submit events with topic length <=4.
Expanding `impl_topics_for_tuple` makes it more convenient to construct
longer topics (up to 13).
Constructing topics from a `Vec<T>` does not subject to any length
limit.

### Known limitations

[TODO or N/A]
  • Loading branch information
jayz22 authored Apr 25, 2024
1 parent e43b3db commit aff2a81
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 55 deletions.
34 changes: 6 additions & 28 deletions soroban-sdk/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ use core::fmt::Debug;

#[cfg(doc)]
use crate::{contracttype, Bytes, Map};
use crate::{
env::internal, unwrap::UnwrapInfallible, ConversionError, Env, IntoVal, TryFromVal, Val, Vec,
};
use crate::{env::internal, unwrap::UnwrapInfallible, Env, IntoVal, Val, Vec};

// TODO: consolidate with host::events::TOPIC_BYTES_LENGTH_LIMIT
const TOPIC_BYTES_LENGTH_LIMIT: u32 = 32;
Expand All @@ -25,16 +23,20 @@ const TOPIC_BYTES_LENGTH_LIMIT: u32 = 32;
/// # pub fn f(env: Env) {
/// let event = env.events();
/// let data = map![&env, (1u32, 2u32)];
/// // topics can be represented with tuple up to a certain length
/// let topics0 = ();
/// let topics1 = (0u32,);
/// let topics2 = (0u32, 1u32);
/// let topics3 = (0u32, 1u32, 2u32);
/// let topics4 = (0u32, 1u32, 2u32, 3u32);
/// // topics can also be represented with a `Vec` with no length limit
/// let topics5 = vec![&env, 4u32, 5u32, 6u32, 7u32, 8u32];
/// event.publish(topics0, data.clone());
/// event.publish(topics1, data.clone());
/// event.publish(topics2, data.clone());
/// event.publish(topics3, data.clone());
/// event.publish(topics4, data.clone());
/// event.publish(topics5, data.clone());
/// # }
/// # }
///
Expand All @@ -58,31 +60,7 @@ impl Debug for Events {

pub trait Topics: IntoVal<Env, Vec<Val>> {}

impl TryFromVal<Env, ()> for Vec<Val> {
type Error = ConversionError;

fn try_from_val(env: &Env, _v: &()) -> Result<Self, Self::Error> {
Ok(Vec::<Val>::new(env))
}
}

macro_rules! impl_topics_for_tuple {
( $($typ:ident $idx:tt)* ) => {
impl<$($typ),*> Topics for ($($typ,)*)
where
$($typ: IntoVal<Env, Val>),*
{
}
};
}

// 0 topics
impl Topics for () {}
// 1-4 topics
impl_topics_for_tuple! { T0 0 }
impl_topics_for_tuple! { T0 0 T1 1 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 T3 3 }
impl<T> Topics for Vec<T> {}

impl Events {
#[inline(always)]
Expand Down
2 changes: 2 additions & 0 deletions soroban-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,7 @@ pub mod deploy;
mod error;
pub use error::InvokeError;
pub mod events;
pub use events::Topics;
pub mod iter;
pub mod ledger;
pub mod logs;
Expand All @@ -792,6 +793,7 @@ mod num;
pub use num::{Duration, Timepoint, I256, U256};
mod string;
pub use string::String;
mod tuple;

pub mod xdr;

Expand Down
65 changes: 65 additions & 0 deletions soroban-sdk/src/tuple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//! This module contains conversion helpers for tuple
use crate::{vec, ConversionError, Env, IntoVal, Topics, TryFromVal, Val, Vec};

impl TryFromVal<Env, ()> for Vec<Val> {
type Error = ConversionError;

fn try_from_val(env: &Env, _v: &()) -> Result<Self, Self::Error> {
Ok(Vec::<Val>::new(env))
}
}

macro_rules! impl_into_vec_for_tuple {
( $($typ:ident $idx:tt)* ) => {
impl<$($typ),*> TryFromVal<Env, ($($typ,)*)> for Vec<Val>
where
$($typ: IntoVal<Env, Val>),*
{
type Error = ConversionError;
fn try_from_val(env: &Env, v: &($($typ,)*)) -> Result<Self, Self::Error> {
Ok(vec![&env, $(v.$idx.into_val(env), )*])
}
}
};
}
impl_into_vec_for_tuple! { T0 0 }
impl_into_vec_for_tuple! { T0 0 T1 1 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 T12 12 }

macro_rules! impl_topics_for_tuple {
( $($typ:ident $idx:tt)* ) => {
impl<$($typ),*> Topics for ($($typ,)*)
where
$($typ: IntoVal<Env, Val>),*
{
}
};
}

// 0 topics
impl Topics for () {}
// 1-13 topics
impl_topics_for_tuple! { T0 0 }
impl_topics_for_tuple! { T0 0 T1 1 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 T3 3 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 }
impl_topics_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 T12 12 }
27 changes: 0 additions & 27 deletions soroban-sdk/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,33 +45,6 @@ macro_rules! vec {
};
}

macro_rules! impl_into_vec_for_tuple {
( $($typ:ident $idx:tt)* ) => {
impl<$($typ),*> TryFromVal<Env, ($($typ,)*)> for Vec<Val>
where
$($typ: IntoVal<Env, Val>),*
{
type Error = ConversionError;
fn try_from_val(env: &Env, v: &($($typ,)*)) -> Result<Self, Self::Error> {
Ok(vec![&env, $(v.$idx.into_val(env), )*])
}
}
};
}
impl_into_vec_for_tuple! { T0 0 }
impl_into_vec_for_tuple! { T0 0 T1 1 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 }
impl_into_vec_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 T12 12 }

/// Vec is a sequential and indexable growable collection type.
///
/// Values are stored in the environment and are available to contract through
Expand Down

0 comments on commit aff2a81

Please sign in to comment.