Skip to content

Commit

Permalink
Allow using evm.node as index datasource (#997)
Browse files Browse the repository at this point in the history
  • Loading branch information
droserasprout authored Apr 15, 2024
1 parent 60afd56 commit d19f799
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 48 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog], and this project adheres to [Semantic Versioning].

## [Unreleased]

### Added

- evm.subsquid: `evm.node` datasources can be used as index datasources.

## [7.5.4] - 2024-04-09

### Fixed
Expand Down
10 changes: 5 additions & 5 deletions docs/7.references/2.config.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,12 @@ description: "Config file reference"
<dt class="field-odd" style="color: var(--txt-primary);">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>kind</strong> (<em>Literal</em><em>[</em><em>'evm.subsquid.events'</em><em>]</em>) – Always ‘evm.subsquid.events’</p></li>
<li><p><strong>datasource</strong> (<em>str</em><em> | </em><a class="reference internal" href="#dipdupconfigevm_subsquidsubsquiddatasourceconfig" title="dipdup.config.evm_subsquid.SubsquidDatasourceConfig" target="_self"><em>SubsquidDatasourceConfig</em></a>) – Subsquid datasource</p></li>
<li><p><strong>datasource</strong> (<em>str</em><em> | </em><a class="reference internal" href="#dipdupconfigevm_subsquidsubsquiddatasourceconfig" title="dipdup.config.evm_subsquid.SubsquidDatasourceConfig" target="_self"><em>SubsquidDatasourceConfig</em></a><em> | </em><a class="reference internal" href="#dipdupconfigevm_nodeevmnodedatasourceconfig" title="dipdup.config.evm_node.EvmNodeDatasourceConfig" target="_self"><em>EvmNodeDatasourceConfig</em></a>) – Subsquid datasource</p></li>
<li><p><strong>handlers</strong> (<em>tuple</em><em>[</em><a class="reference internal" href="#dipdupconfigevm_subsquid_eventssubsquideventshandlerconfig" title="dipdup.config.evm_subsquid_events.SubsquidEventsHandlerConfig" target="_self"><em>SubsquidEventsHandlerConfig</em></a><em>, </em><em>...</em><em>]</em>) – Event handlers</p></li>
<li><p><strong>abi</strong> (<a class="reference internal" href="#dipdupconfigabidatasourceconfig" title="dipdup.config.AbiDatasourceConfig" target="_self"><em>AbiDatasourceConfig</em></a><em> | </em><em>tuple</em><em>[</em><a class="reference internal" href="#dipdupconfigabidatasourceconfig" title="dipdup.config.AbiDatasourceConfig" target="_self"><em>AbiDatasourceConfig</em></a><em>, </em><em>...</em><em>] </em><em>| </em><em>None</em>) – One or more <cite>evm.abi</cite> datasource(s) for the same network</p></li>
<li><p><strong>node_only</strong> (<em>bool</em>) – Don’t use Subsquid Network API (dev only)</p></li>
<li><p><strong>first_level</strong> (<em>int</em>) – Level to start indexing from</p></li>
<li><p><strong>last_level</strong> (<em>int</em>) – Level to stop indexing and disable this index</p></li>
<li><p><strong>node_only</strong> (<em>bool</em>) – </p></li>
</ul>
</dd>
</dl>
Expand Down Expand Up @@ -258,7 +258,7 @@ description: "Config file reference"
<dt class="field-odd" style="color: var(--txt-primary);">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>kind</strong> (<em>str</em>) – starts with ‘evm.subsquid’</p></li>
<li><p><strong>datasource</strong> (<em>str</em><em> | </em><a class="reference internal" href="#dipdupconfigevm_subsquidsubsquiddatasourceconfig" title="dipdup.config.evm_subsquid.SubsquidDatasourceConfig" target="_self"><em>SubsquidDatasourceConfig</em></a>) – Subsquid datasource config</p></li>
<li><p><strong>datasource</strong> (<em>str</em><em> | </em><a class="reference internal" href="#dipdupconfigevm_subsquidsubsquiddatasourceconfig" title="dipdup.config.evm_subsquid.SubsquidDatasourceConfig" target="_self"><em>SubsquidDatasourceConfig</em></a><em> | </em><a class="reference internal" href="#dipdupconfigevm_nodeevmnodedatasourceconfig" title="dipdup.config.evm_node.EvmNodeDatasourceConfig" target="_self"><em>EvmNodeDatasourceConfig</em></a>) – Subsquid datasource config</p></li>
</ul>
</dd>
</dl>
Expand Down Expand Up @@ -293,12 +293,12 @@ description: "Config file reference"
<dt class="field-odd" style="color: var(--txt-primary);">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>kind</strong> (<em>Literal</em><em>[</em><em>'evm.subsquid.transactions'</em><em>]</em>) – always ‘evm.subsquid.transactions’</p></li>
<li><p><strong>datasource</strong> (<em>str</em><em> | </em><a class="reference internal" href="#dipdupconfigevm_subsquidsubsquiddatasourceconfig" title="dipdup.config.evm_subsquid.SubsquidDatasourceConfig" target="_self"><em>SubsquidDatasourceConfig</em></a>) – Subsquid datasource config</p></li>
<li><p><strong>datasource</strong> (<em>str</em><em> | </em><a class="reference internal" href="#dipdupconfigevm_subsquidsubsquiddatasourceconfig" title="dipdup.config.evm_subsquid.SubsquidDatasourceConfig" target="_self"><em>SubsquidDatasourceConfig</em></a><em> | </em><a class="reference internal" href="#dipdupconfigevm_nodeevmnodedatasourceconfig" title="dipdup.config.evm_node.EvmNodeDatasourceConfig" target="_self"><em>EvmNodeDatasourceConfig</em></a>) – Subsquid datasource config</p></li>
<li><p><strong>handlers</strong> (<em>tuple</em><em>[</em><a class="reference internal" href="#dipdupconfigevm_subsquid_transactionssubsquidtransactionshandlerconfig" title="dipdup.config.evm_subsquid_transactions.SubsquidTransactionsHandlerConfig" target="_self"><em>SubsquidTransactionsHandlerConfig</em></a><em>, </em><em>...</em><em>]</em>) – Transaction handlers</p></li>
<li><p><strong>abi</strong> (<a class="reference internal" href="#dipdupconfigabidatasourceconfig" title="dipdup.config.AbiDatasourceConfig" target="_self"><em>AbiDatasourceConfig</em></a><em> | </em><em>tuple</em><em>[</em><a class="reference internal" href="#dipdupconfigabidatasourceconfig" title="dipdup.config.AbiDatasourceConfig" target="_self"><em>AbiDatasourceConfig</em></a><em>, </em><em>...</em><em>] </em><em>| </em><em>None</em>) – One or many ABI datasource(s)</p></li>
<li><p><strong>node_only</strong> (<em>bool</em>) – Don’t use Subsquid Network, only node RPC</p></li>
<li><p><strong>first_level</strong> (<em>int</em>) – Level to start indexing from</p></li>
<li><p><strong>last_level</strong> (<em>int</em>) – Level to stop indexing at</p></li>
<li><p><strong>node_only</strong> (<em>bool</em>) – </p></li>
</ul>
</dd>
</dl>
Expand Down
21 changes: 21 additions & 0 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2003,6 +2003,13 @@
"$ref": "#/$defs/SubsquidDatasourceConfig"
}
]
},
{
"allOf": [
{
"$ref": "#/$defs/EvmNodeDatasourceConfig"
}
]
}
]
},
Expand Down Expand Up @@ -2092,6 +2099,13 @@
"$ref": "#/$defs/SubsquidDatasourceConfig"
}
]
},
{
"allOf": [
{
"$ref": "#/$defs/EvmNodeDatasourceConfig"
}
]
}
]
},
Expand Down Expand Up @@ -2228,6 +2242,13 @@
"$ref": "#/$defs/SubsquidDatasourceConfig"
}
]
},
{
"allOf": [
{
"$ref": "#/$defs/EvmNodeDatasourceConfig"
}
]
}
]
},
Expand Down
15 changes: 10 additions & 5 deletions src/dipdup/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,12 +934,16 @@ def _resolve_index_links(self, index_config: ResolvedIndexConfigU) -> None:
"""
handler_config: HandlerConfig

# NOTE: Each index must have a corresponding (currently) TzKT datasource
# NOTE: Each index must have a corresponding index datasource
if isinstance(index_config.datasource, str):
if 'tzkt' in index_config.kind:
index_config.datasource = self.get_tzkt_datasource(index_config.datasource)
elif 'subsquid' in index_config.kind:
index_config.datasource = self.get_subsquid_datasource(index_config.datasource)
name = index_config.datasource
if index_config.kind.startswith('tezos.tzkt'):
index_config.datasource = self.get_tzkt_datasource(name)
elif index_config.kind.startswith('evm.subsquid'):
try:
index_config.datasource = self.get_subsquid_datasource(name)
except ConfigurationError:
index_config.datasource = self.get_evm_node_datasource(name)
else:
raise FrameworkException(f'Unknown datasource type for index `{index_config.name}`')

Expand Down Expand Up @@ -1150,6 +1154,7 @@ def _patch_annotations(replace_table: dict[str, str]) -> None:
_original_to_aliased = {
'TzktDatasourceConfig': 'str | TzktDatasourceConfig',
'SubsquidDatasourceConfig': 'str | SubsquidDatasourceConfig',
'SubsquidDatasourceConfig | EvmNodeDatasourceConfig': 'str | SubsquidDatasourceConfig | EvmNodeDatasourceConfig',
'ContractConfig': 'str | ContractConfig',
'ContractConfig | None': 'str | ContractConfig | None',
'TezosContractConfig': 'str | TezosContractConfig',
Expand Down
2 changes: 1 addition & 1 deletion src/dipdup/config/evm_subsquid.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@ class SubsquidIndexConfig(IndexConfig, ABC):
:param datasource: Subsquid datasource config
"""

