Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/dipdup/test/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import logging
from collections import deque
from contextlib import contextmanager
from contextlib import AsyncExitStack, contextmanager
from typing import AsyncGenerator, Deque, Iterator, Tuple
from unittest.mock import patch

from dipdup.config import DipDupConfig, SqliteDatabaseConfig
from dipdup.datasources.tzkt.datasource import OperationFetcher
from dipdup.dipdup import DipDup
from dipdup.index import OperationIndex
from dipdup.models import OperationData

Expand Down Expand Up @@ -54,3 +56,15 @@ def with_operation_index_fuzzer(levels=100, repeats=100) -> Iterator[None]:
with with_operation_fetcher_fuzzer(levels=levels, repeats=repeats):
with patch('dipdup.index.OperationIndex', OperationIndexFuzzer):
yield


async def create_test_dipdup(config: DipDupConfig, stack: AsyncExitStack) -> DipDup:
config.database = SqliteDatabaseConfig(kind='sqlite', path=':memory:')
config.initialize(skip_imports=True)

dipdup = DipDup(config)
await dipdup._create_datasources()
await dipdup._set_up_database(stack)
await dipdup._set_up_hooks()
await dipdup._initialize_schema()
return dipdup
25 changes: 7 additions & 18 deletions tests/test_dipdup/test_dipdup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,13 @@

from pytz import UTC

from dipdup.config import DipDupConfig, SqliteDatabaseConfig
from dipdup.config import DipDupConfig
from dipdup.context import pending_indexes
from dipdup.dipdup import DipDup, IndexDispatcher
from dipdup.dipdup import IndexDispatcher
from dipdup.enums import IndexStatus, IndexType
from dipdup.exceptions import ReindexingRequiredError
from dipdup.models import Index


async def _create_dipdup(config: DipDupConfig, stack: AsyncExitStack) -> DipDup:
config.database = SqliteDatabaseConfig(kind='sqlite', path=':memory:')
config.initialize(skip_imports=True)

dipdup = DipDup(config)
await dipdup._create_datasources()
await dipdup._set_up_database(stack)
await dipdup._set_up_hooks()
await dipdup._initialize_schema()
return dipdup
from dipdup.test import create_test_dipdup


async def _create_index(hash_: str) -> None:
Expand Down Expand Up @@ -58,7 +47,7 @@ async def asyncSetUp(self) -> None:
async def test_first_run(self) -> None:
async with AsyncExitStack() as stack:
# Arrange
dipdup = await _create_dipdup(self.config, stack)
dipdup = await create_test_dipdup(self.config, stack)
dispatcher = IndexDispatcher(dipdup._ctx)

# Act
Expand All @@ -72,7 +61,7 @@ async def test_first_run(self) -> None:
async def test_new_hash(self) -> None:
async with AsyncExitStack() as stack:
# Arrange
dipdup = await _create_dipdup(self.config, stack)
dipdup = await create_test_dipdup(self.config, stack)
dispatcher = IndexDispatcher(dipdup._ctx)
await _create_index(self.new_hash)

Expand All @@ -86,7 +75,7 @@ async def test_new_hash(self) -> None:
async def test_old_hash(self) -> None:
async with AsyncExitStack() as stack:
# Arrange
dipdup = await _create_dipdup(self.config, stack)
dipdup = await create_test_dipdup(self.config, stack)
dispatcher = IndexDispatcher(dipdup._ctx)
await _create_index(self.old_hash)

Expand All @@ -100,7 +89,7 @@ async def test_old_hash(self) -> None:
async def test_invalid_hash(self) -> None:
async with AsyncExitStack() as stack:
# Arrange
dipdup = await _create_dipdup(self.config, stack)
dipdup = await create_test_dipdup(self.config, stack)
dispatcher = IndexDispatcher(dipdup._ctx)
await _create_index('hehehe')

Expand Down
300 changes: 300 additions & 0 deletions tests/test_dipdup/test_index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
import datetime
from unittest import IsolatedAsyncioTestCase
from unittest.mock import AsyncMock

from dipdup.config import (
ContractConfig,
OperationHandlerConfig,
OperationHandlerTransactionPatternConfig,
OperationIndexConfig,
OperationType,
TzktDatasourceConfig,
)
from dipdup.index import OperationIndex
from dipdup.models import OperationData

