Skip to content

Commit 88b14a1

Browse files
authored
fix(cast): unknown signatures are cached as an empty string (#11127)
* make sure signatures are not empty, previously we were caching empty results ("") preventing refetching * add tests * avoid duplicate code
1 parent 094eff8 commit 88b14a1

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

crates/cast/tests/cli/selectors.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,48 @@
1+
use foundry_config::Config;
12
use foundry_test_utils::util::OutputExt;
23
use std::path::Path;
34

5+
// <https://github.com/foundry-rs/foundry/issues/11125>
46
casttest!(error_decode_with_openchain, |prj, cmd| {
57
prj.clear_cache();
8+
69
cmd.args(["decode-error", "0x7a0e198500000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000064"]).assert_success().stdout_eq(str![[r#"
710
ValueTooHigh(uint256,uint256)
811
101
912
100
1013
1114
"#]]);
15+
16+
// Read cache to ensure the error is cached
17+
assert_eq!(
18+
read_error_cache().get("0x7a0e1985"),
19+
Some(&serde_json::Value::String("ValueTooHigh(uint256,uint256)".to_string())),
20+
"Selector should be cached"
21+
);
22+
});
23+
24+
// <https://github.com/foundry-rs/foundry/issues/11125>
25+
// NOTE: if a user does happen to mine and submit 0x37d01491 this is expected to fail.
26+
casttest!(error_decode_with_openchain_nonexistent, |prj, cmd| {
27+
prj.clear_cache();
28+
29+
cmd.args(["decode-error", "0x37d0149100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"]).assert_failure().stderr_eq(str![[r#"
30+
Error: No matching error signature found for selector `37d01491`
31+
32+
"#]]);
33+
34+
// Read cache to ensure the error is not cached
35+
assert_eq!(read_error_cache().get("0x37d01491"), None, "Selector should not be cached");
1236
});
1337

38+
/// Read the errors section from the signatures cache in the global foundry cache directory.
39+
fn read_error_cache() -> serde_json::Value {
40+
let cache = Config::foundry_cache_dir().unwrap().join("signatures");
41+
let contents = std::fs::read_to_string(cache).unwrap();
42+
let cache_json: serde_json::Value = serde_json::from_str(&contents).unwrap();
43+
cache_json.get("errors").cloned().unwrap_or_default()
44+
}
45+
1446
casttest!(fourbyte, |_prj, cmd| {
1547
cmd.args(["4byte", "0xa9059cbb"]).assert_success().stdout_eq(str![[r#"
1648
transfer(address,uint256)

crates/evm/traces/src/identifier/signatures.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,9 @@ impl SignaturesIdentifier {
250250
let mut cache_w = self.cache.write().await;
251251
if let Ok(res) = client.decode_selectors(&query).await {
252252
for (selector, signatures) in std::iter::zip(query, res) {
253-
cache_w.signatures.insert(selector, signatures.into_iter().next());
253+
if !signatures.is_empty() {
254+
cache_w.signatures.insert(selector, signatures.into_iter().next());
255+
}
254256
}
255257
}
256258
drop(cache_w);

0 commit comments

Comments
 (0)