Skip to content

Commit 1f2be69

Browse files
JannisJannis Pohlmann
authored andcommitted
graph: Make event matching as backwards-compatible as possible
If there is only one event variant with the same name as in the manifest, consider it a match to the signature from the manifest even if the `indexed` hints are missing in the manifest.
1 parent 32e3a60 commit 1f2be69

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

graph/src/util/ethereum.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@ fn event_param_type_signature(kind: &ParamType) -> String {
4646
}
4747
}
4848

49+
/// Returns an `Event(uint256,address)` signature for an event, without `indexed` hints.
50+
fn ambiguous_event_signature(event: &Event) -> String {
51+
format!(
52+
"{}({})",
53+
event.name,
54+
event
55+
.inputs
56+
.iter()
57+
.map(|input| format!("{}", event_param_type_signature(&input.kind)))
58+
.collect::<Vec<_>>()
59+
.join(",")
60+
)
61+
}
62+
4963
/// Returns an `Event(indexed uint256,address)` type signature for an event.
5064
fn event_signature(event: &Event) -> String {
5165
format!(
@@ -72,6 +86,36 @@ pub fn contract_event_with_signature<'a>(
7286
contract
7387
.events()
7488
.find(|event| event_signature(event) == signature)
89+
.or_else(|| {
90+
// Fallback for subgraphs that don't use `indexed` in event signatures yet:
91+
//
92+
// If there is only one event variant with this name and if its signature
93+
// without `indexed` matches the event signature from the manifest, we
94+
// can safely assume that the event is a match, we don't need to force
95+
// the subgraph to add `indexed`.
96+
97+
// Extract the event name; if there is no '(' in the signature,
98+
// `event_name` will be empty and not match any events, so that's ok
99+
let parens = signature.find("(").unwrap_or(0);
100+
let event_name = &signature[0..parens];
101+
102+
let matching_events = contract
103+
.events()
104+
.filter(|event| event.name == event_name)
105+
.collect::<Vec<_>>();
106+
107+
// Only match the event signature without `indexed` if there is
108+
// only a single event variant
109+
if matching_events.len() == 1
110+
&& ambiguous_event_signature(matching_events[0]) == signature
111+
{
112+
Some(matching_events[0])
113+
} else {
114+
// More than one event variant or the signature
115+
// still doesn't match, even if we ignore `indexed` hints
116+
None
117+
}
118+
})
75119
}
76120

77121
pub fn contract_function_with_signature<'a>(

0 commit comments

Comments
 (0)