@@ -6,7 +6,7 @@ use graph::components::store::{EthereumCallCache, StoredDynamicDataSource};
6
6
use graph:: components:: subgraph:: { HostMetrics , InstanceDSTemplateInfo , MappingError } ;
7
7
use graph:: components:: trigger_processor:: RunnableTriggers ;
8
8
use graph:: data_source:: common:: {
9
- CallDecls , DeclaredCall , FindMappingABI , MappingABI , UnresolvedMappingABI ,
9
+ CallDecls , DeclaredCall , FindMappingABI , MappingABI , UnresolvedCallDecls , UnresolvedMappingABI ,
10
10
} ;
11
11
use graph:: data_source:: { CausalityRegion , MappingTrigger as MappingTriggerType } ;
12
12
use graph:: env:: ENV_VARS ;
@@ -41,7 +41,7 @@ use graph::{
41
41
42
42
use graph:: data:: subgraph:: {
43
43
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 ,
45
45
} ;
46
46
47
47
use crate :: adapter:: EthereumAdapter as _;
@@ -74,38 +74,6 @@ pub struct DataSource {
74
74
pub contract_abi : Arc < MappingABI > ,
75
75
}
76
76
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
-
109
77
impl blockchain:: DataSource < Chain > for DataSource {
110
78
fn from_template_info (
111
79
info : InstanceDSTemplateInfo ,
@@ -412,19 +380,6 @@ impl blockchain::DataSource<Chain> for DataSource {
412
380
}
413
381
}
414
382
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
-
428
383
for handler in & self . mapping . event_handlers {
429
384
for call in handler. calls . decls . as_ref ( ) {
430
385
match self . mapping . find_abi ( & call. expr . abi ) {
@@ -1266,7 +1221,7 @@ impl blockchain::UnresolvedDataSource<Chain> for UnresolvedDataSource {
1266
1221
}
1267
1222
}
1268
1223
1269
- #[ derive( Clone , Debug , Default , Hash , Eq , PartialEq , Deserialize ) ]
1224
+ #[ derive( Clone , Debug , Default , Eq , PartialEq , Deserialize ) ]
1270
1225
pub struct UnresolvedDataSourceTemplate {
1271
1226
pub kind : String ,
1272
1227
pub network : Option < String > ,
@@ -1339,7 +1294,7 @@ impl blockchain::DataSourceTemplate<Chain> for DataSourceTemplate {
1339
1294
}
1340
1295
}
1341
1296
1342
- #[ derive( Clone , Debug , Default , Hash , Eq , PartialEq , Deserialize ) ]
1297
+ #[ derive( Clone , Debug , Default , Eq , PartialEq , Deserialize ) ]
1343
1298
#[ serde( rename_all = "camelCase" ) ]
1344
1299
pub struct UnresolvedMapping {
1345
1300
pub kind : String ,
@@ -1352,7 +1307,7 @@ pub struct UnresolvedMapping {
1352
1307
#[ serde( default ) ]
1353
1308
pub call_handlers : Vec < MappingCallHandler > ,
1354
1309
#[ serde( default ) ]
1355
- pub event_handlers : Vec < MappingEventHandler > ,
1310
+ pub event_handlers : Vec < UnresolvedMappingEventHandler > ,
1356
1311
pub file : Link ,
1357
1312
}
1358
1313
@@ -1435,6 +1390,30 @@ impl UnresolvedMapping {
1435
1390
. await
1436
1391
. with_context ( || format ! ( "failed to resolve mapping {}" , link. link) ) ?;
1437
1392
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
+
1438
1417
Ok ( Mapping {
1439
1418
kind,
1440
1419
api_version,
@@ -1443,7 +1422,7 @@ impl UnresolvedMapping {
1443
1422
abis,
1444
1423
block_handlers : block_handlers. clone ( ) ,
1445
1424
call_handlers : call_handlers. clone ( ) ,
1446
- event_handlers : event_handlers . clone ( ) ,
1425
+ event_handlers : resolved_event_handlers ,
1447
1426
runtime,
1448
1427
link,
1449
1428
} )
@@ -1487,6 +1466,46 @@ pub struct MappingCallHandler {
1487
1466
pub handler : String ,
1488
1467
}
1489
1468
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
+
1490
1509
#[ derive( Clone , Debug , Hash , Eq , PartialEq , Deserialize ) ]
1491
1510
pub struct MappingEventHandler {
1492
1511
pub event : String ,
0 commit comments