fix(abigen): handle all struct field types (#2289)

* fix(abigen): handle all struct field types

* typo
This commit is contained in:
DaniPopes 2023-03-21 18:38:23 +01:00 committed by GitHub
parent f7a066e700
commit 944ed05556
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 23 deletions

View File

@ -263,14 +263,15 @@ fn _derive_builtin_traits_struct(
}
}
/// Recurses on the type until it reaches the struct tuple `ParamType`.
fn get_struct_params<'a>(s_ty: &StructFieldType, ty: &'a ParamType) -> &'a [ParamType] {
match (s_ty, ty) {
(StructFieldType::Type(_), ParamType::Tuple(params)) => params,
(StructFieldType::Array(s_ty), ParamType::Array(ty)) => get_struct_params(s_ty, ty),
(StructFieldType::FixedArray(s_ty, _), ParamType::FixedArray(ty, _)) => {
get_struct_params(s_ty, ty)
}
_ => unreachable!(),
(_, ParamType::Tuple(params)) => params,
(
StructFieldType::Array(s_ty) | StructFieldType::FixedArray(s_ty, _),
ParamType::Array(param) | ParamType::FixedArray(param, _),
) => get_struct_params(s_ty, param),
_ => unreachable!("Unhandled struct field: {s_ty:?} | {ty:?}"),
}
}

View File

@ -8,7 +8,7 @@ use ethers_core::{
};
use ethers_providers::{MockProvider, Provider};
use ethers_solc::Solc;
use std::sync::Arc;
use std::{fmt::Debug, hash::Hash, sync::Arc};
const fn assert_codec<T: AbiDecode + AbiEncode>() {}
const fn assert_tokenizeable<T: Tokenizable>() {}
@ -16,7 +16,12 @@ const fn assert_call<T: AbiEncode + AbiDecode + Default + Tokenizable>() {}
const fn assert_event<T: EthEvent>() {}
const fn assert_clone<T: Clone>() {}
const fn assert_default<T: Default>() {}
const fn assert_builtin<T: std::fmt::Debug + PartialEq + Eq + std::hash::Hash>() {}
const fn assert_builtin<T: Debug + PartialEq + Eq + Hash>() {}
const fn assert_struct<T>()
where
T: AbiEncode + AbiDecode + Tokenizable + Clone + Default + Debug + PartialEq + Eq + Hash,
{
}
#[test]
fn can_generate_human_readable() {
@ -25,7 +30,7 @@ fn can_generate_human_readable() {
r#"[
event ValueChanged(address indexed author, string oldValue, string newValue)
]"#,
event_derives(serde::Deserialize, serde::Serialize)
derives(serde::Deserialize, serde::Serialize)
);
assert_eq!("ValueChanged", ValueChangedFilter::name());
assert_eq!("ValueChanged(address,string,string)", ValueChangedFilter::abi_signature());
@ -43,13 +48,13 @@ fn can_generate_human_readable_multiple() {
r#"[
event ValueChanged1(address indexed author, string oldValue, string newValue)
]"#,
event_derives(serde::Deserialize, serde::Serialize);
derives(serde::Deserialize, serde::Serialize);
SimpleContract2,
r#"[
event ValueChanged2(address indexed author, string oldValue, string newValue)
]"#,
event_derives(serde::Deserialize, serde::Serialize)
derives(serde::Deserialize, serde::Serialize)
);
assert_eq!("ValueChanged1", ValueChanged1Filter::name());
assert_eq!("ValueChanged1(address,string,string)", ValueChanged1Filter::abi_signature());
@ -66,7 +71,7 @@ fn can_generate_structs_readable() {
struct Addresses {address[] addr; string s;}
event ValueChanged(Value indexed old, Value newValue, Addresses _a)
]"#,
event_derives(serde::Deserialize, serde::Serialize)
derives(serde::Deserialize, serde::Serialize)
);
let addr = Addresses {
addr: vec!["eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee".parse().unwrap()],
@ -97,7 +102,7 @@ fn can_generate_structs_with_arrays_readable() {
struct Addresses {address[] addr; string s;}
event ValueChanged(Value indexed old, Value newValue, Addresses[] _a)
]"#,
event_derives(serde::Deserialize, serde::Serialize)
derives(serde::Deserialize, serde::Serialize)
);
assert_eq!(
"ValueChanged((address,string),(address,string),(address[],string)[])",
@ -113,15 +118,32 @@ fn can_generate_internal_structs() {
abigen!(
VerifierContract,
"ethers-contract/tests/solidity-contracts/verifier_abi.json",
event_derives(serde::Deserialize, serde::Serialize)
derives(serde::Deserialize, serde::Serialize)
);
assert_tokenizeable::<VerifyingKey>();
assert_tokenizeable::<G1Point>();
assert_tokenizeable::<G2Point>();
assert_struct::<VerifyingKey>();
assert_struct::<G1Point>();
assert_struct::<G2Point>();
}
assert_codec::<VerifyingKey>();
assert_codec::<G1Point>();
assert_codec::<G2Point>();
#[test]
fn can_generate_internal_structs_2() {
abigen!(Beefy, "./tests/solidity-contracts/BeefyV1.json");
assert_struct::<AuthoritySetCommitment>();
assert_struct::<BeefyConsensusState>();
assert_struct::<ProofNode>();
assert_struct::<BeefyConsensusProof>();
let s =
AuthoritySetCommitment { id: U256::from(1), len: U256::from(2), root: Default::default() };
let _encoded = AbiEncode::encode(s.clone());
let s = BeefyConsensusState { current_authority_set: s, ..Default::default() };
let _encoded = AbiEncode::encode(s);
// tuple[][]
let node = ProofNode::default();
let s = BeefyConsensusProof { authorities_proof: vec![vec![node; 2]; 2], ..Default::default() };
let _encoded = AbiEncode::encode(s);
}
#[test]
@ -133,11 +155,11 @@ fn can_generate_internal_structs_multiple() {
abigen!(
VerifierContract,
"ethers-contract/tests/solidity-contracts/verifier_abi.json",
event_derives(serde::Deserialize, serde::Serialize);
derives(serde::Deserialize, serde::Serialize);
MyOtherVerifierContract,
"ethers-contract/tests/solidity-contracts/verifier_abi.json",
event_derives(serde::Deserialize, serde::Serialize);
derives(serde::Deserialize, serde::Serialize);
);
}
assert_tokenizeable::<VerifyingKey>();
@ -207,7 +229,7 @@ fn can_generate_human_readable_with_structs() {
function bar(uint256 x, uint256 y, address addr)
yeet(uint256,uint256,address)
]"#,
event_derives(serde::Deserialize, serde::Serialize)
derives(serde::Deserialize, serde::Serialize)
);
assert_tokenizeable::<Foo>();
assert_codec::<Foo>();

