Skip to content

Commit 0a62ea9

Browse files
committed
add tests
1 parent 18323f3 commit 0a62ea9

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

src/tests/tests.py

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import pytest
2+
import time
3+
from bittensor_commit_reveal import get_encrypted_commit
4+
5+
SUBTENSOR_PULSE_DELAY = 24
6+
PERIOD = 3 # Drand period in seconds
7+
GENESIS_TIME = 1692803367
8+
9+
10+
def test_get_encrypted_commit_ok():
11+
uids = [1, 2]
12+
weights = [11, 22]
13+
version_key = 50
14+
tempo = 100
15+
current_block = 1000
16+
netuid = 1
17+
reveal_period = 2
18+
block_time = 12
19+
20+
start_time = int(time.time())
21+
ct_pybytes, reveal_round = get_encrypted_commit(
22+
uids, weights, version_key, tempo, current_block, netuid, reveal_period, block_time
23+
)
24+
25+
# Basic checks
26+
assert ct_pybytes is not None and len(ct_pybytes) > 0, "Ciphertext should not be empty"
27+
assert reveal_round > 0, "Reveal round should be positive"
28+
29+
expected_reveal_round, _, _ = compute_expected_reveal_round(
30+
start_time, tempo, current_block, netuid, reveal_period, block_time
31+
)
32+
33+
# The reveal_round should be close to what we predict
34+
assert abs(reveal_round - expected_reveal_round) <= 1, (
35+
f"Reveal round {reveal_round} not close to expected {expected_reveal_round}"
36+
)
37+
38+
def test_generate_commit_success():
39+
uids = [1, 2, 3]
40+
values = [10, 20, 30]
41+
version_key = 42
42+
tempo = 50
43+
current_block = 500
44+
netuid = 100
45+
subnet_reveal_period_epochs = 2
46+
block_time = 12
47+
48+
start_time = int(time.time())
49+
ct_pybytes, reveal_round = get_encrypted_commit(
50+
uids, values, version_key, tempo, current_block, netuid, subnet_reveal_period_epochs, block_time
51+
)
52+
53+
assert ct_pybytes is not None and len(ct_pybytes) > 0, "Ciphertext should not be empty"
54+
assert reveal_round > 0, "Reveal round should be positive"
55+
56+
expected_reveal_round, expected_reveal_time, time_until_reveal = compute_expected_reveal_round(
57+
start_time, tempo, current_block, netuid, subnet_reveal_period_epochs, block_time
58+
)
59+
60+
assert abs(reveal_round - expected_reveal_round) <= 1, (
61+
f"Reveal round {reveal_round} differs from expected {expected_reveal_round}"
62+
)
63+
64+
required_lead_time = SUBTENSOR_PULSE_DELAY * PERIOD
65+
computed_reveal_time = GENESIS_TIME + (reveal_round + SUBTENSOR_PULSE_DELAY) * PERIOD
66+
assert computed_reveal_time - start_time >= required_lead_time, (
67+
"Not enough lead time before reveal. "
68+
f"computed_reveal_time={computed_reveal_time}, start_time={start_time}, required={required_lead_time}"
69+
)
70+
71+
assert time_until_reveal >= SUBTENSOR_PULSE_DELAY * PERIOD, (
72+
f"time_until_reveal {time_until_reveal} is less than required {SUBTENSOR_PULSE_DELAY * PERIOD}"
73+
)
74+
75+
76+
@pytest.mark.asyncio
77+
async def test_generate_commit_various_tempos():
78+
NETUID = 1
79+
CURRENT_BLOCK = 100_000
80+
SUBNET_REVEAL_PERIOD_EPOCHS = 1
81+
BLOCK_TIME = 6
82+
TEMPOS = [10, 50, 100, 250, 360, 500, 750, 1000]
83+
84+
uids = [0]
85+
values = [100]
86+
version_key = 1
87+
88+
for tempo in TEMPOS:
89+
start_time = int(time.time())
90+
91+
ct_pybytes, reveal_round = get_encrypted_commit(
92+
uids, values, version_key, tempo, CURRENT_BLOCK, NETUID, SUBNET_REVEAL_PERIOD_EPOCHS, BLOCK_TIME
93+
)
94+
95+
assert len(ct_pybytes) > 0, f"Ciphertext is empty for tempo {tempo}"
96+
assert reveal_round > 0, f"Reveal round is zero or negative for tempo {tempo}"
97+
98+
expected_reveal_round, _, time_until_reveal = compute_expected_reveal_round(
99+
start_time, tempo, CURRENT_BLOCK, NETUID, SUBNET_REVEAL_PERIOD_EPOCHS, BLOCK_TIME
100+
)
101+
102+
assert abs(reveal_round - expected_reveal_round) <= 1, (
103+
f"Tempo {tempo}: reveal_round {reveal_round} not close to expected {expected_reveal_round}"
104+
)
105+
106+
computed_reveal_time = GENESIS_TIME + (reveal_round + SUBTENSOR_PULSE_DELAY) * PERIOD
107+
required_lead_time = SUBTENSOR_PULSE_DELAY * PERIOD
108+
109+
assert computed_reveal_time - start_time >= required_lead_time, (
110+
f"Tempo {tempo}: Not enough lead time: reveal_time={computed_reveal_time}, "
111+
f"start_time={start_time}, required={required_lead_time}"
112+
)
113+
114+
assert time_until_reveal >= SUBTENSOR_PULSE_DELAY * PERIOD, (
115+
f"Tempo {tempo}: time_until_reveal {time_until_reveal} is less than required {SUBTENSOR_PULSE_DELAY * PERIOD}"
116+
)
117+
118+
def compute_expected_reveal_round(
119+
now: int,
120+
tempo: int,
121+
current_block: int,
122+
netuid: int,
123+
subnet_reveal_period_epochs: int,
124+
block_time: int,
125+
):
126+
tempo_plus_one = tempo + 1
127+
netuid_plus_one = netuid + 1
128+
block_with_offset = current_block + netuid_plus_one
129+
current_epoch = block_with_offset // tempo_plus_one
130+
131+
# Initial guess for reveal_epoch
132+
reveal_epoch = current_epoch + subnet_reveal_period_epochs
133+
reveal_block_number = reveal_epoch * tempo_plus_one - netuid_plus_one
134+
135+
# Compute blocks_until_reveal, ensure non-negative
136+
blocks_until_reveal = reveal_block_number - current_block
137+
if blocks_until_reveal < 0:
138+
blocks_until_reveal = 0
139+
time_until_reveal = blocks_until_reveal * block_time
140+
141+
# Adjust until we have enough lead time (at least SUBTENSOR_PULSE_DELAY pulses * period seconds)
142+
while time_until_reveal < SUBTENSOR_PULSE_DELAY * PERIOD:
143+
reveal_epoch += 1
144+
reveal_block_number = reveal_epoch * tempo_plus_one - netuid_plus_one
145+
blocks_until_reveal = reveal_block_number - current_block
146+
if blocks_until_reveal < 0:
147+
blocks_until_reveal = 0
148+
time_until_reveal = blocks_until_reveal * block_time
149+
150+
reveal_time = now + time_until_reveal
151+
reveal_round = ((reveal_time - GENESIS_TIME + PERIOD - 1) // PERIOD) - SUBTENSOR_PULSE_DELAY
152+
return reveal_round, reveal_time, time_until_reveal

0 commit comments

Comments
 (0)