add_liquidity_operations = (
OperationData(
type='transaction',
id=76905130,
level=1676582,
timestamp=datetime.datetime(2021, 9, 8, 16, 2, 14, tzinfo=datetime.timezone.utc),
hash='opWVrmpgeuQ2tz65DcV5USnCFW7j7x97XQ2BzEAcmefPEjUfkMw',
counter=15811432,
sender_address='tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
target_address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
initiator_address=None,
amount=None,
status='applied',
has_internals=True,
storage={
'admin': 'KT1Kfu13FmNbcZSjTPZLrAUbEYNZim6vtg6d',
'lpFee': '400',
'paused': False,
'token1Id': '0',
'token2Id': '0',
'systemFee': '1000',
'token1_Fee': '0',
'token2_Fee': '0',
'token1Check': False,
'token1_pool': '470000000000000000000',
'token2Check': False,
'token2_pool': '16000000',
'totalSupply': '86717933554715',
'maxSwapLimit': '40',
'token1Address': 'KT1GRSvLoikDsXujKgZPsGLX8k8VvR2Tq95b',
'token2Address': 'KT1TwzD6zV3WeJ39ukuqxcfK2fJCnhvrdN1X',
'lpTokenAddress': 'KT1NLZah1MKeWuveQvdsCqAUCjksKw8J296z',
},
block=None,
sender_alias=None,
nonce=None,
target_alias='PLENTY / SMAK Swap',
initiator_alias=None,
entrypoint='AddLiquidity',
parameter_json={
'recipient': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
'token1_max': '470000000000000000000',
'token2_max': '16000000',
},
originated_contract_address=None,
originated_contract_alias=None,
originated_contract_type_hash=None,
originated_contract_code_hash=None,
diffs=None,
),
OperationData(
type='transaction',
id=76905131,
level=1676582,
timestamp=datetime.datetime(2021, 9, 8, 16, 2, 14, tzinfo=datetime.timezone.utc),
hash='opWVrmpgeuQ2tz65DcV5USnCFW7j7x97XQ2BzEAcmefPEjUfkMw',
counter=15811432,
sender_address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
target_address='KT1GRSvLoikDsXujKgZPsGLX8k8VvR2Tq95b',
initiator_address='tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
amount=None,
status='applied',
has_internals=False,
storage={
'paused': False,
'balances': 3943,
'metadata': 3944,
'lastUpdate': '1676287',
'totalSupply': '14712639179877222051752285',
'administrator': 'KT1GpTEq4p2XZ8w9p5xM7Wayyw5VR7tb3UaW',
'token_metadata': 3945,
'tokensPerBlock': '50000000000000000000',
},
block=None,
sender_alias='PLENTY / SMAK Swap',
nonce=0,
target_alias='PLENTY',
initiator_alias=None,
entrypoint='transfer',
parameter_json={
'to': 'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
'from': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
'value': '470000000000000000000',
},
originated_contract_address=None,
originated_contract_alias=None,
originated_contract_type_hash=None,
originated_contract_code_hash=None,
diffs=[
{
'bigmap': 3943,
'path': 'balances',
'action': 'update_key',
'content': {
'hash': 'exprtkqafR3YBedPSHP6Lts8WVHn4jj853RfRZiTpzYNP8KKLaU12H',
'key': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
'value': {
'balance': '1141847967508578897233841',
'approvals': {
'KT19Dskaofi6ZTkrw3Tq4pK7fUqHqCz4pTZ3': '0',
'KT1AbuUaPQmYLsB8n8FdSzBrxvrsm8ctwW1V': '0',
'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU': '0',
'KT1HUnqM6xFJa51PM2xHfLs7s6ARvXungtyq': '0',
'KT1HZkD2T4uczgYkZ6fb9gm1fymeJoRuezLz': '9060000000000000000000',
'KT1NtsnKQ1c3rYB12ZToP77XaJs8WDBvF221': '0',
'KT1PuPNtDFLR6U7e7vDuxunDoKasVT6kMSkz': '0',
'KT1UNBvCJXiwJY6tmHM7CJUVwNPew53XkSfh': '0',
'KT1VeNQa4mucRj36qAJ9rTzm4DTJKfemVaZT': '0',
'KT1X1LgNkQShpF9nRLYw3Dgdy4qp38MX617z': '0',
'KT1XVrXmWY9AdVri6KpxKo4CWxizKajmgzMt': '0',
'KT1XXAavg3tTj12W1ADvd3EEnm1pu6XTmiEF': '550000000000000000',
'KT1XutoFJ9dXvWxT7ttG86N2tSTUEpatFVTm': '0',
},
},
},
},
{
'bigmap': 3943,
'path': 'balances',
'action': 'add_key',
'content': {
'hash': 'exprugvwjodjwqmGVVryY5uqz9fcg6BndukYj6bproCFShQ6nkuG8e',
'key': 'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
'value': {'balance': '470000000000000000000', 'approvals': {}},
},
},
],
),
OperationData(
type='transaction',
id=76905132,
level=1676582,
timestamp=datetime.datetime(2021, 9, 8, 16, 2, 14, tzinfo=datetime.timezone.utc),
hash='opWVrmpgeuQ2tz65DcV5USnCFW7j7x97XQ2BzEAcmefPEjUfkMw',
counter=15811432,
sender_address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
target_address='KT1TwzD6zV3WeJ39ukuqxcfK2fJCnhvrdN1X',
initiator_address='tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
amount=None,
status='applied',
has_internals=False,
storage={
'freezer': 'KT1TwzD6zV3WeJ39ukuqxcfK2fJCnhvrdN1X',
'balances': 1798,
'metadata': 1800,
'totalSupply': '896083333000',
'administrator': 'KT1TwzD6zV3WeJ39ukuqxcfK2fJCnhvrdN1X',
'token_metadata': 1801,
'frozen_accounts': 1799,
},
block=None,
sender_alias='PLENTY / SMAK Swap',
nonce=1,
target_alias='Smartlink',
initiator_alias=None,
entrypoint='transfer',
parameter_json={'to': 'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU', 'from': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4', 'value': '16000000'},
originated_contract_address=None,
originated_contract_alias=None,
originated_contract_type_hash=None,
originated_contract_code_hash=None,
diffs=[
{
'bigmap': 1798,
'path': 'balances',
'action': 'update_key',
'content': {
'hash': 'exprtkqafR3YBedPSHP6Lts8WVHn4jj853RfRZiTpzYNP8KKLaU12H',
'key': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
'value': {'balance': '208684', 'approvals': {'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU': '0'}},
},
},
{
'bigmap': 1798,
'path': 'balances',
'action': 'add_key',
'content': {
'hash': 'exprugvwjodjwqmGVVryY5uqz9fcg6BndukYj6bproCFShQ6nkuG8e',
'key': 'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
'value': {'balance': '16000000', 'approvals': {}},
},
},
],
),
OperationData(
type='transaction',
id=76905133,
level=1676582,
timestamp=datetime.datetime(2021, 9, 8, 16, 2, 14, tzinfo=datetime.timezone.utc),
hash='opWVrmpgeuQ2tz65DcV5USnCFW7j7x97XQ2BzEAcmefPEjUfkMw',
counter=15811432,
sender_address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
target_address='KT1NLZah1MKeWuveQvdsCqAUCjksKw8J296z',
initiator_address='tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
amount=None,
status='applied',
has_internals=False,
storage={
'balances': 14107,
'metadata': 14108,
'totalSupply': '86717933554615',
'administrator': 'tz1ZnK6zYJrC9PfKCPryg9tPW6LrERisTGtg',
'securityCheck': True,
'token_metadata': 14109,
'exchangeAddress': 'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
},
block=None,
sender_alias='PLENTY / SMAK Swap',
nonce=2,
target_alias='PLENTY / SMAK LP Token',
initiator_alias=None,
entrypoint='mint',
parameter_json={'value': '86717933554615', 'address': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4'},
originated_contract_address=None,
originated_contract_alias=None,
originated_contract_type_hash=None,
originated_contract_code_hash=None,
diffs=[
{
'bigmap': 14107,
'path': 'balances',
'action': 'add_key',
'content': {
'hash': 'exprtkqafR3YBedPSHP6Lts8WVHn4jj853RfRZiTpzYNP8KKLaU12H',
'key': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
'value': {'balance': '86717933554615', 'approvals': {}},
},
}
],
),
)

index_config = OperationIndexConfig(
datasource=TzktDatasourceConfig(kind='tzkt', url='https://api.tzkt.io', http=None),
kind='operation',
handlers=[
OperationHandlerConfig(
callback='on_fa12_and_fa12_add_liquidity',
pattern=[
OperationHandlerTransactionPatternConfig(
type='transaction',
source=None,
destination=ContractConfig(address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU', typename='plenty_smak_amm'),
entrypoint='AddLiquidity',
optional=False,
),
OperationHandlerTransactionPatternConfig(
type='transaction',
source=None,
destination=ContractConfig(address='KT1GRSvLoikDsXujKgZPsGLX8k8VvR2Tq95b', typename='plenty_token'),
entrypoint='transfer',
optional=False,
),
OperationHandlerTransactionPatternConfig(
type='transaction',
source=None,
destination=ContractConfig(address='KT1TwzD6zV3WeJ39ukuqxcfK2fJCnhvrdN1X', typename='smak_token'),
entrypoint='transfer',
optional=False,
),
OperationHandlerTransactionPatternConfig(
type='transaction',
source=None,
destination=ContractConfig(address='KT1NLZah1MKeWuveQvdsCqAUCjksKw8J296z', typename='plenty_smak_lp'),
entrypoint='mint',
optional=False,
),
],
),
],
types=[OperationType.transaction, OperationType.origination],
contracts=[ContractConfig(address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU', typename='plenty_smak_amm')],
first_level=0,
last_level=0,
)
index_config.name = 'asdf'


class MatcherTest(IsolatedAsyncioTestCase):
async def test_match_smak_add_liquidity(self) -> None:
index = OperationIndex(None, index_config, None) # type: ignore
index._prepare_handler_args = AsyncMock() # type: ignore
matched_operations = await index._match_operations(add_liquidity_operations)
index._prepare_handler_args.assert_called()
self.assertEqual(len(matched_operations), 1)