Skip to content

Commit 950b086

Browse files
Operation matching tests (#162)
1 parent 49b0c1e commit 950b086

File tree

3 files changed

+322
-19
lines changed

3 files changed

+322
-19
lines changed

src/dipdup/test/__init__.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import logging
22
from collections import deque
3-
from contextlib import contextmanager
3+
from contextlib import AsyncExitStack, contextmanager
44
from typing import AsyncGenerator, Deque, Iterator, Tuple
55
from unittest.mock import patch
66

7+
from dipdup.config import DipDupConfig, SqliteDatabaseConfig
78
from dipdup.datasources.tzkt.datasource import OperationFetcher
9+
from dipdup.dipdup import DipDup
810
from dipdup.index import OperationIndex
911
from dipdup.models import OperationData
1012

@@ -54,3 +56,15 @@ def with_operation_index_fuzzer(levels=100, repeats=100) -> Iterator[None]:
5456
with with_operation_fetcher_fuzzer(levels=levels, repeats=repeats):
5557
with patch('dipdup.index.OperationIndex', OperationIndexFuzzer):
5658
yield
59+
60+
61+
async def create_test_dipdup(config: DipDupConfig, stack: AsyncExitStack) -> DipDup:
62+
config.database = SqliteDatabaseConfig(kind='sqlite', path=':memory:')
63+
config.initialize(skip_imports=True)
64+
65+
dipdup = DipDup(config)
66+
await dipdup._create_datasources()
67+
await dipdup._set_up_database(stack)
68+
await dipdup._set_up_hooks()
69+
await dipdup._initialize_schema()
70+
return dipdup

tests/test_dipdup/test_dipdup.py

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,13 @@
55

66
from pytz import UTC
77

8-
from dipdup.config import DipDupConfig, SqliteDatabaseConfig
8+
from dipdup.config import DipDupConfig
99
from dipdup.context import pending_indexes
10-
from dipdup.dipdup import DipDup, IndexDispatcher
10+
from dipdup.dipdup import IndexDispatcher
1111
from dipdup.enums import IndexStatus, IndexType
1212
from dipdup.exceptions import ReindexingRequiredError
1313
from dipdup.models import Index
14-
15-
16-
async def _create_dipdup(config: DipDupConfig, stack: AsyncExitStack) -> DipDup:
17-
config.database = SqliteDatabaseConfig(kind='sqlite', path=':memory:')
18-
config.initialize(skip_imports=True)
19-
20-
dipdup = DipDup(config)
21-
await dipdup._create_datasources()
22-
await dipdup._set_up_database(stack)
23-
await dipdup._set_up_hooks()
24-
await dipdup._initialize_schema()
25-
return dipdup
14+
from dipdup.test import create_test_dipdup
2615

2716

2817
async def _create_index(hash_: str) -> None:
@@ -58,7 +47,7 @@ async def asyncSetUp(self) -> None:
5847
async def test_first_run(self) -> None:
5948
async with AsyncExitStack() as stack:
6049
# Arrange
61-
dipdup = await _create_dipdup(self.config, stack)
50+
dipdup = await create_test_dipdup(self.config, stack)
6251
dispatcher = IndexDispatcher(dipdup._ctx)
6352

6453
# Act
@@ -72,7 +61,7 @@ async def test_first_run(self) -> None:
7261
async def test_new_hash(self) -> None:
7362
async with AsyncExitStack() as stack:
7463
# Arrange
75-
dipdup = await _create_dipdup(self.config, stack)
64+
dipdup = await create_test_dipdup(self.config, stack)
7665
dispatcher = IndexDispatcher(dipdup._ctx)
7766
await _create_index(self.new_hash)
7867

@@ -86,7 +75,7 @@ async def test_new_hash(self) -> None:
8675
async def test_old_hash(self) -> None:
8776
async with AsyncExitStack() as stack:
8877
# Arrange
89-
dipdup = await _create_dipdup(self.config, stack)
78+
dipdup = await create_test_dipdup(self.config, stack)
9079
dispatcher = IndexDispatcher(dipdup._ctx)
9180
await _create_index(self.old_hash)
9281

@@ -100,7 +89,7 @@ async def test_old_hash(self) -> None:
10089
async def test_invalid_hash(self) -> None:
10190
async with AsyncExitStack() as stack:
10291
# Arrange
103-
dipdup = await _create_dipdup(self.config, stack)
92+
dipdup = await create_test_dipdup(self.config, stack)
10493
dispatcher = IndexDispatcher(dipdup._ctx)
10594
await _create_index('hehehe')
10695

tests/test_dipdup/test_index.py

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
import datetime
2+
from unittest import IsolatedAsyncioTestCase
3+
from unittest.mock import AsyncMock
4+
5+
from dipdup.config import (
6+
ContractConfig,
7+
OperationHandlerConfig,
8+
OperationHandlerTransactionPatternConfig,
9+
OperationIndexConfig,
10+
OperationType,
11+
TzktDatasourceConfig,
12+
)
13+
from dipdup.index import OperationIndex
14+
from dipdup.models import OperationData
15+
16+
add_liquidity_operations = (
17+
OperationData(
18+
type='transaction',
19+
id=76905130,
20+
level=1676582,
21+
timestamp=datetime.datetime(2021, 9, 8, 16, 2, 14, tzinfo=datetime.timezone.utc),
22+
hash='opWVrmpgeuQ2tz65DcV5USnCFW7j7x97XQ2BzEAcmefPEjUfkMw',
23+
counter=15811432,
24+
sender_address='tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
25+
target_address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
26+
initiator_address=None,
27+
amount=None,
28+
status='applied',
29+
has_internals=True,
30+
storage={
31+
'admin': 'KT1Kfu13FmNbcZSjTPZLrAUbEYNZim6vtg6d',
32+
'lpFee': '400',
33+
'paused': False,
34+
'token1Id': '0',
35+
'token2Id': '0',
36+
'systemFee': '1000',
37+
'token1_Fee': '0',
38+
'token2_Fee': '0',
39+
'token1Check': False,
40+
'token1_pool': '470000000000000000000',
41+
'token2Check': False,
42+
'token2_pool': '16000000',
43+
'totalSupply': '86717933554715',
44+
'maxSwapLimit': '40',
45+
'token1Address': 'KT1GRSvLoikDsXujKgZPsGLX8k8VvR2Tq95b',
46+
'token2Address': 'KT1TwzD6zV3WeJ39ukuqxcfK2fJCnhvrdN1X',
47+
'lpTokenAddress': 'KT1NLZah1MKeWuveQvdsCqAUCjksKw8J296z',
48+
},
49+
block=None,
50+
sender_alias=None,
51+
nonce=None,
52+
target_alias='PLENTY / SMAK Swap',
53+
initiator_alias=None,
54+
entrypoint='AddLiquidity',
55+
parameter_json={
56+
'recipient': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
57+
'token1_max': '470000000000000000000',
58+
'token2_max': '16000000',
59+
},
60+
originated_contract_address=None,
61+
originated_contract_alias=None,
62+
originated_contract_type_hash=None,
63+
originated_contract_code_hash=None,
64+
diffs=None,
65+
),
66+
OperationData(
67+
type='transaction',
68+
id=76905131,
69+
level=1676582,
70+
timestamp=datetime.datetime(2021, 9, 8, 16, 2, 14, tzinfo=datetime.timezone.utc),
71+
hash='opWVrmpgeuQ2tz65DcV5USnCFW7j7x97XQ2BzEAcmefPEjUfkMw',
72+
counter=15811432,
73+
sender_address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
74+
target_address='KT1GRSvLoikDsXujKgZPsGLX8k8VvR2Tq95b',
75+
initiator_address='tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
76+
amount=None,
77+
status='applied',
78+
has_internals=False,
79+
storage={
80+
'paused': False,
81+
'balances': 3943,
82+
'metadata': 3944,
83+
'lastUpdate': '1676287',
84+
'totalSupply': '14712639179877222051752285',
85+
'administrator': 'KT1GpTEq4p2XZ8w9p5xM7Wayyw5VR7tb3UaW',
86+
'token_metadata': 3945,
87+
'tokensPerBlock': '50000000000000000000',
88+
},
89+
block=None,
90+
sender_alias='PLENTY / SMAK Swap',
91+
nonce=0,
92+
target_alias='PLENTY',
93+
initiator_alias=None,
94+
entrypoint='transfer',
95+
parameter_json={
96+
'to': 'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
97+
'from': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
98+
'value': '470000000000000000000',
99+
},
100+
originated_contract_address=None,
101+
originated_contract_alias=None,
102+
originated_contract_type_hash=None,
103+
originated_contract_code_hash=None,
104+
diffs=[
105+
{
106+
'bigmap': 3943,
107+
'path': 'balances',
108+
'action': 'update_key',
109+
'content': {
110+
'hash': 'exprtkqafR3YBedPSHP6Lts8WVHn4jj853RfRZiTpzYNP8KKLaU12H',
111+
'key': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
112+
'value': {
113+
'balance': '1141847967508578897233841',
114+
'approvals': {
115+
'KT19Dskaofi6ZTkrw3Tq4pK7fUqHqCz4pTZ3': '0',
116+
'KT1AbuUaPQmYLsB8n8FdSzBrxvrsm8ctwW1V': '0',
117+
'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU': '0',
118+
'KT1HUnqM6xFJa51PM2xHfLs7s6ARvXungtyq': '0',
119+
'KT1HZkD2T4uczgYkZ6fb9gm1fymeJoRuezLz': '9060000000000000000000',
120+
'KT1NtsnKQ1c3rYB12ZToP77XaJs8WDBvF221': '0',
121+
'KT1PuPNtDFLR6U7e7vDuxunDoKasVT6kMSkz': '0',
122+
'KT1UNBvCJXiwJY6tmHM7CJUVwNPew53XkSfh': '0',
123+
'KT1VeNQa4mucRj36qAJ9rTzm4DTJKfemVaZT': '0',
124+
'KT1X1LgNkQShpF9nRLYw3Dgdy4qp38MX617z': '0',
125+
'KT1XVrXmWY9AdVri6KpxKo4CWxizKajmgzMt': '0',
126+
'KT1XXAavg3tTj12W1ADvd3EEnm1pu6XTmiEF': '550000000000000000',
127+
'KT1XutoFJ9dXvWxT7ttG86N2tSTUEpatFVTm': '0',
128+
},
129+
},
130+
},
131+
},
132+
{
133+
'bigmap': 3943,
134+
'path': 'balances',
135+
'action': 'add_key',
136+
'content': {
137+
'hash': 'exprugvwjodjwqmGVVryY5uqz9fcg6BndukYj6bproCFShQ6nkuG8e',
138+
'key': 'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
139+
'value': {'balance': '470000000000000000000', 'approvals': {}},
140+
},
141+
},
142+
],
143+
),
144+
OperationData(
145+
type='transaction',
146+
id=76905132,
147+
level=1676582,
148+
timestamp=datetime.datetime(2021, 9, 8, 16, 2, 14, tzinfo=datetime.timezone.utc),
149+
hash='opWVrmpgeuQ2tz65DcV5USnCFW7j7x97XQ2BzEAcmefPEjUfkMw',
150+
counter=15811432,
151+
sender_address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
152+
target_address='KT1TwzD6zV3WeJ39ukuqxcfK2fJCnhvrdN1X',
153+
initiator_address='tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
154+
amount=None,
155+
status='applied',
156+
has_internals=False,
157+
storage={
158+
'freezer': 'KT1TwzD6zV3WeJ39ukuqxcfK2fJCnhvrdN1X',
159+
'balances': 1798,
160+
'metadata': 1800,
161+
'totalSupply': '896083333000',
162+
'administrator': 'KT1TwzD6zV3WeJ39ukuqxcfK2fJCnhvrdN1X',
163+
'token_metadata': 1801,
164+
'frozen_accounts': 1799,
165+
},
166+
block=None,
167+
sender_alias='PLENTY / SMAK Swap',
168+
nonce=1,
169+
target_alias='Smartlink',
170+
initiator_alias=None,
171+
entrypoint='transfer',
172+
parameter_json={'to': 'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU', 'from': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4', 'value': '16000000'},
173+
originated_contract_address=None,
174+
originated_contract_alias=None,
175+
originated_contract_type_hash=None,
176+
originated_contract_code_hash=None,
177+
diffs=[
178+
{
179+
'bigmap': 1798,
180+
'path': 'balances',
181+
'action': 'update_key',
182+
'content': {
183+
'hash': 'exprtkqafR3YBedPSHP6Lts8WVHn4jj853RfRZiTpzYNP8KKLaU12H',
184+
'key': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
185+
'value': {'balance': '208684', 'approvals': {'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU': '0'}},
186+
},
187+
},
188+
{
189+
'bigmap': 1798,
190+
'path': 'balances',
191+
'action': 'add_key',
192+
'content': {
193+
'hash': 'exprugvwjodjwqmGVVryY5uqz9fcg6BndukYj6bproCFShQ6nkuG8e',
194+
'key': 'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
195+
'value': {'balance': '16000000', 'approvals': {}},
196+
},
197+
},
198+
],
199+
),
200+
OperationData(
201+
type='transaction',
202+
id=76905133,
203+
level=1676582,
204+
timestamp=datetime.datetime(2021, 9, 8, 16, 2, 14, tzinfo=datetime.timezone.utc),
205+
hash='opWVrmpgeuQ2tz65DcV5USnCFW7j7x97XQ2BzEAcmefPEjUfkMw',
206+
counter=15811432,
207+
sender_address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
208+
target_address='KT1NLZah1MKeWuveQvdsCqAUCjksKw8J296z',
209+
initiator_address='tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
210+
amount=None,
211+
status='applied',
212+
has_internals=False,
213+
storage={
214+
'balances': 14107,
215+
'metadata': 14108,
216+
'totalSupply': '86717933554615',
217+
'administrator': 'tz1ZnK6zYJrC9PfKCPryg9tPW6LrERisTGtg',
218+
'securityCheck': True,
219+
'token_metadata': 14109,
220+
'exchangeAddress': 'KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU',
221+
},
222+
block=None,
223+
sender_alias='PLENTY / SMAK Swap',
224+
nonce=2,
225+
target_alias='PLENTY / SMAK LP Token',
226+
initiator_alias=None,
227+
entrypoint='mint',
228+
parameter_json={'value': '86717933554615', 'address': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4'},
229+
originated_contract_address=None,
230+
originated_contract_alias=None,
231+
originated_contract_type_hash=None,
232+
originated_contract_code_hash=None,
233+
diffs=[
234+
{
235+
'bigmap': 14107,
236+
'path': 'balances',
237+
'action': 'add_key',
238+
'content': {
239+
'hash': 'exprtkqafR3YBedPSHP6Lts8WVHn4jj853RfRZiTpzYNP8KKLaU12H',
240+
'key': 'tz1cmAfyjWW3Rf3tH3M3maCpwsiAwBKbtmG4',
241+
'value': {'balance': '86717933554615', 'approvals': {}},
242+
},
243+
}
244+
],
245+
),
246+
)
247+
248+
index_config = OperationIndexConfig(
249+
datasource=TzktDatasourceConfig(kind='tzkt', url='https://api.tzkt.io', http=None),
250+
kind='operation',
251+
handlers=[
252+
OperationHandlerConfig(
253+
callback='on_fa12_and_fa12_add_liquidity',
254+
pattern=[
255+
OperationHandlerTransactionPatternConfig(
256+
type='transaction',
257+
source=None,
258+
destination=ContractConfig(address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU', typename='plenty_smak_amm'),
259+
entrypoint='AddLiquidity',
260+
optional=False,
261+
),
262+
OperationHandlerTransactionPatternConfig(
263+
type='transaction',
264+
source=None,
265+
destination=ContractConfig(address='KT1GRSvLoikDsXujKgZPsGLX8k8VvR2Tq95b', typename='plenty_token'),
266+
entrypoint='transfer',
267+
optional=False,
268+
),
269+
OperationHandlerTransactionPatternConfig(
270+
type='transaction',
271+
source=None,
272+
destination=ContractConfig(address='KT1TwzD6zV3WeJ39ukuqxcfK2fJCnhvrdN1X', typename='smak_token'),
273+
entrypoint='transfer',
274+
optional=False,
275+
),
276+
OperationHandlerTransactionPatternConfig(
277+
type='transaction',
278+
source=None,
279+
destination=ContractConfig(address='KT1NLZah1MKeWuveQvdsCqAUCjksKw8J296z', typename='plenty_smak_lp'),
280+
entrypoint='mint',
281+
optional=False,
282+
),
283+
],
284+
),
285+
],
286+
types=[OperationType.transaction, OperationType.origination],
287+
contracts=[ContractConfig(address='KT1BEC9uHmADgVLXCm3wxN52qJJ85ohrWEaU', typename='plenty_smak_amm')],
288+
first_level=0,
289+
last_level=0,
290+
)
291+
index_config.name = 'asdf'
292+
293+
294+
class MatcherTest(IsolatedAsyncioTestCase):
295+
async def test_match_smak_add_liquidity(self) -> None:
296+
index = OperationIndex(None, index_config, None) # type: ignore
297+
index._prepare_handler_args = AsyncMock() # type: ignore
298+
matched_operations = await index._match_operations(add_liquidity_operations)
299+
index._prepare_handler_args.assert_called()
300+
self.assertEqual(len(matched_operations), 1)

0 commit comments

Comments
 (0)