Skip to content

Commit a482186

Browse files
Add warning on using multiple indexes with the same contract (#107)
1 parent 829f2aa commit a482186

File tree

3 files changed

+43
-29
lines changed

3 files changed

+43
-29
lines changed

src/dipdup/config.py

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -605,23 +605,9 @@ class BigMapIndexConfig(IndexConfig):
605605
first_block: int = 0
606606
last_block: int = 0
607607

608-
609-
@dataclass
610-
class BlockHandlerConfig(HandlerConfig):
611-
pattern = None
612-
613-
614-
@dataclass
615-
class BlockIndexConfig(IndexConfig):
616-
"""Stub, not implemented"""
617-
618-
kind: Literal['block']
619-
datasource: Union[str, TzktDatasourceConfig]
620-
handlers: List[BlockHandlerConfig]
621-
622-
stateless: bool = False
623-
first_block: int = 0
624-
last_block: int = 0
608+
@property
609+
def contracts(self) -> List[ContractConfig]:
610+
return list(set([cast(ContractConfig, handler_config.contract) for handler_config in self.handlers]))
625611

626612

627613
@dataclass
@@ -631,8 +617,8 @@ class IndexTemplateConfig:
631617
values: Dict[str, str]
632618

633619

634-
IndexConfigT = Union[OperationIndexConfig, BigMapIndexConfig, BlockIndexConfig, IndexTemplateConfig]
635-
IndexConfigTemplateT = Union[OperationIndexConfig, BigMapIndexConfig, BlockIndexConfig]
620+
IndexConfigT = Union[OperationIndexConfig, BigMapIndexConfig, IndexTemplateConfig]
621+
IndexConfigTemplateT = Union[OperationIndexConfig, BigMapIndexConfig]
636622
HandlerPatternConfigT = Union[OperationHandlerOriginationPatternConfig, OperationHandlerTransactionPatternConfig]
637623

638624

@@ -714,14 +700,6 @@ class DipDupConfig:
714700
jobs: Optional[Dict[str, JobConfig]] = None
715701
sentry: Optional[SentryConfig] = None
716702

717-
@property
718-
def environment(self) -> Dict[str, str]:
719-
return self._environment
720-
721-
@property
722-
def filenames(self) -> List[str]:
723-
return self._filenames
724-
725703
def __post_init_post_parse__(self):
726704
self._filenames: List[str] = []
727705
self._environment: Dict[str, str] = {}
@@ -730,6 +708,14 @@ def __post_init_post_parse__(self):
730708
self._initialized = []
731709
self.validate()
732710

711+
@property
712+
def environment(self) -> Dict[str, str]:
713+
return self._environment
714+
715+
@property
716+
def filenames(self) -> List[str]:
717+
return self._filenames
718+
733719
def validate(self) -> None:
734720
if isinstance(self.database, SqliteDatabaseConfig) and self.hasura:
735721
raise ConfigurationError('SQLite DB engine is not supported by Hasura')

src/dipdup/dipdup.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import asyncio
22
import hashlib
33
import logging
4+
import operator
5+
from collections import Counter
46
from contextlib import AsyncExitStack, asynccontextmanager, suppress
7+
from functools import reduce
58
from os import listdir
69
from os.path import join
710
from typing import Dict, List, Optional, cast
@@ -18,6 +21,7 @@
1821
BcdDatasourceConfig,
1922
BigMapIndexConfig,
2023
CoinbaseDatasourceConfig,
24+
ContractConfig,
2125
DatasourceConfigT,
2226
DipDupConfig,
2327
IndexConfigTemplateT,
@@ -84,9 +88,18 @@ async def reload_config(self) -> None:
8488

8589
for index_config in self._ctx.config.indexes.values():
8690
if isinstance(index_config, IndexTemplateConfig):
87-
raise RuntimeError
91+
raise RuntimeError('Config is not initialized')
8892
await self.add_index(index_config)
8993

94+
contracts = [index._config.contracts for index in self._indexes.values() if index._config.contracts]
95+
plain_contracts = reduce(operator.add, contracts)
96+
duplicate_contracts = [cast(ContractConfig, item).name for item, count in Counter(plain_contracts).items() if count > 1]
97+
if duplicate_contracts:
98+
self._logger.warning(
99+
"The following contracts are used in more than one index: %s. Make sure you know what you're doing.",
100+
' '.join(duplicate_contracts),
101+
)
102+
90103
self._ctx.reset()
91104

92105
async def dispatch_operations(self, datasource: TzktDatasource, operations: List[OperationData], block: HeadBlockData) -> None:

src/dipdup/utils.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
import pkgutil
77
import time
88
import types
9+
from collections import defaultdict
910
from contextlib import asynccontextmanager
11+
from functools import reduce
1012
from logging import Logger
1113
from os import listdir, makedirs
1214
from os.path import dirname, exists, getsize, join
13-
from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, TextIO, Tuple, Type
15+
from typing import Any, AsyncIterator, Callable, DefaultDict, Dict, Iterator, List, Optional, Sequence, TextIO, Tuple, Type, TypeVar
1416

1517
import humps # type: ignore
1618
from tortoise import Tortoise
@@ -147,6 +149,19 @@ def set_decimal_context(package: str) -> None:
147149
decimal.setcontext(context)
148150

149151

152+
_T = TypeVar('_T')
153+
_TT = TypeVar('_TT')
154+
155+
156+
def groupby(seq: Sequence[_T], key: Callable[[Any], _TT]) -> DefaultDict[_TT, List[_T]]:
157+
"""Group by key into defaultdict"""
158+
return reduce(
159+
lambda grp, val: grp[key(val)].append(val) or grp, # type: ignore
160+
seq,
161+
defaultdict(list),
162+
)
163+
164+
150165
class FormattedLogger(Logger):
151166
def __init__(
152167
self,

0 commit comments

Comments
 (0)