Skip to content

Commit

Permalink
fix rust-ethereum#297 add name and internal type information to Param…
Browse files Browse the repository at this point in the history
…Type::Tuple
  • Loading branch information
al8n committed Jun 28, 2023
1 parent a148a4a commit e26d996
Show file tree
Hide file tree
Showing 12 changed files with 217 additions and 104 deletions.
46 changes: 28 additions & 18 deletions ethabi/src/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ fn decode_param(param: &ParamType, data: &[u8], offset: usize, validate: bool) -
let len = t.len();
let mut tokens = Vec::with_capacity(len);
for param in t {
let res = decode_param(param, tail, new_offset, validate)?;
let res = decode_param(&param.kind, tail, new_offset, validate)?;
new_offset = res.new_offset;
tokens.push(res.token);
}
Expand Down Expand Up @@ -300,9 +300,11 @@ mod tests {
let uint = Token::Uint([0x11u8; 32].into());
let tuple = Token::Tuple(vec![address1, address2, uint]);
let expected = vec![tuple];
let decoded =
decode(&[ParamType::Tuple(vec![ParamType::Address, ParamType::Address, ParamType::Uint(32)])], &encoded)
.unwrap();
let decoded = decode(
&[ParamType::Tuple(vec![ParamType::Address.into(), ParamType::Address.into(), ParamType::Uint(32).into()])],
&encoded,
)
.unwrap();
assert_eq!(decoded, expected);
}

