@@ -692,24 +692,25 @@ impl EthereumBlockFilter {
692
692
} = other;
693
693
694
694
self . trigger_every_block = self . trigger_every_block || trigger_every_block;
695
- self . contract_addresses = self . contract_addresses . iter ( ) . cloned ( ) . fold (
696
- HashSet :: new ( ) ,
697
- |mut addresses, ( start_block, address) | {
698
- match contract_addresses
699
- . iter ( )
700
- . cloned ( )
701
- . find ( |( _, other_address) | & address == other_address)
702
- {
703
- Some ( ( other_start_block, address) ) => {
704
- addresses. insert ( ( cmp:: min ( other_start_block, start_block) , address) ) ;
705
- }
706
- None => {
707
- addresses. insert ( ( start_block, address) ) ;
695
+
696
+ for other in contract_addresses {
697
+ let ( other_start_block, other_address) = other;
698
+
699
+ match self . find_contract_address ( & other. 1 ) {
700
+ Some ( ( current_start_block, current_address) ) => {
701
+ if other_start_block < current_start_block {
702
+ self . contract_addresses
703
+ . remove ( & ( current_start_block, current_address) ) ;
704
+ self . contract_addresses
705
+ . insert ( ( other_start_block, other_address) ) ;
708
706
}
709
707
}
710
- addresses
711
- } ,
712
- ) ;
708
+ None => {
709
+ self . contract_addresses
710
+ . insert ( ( other_start_block, other_address) ) ;
711
+ }
712
+ }
713
+ }
713
714
}
714
715
715
716
fn requires_traces ( & self ) -> bool {
@@ -725,6 +726,13 @@ impl EthereumBlockFilter {
725
726
726
727
self . contract_addresses . is_empty ( )
727
728
}
729
+
730
+ fn find_contract_address ( & self , candidate : & Address ) -> Option < ( i32 , Address ) > {
731
+ self . contract_addresses
732
+ . iter ( )
733
+ . find ( |( _, current_address) | candidate == current_address)
734
+ . cloned ( )
735
+ }
728
736
}
729
737
730
738
pub enum ProviderStatus {
@@ -1188,8 +1196,6 @@ mod tests {
1188
1196
1189
1197
#[ test]
1190
1198
fn matching_ethereum_call_filter ( ) {
1191
- let address = |id : u64 | Address :: from_low_u64_be ( id) ;
1192
- let bytes = |value : Vec < u8 > | Bytes :: from ( value) ;
1193
1199
let call = |to : Address , input : Vec < u8 > | EthereumCall {
1194
1200
to,
1195
1201
input : bytes ( input) ,
@@ -1287,6 +1293,125 @@ mod tests {
1287
1293
) ;
1288
1294
}
1289
1295
1296
+ #[ test]
1297
+ fn extending_ethereum_block_filter_no_found ( ) {
1298
+ let mut base = EthereumBlockFilter {
1299
+ contract_addresses : HashSet :: new ( ) ,
1300
+ trigger_every_block : false ,
1301
+ } ;
1302
+
1303
+ let extension = EthereumBlockFilter {
1304
+ contract_addresses : HashSet :: from_iter ( vec ! [ ( 10 , address( 1 ) ) ] ) ,
1305
+ trigger_every_block : false ,
1306
+ } ;
1307
+
1308
+ base. extend ( extension) ;
1309
+
1310
+ assert_eq ! (
1311
+ HashSet :: from_iter( vec![ ( 10 , address( 1 ) ) ] ) ,
1312
+ base. contract_addresses,
1313
+ ) ;
1314
+ }
1315
+
1316
+ #[ test]
1317
+ fn extending_ethereum_block_filter_conflict_picks_lowest_block_from_ext ( ) {
1318
+ let mut base = EthereumBlockFilter {
1319
+ contract_addresses : HashSet :: from_iter ( vec ! [ ( 10 , address( 1 ) ) ] ) ,
1320
+ trigger_every_block : false ,
1321
+ } ;
1322
+
1323
+ let extension = EthereumBlockFilter {
1324
+ contract_addresses : HashSet :: from_iter ( vec ! [ ( 2 , address( 1 ) ) ] ) ,
1325
+ trigger_every_block : false ,
1326
+ } ;
1327
+
1328
+ base. extend ( extension) ;
1329
+
1330
+ assert_eq ! (
1331
+ HashSet :: from_iter( vec![ ( 2 , address( 1 ) ) ] ) ,
1332
+ base. contract_addresses,
1333
+ ) ;
1334
+ }
1335
+
1336
+ #[ test]
1337
+ fn extending_ethereum_block_filter_conflict_picks_lowest_block_from_base ( ) {
1338
+ let mut base = EthereumBlockFilter {
1339
+ contract_addresses : HashSet :: from_iter ( vec ! [ ( 2 , address( 1 ) ) ] ) ,
1340
+ trigger_every_block : false ,
1341
+ } ;
1342
+
1343
+ let extension = EthereumBlockFilter {
1344
+ contract_addresses : HashSet :: from_iter ( vec ! [ ( 10 , address( 1 ) ) ] ) ,
1345
+ trigger_every_block : false ,
1346
+ } ;
1347
+
1348
+ base. extend ( extension) ;
1349
+
1350
+ assert_eq ! (
1351
+ HashSet :: from_iter( vec![ ( 2 , address( 1 ) ) ] ) ,
1352
+ base. contract_addresses,
1353
+ ) ;
1354
+ }
1355
+
1356
+ #[ test]
1357
+ fn extending_ethereum_block_filter_every_block_in_ext ( ) {
1358
+ let mut base = EthereumBlockFilter {
1359
+ contract_addresses : HashSet :: default ( ) ,
1360
+ trigger_every_block : false ,
1361
+ } ;
1362
+
1363
+ let extension = EthereumBlockFilter {
1364
+ contract_addresses : HashSet :: default ( ) ,
1365
+ trigger_every_block : true ,
1366
+ } ;
1367
+
1368
+ base. extend ( extension) ;
1369
+
1370
+ assert_eq ! ( true , base. trigger_every_block) ;
1371
+ }
1372
+
1373
+ #[ test]
1374
+ fn extending_ethereum_block_filter_every_block_in_base_and_merge_contract_addresses ( ) {
1375
+ let mut base = EthereumBlockFilter {
1376
+ contract_addresses : HashSet :: from_iter ( vec ! [ ( 10 , address( 2 ) ) ] ) ,
1377
+ trigger_every_block : true ,
1378
+ } ;
1379
+
1380
+ let extension = EthereumBlockFilter {
1381
+ contract_addresses : HashSet :: from_iter ( vec ! [ ] ) ,
1382
+ trigger_every_block : false ,
1383
+ } ;
1384
+
1385
+ base. extend ( extension) ;
1386
+
1387
+ assert_eq ! ( true , base. trigger_every_block) ;
1388
+ assert_eq ! (
1389
+ HashSet :: from_iter( vec![ ( 10 , address( 2 ) ) ] ) ,
1390
+ base. contract_addresses,
1391
+ ) ;
1392
+ }
1393
+
1394
+ #[ test]
1395
+ fn extending_ethereum_block_filter_every_block_in_ext_and_merge_contract_addresses ( ) {
1396
+ let mut base = EthereumBlockFilter {
1397
+ contract_addresses : HashSet :: from_iter ( vec ! [ ( 10 , address( 2 ) ) ] ) ,
1398
+ trigger_every_block : false ,
1399
+ } ;
1400
+
1401
+ let extension = EthereumBlockFilter {
1402
+ contract_addresses : HashSet :: from_iter ( vec ! [ ( 10 , address( 1 ) ) ] ) ,
1403
+ trigger_every_block : true ,
1404
+ } ;
1405
+
1406
+ base. extend ( extension) ;
1407
+
1408
+ assert_eq ! ( true , base. trigger_every_block) ;
1409
+ assert_eq ! (
1410
+ HashSet :: from_iter( vec![ ( 10 , address( 2 ) ) , ( 10 , address( 1 ) ) ] ) ,
1411
+ base. contract_addresses,
1412
+ ) ;
1413
+ }
1414
+
1290
1415
#[ test]
1291
1416
fn extending_ethereum_call_filter ( ) {
1292
1417
let mut base = EthereumCallFilter {
@@ -1333,6 +1458,14 @@ mod tests {
1333
1458
Some ( & ( 1 , HashSet :: from_iter( vec![ [ 1u8 ; 4 ] ] ) ) )
1334
1459
) ;
1335
1460
}
1461
+
1462
+ fn address ( id : u64 ) -> Address {
1463
+ Address :: from_low_u64_be ( id)
1464
+ }
1465
+
1466
+ fn bytes ( value : Vec < u8 > ) -> Bytes {
1467
+ Bytes :: from ( value)
1468
+ }
1336
1469
}
1337
1470
1338
1471
// Tests `eth_get_logs_filters` in instances where all events are filtered on by all contracts.
0 commit comments