datasource: SubsquidDatasourceConfig
datasource: SubsquidDatasourceConfig | EvmNodeDatasourceConfig
4 changes: 2 additions & 2 deletions src/dipdup/config/evm_subsquid_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from dipdup.config import AbiDatasourceConfig
from dipdup.config import HandlerConfig
from dipdup.config.evm import EvmContractConfig
from dipdup.config.evm_node import EvmNodeDatasourceConfig
from dipdup.config.evm_subsquid import SubsquidDatasourceConfig
from dipdup.config.evm_subsquid import SubsquidIndexConfig
from dipdup.models.evm_node import EvmNodeHeadSubscription
Expand Down Expand Up @@ -60,13 +61,12 @@ class SubsquidEventsIndexConfig(SubsquidIndexConfig):
:param datasource: Subsquid datasource
:param handlers: Event handlers
:param abi: One or more `evm.abi` datasource(s) for the same network
:param node_only: Don't use Subsquid Network API (dev only)
:param first_level: Level to start indexing from
:param last_level: Level to stop indexing and disable this index
"""

kind: Literal['evm.subsquid.events']
datasource: SubsquidDatasourceConfig
datasource: SubsquidDatasourceConfig | EvmNodeDatasourceConfig
handlers: tuple[SubsquidEventsHandlerConfig, ...] = field(default_factory=tuple)
abi: AbiDatasourceConfig | tuple[AbiDatasourceConfig, ...] | None = None
node_only: bool = False
Expand Down
3 changes: 2 additions & 1 deletion src/dipdup/config/evm_subsquid_traces.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from dipdup.config import AbiDatasourceConfig
from dipdup.config import HandlerConfig
from dipdup.config.evm_node import EvmNodeDatasourceConfig
from dipdup.config.evm_subsquid import SubsquidDatasourceConfig
from dipdup.config.evm_subsquid import SubsquidIndexConfig

Expand All @@ -21,7 +22,7 @@ class SubsquidTracesHandlerConfig(HandlerConfig): ...
class SubsquidTracesIndexConfig(SubsquidIndexConfig):
kind: Literal['evm.subsquid.traces']

datasource: SubsquidDatasourceConfig
datasource: SubsquidDatasourceConfig | EvmNodeDatasourceConfig
handlers: tuple[SubsquidTracesHandlerConfig, ...] = field(default_factory=tuple)
abi: AbiDatasourceConfig | tuple[AbiDatasourceConfig, ...] | None = None
node_only: bool = False
Expand Down
4 changes: 2 additions & 2 deletions src/dipdup/config/evm_subsquid_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from dipdup.config import CodegenMixin
from dipdup.config import HandlerConfig
from dipdup.config.evm import EvmContractConfig
from dipdup.config.evm_node import EvmNodeDatasourceConfig
from dipdup.config.evm_subsquid import SubsquidDatasourceConfig
from dipdup.config.evm_subsquid import SubsquidIndexConfig
from dipdup.models.evm_node import EvmNodeHeadSubscription
Expand Down Expand Up @@ -76,14 +77,13 @@ class SubsquidTransactionsIndexConfig(SubsquidIndexConfig):
:param datasource: Subsquid datasource config
:param handlers: Transaction handlers
:param abi: One or many ABI datasource(s)
:param node_only: Don't use Subsquid Network, only node RPC
:param first_level: Level to start indexing from
:param last_level: Level to stop indexing at
"""

