|
1 | 1 | use super::{AddressIdentity, TraceIdentifier}; |
2 | | -use ethers::{ |
3 | | - abi::{Abi, Address, Event}, |
4 | | - prelude::ArtifactId, |
5 | | -}; |
| 2 | +use ethers::abi::{Address, Event}; |
6 | 3 | use foundry_common::contracts::{diff_score, ContractsByArtifact}; |
7 | | -use itertools::Itertools; |
8 | 4 | use ordered_float::OrderedFloat; |
9 | | -use std::{borrow::Cow, collections::BTreeMap}; |
| 5 | +use std::borrow::Cow; |
10 | 6 |
|
11 | 7 | /// A trace identifier that tries to identify addresses using local contracts. |
12 | | -pub struct LocalTraceIdentifier { |
13 | | - local_contracts: BTreeMap<Vec<u8>, (ArtifactId, Abi)>, |
| 8 | +pub struct LocalTraceIdentifier<'a> { |
| 9 | + known_contracts: &'a ContractsByArtifact, |
14 | 10 | } |
15 | 11 |
|
16 | | -impl LocalTraceIdentifier { |
17 | | - pub fn new(known_contracts: &ContractsByArtifact) -> Self { |
18 | | - Self { |
19 | | - local_contracts: known_contracts |
20 | | - .iter() |
21 | | - .map(|(id, (abi, runtime_code))| (runtime_code.clone(), (id.clone(), abi.clone()))) |
22 | | - .collect(), |
23 | | - } |
| 12 | +impl<'a> LocalTraceIdentifier<'a> { |
| 13 | + pub fn new(known_contracts: &'a ContractsByArtifact) -> Self { |
| 14 | + Self { known_contracts } |
24 | 15 | } |
25 | 16 |
|
26 | 17 | /// Get all the events of the local contracts. |
27 | 18 | pub fn events(&self) -> impl Iterator<Item = &Event> { |
28 | | - self.local_contracts.iter().flat_map(|(_, (_, abi))| abi.events()) |
| 19 | + self.known_contracts.iter().flat_map(|(_, (abi, _))| abi.events()) |
29 | 20 | } |
30 | 21 | } |
31 | 22 |
|
32 | | -impl TraceIdentifier for LocalTraceIdentifier { |
33 | | - fn identify_addresses( |
34 | | - &mut self, |
35 | | - addresses: Vec<(&Address, Option<&[u8]>)>, |
36 | | - ) -> Vec<AddressIdentity> { |
| 23 | +impl TraceIdentifier for LocalTraceIdentifier<'_> { |
| 24 | + fn identify_addresses<'a, A>(&mut self, addresses: A) -> Vec<AddressIdentity> |
| 25 | + where |
| 26 | + A: Iterator<Item = (&'a Address, Option<&'a [u8]>)>, |
| 27 | + { |
37 | 28 | addresses |
38 | | - .into_iter() |
39 | 29 | .filter_map(|(address, code)| { |
40 | 30 | let code = code?; |
41 | | - let (_, (_, (id, abi))) = self |
42 | | - .local_contracts |
| 31 | + let (_, (id, abi)) = self |
| 32 | + .known_contracts |
43 | 33 | .iter() |
44 | | - .filter_map(|entry| { |
45 | | - let score = diff_score(entry.0, code); |
46 | | - if score < 0.1 { |
47 | | - Some((OrderedFloat(score), entry)) |
48 | | - } else { |
49 | | - None |
50 | | - } |
| 34 | + .map(|(id, (abi, known_code))| { |
| 35 | + (OrderedFloat(diff_score(known_code, code)), (id, abi)) |
51 | 36 | }) |
52 | | - .sorted_by_key(|(score, _)| *score) |
53 | | - .next()?; |
| 37 | + .min_by_key(|(score, _)| *score)?; |
54 | 38 |
|
55 | 39 | Some(AddressIdentity { |
56 | 40 | address: *address, |
|
0 commit comments