View File

@ -0,0 +1 @@
[{"inputs":[{"internalType":"contract ISMPHost","name":"host","type":"address"},{"components":[{"internalType":"uint256","name":"latestHeight","type":"uint256"},{"internalType":"uint256","name":"latestTimestamp","type":"uint256"},{"internalType":"uint256","name":"frozenHeight","type":"uint256"},{"internalType":"bytes32","name":"latestHeadsRoot","type":"bytes32"},{"internalType":"uint256","name":"beefyActivationBlock","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"len","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"internalType":"struct AuthoritySetCommitment","name":"currentAuthoritySet","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"len","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"internalType":"struct AuthoritySetCommitment","name":"nextAuthoritySet","type":"tuple"}],"internalType":"struct BeefyConsensusState","name":"trustedState","type":"tuple"},{"components":[{"components":[{"components":[{"components":[{"internalType":"bytes2","name":"id","type":"bytes2"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Payload[]","name":"payload","type":"tuple[]"},{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"validatorSetId","type":"uint256"}],"internalType":"struct Commitment","name":"commitment","type":"tuple"},{"components":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"authorityIndex","type":"uint256"}],"internalType":"struct Signature[]","name":"signatures","type":"tuple[]"}],"internalType":"struct SignedCommitment","name":"signedCommitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"version","type":"uint256"},{"internalType":"uint256","name":"parentNumber","type":"uint256"},{"internalType":"bytes32","name":"parentHash","type":"bytes32"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"len","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"internalType":"struct AuthoritySetCommitment","name":"nextAuthoritySet","type":"tuple"},{"internalType":"bytes32","name":"extra","type":"bytes32"},{"internalType":"uint256","name":"kIndex","type":"uint256"}],"internalType":"struct BeefyMmrLeaf","name":"latestMmrLeaf","type":"tuple"},{"internalType":"bytes32[]","name":"mmrProof","type":"bytes32[]"},{"components":[{"internalType":"uint256","name":"k_index","type":"uint256"},{"internalType":"bytes32","name":"node","type":"bytes32"}],"internalType":"struct ProofNode[][]","name":"authoritiesProof","type":"tuple[][]"},{"internalType":"bytes","name":"header","type":"bytes"},{"internalType":"uint256","name":"headsIndex","type":"uint256"},{"internalType":"bytes[]","name":"extrinsicProof","type":"bytes[]"},{"internalType":"bytes","name":"timestampExtrinsic","type":"bytes"}],"internalType":"struct BeefyConsensusProof","name":"proof","type":"tuple"}],"name":"VerifyConsensus","outputs":[{"components":[{"internalType":"uint256","name":"latestHeight","type":"uint256"},{"internalType":"uint256","name":"latestTimestamp","type":"uint256"},{"internalType":"uint256","name":"frozenHeight","type":"uint256"},{"internalType":"bytes32","name":"latestHeadsRoot","type":"bytes32"},{"internalType":"uint256","name":"beefyActivationBlock","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"len","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"internalType":"struct AuthoritySetCommitment","name":"currentAuthoritySet","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"len","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"internalType":"struct AuthoritySetCommitment","name":"nextAuthoritySet","type":"tuple"}],"internalType":"struct BeefyConsensusState","name":"","type":"tuple"},{"components":[{"components":[{"internalType":"uint256","name":"stateMachineId","type":"uint256"},{"internalType":"uint256","name":"height","type":"uint256"}],"internalType":"struct StateMachineHeight","name":"height","type":"tuple"},{"components":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"bytes32","name":"commitment","type":"bytes32"}],"internalType":"struct StateCommitment","name":"commitment","type":"tuple"}],"internalType":"struct IntermediateState","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"}]

View File

@ -903,6 +903,7 @@ impl Node {
///
/// This returns an error if the file's version is invalid semver, or is not available such as
/// 0.8.20, if the highest available version is `0.8.19`
#[allow(dead_code)]
fn check_available_version(
&self,
all_versions: &[SolcVersion],