Expand All @@ -322,7 +324,8 @@ mod tests {
let string1 = Token::String("gavofyork".to_owned());
let string2 = Token::String("gavofyork".to_owned());
let tuple = Token::Tuple(vec![string1, string2]);
let decoded = decode(&[ParamType::Tuple(vec![ParamType::String, ParamType::String])], &encoded).unwrap();
let decoded =
decode(&[ParamType::Tuple(vec![ParamType::String.into(), ParamType::String.into()])], &encoded).unwrap();
let expected = vec![tuple];
assert_eq!(decoded, expected);
}
Expand Down Expand Up @@ -368,14 +371,15 @@ mod tests {
let expected = vec![outer_tuple];
let decoded = decode(
&[ParamType::Tuple(vec![
ParamType::String,
ParamType::Bool,
ParamType::String,
ParamType::String.into(),
ParamType::Bool.into(),
ParamType::String.into(),
ParamType::Tuple(vec![
ParamType::String,
ParamType::String,
ParamType::Tuple(vec![ParamType::String, ParamType::String]),
]),
ParamType::String.into(),
ParamType::String.into(),
ParamType::Tuple(vec![ParamType::String.into(), ParamType::String.into()]).into(),
])
.into(),
])],
&encoded,
)
Expand Down Expand Up @@ -403,7 +407,12 @@ mod tests {
let tuple = Token::Tuple(vec![uint, string, address1, address2]);
let expected = vec![tuple];
let decoded = decode(
&[ParamType::Tuple(vec![ParamType::Uint(32), ParamType::String, ParamType::Address, ParamType::Address])],
&[ParamType::Tuple(vec![
ParamType::Uint(32).into(),
ParamType::String.into(),
ParamType::Address.into(),
ParamType::Address.into(),
])],
&encoded,
)
.unwrap();
Expand Down Expand Up @@ -440,7 +449,7 @@ mod tests {
let decoded = decode(
&[
ParamType::Address,
ParamType::Tuple(vec![ParamType::Bool, ParamType::String, ParamType::String]),
ParamType::Tuple(vec![ParamType::Bool.into(), ParamType::String.into(), ParamType::String.into()]),
ParamType::Address,
ParamType::Address,
ParamType::Bool,
Expand Down Expand Up @@ -475,7 +484,7 @@ mod tests {
let decoded = decode(
&[
ParamType::Address,
ParamType::Tuple(vec![ParamType::Address, ParamType::Bool, ParamType::Bool]),
ParamType::Tuple(vec![ParamType::Address.into(), ParamType::Bool.into(), ParamType::Bool.into()]),
ParamType::Address,
ParamType::Address,
],
Expand Down Expand Up @@ -654,14 +663,15 @@ ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
inputs: vec![
Param {
name: "c".to_string(),
kind: Array(Box::new(Tuple(vec![Uint(256), Uint(256)]))),
kind: Array(Box::new(Tuple(vec![Uint(256).into(), Uint(256).into()]))),
internal_type: None,
},
Param {
name: "d".to_string(),
kind: Array(Box::new(Tuple(vec![
Uint(256),
Array(Box::new(Tuple(vec![Uint(256), Array(Box::new(ParamType::String))]))),
Uint(256).into(),
Array(Box::new(Tuple(vec![Uint(256).into(), Array(Box::new(ParamType::String)).into()])))
.into(),
]))),
internal_type: None,
},
Expand Down
2 changes: 1 addition & 1 deletion ethabi/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ mod tests {
inputs: vec![
EventParam {
name: "tuple".into(),
kind: ParamType::Tuple(vec![ParamType::Address, ParamType::Address]),
kind: ParamType::Tuple(vec![ParamType::Address.into(), ParamType::Address.into()]),
indexed: false,
},
EventParam { name: "addr".into(), kind: ParamType::Address, indexed: true },
Expand Down
32 changes: 22 additions & 10 deletions ethabi/src/event_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,10 @@ mod tests {
deserialized,
EventParam {
name: "foo".to_owned(),
kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]),
kind: ParamType::Tuple(vec![
ParamType::Uint(48).into(),
ParamType::Tuple(vec![ParamType::Address.into()]).into()
]),
indexed: true,
}
);
Expand Down Expand Up @@ -225,16 +228,25 @@ mod tests {
EventParam {
name: "LogTaskSubmitted".to_owned(),
kind: ParamType::Tuple(vec![
ParamType::Uint(256),
ParamType::Address,
ParamType::Tuple(vec![ParamType::Address, ParamType::Address]),
ParamType::Uint(256),
ParamType::Uint(256).into(),
ParamType::Address.into(),
ParamType::Tuple(vec![ParamType::Address.into(), ParamType::Address.into()]).into(),
ParamType::Uint(256).into(),
ParamType::Array(Box::new(ParamType::Tuple(vec![
ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address, ParamType::Bytes,]))),
ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address, ParamType::Uint(256)]))),
ParamType::Uint(256),
]))),
ParamType::Uint(256),
ParamType::Array(Box::new(ParamType::Tuple(vec![
ParamType::Address.into(),
ParamType::Bytes.into(),
])))
.into(),
ParamType::Array(Box::new(ParamType::Tuple(vec![
ParamType::Address.into(),
ParamType::Uint(256).into()
])))
.into(),
ParamType::Uint(256).into(),
])))
.into(),
ParamType::Uint(256).into(),
]),
indexed: false,
}
Expand Down
20 changes: 16 additions & 4 deletions ethabi/src/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ mod tests {
use super::Operation;
#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
use crate::{tests::assert_ser_de, Event, EventParam, Function, Param, ParamType, StateMutability};
use crate::{tests::assert_ser_de, Event, EventParam, Function, Param, ParamType, StateMutability, TupleParam};

#[test]
fn operation() {
Expand Down Expand Up @@ -119,9 +119,21 @@ mod tests {
EventParam {
name: "b".to_owned(),
kind: ParamType::Array(Box::new(ParamType::Tuple(vec![
ParamType::Address,
ParamType::Uint(256),
ParamType::Bytes
TupleParam {
name: Some("to".into()),
kind: ParamType::Address,
internal_type: Some("address".into())
},
TupleParam {
name: Some("value".into()),
kind: ParamType::Uint(256),
internal_type: Some("uint256".into())
},
TupleParam {
name: Some("data".into()),
kind: ParamType::Bytes,
internal_type: Some("bytes".into())
}
]))),
indexed: false
},
Expand Down
67 changes: 47 additions & 20 deletions ethabi/src/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl Serialize for Param {
}

#[cfg(feature = "serde")]
pub(crate) fn inner_tuple_mut(mut param: &mut ParamType) -> Option<&mut Vec<ParamType>> {
pub(crate) fn inner_tuple_mut(mut param: &mut ParamType) -> Option<&mut Vec<TupleParam>> {
loop {
match param {
ParamType::Array(inner) => param = inner.as_mut(),
Expand All @@ -135,7 +135,7 @@ pub(crate) fn inner_tuple_mut(mut param: &mut ParamType) -> Option<&mut Vec<Para
}

#[cfg(feature = "serde")]
pub(crate) fn inner_tuple(mut param: &ParamType) -> Option<&Vec<ParamType>> {
pub(crate) fn inner_tuple(mut param: &ParamType) -> Option<&Vec<TupleParam>> {
loop {
match param {
ParamType::Array(inner) => param = inner.as_ref(),
Expand All @@ -153,13 +153,13 @@ pub(crate) fn set_tuple_components<Error: serde::de::Error>(
) -> Result<(), Error> {
if let Some(inner_tuple_mut) = inner_tuple_mut(kind) {
let tuple_params = components.ok_or_else(|| Error::missing_field("components"))?;
inner_tuple_mut.extend(tuple_params.into_iter().map(|param| param.kind))
inner_tuple_mut.extend(tuple_params.into_iter())
}
Ok(())
}

#[cfg(feature = "serde")]
pub(crate) struct SerializeableParamVec<'a>(pub(crate) &'a [ParamType]);
pub(crate) struct SerializeableParamVec<'a>(pub(crate) &'a [TupleParam]);

#[cfg(feature = "serde")]
impl Serialize for SerializeableParamVec<'_> {
Expand All @@ -176,7 +176,7 @@ impl Serialize for SerializeableParamVec<'_> {
}

#[cfg(feature = "serde")]
pub(crate) struct SerializeableParam<'a>(pub(crate) &'a ParamType);
pub(crate) struct SerializeableParam<'a>(pub(crate) &'a TupleParam);

#[cfg(feature = "serde")]
impl Serialize for SerializeableParam<'_> {
Expand All @@ -185,8 +185,14 @@ impl Serialize for SerializeableParam<'_> {
S: Serializer,
{
let mut map = serializer.serialize_map(None)?;
map.serialize_entry("type", &Writer::write_for_abi(self.0, false))?;
if let Some(inner_tuple) = inner_tuple(self.0) {
map.serialize_entry("type", &Writer::write_for_abi(&self.0.kind, false))?;
if let Some(ref name) = self.0.name {
map.serialize_entry("name", &name)?;
}
if let Some(ref internal_type) = self.0.internal_type {
map.serialize_entry("internalType", &internal_type)?;
}
if let Some(inner_tuple) = inner_tuple(&self.0.kind) {
map.serialize_key("components")?;
map.serialize_value(&SerializeableParamVec(inner_tuple))?;
}
Expand All @@ -200,7 +206,7 @@ mod tests {
use crate::no_std_prelude::*;
use crate::{
tests::{assert_json_eq, assert_ser_de},
Param, ParamType,
Param, ParamType, TupleParam,
};

#[test]
Expand Down Expand Up @@ -265,7 +271,10 @@ mod tests {
deserialized,
Param {
name: "foo".to_owned(),
kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]),
kind: ParamType::Tuple(vec![
ParamType::Uint(48).into(),
ParamType::Tuple(vec![ParamType::Address.into()]).into()
]),
internal_type: None
}
);
Expand Down Expand Up @@ -300,7 +309,10 @@ mod tests {
deserialized,
Param {
name: "foo".to_owned(),
kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]),
kind: ParamType::Tuple(vec![
ParamType::Uint(48).into(),
ParamType::Tuple(vec![ParamType::Address.into()]).into()
]),
internal_type: Some("struct Pairing.G1Point[]".to_string())
}
);
Expand Down Expand Up @@ -337,9 +349,20 @@ mod tests {
deserialized,
Param {
name: "foo".to_owned(),
kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]),
kind: ParamType::Tuple(vec![
TupleParam { name: Some("amount".into()), kind: ParamType::Uint(48), internal_type: None },
TupleParam {
name: Some("things".into()),
kind: ParamType::Tuple(vec![TupleParam {
name: Some("baseTupleParam".into()),
kind: ParamType::Address,
internal_type: None
}]),
internal_type: None
}
]),
internal_type: None
}
},
);

assert_ser_de(&deserialized);
Expand Down Expand Up @@ -370,9 +393,9 @@ mod tests {
Param {
name: "foo".to_owned(),
kind: ParamType::Array(Box::new(ParamType::Tuple(vec![
ParamType::Uint(48),
ParamType::Address,
ParamType::Address
ParamType::Uint(48).into(),
ParamType::Address.into(),
ParamType::Address.into()
]))),
internal_type: None
}
Expand Down Expand Up @@ -402,8 +425,8 @@ mod tests {
Param {
name: "foo".to_owned(),
kind: ParamType::Array(Box::new(ParamType::Array(Box::new(ParamType::Tuple(vec![
ParamType::Uint(8),
ParamType::Uint(16),
ParamType::Uint(8).into(),
ParamType::Uint(16).into(),
]))))),
internal_type: None
}
Expand Down Expand Up @@ -437,7 +460,11 @@ mod tests {
Param {
name: "foo".to_owned(),
kind: ParamType::FixedArray(
Box::new(ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Address, ParamType::Address])),
Box::new(ParamType::Tuple(vec![
ParamType::Uint(48).into(),
ParamType::Address.into(),
ParamType::Address.into()
])),
2
),
internal_type: None
Expand Down Expand Up @@ -479,8 +506,8 @@ mod tests {
Param {
name: "foo".to_owned(),
kind: ParamType::Tuple(vec![
ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address]))),
ParamType::FixedArray(Box::new(ParamType::Tuple(vec![ParamType::Address])), 42,)
ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address.into()]))).into(),
ParamType::FixedArray(Box::new(ParamType::Tuple(vec![ParamType::Address.into()])), 42,).into(),
]),
internal_type: None
}
Expand Down
5 changes: 3 additions & 2 deletions ethabi/src/param_type/param_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use core::fmt;
use super::Writer;
#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
use crate::TupleParam;

/// Function and event param types.
#[derive(Debug, Clone, PartialEq)]
Expand All @@ -36,7 +37,7 @@ pub enum ParamType {
/// Array with fixed size.
FixedArray(Box<ParamType>, usize),
/// Tuple containing different types
Tuple(Vec<ParamType>),
Tuple(Vec<TupleParam>),
}

impl fmt::Display for ParamType {
Expand All @@ -62,7 +63,7 @@ impl ParamType {
match self {
ParamType::Bytes | ParamType::String | ParamType::Array(_) => true,
ParamType::FixedArray(elem_type, _) => elem_type.is_dynamic(),
ParamType::Tuple(params) => params.iter().any(|param| param.is_dynamic()),
ParamType::Tuple(params) => params.iter().any(|param| param.kind.is_dynamic()),
_ => false,
}
}
Expand Down

0 comments on commit e26d996

Please sign in to comment.