@@ -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,23 @@ 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. first ( ) . ok_or_else ( || {
1399+ anyhow ! (
1400+ "No ABI found for event '{}' in event handler '{}'" ,
1401+ unresolved_handler. event,
1402+ unresolved_handler. handler
1403+ )
1404+ } ) ?;
1405+
1406+ unresolved_handler. resolve ( event_abi, Some ( & api_version) )
1407+ } )
1408+ . collect :: < Result < Vec < _ > , anyhow:: Error > > ( ) ?;
1409+
14381410 Ok ( Mapping {
14391411 kind,
14401412 api_version,
@@ -1443,7 +1415,7 @@ impl UnresolvedMapping {
14431415 abis,
14441416 block_handlers : block_handlers. clone ( ) ,
14451417 call_handlers : call_handlers. clone ( ) ,
1446- event_handlers : event_handlers . clone ( ) ,
1418+ event_handlers : resolved_event_handlers ,
14471419 runtime,
14481420 link,
14491421 } )
@@ -1487,6 +1459,46 @@ pub struct MappingCallHandler {
14871459 pub handler : String ,
14881460}
14891461
1462+ #[ derive( Clone , Debug , Eq , PartialEq , Deserialize ) ]
1463+ pub struct UnresolvedMappingEventHandler {
1464+ pub event : String ,
1465+ pub topic0 : Option < H256 > ,
1466+ #[ serde( deserialize_with = "deserialize_h256_vec" , default ) ]
1467+ pub topic1 : Option < Vec < H256 > > ,
1468+ #[ serde( deserialize_with = "deserialize_h256_vec" , default ) ]
1469+ pub topic2 : Option < Vec < H256 > > ,
1470+ #[ serde( deserialize_with = "deserialize_h256_vec" , default ) ]
1471+ pub topic3 : Option < Vec < H256 > > ,
1472+ pub handler : String ,
1473+ #[ serde( default ) ]
1474+ pub receipt : bool ,
1475+ #[ serde( default ) ]
1476+ pub calls : UnresolvedCallDecls ,
1477+ }
1478+
1479+ impl UnresolvedMappingEventHandler {
1480+ pub fn resolve (
1481+ & self ,
1482+ mapping : & MappingABI ,
1483+ spec_version : Option < & semver:: Version > ,
1484+ ) -> Result < MappingEventHandler , anyhow:: Error > {
1485+ let resolved_calls = self
1486+ . calls
1487+ . resolve ( mapping, Some ( & self . event ) , spec_version) ?;
1488+
1489+ Ok ( MappingEventHandler {
1490+ event : self . event . clone ( ) ,
1491+ topic0 : self . topic0 ,
1492+ topic1 : self . topic1 . clone ( ) ,
1493+ topic2 : self . topic2 . clone ( ) ,
1494+ topic3 : self . topic3 . clone ( ) ,
1495+ handler : self . handler . clone ( ) ,
1496+ receipt : self . receipt ,
1497+ calls : resolved_calls,
1498+ } )
1499+ }
1500+ }
1501+
14901502#[ derive( Clone , Debug , Hash , Eq , PartialEq , Deserialize ) ]
14911503pub struct MappingEventHandler {
14921504 pub event : String ,
0 commit comments