fix(abigen): use abi signature attribute if provided (#1409)

This commit is contained in:
Matthias Seitz 2022-06-23 08:53:24 +02:00 committed by GitHub
parent 3d77f44066
commit 2524663674
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 28 deletions

View File

@ -117,7 +117,7 @@ impl Context {
let function_name = &function.name; let function_name = &function.name;
let abi_signature = function.abi_signature(); let abi_signature = function.abi_signature();
let doc = format!( let doc = format!(
"Container type for all input parameters for the `{}`function with signature `{}` and selector `{:?}`", "Container type for all input parameters for the `{}` function with signature `{}` and selector `{:?}`",
function.name, function.name,
abi_signature, abi_signature,
function.selector() function.selector()

View File

@ -27,21 +27,24 @@ pub(crate) fn derive_eth_call_impl(input: DeriveInput) -> TokenStream {
fun fun
} else { } else {
// try as tuple // try as tuple
if let Some(inputs) = Reader::read( let raw_function_signature = src.trim_start_matches("function ").trim_start();
src.trim_start_matches("function ") if let Some(inputs) =
.trim_start() Reader::read(raw_function_signature.trim_start_matches(&function_call_name))
.trim_start_matches(&function_call_name), .ok()
) .and_then(|param| match param {
.ok() ParamType::Tuple(params) => Some(
.and_then(|param| match param { params
ParamType::Tuple(params) => Some( .into_iter()
params .map(|kind| Param {
.into_iter() name: "".to_string(),
.map(|kind| Param { name: "".to_string(), kind, internal_type: None }) kind,
.collect(), internal_type: None,
), })
_ => None, .collect(),
}) { ),
_ => None,
})
{
#[allow(deprecated)] #[allow(deprecated)]
Function { Function {
name: function_call_name.clone(), name: function_call_name.clone(),
@ -52,7 +55,11 @@ pub(crate) fn derive_eth_call_impl(input: DeriveInput) -> TokenStream {
} }
} else { } else {
// try to determine the abi by using its fields at runtime // try to determine the abi by using its fields at runtime
return match derive_trait_impls_with_abi_type(&input, &function_call_name) { return match derive_trait_impls_with_abi_type(
&input,
&function_call_name,
Some(raw_function_signature),
) {
Ok(derived) => derived, Ok(derived) => derived,
Err(err) => { Err(err) => {
Error::new(span, format!("Unable to determine ABI for `{}` : {}", src, err)) Error::new(span, format!("Unable to determine ABI for `{}` : {}", src, err))
@ -63,7 +70,7 @@ pub(crate) fn derive_eth_call_impl(input: DeriveInput) -> TokenStream {
} }
} else { } else {
// try to determine the abi by using its fields at runtime // try to determine the abi by using its fields at runtime
return match derive_trait_impls_with_abi_type(&input, &function_call_name) { return match derive_trait_impls_with_abi_type(&input, &function_call_name, None) {
Ok(derived) => derived, Ok(derived) => derived,
Err(err) => err.to_compile_error(), Err(err) => err.to_compile_error(),
} }
@ -178,11 +185,16 @@ fn derive_decode_impl(datatypes_array: TokenStream) -> TokenStream {
fn derive_trait_impls_with_abi_type( fn derive_trait_impls_with_abi_type(
input: &DeriveInput, input: &DeriveInput,
function_call_name: &str, function_call_name: &str,
abi_signature: Option<&str>,
) -> Result<TokenStream, Error> { ) -> Result<TokenStream, Error> {
let abi_signature = let abi_signature = if let Some(abi) = abi_signature {
utils::derive_abi_signature_with_abi_type(input, function_call_name, "EthCall")?; quote! {#abi}
} else {
utils::derive_abi_signature_with_abi_type(input, function_call_name, "EthCall")?
};
let abi_signature = quote! { let abi_signature = quote! {
::std::borrow::Cow::Owned(#abi_signature) #abi_signature.into()
}; };
let decode_impl = derive_decode_impl_with_abi_type(input)?; let decode_impl = derive_decode_impl_with_abi_type(input)?;
Ok(derive_trait_impls(input, function_call_name, abi_signature, None, decode_impl)) Ok(derive_trait_impls(input, function_call_name, abi_signature, None, decode_impl))

View File

@ -590,3 +590,14 @@ async fn can_send_struct_param() {
let logs: Vec<NewPointFilter> = contract.event().from_block(0u64).query().await.unwrap(); let logs: Vec<NewPointFilter> = contract.event().from_block(0u64).query().await.unwrap();
assert_eq!(logs.len(), 1); assert_eq!(logs.len(), 1);
} }
#[test]
fn can_gen_seaport() {
abigen!(Seaport, "./tests/solidity-contracts/seaport.json");
assert_eq!(
FulfillAdvancedOrderCall::abi_signature(),
"fulfillAdvancedOrder(((address,address,(uint8,address,uint256,uint256,uint256)[],(uint8,address,uint256,uint256,uint256,address)[],uint8,uint256,uint256,bytes32,uint256,bytes32,uint256),uint120,uint120,bytes,bytes),(uint256,uint8,uint256,uint256,bytes32[])[],bytes32,address)"
);
assert_eq!(hex::encode(FulfillAdvancedOrderCall::selector()), "e7acab24");
}

View File

@ -17,7 +17,7 @@ struct ValueChanged {
new_value: String, new_value: String,
} }
#[derive(Debug, Clone, PartialEq, EthAbiType)] #[derive(Debug, Clone, PartialEq, Eq, EthAbiType)]
struct ValueChangedWrapper { struct ValueChangedWrapper {
inner: ValueChanged, inner: ValueChanged,
msg: String, msg: String,
@ -26,10 +26,10 @@ struct ValueChangedWrapper {
#[derive(Debug, Clone, PartialEq, Eq, EthAbiType)] #[derive(Debug, Clone, PartialEq, Eq, EthAbiType)]
struct ValueChangedTuple(Address, Address, String, String); struct ValueChangedTuple(Address, Address, String, String);
#[derive(Debug, Clone, PartialEq, EthAbiType)] #[derive(Debug, Clone, PartialEq, Eq, EthAbiType)]
struct ValueChangedTupleWrapper(ValueChangedTuple, String); struct ValueChangedTupleWrapper(ValueChangedTuple, String);
#[derive(Debug, Clone, PartialEq, EthAbiType)] #[derive(Debug, Clone, PartialEq, Eq, EthAbiType)]
struct ValueChangedVecWrapper { struct ValueChangedVecWrapper {
inner: Vec<ValueChanged>, inner: Vec<ValueChanged>,
} }
@ -210,7 +210,7 @@ fn can_set_eth_abi_attribute() {
msg: String, msg: String,
} }
#[derive(Debug, PartialEq, EthEvent)] #[derive(Debug, PartialEq, Eq, EthEvent)]
#[ethevent(abi = "ValueChangedEvent(address,(address,string),string)")] #[ethevent(abi = "ValueChangedEvent(address,(address,string),string)")]
struct ValueChangedEvent { struct ValueChangedEvent {
old_author: Address, old_author: Address,
@ -223,7 +223,7 @@ fn can_set_eth_abi_attribute() {
ValueChangedEvent::abi_signature() ValueChangedEvent::abi_signature()
); );
#[derive(Debug, PartialEq, EthEvent)] #[derive(Debug, PartialEq, Eq, EthEvent)]
#[ethevent( #[ethevent(
name = "ValueChangedEvent", name = "ValueChangedEvent",
abi = "ValueChangedEvent(address,(address,string),string)" abi = "ValueChangedEvent(address,(address,string),string)"
@ -452,7 +452,7 @@ fn can_derive_ethcall_with_nested_structs() {
msg: String, msg: String,
} }
#[derive(Debug, PartialEq, EthCall)] #[derive(Debug, PartialEq, Eq, EthCall)]
#[ethcall(name = "foo", abi = "foo(address,(address,string),string)")] #[ethcall(name = "foo", abi = "foo(address,(address,string),string)")]
struct FooCall { struct FooCall {
old_author: Address, old_author: Address,

View File

@ -673,6 +673,6 @@ mod eth_tests {
"Encoded value does not match!" "Encoded value does not match!"
); );
assert_eq!(verify, true, "typed data signature failed!"); assert!(verify, "typed data signature failed!");
} }
} }

File diff suppressed because one or more lines are too long