55from collections import namedtuple
66from contextlib import ExitStack
77from datetime import datetime
8- from typing import Any
98from typing import DefaultDict
109from typing import Deque
1110from typing import Dict
@@ -635,8 +634,8 @@ async def _synchronize(self, last_level: int, cache: bool = False) -> None:
635634 async def _synchronize_full (self , first_level : int , last_level : int , cache : bool = False ) -> None :
636635 self ._logger .info ('Fetching big map diffs from level %s to %s' , first_level , last_level )
637636
638- big_map_addresses = await self ._get_big_map_addresses ()
639- big_map_paths = await self ._get_big_map_paths ()
637+ big_map_addresses = self ._get_big_map_addresses ()
638+ big_map_paths = self ._get_big_map_paths ()
640639
641640 fetcher = BigMapFetcher (
642641 datasource = self ._datasource ,
@@ -659,42 +658,38 @@ async def _synchronize_level(self, last_level: int, cache: bool = False) -> None
659658 if not self ._ctx .config .advanced .early_realtime :
660659 raise ConfigurationError ('`skip_history` requires `early_realtime` feature flag to be enabled' )
661660
662- big_map_addresses = await self ._get_big_map_addresses ()
663- big_map_paths = await self ._get_big_map_paths ()
664- big_map_ids : Set [Tuple [int , str ]] = set ()
661+ big_map_pairs = self ._get_big_map_pairs ()
662+ big_map_ids : Set [Tuple [int , str , str ]] = set ()
665663
666- for address in big_map_addresses :
664+ for address , path in big_map_pairs :
667665 async for contract_big_maps in self ._datasource .iter_contract_big_maps (address ):
668666 for contract_big_map in contract_big_maps :
669- if contract_big_map ['path' ] in big_map_paths :
670- big_map_ids .add ((int (contract_big_map ['ptr' ]), contract_big_map [ ' path' ] ))
667+ if contract_big_map ['path' ] == path :
668+ big_map_ids .add ((int (contract_big_map ['ptr' ]), address , path ))
671669
672670 # NOTE: Do not use `_process_level_big_maps` here; we want to maintain transaction manually.
673- async def _process_big_map_batch (big_maps : Tuple [Dict [str , Any ], ...], path : str ) -> None :
674- big_map_data = tuple (
675- BigMapData (
676- id = big_map ['id' ],
677- level = last_level ,
678- operation_id = last_level ,
679- timestamp = datetime .now (),
680- bigmap = big_map_id ,
681- contract_address = address ,
682- path = path ,
683- action = BigMapAction .ADD_KEY ,
684- active = big_map ['active' ],
685- key = big_map ['key' ],
686- value = big_map ['value' ],
687- )
688- for big_map in big_maps
689- )
690- matched_handlers = await self ._match_big_maps (big_map_data )
691- for handler_config , big_map_diff in matched_handlers :
692- await self ._call_matched_handler (handler_config , big_map_diff )
693-
694671 async with in_global_transaction ():
695- for big_map_id , path in big_map_ids :
696- async for big_maps in self ._datasource .iter_big_map (big_map_id , last_level ):
697- await _process_big_map_batch (big_maps , path )
672+ for big_map_id , address , path in big_map_ids :
673+ async for big_map_keys in self ._datasource .iter_big_map (big_map_id , last_level ):
674+ big_map_data = tuple (
675+ BigMapData (
676+ id = big_map_key ['id' ],
677+ level = last_level ,
678+ operation_id = last_level ,
679+ timestamp = datetime .now (),
680+ bigmap = big_map_id ,
681+ contract_address = address ,
682+ path = path ,
683+ action = BigMapAction .ADD_KEY ,
684+ active = big_map_key ['active' ],
685+ key = big_map_key ['key' ],
686+ value = big_map_key ['value' ],
687+ )
688+ for big_map_key in big_map_keys
689+ )
690+ matched_handlers = await self ._match_big_maps (big_map_data )
691+ for handler_config , big_map_diff in matched_handlers :
692+ await self ._call_matched_handler (handler_config , big_map_diff )
698693
699694 await self .state .update_status (level = last_level )
700695
@@ -767,8 +762,8 @@ async def _match_big_maps(self, big_maps: Iterable[BigMapData]) -> Deque[Matched
767762 """Try to match big map diffs in cache with all patterns from indexes."""
768763 matched_handlers : Deque [MatchedBigMapsT ] = deque ()
769764
770- for big_map in big_maps :
771- for handler_config in self . _config . handlers :
765+ for handler_config in self . _config . handlers :
766+ for big_map in big_maps :
772767 big_map_matched = await self ._match_big_map (handler_config , big_map )
773768 if big_map_matched :
774769 arg = await self ._prepare_handler_args (handler_config , big_map )
@@ -789,20 +784,32 @@ async def _call_matched_handler(self, handler_config: BigMapHandlerConfig, big_m
789784 big_map_diff ,
790785 )
791786
792- async def _get_big_map_addresses (self ) -> Set [str ]:
787+ def _get_big_map_addresses (self ) -> Set [str ]:
793788 """Get addresses to fetch big map diffs from during initial synchronization"""
794789 addresses = set ()
795790 for handler_config in self ._config .handlers :
796791 addresses .add (cast (ContractConfig , handler_config .contract ).address )
797792 return addresses
798793
799- async def _get_big_map_paths (self ) -> Set [str ]:
794+ def _get_big_map_paths (self ) -> Set [str ]:
800795 """Get addresses to fetch big map diffs from during initial synchronization"""
801796 paths = set ()
802797 for handler_config in self ._config .handlers :
803798 paths .add (handler_config .path )
804799 return paths
805800
801+ def _get_big_map_pairs (self ) -> Set [Tuple [str , str ]]:
802+ """Get address-path pairs for fetch big map diffs during sync with `skip_history`"""
803+ pairs = set ()
804+ for handler_config in self ._config .handlers :
805+ pairs .add (
806+ (
807+ cast (ContractConfig , handler_config .contract ).address ,
808+ handler_config .path ,
809+ )
810+ )
811+ return pairs
812+
806813
807814class HeadIndex (Index ):
808815 _config : HeadIndexConfig
0 commit comments