From c56a398bfb0fa5af10c7852e9f32bc6ffbc90bbe Mon Sep 17 00:00:00 2001 From: Lev Gorodetskiy Date: Wed, 21 Apr 2021 09:09:16 +0300 Subject: [PATCH] Fix merging nested bigmapdiffs --- src/dipdup/models.py | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/dipdup/models.py b/src/dipdup/models.py index 66c0dd93b..9740382ae 100644 --- a/src/dipdup/models.py +++ b/src/dipdup/models.py @@ -67,25 +67,26 @@ class OperationData: def _merge_bigmapdiffs(self, storage_dict: Dict[str, Any], bigmap_name: str, array: bool) -> None: if self.diffs is None: raise Exception('`bigmaps` field missing') + _logger.debug(bigmap_name) bigmapdiffs = [bm for bm in self.diffs if bm['path'] == bigmap_name] + bigmap_key = bigmap_name.split('.')[-1] for diff in bigmapdiffs: _logger.debug('Applying bigmapdiff: %s', diff) if diff['action'] in ('add_key', 'update_key'): key = diff['content']['key'] if array is True: - storage_dict[bigmap_name].append({'key': key, 'value': diff['content']['value']}) + storage_dict[bigmap_key].append({'key': key, 'value': diff['content']['value']}) else: - storage_dict[bigmap_name][key] = diff['content']['value'] + storage_dict[bigmap_key][key] = diff['content']['value'] - def get_merged_storage(self, storage_type: Type[StorageType]) -> StorageType: - if self.storage is None: - raise Exception('`storage` field missing') - - storage = deepcopy(self.storage) - _logger.debug('Merging storage') - _logger.debug('Before: %s', storage) + def _process_storage(self, storage_type: Type[StorageType], storage: Dict, prefix: str = None): for key, field in storage_type.__fields__.items(): + bigmap_name = key if prefix is None else '.'.join([prefix, key]) + + if key == '__root__': + continue + if field.alias: key = field.alias @@ -95,11 +96,26 @@ def get_merged_storage(self, storage_type: Type[StorageType]) -> StorageType: if hasattr(field.type_, '__fields__') and 'key' in field.type_.__fields__ and 'value' in field.type_.__fields__: storage[key] = [] if self.diffs: - self._merge_bigmapdiffs(storage, key, array=True) + self._merge_bigmapdiffs(storage, bigmap_name, array=True) else: storage[key] = {} if self.diffs: - self._merge_bigmapdiffs(storage, key, array=False) + self._merge_bigmapdiffs(storage, bigmap_name, array=False) + elif hasattr(field.type_, '__fields__') and isinstance(storage[key], dict): + storage[key] = self._process_storage(field.type_, storage[key], bigmap_name) + + return storage + + def get_merged_storage(self, storage_type: Type[StorageType]) -> StorageType: + if self.storage is None: + raise Exception('`storage` field missing') + + storage = deepcopy(self.storage) + _logger.debug('Merging storage') + _logger.debug('Before: %s', storage) + _logger.debug('Diffs: %s', self.diffs) + + storage = self._process_storage(storage_type, storage, None) _logger.debug('After: %s', storage)