@@ -11,6 +11,7 @@ use std::{
1111 sync:: { Mutex , MutexGuard , PoisonError } ,
1212} ;
1313use thiserror:: Error ;
14+ use url:: Url ;
1415
1516pub const SELECTOR_REGISTRY_URL : & str = "https://api.openchain.xyz/signature-database/v1/lookup" ;
1617
@@ -28,14 +29,14 @@ pub trait ErrorRegistry: Send + Sync {
2829/// Default OpenChain-backed registry implementation.
2930pub struct OpenChainRegistry {
3031 client : Client ,
31- url : String ,
32+ url : Url ,
3233}
3334
3435impl Default for OpenChainRegistry {
3536 fn default ( ) -> Self {
3637 Self {
3738 client : Client :: new ( ) ,
38- url : SELECTOR_REGISTRY_URL . to_string ( ) ,
39+ url : Url :: parse ( SELECTOR_REGISTRY_URL ) . unwrap ( ) ,
3940 }
4041 }
4142}
@@ -47,7 +48,7 @@ impl ErrorRegistry for OpenChainRegistry {
4748 let selector_hash = alloy:: primitives:: hex:: encode_prefixed ( selector) ;
4849 let response = self
4950 . client
50- . get ( & self . url )
51+ . get ( self . url . as_ref ( ) )
5152 . query ( & vec ! [
5253 ( "function" , selector_hash. as_str( ) ) ,
5354 ( "filter" , "true" ) ,
@@ -58,17 +59,13 @@ impl ErrorRegistry for OpenChainRegistry {
5859 . json :: < Value > ( )
5960 . await ?;
6061
61- let mut out: Vec < AlloyError > = Vec :: new ( ) ;
62- if let Some ( selectors) = response[ "result" ] [ "function" ] [ selector_hash] . as_array ( ) {
63- for opt_selector in selectors {
64- if let Some ( name) = opt_selector[ "name" ] . as_str ( ) {
65- if let Ok ( err) = name. parse :: < AlloyError > ( ) {
66- out. push ( err) ;
67- }
68- }
69- }
70- }
71- Ok ( out)
62+ Ok ( response[ "result" ] [ "function" ] [ selector_hash]
63+ . as_array ( )
64+ . into_iter ( )
65+ . flat_map ( |selectors| selectors. iter ( ) )
66+ . filter_map ( |opt_selector| opt_selector[ "name" ] . as_str ( ) )
67+ . filter_map ( |name| name. parse :: < AlloyError > ( ) . ok ( ) )
68+ . collect ( ) )
7269 }
7370}
7471
@@ -170,23 +167,27 @@ impl AbiDecodedErrorType {
170167
171168 // consult the registry
172169 let candidates = registry. lookup ( selector_hash_bytes) . await ?;
173- for error in candidates {
174- if let Ok ( result) = error. abi_decode_input ( args_data) {
170+ Ok ( candidates
171+ . into_iter ( )
172+ . find_map ( |error| {
173+ let result = error. abi_decode_input ( args_data) . ok ( ) ?;
174+
175175 // cache the fetched selector
176- {
177- let mut cached_selectors = SELECTORS . lock ( ) ?;
178- cached_selectors. insert ( selector_hash_bytes, error. clone ( ) ) ;
179- }
180- return Ok ( Self :: Known {
176+ let mut cached_selectors = match SELECTORS . lock ( ) {
177+ Ok ( lock) => lock,
178+ Err ( e) => return Some ( Err ( e) ) ,
179+ } ;
180+ cached_selectors. insert ( selector_hash_bytes, error. clone ( ) ) ;
181+
182+ Some ( Ok ( Self :: Known {
181183 sig : error. signature ( ) ,
182184 name : error. name ,
183185 args : result. iter ( ) . map ( |v| format ! ( "{:?}" , v) ) . collect ( ) ,
184186 data : error_data. to_vec ( ) ,
185- } ) ;
186- }
187- }
188-
189- Ok ( Self :: Unknown ( error_data. to_vec ( ) ) )
187+ } ) )
188+ } )
189+ . transpose ( ) ?
190+ . unwrap_or_else ( || Self :: Unknown ( error_data. to_vec ( ) ) ) )
190191 }
191192
192193 /// Decodes an error by checking if it is a Panic(uint256) and returns `None` if
0 commit comments