Repository: gakonst/ethers-rs
Pull request #1649 (2022-08-31 03:22:34)

chore(deps): bump md-5 from 0.10.1 to 0.10.2
Bumps [md-5](https://github.com/RustCrypto/hashes) from 0.10.1 to 0.10.2.
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/RustCrypto/hashes/commit/b74be34693d32996b6861806d221edfafa1cb4ff"><code>b74be34</code></a> Remove html_root_url (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/393">#393</a>)</li>
<li><a href="https://github.com/RustCrypto/hashes/commit/38ea35559cc4bf6c9574d6da3c8457668cb62f70"><code>38ea355</code></a> Release md5 v0.10.2, sha1 v0.10.2, sha2 v0.10.3, whirlpool v0.10.2 (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/392">#392</a>)</li>
<li><a href="https://github.com/RustCrypto/hashes/commit/4c7a3fa240369a1b51d8361a7e883ac202752e8a"><code>4c7a3fa</code></a> build(deps): bump cpufeatures from 0.2.3 to 0.2.4 (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/389">#389</a>)</li>
<li><a href="https://github.com/RustCrypto/hashes/commit/e5ad181cdb50f30393a2efe484029b6d53e11110"><code>e5ad181</code></a> Ignore <code>asm</code> feature on unsupported targets (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/388">#388</a>)</li>
<li><a href="https://github.com/RustCrypto/hashes/commit/79af27adf58ec48efe7f29b793e8522bdeb2ffce"><code>79af27a</code></a> Expand on DynDigest example in README (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/390">#390</a>)</li>
<li><a href="https://github.com/RustCrypto/hashes/commit/e5d93562432a4075f7cf576cfa16c952807f554e"><code>e5d9356</code></a> Update Cargo.lock</li>
<li><a href="https://github.com/RustCrypto/hashes/commit/457061f19b3538651aa7ef208ce6b04bfba65e61"><code>457061f</code></a> sha3 v0.10.2 (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/384">#384</a>)</li>
<li><a href="https://github.com/RustCrypto/hashes/commit/53d9671baf76133cd729ab9be37338ff2c50d973"><code>53d9671</code></a> Release fsb v0.1.2 (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/382">#382</a>)</li>
<li><a href="https://github.com/RustCrypto/hashes/commit/60ca9bafa7f894cda770b5cef3bfa43026bd8bab"><code>60ca9ba</code></a> fsb: resolve hashing errors (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/379">#379</a>)</li>
<li><a href="https://github.com/RustCrypto/hashes/commit/072287a9cf01b97b9953d927b71681aa350fd657"><code>072287a</code></a> Fix ripemd readme links (<a href="https://github-redirect.dependabot.com/RustCrypto/hashes/issues/378">#378</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/RustCrypto/hashes/compare/md2-v0.10.1...md-5-v0.10.2">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=md-5&package-manager=cargo&previous-version=0.10.1&new-version=0.10.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index c8a4ed59..922e4acd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1478,7 +1478,7 @@ dependencies = [
  "glob",
  "hex",
  "home",
- "md-5 0.10.1",
+ "md-5 0.10.2",
  "num_cpus",
  "once_cell",
  "path-slash",
@@ -2297,9 +2297,9 @@ dependencies = [
 
 [[package]]
 name = "md-5"
-version = "0.10.1"
+version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "658646b21e0b72f7866c7038ab086d3d5e1cd6271f060fd37defb241949d0582"
+checksum = "274fd6bd98a3c75c9515d9393b063099f60f9b47f09ee20a34fd76287fd017f4"
 dependencies = [
  "digest 0.10.3",
 ]
diff --git a/ethers-contract/ethers-contract-abigen/src/contract/methods.rs b/ethers-contract/ethers-contract-abigen/src/contract/methods.rs
index 58a2aaff..69f59ce9 100644
--- a/ethers-contract/ethers-contract-abigen/src/contract/methods.rs
+++ b/ethers-contract/ethers-contract-abigen/src/contract/methods.rs
@@ -1,8 +1,9 @@
 use std::collections::{btree_map::Entry, BTreeMap, HashMap};
 
 use super::{types, util, Context};
-use crate::contract::common::{
-    expand_data_struct, expand_data_tuple, expand_param_type, expand_params,
+use crate::{
+    contract::common::{expand_data_struct, expand_data_tuple, expand_param_type, expand_params},
+    util::can_derive_defaults,
 };
 use ethers_core::{
     abi::{Function, FunctionExt, Param, ParamType},
@@ -134,9 +135,20 @@ impl Context {
         // use the same derives as for events
         let derives = util::expand_derives(&self.event_derives);
 
+        // rust-std only derives default automatically for arrays len <= 32
+        // for large array types we skip derive(Default) <https://github.com/gakonst/ethers-rs/issues/1640>
+        let derive_default = if can_derive_defaults(&function.inputs) {
+            quote! {
+                #[derive(Default)]
+            }
+        } else {
+            quote! {}
+        };
+
         Ok(quote! {
             #abi_signature_doc
-            #[derive(Clone, Debug, Default, Eq, PartialEq, #ethers_contract::EthCall, #ethers_contract::EthDisplay, #derives)]
+            #[derive(Clone, Debug, Eq, PartialEq, #ethers_contract::EthCall, #ethers_contract::EthDisplay, #derives)]
+            #derive_default
             #[ethcall( name = #function_name, abi = #abi_signature )]
             pub #call_type_definition
         })
@@ -175,9 +187,20 @@ impl Context {
         // use the same derives as for events
         let derives = util::expand_derives(&self.event_derives);
 
+        // rust-std only derives default automatically for arrays len <= 32
+        // for large array types we skip derive(Default) <https://github.com/gakonst/ethers-rs/issues/1640>
+        let derive_default = if can_derive_defaults(&function.outputs) {
+            quote! {
+                #[derive(Default)]
+            }
+        } else {
+            quote! {}
+        };
+
         Ok(quote! {
             #abi_signature_doc
-            #[derive(Clone, Debug, Default, Eq, PartialEq, #ethers_contract::EthAbiType, #ethers_contract::EthAbiCodec, #derives)]
+            #[derive(Clone, Debug,Eq, PartialEq, #ethers_contract::EthAbiType, #ethers_contract::EthAbiCodec, #derives)]
+             #derive_default
             pub #return_type_definition
         })
     }
diff --git a/ethers-contract/ethers-contract-abigen/src/util.rs b/ethers-contract/ethers-contract-abigen/src/util.rs
index ec465104..5a2f775b 100644
--- a/ethers-contract/ethers-contract-abigen/src/util.rs
+++ b/ethers-contract/ethers-contract-abigen/src/util.rs
@@ -1,11 +1,12 @@
-use ethers_core::types::Address;
-use std::path::PathBuf;
-
+use ethers_core::{
+    abi::{Param, ParamType},
+    types::Address,
+};
 use eyre::Result;
 use inflector::Inflector;
 use proc_macro2::{Ident, Literal, Span, TokenStream};
 use quote::quote;
-
+use std::path::PathBuf;
 use syn::{Ident as SynIdent, Path};
 
 /// Expands a identifier string into a token.
@@ -185,10 +186,42 @@ pub fn json_files(root: impl AsRef<std::path::Path>) -> Vec<PathBuf> {
         .collect()
 }
 
+/// rust-std derives `Default` automatically only for arrays len <= 32
+///
+/// Returns whether the corresponding struct can derive `Default`
+pub fn can_derive_defaults(params: &[Param]) -> bool {
+    params.iter().map(|param| &param.kind).all(can_derive_default)
+}
+
+pub fn can_derive_default(param: &ParamType) -> bool {
+    const MAX_SUPPORTED_LEN: usize = 32;
+    match param {
+        ParamType::FixedBytes(len) => *len <= MAX_SUPPORTED_LEN,
+        ParamType::FixedArray(ty, len) => {
+            if *len > MAX_SUPPORTED_LEN {
+                false
+            } else {
+                can_derive_default(ty)
+            }
+        }
+        ParamType::Tuple(params) => params.iter().all(can_derive_default),
+        _ => true,
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
 
+    #[test]
+    fn can_detect_non_default() {
+        let param = ParamType::FixedArray(Box::new(ParamType::Uint(64)), 128);
+        assert!(!can_derive_default(&param));
+
+        let param = ParamType::FixedArray(Box::new(ParamType::Uint(64)), 32);
+        assert!(can_derive_default(&param));
+    }
+
     #[test]
     fn can_resolve_path() {
         let raw = "./$ENV_VAR";
diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml
index b8bd4b31..637b8cb8 100644
--- a/ethers-solc/Cargo.toml
+++ b/ethers-solc/Cargo.toml
@@ -23,7 +23,7 @@ tokio = { version = "1.18", default-features = false, features = ["rt"] }
 futures-util = { version = "^0.3", optional = true }
 once_cell = "1.13.1"
 regex = "1.6.0"
-md-5 = "0.10.1"
+md-5 = "0.10.2"
 thiserror = "1.0"
 hex = "0.4.3"
 colored = "2.0.0"


Test patch:
diff --git a/ethers-contract/tests/it/abigen.rs b/ethers-contract/tests/it/abigen.rs
index 273498d0..2d924be3 100644
--- a/ethers-contract/tests/it/abigen.rs
+++ b/ethers-contract/tests/it/abigen.rs
@@ -11,10 +11,14 @@ use ethers_middleware::SignerMiddleware;
 use ethers_providers::{MockProvider, Provider};
 use ethers_signers::{LocalWallet, Signer};
 use ethers_solc::Solc;
-use std::{convert::TryFrom, sync::Arc};
+use std::{
+    convert::{TryFrom, TryInto},
+    sync::Arc,
+};
 
 fn assert_codec<T: AbiDecode + AbiEncode>() {}
 fn assert_tokenizeable<T: Tokenizable>() {}
+fn assert_call<T: AbiEncode + AbiDecode + Default + Tokenizable>() {}
 
 #[test]
 fn can_gen_human_readable() {
@@ -237,6 +241,9 @@ fn can_gen_human_readable_with_structs() {
     assert_eq!(contract_call, decoded_enum);
     assert_eq!(contract_call, call.into());
     assert_eq!(encoded_call, contract_call.encode());
+
+    assert_call::<BarCall>();
+    assert_call::<YeetCall>();
 }
 
 #[test]
@@ -301,6 +308,10 @@ fn can_handle_overloaded_functions() {
     let _contract_call = SimpleContractCalls::SetValue0(call);
     let call = SetValue1Call("message".to_string(), "message".to_string());
     let _contract_call = SimpleContractCalls::SetValue1(call);
+
+    assert_call::<SetValue0Call>();
+    assert_call::<SetValue1Call>();
+    assert_call::<GetValueWithOtherValueAndAddrCall>();
 }
 
 #[test]
@@ -695,3 +706,17 @@ fn gen_complex_function() {
 fn can_gen_large_tuple_types() {
     abigen!(LargeTuple, "./tests/solidity-contracts/large_tuple.json");
 }
+
+#[test]
+fn can_gen_large_tuple_array() {
+    abigen!(LargeTuple, "./tests/solidity-contracts/large-array.json");
+
+    impl Default for CallWithLongArrayCall {
+        fn default() -> Self {
+            Self { long_array: [0; 128] }
+        }
+    }
+
+    let _call = CallWithLongArrayCall::default();
+    assert_call::<CallWithLongArrayCall>();
+}
diff --git a/ethers-contract/tests/solidity-contracts/large-array.json b/ethers-contract/tests/solidity-contracts/large-array.json
new file mode 100644
index 00000000..8d681240
--- /dev/null
+++ b/ethers-contract/tests/solidity-contracts/large-array.json
@@ -0,0 +1,15 @@
+[
+  {
+    "inputs": [
+      {
+        "internalType": "uint64[128]",
+        "name": "longArray",
+        "type": "uint64[128]"
+      }
+    ],
+    "name": "callWithLongArray",
+    "outputs": [],
+    "stateMutability": "view",
+    "type": "function"
+  }
+]
\ No newline at end of file