tonutils 2.0.1b4__py3-none-any.whl → 2.0.1b5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tonutils/__meta__.py +1 -1
- tonutils/clients/base.py +5 -1
- tonutils/tools/block_scanner/__init__.py +1 -11
- tonutils/tools/block_scanner/scanner.py +3 -5
- tonutils/tools/block_scanner/traversal.py +55 -54
- tonutils/tools/block_scanner/where.py +0 -98
- {tonutils-2.0.1b4.dist-info → tonutils-2.0.1b5.dist-info}/METADATA +1 -1
- {tonutils-2.0.1b4.dist-info → tonutils-2.0.1b5.dist-info}/RECORD +12 -12
- {tonutils-2.0.1b4.dist-info → tonutils-2.0.1b5.dist-info}/WHEEL +0 -0
- {tonutils-2.0.1b4.dist-info → tonutils-2.0.1b5.dist-info}/entry_points.txt +0 -0
- {tonutils-2.0.1b4.dist-info → tonutils-2.0.1b5.dist-info}/licenses/LICENSE +0 -0
- {tonutils-2.0.1b4.dist-info → tonutils-2.0.1b5.dist-info}/top_level.txt +0 -0
tonutils/__meta__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2.0.
|
|
1
|
+
__version__ = "2.0.1b5"
|
tonutils/clients/base.py
CHANGED
|
@@ -272,7 +272,11 @@ class BaseClient(abc.ABC):
|
|
|
272
272
|
|
|
273
273
|
blen = len(domain) * 8
|
|
274
274
|
rlen = t.cast(int, res[0])
|
|
275
|
-
|
|
275
|
+
|
|
276
|
+
cell = res[1]
|
|
277
|
+
|
|
278
|
+
if cell is None:
|
|
279
|
+
return None
|
|
276
280
|
|
|
277
281
|
if rlen % 8 != 0 or rlen > blen:
|
|
278
282
|
raise ValueError(f"Invalid resolved length: result {rlen}, bytes {blen}.")
|
|
@@ -4,13 +4,7 @@ from .events import (
|
|
|
4
4
|
TransactionsEvent,
|
|
5
5
|
)
|
|
6
6
|
from .scanner import BlockScanner
|
|
7
|
-
from .where import
|
|
8
|
-
Where,
|
|
9
|
-
comment,
|
|
10
|
-
destination,
|
|
11
|
-
opcode,
|
|
12
|
-
sender,
|
|
13
|
-
)
|
|
7
|
+
from .where import Where
|
|
14
8
|
|
|
15
9
|
|
|
16
10
|
__all__ = [
|
|
@@ -19,8 +13,4 @@ __all__ = [
|
|
|
19
13
|
"TransactionEvent",
|
|
20
14
|
"TransactionsEvent",
|
|
21
15
|
"Where",
|
|
22
|
-
"comment",
|
|
23
|
-
"destination",
|
|
24
|
-
"opcode",
|
|
25
|
-
"sender",
|
|
26
16
|
]
|
|
@@ -186,8 +186,9 @@ class BlockScanner:
|
|
|
186
186
|
get_header=self._client.get_block_header,
|
|
187
187
|
)
|
|
188
188
|
)
|
|
189
|
+
# Update seen_seqno after collecting blocks for this shard
|
|
190
|
+
shards_seqno[self._traversal.shard_key(shard_tip)] = shard_tip.seqno
|
|
189
191
|
|
|
190
|
-
blocks.sort(key=lambda b: (b.workchain, b.shard, b.seqno))
|
|
191
192
|
return blocks
|
|
192
193
|
|
|
193
194
|
def _emit_block(self, mc_block: BlockIdExt, block: BlockIdExt) -> None:
|
|
@@ -239,12 +240,9 @@ class BlockScanner:
|
|
|
239
240
|
self,
|
|
240
241
|
mc_block: BlockIdExt,
|
|
241
242
|
block: BlockIdExt,
|
|
242
|
-
shards_seqno: t.Dict[t.Tuple[int, int], int],
|
|
243
243
|
) -> None:
|
|
244
244
|
"""Process shard block and emit events for block + transactions."""
|
|
245
245
|
self._ensure_running()
|
|
246
|
-
|
|
247
|
-
shards_seqno[self._traversal.shard_key(block)] = block.seqno
|
|
248
246
|
self._emit_block(mc_block, block)
|
|
249
247
|
|
|
250
248
|
if not self._include_transactions:
|
|
@@ -304,7 +302,7 @@ class BlockScanner:
|
|
|
304
302
|
shards_seqno=state.shards_seqno,
|
|
305
303
|
)
|
|
306
304
|
for block in blocks:
|
|
307
|
-
await self._handle_block(state.mc_block, block
|
|
305
|
+
await self._handle_block(state.mc_block, block)
|
|
308
306
|
state.mc_block = await self._wait_next_mc_block(state.mc_block)
|
|
309
307
|
finally:
|
|
310
308
|
await self._dispatcher.aclose()
|
|
@@ -34,63 +34,64 @@ class ShardTraversal:
|
|
|
34
34
|
root: BlockIdExt,
|
|
35
35
|
seen_seqno: t.Dict[t.Tuple[int, int], int],
|
|
36
36
|
get_header: t.Callable[[BlockIdExt], t.Awaitable[t.Any]],
|
|
37
|
+
out: t.Optional[t.List[BlockIdExt]] = None,
|
|
37
38
|
) -> t.List[BlockIdExt]:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
"""Recursively walk from root block back to seen blocks."""
|
|
40
|
+
if out is None:
|
|
41
|
+
out = []
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if seen_seqno.get(key, -1) >= blk.seqno:
|
|
46
|
-
continue
|
|
43
|
+
key = self.shard_key(root)
|
|
44
|
+
if seen_seqno.get(key, -1) >= root.seqno:
|
|
45
|
+
return out
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
prev_ref = header.info.prev_ref
|
|
47
|
+
_, header = await get_header(root)
|
|
48
|
+
prev_ref = header.info.prev_ref
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
50
|
+
if prev_ref.type_ == "prev_blk_info":
|
|
51
|
+
prev: ExtBlkRef = prev_ref.prev
|
|
52
|
+
prev_shard = (
|
|
53
|
+
self.get_parent_shard(root.shard)
|
|
54
|
+
if header.info.after_split
|
|
55
|
+
else root.shard
|
|
56
|
+
)
|
|
57
|
+
await self.walk_unseen(
|
|
58
|
+
root=BlockIdExt(
|
|
59
|
+
workchain=root.workchain,
|
|
60
|
+
shard=prev_shard,
|
|
61
|
+
seqno=prev.seqno,
|
|
62
|
+
root_hash=prev.root_hash,
|
|
63
|
+
file_hash=prev.file_hash,
|
|
64
|
+
),
|
|
65
|
+
seen_seqno=seen_seqno,
|
|
66
|
+
get_header=get_header,
|
|
67
|
+
out=out,
|
|
68
|
+
)
|
|
69
|
+
else:
|
|
70
|
+
prev1, prev2 = prev_ref.prev1, prev_ref.prev2
|
|
71
|
+
await self.walk_unseen(
|
|
72
|
+
root=BlockIdExt(
|
|
73
|
+
workchain=root.workchain,
|
|
74
|
+
shard=self.get_child_shard(root.shard, left=True),
|
|
75
|
+
seqno=prev1.seqno,
|
|
76
|
+
root_hash=prev1.root_hash,
|
|
77
|
+
file_hash=prev1.file_hash,
|
|
78
|
+
),
|
|
79
|
+
seen_seqno=seen_seqno,
|
|
80
|
+
get_header=get_header,
|
|
81
|
+
out=out,
|
|
82
|
+
)
|
|
83
|
+
await self.walk_unseen(
|
|
84
|
+
root=BlockIdExt(
|
|
85
|
+
workchain=root.workchain,
|
|
86
|
+
shard=self.get_child_shard(root.shard, left=False),
|
|
87
|
+
seqno=prev2.seqno,
|
|
88
|
+
root_hash=prev2.root_hash,
|
|
89
|
+
file_hash=prev2.file_hash,
|
|
90
|
+
),
|
|
91
|
+
seen_seqno=seen_seqno,
|
|
92
|
+
get_header=get_header,
|
|
93
|
+
out=out,
|
|
94
|
+
)
|
|
95
95
|
|
|
96
|
+
out.append(root)
|
|
96
97
|
return out
|
|
@@ -2,11 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import typing as t
|
|
4
4
|
|
|
5
|
-
from pytoniq_core import Address
|
|
6
|
-
|
|
7
|
-
from tonutils.tools.block_scanner import TransactionEvent
|
|
8
5
|
from tonutils.tools.block_scanner.annotations import TEvent
|
|
9
|
-
from tonutils.types import AddressLike
|
|
10
6
|
|
|
11
7
|
|
|
12
8
|
class Where(t.Generic[TEvent]):
|
|
@@ -55,97 +51,3 @@ class _Not(Where[TEvent]):
|
|
|
55
51
|
|
|
56
52
|
def __call__(self, event: TEvent) -> bool:
|
|
57
53
|
return not self._f(event)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
class _Opcode(Where[TransactionEvent]):
|
|
61
|
-
__slots__ = ("_ops",)
|
|
62
|
-
|
|
63
|
-
def __init__(self, *ops: int) -> None:
|
|
64
|
-
self._ops = frozenset(ops)
|
|
65
|
-
|
|
66
|
-
def __call__(self, event: TransactionEvent) -> bool:
|
|
67
|
-
msg = event.transaction.in_msg
|
|
68
|
-
if msg is None or msg.body is None:
|
|
69
|
-
return False
|
|
70
|
-
|
|
71
|
-
if len(msg.body.bits) < 32:
|
|
72
|
-
return False
|
|
73
|
-
|
|
74
|
-
op = msg.body.begin_parse().load_uint(32)
|
|
75
|
-
return op in self._ops
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
class _Comment(Where[TransactionEvent]):
|
|
79
|
-
__slots__ = ("_texts", "_any")
|
|
80
|
-
|
|
81
|
-
def __init__(self, *texts: str) -> None:
|
|
82
|
-
self._texts = frozenset(texts)
|
|
83
|
-
self._any = len(texts) == 0
|
|
84
|
-
|
|
85
|
-
def __call__(self, event: TransactionEvent) -> bool:
|
|
86
|
-
msg = event.transaction.in_msg
|
|
87
|
-
if msg is None or msg.body is None:
|
|
88
|
-
return False
|
|
89
|
-
|
|
90
|
-
body = msg.body.begin_parse()
|
|
91
|
-
if len(body.bits) < 32:
|
|
92
|
-
return False
|
|
93
|
-
|
|
94
|
-
op = body.load_uint(32)
|
|
95
|
-
if op != 0:
|
|
96
|
-
return False
|
|
97
|
-
|
|
98
|
-
if self._any:
|
|
99
|
-
return True
|
|
100
|
-
try:
|
|
101
|
-
text = body.load_snake_string()
|
|
102
|
-
except (Exception,):
|
|
103
|
-
return False
|
|
104
|
-
|
|
105
|
-
return text in self._texts
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
class _Sender(Where[TransactionEvent]):
|
|
109
|
-
__slots__ = ("_addrs",)
|
|
110
|
-
|
|
111
|
-
def __init__(self, *addrs: AddressLike) -> None:
|
|
112
|
-
self._addrs = frozenset(Address(a) if isinstance(a, str) else a for a in addrs)
|
|
113
|
-
|
|
114
|
-
def __call__(self, event: TransactionEvent) -> bool:
|
|
115
|
-
msg = event.transaction.in_msg
|
|
116
|
-
if msg is None:
|
|
117
|
-
return False
|
|
118
|
-
|
|
119
|
-
src = msg.info.src
|
|
120
|
-
return src is not None and src in self._addrs
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
class _Destination(Where[TransactionEvent]):
|
|
124
|
-
__slots__ = ("_addrs",)
|
|
125
|
-
|
|
126
|
-
def __init__(self, *addrs: AddressLike) -> None:
|
|
127
|
-
self._addrs = frozenset(Address(a) if isinstance(a, str) else a for a in addrs)
|
|
128
|
-
|
|
129
|
-
def __call__(self, event: TransactionEvent) -> bool:
|
|
130
|
-
msg = event.transaction.in_msg
|
|
131
|
-
if msg is None:
|
|
132
|
-
return False
|
|
133
|
-
|
|
134
|
-
dest = msg.info.dest
|
|
135
|
-
return dest is not None and dest in self._addrs
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
def opcode(*ops: int) -> Where[TransactionEvent]:
|
|
139
|
-
return _Opcode(*ops)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
def comment(*texts: str) -> Where[TransactionEvent]:
|
|
143
|
-
return _Comment(*texts)
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def sender(*addresses: AddressLike) -> Where[TransactionEvent]:
|
|
147
|
-
return _Sender(*addresses)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
def destination(*addresses: AddressLike) -> Where[TransactionEvent]:
|
|
151
|
-
return _Destination(*addresses)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
tonutils/__init__.py,sha256=ueJrDkU1JBlZiX0q8roQfzYOZY62Of_CiHZlxIIQFO0,228
|
|
2
|
-
tonutils/__meta__.py,sha256=
|
|
2
|
+
tonutils/__meta__.py,sha256=uHnZdT43kWVuqeXaVY86NLU06cIBG4SuxsLdEUaX6v8,24
|
|
3
3
|
tonutils/cli.py,sha256=WGir-ihgPuKTgKGmhjPZeKk9wgsm64jiJciOnVlsdco,2645
|
|
4
4
|
tonutils/exceptions.py,sha256=67jXCFPyOnVnd8EaqYg1osVIXg34VZX-aJHPunpc-oI,6462
|
|
5
5
|
tonutils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
tonutils/types.py,sha256=ORevKllLjb7pmL3AQTMeSoiZQ4KFhoB_rA7KpGqZZjU,14542
|
|
7
7
|
tonutils/utils.py,sha256=w2sXvVMA2Erz_JSSN2WuYSi7RAPDAOOwWYiThu8Q0Ps,16499
|
|
8
8
|
tonutils/clients/__init__.py,sha256=PvHsOHOtkVonfiowEPi6P7ggDeQeQorXcksujru6efQ,561
|
|
9
|
-
tonutils/clients/base.py,sha256=
|
|
9
|
+
tonutils/clients/base.py,sha256=DjNhFd_p82Osqn0qWIjflpt9S1NVZc3MQIEj5U5E9-k,9631
|
|
10
10
|
tonutils/clients/limiter.py,sha256=d2WO7Dx-ksg3gvl05WuDMu1KycuQj0XrmiG67Q7wnFo,3592
|
|
11
11
|
tonutils/clients/protocol.py,sha256=4QerYoqBKAAfNZVpyQW2sp5KZZlq8xHCn9yWbbJERPQ,2557
|
|
12
12
|
tonutils/clients/adnl/__init__.py,sha256=shkczPIYlTrOHjpnOBIoRwEYRQ4rVGfLnOZvnQY0a5U,174
|
|
@@ -89,20 +89,20 @@ tonutils/contracts/wallet/versions/v4.py,sha256=2sAsjJ8_3oYAj5JwWH3PiMyoGbgl6-f7
|
|
|
89
89
|
tonutils/contracts/wallet/versions/v5.py,sha256=1J6KXPOc7Q5S5EdFM9WXQzNGRZrw5EgxDZ9dmyHwsXE,8890
|
|
90
90
|
tonutils/tonconnect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
91
91
|
tonutils/tools/__init__.py,sha256=QYOVuGY50FFkWlgIvHc2RPU3xiEWSbwnwZ6wuZPQnCA,102
|
|
92
|
-
tonutils/tools/block_scanner/__init__.py,sha256=
|
|
92
|
+
tonutils/tools/block_scanner/__init__.py,sha256=NRZ2XuDL3VwXJJ0iMe6ETh5w1aX4pCMMIv9UmmOj5yE,260
|
|
93
93
|
tonutils/tools/block_scanner/annotations.py,sha256=i6Xsu_rBERr7qEmhGGcwlYYkqf8cLjNJlZ4rXUf51WY,795
|
|
94
94
|
tonutils/tools/block_scanner/dispatcher.py,sha256=lgrs0MPnnyx0VibVQGYXU6s5mpqV_lO47yhO0uOCV30,4393
|
|
95
95
|
tonutils/tools/block_scanner/events.py,sha256=6M80JoiVMRy7kBBuT8-KlHJ5Dx3GHUjIKmZVPaXXeaA,727
|
|
96
|
-
tonutils/tools/block_scanner/scanner.py,sha256=
|
|
97
|
-
tonutils/tools/block_scanner/traversal.py,sha256=
|
|
98
|
-
tonutils/tools/block_scanner/where.py,sha256=
|
|
96
|
+
tonutils/tools/block_scanner/scanner.py,sha256=2arPhNPu-6Klcj-PnSnP3DBVWekhlYjn2iqvN-1wigU,9929
|
|
97
|
+
tonutils/tools/block_scanner/traversal.py,sha256=Zp0Uon0OTvLTsZi-zviMyvJHBsZRUx9XExxLU6LMkVA,3101
|
|
98
|
+
tonutils/tools/block_scanner/where.py,sha256=sZUuabQ5joATkJqUh5R3N5r4P9WblmRrVYEVdZeJvZw,1239
|
|
99
99
|
tonutils/tools/status_monitor/__init__.py,sha256=QnMlA0IDLtCGgXsEgB9q3EJTBo2s5js6lSJk0oZkQZQ,72
|
|
100
100
|
tonutils/tools/status_monitor/console.py,sha256=UX3BzjjzeS_nKFGg4NkZJpu9fR_IAJZdQUMz0HcJCdg,5036
|
|
101
101
|
tonutils/tools/status_monitor/models.py,sha256=yHuiEuij4h2kVoOK3sbhNq6SwiGDW_evZmzUwMy1GQs,608
|
|
102
102
|
tonutils/tools/status_monitor/monitor.py,sha256=8zUwNwFScmcjK9ES7XX1LZWjw49lk8CSUQATcUYM57E,10085
|
|
103
|
-
tonutils-2.0.
|
|
104
|
-
tonutils-2.0.
|
|
105
|
-
tonutils-2.0.
|
|
106
|
-
tonutils-2.0.
|
|
107
|
-
tonutils-2.0.
|
|
108
|
-
tonutils-2.0.
|
|
103
|
+
tonutils-2.0.1b5.dist-info/licenses/LICENSE,sha256=fG-yM-8DSkOTaJ558P7uF5PNXBmineVO9-HC12YbIxs,1060
|
|
104
|
+
tonutils-2.0.1b5.dist-info/METADATA,sha256=1Wvi3Vlsb0IYwLaKlchY-OdFZ_TYNmHmZIzuyDQj55w,4181
|
|
105
|
+
tonutils-2.0.1b5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
106
|
+
tonutils-2.0.1b5.dist-info/entry_points.txt,sha256=qijo1cqvbbzLVbXp-PCYh19Pgmd7duH6yljmnUPd55I,47
|
|
107
|
+
tonutils-2.0.1b5.dist-info/top_level.txt,sha256=-7H_mGl8S9HKQrkUiTLmEbtMM-knzRzd_a0cZZnuZIU,9
|
|
108
|
+
tonutils-2.0.1b5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|