kind: Literal['evm.subsquid.transactions']

datasource: SubsquidDatasourceConfig
datasource: SubsquidDatasourceConfig | EvmNodeDatasourceConfig
handlers: tuple[SubsquidTransactionsHandlerConfig, ...] = field(default_factory=tuple)
abi: AbiDatasourceConfig | tuple[AbiDatasourceConfig, ...] | None = None
node_only: bool = False
Expand Down
35 changes: 21 additions & 14 deletions src/dipdup/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from dipdup.config import HookConfig
from dipdup.config import ResolvedIndexConfigU
from dipdup.config.evm import EvmContractConfig
from dipdup.config.evm_node import EvmNodeDatasourceConfig
from dipdup.config.evm_subsquid import SubsquidDatasourceConfig
from dipdup.config.evm_subsquid_events import SubsquidEventsIndexConfig
from dipdup.config.evm_subsquid_traces import SubsquidTracesIndexConfig
from dipdup.config.evm_subsquid_transactions import SubsquidTransactionsIndexConfig
Expand Down Expand Up @@ -76,7 +78,6 @@
from collections.abc import Iterator
from types import ModuleType

from dipdup.config.evm_node import EvmNodeDatasourceConfig
from dipdup.package import DipDupPackage
from dipdup.transactions import TransactionManager

