11use super :: {
2- identifier:: { SingleSignaturesIdentifier , TraceIdentifier } ,
2+ identifier:: { AddressIdentity , SingleSignaturesIdentifier , TraceIdentifier } ,
33 CallTraceArena , RawOrDecodedCall , RawOrDecodedLog , RawOrDecodedReturnData ,
44} ;
55use crate :: {
@@ -20,22 +20,27 @@ use std::collections::{BTreeMap, HashMap};
2020
2121/// Build a new [CallTraceDecoder].
2222#[ derive( Default ) ]
23+ #[ must_use = "builders do nothing unless you call `build` on them" ]
2324pub struct CallTraceDecoderBuilder {
2425 decoder : CallTraceDecoder ,
2526}
2627
2728impl CallTraceDecoderBuilder {
29+ /// Create a new builder.
30+ #[ inline]
2831 pub fn new ( ) -> Self {
2932 Self { decoder : CallTraceDecoder :: new ( ) . clone ( ) }
3033 }
3134
3235 /// Add known labels to the decoder.
36+ #[ inline]
3337 pub fn with_labels ( mut self , labels : impl IntoIterator < Item = ( Address , String ) > ) -> Self {
3438 self . decoder . labels . extend ( labels) ;
3539 self
3640 }
3741
3842 /// Add known events to the decoder.
43+ #[ inline]
3944 pub fn with_events ( mut self , events : impl IntoIterator < Item = Event > ) -> Self {
4045 for event in events {
4146 self . decoder
@@ -48,12 +53,21 @@ impl CallTraceDecoderBuilder {
4853 }
4954
5055 /// Sets the verbosity level of the decoder.
56+ #[ inline]
5157 pub fn with_verbosity ( mut self , level : u8 ) -> Self {
5258 self . decoder . verbosity = level;
5359 self
5460 }
5561
62+ /// Sets the signature identifier for events and functions.
63+ #[ inline]
64+ pub fn with_signature_identifier ( mut self , identifier : SingleSignaturesIdentifier ) -> Self {
65+ self . decoder . signature_identifier = Some ( identifier) ;
66+ self
67+ }
68+
5669 /// Build the decoder.
70+ #[ inline]
5771 pub fn build ( self ) -> CallTraceDecoder {
5872 self . decoder
5973 }
@@ -168,23 +182,26 @@ impl CallTraceDecoder {
168182 }
169183 }
170184
171- pub fn add_signature_identifier ( & mut self , identifier : SingleSignaturesIdentifier ) {
172- self . signature_identifier = Some ( identifier) ;
173- }
174-
175185 /// Identify unknown addresses in the specified call trace using the specified identifier.
176186 ///
177187 /// Unknown contracts are contracts that either lack a label or an ABI.
188+ #[ inline]
178189 pub fn identify ( & mut self , trace : & CallTraceArena , identifier : & mut impl TraceIdentifier ) {
179- let unidentified_addresses = trace
180- . addresses ( )
181- . into_iter ( )
182- . filter ( |( address, _) | {
183- !self . labels . contains_key ( address) || !self . contracts . contains_key ( address)
184- } )
185- . collect ( ) ;
186-
187- identifier. identify_addresses ( unidentified_addresses) . iter ( ) . for_each ( |identity| {
190+ self . collect_identities ( identifier. identify_addresses ( self . addresses ( trace) ) ) ;
191+ }
192+
193+ #[ inline( always) ]
194+ fn addresses < ' a > (
195+ & ' a self ,
196+ trace : & ' a CallTraceArena ,
197+ ) -> impl Iterator < Item = ( & ' a Address , Option < & ' a [ u8 ] > ) > + ' a {
198+ trace. addresses ( ) . into_iter ( ) . filter ( |& ( address, _) | {
199+ !self . labels . contains_key ( address) || !self . contracts . contains_key ( address)
200+ } )
201+ }
202+
203+ fn collect_identities ( & mut self , identities : Vec < AddressIdentity > ) {
204+ for identity in identities {
188205 let address = identity. address ;
189206
190207 if let Some ( contract) = & identity. contract {
@@ -197,30 +214,31 @@ impl CallTraceDecoder {
197214
198215 if let Some ( abi) = & identity. abi {
199216 // Store known functions for the address
200- abi. functions ( )
201- . map ( |func| ( func. short_signature ( ) , func. clone ( ) ) )
202- . for_each ( |( sig, func) | self . functions . entry ( sig) . or_default ( ) . push ( func) ) ;
217+ for function in abi. functions ( ) {
218+ self . functions
219+ . entry ( function. short_signature ( ) )
220+ . or_default ( )
221+ . push ( function. clone ( ) )
222+ }
203223
204224 // Flatten events from all ABIs
205- abi. events ( )
206- . map ( |event| ( ( event. signature ( ) , indexed_inputs ( event) ) , event. clone ( ) ) )
207- . for_each ( |( sig, event) | {
208- self . events . entry ( sig) . or_default ( ) . push ( event) ;
209- } ) ;
225+ for event in abi. events ( ) {
226+ let sig = ( event. signature ( ) , indexed_inputs ( event) ) ;
227+ self . events . entry ( sig) . or_default ( ) . push ( event. clone ( ) ) ;
228+ }
210229
211230 // Flatten errors from all ABIs
212- abi. errors ( ) . for_each ( |error| {
213- let entry = self . errors . errors . entry ( error. name . clone ( ) ) . or_default ( ) ;
214- entry. push ( error. clone ( ) ) ;
215- } ) ;
231+ for error in abi. errors ( ) {
232+ self . errors . errors . entry ( error. name . clone ( ) ) . or_default ( ) . push ( error. clone ( ) ) ;
233+ }
216234
217235 self . receive_contracts . entry ( address) . or_insert ( abi. receive ) ;
218236 }
219- } ) ;
237+ }
220238 }
221239
222240 pub async fn decode ( & self , traces : & mut CallTraceArena ) {
223- for node in traces. arena . iter_mut ( ) {
241+ for node in & mut traces. arena {
224242 // Set contract name
225243 if let Some ( contract) = self . contracts . get ( & node. trace . address ) . cloned ( ) {
226244 node. trace . contract = Some ( contract) ;
0 commit comments