toncenter / pytonlib

Python SDK for TON via tonlib
GNU General Public License v3.0
80 stars 21 forks source link

Some TON DNS Domain break `client.get_token_data` #44

Closed gromgull closed 1 year ago

gromgull commented 1 year ago

Like this one: EQBdWPy9ZD7XPsNDbEOhVRDIbZPZrMw2P9OgSB3vZtX8ICd9

It fails to parse the reply of the get_nft_content call to the collection:

Traceback (most recent call last):
  File "apps/backend/api/api_bt/handlers/nft.py", line 145, in get_nft_data
    data = await tonlibclient.get_token_data(address)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/backend/api/api_bt/redis.py", line 76, in _wrapper
    res = await fn(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/backend/api/api_bt/tonlibclient.py", line 27, in get_token_data
    return await super().get_token_data(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/backend/.venv/lib/python3.11/site-packages/pytonlib/client.py", line 779, in get_token_data
    content = parse_dns_content(content_raw['stack'])
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/backend/.venv/lib/python3.11/site-packages/pytonlib/utils/tokens.py", line 110, in parse_dns_content
    return parse_tlb_object(read_stack_cell(stack[0]), DNSRecordSet)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/backend/.venv/lib/python3.11/site-packages/pytonlib/utils/tlb.py", line 769, in parse_tlb_object
    object = tlb_type(cell_slice)
             ^^^^^^^^^^^^^^^^^^^^
  File "apps/backend/.venv/lib/python3.11/site-packages/pytonlib/utils/tlb.py", line 568, in __init__
    self.data = self._parse_attributes(hashmap)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/backend/.venv/lib/python3.11/site-packages/pytonlib/utils/tlb.py", line 580, in _parse_attributes
    res[attr_name] = DNSRecord(Slice(value_cell.refs[0]))
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/backend/.venv/lib/python3.11/site-packages/pytonlib/utils/tlb.py", line 541, in __init__
    flags = ba2int(cell_slice.read_next(8))
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "apps/backend/.venv/lib/python3.11/site-packages/bitarray/util.py", line 209, in ba2int
    raise ValueError("non-empty bitarray expected")
gromgull commented 1 year ago

I mistyped, it's in parse_dns_content and it's when parsing one of the DNSRecord out of the map of records.

For a adnl record the tlb is: dns_adnl_address#ad01 adnl_addr:bits256 flags:(## 8) { flags <= 1 } proto_list:flags . 0?ProtoList = DNSRecord;

in this case, the cell just ends after the address - there is no flag.

So technically, the record is broken and pytonlib is ok - but there are many of these records.

I see for example tongo also doesn't make allowance for this: https://github.com/tonkeeper/tongo/blob/c6497b2bfc8d49688be1c9b3201806cd1522a8c1/tlb/dns.go#L145

nor the kotlin library:

https://github.com/ton-community/ton-kotlin/blob/b1edc4b134e89ccf252149f27c85fd530377cebe/ton-kotlin-block/src/commonMain/kotlin/org/ton/block/DnsAdnlAddress.kt#L45

So I guess this can be closed.