Expand Down Expand Up @@ -320,8 +321,7 @@ async def _spawn_index(self, name: str, state: Index | None = None) -> Any:
)

datasource_name = index_config.datasource.name
datasource: TzktDatasource | SubsquidDatasource
node_configs: tuple[EvmNodeDatasourceConfig, ...] = ()
datasource: TzktDatasource | SubsquidDatasource | EvmNodeDatasource

if isinstance(index_config, TzktOperationsIndexConfig | TzktOperationsUnfilteredIndexConfig):
datasource = self.get_tzkt_datasource(datasource_name)
Expand All @@ -342,26 +342,33 @@ async def _spawn_index(self, name: str, state: Index | None = None) -> Any:
datasource = self.get_tzkt_datasource(datasource_name)
index = TzktEventsIndex(self, index_config, datasource)
elif isinstance(index_config, SubsquidEventsIndexConfig):
datasource = self.get_subsquid_datasource(datasource_name)
node_field = index_config.datasource.node
if node_field:
node_configs = node_configs + node_field if isinstance(node_field, tuple) else (node_field,)
datasource_config = index_config.datasource
if isinstance(datasource_config, SubsquidDatasourceConfig):
datasource = self.get_subsquid_datasource(datasource_name)
elif isinstance(datasource_config, EvmNodeDatasourceConfig):
datasource = self.get_evm_node_datasource(datasource_name)
else:
raise NotImplementedError
index = SubsquidEventsIndex(self, index_config, datasource)
for node_datasource in index.node_datasources:
node_datasource.add_index(index_config)
elif isinstance(index_config, SubsquidTracesIndexConfig):
raise NotImplementedError
elif isinstance(index_config, SubsquidTransactionsIndexConfig):
datasource = self.get_subsquid_datasource(datasource_name)
node_field = index_config.datasource.node
if node_field:
node_configs = node_configs + node_field if isinstance(node_field, tuple) else (node_field,)
datasource_config = index_config.datasource
if isinstance(datasource_config, SubsquidDatasourceConfig):
datasource = self.get_subsquid_datasource(datasource_name)
elif isinstance(datasource_config, EvmNodeDatasourceConfig):
datasource = self.get_evm_node_datasource(datasource_name)
else:
raise NotImplementedError
index = SubsquidTransactionsIndex(self, index_config, datasource)
for node_datasource in index.node_datasources:
node_datasource.add_index(index_config)
else:
raise NotImplementedError

