-
Notifications
You must be signed in to change notification settings - Fork 362
/
Copy pathtest_commit_reveal_v3.py
200 lines (169 loc) · 7.12 KB
/
test_commit_reveal_v3.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
import re
import time
import numpy as np
import pytest
from bittensor.utils.btlogging import logging
from bittensor.utils.balance import Balance
from bittensor.utils.weight_utils import convert_weights_and_uids_for_emit
from tests.e2e_tests.utils.chain_interactions import (
sudo_set_admin_utils,
sudo_set_hyperparameter_bool,
sudo_set_hyperparameter_values,
wait_interval,
next_tempo,
)
@pytest.mark.parametrize("local_chain", [False], indirect=True)
@pytest.mark.asyncio
async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_wallet):
"""
Tests the commit/reveal weights mechanism (CR3)
Steps:
1. Register a subnet through Alice
2. Register Alice's neuron and add stake
3. Enable commit-reveal mechanism on the subnet
4. Lower weights rate limit
5. Change the tempo for subnet 1
5. Commit weights and ensure they are committed.
6. Wait interval & reveal weights and verify
Raises:
AssertionError: If any of the checks or verifications fail
"""
netuid = 2
logging.console.info("Testing test_commit_and_reveal_weights")
# Register root as Alice
assert subtensor.register_subnet(alice_wallet), "Unable to register the subnet"
# Verify subnet 2 created successfully
assert subtensor.subnet_exists(netuid), "Subnet wasn't created successfully"
logging.console.info("Subnet 2 is registered")
# Enable commit_reveal on the subnet
assert sudo_set_hyperparameter_bool(
local_chain,
alice_wallet,
"sudo_set_commit_reveal_weights_enabled",
True,
netuid,
), "Unable to enable commit reveal on the subnet"
# Verify commit_reveal was enabled
assert subtensor.get_subnet_hyperparameters(
netuid=netuid,
).commit_reveal_weights_enabled, "Failed to enable commit/reveal"
logging.console.info("Commit reveal enabled")
# Change the weights rate limit on the subnet
assert sudo_set_hyperparameter_values(
local_chain,
alice_wallet,
call_function="sudo_set_weights_set_rate_limit",
call_params={"netuid": netuid, "weights_set_rate_limit": "0"},
return_error_message=True,
)
# Verify weights rate limit was changed
assert (
subtensor.get_subnet_hyperparameters(netuid=netuid).weights_rate_limit == 0
), "Failed to set weights_rate_limit"
assert subtensor.weights_rate_limit(netuid=netuid) == 0
logging.console.info("sudo_set_weights_set_rate_limit executed: set to 0")
# Change the tempo of the subnet from default 360
# Since this is in normal blocks, this is necessary
tempo_set = 10
assert (
sudo_set_admin_utils(
local_chain,
alice_wallet,
call_function="sudo_set_tempo",
call_params={"netuid": netuid, "tempo": tempo_set},
return_error_message=True,
)[0]
is True
)
tempo = subtensor.get_subnet_hyperparameters(netuid=netuid).tempo
assert tempo_set == tempo
logging.console.info(f"sudo_set_tempo executed: set to {tempo_set}")
# Commit-reveal values - setting weights to self
uids = np.array([0], dtype=np.int64)
weights = np.array([0.1], dtype=np.float32)
weight_uids, weight_vals = convert_weights_and_uids_for_emit(
uids=uids, weights=weights
)
# Fetch current block and calculate next tempo for the subnet
current_block = subtensor.get_current_block()
upcoming_tempo = next_tempo(current_block, tempo, netuid)
logging.console.info(
f"Checking if window is too low with Current block: {current_block}, next tempo: {upcoming_tempo}"
)
# Wait for 2 tempos to pass as CR3 only reveals weights after 2 tempos
subtensor.wait_for_block(20)
# Lower than this might mean weights will get revealed before we can check them
if upcoming_tempo - current_block < 3:
await wait_interval(
tempo,
subtensor,
netuid=netuid,
reporting_interval=1,
)
current_block = subtensor.get_current_block()
latest_drand_round = subtensor.last_drand_round()
upcoming_tempo = next_tempo(current_block, tempo, netuid)
logging.console.info(
f"Post first wait_interval (to ensure window isnt too low): {current_block}, next tempo: {upcoming_tempo}, drand: {latest_drand_round}"
)
# Commit weights
success, message = subtensor.set_weights(
alice_wallet,
netuid,
uids=weight_uids,
weights=weight_vals,
wait_for_inclusion=True,
wait_for_finalization=True,
)
# Assert committing was a success
assert success is True
assert bool(re.match(r"reveal_round:\d+", message))
# Parse expected reveal_round
expected_reveal_round = int(message.split(":")[1])
logging.console.info(
f"Successfully set weights: uids {weight_uids}, weights {weight_vals}, reveal_round: {expected_reveal_round}"
)
current_block = subtensor.get_current_block()
latest_drand_round = subtensor.last_drand_round()
upcoming_tempo = next_tempo(current_block, tempo, netuid)
logging.console.info(
f"After setting weights: Current block: {current_block}, next tempo: {upcoming_tempo}, drand: {latest_drand_round}"
)
# Ensure the expected drand round is well in the future
assert (
expected_reveal_round > latest_drand_round
), "Revealed drand pulse is older than the drand pulse right after setting weights"
# Fetch current commits pending on the chain
commits_on_chain = subtensor.get_current_weight_commit_info(netuid=netuid)
address, commit, reveal_round = commits_on_chain[0]
# Assert correct values are committed on the chain
assert expected_reveal_round == reveal_round
assert address == alice_wallet.hotkey.ss58_address
# Ensure no weights are available as of now
assert subtensor.weights(netuid=netuid) == []
# Wait for the next tempo so weights can be revealed
await wait_interval(
subtensor.get_subnet_hyperparameters(netuid=netuid).tempo,
subtensor,
netuid=netuid,
reporting_interval=1,
)
# Fetch the latest drand pulse
latest_drand_round = subtensor.last_drand_round()
logging.console.info(
f"Latest drand round after waiting for tempo: {latest_drand_round}"
)
# Fetch weights on the chain as they should be revealed now
revealed_weights_ = subtensor.weights(netuid=netuid)
print("revealed weights", revealed_weights_)
revealed_weights = revealed_weights_[0][1]
# Assert correct weights were revealed
assert weight_uids[0] == revealed_weights[0][0]
assert weight_vals[0] == revealed_weights[0][1]
# Now that the commit has been revealed, there shouldn't be any pending commits
assert subtensor.get_current_weight_commit_info(netuid=netuid) == []
# Ensure the drand_round is always in the positive w.r.t expected when revealed
assert (
latest_drand_round - expected_reveal_round >= 0
), f"latest_drand_round ({latest_drand_round}) is less than expected_reveal_round ({expected_reveal_round})"
logging.console.info("✅ Passed commit_reveal v3")