From e37a7daee6a9083858d9dbc1c7a5451adbc4c2fd Mon Sep 17 00:00:00 2001 From: christn Date: Thu, 4 Jan 2024 09:31:49 +1100 Subject: [PATCH] Fix deserialization error resulting from Blockscout omitting "OptimizationRuns" field when optimization was not used (#23) Blockscout seems to omit the "OptimizationRuns" field in the "getSourceCode" response when the optimizer has not been used, resulting in a serde deserialization error in the current implementation. See for example the response for [this contract](https://eth.blockscout.com/api?apikey=test&module=contract&action=getsourcecode&address=0xDef1C0ded9bec7F1a1670819833240f027b25EfF). To avoid this I added a default (0) to the respective serde model field. --- src/contract.rs | 2 +- tests/it/contract.rs | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/contract.rs b/src/contract.rs index fb22275..e1d9b00 100644 --- a/src/contract.rs +++ b/src/contract.rs @@ -132,7 +132,7 @@ pub struct Metadata { pub optimization_used: u64, /// The number of optimizations performed. - #[serde(deserialize_with = "deserialize_stringified_u64", alias = "OptimizationRuns")] + #[serde(deserialize_with = "deserialize_stringified_u64", alias = "OptimizationRuns", default)] pub runs: u64, /// The constructor arguments the contract was deployed with. diff --git a/tests/it/contract.rs b/tests/it/contract.rs index 2721c03..8208d36 100644 --- a/tests/it/contract.rs +++ b/tests/it/contract.rs @@ -33,7 +33,7 @@ async fn can_fetch_contract_abi() { #[tokio::test] #[serial] -async fn can_fetch_contract_source_code_from_blockscout() { +async fn can_fetch_deposit_contract_source_code_from_blockscout() { let client = Client::builder() .with_url("https://eth.blockscout.com") .unwrap() @@ -54,6 +54,28 @@ async fn can_fetch_contract_source_code_from_blockscout() { assert_eq!(item.abi().unwrap(), serde_json::from_str(DEPOSIT_CONTRACT_ABI).unwrap()); } +#[tokio::test] +#[serial] +async fn can_fetch_other_contract_source_code_from_blockscout() { + let client = Client::builder() + .with_url("https://eth.blockscout.com") + .unwrap() + .with_api_url("https://eth.blockscout.com/api") + .unwrap() + .with_api_key("test") + .build() + .unwrap(); + let meta = client + .contract_source_code("0xDef1C0ded9bec7F1a1670819833240f027b25EfF".parse().unwrap()) + .await + .unwrap(); + + assert_eq!(meta.items.len(), 1); + let item = &meta.items[0]; + assert!(matches!(item.source_code, SourceCodeMetadata::SourceCode(_))); + assert_eq!(item.source_code.sources().len(), 1); +} + #[tokio::test] #[serial] async fn can_fetch_contract_source_code() {