forked from tonfactory/tonsdk
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add highload wallet v3 (initial support)
- Loading branch information
Showing
10 changed files
with
491 additions
and
94 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from tonsdk_ng.contract.wallet import HighloadQueryId | ||
|
||
|
||
def test_highload_query_id_seqno(): | ||
assert HighloadQueryId.from_seqno(0).to_seqno() == 0 | ||
assert HighloadQueryId.from_seqno(1022).to_seqno() == 1022 | ||
assert HighloadQueryId.from_seqno(1023).to_seqno() == 1023 | ||
assert HighloadQueryId.from_seqno(1024).to_seqno() == 1024 | ||
assert HighloadQueryId.from_seqno(8380415).to_seqno() == 8380415 | ||
|
||
|
||
def test_highload_query_id(): | ||
MAX = (2**13) * 1023 - 2 | ||
query_id = HighloadQueryId() | ||
for i in range(MAX): | ||
query_id = query_id.get_next() | ||
|
||
q = query_id.query_id | ||
q2 = HighloadQueryId.from_query_id(q) | ||
|
||
assert query_id.shift == q2.shift | ||
assert query_id.bit_number == q2.bit_number | ||
assert q2.query_id == q | ||
|
||
q3 = HighloadQueryId.from_shift_and_bit_number( | ||
query_id.shift, query_id.bit_number | ||
) | ||
assert query_id.shift == q3.shift | ||
assert query_id.bit_number == q3.bit_number | ||
assert q3.query_id == q | ||
|
||
if i == MAX - 1: | ||
assert not query_id.has_next() | ||
else: | ||
assert query_id.has_next() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
BIT_NUMBER_SIZE = 10 # 10 bit | ||
SHIFT_SIZE = 13 # 13 bit | ||
MAX_BIT_NUMBER = 1022 | ||
MAX_SHIFT = 8191 # 2^13 = 8192 | ||
|
||
|
||
class HighloadQueryId: | ||
def __init__(self): | ||
""" | ||
Initializes a HighloadQueryId instance with default values. | ||
:ivar _shift: Internal state for shift (bigint) [0 .. 8191] | ||
:ivar _bit_number: Internal state for bit number (bigint) [0 .. 1022] | ||
""" | ||
self._shift = 0 | ||
self._bit_number = 0 | ||
|
||
@staticmethod | ||
def from_shift_and_bit_number(shift, bit_number): | ||
""" | ||
Creates a new HighloadQueryId object with specified shift and bit number. | ||
:param shift: The shift value (int) | ||
:param bit_number: The bit number value (int) | ||
:return: A new instance of HighloadQueryId | ||
:raises ValueError: If the shift or bit number is out of valid range | ||
""" | ||
if not (0 <= shift <= MAX_SHIFT): | ||
raise ValueError("invalid shift") | ||
if not (0 <= bit_number <= MAX_BIT_NUMBER): | ||
raise ValueError("invalid bitnumber") | ||
|
||
q = HighloadQueryId() | ||
q._shift = shift | ||
q._bit_number = bit_number | ||
return q | ||
|
||
def get_next(self): | ||
""" | ||
Calculates the next HighloadQueryId based on the current state. | ||
:return: HighloadQueryId representing the next ID | ||
:raises ValueError: If the current ID is at the maximum capacity | ||
""" | ||
new_bit_number = self._bit_number + 1 | ||
new_shift = self._shift | ||
|
||
if new_shift == MAX_SHIFT and new_bit_number > (MAX_BIT_NUMBER - 1): | ||
# we left one queryId for emergency withdraw | ||
raise ValueError("Overload") | ||
|
||
if new_bit_number > MAX_BIT_NUMBER: | ||
new_bit_number = 0 | ||
new_shift += 1 | ||
if new_shift > MAX_SHIFT: | ||
raise ValueError("Overload") | ||
|
||
return HighloadQueryId.from_shift_and_bit_number( | ||
new_shift, new_bit_number | ||
) | ||
|
||
def has_next(self): | ||
""" | ||
Checks if there is a next HighloadQueryId available. | ||
:return: True if there is a next ID available, False otherwise | ||
""" | ||
# we left one queryId for emergency withdraw | ||
is_end = ( | ||
self._bit_number >= (MAX_BIT_NUMBER - 1) | ||
and self._shift == MAX_SHIFT | ||
) | ||
return not is_end | ||
|
||
@property | ||
def shift(self): | ||
""" | ||
Gets the current shift value. | ||
:return: The current shift value (int) | ||
""" | ||
return self._shift | ||
|
||
@property | ||
def bit_number(self): | ||
""" | ||
Gets the current bit number value. | ||
:return: The current bit number value (int) | ||
""" | ||
return self._bit_number | ||
|
||
@property | ||
def query_id(self): | ||
""" | ||
Computes the query ID based on the current shift and bit number. | ||
:return: The computed query ID (int) | ||
""" | ||
return (self._shift << BIT_NUMBER_SIZE) + self._bit_number | ||
|
||
@staticmethod | ||
def from_query_id(query_id: int): | ||
""" | ||
Creates a new HighloadQueryId object from a given query ID. | ||
:param query_id: The query ID to parse (int) | ||
:return: A new instance of HighloadQueryId | ||
""" | ||
shift = query_id >> BIT_NUMBER_SIZE | ||
bit_number = query_id & 1023 | ||
return HighloadQueryId.from_shift_and_bit_number(shift, bit_number) | ||
|
||
@staticmethod | ||
def from_seqno(i: int): | ||
""" | ||
Creates a HighloadQueryId from a sequence number. | ||
:param i: The sequence number (int) | ||
:return: A new HighloadQueryId | ||
""" | ||
shift = i // 1023 | ||
bit_number = i % 1023 | ||
return HighloadQueryId.from_shift_and_bit_number(shift, bit_number) | ||
|
||
def to_seqno(self) -> int: | ||
""" | ||
Converts the current HighloadQueryId to a sequence number. | ||
:return: The sequence number (int) | ||
""" | ||
return self._bit_number + self._shift * 1023 |
File renamed without changes.
Oops, something went wrong.