@@ -6,7 +6,7 @@ use graph::components::store::{EthereumCallCache, StoredDynamicDataSource};
66use graph:: components:: subgraph:: { HostMetrics , InstanceDSTemplateInfo , MappingError } ;
77use graph:: components:: trigger_processor:: RunnableTriggers ;
88use graph:: data_source:: common:: {
9- CallDecls , DeclaredCall , FindMappingABI , MappingABI , UnresolvedMappingABI ,
9+ CallDecls , DeclaredCall , FindMappingABI , MappingABI , UnresolvedCallDecls , UnresolvedMappingABI ,
1010} ;
1111use graph:: data_source:: { CausalityRegion , MappingTrigger as MappingTriggerType } ;
1212use graph:: env:: ENV_VARS ;
@@ -41,7 +41,7 @@ use graph::{
4141
4242use graph:: data:: subgraph:: {
4343 calls_host_fn, DataSourceContext , Source , MIN_SPEC_VERSION , SPEC_VERSION_0_0_8 ,
44- SPEC_VERSION_1_2_0 , SPEC_VERSION_1_4_0 ,
44+ SPEC_VERSION_1_2_0 ,
4545} ;
4646
4747use crate :: adapter:: EthereumAdapter as _;
@@ -74,38 +74,6 @@ pub struct DataSource {
7474 pub contract_abi : Arc < MappingABI > ,
7575}
7676
77- /// Checks if a declarative call uses struct field access that would require spec version 1.4.0+
78- /// This detects if the call was parsed with ABI context to resolve named fields
79- fn call_uses_named_field_access ( call_expr : & graph:: data_source:: common:: CallExpr ) -> bool {
80- // Check address for struct field access
81- if has_struct_field_access ( & call_expr. address ) {
82- return true ;
83- }
84-
85- // Check all arguments for struct field access
86- for arg in & call_expr. args {
87- if has_struct_field_access ( arg) {
88- return true ;
89- }
90- }
91-
92- false
93- }
94-
95- /// Helper function to check if a CallArg uses struct field access
96- fn has_struct_field_access ( arg : & graph:: data_source:: common:: CallArg ) -> bool {
97- use graph:: data_source:: common:: { CallArg , EthereumArg } ;
98-
99- match arg {
100- CallArg :: Ethereum ( EthereumArg :: StructField ( _, indices) ) => {
101- // If we have struct field access with indices, it means named fields were resolved
102- // This feature requires spec version 1.4.0+
103- !indices. is_empty ( )
104- }
105- _ => false ,
106- }
107- }
108-
10977impl blockchain:: DataSource < Chain > for DataSource {
11078 fn from_template_info (
11179 info : InstanceDSTemplateInfo ,
@@ -412,19 +380,6 @@ impl blockchain::DataSource<Chain> for DataSource {
412380 }
413381 }
414382
415- if spec_version < & SPEC_VERSION_1_4_0 {
416- for handler in & self . mapping . event_handlers {
417- for call in handler. calls . decls . as_ref ( ) {
418- if call_uses_named_field_access ( & call. expr ) {
419- errors. push ( anyhow ! (
420- "handler {}: struct field access by name in declarative calls is only supported for specVersion >= 1.4.0" , handler. event
421- ) ) ;
422- break ;
423- }
424- }
425- }
426- }
427-
428383 for handler in & self . mapping . event_handlers {
429384 for call in handler. calls . decls . as_ref ( ) {
430385 match self . mapping . find_abi ( & call. expr . abi ) {
@@ -1266,7 +1221,7 @@ impl blockchain::UnresolvedDataSource<Chain> for UnresolvedDataSource {
12661221 }
12671222}
12681223
1269- #[ derive( Clone , Debug , Default , Hash , Eq , PartialEq , Deserialize ) ]
1224+ #[ derive( Clone , Debug , Default , Eq , PartialEq , Deserialize ) ]
12701225pub struct UnresolvedDataSourceTemplate {
12711226 pub kind : String ,
12721227 pub network : Option < String > ,
@@ -1339,7 +1294,7 @@ impl blockchain::DataSourceTemplate<Chain> for DataSourceTemplate {
13391294 }
13401295}
13411296
1342- #[ derive( Clone , Debug , Default , Hash , Eq , PartialEq , Deserialize ) ]
1297+ #[ derive( Clone , Debug , Default , Eq , PartialEq , Deserialize ) ]
13431298#[ serde( rename_all = "camelCase" ) ]
13441299pub struct UnresolvedMapping {
13451300 pub kind : String ,
@@ -1352,7 +1307,7 @@ pub struct UnresolvedMapping {
13521307 #[ serde( default ) ]
13531308 pub call_handlers : Vec < MappingCallHandler > ,
13541309 #[ serde( default ) ]
1355- pub event_handlers : Vec < MappingEventHandler > ,
1310+ pub event_handlers : Vec < UnresolvedMappingEventHandler > ,
13561311 pub file : Link ,
13571312}
13581313
@@ -1435,6 +1390,30 @@ impl UnresolvedMapping {
14351390 . await
14361391 . with_context ( || format ! ( "failed to resolve mapping {}" , link. link) ) ?;
14371392
1393+ // Resolve event handlers with ABI context
1394+ let resolved_event_handlers = event_handlers
1395+ . into_iter ( )
1396+ . map ( |unresolved_handler| {
1397+ // Find the ABI for this event handler
1398+ let event_abi = abis
1399+ . iter ( )
1400+ . find ( |abi| {
1401+ abi. contract
1402+ . events ( )
1403+ . any ( |event| event. name == unresolved_handler. event )
1404+ } )
1405+ . ok_or_else ( || {
1406+ anyhow ! (
1407+ "No ABI found for event '{}' in event handler '{}'" ,
1408+ unresolved_handler. event,
1409+ unresolved_handler. handler
1410+ )
1411+ } ) ?;
1412+
1413+ unresolved_handler. resolve ( event_abi, Some ( & api_version) )
1414+ } )
1415+ . collect :: < Result < Vec < _ > , anyhow:: Error > > ( ) ?;
1416+
14381417 Ok ( Mapping {
14391418 kind,
14401419 api_version,
@@ -1443,7 +1422,7 @@ impl UnresolvedMapping {
14431422 abis,
14441423 block_handlers : block_handlers. clone ( ) ,
14451424 call_handlers : call_handlers. clone ( ) ,
1446- event_handlers : event_handlers . clone ( ) ,
1425+ event_handlers : resolved_event_handlers ,
14471426 runtime,
14481427 link,
14491428 } )
@@ -1487,6 +1466,46 @@ pub struct MappingCallHandler {
14871466 pub handler : String ,
14881467}
14891468
1469+ #[ derive( Clone , Debug , Eq , PartialEq , Deserialize ) ]
1470+ pub struct UnresolvedMappingEventHandler {
1471+ pub event : String ,
1472+ pub topic0 : Option < H256 > ,
1473+ #[ serde( deserialize_with = "deserialize_h256_vec" , default ) ]
1474+ pub topic1 : Option < Vec < H256 > > ,
1475+ #[ serde( deserialize_with = "deserialize_h256_vec" , default ) ]
1476+ pub topic2 : Option < Vec < H256 > > ,
1477+ #[ serde( deserialize_with = "deserialize_h256_vec" , default ) ]
1478+ pub topic3 : Option < Vec < H256 > > ,
1479+ pub handler : String ,
1480+ #[ serde( default ) ]
1481+ pub receipt : bool ,
1482+ #[ serde( default ) ]
1483+ pub calls : UnresolvedCallDecls ,
1484+ }
1485+
1486+ impl UnresolvedMappingEventHandler {
1487+ pub fn resolve (
1488+ & self ,
1489+ mapping : & MappingABI ,
1490+ spec_version : Option < & semver:: Version > ,
1491+ ) -> Result < MappingEventHandler , anyhow:: Error > {
1492+ let resolved_calls = self
1493+ . calls
1494+ . resolve ( mapping, Some ( & self . event ) , spec_version) ?;
1495+
1496+ Ok ( MappingEventHandler {
1497+ event : self . event . clone ( ) ,
1498+ topic0 : self . topic0 ,
1499+ topic1 : self . topic1 . clone ( ) ,
1500+ topic2 : self . topic2 . clone ( ) ,
1501+ topic3 : self . topic3 . clone ( ) ,
1502+ handler : self . handler . clone ( ) ,
1503+ receipt : self . receipt ,
1504+ calls : resolved_calls,
1505+ } )
1506+ }
1507+ }
1508+
14901509#[ derive( Clone , Debug , Hash , Eq , PartialEq , Deserialize ) ]
14911510pub struct MappingEventHandler {
14921511 pub event : String ,
0 commit comments