-
Notifications
You must be signed in to change notification settings - Fork 338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added e2e test for CRv3 + enhancements #2532
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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 |
---|---|---|
|
@@ -1291,6 +1291,40 @@ def neurons(self, netuid: int, block: Optional[int] = None) -> list["NeuronInfo" | |
|
||
return neurons | ||
|
||
def last_drand_round( | ||
self, | ||
) -> Optional[int]: | ||
""" | ||
Retrieves the last drand round emitted in bittensor. This corresponds when committed weights will be revealed. | ||
|
||
Returns: | ||
int: The latest Drand round emitted in bittensor. | ||
""" | ||
result = self.substrate.query( | ||
module="Drand", storage_function="LastStoredRound" | ||
) | ||
return getattr(result, "value", None) | ||
|
||
def get_weight_commits(self, netuid: int, block: Optional[int] = None) -> list: | ||
""" | ||
Retrieves CRV3 weight commit information for a specific subnet. | ||
|
||
Args: | ||
netuid (int): The unique identifier of the subnet. | ||
block (Optional[int]): The blockchain block number for the query. | ||
|
||
Returns: | ||
list: A list of commit details, where each entry is a dictionary with keys 'who', | ||
'serialized_commit', and 'reveal_round', or an empty list if no data is found. | ||
""" | ||
result = self.query_map( | ||
module="SubtensorModule", | ||
name="CRV3WeightCommits", | ||
params=[netuid], | ||
block=block, | ||
) | ||
return result.records[0][1].value if result and result.records else [] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thing here |
||
|
||
def get_total_subnets(self, block: Optional[int] = None) -> Optional[int]: | ||
""" | ||
Retrieves the total number of subnets within the Bittensor network as of a specific blockchain block. | ||
|
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,188 @@ | ||
import re | ||
|
||
import numpy as np | ||
import pytest | ||
from bittensor.utils.btlogging import logging | ||
from bittensor.core.subtensor import Subtensor | ||
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 ( | ||
add_stake, | ||
register_subnet, | ||
sudo_set_hyperparameter_bool, | ||
sudo_set_hyperparameter_values, | ||
wait_interval, | ||
sudo_set_admin_utils, | ||
next_tempo, | ||
) | ||
from tests.e2e_tests.utils.e2e_test_utils import setup_wallet | ||
|
||
|
||
# Skipping till we have CRV3 on testnet | ||
@pytest.mark.skip | ||
@pytest.mark.parametrize("local_chain", [False], indirect=True) | ||
@pytest.mark.asyncio | ||
async def test_commit_and_reveal_weights_cr3(local_chain): | ||
""" | ||
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 = 1 | ||
logging.console.info("Testing test_commit_and_reveal_weights") | ||
|
||
# Register root as Alice | ||
keypair, alice_wallet = setup_wallet("//Alice") | ||
assert register_subnet(local_chain, alice_wallet), "Unable to register the subnet" | ||
|
||
# Verify subnet 1 created successfully | ||
assert local_chain.query( | ||
"SubtensorModule", "NetworksAdded", [1] | ||
).serialize(), "Subnet wasn't created successfully" | ||
|
||
logging.console.info("Subnet 1 is registered") | ||
|
||
subtensor = Subtensor(network="ws://localhost:9945") | ||
|
||
# Register Alice to the subnet | ||
assert subtensor.burned_register( | ||
alice_wallet, netuid | ||
), "Unable to register Alice as a neuron" | ||
logging.console.info("Registered Alice to subnet 1") | ||
|
||
# Stake to become to top neuron after the first epoch | ||
add_stake(local_chain, alice_wallet, Balance.from_tao(100_000)) | ||
logging.console.info("Stake added by Alice") | ||
|
||
# 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, | ||
) | ||
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) | ||
revealed_weights = np.array([0.1], dtype=np.float32) | ||
weight_uids, weight_vals = convert_weights_and_uids_for_emit( | ||
uids=uids, weights=revealed_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) | ||
|
||
# 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, | ||
) | ||
|
||
# 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)) | ||
logging.console.info( | ||
f"Successfully set weights: uids {weight_uids}, weights {weight_vals}" | ||
) | ||
|
||
# Parse expected reveal_round | ||
expected_reveal_round = int(message.split(":")[1]) | ||
|
||
# Fetch current commits pending on the chain | ||
commits_on_chain = subtensor.get_weight_commits(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() | ||
|
||
# Fetch weights on the chain as they should be revealed now | ||
revealed_weights = subtensor.weights(netuid=netuid)[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_weight_commits(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") |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make a note that we'll need to update this after #2526 is merged