datasource.add_index(index_config)
for node_config in node_configs:
node_datasource = self.get_evm_node_datasource(node_config.name)
node_datasource.add_index(index_config)

handlers = (
(index_config.handler_config,)
Expand Down
32 changes: 21 additions & 11 deletions src/dipdup/indexes/evm_subsquid.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from dipdup.config import SubsquidIndexConfigU
from dipdup.config.evm import EvmContractConfig
from dipdup.config.evm_node import EvmNodeDatasourceConfig
from dipdup.config.evm_subsquid import SubsquidDatasourceConfig
from dipdup.context import DipDupContext
from dipdup.datasources import IndexDatasource
from dipdup.datasources.evm_node import NODE_LAST_MILE
Expand All @@ -27,7 +28,7 @@
SUBSQUID_READAHEAD_LIMIT = 10000

IndexConfigT = TypeVar('IndexConfigT', bound=SubsquidIndexConfigU)
DatasourceT = TypeVar('DatasourceT', bound=SubsquidDatasource)
DatasourceT = TypeVar('DatasourceT', bound=SubsquidDatasource | EvmNodeDatasource)


_sighashes: dict[str, str] = {}
Expand Down Expand Up @@ -62,14 +63,19 @@ def __init__(
) -> None:
super().__init__(ctx, config, datasource)

node_field = self._config.datasource.node
if node_field is None:
node_field = ()
elif isinstance(node_field, EvmNodeDatasourceConfig):
node_field = (node_field,)
self._node_datasources = tuple(
self._ctx.get_evm_node_datasource(node_config.name) for node_config in node_field
)
if isinstance(datasource, SubsquidDatasource) and isinstance(config.datasource, SubsquidDatasourceConfig):
node_field = config.datasource.node
if node_field is None:
node_field = ()
elif isinstance(node_field, EvmNodeDatasourceConfig):
node_field = (node_field,)
self._node_datasources = tuple(
self._ctx.get_evm_node_datasource(node_config.name) for node_config in node_field
)
elif isinstance(datasource, EvmNodeDatasource) and isinstance(config.datasource, EvmNodeDatasourceConfig):
self._node_datasources = (datasource,)
else:
raise FrameworkException('Invalid datasource type')

@abstractmethod
async def _synchronize_subsquid(self, sync_level: int) -> None: ...
Expand Down Expand Up @@ -133,8 +139,12 @@ async def _synchronize(self, sync_level: int) -> None:
if levels_left <= 0:
return

subsquid_sync_level = await self.datasource.get_head_level()
Metrics.set_sqd_processor_chain_height(subsquid_sync_level)
if isinstance(self.datasource, SubsquidDatasource):
subsquid_sync_level = await self.datasource.get_head_level()
Metrics.set_sqd_processor_chain_height(subsquid_sync_level)
else:
subsquid_sync_level = 0

node_sync_level = await self._get_node_sync_level(subsquid_sync_level, index_level)

# NOTE: Fetch last blocks from node if there are not enough realtime messages in queue
Expand Down
Loading

0 comments on commit d19f799

Please sign in to comment.