diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index f30f9c48a7..494da0b011 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -43,7 +43,7 @@ jobs: run: | test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') # keep it here for future debug - # test_files=$(find tests/e2e_tests -type f -name "test*.py" | grep -E 'test_(incentive|commit_weights|set_weights)\.py$' | jq -R -s -c 'split("\n") | map(select(. != ""))') + # test_files=$(find tests/e2e_tests -type f -name "test*.py" | grep -E 'test_(hotkeys|staking)\.py$' | jq -R -s -c 'split("\n") | map(select(. != ""))') echo "test-files=$test_files" >> "$GITHUB_OUTPUT" shell: bash @@ -66,8 +66,8 @@ jobs: path: subtensor-localnet.tar # Job to run tests in parallel - run-e2e-test: - name: ${{ matrix.test-file }} / Python ${{ matrix.python-version }} + run-fast-blocks-e2e-test: + name: "FB: ${{ matrix.test-file }} / Python ${{ matrix.python-version }}" needs: - find-tests - pull-docker-image @@ -127,3 +127,76 @@ jobs: sleep 5 fi done + + + cron-run-non-fast-blocks-e2e-test: + if: github.event_name == 'schedule' + name: "NFB: ${{ matrix.test-file }} / Python ${{ matrix.python-version }}" + needs: + - find-tests + - pull-docker-image + runs-on: ubuntu-latest + timeout-minutes: 1440 + + strategy: + fail-fast: false # Allow other matrix jobs to run even if this job fails + max-parallel: 32 # Set the maximum number of parallel jobs (same as we have cores in ubuntu-latest runner) + matrix: + os: + - ubuntu-latest + test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + + steps: + - name: Check if today is Saturday + run: | + day=$(date -u +%u) + echo "Today is weekday $day" + if [ "$day" -ne 6 ]; then + echo "⏭️ Skipping: not Saturday" + exit 78 + fi + - name: Check-out repository + uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@v4 + + - name: install dependencies + run: uv sync --extra dev --dev + + - name: Download Cached Docker Image + uses: actions/download-artifact@v4 + with: + name: subtensor-localnet + + - name: Load Docker Image + run: docker load -i subtensor-localnet.tar + + - name: Run patched E2E tests + env: + FAST_BLOCKS: "0" + run: | + set +e + for i in 1 2 3; do + echo "🔁 Attempt $i: Running tests" + uv run pytest ${{ matrix.test-file }} -s + status=$? + if [ $status -eq 0 ]; then + echo "✅ Tests passed on attempt $i" + break + else + echo "❌ Tests failed on attempt $i" + if [ $i -eq 3 ]; then + echo "Tests failed after 3 attempts" + exit 1 + fi + echo "Retrying..." + sleep 5 + fi + done diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index edf83cf78b..7c290fa480 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -2488,6 +2488,12 @@ async def immunity_period( ) return None if call is None else int(call) + async def is_fast_blocks(self): + """Returns True if the node is running with fast blocks. False if not.""" + return ( + await self.query_constant("SubtensorModule", "DurationOfStartCall") + ).value == 10 + async def is_hotkey_delegate( self, hotkey_ss58: str, diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 796440cb90..8dde2487af 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -1971,6 +1971,10 @@ def immunity_period( ) return None if call is None else int(call) + def is_fast_blocks(self): + """Returns True if the node is running with fast blocks. False if not.""" + return self.query_constant("SubtensorModule", "DurationOfStartCall").value == 10 + def is_hotkey_delegate(self, hotkey_ss58: str, block: Optional[int] = None) -> bool: """ Determines whether a given hotkey (public key) is a delegate on the Bittensor network. This function checks if diff --git a/bittensor/core/subtensor_api/chain.py b/bittensor/core/subtensor_api/chain.py index fe03aada99..cd2bfda02f 100644 --- a/bittensor/core/subtensor_api/chain.py +++ b/bittensor/core/subtensor_api/chain.py @@ -14,6 +14,7 @@ def __init__(self, subtensor: Union["_Subtensor", "_AsyncSubtensor"]): self.get_minimum_required_stake = subtensor.get_minimum_required_stake self.get_vote_data = subtensor.get_vote_data self.get_timestamp = subtensor.get_timestamp + self.is_fast_blocks = subtensor.is_fast_blocks self.last_drand_round = subtensor.last_drand_round self.state_call = subtensor.state_call self.tx_rate_limit = subtensor.tx_rate_limit diff --git a/bittensor/core/subtensor_api/utils.py b/bittensor/core/subtensor_api/utils.py index 5d8783f6e6..0002b60216 100644 --- a/bittensor/core/subtensor_api/utils.py +++ b/bittensor/core/subtensor_api/utils.py @@ -101,6 +101,7 @@ def add_legacy_methods(subtensor: "SubtensorApi"): subtensor.get_unstake_fee = subtensor._subtensor.get_unstake_fee subtensor.get_vote_data = subtensor._subtensor.get_vote_data subtensor.immunity_period = subtensor._subtensor.immunity_period + subtensor.is_fast_blocks = subtensor._subtensor.is_fast_blocks subtensor.is_hotkey_delegate = subtensor._subtensor.is_hotkey_delegate subtensor.is_hotkey_registered = subtensor._subtensor.is_hotkey_registered subtensor.is_hotkey_registered_any = subtensor._subtensor.is_hotkey_registered_any diff --git a/tests/e2e_tests/conftest.py b/tests/e2e_tests/conftest.py index cd5229d5ee..ae3d11b50d 100644 --- a/tests/e2e_tests/conftest.py +++ b/tests/e2e_tests/conftest.py @@ -206,10 +206,13 @@ def stop_existing_test_containers(): "9944:9944", "-p", "9945:9945", - LOCALNET_IMAGE_NAME, - params, + str(LOCALNET_IMAGE_NAME), ] + cmds += params.split() if params else [] + + print("Entire run command: ", cmds) + try_start_docker() stop_existing_test_containers() @@ -275,7 +278,19 @@ def bob_wallet(): return wallet +@pytest.fixture +def charlie_wallet(): + keypair, wallet = setup_wallet("//Charlie") + return wallet + + @pytest.fixture def dave_wallet(): keypair, wallet = setup_wallet("//Dave") return wallet + + +@pytest.fixture +def eve_wallet(): + keypair, wallet = setup_wallet("//Eve") + return wallet diff --git a/tests/e2e_tests/test_commit_reveal_v3.py b/tests/e2e_tests/test_commit_reveal_v3.py index 6fdf02101f..719dbe5827 100644 --- a/tests/e2e_tests/test_commit_reveal_v3.py +++ b/tests/e2e_tests/test_commit_reveal_v3.py @@ -30,17 +30,22 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle Raises: AssertionError: If any of the checks or verifications fail """ - BLOCK_TIME = 0.25 # 12 for non-fast-block, 0.25 for fast block - netuid = 2 + BLOCK_TIME = ( + 0.25 if subtensor.is_fast_blocks() else 12.0 + ) # 12 for non-fast-block, 0.25 for fast block + netuid = subtensor.get_total_subnets() # 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" + assert subtensor.subnet_exists(netuid), ( + f"Subnet {netuid} wasn't created successfully" + ) - logging.console.info("Subnet 2 is registered") + logging.console.success(f"Subnet {netuid} is registered") # Enable commit_reveal on the subnet assert sudo_set_hyperparameter_bool( @@ -74,7 +79,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle logging.console.info("sudo_set_weights_set_rate_limit executed: set to 0") # Change the tempo of the subnet - tempo_set = 50 + tempo_set = 50 if subtensor.is_fast_blocks() else 10 assert ( sudo_set_admin_utils( local_chain, @@ -103,7 +108,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle ) # Wait for 2 tempos to pass as CR3 only reveals weights after 2 tempos + 1 - subtensor.wait_for_block((tempo_set * 2) + 1) + subtensor.wait_for_block(tempo_set * 2 + 1) # Lower than this might mean weights will get revealed before we can check them if upcoming_tempo - current_block < 3: @@ -117,7 +122,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle latest_drand_round = subtensor.last_drand_round() upcoming_tempo = next_tempo(current_block, tempo) logging.console.info( - f"Post first wait_interval (to ensure window isnt too low): {current_block}, next tempo: {upcoming_tempo}, drand: {latest_drand_round}" + f"Post first wait_interval (to ensure window isn't too low): {current_block}, next tempo: {upcoming_tempo}, drand: {latest_drand_round}" ) # Commit weights @@ -171,6 +176,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle subtensor, netuid=netuid, reporting_interval=1, + sleep=BLOCK_TIME, ) # Fetch the latest drand pulse diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index d3dabf6152..7f98d8a6f6 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -27,7 +27,7 @@ async def test_commit_and_reveal_weights_legacy(local_chain, subtensor, alice_wa AssertionError: If any of the checks or verifications fail """ netuid = subtensor.get_total_subnets() # 2 - + set_tempo = 100 if subtensor.is_fast_blocks() else 10 print("Testing test_commit_and_reveal_weights") # Register root as Alice @@ -78,7 +78,7 @@ async def test_commit_and_reveal_weights_legacy(local_chain, subtensor, alice_wa call_function="sudo_set_tempo", call_params={ "netuid": netuid, - "tempo": 100, + "tempo": set_tempo, }, ) @@ -165,11 +165,11 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall Raises: AssertionError: If any of the checks or verifications fail """ - subnet_tempo = 50 + subnet_tempo = 50 if subtensor.is_fast_blocks() else 10 netuid = subtensor.get_total_subnets() # 2 # Wait for 2 tempos to pass as CR3 only reveals weights after 2 tempos - subtensor.wait_for_block(subnet_tempo * 2 + 1) + subtensor.wait_for_block(subtensor.block + (subnet_tempo * 2) + 1) print("Testing test_commit_and_reveal_weights") # Register root as Alice @@ -267,8 +267,9 @@ def send_commit(salt_, weight_uids_, weight_vals_): send_commit(salt, weight_uids, weight_vals) - # let's wait for 3 (12 fast blocks) seconds between transactions - subtensor.wait_for_block(subtensor.block + 12) + # let's wait for 3 (12 fast blocks) seconds between transactions, next block for non-fast-blocks + waiting_block = (subtensor.block + 12) if subtensor.is_fast_blocks() else None + subtensor.wait_for_block(waiting_block) logging.console.info( f"[orange]Nonce after third commit_weights: " @@ -276,7 +277,12 @@ def send_commit(salt_, weight_uids_, weight_vals_): ) # Wait a few blocks - subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuid) * 2) + waiting_block = ( + (subtensor.block + subtensor.tempo(netuid) * 2) + if subtensor.is_fast_blocks() + else None + ) + subtensor.wait_for_block(waiting_block) # Query the WeightCommits storage map for all three salts weight_commits = subtensor.query_module( diff --git a/tests/e2e_tests/test_commitment.py b/tests/e2e_tests/test_commitment.py index e4704c8d8f..a6a33f98c2 100644 --- a/tests/e2e_tests/test_commitment.py +++ b/tests/e2e_tests/test_commitment.py @@ -3,7 +3,10 @@ from bittensor import logging from tests.e2e_tests.utils.chain_interactions import sudo_set_admin_utils -from tests.e2e_tests.utils.e2e_test_utils import wait_to_start_call +from tests.e2e_tests.utils.e2e_test_utils import ( + wait_to_start_call, + async_wait_to_start_call, +) logging.set_trace() @@ -15,7 +18,7 @@ def test_commitment(local_chain, subtensor, alice_wallet, dave_wallet): "Subnet wasn't created successfully" ) - assert wait_to_start_call(subtensor, dave_wallet, dave_subnet_netuid, 10) + assert wait_to_start_call(subtensor, dave_wallet, dave_subnet_netuid) with pytest.raises(SubstrateRequestException, match="AccountNotAllowedCommit"): subtensor.set_commitment( @@ -93,11 +96,9 @@ async def test_commitment_async( "Subnet wasn't created successfully" ) - await async_subtensor.wait_for_block(await async_subtensor.block + 20) - status, message = await async_subtensor.start_call( - dave_wallet, dave_subnet_netuid, True, True + assert await async_wait_to_start_call( + async_subtensor, dave_wallet, dave_subnet_netuid ) - assert status, message async with async_subtensor as sub: with pytest.raises(SubstrateRequestException, match="AccountNotAllowedCommit"): diff --git a/tests/e2e_tests/test_delegate.py b/tests/e2e_tests/test_delegate.py index c66691351d..c3157c9db1 100644 --- a/tests/e2e_tests/test_delegate.py +++ b/tests/e2e_tests/test_delegate.py @@ -171,7 +171,7 @@ def test_change_take(local_chain, subtensor, alice_wallet, bob_wallet): @pytest.mark.asyncio -async def test_delegates(subtensor, alice_wallet, bob_wallet): +async def test_delegates(local_chain, subtensor, alice_wallet, bob_wallet): """ Tests: - Check default Delegates @@ -240,6 +240,7 @@ async def test_delegates(subtensor, alice_wallet, bob_wallet): assert subtensor.get_delegated(bob_wallet.coldkey.ss58_address) == [] alice_subnet_netuid = subtensor.get_total_subnets() # 2 + set_tempo = 10 # Register a subnet, netuid 2 assert subtensor.register_subnet(alice_wallet), "Subnet wasn't created" @@ -250,6 +251,17 @@ async def test_delegates(subtensor, alice_wallet, bob_wallet): assert wait_to_start_call(subtensor, alice_wallet, alice_subnet_netuid) + # set the same tempo for both type of nodes (fast and non-fast blocks) + assert ( + sudo_set_admin_utils( + local_chain, + alice_wallet, + call_function="sudo_set_tempo", + call_params={"netuid": alice_subnet_netuid, "tempo": set_tempo}, + )[0] + is True + ) + subtensor.add_stake( bob_wallet, alice_wallet.hotkey.ss58_address, @@ -259,6 +271,9 @@ async def test_delegates(subtensor, alice_wallet, bob_wallet): wait_for_finalization=True, ) + # let chain update validator_permits + subtensor.wait_for_block(subtensor.block + set_tempo + 1) + bob_delegated = subtensor.get_delegated(bob_wallet.coldkey.ss58_address) assert bob_delegated == [ DelegatedInfo( @@ -272,9 +287,10 @@ async def test_delegates(subtensor, alice_wallet, bob_wallet): bob_delegated[0].total_daily_return.rao ), netuid=alice_subnet_netuid, - stake=get_dynamic_balance(bob_delegated[0].stake.rao), + stake=get_dynamic_balance(bob_delegated[0].stake.rao, alice_subnet_netuid), ), ] + bittensor.logging.console.success("Test [green]test_delegates[/green] passed.") def test_nominator_min_required_stake(local_chain, subtensor, alice_wallet, bob_wallet): diff --git a/tests/e2e_tests/test_hotkeys.py b/tests/e2e_tests/test_hotkeys.py index f28f4c07f9..3a699f08d0 100644 --- a/tests/e2e_tests/test_hotkeys.py +++ b/tests/e2e_tests/test_hotkeys.py @@ -1,14 +1,22 @@ import pytest -import bittensor -from tests.e2e_tests.utils.chain_interactions import ( - sudo_set_admin_utils, - wait_epoch, +from bittensor.core.errors import ( + NotEnoughStakeToSetChildkeys, + RegistrationNotPermittedOnRootSubnet, + SubNetworkDoesNotExist, + InvalidChild, + TooManyChildren, + ProportionOverflow, + DuplicateChild, + TxRateLimitExceeded, + NonAssociatedColdKey, ) +from bittensor.utils.btlogging import logging +from tests.e2e_tests.utils.chain_interactions import sudo_set_admin_utils from tests.e2e_tests.utils.e2e_test_utils import wait_to_start_call -SET_CHILDREN_COOLDOWN_PERIOD = 15 -SET_CHILDREN_RATE_LIMIT = 150 + +SET_CHILDREN_RATE_LIMIT = 15 def test_hotkeys(subtensor, alice_wallet, dave_wallet): @@ -17,8 +25,7 @@ def test_hotkeys(subtensor, alice_wallet, dave_wallet): - Check if Hotkey exists - Check if Hotkey is registered """ - - dave_subnet_netuid = 2 + dave_subnet_netuid = subtensor.get_total_subnets() # 2 assert subtensor.register_subnet(dave_wallet, True, True) assert subtensor.subnet_exists(dave_subnet_netuid), ( f"Subnet #{dave_subnet_netuid} does not exist." @@ -62,6 +69,7 @@ def test_hotkeys(subtensor, alice_wallet, dave_wallet): ) is True ) + logging.console.success(f"✅ Test [green]test_hotkeys[/green] passed") @pytest.mark.asyncio @@ -76,7 +84,9 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w - Clear children list """ - dave_subnet_netuid = 2 + dave_subnet_netuid = subtensor.get_total_subnets() # 2 + set_tempo = 10 # affect to non-fast-blocks mode + assert subtensor.register_subnet(dave_wallet, True, True) assert subtensor.subnet_exists(dave_subnet_netuid), ( f"Subnet #{dave_subnet_netuid} does not exist." @@ -84,7 +94,29 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w assert wait_to_start_call(subtensor, dave_wallet, dave_subnet_netuid) - with pytest.raises(bittensor.RegistrationNotPermittedOnRootSubnet): + # set the same tempo for both type of nodes (to avoid tests timeout) + if not subtensor.is_fast_blocks(): + assert ( + sudo_set_admin_utils( + local_chain, + alice_wallet, + call_function="sudo_set_tempo", + call_params={"netuid": dave_subnet_netuid, "tempo": set_tempo}, + )[0] + is True + ) + + assert ( + sudo_set_admin_utils( + local_chain, + alice_wallet, + call_function="sudo_set_tx_rate_limit", + call_params={"tx_rate_limit": 0}, + )[0] + is True + ) + + with pytest.raises(RegistrationNotPermittedOnRootSubnet): subtensor.set_children( alice_wallet, alice_wallet.hotkey.ss58_address, @@ -93,7 +125,7 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w raise_error=True, ) - with pytest.raises(bittensor.NonAssociatedColdKey): + with pytest.raises(NonAssociatedColdKey): subtensor.set_children( alice_wallet, alice_wallet.hotkey.ss58_address, @@ -102,7 +134,7 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w raise_error=True, ) - with pytest.raises(bittensor.SubNetworkDoesNotExist): + with pytest.raises(SubNetworkDoesNotExist): subtensor.set_children( alice_wallet, alice_wallet.hotkey.ss58_address, @@ -115,10 +147,12 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w alice_wallet, netuid=dave_subnet_netuid, ) + logging.console.success(f"Alice registered on subnet {dave_subnet_netuid}") subtensor.burned_register( bob_wallet, netuid=dave_subnet_netuid, ) + logging.console.success(f"Bob registered on subnet {dave_subnet_netuid}") success, children, error = subtensor.get_children( alice_wallet.hotkey.ss58_address, @@ -129,7 +163,7 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w assert success is True assert children == [] - with pytest.raises(bittensor.InvalidChild): + with pytest.raises(InvalidChild): subtensor.set_children( alice_wallet, alice_wallet.hotkey.ss58_address, @@ -143,7 +177,7 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w raise_error=True, ) - with pytest.raises(bittensor.TooManyChildren): + with pytest.raises(TooManyChildren): subtensor.set_children( alice_wallet, alice_wallet.hotkey.ss58_address, @@ -158,7 +192,7 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w raise_error=True, ) - with pytest.raises(bittensor.ProportionOverflow): + with pytest.raises(ProportionOverflow): subtensor.set_children( alice_wallet, alice_wallet.hotkey.ss58_address, @@ -176,7 +210,7 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w raise_error=True, ) - with pytest.raises(bittensor.DuplicateChild): + with pytest.raises(DuplicateChild): subtensor.set_children( alice_wallet, alice_wallet.hotkey.ss58_address, @@ -229,16 +263,9 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w netuid=dave_subnet_netuid, ) - assert pending == [ - ( - 1.0, - "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", - ), - ] + assert pending == [(1.0, bob_wallet.hotkey.ss58_address)] - subtensor.wait_for_block(cooldown) - - await wait_epoch(subtensor, netuid=1) + subtensor.wait_for_block(cooldown + 15) success, children, error = subtensor.get_children( alice_wallet.hotkey.ss58_address, @@ -247,22 +274,24 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w assert error == "" assert success is True - assert children == [ - ( - 1.0, - bob_wallet.hotkey.ss58_address, - ) - ] + assert children == [(1.0, bob_wallet.hotkey.ss58_address)] # pending queue is empty pending, cooldown = subtensor.get_children_pending( alice_wallet.hotkey.ss58_address, netuid=dave_subnet_netuid, ) - assert pending == [] - with pytest.raises(bittensor.TxRateLimitExceeded): + with pytest.raises(TxRateLimitExceeded): + set_children_block = subtensor.get_current_block() + subtensor.set_children( + alice_wallet, + alice_wallet.hotkey.ss58_address, + netuid=dave_subnet_netuid, + children=[], + raise_error=True, + ) subtensor.set_children( alice_wallet, alice_wallet.hotkey.ss58_address, @@ -311,7 +340,7 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w }, ) - with pytest.raises(bittensor.NotEnoughStakeToSetChildkeys): + with pytest.raises(NotEnoughStakeToSetChildkeys): subtensor.set_children( alice_wallet, alice_wallet.hotkey.ss58_address, @@ -324,3 +353,5 @@ async def test_children(local_chain, subtensor, alice_wallet, bob_wallet, dave_w ], raise_error=True, ) + + logging.console.success(f"✅ Test [green]test_children[/green] passed") diff --git a/tests/e2e_tests/test_reveal_commitments.py b/tests/e2e_tests/test_reveal_commitments.py index 40cc8794a1..c4757e24cb 100644 --- a/tests/e2e_tests/test_reveal_commitments.py +++ b/tests/e2e_tests/test_reveal_commitments.py @@ -26,8 +26,10 @@ async def test_set_reveal_commitment(local_chain, subtensor, alice_wallet, bob_w Note: Actually we can run this tests in fast block mode. For this we need to set `BLOCK_TIME` to 0.25 and replace `False` to `True` in `pytest.mark.parametrize` decorator. """ - BLOCK_TIME = 0.25 # 12 for non-fast-block, 0.25 for fast block - BLOCKS_UNTIL_REVEAL = 10 + BLOCK_TIME = ( + 0.25 if subtensor.is_fast_blocks() else 12.0 + ) # 12 for non-fast-block, 0.25 for fast block + BLOCKS_UNTIL_REVEAL = 10 if subtensor.is_fast_blocks() else 5 alice_subnet_netuid = subtensor.get_total_subnets() # 2 @@ -79,7 +81,8 @@ async def test_set_reveal_commitment(local_chain, subtensor, alice_wallet, bob_w # Sometimes the chain doesn't update the repository right away and the commit doesn't appear in the expected # `last_drand_round`. In this case need to wait a bit. print(f"Waiting for reveal round {target_reveal_round}") - while subtensor.last_drand_round() <= target_reveal_round + 1: + chain_offset = 1 if subtensor.is_fast_blocks() else 24 + while subtensor.last_drand_round() <= target_reveal_round + chain_offset: # wait one drand period (3 sec) print(f"Current last reveled drand round {subtensor.last_drand_round()}") time.sleep(3) diff --git a/tests/e2e_tests/test_root_set_weights.py b/tests/e2e_tests/test_root_set_weights.py index f399a071b3..5973a144cb 100644 --- a/tests/e2e_tests/test_root_set_weights.py +++ b/tests/e2e_tests/test_root_set_weights.py @@ -62,7 +62,7 @@ async def test_root_reg_hyperparams( # Default immunity period & tempo set through the subtensor side default_immunity_period = 5000 - default_tempo = 10 + default_tempo = 10 if subtensor.is_fast_blocks() else 360 # 0.2 for root network, 0.8 for sn 1 # Corresponding to [0.2, 0.8] diff --git a/tests/e2e_tests/test_staking.py b/tests/e2e_tests/test_staking.py index 37bb87e332..f9bcc45510 100644 --- a/tests/e2e_tests/test_staking.py +++ b/tests/e2e_tests/test_staking.py @@ -5,8 +5,6 @@ from tests.helpers.helpers import ApproxBalance from tests.e2e_tests.utils.e2e_test_utils import wait_to_start_call -logging.enable_debug() - def test_single_operation(subtensor, alice_wallet, bob_wallet): """ @@ -28,29 +26,31 @@ def test_single_operation(subtensor, alice_wallet, bob_wallet): assert wait_to_start_call(subtensor, alice_wallet, alice_subnet_netuid) subtensor.burned_register( - alice_wallet, + wallet=alice_wallet, netuid=alice_subnet_netuid, wait_for_inclusion=True, wait_for_finalization=True, ) + logging.console.success(f"Alice is registered in subnet {alice_subnet_netuid}") subtensor.burned_register( - bob_wallet, + wallet=bob_wallet, netuid=alice_subnet_netuid, wait_for_inclusion=True, wait_for_finalization=True, ) + logging.console.success(f"Bob is registered in subnet {alice_subnet_netuid}") stake = subtensor.get_stake( - alice_wallet.coldkey.ss58_address, - bob_wallet.hotkey.ss58_address, + coldkey_ss58=alice_wallet.coldkey.ss58_address, + hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, ) assert stake == Balance(0).set_unit(alice_subnet_netuid) success = subtensor.add_stake( - alice_wallet, - bob_wallet.hotkey.ss58_address, + wallet=alice_wallet, + hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, amount=Balance.from_tao(1), wait_for_inclusion=True, @@ -61,24 +61,26 @@ def test_single_operation(subtensor, alice_wallet, bob_wallet): assert success is True stake_alice = subtensor.get_stake( - alice_wallet.coldkey.ss58_address, - alice_wallet.hotkey.ss58_address, + coldkey_ss58=alice_wallet.coldkey.ss58_address, + hotkey_ss58=alice_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, ) + logging.console.info(f"Alice stake: {stake_alice}") stake_bob = subtensor.get_stake( - alice_wallet.coldkey.ss58_address, - bob_wallet.hotkey.ss58_address, + coldkey_ss58=alice_wallet.coldkey.ss58_address, + hotkey_ss58=bob_wallet.hotkey.ss58_address, netuid=alice_subnet_netuid, ) + logging.console.info(f"Bob stake: {stake_bob}") assert stake_bob > Balance(0).set_unit(alice_subnet_netuid) stakes = subtensor.get_stake_for_coldkey(alice_wallet.coldkey.ss58_address) - assert stakes == [ + expected_stakes = [ StakeInfo( - hotkey_ss58=alice_wallet.hotkey.ss58_address, + hotkey_ss58=stakes[0].hotkey_ss58, coldkey_ss58=alice_wallet.coldkey.ss58_address, netuid=alice_subnet_netuid, stake=get_dynamic_balance(stakes[0].stake.rao, alice_subnet_netuid), @@ -87,42 +89,31 @@ def test_single_operation(subtensor, alice_wallet, bob_wallet): drain=0, is_registered=True, ), - StakeInfo( - hotkey_ss58=bob_wallet.hotkey.ss58_address, - coldkey_ss58=alice_wallet.coldkey.ss58_address, - netuid=alice_subnet_netuid, - stake=get_dynamic_balance(stakes[1].stake.rao, alice_subnet_netuid), - locked=Balance(0).set_unit(alice_subnet_netuid), - emission=get_dynamic_balance(stakes[1].emission.rao, alice_subnet_netuid), - drain=0, - is_registered=True, - ), ] - stakes = subtensor.get_stake_info_for_coldkey(alice_wallet.coldkey.ss58_address) - - assert stakes == [ - StakeInfo( - hotkey_ss58=alice_wallet.hotkey.ss58_address, - coldkey_ss58=alice_wallet.coldkey.ss58_address, - netuid=alice_subnet_netuid, - stake=get_dynamic_balance(stakes[0].stake.rao, alice_subnet_netuid), - locked=Balance(0).set_unit(alice_subnet_netuid), - emission=get_dynamic_balance(stakes[0].emission.rao, alice_subnet_netuid), - drain=0, - is_registered=True, - ), - StakeInfo( - hotkey_ss58=bob_wallet.hotkey.ss58_address, - coldkey_ss58=alice_wallet.coldkey.ss58_address, - netuid=alice_subnet_netuid, - stake=get_dynamic_balance(stakes[1].stake.rao, alice_subnet_netuid), - locked=Balance(0).set_unit(alice_subnet_netuid), - emission=get_dynamic_balance(stakes[1].emission.rao, alice_subnet_netuid), - drain=0, - is_registered=True, - ), - ] + fast_blocks_stake = ( + [ + StakeInfo( + hotkey_ss58=stakes[1].hotkey_ss58, + coldkey_ss58=alice_wallet.coldkey.ss58_address, + netuid=alice_subnet_netuid, + stake=get_dynamic_balance(stakes[1].stake.rao, alice_subnet_netuid), + locked=Balance(0).set_unit(alice_subnet_netuid), + emission=get_dynamic_balance( + stakes[1].emission.rao, alice_subnet_netuid + ), + drain=0, + is_registered=True, + ) + ] + if subtensor.is_fast_blocks() + else [] + ) + + expected_stakes += fast_blocks_stake + + assert stakes == expected_stakes + assert subtensor.get_stake_for_coldkey == subtensor.get_stake_info_for_coldkey stakes = subtensor.get_stake_for_coldkey_and_hotkey( alice_wallet.coldkey.ss58_address, @@ -182,6 +173,7 @@ def test_single_operation(subtensor, alice_wallet, bob_wallet): # all balances have been unstaked assert stake == Balance(0).set_unit(alice_subnet_netuid) + logging.console.success(f"✅ Test [green]test_single_operation[/green] passed") def test_batch_operations(subtensor, alice_wallet, bob_wallet): @@ -303,6 +295,7 @@ def test_batch_operations(subtensor, alice_wallet, bob_wallet): bob_wallet.coldkey.ss58_address: Balance.from_tao(999_998), } assert balances[alice_wallet.coldkey.ss58_address] > alice_balance + logging.console.success(f"✅ Test [green]test_batch_operations[/green] passed") def test_safe_staking_scenarios(subtensor, alice_wallet, bob_wallet): @@ -477,6 +470,9 @@ def test_safe_staking_scenarios(subtensor, alice_wallet, bob_wallet): allow_partial_stake=False, ) assert success is True, "Unstake should succeed" + logging.console.success( + f"✅ Test [green]test_safe_staking_scenarios[/green] passed" + ) def test_safe_swap_stake_scenarios(subtensor, alice_wallet, bob_wallet): @@ -588,6 +584,9 @@ def test_safe_swap_stake_scenarios(subtensor, alice_wallet, bob_wallet): assert dest_stake > Balance(0), ( "Destination stake should be non-zero after successful swap" ) + logging.console.success( + f"✅ Test [green]test_safe_swap_stake_scenarios[/green] passed" + ) def test_move_stake(subtensor, alice_wallet, bob_wallet): @@ -657,29 +656,43 @@ def test_move_stake(subtensor, alice_wallet, bob_wallet): stakes = subtensor.get_stake_for_coldkey(alice_wallet.coldkey.ss58_address) - assert stakes == [ + expected_stakes = [ StakeInfo( - hotkey_ss58=alice_wallet.hotkey.ss58_address, + hotkey_ss58=stakes[0].hotkey_ss58, coldkey_ss58=alice_wallet.coldkey.ss58_address, - netuid=alice_subnet_netuid, + netuid=alice_subnet_netuid + if subtensor.is_fast_blocks() + else bob_subnet_netuid, stake=get_dynamic_balance(stakes[0].stake.rao, bob_subnet_netuid), locked=Balance(0).set_unit(bob_subnet_netuid), emission=get_dynamic_balance(stakes[0].emission.rao, bob_subnet_netuid), drain=0, is_registered=True, - ), - StakeInfo( - hotkey_ss58=bob_wallet.hotkey.ss58_address, - coldkey_ss58=alice_wallet.coldkey.ss58_address, - netuid=bob_subnet_netuid, - stake=get_dynamic_balance(stakes[1].stake.rao, bob_subnet_netuid), - locked=Balance(0).set_unit(bob_subnet_netuid), - emission=get_dynamic_balance(stakes[1].emission.rao, bob_subnet_netuid), - drain=0, - is_registered=True, - ), + ) ] + fast_block_stake = ( + [ + StakeInfo( + hotkey_ss58=stakes[1].hotkey_ss58, + coldkey_ss58=alice_wallet.coldkey.ss58_address, + netuid=bob_subnet_netuid, + stake=get_dynamic_balance(stakes[1].stake.rao, bob_subnet_netuid), + locked=Balance(0).set_unit(bob_subnet_netuid), + emission=get_dynamic_balance(stakes[1].emission.rao, bob_subnet_netuid), + drain=0, + is_registered=True, + ), + ] + if subtensor.is_fast_blocks() + else [] + ) + + expected_stakes += fast_block_stake + + assert stakes == expected_stakes + logging.console.success(f"✅ Test [green]test_move_stake[/green] passed") + def test_transfer_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): """ @@ -758,24 +771,32 @@ def test_transfer_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): alice_stakes = subtensor.get_stake_for_coldkey(alice_wallet.coldkey.ss58_address) - assert alice_stakes == [ - StakeInfo( - hotkey_ss58=alice_wallet.hotkey.ss58_address, - coldkey_ss58=alice_wallet.coldkey.ss58_address, - netuid=alice_subnet_netuid, - stake=get_dynamic_balance(alice_stakes[0].stake.rao, alice_subnet_netuid), - locked=Balance(0).set_unit(alice_subnet_netuid), - emission=get_dynamic_balance( - alice_stakes[0].emission.rao, alice_subnet_netuid + expected_alice_stake = ( + [ + StakeInfo( + hotkey_ss58=alice_wallet.hotkey.ss58_address, + coldkey_ss58=alice_wallet.coldkey.ss58_address, + netuid=alice_subnet_netuid, + stake=get_dynamic_balance( + alice_stakes[0].stake.rao, alice_subnet_netuid + ), + locked=Balance(0).set_unit(alice_subnet_netuid), + emission=get_dynamic_balance( + alice_stakes[0].emission.rao, alice_subnet_netuid + ), + drain=0, + is_registered=True, ), - drain=0, - is_registered=True, - ), - ] + ] + if subtensor.is_fast_blocks() + else [] + ) + + assert alice_stakes == expected_alice_stake bob_stakes = subtensor.get_stake_for_coldkey(bob_wallet.coldkey.ss58_address) - assert bob_stakes == [ + expected_bob_stake = [ StakeInfo( hotkey_ss58=alice_wallet.hotkey.ss58_address, coldkey_ss58=bob_wallet.coldkey.ss58_address, @@ -789,3 +810,5 @@ def test_transfer_stake(subtensor, alice_wallet, bob_wallet, dave_wallet): is_registered=False, ), ] + assert bob_stakes == expected_bob_stake + logging.console.success(f"✅ Test [green]test_transfer_stake[/green] passed") diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index a688156c7b..745c8977ab 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -235,6 +235,13 @@ def wait_to_start_call( in_blocks: int = 10, ): """Waits for a certain number of blocks before making a start call.""" + if subtensor.is_fast_blocks() is False: + in_blocks = 5 + bittensor.logging.console.info( + f"Waiting for [blue]{in_blocks}[/blue] blocks before [red]start call[/red]. " + f"Current block: [blue]{subtensor.block}[/blue]." + ) + # make sure we passed start_call limit subtensor.wait_for_block(subtensor.block + in_blocks + 1) status, message = subtensor.start_call( @@ -254,6 +261,14 @@ async def async_wait_to_start_call( in_blocks: int = 10, ): """Waits for a certain number of blocks before making a start call.""" + if await subtensor.is_fast_blocks() is False: + in_blocks = 5 + + bittensor.logging.console.info( + f"Waiting for [blue]{in_blocks}[/blue] blocks before [red]start call[/red]. " + f"Current block: [blue]{subtensor.block}[/blue]." + ) + # make sure we passed start_call limit current_block = await subtensor.block await subtensor.wait_for_block(current_block + in_blocks + 1)