From 2b9b1a02e2c907c41e0acba0991cfdead2ec76c9 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 13:43:43 -0700 Subject: [PATCH 001/150] adding one extra epoch since set_weight can be executed at the epoch boundary --- tests/e2e_tests/test_incentive.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 56f23ddd52..d0fc1615b6 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -95,8 +95,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa }, ) - assert error is None - assert status is True + assert error is None and status is True, "Failed to set weights_set_rate_limit" async with templates.miner(bob_wallet, netuid): async with templates.validator(alice_wallet, netuid) as validator: @@ -104,7 +103,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa await asyncio.wait_for(validator.set_weights.wait(), 60) # Wait till new epoch - await wait_interval(tempo, subtensor, netuid) + await wait_interval(tempo, subtensor, netuid, times=2) # Refresh metagraph metagraph = subtensor.metagraph(netuid) From 9cf13ba1ee77221de972ed5ec9f0b1b9c950acf2 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 13:49:16 -0700 Subject: [PATCH 002/150] temporarily run only 1 test --- .github/workflows/e2e-subtensor-tests.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index c74c5fadfe..8966ee4496 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -38,7 +38,8 @@ jobs: - name: Find test files id: get-tests run: | - test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + # test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + test_files=$(find tests/e2e_tests -name "test_incentive.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') echo "::set-output name=test-files::$test_files" shell: bash From b626be42470e0faff9584e39a1cd3a6aa656f3b3 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 13:57:00 -0700 Subject: [PATCH 003/150] replace runner --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 8966ee4496..ff131265f4 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -67,7 +67,7 @@ jobs: needs: - find-tests - pull-docker-image - runs-on: ubuntu-latest + runs-on: SubtensorCI timeout-minutes: 45 strategy: fail-fast: false # Allow other matrix jobs to run even if this job fails From 146dd0e2d242db68dd14300c12834a485dea28e5 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 14:02:44 -0700 Subject: [PATCH 004/150] wait 1 second --- tests/e2e_tests/test_incentive.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index d0fc1615b6..ce48093e83 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -103,7 +103,8 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa await asyncio.wait_for(validator.set_weights.wait(), 60) # Wait till new epoch - await wait_interval(tempo, subtensor, netuid, times=2) + # times=4 means let's wait at least 10 second to store weights in the chain (for fast block and powerful SubtensorCI GH runner) + await wait_interval(tempo, subtensor, netuid, times=4) # Refresh metagraph metagraph = subtensor.metagraph(netuid) From 3a6a702e7f876d09e41db1b0e635a15685a8049f Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 14:18:44 -0700 Subject: [PATCH 005/150] add retry --- tests/e2e_tests/test_incentive.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index ce48093e83..048b75a702 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -99,12 +99,25 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa async with templates.miner(bob_wallet, netuid): async with templates.validator(alice_wallet, netuid) as validator: - # wait for the Validator to process and set_weights - await asyncio.wait_for(validator.set_weights.wait(), 60) + + # wait for the Validator to process and set_weights with 3 attempts + max_retries = 3 + for attempt in range(max_retries): + try: + print(f"Attempt {attempt} to wait for set_weights...") + await asyncio.wait_for(validator.set_weights.wait(), timeout=60) + break + except asyncio.TimeoutError: + print(f"Attempt {attempt} failed: validator.set_weights timed out.") + if attempt == max_retries: + raise + await asyncio.sleep(1) + + # # wait for the Validator to process and set_weights + # await asyncio.wait_for(validator.set_weights.wait(), 60) # Wait till new epoch - # times=4 means let's wait at least 10 second to store weights in the chain (for fast block and powerful SubtensorCI GH runner) - await wait_interval(tempo, subtensor, netuid, times=4) + await wait_interval(tempo, subtensor, netuid) # Refresh metagraph metagraph = subtensor.metagraph(netuid) From a5d00aa1aaf8e770ba07d0f7550a98737a9fd1b8 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 14:18:57 -0700 Subject: [PATCH 006/150] add retry --- tests/e2e_tests/test_incentive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 048b75a702..079e838496 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -105,7 +105,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa for attempt in range(max_retries): try: print(f"Attempt {attempt} to wait for set_weights...") - await asyncio.wait_for(validator.set_weights.wait(), timeout=60) + await asyncio.wait_for(validator.set_weights.wait(), timeout=30) break except asyncio.TimeoutError: print(f"Attempt {attempt} failed: validator.set_weights timed out.") From e9c06479a61556b915bf7ea2b2033efaeda9d005 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 14:22:08 -0700 Subject: [PATCH 007/150] bring back 60 sec wait --- tests/e2e_tests/test_incentive.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 079e838496..a3662850e4 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -99,13 +99,12 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa async with templates.miner(bob_wallet, netuid): async with templates.validator(alice_wallet, netuid) as validator: - # wait for the Validator to process and set_weights with 3 attempts max_retries = 3 for attempt in range(max_retries): try: print(f"Attempt {attempt} to wait for set_weights...") - await asyncio.wait_for(validator.set_weights.wait(), timeout=30) + await asyncio.wait_for(validator.set_weights.wait(), timeout=60) break except asyncio.TimeoutError: print(f"Attempt {attempt} failed: validator.set_weights timed out.") From a832e21efc3e735c2197e8df6eed51fdff3f6e86 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 14:25:29 -0700 Subject: [PATCH 008/150] oops, wrong exception --- tests/e2e_tests/test_incentive.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index a3662850e4..44242725a7 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -104,9 +104,9 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa for attempt in range(max_retries): try: print(f"Attempt {attempt} to wait for set_weights...") - await asyncio.wait_for(validator.set_weights.wait(), timeout=60) + await asyncio.wait_for(validator.set_weights.wait(), timeout=30) break - except asyncio.TimeoutError: + except TimeoutError: print(f"Attempt {attempt} failed: validator.set_weights timed out.") if attempt == max_retries: raise From c819fd71c1f723d525efbfb5f1a9dd254d04ad1e Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 14:29:37 -0700 Subject: [PATCH 009/150] wait extra epoch to give the chain additional time to reveal weights --- tests/e2e_tests/test_incentive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 44242725a7..a642c53a96 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -116,7 +116,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa # await asyncio.wait_for(validator.set_weights.wait(), 60) # Wait till new epoch - await wait_interval(tempo, subtensor, netuid) + await wait_interval(tempo, subtensor, netuid, times=2) # Refresh metagraph metagraph = subtensor.metagraph(netuid) From 4ec302db66f6fe3496113d218ee6f677fab56778 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 14:34:03 -0700 Subject: [PATCH 010/150] extend except --- tests/e2e_tests/test_incentive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index a642c53a96..07a0e26a85 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -106,7 +106,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa print(f"Attempt {attempt} to wait for set_weights...") await asyncio.wait_for(validator.set_weights.wait(), timeout=30) break - except TimeoutError: + except (TimeoutError, asyncio.exceptions.TimeoutError): print(f"Attempt {attempt} failed: validator.set_weights timed out.") if attempt == max_retries: raise From 1d1dd5865fd5f73bf6adba4599798132c59e975c Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 15:11:01 -0700 Subject: [PATCH 011/150] remove commented code --- tests/e2e_tests/test_incentive.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 07a0e26a85..52ac8ca132 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -112,9 +112,6 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa raise await asyncio.sleep(1) - # # wait for the Validator to process and set_weights - # await asyncio.wait_for(validator.set_weights.wait(), 60) - # Wait till new epoch await wait_interval(tempo, subtensor, netuid, times=2) From 6196c4375ad19bc7c3593316613306be1f94dc7f Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 15:11:51 -0700 Subject: [PATCH 012/150] bring back all tests --- .github/workflows/e2e-subtensor-tests.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index ff131265f4..9daa330008 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -38,8 +38,7 @@ jobs: - name: Find test files id: get-tests run: | - # test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') - test_files=$(find tests/e2e_tests -name "test_incentive.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') echo "::set-output name=test-files::$test_files" shell: bash From bbe14dea2646d134b51a4a552524fdb925cb2e31 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 16:12:47 -0700 Subject: [PATCH 013/150] add retry logic to `use_and_wait_for_next_nonce` helper --- tests/e2e_tests/utils/chain_interactions.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index d571f7ff80..67d03c0a95 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -167,7 +167,17 @@ async def wait_for_new_nonce(): ): await asyncio.sleep(sleep) - await asyncio.wait_for(wait_for_new_nonce(), timeout) + # give the chain 3 tries to reveal a new nonce after latest extrinsic call + max_retries = 3 + for attempt in range(max_retries): + try: + await asyncio.wait_for(wait_for_new_nonce(), timeout) + break + except asyncio.TimeoutError: + logging.warning(f"Attempt {attempt + 1} of {max_retries} timed out.") + if attempt + 1 == max_retries: + raise + await asyncio.sleep(sleep) # Helper to execute sudo wrapped calls on the chain From 1b9b29d2e5917bc18376cec9723ab1e73182d71b Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 16:30:31 -0700 Subject: [PATCH 014/150] add TimeoutError --- tests/e2e_tests/utils/chain_interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index 67d03c0a95..5d7843294c 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -173,7 +173,7 @@ async def wait_for_new_nonce(): try: await asyncio.wait_for(wait_for_new_nonce(), timeout) break - except asyncio.TimeoutError: + except (asyncio.TimeoutError, TimeoutError): logging.warning(f"Attempt {attempt + 1} of {max_retries} timed out.") if attempt + 1 == max_retries: raise From 4451c65d2ae7a79ab8bd4fb248275dda71624d67 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 16:50:40 -0700 Subject: [PATCH 015/150] wait 2 epoch + 1 block to guaranty --- tests/e2e_tests/test_commit_weights.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index c4701ad71e..a3fb4ddaeb 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -268,7 +268,9 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True # Wait a few blocks - await asyncio.sleep(10) # Wait for the txs to be included in the chain + # await asyncio.sleep(10) # Wait for the txs to be included in the chain + subtensor.wait_for_block(subtensor.block + 20 + 1) + # Query the WeightCommits storage map for all three salts weight_commits = subtensor.query_module( From b531a4588f389ccef231d6ee26ad08d50b4bdc43 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 16:51:33 -0700 Subject: [PATCH 016/150] use self-hosted runner --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 9daa330008..c74c5fadfe 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -66,7 +66,7 @@ jobs: needs: - find-tests - pull-docker-image - runs-on: SubtensorCI + runs-on: ubuntu-latest timeout-minutes: 45 strategy: fail-fast: false # Allow other matrix jobs to run even if this job fails From 109518b608169d059c9ad604c1fda07efdef496e Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 17:06:47 -0700 Subject: [PATCH 017/150] ruff --- tests/e2e_tests/test_commit_weights.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index a3fb4ddaeb..9781e7cddd 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -267,11 +267,9 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - # Wait a few blocks - # await asyncio.sleep(10) # Wait for the txs to be included in the chain + # Wait 2 epoch + 1 block subtensor.wait_for_block(subtensor.block + 20 + 1) - # Query the WeightCommits storage map for all three salts weight_commits = subtensor.query_module( module="SubtensorModule", From 1acf4fd141dea5e6e32c01c737a2d1ffaab63944 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 17:33:19 -0700 Subject: [PATCH 018/150] sleep from 0.25 to 3.0 seconds for use_and_wait_for_next_nonce.the chain does not have time to update during 0.25 sec --- tests/e2e_tests/utils/chain_interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index 5d7843294c..bd61189a9a 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -150,7 +150,7 @@ async def wait_interval( async def use_and_wait_for_next_nonce( subtensor: "Subtensor", wallet: "Wallet", - sleep: float = 0.25, + sleep: float = 3.0, timeout: float = 15.0, ): """ From 56cfbc8e6cdacce021823c398de0a83b8a943fb2 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 18:02:10 -0700 Subject: [PATCH 019/150] add timeout --- tests/e2e_tests/utils/chain_interactions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index bd61189a9a..9001442303 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -151,7 +151,7 @@ async def use_and_wait_for_next_nonce( subtensor: "Subtensor", wallet: "Wallet", sleep: float = 3.0, - timeout: float = 15.0, + timeout: float = 60.0, ): """ ContextManager that makes sure the Nonce has been consumed after sending Extrinsic. @@ -174,7 +174,9 @@ async def wait_for_new_nonce(): await asyncio.wait_for(wait_for_new_nonce(), timeout) break except (asyncio.TimeoutError, TimeoutError): - logging.warning(f"Attempt {attempt + 1} of {max_retries} timed out.") + logging.warning( + f"Attempt {attempt + 1} of {max_retries} timed out for `wait_for_new_nonce`." + ) if attempt + 1 == max_retries: raise await asyncio.sleep(sleep) From ade2042030233306da08272a1ee406229b223139 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 18:06:29 -0700 Subject: [PATCH 020/150] wait 2 epoch before metagraph --- tests/e2e_tests/test_incentive.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 52ac8ca132..2f60325c12 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -118,6 +118,9 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa # Refresh metagraph metagraph = subtensor.metagraph(netuid) + # give network time before updating metagraph + await wait_epoch(subtensor, netuid, times=2) + # Get current emissions and validate that Alice has gotten tao alice_neuron = metagraph.neurons[0] From b39f9f6a85c3333738515fc92278ef8e39e6f369 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 18:07:14 -0700 Subject: [PATCH 021/150] reduce max-parallel --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index c74c5fadfe..87d364a8c4 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -70,7 +70,7 @@ jobs: timeout-minutes: 45 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 SubtensorCI runner) + max-parallel: 16 # Set the maximum number of parallel jobs (same as we have cores in SubtensorCI runner) matrix: os: - ubuntu-latest From fa6e60e417639e4a037f21c1e02dcf1eb9937802 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 18:39:22 -0700 Subject: [PATCH 022/150] separate steps --- tests/e2e_tests/test_set_weights.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 8211e62aa9..0697fb20dc 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -126,11 +126,13 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) for netuid in netuids: # Query the Weights storage map for all three subnets - weights = subtensor.query_module( + query = subtensor.query_module( module="SubtensorModule", name="Weights", params=[netuid, 0], # Alice should be the only UID - ).value + ) + + weights = query.value assert weights is not None, f"Weights not found for subnet {netuid}" assert weights == list( From d1e7a018ca2a89af092c62283a6dc0b2a7d782b0 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 18:40:08 -0700 Subject: [PATCH 023/150] set max-parallel=32 --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 87d364a8c4..c74c5fadfe 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -70,7 +70,7 @@ jobs: timeout-minutes: 45 strategy: fail-fast: false # Allow other matrix jobs to run even if this job fails - max-parallel: 16 # Set the maximum number of parallel jobs (same as we have cores in SubtensorCI runner) + max-parallel: 32 # Set the maximum number of parallel jobs (same as we have cores in SubtensorCI runner) matrix: os: - ubuntu-latest From 9d5a399df608e460f079eb9454d25beb1b6c7aaa Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 18:54:12 -0700 Subject: [PATCH 024/150] add wait 1 epoch (bc fast block is too fast) --- tests/e2e_tests/test_commit_weights.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 9781e7cddd..b2bbca948e 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -241,6 +241,9 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True + # Wait 1 epoch (bc fast block is too fast) + subtensor.wait_for_block(subtensor.block + 10) + async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( alice_wallet, @@ -254,6 +257,9 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True + # Wait 1 epoch (bc fast block is too fast) + subtensor.wait_for_block(subtensor.block + 10) + async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( alice_wallet, @@ -267,19 +273,22 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - # Wait 2 epoch + 1 block - subtensor.wait_for_block(subtensor.block + 20 + 1) + # Wait 1 epoch (bc fast block is too fast) + subtensor.wait_for_block(subtensor.block + 10) # Query the WeightCommits storage map for all three salts - weight_commits = subtensor.query_module( + query = subtensor.query_module( module="SubtensorModule", name="WeightCommits", params=[netuid, alice_wallet.hotkey.ss58_address], ) + + weight_commits = query.value + # Assert that the committed weights are set correctly - assert weight_commits.value is not None, "Weight commit not found in storage" - commit_hash, commit_block, reveal_block, expire_block = weight_commits.value[0] + assert weight_commits is not None, "Weight commit not found in storage" + commit_hash, commit_block, reveal_block, expire_block = weight_commits[0] assert commit_block > 0, f"Invalid block number: {commit_block}" # Check for three commits in the WeightCommits storage map - assert len(weight_commits.value) == 3, "Expected 3 weight commits" + assert len(weight_commits) == 3, "Expected 3 weight commits" From 95174166115f94714e4c9db07cc0184e465c38eb Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 20:19:42 -0700 Subject: [PATCH 025/150] test --- tests/e2e_tests/test_set_weights.py | 6 ++---- tests/e2e_tests/utils/chain_interactions.py | 16 ++-------------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 0697fb20dc..8211e62aa9 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -126,13 +126,11 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) for netuid in netuids: # Query the Weights storage map for all three subnets - query = subtensor.query_module( + weights = subtensor.query_module( module="SubtensorModule", name="Weights", params=[netuid, 0], # Alice should be the only UID - ) - - weights = query.value + ).value assert weights is not None, f"Weights not found for subnet {netuid}" assert weights == list( diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index 9001442303..23dae9d8a3 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -150,7 +150,7 @@ async def wait_interval( async def use_and_wait_for_next_nonce( subtensor: "Subtensor", wallet: "Wallet", - sleep: float = 3.0, + sleep: float = 3, timeout: float = 60.0, ): """ @@ -167,19 +167,7 @@ async def wait_for_new_nonce(): ): await asyncio.sleep(sleep) - # give the chain 3 tries to reveal a new nonce after latest extrinsic call - max_retries = 3 - for attempt in range(max_retries): - try: - await asyncio.wait_for(wait_for_new_nonce(), timeout) - break - except (asyncio.TimeoutError, TimeoutError): - logging.warning( - f"Attempt {attempt + 1} of {max_retries} timed out for `wait_for_new_nonce`." - ) - if attempt + 1 == max_retries: - raise - await asyncio.sleep(sleep) + await asyncio.wait_for(wait_for_new_nonce(), timeout) # Helper to execute sudo wrapped calls on the chain From 3419218c7ce89ac216da0e84f091d776775a00a4 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 21:05:30 -0700 Subject: [PATCH 026/150] increase epoch (10 * 0.25 is too fast), add waiting for 1 block after setting weights --- tests/e2e_tests/test_commit_weights.py | 25 ++++++++++++++++++------- tests/e2e_tests/test_set_weights.py | 18 ++++++++++++++++-- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index b2bbca948e..fb8f00c083 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -166,7 +166,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall AssertionError: If any of the checks or verifications fail """ # Wait for 2 tempos to pass as CR3 only reveals weights after 2 tempos - subtensor.wait_for_block(20) + subtensor.wait_for_block(21) netuid = 2 print("Testing test_commit_and_reveal_weights") @@ -203,6 +203,17 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall call_params={"netuid": netuid, "weights_set_rate_limit": "0"}, ) + # weights sensitive to epoch changes + assert sudo_set_admin_utils( + local_chain, + alice_wallet, + call_function="sudo_set_tempo", + call_params={ + "netuid": netuid, + "tempo": 100, + }, + ) + assert error is None assert status is True @@ -241,8 +252,8 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - # Wait 1 epoch (bc fast block is too fast) - subtensor.wait_for_block(subtensor.block + 10) + # Wait 1 block + subtensor.wait_for_block(subtensor.block + 1) async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( @@ -257,8 +268,8 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - # Wait 1 epoch (bc fast block is too fast) - subtensor.wait_for_block(subtensor.block + 10) + # Wait 1 block + subtensor.wait_for_block(subtensor.block + 1) async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( @@ -273,8 +284,8 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - # Wait 1 epoch (bc fast block is too fast) - subtensor.wait_for_block(subtensor.block + 10) + # Wait 1 block + subtensor.wait_for_block(subtensor.block + 1) # Query the WeightCommits storage map for all three salts query = subtensor.query_module( diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 8211e62aa9..6d671e2f46 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -26,6 +26,7 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) Raises: AssertionError: If any of the checks or verifications fail """ + netuids = [2, 3] print("Testing test_set_weights_uses_next_nonce") @@ -56,6 +57,19 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) for netuid in netuids: assert subtensor.subnet_exists(netuid), "Subnet wasn't created successfully" + # weights sensitive to epoch changes + assert sudo_set_admin_utils( + local_chain, + alice_wallet, + call_function="sudo_set_tempo", + call_params={ + "netuid": netuid, + "tempo": 50, + }, + ) + + await wait_epoch(subtensor, netuid=2, times=2) + # Stake to become to top neuron after the first epoch for netuid in netuids: subtensor.add_stake( @@ -121,8 +135,8 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) assert success is True, message - # Wait for the txs to be included in the chain - await wait_epoch(subtensor, netuid=netuids[-1], times=4) + # wait next block + subtensor.wait_for_block(subtensor.block + 1) for netuid in netuids: # Query the Weights storage map for all three subnets From 2052a4a5d9461e10ad01378baf029e6a13abd902 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 21:22:08 -0700 Subject: [PATCH 027/150] add wait after validator run --- tests/e2e_tests/utils/e2e_test_utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index e10cbfa6d8..007810b08c 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -167,6 +167,8 @@ async def __aenter__(self): await asyncio.wait_for(self.started.wait(), 30) + await asyncio.sleep(1) + return self async def __aexit__(self, exc_type, exc_value, traceback): From 32a5f4d134e49440e89d0a278b6829937e466a42 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 21:22:46 -0700 Subject: [PATCH 028/150] remove wait_interval --- tests/e2e_tests/test_incentive.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 2f60325c12..7920937b90 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -112,9 +112,6 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa raise await asyncio.sleep(1) - # Wait till new epoch - await wait_interval(tempo, subtensor, netuid, times=2) - # Refresh metagraph metagraph = subtensor.metagraph(netuid) From c87e97b5b28c503bb622ad89d28973edb02e9733 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 21:41:03 -0700 Subject: [PATCH 029/150] new --- tests/e2e_tests/test_incentive.py | 22 ++++++---------------- tests/e2e_tests/utils/e2e_test_utils.py | 2 -- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 7920937b90..eaa7e95cde 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -46,7 +46,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa ), "Alice & Bob not registered in the subnet" # Wait for the first epoch to pass - await wait_epoch(subtensor, netuid) + await wait_epoch(subtensor, netuid, times=2) # Get latest metagraph metagraph = subtensor.metagraph(netuid) @@ -99,25 +99,15 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa async with templates.miner(bob_wallet, netuid): async with templates.validator(alice_wallet, netuid) as validator: - # wait for the Validator to process and set_weights with 3 attempts - max_retries = 3 - for attempt in range(max_retries): - try: - print(f"Attempt {attempt} to wait for set_weights...") - await asyncio.wait_for(validator.set_weights.wait(), timeout=30) - break - except (TimeoutError, asyncio.exceptions.TimeoutError): - print(f"Attempt {attempt} failed: validator.set_weights timed out.") - if attempt == max_retries: - raise - await asyncio.sleep(1) + # wait for the Validator to process and set_weights + await asyncio.wait_for(validator.set_weights.wait(), 60) + + # Wait till new epoch + await wait_interval(tempo, subtensor, netuid) # Refresh metagraph metagraph = subtensor.metagraph(netuid) - # give network time before updating metagraph - await wait_epoch(subtensor, netuid, times=2) - # Get current emissions and validate that Alice has gotten tao alice_neuron = metagraph.neurons[0] diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index 007810b08c..e10cbfa6d8 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -167,8 +167,6 @@ async def __aenter__(self): await asyncio.wait_for(self.started.wait(), 30) - await asyncio.sleep(1) - return self async def __aexit__(self, exc_type, exc_value, traceback): From 54d311768f963d6da2042d7e2ef32ff14a32a4be Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 21:52:06 -0700 Subject: [PATCH 030/150] add waiting time for commit weights --- tests/e2e_tests/test_commit_weights.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index fb8f00c083..06b6181109 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -253,7 +253,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True # Wait 1 block - subtensor.wait_for_block(subtensor.block + 1) + subtensor.wait_for_block(subtensor.block + 8) # + 2 sec async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( @@ -269,7 +269,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True # Wait 1 block - subtensor.wait_for_block(subtensor.block + 1) + subtensor.wait_for_block(subtensor.block + 8) # + 2 sec async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( From ce165b7a715fc525ae3db08d14a9283b00c553b1 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 21:54:52 -0700 Subject: [PATCH 031/150] add waiting time for commit weights --- tests/e2e_tests/test_incentive.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index eaa7e95cde..910d338521 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -102,11 +102,14 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa # wait for the Validator to process and set_weights await asyncio.wait_for(validator.set_weights.wait(), 60) - # Wait till new epoch - await wait_interval(tempo, subtensor, netuid) + # Wait 2 seconds + subtensor.wait_for_block(subtensor.block + 8) - # Refresh metagraph - metagraph = subtensor.metagraph(netuid) + # Refresh metagraph + metagraph = subtensor.metagraph(netuid) + + # just for test + await asyncio.sleep(1) # Get current emissions and validate that Alice has gotten tao alice_neuron = metagraph.neurons[0] From 42dffa28f6e3f033523d897b57dd3d50afa8b82a Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 22:24:59 -0700 Subject: [PATCH 032/150] increase timout for validator.set_weights.wait() --- tests/e2e_tests/test_incentive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 910d338521..480c75f5f6 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -100,7 +100,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa async with templates.miner(bob_wallet, netuid): async with templates.validator(alice_wallet, netuid) as validator: # wait for the Validator to process and set_weights - await asyncio.wait_for(validator.set_weights.wait(), 60) + await asyncio.wait_for(validator.set_weights.wait(), 120) # Wait 2 seconds subtensor.wait_for_block(subtensor.block + 8) From 8640c52defd9999494a71e22ba4030a487a1ab65 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 22:34:32 -0700 Subject: [PATCH 033/150] set longer tempo --- tests/e2e_tests/test_incentive.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 480c75f5f6..ee530353d4 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -83,15 +83,25 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert status is True, error + # weights sensitive to epoch changes + assert sudo_set_admin_utils( + local_chain, + alice_wallet, + call_function="sudo_set_tempo", + call_params={ + "netuid": netuid, + "tempo": 100, + }, + ) + # update weights_set_rate_limit for fast-blocks - tempo = subtensor.tempo(netuid) status, error = sudo_set_admin_utils( local_chain, alice_wallet, call_function="sudo_set_weights_set_rate_limit", call_params={ "netuid": netuid, - "weights_set_rate_limit": tempo, + "weights_set_rate_limit": 0, }, ) From 0e54b85ef1106c3fa3e169bbdc5ebe2e29dab309 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 22:42:06 -0700 Subject: [PATCH 034/150] add debug --- tests/e2e_tests/utils/e2e_test_utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index e10cbfa6d8..e8e65f9245 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -181,6 +181,9 @@ async def _reader(self): self.started.set() elif b"Successfully set weights and Finalized." in line: self.set_weights.set() + bittensor.logging.console.info( + "Validator successfully set weights and Finalized." + ) def __init__(self): self.dir = clone_or_update_templates() From 01150b259b098fec6b2254af6dedec702f7b6d01 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 22:51:37 -0700 Subject: [PATCH 035/150] just flaky tests --- .github/workflows/e2e-subtensor-tests.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index c74c5fadfe..597bd22b50 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -38,7 +38,8 @@ jobs: - name: Find test files id: get-tests run: | - test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + # test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + 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(. != ""))') echo "::set-output name=test-files::$test_files" shell: bash From c5088a0daab6210bb1169237900a9a81a5133b49 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 23:02:43 -0700 Subject: [PATCH 036/150] use default tempo --- tests/e2e_tests/test_incentive.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index ee530353d4..2ab26c961d 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -83,17 +83,6 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert status is True, error - # weights sensitive to epoch changes - assert sudo_set_admin_utils( - local_chain, - alice_wallet, - call_function="sudo_set_tempo", - call_params={ - "netuid": netuid, - "tempo": 100, - }, - ) - # update weights_set_rate_limit for fast-blocks status, error = sudo_set_admin_utils( local_chain, From 32cb5c4b0ab11c6d22a7dc2241528e443f4978ba Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 23:03:07 -0700 Subject: [PATCH 037/150] use retry --- tests/e2e_tests/utils/chain_interactions.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index 23dae9d8a3..80139782b0 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -167,7 +167,17 @@ async def wait_for_new_nonce(): ): await asyncio.sleep(sleep) - await asyncio.wait_for(wait_for_new_nonce(), timeout) + # give the chain 3 tries to reveal a new nonce after latest extrinsic call + max_retries = 3 + for attempt in range(max_retries): + try: + await asyncio.wait_for(wait_for_new_nonce(), timeout) + break + except asyncio.TimeoutError: + logging.warning(f"Attempt {attempt + 1} of {max_retries} timed out.") + if attempt + 1 == max_retries: + raise + await asyncio.sleep(sleep) # Helper to execute sudo wrapped calls on the chain From 6b6034160acac4da23af3bbee89189cb71117235 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 23:04:45 -0700 Subject: [PATCH 038/150] add wait epoch --- tests/e2e_tests/test_incentive.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 2ab26c961d..17104a3a61 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -107,8 +107,8 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa # Refresh metagraph metagraph = subtensor.metagraph(netuid) - # just for test - await asyncio.sleep(1) + # give network time before updating metagraph + await wait_epoch(subtensor, netuid, times=2) # Get current emissions and validate that Alice has gotten tao alice_neuron = metagraph.neurons[0] From 3dc057d848bea984c1c4954f71d6711a51245c5d Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 23:10:19 -0700 Subject: [PATCH 039/150] test incentive as it is for debug --- tests/e2e_tests/test_incentive.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 17104a3a61..57ea9fb3d5 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -46,7 +46,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa ), "Alice & Bob not registered in the subnet" # Wait for the first epoch to pass - await wait_epoch(subtensor, netuid, times=2) + await wait_epoch(subtensor, netuid) # Get latest metagraph metagraph = subtensor.metagraph(netuid) @@ -84,31 +84,30 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert status is True, error # update weights_set_rate_limit for fast-blocks + tempo = subtensor.tempo(netuid) status, error = sudo_set_admin_utils( local_chain, alice_wallet, call_function="sudo_set_weights_set_rate_limit", call_params={ "netuid": netuid, - "weights_set_rate_limit": 0, + "weights_set_rate_limit": tempo, }, ) - assert error is None and status is True, "Failed to set weights_set_rate_limit" + assert error is None + assert status is True async with templates.miner(bob_wallet, netuid): async with templates.validator(alice_wallet, netuid) as validator: # wait for the Validator to process and set_weights await asyncio.wait_for(validator.set_weights.wait(), 120) - # Wait 2 seconds - subtensor.wait_for_block(subtensor.block + 8) + # Wait till new epoch + await wait_interval(tempo, subtensor, netuid) - # Refresh metagraph - metagraph = subtensor.metagraph(netuid) - - # give network time before updating metagraph - await wait_epoch(subtensor, netuid, times=2) + # Refresh metagraph + metagraph = subtensor.metagraph(netuid) # Get current emissions and validate that Alice has gotten tao alice_neuron = metagraph.neurons[0] From 1916204bece02b9448b705b8f6b8b9fc3de64d9f Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 23:18:05 -0700 Subject: [PATCH 040/150] subtensor.wait_for_block(DURATION_OF_START_CALL * 2) --- tests/e2e_tests/test_incentive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 57ea9fb3d5..a6ae2919bc 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -69,7 +69,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert bob_neuron.rank == 0 assert bob_neuron.trust == 0 - subtensor.wait_for_block(DURATION_OF_START_CALL) + subtensor.wait_for_block(DURATION_OF_START_CALL * 2) # Subnet "Start Call" https://github.com/opentensor/bits/pull/13 status, error = await root_set_subtensor_hyperparameter_values( From 991219eb5e7460fddc144fa386d3d677355d999f Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 23:32:17 -0700 Subject: [PATCH 041/150] try to set weights in the beginning of the epoch --- tests/e2e_tests/test_incentive.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index a6ae2919bc..09dabf377e 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -98,6 +98,12 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert error is None assert status is True + while True: + if 0 <= subtensor.block % subtensor.tempo(netuid) <= 1: + break + else: + await asyncio.sleep(0.25) + async with templates.miner(bob_wallet, netuid): async with templates.validator(alice_wallet, netuid) as validator: # wait for the Validator to process and set_weights From 0a52e439e63fde66f0a8b047567fe8caa8e5a0da Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 23:49:37 -0700 Subject: [PATCH 042/150] add wait_for_block --- tests/e2e_tests/test_commit_weights.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 06b6181109..e09566fa7e 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -285,7 +285,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True # Wait 1 block - subtensor.wait_for_block(subtensor.block + 1) + subtensor.wait_for_block(subtensor.block + 8) # Query the WeightCommits storage map for all three salts query = subtensor.query_module( From 089f30bea89731762c2957e5ed513b66c23957e8 Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 23:50:55 -0700 Subject: [PATCH 043/150] add debug --- tests/e2e_tests/test_set_weights.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 6d671e2f46..d782651d88 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -9,6 +9,7 @@ use_and_wait_for_next_nonce, wait_epoch, ) +from bittensor.utils.btlogging import logging @pytest.mark.asyncio @@ -134,17 +135,18 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) ) assert success is True, message - - # wait next block - subtensor.wait_for_block(subtensor.block + 1) + logging.console.success(f"Set weights for subnet {netuid}") for netuid in netuids: # Query the Weights storage map for all three subnets - weights = subtensor.query_module( + query = subtensor.query_module( module="SubtensorModule", name="Weights", params=[netuid, 0], # Alice should be the only UID - ).value + ) + + weights = query.value + logging.console.info(f"Weights for subnet {netuid}: {weights}") assert weights is not None, f"Weights not found for subnet {netuid}" assert weights == list( From 679f7ab81ecef41640ec0c996d1ad826f470eb9d Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 23:51:49 -0700 Subject: [PATCH 044/150] increase sleep in case of waiting nonce --- tests/e2e_tests/utils/chain_interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index 80139782b0..95e7285cbc 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -150,7 +150,7 @@ async def wait_interval( async def use_and_wait_for_next_nonce( subtensor: "Subtensor", wallet: "Wallet", - sleep: float = 3, + sleep: float = 25, timeout: float = 60.0, ): """ From ddb9f6b547852f03e90a7f4e13112e93e87d91db Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 23:58:04 -0700 Subject: [PATCH 045/150] remove wait --- tests/e2e_tests/test_commit_weights.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index e09566fa7e..90d420fbaf 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -252,9 +252,6 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - # Wait 1 block - subtensor.wait_for_block(subtensor.block + 8) # + 2 sec - async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( alice_wallet, @@ -268,9 +265,6 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - # Wait 1 block - subtensor.wait_for_block(subtensor.block + 8) # + 2 sec - async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( alice_wallet, @@ -284,9 +278,6 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - # Wait 1 block - subtensor.wait_for_block(subtensor.block + 8) - # Query the WeightCommits storage map for all three salts query = subtensor.query_module( module="SubtensorModule", From b6628c1058e36c0c5613c6a9a5ddf88c4c8182fe Mon Sep 17 00:00:00 2001 From: Roman Date: Mon, 7 Apr 2025 23:58:43 -0700 Subject: [PATCH 046/150] sleep 0.25 --- tests/e2e_tests/utils/chain_interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index 95e7285cbc..d6b816045e 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -150,7 +150,7 @@ async def wait_interval( async def use_and_wait_for_next_nonce( subtensor: "Subtensor", wallet: "Wallet", - sleep: float = 25, + sleep: float = 0.25, timeout: float = 60.0, ): """ From 14ebd6e9af033ce8466e066175e562690befb227 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 00:02:32 -0700 Subject: [PATCH 047/150] sleep 3 --- tests/e2e_tests/utils/chain_interactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index d6b816045e..80139782b0 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -150,7 +150,7 @@ async def wait_interval( async def use_and_wait_for_next_nonce( subtensor: "Subtensor", wallet: "Wallet", - sleep: float = 0.25, + sleep: float = 3, timeout: float = 60.0, ): """ From ec5aec14b8e634528bae558e9203fb48ecc12715 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 00:08:31 -0700 Subject: [PATCH 048/150] try to fix commit weights --- tests/e2e_tests/test_commit_weights.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 90d420fbaf..8580867948 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -252,6 +252,8 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True + await asyncio.sleep(1) + async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( alice_wallet, @@ -265,6 +267,8 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True + await asyncio.sleep(1) + async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( alice_wallet, @@ -278,6 +282,8 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True + await asyncio.sleep(1) + # Query the WeightCommits storage map for all three salts query = subtensor.query_module( module="SubtensorModule", From ccb8f9bd2c89badfffa4ce74340cc17672be199d Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 00:16:17 -0700 Subject: [PATCH 049/150] try to fix set weights --- tests/e2e_tests/test_set_weights.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index d782651d88..0aa8f4de4f 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -137,6 +137,8 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) assert success is True, message logging.console.success(f"Set weights for subnet {netuid}") + subtensor.wait_for_block(subtensor.block + 1) + for netuid in netuids: # Query the Weights storage map for all three subnets query = subtensor.query_module( From b178f2e1c6c32b1ea0c4037ece896ac8e9ee94b7 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 00:27:12 -0700 Subject: [PATCH 050/150] try to fix test_commit (increase final wait) --- tests/e2e_tests/test_commit_weights.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 8580867948..e6af570bd8 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -282,7 +282,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - await asyncio.sleep(1) + await asyncio.sleep(2) # Query the WeightCommits storage map for all three salts query = subtensor.query_module( From 7e73e85d568a6511d25c5d29c030c167b5150daa Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 00:31:06 -0700 Subject: [PATCH 051/150] increase Validator wait_for timeout --- tests/e2e_tests/utils/e2e_test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index e8e65f9245..4cab7b9ab3 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -165,7 +165,7 @@ async def __aenter__(self): self.__reader_task = asyncio.create_task(self._reader()) - await asyncio.wait_for(self.started.wait(), 30) + await asyncio.wait_for(self.started.wait(), 120) return self From e63253f2e255b74d7bf5e9baf202bfa4fd022656 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 00:36:15 -0700 Subject: [PATCH 052/150] oops --- tests/e2e_tests/test_commit_weights.py | 2 +- tests/e2e_tests/utils/e2e_test_utils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index e6af570bd8..8580867948 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -282,7 +282,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - await asyncio.sleep(2) + await asyncio.sleep(1) # Query the WeightCommits storage map for all three salts query = subtensor.query_module( diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index 4cab7b9ab3..8548db6c70 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -165,7 +165,7 @@ async def __aenter__(self): self.__reader_task = asyncio.create_task(self._reader()) - await asyncio.wait_for(self.started.wait(), 120) + await asyncio.wait_for(self.started.wait(), 60) return self From 81cf799e4e832d2827ba092c4281fe424e1d43d5 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 00:43:24 -0700 Subject: [PATCH 053/150] incentive --- tests/e2e_tests/test_incentive.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 09dabf377e..57ea9fb3d5 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -69,7 +69,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert bob_neuron.rank == 0 assert bob_neuron.trust == 0 - subtensor.wait_for_block(DURATION_OF_START_CALL * 2) + subtensor.wait_for_block(DURATION_OF_START_CALL) # Subnet "Start Call" https://github.com/opentensor/bits/pull/13 status, error = await root_set_subtensor_hyperparameter_values( @@ -98,12 +98,6 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert error is None assert status is True - while True: - if 0 <= subtensor.block % subtensor.tempo(netuid) <= 1: - break - else: - await asyncio.sleep(0.25) - async with templates.miner(bob_wallet, netuid): async with templates.validator(alice_wallet, netuid) as validator: # wait for the Validator to process and set_weights From 2277cfd3b53f22a4dec7e7a15dc8607453d3addc Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 01:41:38 -0700 Subject: [PATCH 054/150] remove unnecessary netuid from `next_tempo` (bug if subnet number is greater than tempo) + fix_test_commit_reveal_v3 --- tests/e2e_tests/test_commit_reveal_v3.py | 6 +++--- tests/e2e_tests/utils/chain_interactions.py | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/e2e_tests/test_commit_reveal_v3.py b/tests/e2e_tests/test_commit_reveal_v3.py index 6d45cbd94d..71dde62f79 100644 --- a/tests/e2e_tests/test_commit_reveal_v3.py +++ b/tests/e2e_tests/test_commit_reveal_v3.py @@ -96,7 +96,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle # Fetch current block and calculate next tempo for the subnet current_block = subtensor.get_current_block() - upcoming_tempo = next_tempo(current_block, tempo, netuid) + upcoming_tempo = next_tempo(current_block, tempo) logging.console.info( f"Checking if window is too low with Current block: {current_block}, next tempo: {upcoming_tempo}" ) @@ -114,7 +114,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle ) current_block = subtensor.get_current_block() latest_drand_round = subtensor.last_drand_round() - upcoming_tempo = next_tempo(current_block, tempo, netuid) + 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}" ) @@ -142,7 +142,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle current_block = subtensor.get_current_block() latest_drand_round = subtensor.last_drand_round() - upcoming_tempo = next_tempo(current_block, tempo, netuid) + upcoming_tempo = next_tempo(current_block, tempo) logging.console.info( f"After setting weights: Current block: {current_block}, next tempo: {upcoming_tempo}, drand: {latest_drand_round}" ) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index 80139782b0..e90c38cfdf 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -93,19 +93,18 @@ async def wait_epoch(subtensor: "Subtensor", netuid: int = 1, **kwargs): await wait_interval(tempo, subtensor, netuid, **kwargs) -def next_tempo(current_block: int, tempo: int, netuid: int) -> int: +def next_tempo(current_block: int, tempo: int) -> int: """ Calculates the next tempo block for a specific subnet. Args: current_block (int): The current block number. tempo (int): The tempo value for the subnet. - netuid (int): The unique identifier of the subnet. Returns: int: The next tempo block number. """ - return (((current_block + netuid) // tempo) + 1) * tempo + 1 + return ((current_block // tempo) + 1) * tempo + 1 async def wait_interval( @@ -127,7 +126,7 @@ async def wait_interval( next_tempo_block_start = current_block for _ in range(times): - next_tempo_block_start = next_tempo(next_tempo_block_start, tempo, netuid) + next_tempo_block_start = next_tempo(next_tempo_block_start, tempo) last_reported = None From 2102639d30fc591e5a850ede8920c3a056f19e77 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 01:42:47 -0700 Subject: [PATCH 055/150] fixed `test_incentive.py` (subtensor issue) --- tests/e2e_tests/test_incentive.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 57ea9fb3d5..e4093be60e 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -2,6 +2,7 @@ import pytest +from bittensor.utils.btlogging import logging from tests.e2e_tests.utils.chain_interactions import ( root_set_subtensor_hyperparameter_values, sudo_set_admin_utils, @@ -101,13 +102,21 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa async with templates.miner(bob_wallet, netuid): async with templates.validator(alice_wallet, netuid) as validator: # wait for the Validator to process and set_weights - await asyncio.wait_for(validator.set_weights.wait(), 120) + await asyncio.wait_for(validator.set_weights.wait(), 60) # Wait till new epoch await wait_interval(tempo, subtensor, netuid) - # Refresh metagraph - metagraph = subtensor.metagraph(netuid) + # Sometimes the network does not have time to release data, and it requires several additional blocks (subtensor issue) + # Call get_metagraph_info since if faster and chipper + while subtensor.get_metagraph_info(netuid).incentives[0] == 0: + logging.console.info( + f"Additional fast block to wait chain data updated: {subtensor.block}" + ) + await asyncio.sleep(0.25) + + # Refresh metagraph + metagraph = subtensor.metagraph(netuid) # Get current emissions and validate that Alice has gotten tao alice_neuron = metagraph.neurons[0] From c8b0415ec2ee416df4e8c492c05d7ac7d6809f51 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 01:57:10 -0700 Subject: [PATCH 056/150] fix `Using CPython 3.13.2 interpreter error: Failed to fetch: `https://pypi.org/simple/py-bip39-bindings/`` --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 597bd22b50..a1dc5707b7 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -76,7 +76,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - name: Check-out repository uses: actions/checkout@v4 From d19bc8aa589efa35adf1a4bcfa422d9b1fd096ed Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 02:05:32 -0700 Subject: [PATCH 057/150] debug for `use_and_wait_for_next_nonce` + sleep: float = 0.25 --- tests/e2e_tests/utils/chain_interactions.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index e90c38cfdf..036000ac8b 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -149,7 +149,7 @@ async def wait_interval( async def use_and_wait_for_next_nonce( subtensor: "Subtensor", wallet: "Wallet", - sleep: float = 3, + sleep: float = 0.25, timeout: float = 60.0, ): """ @@ -164,6 +164,9 @@ async def wait_for_new_nonce(): while nonce == subtensor.substrate.get_account_next_index( wallet.hotkey.ss58_address ): + logging.console.info( + f"Waiting for new nonce. Current nonce: {nonce} for wallet {wallet.hotkey.ss58_address}" + ) await asyncio.sleep(sleep) # give the chain 3 tries to reveal a new nonce after latest extrinsic call From e839e5464955b9ec7985cc485339c360691d6e4e Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 02:11:32 -0700 Subject: [PATCH 058/150] debug to `e2e_test_utils.py` --- tests/e2e_tests/utils/e2e_test_utils.py | 28 ++++++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index 8548db6c70..d4f422c26b 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -93,6 +93,8 @@ def __init__(self, dir, wallet, netuid): self.started = asyncio.Event() async def __aenter__(self): + env = os.environ.copy() + env["BT_LOGGING_INFO"] = "1" self.process = await asyncio.create_subprocess_exec( sys.executable, f"{self.dir}/miner.py", @@ -108,15 +110,19 @@ async def __aenter__(self): self.wallet.name, "--wallet.hotkey", "default", - env={ - "BT_LOGGING_INFO": "1", - }, + env=env, stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) self.__reader_task = asyncio.create_task(self._reader()) - await asyncio.wait_for(self.started.wait(), 30) + try: + await asyncio.wait_for(self.started.wait(), 30) + except asyncio.TimeoutError: + self.process.kill() + await self.process.wait() + raise RuntimeError("Miner failed to start within timeout") return self @@ -142,6 +148,8 @@ def __init__(self, dir, wallet, netuid): self.set_weights = asyncio.Event() async def __aenter__(self): + env = os.environ.copy() + env["BT_LOGGING_INFO"] = "1" self.process = await asyncio.create_subprocess_exec( sys.executable, f"{self.dir}/validator.py", @@ -157,15 +165,19 @@ async def __aenter__(self): self.wallet.name, "--wallet.hotkey", "default", - env={ - "BT_LOGGING_INFO": "1", - }, + env=env, stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, ) self.__reader_task = asyncio.create_task(self._reader()) - await asyncio.wait_for(self.started.wait(), 60) + try: + await asyncio.wait_for(self.started.wait(), 30) + except asyncio.TimeoutError: + self.process.kill() + await self.process.wait() + raise RuntimeError("Validator failed to start within timeout") return self From 8a84cb528074c6a9f37ae35d374a9000ec36d48e Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 02:18:09 -0700 Subject: [PATCH 059/150] increase timeout to avoid `asyncio.exceptions.TimeoutError` --- tests/e2e_tests/test_incentive.py | 2 +- tests/e2e_tests/utils/e2e_test_utils.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index e4093be60e..fef0338aa9 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -102,7 +102,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa async with templates.miner(bob_wallet, netuid): async with templates.validator(alice_wallet, netuid) as validator: # wait for the Validator to process and set_weights - await asyncio.wait_for(validator.set_weights.wait(), 60) + await asyncio.wait_for(validator.set_weights.wait(), 120) # Wait till new epoch await wait_interval(tempo, subtensor, netuid) diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index d4f422c26b..3b6018f327 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -118,7 +118,7 @@ async def __aenter__(self): self.__reader_task = asyncio.create_task(self._reader()) try: - await asyncio.wait_for(self.started.wait(), 30) + await asyncio.wait_for(self.started.wait(), 60) except asyncio.TimeoutError: self.process.kill() await self.process.wait() @@ -173,7 +173,7 @@ async def __aenter__(self): self.__reader_task = asyncio.create_task(self._reader()) try: - await asyncio.wait_for(self.started.wait(), 30) + await asyncio.wait_for(self.started.wait(), 60) except asyncio.TimeoutError: self.process.kill() await self.process.wait() From b979e9c5364e5e5ab908def176635e54c11ef231 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 02:19:50 -0700 Subject: [PATCH 060/150] increase timeout to avoid `asyncio.exceptions.TimeoutError` --- tests/e2e_tests/test_incentive.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index fef0338aa9..079bdbcc43 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -99,13 +99,14 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert error is None assert status is True - async with templates.miner(bob_wallet, netuid): - async with templates.validator(alice_wallet, netuid) as validator: - # wait for the Validator to process and set_weights - await asyncio.wait_for(validator.set_weights.wait(), 120) - - # Wait till new epoch - await wait_interval(tempo, subtensor, netuid) + async with templates.miner(bob_wallet, netuid), templates.validator( + alice_wallet, netuid + ) as validator: + # wait for the Validator to process and set_weights + await asyncio.wait_for(validator.set_weights.wait(), 120) + + # Wait till new epoch + await wait_interval(tempo, subtensor, netuid) # Sometimes the network does not have time to release data, and it requires several additional blocks (subtensor issue) # Call get_metagraph_info since if faster and chipper From c46b96d794e5e34c1b444412370fb16685c0579a Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 02:22:22 -0700 Subject: [PATCH 061/150] pypi was on maintenance --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index a1dc5707b7..597bd22b50 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -76,7 +76,7 @@ jobs: os: - ubuntu-latest test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - name: Check-out repository uses: actions/checkout@v4 From 5081de1d9ef2febf8b5398dae9b5f667dca2c6dd Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 02:22:30 -0700 Subject: [PATCH 062/150] review fix --- tests/e2e_tests/test_commit_weights.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 8580867948..ece3195b25 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -203,6 +203,9 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall call_params={"netuid": netuid, "weights_set_rate_limit": "0"}, ) + assert error is None + assert status is True + # weights sensitive to epoch changes assert sudo_set_admin_utils( local_chain, @@ -214,9 +217,6 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall }, ) - assert error is None - assert status is True - assert ( subtensor.get_subnet_hyperparameters(netuid=netuid).weights_rate_limit == 0 ), "Failed to set weights_rate_limit" From c30d86e4b06c8a985122b11d2d88b36a907ddedd Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 02:38:41 -0700 Subject: [PATCH 063/150] add debug fix for `test_commit_weights_uses_next_nonce` --- tests/e2e_tests/test_commit_weights.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index ece3195b25..79993d434d 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -3,6 +3,7 @@ import numpy as np import pytest +from bittensor.utils.btlogging import logging from bittensor.utils.weight_utils import convert_weights_and_uids_for_emit from tests.e2e_tests.utils.chain_interactions import ( sudo_set_admin_utils, @@ -284,6 +285,14 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall await asyncio.sleep(1) + # Sometimes the network does not have time to release data, and it requires several additional blocks (subtensor issue) + # Call get_metagraph_info since if faster and chipper + while not subtensor.weights(netuid=netuid): + logging.console.info( + f"Additional fast block to wait chain data updated: {subtensor.block}" + ) + await asyncio.sleep(0.25) + # Query the WeightCommits storage map for all three salts query = subtensor.query_module( module="SubtensorModule", From 0af421dc4604b123d052f0e3829bf3b08615b64a Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 02:46:00 -0700 Subject: [PATCH 064/150] add debug fix for `test_commit_weights_uses_next_nonce` --- tests/e2e_tests/test_commit_weights.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 79993d434d..c2a05f77b1 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -287,7 +287,16 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall # Sometimes the network does not have time to release data, and it requires several additional blocks (subtensor issue) # Call get_metagraph_info since if faster and chipper - while not subtensor.weights(netuid=netuid): + while ( + len( + subtensor.query_module( + module="SubtensorModule", + name="WeightCommits", + params=[netuid, alice_wallet.hotkey.ss58_address], + ).value + ) + < 3 + ): logging.console.info( f"Additional fast block to wait chain data updated: {subtensor.block}" ) From ba2696fa64b7a9f34f7678a14accd8f4c6033b0a Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 03:00:56 -0700 Subject: [PATCH 065/150] all tests back --- .github/workflows/e2e-subtensor-tests.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 597bd22b50..fe9fcaacaf 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -38,8 +38,9 @@ jobs: - name: Find test files id: get-tests run: | - # test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') - 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 -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(. != ""))') echo "::set-output name=test-files::$test_files" shell: bash From f130879677b2d4fb9d3b4c6a36e17e45b4de0fe0 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 11:58:20 -0700 Subject: [PATCH 066/150] limited tests --- .github/workflows/e2e-subtensor-tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index fe9fcaacaf..955aaaab4e 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -38,9 +38,9 @@ jobs: - name: Find test files id: get-tests run: | - test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + # 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_(incentive|commit_weights|set_weights)\.py$' | jq -R -s -c 'split("\n") | map(select(. != ""))') echo "::set-output name=test-files::$test_files" shell: bash From 59074b13c0e3118a3f66b2cb5442ed999a83bc52 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 12:21:57 -0700 Subject: [PATCH 067/150] logging, waiting, limited tests --- tests/e2e_tests/test_incentive.py | 29 +++++++++++++++++++------ tests/e2e_tests/utils/e2e_test_utils.py | 2 ++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 079bdbcc43..26f631a66d 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -36,6 +36,17 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa # Verify subnet created successfully assert subtensor.subnet_exists(netuid), "Subnet wasn't created successfully" + # weights sensitive to epoch changes + assert sudo_set_admin_utils( + local_chain, + alice_wallet, + call_function="sudo_set_tempo", + call_params={ + "netuid": netuid, + "tempo": 100, + }, + ) + # Register Bob as a neuron on the subnet assert subtensor.burned_register( bob_wallet, netuid @@ -99,14 +110,18 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert error is None assert status is True - async with templates.miner(bob_wallet, netuid), templates.validator( - alice_wallet, netuid - ) as validator: - # wait for the Validator to process and set_weights - await asyncio.wait_for(validator.set_weights.wait(), 120) + async with templates.miner(bob_wallet, netuid): + + subtensor.wait_for_block(subtensor.block + 4) + + async with templates.validator(alice_wallet, netuid) as validator: + + subtensor.wait_for_block(subtensor.block + 4) - # Wait till new epoch - await wait_interval(tempo, subtensor, netuid) + # wait for the Validator to process and set_weights + logging.console.info(f"Waiting for validator to set weights: {validator}") + await asyncio.wait_for(validator.set_weights.wait(), 120) + logging.console.info(f"Validator got weights: {validator}") # Sometimes the network does not have time to release data, and it requires several additional blocks (subtensor issue) # Call get_metagraph_info since if faster and chipper diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index 3b6018f327..91c6a1d508 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -190,8 +190,10 @@ async def __aexit__(self, exc_type, exc_value, traceback): async def _reader(self): async for line in self.process.stdout: if b"Starting validator loop." in line: + bittensor.logging.console.info("Validator started.") self.started.set() elif b"Successfully set weights and Finalized." in line: + bittensor.logging.console.info("Validator is setting weights.") self.set_weights.set() bittensor.logging.console.info( "Validator successfully set weights and Finalized." From 98de61476e3484ad1914438248513e19de4d968d Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 13:15:55 -0700 Subject: [PATCH 068/150] ruff --- tests/e2e_tests/test_incentive.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 26f631a66d..01bf3ab20c 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -111,11 +111,9 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert status is True async with templates.miner(bob_wallet, netuid): - subtensor.wait_for_block(subtensor.block + 4) async with templates.validator(alice_wallet, netuid) as validator: - subtensor.wait_for_block(subtensor.block + 4) # wait for the Validator to process and set_weights From 31ca484151fc7b086c95c258e8703cccddcc3627 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 14:27:08 -0700 Subject: [PATCH 069/150] > --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ceed41972a..3ea1679a96 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools~=70.0.0", "wheel"] +requires = ["setuptools>=70.0.0", "wheel"] build-backend = "setuptools.build_meta" [project] From 914b53c2831aa930bf5d1429d0353ad320b0be4f Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 14:36:47 -0700 Subject: [PATCH 070/150] all tests --- .github/workflows/e2e-subtensor-tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 955aaaab4e..fe9fcaacaf 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -38,9 +38,9 @@ jobs: - name: Find test files id: get-tests run: | - # test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + 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_(incentive|commit_weights|set_weights)\.py$' | jq -R -s -c 'split("\n") | map(select(. != ""))') echo "::set-output name=test-files::$test_files" shell: bash From dd3b3b7427c3d5159f7af778e37e828354a42dd5 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 14:54:23 -0700 Subject: [PATCH 071/150] try use SubtensorCI runner --- .github/workflows/e2e-subtensor-tests.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index fe9fcaacaf..3d843929d6 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -27,7 +27,7 @@ env: jobs: find-tests: - runs-on: ubuntu-latest + runs-on: SubtensorCI if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} outputs: test-files: ${{ steps.get-tests.outputs.test-files }} @@ -45,7 +45,7 @@ jobs: shell: bash pull-docker-image: - runs-on: ubuntu-latest + runs-on: SubtensorCI steps: - name: Log in to GitHub Container Registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin @@ -68,7 +68,7 @@ jobs: needs: - find-tests - pull-docker-image - runs-on: ubuntu-latest + runs-on: SubtensorCI timeout-minutes: 45 strategy: fail-fast: false # Allow other matrix jobs to run even if this job fails From 3dcc5700109f1ef9db581eafc32e08cf02ef241e Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 15:06:45 -0700 Subject: [PATCH 072/150] add tricky waiter to `test_set_weights.py` --- tests/e2e_tests/test_set_weights.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 0aa8f4de4f..7611c4d5ba 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -139,6 +139,16 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) subtensor.wait_for_block(subtensor.block + 1) + while not subtensor.query_module( + module="SubtensorModule", + name="Weights", + params=[netuids[-1], 0], # Alice should be the only UID + ): + logging.console.info( + f"Additional fast block to wait chain data updated: {subtensor.block}" + ) + subtensor.wait_for_block(subtensor.block + 1) + for netuid in netuids: # Query the Weights storage map for all three subnets query = subtensor.query_module( From a39f5024b9d41c6569348a333908879c2053d2ad Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 15:16:13 -0700 Subject: [PATCH 073/150] add 2 tricky waiter to `test_set_weights.py` --- tests/e2e_tests/test_set_weights.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 7611c4d5ba..d9e35a5767 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -142,7 +142,11 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) while not subtensor.query_module( module="SubtensorModule", name="Weights", - params=[netuids[-1], 0], # Alice should be the only UID + params=[2, 0], # Alice should be the only UID + ) or not subtensor.query_module( + module="SubtensorModule", + name="Weights", + params=[3, 0], ): logging.console.info( f"Additional fast block to wait chain data updated: {subtensor.block}" From 16dc7ef74d77a40e2696b110c138c2eec198b11a Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 15:46:36 -0700 Subject: [PATCH 074/150] add 120 second to waiters --- tests/e2e_tests/test_set_weights.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index d9e35a5767..f82a382a9e 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -1,7 +1,10 @@ +import time + import numpy as np import pytest from bittensor.utils.balance import Balance +from bittensor.utils.btlogging import logging from bittensor.utils.weight_utils import convert_weights_and_uids_for_emit from tests.e2e_tests.utils.chain_interactions import ( sudo_set_hyperparameter_bool, @@ -9,7 +12,6 @@ use_and_wait_for_next_nonce, wait_epoch, ) -from bittensor.utils.btlogging import logging @pytest.mark.asyncio @@ -135,19 +137,22 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) ) assert success is True, message + subtensor.wait_for_block(subtensor.block + 1) logging.console.success(f"Set weights for subnet {netuid}") - subtensor.wait_for_block(subtensor.block + 1) - + extra_time = time.time() while not subtensor.query_module( module="SubtensorModule", name="Weights", - params=[2, 0], # Alice should be the only UID + params=[2, 0], ) or not subtensor.query_module( module="SubtensorModule", name="Weights", params=[3, 0], ): + if time.time() - extra_time > 120: + raise TimeoutError("Timed out waiting for chain data to update") + logging.console.info( f"Additional fast block to wait chain data updated: {subtensor.block}" ) From a5b18e582df1981b660f41649b4a7bd610965836 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 15:56:13 -0700 Subject: [PATCH 075/150] bring back `ubuntu-latest` --- .github/workflows/e2e-subtensor-tests.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 3d843929d6..1f7d2a3598 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -27,7 +27,7 @@ env: jobs: find-tests: - runs-on: SubtensorCI + runs-on: ubuntu-latest if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} outputs: test-files: ${{ steps.get-tests.outputs.test-files }} @@ -45,7 +45,7 @@ jobs: shell: bash pull-docker-image: - runs-on: SubtensorCI + runs-on: ubuntu-latest steps: - name: Log in to GitHub Container Registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin @@ -68,11 +68,11 @@ jobs: needs: - find-tests - pull-docker-image - runs-on: SubtensorCI + runs-on: ubuntu-latest timeout-minutes: 45 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 SubtensorCI runner) + max-parallel: 32 # Set the maximum number of parallel jobs (same as we have cores in ubuntu-latest runner) matrix: os: - ubuntu-latest From b053d9846a46af6501c303fb1f70492a8ea23fca Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 16:05:00 -0700 Subject: [PATCH 076/150] skip flaky test --- tests/e2e_tests/test_commit_weights.py | 11 ++++++++++- tests/e2e_tests/test_incentive.py | 8 +++++++- tests/e2e_tests/test_set_weights.py | 4 +++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index c2a05f77b1..37edd981a0 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -1,4 +1,5 @@ import asyncio +import time import numpy as np import pytest @@ -13,6 +14,7 @@ ) +@pytest.mark.skipif @pytest.mark.asyncio async def test_commit_and_reveal_weights_legacy(local_chain, subtensor, alice_wallet): """ @@ -247,7 +249,8 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall salt=salt, uids=weight_uids, weights=weight_vals, - wait_for_inclusion=False, # Don't wait for inclusion, we are testing the nonce when there is a tx in the pool + wait_for_inclusion=False, + # Don't wait for inclusion, we are testing the nonce when there is a tx in the pool wait_for_finalization=False, ) @@ -287,6 +290,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall # Sometimes the network does not have time to release data, and it requires several additional blocks (subtensor issue) # Call get_metagraph_info since if faster and chipper + extra_time = time.time() while ( len( subtensor.query_module( @@ -297,6 +301,11 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall ) < 3 ): + if time.time() - extra_time > 120: + pytest.skip( + "Skipping due to FLAKY TEST. Check the same tests with another Python version or run again." + ) + logging.console.info( f"Additional fast block to wait chain data updated: {subtensor.block}" ) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 01bf3ab20c..0fefe220c1 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -1,5 +1,5 @@ import asyncio - +import time import pytest from bittensor.utils.btlogging import logging @@ -123,10 +123,16 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa # Sometimes the network does not have time to release data, and it requires several additional blocks (subtensor issue) # Call get_metagraph_info since if faster and chipper + extra_time = time.time() while subtensor.get_metagraph_info(netuid).incentives[0] == 0: logging.console.info( f"Additional fast block to wait chain data updated: {subtensor.block}" ) + if time.time() - extra_time > 120: + pytest.skip( + "Skipping due to FLAKY TEST. Check the same tests with another Python version or run again." + ) + await asyncio.sleep(0.25) # Refresh metagraph diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index f82a382a9e..0bb1734c3f 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -151,7 +151,9 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) params=[3, 0], ): if time.time() - extra_time > 120: - raise TimeoutError("Timed out waiting for chain data to update") + pytest.skip( + "Skipping due to FLAKY TEST. Check the same tests with another Python version or run again." + ) logging.console.info( f"Additional fast block to wait chain data updated: {subtensor.block}" From aee1c53bf10df5efd03989f309432a9b13e03762 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 17:04:02 -0700 Subject: [PATCH 077/150] oops --- tests/e2e_tests/test_commit_weights.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 37edd981a0..cb23b640f4 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -14,7 +14,6 @@ ) -@pytest.mark.skipif @pytest.mark.asyncio async def test_commit_and_reveal_weights_legacy(local_chain, subtensor, alice_wallet): """ From d1266f06630685d869909f9972fa1497a4852e5e Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 17:04:20 -0700 Subject: [PATCH 078/150] epoch 3 come --- tests/e2e_tests/test_set_weights.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 0bb1734c3f..6997e47a9f 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -72,6 +72,7 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) ) await wait_epoch(subtensor, netuid=2, times=2) + subtensor.wait_for_block(subtensor.block + 1) # Stake to become to top neuron after the first epoch for netuid in netuids: @@ -119,7 +120,7 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) # Weights values uids = np.array([0], dtype=np.int64) - weights = np.array([0.1], dtype=np.float32) + weights = np.array([0.5], dtype=np.float32) weight_uids, weight_vals = convert_weights_and_uids_for_emit( uids=uids, weights=weights ) From 33e40bd2a85c6945123b01d7664cbed01f195fb2 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 17:49:36 -0700 Subject: [PATCH 079/150] test_set_weights.py to non-fast-block --- tests/e2e_tests/test_set_weights.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 6997e47a9f..c6635399bd 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -10,10 +10,10 @@ sudo_set_hyperparameter_bool, sudo_set_admin_utils, use_and_wait_for_next_nonce, - wait_epoch, ) +@pytest.mark.parametrize("local_chain", [False], indirect=True) @pytest.mark.asyncio async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet): """ @@ -31,6 +31,9 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) """ netuids = [2, 3] + subnet_tempo = 10 + BLOCK_TIME = 12 # 12 for non-fast-block, 0.25 for fast block + print("Testing test_set_weights_uses_next_nonce") # Lower the network registration rate limit and cost @@ -67,12 +70,12 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) call_function="sudo_set_tempo", call_params={ "netuid": netuid, - "tempo": 50, + "tempo": subnet_tempo, }, ) - await wait_epoch(subtensor, netuid=2, times=2) - subtensor.wait_for_block(subtensor.block + 1) + # make sure 2 epochs are passed + subtensor.wait_for_block(subnet_tempo * 2 + 1) # Stake to become to top neuron after the first epoch for netuid in netuids: @@ -127,7 +130,7 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) # Set weights for each subnet for netuid in netuids: - async with use_and_wait_for_next_nonce(subtensor, alice_wallet): + async with use_and_wait_for_next_nonce(subtensor, alice_wallet, BLOCK_TIME): success, message = subtensor.set_weights( alice_wallet, netuid, @@ -152,9 +155,10 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) params=[3, 0], ): if time.time() - extra_time > 120: - pytest.skip( - "Skipping due to FLAKY TEST. Check the same tests with another Python version or run again." - ) + # pytest.skip( + # "Skipping due to FLAKY TEST. Check the same tests with another Python version or run again." + # ) + raise Exception("Failed to commit weights") logging.console.info( f"Additional fast block to wait chain data updated: {subtensor.block}" From e378733a395693304c4d8e3888d0131894f1c1e7 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 18:19:27 -0700 Subject: [PATCH 080/150] test_commit_reveal_v3.py to non-fast-block --- tests/e2e_tests/test_commit_reveal_v3.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e_tests/test_commit_reveal_v3.py b/tests/e2e_tests/test_commit_reveal_v3.py index 71dde62f79..6d45cbd94d 100644 --- a/tests/e2e_tests/test_commit_reveal_v3.py +++ b/tests/e2e_tests/test_commit_reveal_v3.py @@ -96,7 +96,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle # Fetch current block and calculate next tempo for the subnet current_block = subtensor.get_current_block() - upcoming_tempo = next_tempo(current_block, tempo) + 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}" ) @@ -114,7 +114,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle ) current_block = subtensor.get_current_block() latest_drand_round = subtensor.last_drand_round() - upcoming_tempo = next_tempo(current_block, tempo) + 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}" ) @@ -142,7 +142,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle current_block = subtensor.get_current_block() latest_drand_round = subtensor.last_drand_round() - upcoming_tempo = next_tempo(current_block, tempo) + 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}" ) From 18271afadd5a81b78934a14f02695dd528b6e463 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 19:00:00 -0700 Subject: [PATCH 081/150] limit tests --- .github/workflows/e2e-subtensor-tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 1f7d2a3598..9e3261f569 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -38,9 +38,9 @@ jobs: - name: Find test files id: get-tests run: | - test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + # 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_(incentive|commit_weights|set_weights)\.py$' | jq -R -s -c 'split("\n") | map(select(. != ""))') echo "::set-output name=test-files::$test_files" shell: bash From 17d061d87284da7db40bb55ff6bbbd89d8dc5bcf Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 8 Apr 2025 19:00:53 -0700 Subject: [PATCH 082/150] test_commit_weights.py to non-fast block --- tests/e2e_tests/test_commit_weights.py | 78 +++++++++----------------- 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index cb23b640f4..66364eb976 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -1,10 +1,8 @@ import asyncio -import time import numpy as np import pytest -from bittensor.utils.btlogging import logging from bittensor.utils.weight_utils import convert_weights_and_uids_for_emit from tests.e2e_tests.utils.chain_interactions import ( sudo_set_admin_utils, @@ -152,6 +150,7 @@ async def test_commit_and_reveal_weights_legacy(local_chain, subtensor, alice_wa print("✅ Passed test_commit_and_reveal_weights") +@pytest.mark.parametrize("local_chain", [False], indirect=True) @pytest.mark.asyncio async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wallet): """ @@ -167,10 +166,12 @@ 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 = 10 + netuid = 2 + # Wait for 2 tempos to pass as CR3 only reveals weights after 2 tempos - subtensor.wait_for_block(21) + subtensor.wait_for_block(subnet_tempo * 2 + 1) - netuid = 2 print("Testing test_commit_and_reveal_weights") # Register root as Alice assert subtensor.register_subnet(alice_wallet), "Unable to register the subnet" @@ -178,6 +179,17 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall # Verify subnet 1 created successfully assert subtensor.subnet_exists(netuid), "Subnet wasn't created successfully" + # weights sensitive to epoch changes + assert sudo_set_admin_utils( + local_chain, + alice_wallet, + call_function="sudo_set_tempo", + call_params={ + "netuid": netuid, + "tempo": subnet_tempo, + }, + ) + # Enable commit_reveal on the subnet assert sudo_set_hyperparameter_bool( local_chain, @@ -205,19 +217,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall call_params={"netuid": netuid, "weights_set_rate_limit": "0"}, ) - assert error is None - assert status is True - - # weights sensitive to epoch changes - assert sudo_set_admin_utils( - local_chain, - alice_wallet, - call_function="sudo_set_tempo", - call_params={ - "netuid": netuid, - "tempo": 100, - }, - ) + assert error is None and status is True, f"Failed to set rate limit: {error}" assert ( subtensor.get_subnet_hyperparameters(netuid=netuid).weights_rate_limit == 0 @@ -248,14 +248,13 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall salt=salt, uids=weight_uids, weights=weight_vals, - wait_for_inclusion=False, - # Don't wait for inclusion, we are testing the nonce when there is a tx in the pool + wait_for_inclusion=False, # Don't wait for inclusion, we are testing the nonce when there is a tx in the pool wait_for_finalization=False, ) assert success is True - await asyncio.sleep(1) + subtensor.wait_for_block(subtensor.block + 1) async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( @@ -270,7 +269,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - await asyncio.sleep(1) + subtensor.wait_for_block(subtensor.block + 1) async with use_and_wait_for_next_nonce(subtensor, alice_wallet): success, message = subtensor.commit_weights( @@ -285,44 +284,19 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - await asyncio.sleep(1) - - # Sometimes the network does not have time to release data, and it requires several additional blocks (subtensor issue) - # Call get_metagraph_info since if faster and chipper - extra_time = time.time() - while ( - len( - subtensor.query_module( - module="SubtensorModule", - name="WeightCommits", - params=[netuid, alice_wallet.hotkey.ss58_address], - ).value - ) - < 3 - ): - if time.time() - extra_time > 120: - pytest.skip( - "Skipping due to FLAKY TEST. Check the same tests with another Python version or run again." - ) - - logging.console.info( - f"Additional fast block to wait chain data updated: {subtensor.block}" - ) - await asyncio.sleep(0.25) + # Wait a few blocks + await wait_epoch(subtensor, netuid) # Wait for the txs to be included in the chain # Query the WeightCommits storage map for all three salts - query = subtensor.query_module( + weight_commits = subtensor.query_module( module="SubtensorModule", name="WeightCommits", params=[netuid, alice_wallet.hotkey.ss58_address], ) - - weight_commits = query.value - # Assert that the committed weights are set correctly - assert weight_commits is not None, "Weight commit not found in storage" - commit_hash, commit_block, reveal_block, expire_block = weight_commits[0] + assert weight_commits.value is not None, "Weight commit not found in storage" + commit_hash, commit_block, reveal_block, expire_block = weight_commits.value[0] assert commit_block > 0, f"Invalid block number: {commit_block}" # Check for three commits in the WeightCommits storage map - assert len(weight_commits) == 3, "Expected 3 weight commits" + assert len(weight_commits.value) == 3, "Expected 3 weight commits" From 631a4687d4992402b7a9ace7ebb82d62ac49b4ad Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Wed, 9 Apr 2025 22:27:43 +0200 Subject: [PATCH 083/150] Put the version in a single place (toml) --- .circleci/config.yml | 12 ------------ VERSION | 1 - bittensor/core/settings.py | 5 +++-- 3 files changed, 3 insertions(+), 15 deletions(-) delete mode 100644 VERSION diff --git a/.circleci/config.yml b/.circleci/config.yml index fbe39a6645..a1222c0318 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -235,18 +235,6 @@ jobs: uv pip install --upgrade coveralls coveralls --finish --rcfile .coveragerc || echo "Failed to upload coverage" - check-version-updated: - docker: - - image: cimg/python:3.10 - steps: - - checkout - - - run: - name: Version is updated - command: | - [[ $(git diff-tree --no-commit-id --name-only -r HEAD..master | grep bittensor/__init__.py | wc -l) == 1 ]] && echo "bittensor/__init__.py has changed" - [[ $(git diff-tree --no-commit-id --name-only -r HEAD..master | grep VERSION | wc -l) == 1 ]] && echo "VERSION has changed" - check-changelog-updated: docker: - image: cimg/python:3.10 diff --git a/VERSION b/VERSION deleted file mode 100644 index 85f864fe85..0000000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -9.2.0 \ No newline at end of file diff --git a/bittensor/core/settings.py b/bittensor/core/settings.py index 8a53f6c423..cf2c07b38d 100644 --- a/bittensor/core/settings.py +++ b/bittensor/core/settings.py @@ -1,6 +1,5 @@ -__version__ = "9.2.0" - import os +import importlib.metadata import re from pathlib import Path @@ -15,6 +14,8 @@ WALLETS_DIR = USER_BITTENSOR_DIR / "wallets" MINERS_DIR = USER_BITTENSOR_DIR / "miners" +__version__ = importlib.metadata.version("bittensor") + if not READ_ONLY: # Create dirs if they don't exist From e4e32df00955c3245d95f37ad9b7df12c30a4828 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 17:49:48 -0700 Subject: [PATCH 084/150] add log to miner and validator --- tests/e2e_tests/utils/e2e_test_utils.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index 91c6a1d508..cf8fdbf83d 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -134,6 +134,14 @@ async def __aexit__(self, exc_type, exc_value, traceback): async def _reader(self): async for line in self.process.stdout: + try: + bittensor.logging.console.info( + f"[green]MINER LOG: {line.split(b'|')[-1].strip().decode()}[/blue]" + ) + except: + # skipp empty lines + pass + if b"Starting main loop" in line: self.started.set() @@ -189,6 +197,14 @@ async def __aexit__(self, exc_type, exc_value, traceback): async def _reader(self): async for line in self.process.stdout: + try: + bittensor.logging.console.info( + f"[orange]VALIDATOR LOG: {line.split(b'|')[-1].strip().decode()}[/orange]" + ) + except: + # skipp empty lines + pass + if b"Starting validator loop." in line: bittensor.logging.console.info("Validator started.") self.started.set() From 0d74ba4e9c7a0a0b424bf2d7ef62dde05f6fa0cf Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 17:54:27 -0700 Subject: [PATCH 085/150] add wait_for to miner start ,wrapp tests result info while --- tests/e2e_tests/test_incentive.py | 120 ++++++++++++++++-------------- 1 file changed, 64 insertions(+), 56 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 0fefe220c1..cfe645e489 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -2,6 +2,7 @@ import time import pytest +import bittensor from bittensor.utils.btlogging import logging from tests.e2e_tests.utils.chain_interactions import ( root_set_subtensor_hyperparameter_values, @@ -110,66 +111,73 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert error is None assert status is True - async with templates.miner(bob_wallet, netuid): - subtensor.wait_for_block(subtensor.block + 4) + async with templates.miner(bob_wallet, netuid) as miner: + logging.console.info(f"Waiting for miner started.") + await asyncio.wait_for(miner.started.wait(), 120) async with templates.validator(alice_wallet, netuid) as validator: - subtensor.wait_for_block(subtensor.block + 4) - # wait for the Validator to process and set_weights - logging.console.info(f"Waiting for validator to set weights: {validator}") + logging.console.info(f"Waiting for validator to set weights.") await asyncio.wait_for(validator.set_weights.wait(), 120) - logging.console.info(f"Validator got weights: {validator}") # Sometimes the network does not have time to release data, and it requires several additional blocks (subtensor issue) # Call get_metagraph_info since if faster and chipper - extra_time = time.time() - while subtensor.get_metagraph_info(netuid).incentives[0] == 0: - logging.console.info( - f"Additional fast block to wait chain data updated: {subtensor.block}" - ) - if time.time() - extra_time > 120: - pytest.skip( - "Skipping due to FLAKY TEST. Check the same tests with another Python version or run again." - ) - - await asyncio.sleep(0.25) - - # Refresh metagraph - metagraph = subtensor.metagraph(netuid) - - # Get current emissions and validate that Alice has gotten tao - alice_neuron = metagraph.neurons[0] - - assert alice_neuron.validator_permit is True - assert alice_neuron.dividends == 1.0 - assert alice_neuron.stake.tao > 0 - assert alice_neuron.validator_trust > 0.99 - assert alice_neuron.incentive < 0.5 - assert alice_neuron.consensus < 0.5 - assert alice_neuron.rank < 0.5 - - bob_neuron = metagraph.neurons[1] - - assert bob_neuron.incentive > 0.5 - assert bob_neuron.consensus > 0.5 - assert bob_neuron.rank > 0.5 - assert bob_neuron.trust == 1 - - bonds = subtensor.bonds(netuid) - - assert bonds == [ - ( - 0, - [ - (0, 65535), - (1, 65535), - ], - ), - ( - 1, - [], - ), - ] - - print("✅ Passed test_incentive") + # extra_time = time.time() + # while subtensor.get_metagraph_info(netuid).incentives[0] == 0: + # logging.console.info( + # f"Additional fast block to wait chain data updated: {subtensor.block}" + # ) + # if time.time() - extra_time > 120: + # pytest.skip( + # "Skipping due to FLAKY TEST. Check the same tests with another Python version or run again." + # ) + # + # await asyncio.sleep(0.25) + + while True: + logging.console.info("Current block: ", subtensor.block) + + try: + # Refresh metagraph + neurons = subtensor.neurons(netuid) + + # Get current emissions and validate that Alice has gotten tao + alice_neuron = neurons[0] + + assert alice_neuron.validator_permit is True + assert alice_neuron.dividends == 1.0 + assert alice_neuron.stake.tao > 0 + assert alice_neuron.validator_trust > 0.99 + assert alice_neuron.incentive < 0.5 + assert alice_neuron.consensus < 0.5 + assert alice_neuron.rank < 0.5 + + bob_neuron = neurons[1] + + assert bob_neuron.incentive > 0.5 + assert bob_neuron.consensus > 0.5 + assert bob_neuron.rank > 0.5 + assert bob_neuron.trust == 1 + + bonds = subtensor.bonds(netuid) + + assert bonds == [ + ( + 0, + [ + (0, 65535), + (1, 65535), + ], + ), + ( + 1, + [], + ), + ] + + logging.console.info("✅ Passed test_incentive") + break + + except Exception: + logging.console.warning(f"Waiting for incentive to be set.") + await asyncio.sleep(0.25) From 893f8cd2e20c98178c79654a71040ef671547b7b Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 18:11:27 -0700 Subject: [PATCH 086/150] origin --- tests/e2e_tests/test_incentive.py | 125 +++++++++++------------------- 1 file changed, 44 insertions(+), 81 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index cfe645e489..56f23ddd52 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -1,9 +1,7 @@ import asyncio -import time + import pytest -import bittensor -from bittensor.utils.btlogging import logging from tests.e2e_tests.utils.chain_interactions import ( root_set_subtensor_hyperparameter_values, sudo_set_admin_utils, @@ -37,17 +35,6 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa # Verify subnet created successfully assert subtensor.subnet_exists(netuid), "Subnet wasn't created successfully" - # weights sensitive to epoch changes - assert sudo_set_admin_utils( - local_chain, - alice_wallet, - call_function="sudo_set_tempo", - call_params={ - "netuid": netuid, - "tempo": 100, - }, - ) - # Register Bob as a neuron on the subnet assert subtensor.burned_register( bob_wallet, netuid @@ -111,73 +98,49 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert error is None assert status is True - async with templates.miner(bob_wallet, netuid) as miner: - logging.console.info(f"Waiting for miner started.") - await asyncio.wait_for(miner.started.wait(), 120) - + async with templates.miner(bob_wallet, netuid): async with templates.validator(alice_wallet, netuid) as validator: # wait for the Validator to process and set_weights - logging.console.info(f"Waiting for validator to set weights.") - await asyncio.wait_for(validator.set_weights.wait(), 120) - - # Sometimes the network does not have time to release data, and it requires several additional blocks (subtensor issue) - # Call get_metagraph_info since if faster and chipper - # extra_time = time.time() - # while subtensor.get_metagraph_info(netuid).incentives[0] == 0: - # logging.console.info( - # f"Additional fast block to wait chain data updated: {subtensor.block}" - # ) - # if time.time() - extra_time > 120: - # pytest.skip( - # "Skipping due to FLAKY TEST. Check the same tests with another Python version or run again." - # ) - # - # await asyncio.sleep(0.25) - - while True: - logging.console.info("Current block: ", subtensor.block) - - try: + await asyncio.wait_for(validator.set_weights.wait(), 60) + + # Wait till new epoch + await wait_interval(tempo, subtensor, netuid) + # Refresh metagraph - neurons = subtensor.neurons(netuid) - - # Get current emissions and validate that Alice has gotten tao - alice_neuron = neurons[0] - - assert alice_neuron.validator_permit is True - assert alice_neuron.dividends == 1.0 - assert alice_neuron.stake.tao > 0 - assert alice_neuron.validator_trust > 0.99 - assert alice_neuron.incentive < 0.5 - assert alice_neuron.consensus < 0.5 - assert alice_neuron.rank < 0.5 - - bob_neuron = neurons[1] - - assert bob_neuron.incentive > 0.5 - assert bob_neuron.consensus > 0.5 - assert bob_neuron.rank > 0.5 - assert bob_neuron.trust == 1 - - bonds = subtensor.bonds(netuid) - - assert bonds == [ - ( - 0, - [ - (0, 65535), - (1, 65535), - ], - ), - ( - 1, - [], - ), - ] - - logging.console.info("✅ Passed test_incentive") - break - - except Exception: - logging.console.warning(f"Waiting for incentive to be set.") - await asyncio.sleep(0.25) + metagraph = subtensor.metagraph(netuid) + + # Get current emissions and validate that Alice has gotten tao + alice_neuron = metagraph.neurons[0] + + assert alice_neuron.validator_permit is True + assert alice_neuron.dividends == 1.0 + assert alice_neuron.stake.tao > 0 + assert alice_neuron.validator_trust > 0.99 + assert alice_neuron.incentive < 0.5 + assert alice_neuron.consensus < 0.5 + assert alice_neuron.rank < 0.5 + + bob_neuron = metagraph.neurons[1] + + assert bob_neuron.incentive > 0.5 + assert bob_neuron.consensus > 0.5 + assert bob_neuron.rank > 0.5 + assert bob_neuron.trust == 1 + + bonds = subtensor.bonds(netuid) + + assert bonds == [ + ( + 0, + [ + (0, 65535), + (1, 65535), + ], + ), + ( + 1, + [], + ), + ] + + print("✅ Passed test_incentive") From fc99a3118d4f40a2ef19e2fb89232177675ace27 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 19:43:27 -0700 Subject: [PATCH 087/150] set period for set_weights as tempo --- bittensor/core/extrinsics/set_weights.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bittensor/core/extrinsics/set_weights.py b/bittensor/core/extrinsics/set_weights.py index 4c1c194708..85a5c7e921 100644 --- a/bittensor/core/extrinsics/set_weights.py +++ b/bittensor/core/extrinsics/set_weights.py @@ -135,6 +135,7 @@ def set_weights_extrinsic( version_key=version_key, wait_for_finalization=wait_for_finalization, wait_for_inclusion=wait_for_inclusion, + period=subtensor.tempo(netuid=netuid), ) if not wait_for_finalization and not wait_for_inclusion: From e1627ef32ab45287ec69dee05cb15212ee93b7cf Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 19:43:41 -0700 Subject: [PATCH 088/150] update test --- tests/e2e_tests/test_incentive.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 56f23ddd52..daa897bbfe 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -48,11 +48,8 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa # Wait for the first epoch to pass await wait_epoch(subtensor, netuid) - # Get latest metagraph - metagraph = subtensor.metagraph(netuid) - # Get current miner/validator stats - alice_neuron = metagraph.neurons[0] + alice_neuron = subtensor.neurons[0] assert alice_neuron.validator_permit is True assert alice_neuron.dividends == 0 @@ -62,7 +59,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert alice_neuron.consensus == 0 assert alice_neuron.rank == 0 - bob_neuron = metagraph.neurons[1] + bob_neuron = subtensor.neurons[1] assert bob_neuron.incentive == 0 assert bob_neuron.consensus == 0 @@ -98,19 +95,17 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert error is None assert status is True - async with templates.miner(bob_wallet, netuid): + async with templates.miner(bob_wallet, netuid) as miner: + await asyncio.wait_for(miner.started.wait(), 60) + async with templates.validator(alice_wallet, netuid) as validator: # wait for the Validator to process and set_weights await asyncio.wait_for(validator.set_weights.wait(), 60) - # Wait till new epoch - await wait_interval(tempo, subtensor, netuid) - - # Refresh metagraph - metagraph = subtensor.metagraph(netuid) + subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuid)) # Get current emissions and validate that Alice has gotten tao - alice_neuron = metagraph.neurons[0] + alice_neuron = subtensor.neurons[0] assert alice_neuron.validator_permit is True assert alice_neuron.dividends == 1.0 @@ -120,7 +115,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert alice_neuron.consensus < 0.5 assert alice_neuron.rank < 0.5 - bob_neuron = metagraph.neurons[1] + bob_neuron = subtensor.neurons[1] assert bob_neuron.incentive > 0.5 assert bob_neuron.consensus > 0.5 From 9c9bdba9f1ecdade8a02a20a5bbbe200dcab11eb Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 19:55:36 -0700 Subject: [PATCH 089/150] fix neurons call --- tests/e2e_tests/test_incentive.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index daa897bbfe..af5b1a421c 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -49,7 +49,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa await wait_epoch(subtensor, netuid) # Get current miner/validator stats - alice_neuron = subtensor.neurons[0] + alice_neuron = subtensor.neurons(netuid=netuid)[0] assert alice_neuron.validator_permit is True assert alice_neuron.dividends == 0 @@ -59,7 +59,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert alice_neuron.consensus == 0 assert alice_neuron.rank == 0 - bob_neuron = subtensor.neurons[1] + bob_neuron = subtensor.neurons(netuid=netuid)[1] assert bob_neuron.incentive == 0 assert bob_neuron.consensus == 0 From 17723e14837221f9836f0346ca06b8e8f5979c44 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 20:14:52 -0700 Subject: [PATCH 090/150] fix neurons call --- tests/e2e_tests/test_incentive.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index af5b1a421c..e96df7f9ce 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -2,6 +2,8 @@ import pytest +from bittensor.utils.btlogging import logging + from tests.e2e_tests.utils.chain_interactions import ( root_set_subtensor_hyperparameter_values, sudo_set_admin_utils, @@ -105,7 +107,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuid)) # Get current emissions and validate that Alice has gotten tao - alice_neuron = subtensor.neurons[0] + alice_neuron = subtensor.neurons(netuid=netuid)[0] assert alice_neuron.validator_permit is True assert alice_neuron.dividends == 1.0 @@ -115,7 +117,7 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert alice_neuron.consensus < 0.5 assert alice_neuron.rank < 0.5 - bob_neuron = subtensor.neurons[1] + bob_neuron = subtensor.neurons(netuid=netuid)[1] assert bob_neuron.incentive > 0.5 assert bob_neuron.consensus > 0.5 From cf0f1f9edbe02c5e02f18c7aa7d2467be94cca63 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 20:30:44 -0700 Subject: [PATCH 091/150] fix neurons call --- tests/e2e_tests/test_incentive.py | 80 +++++++++++++++++-------------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index e96df7f9ce..09ca1c7373 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -104,40 +104,50 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa # wait for the Validator to process and set_weights await asyncio.wait_for(validator.set_weights.wait(), 60) + # wait one tempo (fast block subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuid)) - # Get current emissions and validate that Alice has gotten tao - alice_neuron = subtensor.neurons(netuid=netuid)[0] - - assert alice_neuron.validator_permit is True - assert alice_neuron.dividends == 1.0 - assert alice_neuron.stake.tao > 0 - assert alice_neuron.validator_trust > 0.99 - assert alice_neuron.incentive < 0.5 - assert alice_neuron.consensus < 0.5 - assert alice_neuron.rank < 0.5 - - bob_neuron = subtensor.neurons(netuid=netuid)[1] - - assert bob_neuron.incentive > 0.5 - assert bob_neuron.consensus > 0.5 - assert bob_neuron.rank > 0.5 - assert bob_neuron.trust == 1 - - bonds = subtensor.bonds(netuid) - - assert bonds == [ - ( - 0, - [ - (0, 65535), - (1, 65535), - ], - ), - ( - 1, - [], - ), - ] - - print("✅ Passed test_incentive") + while True: + try: + neurons = subtensor.neurons(netuid=netuid) + logging.info(f"neurons: {neurons}") + + # Get current emissions and validate that Alice has gotten tao + alice_neuron = neurons[0] + + assert alice_neuron.validator_permit is True + assert alice_neuron.dividends == 1.0 + assert alice_neuron.stake.tao > 0 + assert alice_neuron.validator_trust > 0.99 + assert alice_neuron.incentive < 0.5 + assert alice_neuron.consensus < 0.5 + assert alice_neuron.rank < 0.5 + + bob_neuron = neurons[1] + + assert bob_neuron.incentive > 0.5 + assert bob_neuron.consensus > 0.5 + assert bob_neuron.rank > 0.5 + assert bob_neuron.trust == 1 + + bonds = subtensor.bonds(netuid) + + assert bonds == [ + ( + 0, + [ + (0, 65535), + (1, 65535), + ], + ), + ( + 1, + [], + ), + ] + + print("✅ Passed test_incentive") + break + except Exception: + subtensor.wait_for_block(subtensor.block) + continue From b7902db885ccdb91a2585bee9330f815c6dd8381 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 21:09:47 -0700 Subject: [PATCH 092/150] add period argument to set_weights and related calls + fixed tests --- bittensor/core/async_subtensor.py | 3 +++ bittensor/core/extrinsics/asyncex/weights.py | 3 +++ bittensor/core/extrinsics/set_weights.py | 4 +++- bittensor/core/subtensor.py | 3 +++ tests/unit_tests/extrinsics/asyncex/test_weights.py | 1 + tests/unit_tests/test_async_subtensor.py | 1 + tests/unit_tests/test_subtensor.py | 1 + 7 files changed, 15 insertions(+), 1 deletion(-) diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index 9a132f4258..e9728287fb 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -3813,6 +3813,7 @@ async def set_weights( wait_for_finalization: bool = False, max_retries: int = 5, block_time: float = 12.0, + period: int = 5, ): """ Sets the inter-neuronal weights for the specified neuron. This process involves specifying the influence or @@ -3833,6 +3834,7 @@ async def set_weights( ``False``. max_retries (int): The number of maximum attempts to set weights. Default is ``5``. block_time (float): The amount of seconds for block duration. Default is 12.0 seconds. + period (int, optional): The period in seconds to wait for extrinsic inclusion or finalization. Defaults to 5. Returns: tuple[bool, str]: ``True`` if the setting of weights is successful, False otherwise. And `msg`, a string @@ -3907,6 +3909,7 @@ async def _blocks_weight_limit() -> bool: version_key=version_key, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, + period=period, ) except Exception as e: logging.error(f"Error setting weights: {e}") diff --git a/bittensor/core/extrinsics/asyncex/weights.py b/bittensor/core/extrinsics/asyncex/weights.py index b2221a5263..6e07b90adb 100644 --- a/bittensor/core/extrinsics/asyncex/weights.py +++ b/bittensor/core/extrinsics/asyncex/weights.py @@ -287,6 +287,7 @@ async def set_weights_extrinsic( version_key: int = 0, wait_for_inclusion: bool = False, wait_for_finalization: bool = False, + period: int = 5, ) -> tuple[bool, str]: """Sets the given weights and values on chain for wallet hotkey account. @@ -302,6 +303,7 @@ async def set_weights_extrinsic( returns ``False`` if the extrinsic fails to enter the block within the timeout. wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning ``True``, or returns ``False`` if the extrinsic fails to be finalized within the timeout. + period (int, optional): The period in seconds to wait for extrinsic inclusion or finalization. Defaults to 5. Returns: success (bool): Flag is ``True`` if extrinsic was finalized or included in the block. If we did not wait for @@ -331,6 +333,7 @@ async def set_weights_extrinsic( version_key=version_key, wait_for_finalization=wait_for_finalization, wait_for_inclusion=wait_for_inclusion, + period=period, ) if not wait_for_finalization and not wait_for_inclusion: diff --git a/bittensor/core/extrinsics/set_weights.py b/bittensor/core/extrinsics/set_weights.py index 85a5c7e921..908fb2b2a9 100644 --- a/bittensor/core/extrinsics/set_weights.py +++ b/bittensor/core/extrinsics/set_weights.py @@ -91,6 +91,7 @@ def set_weights_extrinsic( version_key: int = 0, wait_for_inclusion: bool = False, wait_for_finalization: bool = False, + period: int = 5, ) -> tuple[bool, str]: """Sets the given weights and values on chain for wallet hotkey account. @@ -106,6 +107,7 @@ def set_weights_extrinsic( returns ``False`` if the extrinsic fails to enter the block within the timeout. wait_for_finalization (bool): If set, waits for the extrinsic to be finalized on the chain before returning ``True``, or returns ``False`` if the extrinsic fails to be finalized within the timeout. + period (int, optional): The period in seconds to wait for extrinsic inclusion or finalization. Defaults to 5. Returns: success (bool): Flag is ``True`` if extrinsic was finalized or included in the block. If we did not wait for @@ -135,7 +137,7 @@ def set_weights_extrinsic( version_key=version_key, wait_for_finalization=wait_for_finalization, wait_for_inclusion=wait_for_inclusion, - period=subtensor.tempo(netuid=netuid), + period=period, ) if not wait_for_finalization and not wait_for_inclusion: diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 19b14d09c0..65c9f4158f 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -3100,6 +3100,7 @@ def set_weights( wait_for_finalization: bool = False, max_retries: int = 5, block_time: float = 12.0, + period: int = 5, ) -> tuple[bool, str]: """ Sets the inter-neuronal weights for the specified neuron. This process involves specifying the influence or @@ -3120,6 +3121,7 @@ def set_weights( ``False``. max_retries (int): The number of maximum attempts to set weights. Default is ``5``. block_time (float): The amount of seconds for block duration. Default is 12.0 seconds. + period (int, optional): The period in seconds to wait for extrinsic inclusion or finalization. Defaults to 5. Returns: tuple[bool, str]: ``True`` if the setting of weights is successful, False otherwise. And `msg`, a string @@ -3183,6 +3185,7 @@ def _blocks_weight_limit() -> bool: version_key=version_key, wait_for_inclusion=wait_for_inclusion, wait_for_finalization=wait_for_finalization, + period=period, ) except Exception as e: logging.error(f"Error setting weights: {e}") diff --git a/tests/unit_tests/extrinsics/asyncex/test_weights.py b/tests/unit_tests/extrinsics/asyncex/test_weights.py index 8a297602f1..c01490055d 100644 --- a/tests/unit_tests/extrinsics/asyncex/test_weights.py +++ b/tests/unit_tests/extrinsics/asyncex/test_weights.py @@ -169,6 +169,7 @@ async def test_set_weights_extrinsic_success_with_finalization( version_key=0, wait_for_finalization=True, wait_for_inclusion=True, + period=5, ) assert result is True assert message == "Successfully set weights and Finalized." diff --git a/tests/unit_tests/test_async_subtensor.py b/tests/unit_tests/test_async_subtensor.py index 3acab650e9..37c6efc7ff 100644 --- a/tests/unit_tests/test_async_subtensor.py +++ b/tests/unit_tests/test_async_subtensor.py @@ -2688,6 +2688,7 @@ async def test_set_weights_success(subtensor, fake_wallet, mocker): wait_for_finalization=False, wait_for_inclusion=False, weights=fake_weights, + period=5, ) mocked_weights_rate_limit.assert_called_once_with(fake_netuid) assert result is True diff --git a/tests/unit_tests/test_subtensor.py b/tests/unit_tests/test_subtensor.py index 513ce7ab3b..c03e158f79 100644 --- a/tests/unit_tests/test_subtensor.py +++ b/tests/unit_tests/test_subtensor.py @@ -1220,6 +1220,7 @@ def test_set_weights(subtensor, mocker, fake_wallet): version_key=settings.version_as_int, wait_for_inclusion=fake_wait_for_inclusion, wait_for_finalization=fake_wait_for_finalization, + period=5, ) assert result == expected_result From ec5ca290a84a1b0a1f2eac01724b23a299548d4d Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 21:10:01 -0700 Subject: [PATCH 093/150] cleanup --- tests/e2e_tests/utils/e2e_test_utils.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index cf8fdbf83d..1336c66cb4 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -138,7 +138,7 @@ async def _reader(self): bittensor.logging.console.info( f"[green]MINER LOG: {line.split(b'|')[-1].strip().decode()}[/blue]" ) - except: + except BaseException: # skipp empty lines pass @@ -201,7 +201,7 @@ async def _reader(self): bittensor.logging.console.info( f"[orange]VALIDATOR LOG: {line.split(b'|')[-1].strip().decode()}[/orange]" ) - except: + except BaseException: # skipp empty lines pass @@ -211,9 +211,6 @@ async def _reader(self): elif b"Successfully set weights and Finalized." in line: bittensor.logging.console.info("Validator is setting weights.") self.set_weights.set() - bittensor.logging.console.info( - "Validator successfully set weights and Finalized." - ) def __init__(self): self.dir = clone_or_update_templates() From c1dbc0582003d40c06effa7211109a70287a95e5 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 21:25:57 -0700 Subject: [PATCH 094/150] add get_next_epoch_start_block --- bittensor/core/async_subtensor.py | 30 ++++++++++++++++++++++++++++++ bittensor/core/subtensor.py | 22 ++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index 9a132f4258..3740e23676 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -1687,6 +1687,36 @@ async def get_neuron_for_pubkey_and_subnet( reuse_block=reuse_block, ) + async def get_next_epoch_start_block( + self, + netuid: int, + block: Optional[int] = None, + block_hash: Optional[str] = None, + reuse_block: bool = False, + ) -> Optional[int]: + """ + Calculates the first block number of the next epoch for the given subnet. + + If `block` is not provided, the current chain block will be used. Epochs are + determined based on the subnet's tempo (i.e., blocks per epoch). The result + is the block number at which the next epoch will begin. + + Args: + netuid (int): The unique identifier of the subnet. + block (Optional[int], optional): The reference block to calculate from. + If None, uses the current chain block height. + block_hash (Optional[int]): The blockchain block number at which to perform the query. + reuse_block (bool): Whether to reuse the last-used blockchain block hash. + + + Returns: + int: The block number at which the next epoch will start. + """ + tempo = await self.tempo( + netuid=netuid, block=block, block_hash=block_hash, reuse_block=reuse_block + ) + return (((block // tempo) + 1) * tempo) + 1 if tempo else None + async def get_owned_hotkeys( self, coldkey_ss58: str, diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index 19b14d09c0..ee313c9c85 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -1300,6 +1300,28 @@ def get_neuron_for_pubkey_and_subnet( return NeuronInfo.from_dict(result) + def get_next_epoch_start_block( + self, netuid: int, block: Optional[int] = None + ) -> Optional[int]: + """ + Calculates the first block number of the next epoch for the given subnet. + + If `block` is not provided, the current chain block will be used. Epochs are + determined based on the subnet's tempo (i.e., blocks per epoch). The result + is the block number at which the next epoch will begin. + + Args: + netuid (int): The unique identifier of the subnet. + block (Optional[int], optional): The reference block to calculate from. + If None, uses the current chain block height. + + Returns: + int: The block number at which the next epoch will start. + """ + block = block or self.block + tempo = self.tempo(netuid=netuid) + return (((block // tempo) + 1) * tempo) + 1 if tempo else None + def get_owned_hotkeys( self, coldkey_ss58: str, From b70e7133a9155df453afe959ba2ce15691ded13b Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 21:30:22 -0700 Subject: [PATCH 095/150] add get_next_epoch_start_block --- bittensor/core/async_subtensor.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index 3740e23676..4786e30375 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -1712,6 +1712,8 @@ async def get_next_epoch_start_block( Returns: int: The block number at which the next epoch will start. """ + block = block or await self.block + block_hash = block_hash or await self.get_block_hash(block) tempo = await self.tempo( netuid=netuid, block=block, block_hash=block_hash, reuse_block=reuse_block ) From 28217225d59d27eeecd7f7510d855feb9ec13d3b Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 21:50:31 -0700 Subject: [PATCH 096/150] test_commit_weights.py + test_set_weights.py --- tests/e2e_tests/test_commit_weights.py | 15 ++++++------- tests/e2e_tests/test_set_weights.py | 30 +++++--------------------- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 66364eb976..45db49def2 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -150,7 +150,6 @@ async def test_commit_and_reveal_weights_legacy(local_chain, subtensor, alice_wa print("✅ Passed test_commit_and_reveal_weights") -@pytest.mark.parametrize("local_chain", [False], indirect=True) @pytest.mark.asyncio async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wallet): """ @@ -166,7 +165,7 @@ 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 = 10 + subnet_tempo = 100 netuid = 2 # Wait for 2 tempos to pass as CR3 only reveals weights after 2 tempos @@ -241,7 +240,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall salt3[0] += 2 # Increment the first byte to produce a different commit hash # Commit all three salts - async with use_and_wait_for_next_nonce(subtensor, alice_wallet): + async with use_and_wait_for_next_nonce(subtensor, alice_wallet, 2.5): success, message = subtensor.commit_weights( alice_wallet, netuid, @@ -254,9 +253,9 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - subtensor.wait_for_block(subtensor.block + 1) + subtensor.wait_for_block(subtensor.block + 4) - async with use_and_wait_for_next_nonce(subtensor, alice_wallet): + async with use_and_wait_for_next_nonce(subtensor, alice_wallet, 2.5): success, message = subtensor.commit_weights( alice_wallet, netuid, @@ -269,9 +268,9 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True - subtensor.wait_for_block(subtensor.block + 1) + subtensor.wait_for_block(subtensor.block + 4) - async with use_and_wait_for_next_nonce(subtensor, alice_wallet): + async with use_and_wait_for_next_nonce(subtensor, alice_wallet, 2.5): success, message = subtensor.commit_weights( alice_wallet, netuid, @@ -285,7 +284,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True # Wait a few blocks - await wait_epoch(subtensor, netuid) # Wait for the txs to be included in the chain + subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuid)) # Query the WeightCommits storage map for all three salts weight_commits = subtensor.query_module( diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index c6635399bd..c40383dca3 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -13,7 +13,6 @@ ) -@pytest.mark.parametrize("local_chain", [False], indirect=True) @pytest.mark.asyncio async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet): """ @@ -31,8 +30,8 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) """ netuids = [2, 3] - subnet_tempo = 10 - BLOCK_TIME = 12 # 12 for non-fast-block, 0.25 for fast block + subnet_tempo = 100 + BLOCK_TIME = 0.25 # 12 for non-fast-block, 0.25 for fast block print("Testing test_set_weights_uses_next_nonce") @@ -104,7 +103,7 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) subtensor.weights_rate_limit(netuid=netuid) > 0 ), "Weights rate limit is below 0" - # Lower the rate limit + # Lower set weights rate limit status, error = sudo_set_admin_utils( local_chain, alice_wallet, @@ -141,29 +140,10 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) ) assert success is True, message - subtensor.wait_for_block(subtensor.block + 1) + subtensor.wait_for_block(subtensor.block + 4) logging.console.success(f"Set weights for subnet {netuid}") - extra_time = time.time() - while not subtensor.query_module( - module="SubtensorModule", - name="Weights", - params=[2, 0], - ) or not subtensor.query_module( - module="SubtensorModule", - name="Weights", - params=[3, 0], - ): - if time.time() - extra_time > 120: - # pytest.skip( - # "Skipping due to FLAKY TEST. Check the same tests with another Python version or run again." - # ) - raise Exception("Failed to commit weights") - - logging.console.info( - f"Additional fast block to wait chain data updated: {subtensor.block}" - ) - subtensor.wait_for_block(subtensor.block + 1) + subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuids[-1])) for netuid in netuids: # Query the Weights storage map for all three subnets From ef7d8c5894664a74fd9134daeea9eebc39e5bc4a Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 22:10:03 -0700 Subject: [PATCH 097/150] add commit from template-repo (fix for test_incentive) --- tests/e2e_tests/utils/e2e_test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index 1336c66cb4..6618be098b 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -213,7 +213,7 @@ async def _reader(self): self.set_weights.set() def __init__(self): - self.dir = clone_or_update_templates() + self.dir = clone_or_update_templates(specific_commit="92d5bdf1069286d97470362c5c22611aa0fa048c") def __enter__(self): return self From eb5074417376696ce04e3ea2c52cf7c3382d4816 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 22:16:29 -0700 Subject: [PATCH 098/150] add period to `set_weights` in `test_set_weights.py` --- tests/e2e_tests/test_set_weights.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index c40383dca3..4aa46da30f 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -30,7 +30,7 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) """ netuids = [2, 3] - subnet_tempo = 100 + subnet_tempo = 50 BLOCK_TIME = 0.25 # 12 for non-fast-block, 0.25 for fast block print("Testing test_set_weights_uses_next_nonce") @@ -137,6 +137,7 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) weights=weight_vals, wait_for_inclusion=False, # Don't wait for inclusion, we are testing the nonce when there is a tx in the pool wait_for_finalization=False, + period=subnet_tempo, ) assert success is True, message From 1f7e89c0c3fd0f945ef79d7fe01339db322f9125 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 22:17:08 -0700 Subject: [PATCH 099/150] add period to `set_weights` in `test_set_weights.py` --- tests/e2e_tests/utils/e2e_test_utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index 6618be098b..1ad8001564 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -213,7 +213,9 @@ async def _reader(self): self.set_weights.set() def __init__(self): - self.dir = clone_or_update_templates(specific_commit="92d5bdf1069286d97470362c5c22611aa0fa048c") + self.dir = clone_or_update_templates( + specific_commit="92d5bdf1069286d97470362c5c22611aa0fa048c" + ) def __enter__(self): return self From 2fd2024e6fcfc0fee9f9d7ed83e9c6f977768d7f Mon Sep 17 00:00:00 2001 From: sashaphmn Date: Thu, 10 Apr 2025 08:30:04 +0300 Subject: [PATCH 100/150] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7dbfcbc260..1644701d83 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ## Internet-scale Neural Networks -[Discord](https://discord.gg/qasY3HA9F9) • [Network](https://taostats.io/) • [Research](https://bittensor.com/whitepaper) +[Documentation](https://docs.bittensor.com) • [Network](https://taostats.io/) • [Research](https://bittensor.com/whitepaper) From 2855b7045f332da7f0e6bd2a89ba3c89bd11629c Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 22:31:38 -0700 Subject: [PATCH 101/150] add 3 attempts to run validator --- tests/e2e_tests/test_incentive.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/tests/e2e_tests/test_incentive.py b/tests/e2e_tests/test_incentive.py index 09ca1c7373..ff040b6f35 100644 --- a/tests/e2e_tests/test_incentive.py +++ b/tests/e2e_tests/test_incentive.py @@ -97,12 +97,22 @@ async def test_incentive(local_chain, subtensor, templates, alice_wallet, bob_wa assert error is None assert status is True - async with templates.miner(bob_wallet, netuid) as miner: - await asyncio.wait_for(miner.started.wait(), 60) + # max attempts to run miner and validator + max_attempt = 3 + while True: + try: + async with templates.miner(bob_wallet, netuid) as miner: + await asyncio.wait_for(miner.started.wait(), 60) - async with templates.validator(alice_wallet, netuid) as validator: - # wait for the Validator to process and set_weights - await asyncio.wait_for(validator.set_weights.wait(), 60) + async with templates.validator(alice_wallet, netuid) as validator: + # wait for the Validator to process and set_weights + await asyncio.wait_for(validator.set_weights.wait(), 60) + break + except asyncio.TimeoutError: + if max_attempt > 0: + max_attempt -= 1 + continue + raise # wait one tempo (fast block subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuid)) From 161d1465cacd2958bca36777c73137a61b36b6a7 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 22:52:50 -0700 Subject: [PATCH 102/150] increase wait time for `test_commit_weights.py` --- tests/e2e_tests/test_commit_weights.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 45db49def2..97e680f55c 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -284,7 +284,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall assert success is True # Wait a few blocks - subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuid)) + subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuid) * 2) # Query the WeightCommits storage map for all three salts weight_commits = subtensor.query_module( From 104d709d9671b5c0e50369fb48015fdc059c9cde Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 23:11:44 -0700 Subject: [PATCH 103/150] try speedup, especially py3.13 based tests --- .github/workflows/e2e-subtensor-tests.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 9e3261f569..95f573dc87 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -27,7 +27,7 @@ env: jobs: find-tests: - runs-on: ubuntu-latest + runs-on: SubtensorCI if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} outputs: test-files: ${{ steps.get-tests.outputs.test-files }} @@ -45,7 +45,7 @@ jobs: shell: bash pull-docker-image: - runs-on: ubuntu-latest + runs-on: SubtensorCI steps: - name: Log in to GitHub Container Registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin @@ -63,12 +63,12 @@ jobs: path: subtensor-localnet.tar # Job to run tests in parallel - run: + run-e2e-test: name: ${{ matrix.test-file }} / Python ${{ matrix.python-version }} needs: - find-tests - pull-docker-image - runs-on: ubuntu-latest + runs-on: SubtensorCI timeout-minutes: 45 strategy: fail-fast: false # Allow other matrix jobs to run even if this job fails From a121e5ac198323c60739d89179ebebd9164294e0 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 23:20:43 -0700 Subject: [PATCH 104/150] all tests back and tests :fingers_crossed: :fingers_crossed: --- .github/workflows/e2e-subtensor-tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 95f573dc87..278ecbeaee 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -38,9 +38,9 @@ jobs: - name: Find test files id: get-tests run: | - # test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + 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_(incentive|commit_weights|set_weights)\.py$' | jq -R -s -c 'split("\n") | map(select(. != ""))') echo "::set-output name=test-files::$test_files" shell: bash From 77c53215887d75f6e8b1af73771598246b901ccf Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 9 Apr 2025 23:28:15 -0700 Subject: [PATCH 105/150] oops with CRv3 --- tests/e2e_tests/test_commit_reveal_v3.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e_tests/test_commit_reveal_v3.py b/tests/e2e_tests/test_commit_reveal_v3.py index 6d45cbd94d..71dde62f79 100644 --- a/tests/e2e_tests/test_commit_reveal_v3.py +++ b/tests/e2e_tests/test_commit_reveal_v3.py @@ -96,7 +96,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle # Fetch current block and calculate next tempo for the subnet current_block = subtensor.get_current_block() - upcoming_tempo = next_tempo(current_block, tempo, netuid) + upcoming_tempo = next_tempo(current_block, tempo) logging.console.info( f"Checking if window is too low with Current block: {current_block}, next tempo: {upcoming_tempo}" ) @@ -114,7 +114,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle ) current_block = subtensor.get_current_block() latest_drand_round = subtensor.last_drand_round() - upcoming_tempo = next_tempo(current_block, tempo, netuid) + 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}" ) @@ -142,7 +142,7 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle current_block = subtensor.get_current_block() latest_drand_round = subtensor.last_drand_round() - upcoming_tempo = next_tempo(current_block, tempo, netuid) + upcoming_tempo = next_tempo(current_block, tempo) logging.console.info( f"After setting weights: Current block: {current_block}, next tempo: {upcoming_tempo}, drand: {latest_drand_round}" ) From f8f5b8959c5d623153e1cde0338a6a93571691e6 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 00:05:34 -0700 Subject: [PATCH 106/150] convert `wait_for_new_nonce` to sync --- tests/e2e_tests/utils/chain_interactions.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index 036000ac8b..940534241e 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -3,6 +3,7 @@ these are not present in btsdk but are required for e2e tests """ +import time import asyncio import contextlib from typing import Union, Optional, TYPE_CHECKING @@ -160,22 +161,25 @@ async def use_and_wait_for_next_nonce( yield - async def wait_for_new_nonce(): + def wait_for_new_nonce(): + now = time.time() while nonce == subtensor.substrate.get_account_next_index( wallet.hotkey.ss58_address ): + if time.time() - now > timeout: + raise TimeoutError(f"Timeout waiting for new nonce.") logging.console.info( f"Waiting for new nonce. Current nonce: {nonce} for wallet {wallet.hotkey.ss58_address}" ) - await asyncio.sleep(sleep) + time.sleep(sleep) # give the chain 3 tries to reveal a new nonce after latest extrinsic call max_retries = 3 for attempt in range(max_retries): try: - await asyncio.wait_for(wait_for_new_nonce(), timeout) + wait_for_new_nonce() break - except asyncio.TimeoutError: + except TimeoutError: logging.warning(f"Attempt {attempt + 1} of {max_retries} timed out.") if attempt + 1 == max_retries: raise From ed39a0f3aeb3a7d52812c18ffa5cb50ce7bafd8a Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 00:12:31 -0700 Subject: [PATCH 107/150] =?UTF-8?q?ubuntu-latest=20is=20faster=20?= =?UTF-8?q?=F0=9F=8F=8E=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/e2e-subtensor-tests.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 278ecbeaee..bf57be4684 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -27,7 +27,7 @@ env: jobs: find-tests: - runs-on: SubtensorCI + runs-on: ubuntu-latest if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} outputs: test-files: ${{ steps.get-tests.outputs.test-files }} @@ -45,7 +45,7 @@ jobs: shell: bash pull-docker-image: - runs-on: SubtensorCI + runs-on: ubuntu-latest steps: - name: Log in to GitHub Container Registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin @@ -68,7 +68,7 @@ jobs: needs: - find-tests - pull-docker-image - runs-on: SubtensorCI + runs-on: ubuntu-latest timeout-minutes: 45 strategy: fail-fast: false # Allow other matrix jobs to run even if this job fails From 164d275778b79a2d1362ccc164033afa57345038 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 01:00:29 -0700 Subject: [PATCH 108/150] test_commit_reveal_v3.py -> fast block correction --- tests/e2e_tests/test_commit_reveal_v3.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/e2e_tests/test_commit_reveal_v3.py b/tests/e2e_tests/test_commit_reveal_v3.py index 71dde62f79..284dd4f192 100644 --- a/tests/e2e_tests/test_commit_reveal_v3.py +++ b/tests/e2e_tests/test_commit_reveal_v3.py @@ -177,6 +177,9 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle f"Latest drand round after waiting for tempo: {latest_drand_round}" ) + # for fast-block 3 seconds (drand round period) is 12 fast blocks. Let's make sure this round passed. + subtensor.wait_for_block(subtensor.block + 12) + # Fetch weights on the chain as they should be revealed now revealed_weights_ = subtensor.weights(netuid=netuid) From 8d3b23770231e6f3389540feee13543dedc25f62 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 01:26:31 -0700 Subject: [PATCH 109/150] debug subtensor.set_weights regarding nonce --- tests/e2e_tests/test_commit_weights.py | 24 ++++++++++++++++++++---- tests/e2e_tests/test_set_weights.py | 2 +- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 97e680f55c..639d81eaa1 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -1,5 +1,5 @@ import asyncio - +from bittensor.utils.btlogging import logging import numpy as np import pytest @@ -239,6 +239,11 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall salt3 = salt.copy() salt3[0] += 2 # Increment the first byte to produce a different commit hash + subtensor.wait_for_block(subtensor.block + 4) + logging.console.info( + f"Nonce for first set weights: {subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}" + ) + # Commit all three salts async with use_and_wait_for_next_nonce(subtensor, alice_wallet, 2.5): success, message = subtensor.commit_weights( @@ -247,13 +252,16 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall salt=salt, uids=weight_uids, weights=weight_vals, - wait_for_inclusion=False, # Don't wait for inclusion, we are testing the nonce when there is a tx in the pool + wait_for_inclusion=True, # Don't wait for inclusion, we are testing the nonce when there is a tx in the pool wait_for_finalization=False, ) assert success is True subtensor.wait_for_block(subtensor.block + 4) + logging.console.info( + f"Nonce for second set weights: {subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}" + ) async with use_and_wait_for_next_nonce(subtensor, alice_wallet, 2.5): success, message = subtensor.commit_weights( @@ -262,13 +270,16 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall salt=salt2, uids=weight_uids, weights=weight_vals, - wait_for_inclusion=False, + wait_for_inclusion=True, wait_for_finalization=False, ) assert success is True subtensor.wait_for_block(subtensor.block + 4) + logging.console.info( + f"Nonce for third set weights: {subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}" + ) async with use_and_wait_for_next_nonce(subtensor, alice_wallet, 2.5): success, message = subtensor.commit_weights( @@ -277,12 +288,17 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall salt=salt3, uids=weight_uids, weights=weight_vals, - wait_for_inclusion=False, + wait_for_inclusion=True, wait_for_finalization=False, ) assert success is True + subtensor.wait_for_block(subtensor.block + 4) + logging.console.info( + f"Nonce after third set weights: {subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}" + ) + # Wait a few blocks subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuid) * 2) diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 4aa46da30f..7afc149b9c 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -135,7 +135,7 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) netuid, uids=weight_uids, weights=weight_vals, - wait_for_inclusion=False, # Don't wait for inclusion, we are testing the nonce when there is a tx in the pool + wait_for_inclusion=True, # Don't wait for inclusion, we are testing the nonce when there is a tx in the pool wait_for_finalization=False, period=subnet_tempo, ) From da6d17f5d95f275fa07def55bbd185878144b55c Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 01:50:24 -0700 Subject: [PATCH 110/150] convert `use_and_wait_for_next_nonce` to decorator and add retry to calls --- tests/e2e_tests/test_commit_weights.py | 59 +++++------------ tests/e2e_tests/test_set_weights.py | 35 +++++----- tests/e2e_tests/utils/chain_interactions.py | 73 +++++++++++---------- 3 files changed, 72 insertions(+), 95 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 639d81eaa1..014746491a 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -1,13 +1,13 @@ -import asyncio -from bittensor.utils.btlogging import logging import numpy as np import pytest +import retry +from bittensor.utils.btlogging import logging 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, - use_and_wait_for_next_nonce, + execute_and_wait_for_next_nonce, wait_epoch, ) @@ -244,55 +244,26 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall f"Nonce for first set weights: {subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}" ) - # Commit all three salts - async with use_and_wait_for_next_nonce(subtensor, alice_wallet, 2.5): - success, message = subtensor.commit_weights( - alice_wallet, - netuid, - salt=salt, - uids=weight_uids, - weights=weight_vals, - wait_for_inclusion=True, # Don't wait for inclusion, we are testing the nonce when there is a tx in the pool - wait_for_finalization=False, - ) - - assert success is True - - subtensor.wait_for_block(subtensor.block + 4) - logging.console.info( - f"Nonce for second set weights: {subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}" - ) - - async with use_and_wait_for_next_nonce(subtensor, alice_wallet, 2.5): + # 3 time doing call if nonce wasn't updated, then raise error + @retry.retry(exceptions=TimeoutError, tries=3, delay=1) + @execute_and_wait_for_next_nonce(subtensor=subtensor, wallet=alice_wallet) + def send_commit(solt): success, message = subtensor.commit_weights( - alice_wallet, - netuid, - salt=salt2, + wallet=alice_wallet, + netuid=netuid, + salt=solt, uids=weight_uids, weights=weight_vals, - wait_for_inclusion=True, + wait_for_inclusion=False, wait_for_finalization=False, ) + assert success is True and message is None, message - assert success is True - - subtensor.wait_for_block(subtensor.block + 4) - logging.console.info( - f"Nonce for third set weights: {subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}" - ) + send_commit(solt=salt) - async with use_and_wait_for_next_nonce(subtensor, alice_wallet, 2.5): - success, message = subtensor.commit_weights( - alice_wallet, - netuid, - salt=salt3, - uids=weight_uids, - weights=weight_vals, - wait_for_inclusion=True, - wait_for_finalization=False, - ) + send_commit(solt=salt2) - assert success is True + send_commit(solt=salt3) subtensor.wait_for_block(subtensor.block + 4) logging.console.info( diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 7afc149b9c..b5062d38ec 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -1,7 +1,6 @@ -import time - import numpy as np import pytest +import retry from bittensor.utils.balance import Balance from bittensor.utils.btlogging import logging @@ -9,7 +8,7 @@ from tests.e2e_tests.utils.chain_interactions import ( sudo_set_hyperparameter_bool, sudo_set_admin_utils, - use_and_wait_for_next_nonce, + execute_and_wait_for_next_nonce, ) @@ -127,22 +126,24 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) uids=uids, weights=weights ) + # 3 time doing call if nonce wasn't updated, then raise error + @retry.retry(exceptions=TimeoutError, tries=3, delay=1) + @execute_and_wait_for_next_nonce(subtensor=subtensor, wallet=alice_wallet) + def set_weights(netuid_): + success, message = subtensor.set_weights( + wallet=alice_wallet, + netuid=netuid_, + uids=weight_uids, + weights=weight_vals, + wait_for_inclusion=False, + wait_for_finalization=False, + period=subnet_tempo, + ) + assert success is True, message + # Set weights for each subnet for netuid in netuids: - async with use_and_wait_for_next_nonce(subtensor, alice_wallet, BLOCK_TIME): - success, message = subtensor.set_weights( - alice_wallet, - netuid, - uids=weight_uids, - weights=weight_vals, - wait_for_inclusion=True, # Don't wait for inclusion, we are testing the nonce when there is a tx in the pool - wait_for_finalization=False, - period=subnet_tempo, - ) - - assert success is True, message - subtensor.wait_for_block(subtensor.block + 4) - logging.console.success(f"Set weights for subnet {netuid}") + set_weights(netuid) subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuids[-1])) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index 940534241e..2a4751c398 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -3,9 +3,9 @@ these are not present in btsdk but are required for e2e tests """ -import time import asyncio -import contextlib +import functools +import time from typing import Union, Optional, TYPE_CHECKING from bittensor.utils.balance import Balance @@ -146,44 +146,49 @@ async def wait_interval( ) -@contextlib.asynccontextmanager -async def use_and_wait_for_next_nonce( - subtensor: "Subtensor", - wallet: "Wallet", - sleep: float = 0.25, - timeout: float = 60.0, +def execute_and_wait_for_next_nonce( + subtensor, wallet, sleep=0.25, timeout=60.0, max_retries=3 ): """ - ContextManager that makes sure the Nonce has been consumed after sending Extrinsic. + Decorator that ensures the nonce has been consumed after a blockchain extrinsic call. """ - nonce = subtensor.substrate.get_account_next_index(wallet.hotkey.ss58_address) + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + for attempt in range(max_retries): + start_nonce = subtensor.substrate.get_account_next_index( + wallet.hotkey.ss58_address + ) - yield + result = func(*args, **kwargs) - def wait_for_new_nonce(): - now = time.time() - while nonce == subtensor.substrate.get_account_next_index( - wallet.hotkey.ss58_address - ): - if time.time() - now > timeout: - raise TimeoutError(f"Timeout waiting for new nonce.") - logging.console.info( - f"Waiting for new nonce. Current nonce: {nonce} for wallet {wallet.hotkey.ss58_address}" - ) - time.sleep(sleep) - - # give the chain 3 tries to reveal a new nonce after latest extrinsic call - max_retries = 3 - for attempt in range(max_retries): - try: - wait_for_new_nonce() - break - except TimeoutError: - logging.warning(f"Attempt {attempt + 1} of {max_retries} timed out.") - if attempt + 1 == max_retries: - raise - await asyncio.sleep(sleep) + start_time = time.time() + + while time.time() - start_time < timeout: + current_nonce = subtensor.substrate.get_account_next_index( + wallet.hotkey.ss58_address + ) + + if current_nonce != start_nonce: + logging.info( + f"✅ Nonce changed from {start_nonce} to {current_nonce}" + ) + return result + + logging.info( + f"⏳ Waiting for nonce increment. Current: {current_nonce}" + ) + time.sleep(sleep) + + logging.warning( + f"⚠️ Attempt {attempt + 1}/{max_retries}: Nonce did not increment." + ) + raise TimeoutError(f"❌ Nonce did not change after {max_retries} attempts.") + + return wrapper + + return decorator # Helper to execute sudo wrapped calls on the chain From 8ac2b52155fa661ba80c0beca82c5a16796cc976 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 02:02:03 -0700 Subject: [PATCH 111/150] fix assertion --- tests/e2e_tests/test_commit_weights.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 014746491a..8e085a7329 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -257,7 +257,7 @@ def send_commit(solt): wait_for_inclusion=False, wait_for_finalization=False, ) - assert success is True and message is None, message + assert success is True, message send_commit(solt=salt) From 64b40a53e20d0a5d057b16b9f1c621a25e7189a8 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 02:09:53 -0700 Subject: [PATCH 112/150] pass `wait_for_inclusion=True` - we have to be make sure with multiple calls (polkadot recommended) --- tests/e2e_tests/test_commit_weights.py | 2 +- tests/e2e_tests/test_set_weights.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 8e085a7329..94112373a3 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -254,7 +254,7 @@ def send_commit(solt): salt=solt, uids=weight_uids, weights=weight_vals, - wait_for_inclusion=False, + wait_for_inclusion=True, wait_for_finalization=False, ) assert success is True, message diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index b5062d38ec..315258bf27 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -135,7 +135,7 @@ def set_weights(netuid_): netuid=netuid_, uids=weight_uids, weights=weight_vals, - wait_for_inclusion=False, + wait_for_inclusion=True, wait_for_finalization=False, period=subnet_tempo, ) From b3d2efa5b303338f0b23d4668a5a5d0390e3a3ee Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 02:27:20 -0700 Subject: [PATCH 113/150] =?UTF-8?q?cleanup=20+=20debug=20=E2=9C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/e2e_tests/test_commit_weights.py | 8 ++++---- tests/e2e_tests/test_set_weights.py | 12 ++++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 94112373a3..e2c8bba8cb 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -239,9 +239,9 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall salt3 = salt.copy() salt3[0] += 2 # Increment the first byte to produce a different commit hash - subtensor.wait_for_block(subtensor.block + 4) logging.console.info( - f"Nonce for first set weights: {subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}" + f"[orange]Nonce before first commit_weights: " + f"{subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}[/orange]" ) # 3 time doing call if nonce wasn't updated, then raise error @@ -265,9 +265,9 @@ def send_commit(solt): send_commit(solt=salt3) - subtensor.wait_for_block(subtensor.block + 4) logging.console.info( - f"Nonce after third set weights: {subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}" + f"[orange]Nonce after third commit_weights: " + f"{subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}[/orange]" ) # Wait a few blocks diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index 315258bf27..f1f1996c24 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -126,6 +126,11 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) uids=uids, weights=weights ) + logging.console.info( + f"[orange]Nonce before first set_weights: " + f"{subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}[/orange]" + ) + # 3 time doing call if nonce wasn't updated, then raise error @retry.retry(exceptions=TimeoutError, tries=3, delay=1) @execute_and_wait_for_next_nonce(subtensor=subtensor, wallet=alice_wallet) @@ -141,12 +146,15 @@ def set_weights(netuid_): ) assert success is True, message + logging.console.info( + f"[orange]Nonce after second set_weights: " + f"{subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}[/orange]" + ) + # Set weights for each subnet for netuid in netuids: set_weights(netuid) - subtensor.wait_for_block(subtensor.block + subtensor.tempo(netuids[-1])) - for netuid in netuids: # Query the Weights storage map for all three subnets query = subtensor.query_module( From 7c6ae27d444a56912bc676c070a19030bd8d8223 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 02:29:31 -0700 Subject: [PATCH 114/150] cover all type exceptions with decorator. anyway they come to the log --- tests/e2e_tests/test_commit_weights.py | 2 +- tests/e2e_tests/test_set_weights.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index e2c8bba8cb..ca2190d71d 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -245,7 +245,7 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall ) # 3 time doing call if nonce wasn't updated, then raise error - @retry.retry(exceptions=TimeoutError, tries=3, delay=1) + @retry.retry(exceptions=Exception, tries=3, delay=1) @execute_and_wait_for_next_nonce(subtensor=subtensor, wallet=alice_wallet) def send_commit(solt): success, message = subtensor.commit_weights( diff --git a/tests/e2e_tests/test_set_weights.py b/tests/e2e_tests/test_set_weights.py index f1f1996c24..2ea6305099 100644 --- a/tests/e2e_tests/test_set_weights.py +++ b/tests/e2e_tests/test_set_weights.py @@ -132,7 +132,7 @@ async def test_set_weights_uses_next_nonce(local_chain, subtensor, alice_wallet) ) # 3 time doing call if nonce wasn't updated, then raise error - @retry.retry(exceptions=TimeoutError, tries=3, delay=1) + @retry.retry(exceptions=Exception, tries=3, delay=1) @execute_and_wait_for_next_nonce(subtensor=subtensor, wallet=alice_wallet) def set_weights(netuid_): success, message = subtensor.set_weights( From dfb77b2028116f7413caf756f96711039cd06935 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Thu, 10 Apr 2025 17:13:57 +0200 Subject: [PATCH 115/150] Adds compatibility for torch 2.6.0+ --- bittensor/core/metagraph.py | 29 +++++++++++++++++++++++++++-- pyproject.toml | 4 ++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/bittensor/core/metagraph.py b/bittensor/core/metagraph.py index 5554b32a3d..4f829a52c8 100644 --- a/bittensor/core/metagraph.py +++ b/bittensor/core/metagraph.py @@ -1,4 +1,5 @@ import asyncio +import contextlib import copy import os import pickle @@ -11,6 +12,7 @@ import numpy as np from async_substrate_interface.errors import SubstrateRequestException from numpy.typing import NDArray +from packaging import version from bittensor.core import settings from bittensor.core.chain_data import ( @@ -143,6 +145,27 @@ def latest_block_path(dir_path: str) -> str: return latest_file_full_path +def safe_globals(): + """ + Context manager to load torch files for version 2.6+ + """ + if version.parse(torch.__version__).release < version.parse("2.6").release: + return contextlib.nullcontext() + + np_core = ( + np._core if version.parse(np.__version__) >= version.parse("2.0.0") else np.core + ) + allow_list = [ + np_core.multiarray._reconstruct, + np.ndarray, + np.dtype, + type(np.dtype(np.uint32)), + np.dtypes.Float32DType, + bytes, + ] + return torch.serialization.safe_globals(allow_list) + + class MetagraphMixin(ABC): """ The metagraph class is a core component of the Bittensor network, representing the neural graph that forms the @@ -1124,7 +1147,8 @@ def load_from_path(self, dir_path: str) -> "MetagraphMixin": """ graph_file = latest_block_path(dir_path) - state_dict = torch.load(graph_file) + with safe_globals(): + state_dict = torch.load(graph_file, weights_only=True) self.n = torch.nn.Parameter(state_dict["n"], requires_grad=False) self.block = torch.nn.Parameter(state_dict["block"], requires_grad=False) self.uids = torch.nn.Parameter(state_dict["uids"], requires_grad=False) @@ -1256,7 +1280,8 @@ def load_from_path(self, dir_path: str) -> "MetagraphMixin": try: import torch as real_torch - state_dict = real_torch.load(graph_filename) + with safe_globals(): + state_dict = real_torch.load(graph_filename) for key in METAGRAPH_STATE_DICT_NDARRAY_KEYS: state_dict[key] = state_dict[key].detach().numpy() del real_torch diff --git a/pyproject.toml b/pyproject.toml index 2232e33960..612bf7e150 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,10 +59,10 @@ dev = [ "aioresponses==0.7.6", "factory-boy==3.3.0", "types-requests", - "torch>=1.13.1,<2.6.0" + "torch>=1.13.1,<3.0" ] torch = [ - "torch>=1.13.1,<2.6.0" + "torch>=1.13.1,<3.0" ] cli = [ "bittensor-cli>=9.0.2" From 633783ee0eb5cc0ff615d9e8befe4548287bb74d Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Thu, 10 Apr 2025 17:14:45 +0200 Subject: [PATCH 116/150] Adds compatibility for torch 2.6.0+ --- bittensor/core/metagraph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/core/metagraph.py b/bittensor/core/metagraph.py index 4f829a52c8..af758939ea 100644 --- a/bittensor/core/metagraph.py +++ b/bittensor/core/metagraph.py @@ -1148,7 +1148,7 @@ def load_from_path(self, dir_path: str) -> "MetagraphMixin": graph_file = latest_block_path(dir_path) with safe_globals(): - state_dict = torch.load(graph_file, weights_only=True) + state_dict = torch.load(graph_file) self.n = torch.nn.Parameter(state_dict["n"], requires_grad=False) self.block = torch.nn.Parameter(state_dict["block"], requires_grad=False) self.uids = torch.nn.Parameter(state_dict["uids"], requires_grad=False) From 7a041869ab6ed0dcc6155225d1fb6edf04bdd237 Mon Sep 17 00:00:00 2001 From: Roman <167799377+basfroman@users.noreply.github.com> Date: Thu, 10 Apr 2025 10:55:50 -0700 Subject: [PATCH 117/150] Update bittensor/core/async_subtensor.py Co-authored-by: BD Himes <37844818+thewhaleking@users.noreply.github.com> --- bittensor/core/async_subtensor.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bittensor/core/async_subtensor.py b/bittensor/core/async_subtensor.py index 4786e30375..de5184df12 100644 --- a/bittensor/core/async_subtensor.py +++ b/bittensor/core/async_subtensor.py @@ -1712,11 +1712,11 @@ async def get_next_epoch_start_block( Returns: int: The block number at which the next epoch will start. """ - block = block or await self.block - block_hash = block_hash or await self.get_block_hash(block) - tempo = await self.tempo( - netuid=netuid, block=block, block_hash=block_hash, reuse_block=reuse_block - ) + block_hash = await self.determine_block_hash(block, block_hash, reuse_block) + if not block_hash and reuse_block: + block_hash = self.substrate.last_block_hash + block = await self.substrate.get_block_number(block_hash=block_hash) + tempo = await self.tempo(netuid=netuid, block_hash=block_hash) return (((block // tempo) + 1) * tempo) + 1 if tempo else None async def get_owned_hotkeys( From 977966e1230a45786413fd6b6e2404184243b694 Mon Sep 17 00:00:00 2001 From: Roman <167799377+basfroman@users.noreply.github.com> Date: Thu, 10 Apr 2025 10:55:59 -0700 Subject: [PATCH 118/150] Update bittensor/core/subtensor.py Co-authored-by: BD Himes <37844818+thewhaleking@users.noreply.github.com> --- bittensor/core/subtensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/core/subtensor.py b/bittensor/core/subtensor.py index ee313c9c85..bcebfae212 100644 --- a/bittensor/core/subtensor.py +++ b/bittensor/core/subtensor.py @@ -1319,7 +1319,7 @@ def get_next_epoch_start_block( int: The block number at which the next epoch will start. """ block = block or self.block - tempo = self.tempo(netuid=netuid) + tempo = self.tempo(netuid=netuid, block=block) return (((block // tempo) + 1) * tempo) + 1 if tempo else None def get_owned_hotkeys( From bf0215032dcf03af45da804e74443ff12bbf6c94 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 11:14:50 -0700 Subject: [PATCH 119/150] add debug in case UnknownError to format_error_message --- bittensor/utils/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index e0da1d9c99..a0f429c129 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -250,6 +250,10 @@ def format_error_message(error_message: Union[dict, Exception]) -> str: err_docs = error_message.get("docs", [err_description]) err_description = err_docs[0] if err_docs else err_description + logging.debug( + f"String representation of real error_message: {str(error_message)}" + ) + return f"Subtensor returned `{err_name}({err_type})` error. This means: `{err_description}`." From c0b9c379d854323dafded6a83be30222003491a2 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 11:15:12 -0700 Subject: [PATCH 120/150] fix typo --- tests/e2e_tests/test_commit_weights.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index ca2190d71d..b51e60b310 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -247,23 +247,23 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall # 3 time doing call if nonce wasn't updated, then raise error @retry.retry(exceptions=Exception, tries=3, delay=1) @execute_and_wait_for_next_nonce(subtensor=subtensor, wallet=alice_wallet) - def send_commit(solt): + def send_commit(salt_): success, message = subtensor.commit_weights( wallet=alice_wallet, netuid=netuid, - salt=solt, + salt=salt_, uids=weight_uids, weights=weight_vals, wait_for_inclusion=True, - wait_for_finalization=False, + wait_for_finalization=True, ) assert success is True, message - send_commit(solt=salt) + send_commit(salt=salt) - send_commit(solt=salt2) + send_commit(salt=salt2) - send_commit(solt=salt3) + send_commit(salt=salt3) logging.console.info( f"[orange]Nonce after third commit_weights: " From a3fff164562327bd7c228722e0ba8e9c79522400 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Thu, 10 Apr 2025 20:22:37 +0200 Subject: [PATCH 121/150] Update requiresments/torch.txt file --- requirements/torch.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/torch.txt b/requirements/torch.txt index 1abaa00adc..07a6bcf5aa 100644 --- a/requirements/torch.txt +++ b/requirements/torch.txt @@ -1 +1 @@ -torch>=1.13.1,<2.6.0 +torch>=1.13.1,<3.0 From 10df0c27b0d7be1d8b7f21bef972421daf1624c7 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 11:26:05 -0700 Subject: [PATCH 122/150] argument --- tests/e2e_tests/test_commit_weights.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index b51e60b310..e29ca030d3 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -259,11 +259,11 @@ def send_commit(salt_): ) assert success is True, message - send_commit(salt=salt) + send_commit(salt) - send_commit(salt=salt2) + send_commit(salt2) - send_commit(salt=salt3) + send_commit(salt3) logging.console.info( f"[orange]Nonce after third commit_weights: " From 40476b1b4a38fd251614b695b1133805dbda2a83 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Thu, 10 Apr 2025 20:48:57 +0200 Subject: [PATCH 123/150] Remove requirements directory, change workflows to not use this. --- .circleci/config.yml | 26 +------------------------- .github/dependabot.yml | 2 +- pyproject.toml | 5 +++++ requirements/cli.txt | 1 - requirements/cubit.txt | 3 --- requirements/dev.txt | 19 ------------------- requirements/prod.txt | 26 -------------------------- requirements/torch.txt | 1 - 8 files changed, 7 insertions(+), 76 deletions(-) delete mode 100644 requirements/cli.txt delete mode 100644 requirements/cubit.txt delete mode 100644 requirements/dev.txt delete mode 100644 requirements/prod.txt delete mode 100644 requirements/torch.txt diff --git a/.circleci/config.yml b/.circleci/config.yml index fbe39a6645..c82193472c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -39,7 +39,7 @@ jobs: python -m venv .venv . .venv/bin/activate python -m pip install --upgrade uv - uv pip install ruff -c requirements/dev.txt + uv pip install ruff - save_cache: name: Save cached ruff venv @@ -87,12 +87,6 @@ jobs: steps: - checkout - - restore_cache: - name: Restore cached venv - keys: - - v2-pypi-py<< parameters.python-version >>-{{ checksum "requirements/prod.txt" }}+{{ checksum "requirements/dev.txt" }} - - v2-pypi-py<< parameters.python-version >> - - run: name: Update & Activate venv command: | @@ -101,12 +95,6 @@ jobs: python -m pip install --upgrade uv uv sync --all-extras --dev - - save_cache: - name: Save cached venv - paths: - - "venv/" - key: v2-pypi-py<< parameters.python-version >>-{{ checksum "requirements/prod.txt" }}+{{ checksum "requirements/dev.txt" }} - - run: name: Install Bittensor command: | @@ -178,12 +166,6 @@ jobs: steps: - checkout - - restore_cache: - name: Restore cached venv - keys: - - v2-pypi-py<< parameters.python-version >>-{{ checksum "requirements/prod.txt" }}+{{ checksum "requirements/dev.txt" }} - - v2-pypi-py<< parameters.python-version >> - - run: name: Update & Activate venv command: | @@ -193,12 +175,6 @@ jobs: uv sync --all-extras --dev uv pip install flake8 - - save_cache: - name: Save cached venv - paths: - - "env/" - key: v2-pypi-py<< parameters.python-version >>-{{ checksum "requirements/prod.txt" }}+{{ checksum "requirements/dev.txt" }} - - run: name: Install Bittensor command: | diff --git a/.github/dependabot.yml b/.github/dependabot.yml index adff4d0aab..190e4cd6c5 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -2,7 +2,7 @@ version: 2 updates: - package-ecosystem: "pip" directory: "" - file: "requirements/prod.txt" + file: "pyproject.toml" schedule: interval: "daily" open-pull-requests-limit: 0 # Only security updates will be opened as PRs diff --git a/pyproject.toml b/pyproject.toml index 2232e33960..19a5ffaa6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,6 +67,11 @@ torch = [ cli = [ "bittensor-cli>=9.0.2" ] +cubit = [ + "torch>=1.13.1,<3.0", + "cubit @ git+https://github.com/opentensor/cubit.git@v1.1.2" +] + [project.urls] # more details can be found here diff --git a/requirements/cli.txt b/requirements/cli.txt deleted file mode 100644 index e395b2b9c1..0000000000 --- a/requirements/cli.txt +++ /dev/null @@ -1 +0,0 @@ -bittensor-cli>=9.0.2 \ No newline at end of file diff --git a/requirements/cubit.txt b/requirements/cubit.txt deleted file mode 100644 index 5af1316836..0000000000 --- a/requirements/cubit.txt +++ /dev/null @@ -1,3 +0,0 @@ -torch>=1.13.1 -cubit>=1.1.0 -cubit @ git+https://github.com/opentensor/cubit.git diff --git a/requirements/dev.txt b/requirements/dev.txt deleted file mode 100644 index 77e21b0eeb..0000000000 --- a/requirements/dev.txt +++ /dev/null @@ -1,19 +0,0 @@ -pytest==7.2.0 -pytest-asyncio==0.23.7 -pytest-mock==3.12.0 -pytest-split==0.8.0 -pytest-xdist==3.0.2 -pytest-rerunfailures==10.2 -coveralls==3.3.1 -pytest-cov==4.0.0 -ddt==1.6.0 -hypothesis==6.81.1 -flake8==7.0.0 -mypy==1.8.0 -types-retry==0.9.9.4 -freezegun==1.5.0 -httpx==0.27.0 -ruff==0.4.7 -aioresponses==0.7.6 -factory-boy==3.3.0 -types-requests \ No newline at end of file diff --git a/requirements/prod.txt b/requirements/prod.txt deleted file mode 100644 index 893d925ce9..0000000000 --- a/requirements/prod.txt +++ /dev/null @@ -1,26 +0,0 @@ -wheel -setuptools~=70.0.0 -aiohttp~=3.9 -asyncstdlib~=3.13.0 -colorama~=0.4.6 -fastapi~=0.110.1 -munch~=2.5.0 -numpy~=2.0.1 -msgpack-numpy-opentensor~=0.5.0 -nest_asyncio -netaddr -packaging -python-statemachine~=2.1 -pycryptodome>=3.18.0,<4.0.0 -pyyaml -retry -requests -rich -pydantic>=2.3, <3 -python-Levenshtein -scalecodec==1.2.11 -uvicorn -websockets>=14.1 -bittensor-commit-reveal>=0.3.1 -bittensor-wallet>=3.0.7 -async-substrate-interface>=1.0.4 diff --git a/requirements/torch.txt b/requirements/torch.txt deleted file mode 100644 index 1abaa00adc..0000000000 --- a/requirements/torch.txt +++ /dev/null @@ -1 +0,0 @@ -torch>=1.13.1,<2.6.0 From 74b5a1fce388f321c6503a8d80e11e01266e0888 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Thu, 10 Apr 2025 21:09:29 +0200 Subject: [PATCH 124/150] Update uv sync to not install cubit --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index c74c5fadfe..26082029aa 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -89,7 +89,7 @@ jobs: uses: astral-sh/setup-uv@v4 - name: install dependencies - run: uv sync --all-extras --dev + run: uv sync --extra dev --extra torch --dev - name: Download Cached Docker Image uses: actions/download-artifact@v4 From 3b5845e418985223102df37a0a35f63c144c1d94 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 12:31:24 -0700 Subject: [PATCH 125/150] bumping pytest* version --- pyproject.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 101402e46e..686fad4301 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,11 +40,11 @@ dependencies = [ [project.optional-dependencies] dev = [ - "pytest==7.2.0", - "pytest-asyncio==0.23.7", - "pytest-mock==3.12.0", - "pytest-split==0.8.0", - "pytest-xdist==3.0.2", + "pytest==8.3.5", + "pytest-asyncio==0.26.0", + "pytest-mock==3.14.0", + "pytest-split==0.10.0", + "pytest-xdist==3.6.1", "pytest-rerunfailures==10.2", "coveralls==3.3.1", "pytest-cov==4.0.0", From d5737445214538e867af37ec86fa56350570a5c4 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 12:31:44 -0700 Subject: [PATCH 126/150] extend logic of `format_error_message` --- bittensor/utils/__init__.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index a0f429c129..5bf302431b 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -250,9 +250,15 @@ def format_error_message(error_message: Union[dict, Exception]) -> str: err_docs = error_message.get("docs", [err_description]) err_description = err_docs[0] if err_docs else err_description - logging.debug( - f"String representation of real error_message: {str(error_message)}" - ) + elif error_message.get("code") and error_message.get("message"): + err_type = "Custom type" + err_name = error_message.get("code", err_name) + err_description = error_message.get("message", err_description) + + else: + logging.error( + f"String representation of real error_message: {str(error_message)}" + ) return f"Subtensor returned `{err_name}({err_type})` error. This means: `{err_description}`." From 66e4f6a3c262025a54376f1df102ea4e8b6833f6 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Thu, 10 Apr 2025 21:36:08 +0200 Subject: [PATCH 127/150] Fix extras --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c82193472c..82ec57fedb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -93,13 +93,13 @@ jobs: python -m venv .venv . .venv/bin/activate python -m pip install --upgrade uv - uv sync --all-extras --dev + uv sync --extra dev --extra torch --dev - run: name: Install Bittensor command: | . .venv/bin/activate - uv sync --all-extras --dev + uv sync --extra dev --extra torch --dev - run: name: Instantiate Mock Wallet @@ -172,14 +172,14 @@ jobs: python -m venv .venv . .venv/bin/activate python -m pip install --upgrade uv - uv sync --all-extras --dev + uv sync --extra dev --extra torch --dev uv pip install flake8 - run: name: Install Bittensor command: | . .venv/bin/activate - uv sync --all-extras --dev + uv sync --extra dev --extra torch --dev - run: name: Lint with flake8 From 9e1bff957194d7aa51b174bff605ac2a96718e00 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 12:45:44 -0700 Subject: [PATCH 128/150] replace order in format_error_message --- bittensor/utils/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bittensor/utils/__init__.py b/bittensor/utils/__init__.py index 5bf302431b..3d2c82803b 100644 --- a/bittensor/utils/__init__.py +++ b/bittensor/utils/__init__.py @@ -251,8 +251,8 @@ def format_error_message(error_message: Union[dict, Exception]) -> str: err_description = err_docs[0] if err_docs else err_description elif error_message.get("code") and error_message.get("message"): - err_type = "Custom type" - err_name = error_message.get("code", err_name) + err_type = error_message.get("code", err_name) + err_name = "Custom type" err_description = error_message.get("message", err_description) else: From 936214feba773bf16326b154499adb22efb35459 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 13:04:02 -0700 Subject: [PATCH 129/150] extend debug --- tests/e2e_tests/utils/chain_interactions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/utils/chain_interactions.py b/tests/e2e_tests/utils/chain_interactions.py index 2a4751c398..c5871d3155 100644 --- a/tests/e2e_tests/utils/chain_interactions.py +++ b/tests/e2e_tests/utils/chain_interactions.py @@ -171,12 +171,12 @@ def wrapper(*args, **kwargs): ) if current_nonce != start_nonce: - logging.info( + logging.console.info( f"✅ Nonce changed from {start_nonce} to {current_nonce}" ) return result - logging.info( + logging.console.info( f"⏳ Waiting for nonce increment. Current: {current_nonce}" ) time.sleep(sleep) From 86be8ec42addf4d72526dd3f5e0cccc7a27c7637 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Thu, 10 Apr 2025 22:08:00 +0200 Subject: [PATCH 130/150] Limit extras --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 82ec57fedb..d35fe9cc65 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -93,13 +93,13 @@ jobs: python -m venv .venv . .venv/bin/activate python -m pip install --upgrade uv - uv sync --extra dev --extra torch --dev + uv sync --extra dev --dev - run: name: Install Bittensor command: | . .venv/bin/activate - uv sync --extra dev --extra torch --dev + uv sync --extra dev --dev - run: name: Instantiate Mock Wallet @@ -172,14 +172,14 @@ jobs: python -m venv .venv . .venv/bin/activate python -m pip install --upgrade uv - uv sync --extra dev --extra torch --dev + uv sync --extra dev --dev uv pip install flake8 - run: name: Install Bittensor command: | . .venv/bin/activate - uv sync --extra dev --extra torch --dev + uv sync --extra dev --dev - run: name: Lint with flake8 From 0024a194af1974f6d87c7c93b1dc99a40b9f4a85 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 13:32:50 -0700 Subject: [PATCH 131/150] add waiting 1 epoch after setting `weights_rate_limit` --- tests/e2e_tests/test_commit_weights.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index e29ca030d3..dd424e36d0 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -223,6 +223,9 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall ), "Failed to set weights_rate_limit" assert subtensor.weights_rate_limit(netuid=netuid) == 0 + # wait while weights_rate_limit changes applied. + subtensor.wait_for_block(subnet_tempo + 1) + # Commit-reveal values uids = np.array([0], dtype=np.int64) weights = np.array([0.1], dtype=np.float32) From c8a5aff997e4a4a7b2c9498e74d45c4927782310 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 14:24:01 -0700 Subject: [PATCH 132/150] add different weights generator --- tests/e2e_tests/test_commit_weights.py | 47 +++++++++++++------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index dd424e36d0..4468d40288 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -226,21 +226,19 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall # wait while weights_rate_limit changes applied. subtensor.wait_for_block(subnet_tempo + 1) - # Commit-reveal values - uids = np.array([0], dtype=np.int64) - weights = np.array([0.1], dtype=np.float32) - salt = [18, 179, 107, 0, 165, 211, 141, 197] - weight_uids, weight_vals = convert_weights_and_uids_for_emit( - uids=uids, weights=weights - ) - - # Make a second salt - salt2 = salt.copy() - salt2[0] += 1 # Increment the first byte to produce a different commit hash - - # Make a third salt - salt3 = salt.copy() - salt3[0] += 2 # Increment the first byte to produce a different commit hash + # create different commited data to avoid coming into pool black list with the error + # Failed to commit weights: Subtensor returned `Custom type(1012)` error. This means: `Transaction is temporarily + # banned`.Failed to commit weights: Subtensor returned `Custom type(1012)` error. This means: `Transaction is + # temporarily banned`.` + def get_weights_and_salt(counter: int): + # Commit-reveal values + salt_ = [18, 179, 107, counter, 165, 211, 141, 197] + uids_ = np.array([0], dtype=np.int64) + weights_ = np.array([counter / 10], dtype=np.float32) + weight_uids_, weight_vals_ = convert_weights_and_uids_for_emit( + uids=uids_, weights=weights_ + ) + return salt_, weight_uids_, weight_vals_ logging.console.info( f"[orange]Nonce before first commit_weights: " @@ -250,23 +248,24 @@ async def test_commit_weights_uses_next_nonce(local_chain, subtensor, alice_wall # 3 time doing call if nonce wasn't updated, then raise error @retry.retry(exceptions=Exception, tries=3, delay=1) @execute_and_wait_for_next_nonce(subtensor=subtensor, wallet=alice_wallet) - def send_commit(salt_): + def send_commit(salt_, weight_uids_, weight_vals_): success, message = subtensor.commit_weights( wallet=alice_wallet, netuid=netuid, salt=salt_, - uids=weight_uids, - weights=weight_vals, + uids=weight_uids_, + weights=weight_vals_, wait_for_inclusion=True, wait_for_finalization=True, ) assert success is True, message - send_commit(salt) - - send_commit(salt2) + # send some amount of commit weights + AMOUNT_OF_COMMIT_WEIGHTS = 3 + for call in range(AMOUNT_OF_COMMIT_WEIGHTS): + weight_uids, weight_vals, salt = get_weights_and_salt(call) - send_commit(salt3) + send_commit(salt, weight_uids, weight_vals) logging.console.info( f"[orange]Nonce after third commit_weights: " @@ -288,4 +287,6 @@ def send_commit(salt_): assert commit_block > 0, f"Invalid block number: {commit_block}" # Check for three commits in the WeightCommits storage map - assert len(weight_commits.value) == 3, "Expected 3 weight commits" + assert ( + len(weight_commits.value) == AMOUNT_OF_COMMIT_WEIGHTS + ), "Expected exact list of weight commits" From 1427d777538f088bda74cf7557a6813ffd6f1dc1 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 14:45:44 -0700 Subject: [PATCH 133/150] test multiple times 3 tests --- .github/workflows/e2e-subtensor-tests.yaml | 4 ++-- tests/e2e_tests/test_commit_weights.py | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index bf57be4684..2604d69ee3 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -38,9 +38,9 @@ jobs: - name: Find test files id: get-tests run: | - test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + # 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_(incentive|commit_weights|set_weights)\.py$' | jq -R -s -c 'split("\n") | map(select(. != ""))') echo "::set-output name=test-files::$test_files" shell: bash diff --git a/tests/e2e_tests/test_commit_weights.py b/tests/e2e_tests/test_commit_weights.py index 4468d40288..1a9f4c6016 100644 --- a/tests/e2e_tests/test_commit_weights.py +++ b/tests/e2e_tests/test_commit_weights.py @@ -165,7 +165,7 @@ 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 = 100 + subnet_tempo = 50 netuid = 2 # Wait for 2 tempos to pass as CR3 only reveals weights after 2 tempos @@ -267,6 +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) + logging.console.info( f"[orange]Nonce after third commit_weights: " f"{subtensor.substrate.get_account_next_index(alice_wallet.hotkey.ss58_address)}[/orange]" From e7449a8a7093e14b76e8878e8e3ab2bb3b457eeb Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 15:33:28 -0700 Subject: [PATCH 134/150] try short name - works with local runner --- .github/workflows/e2e-subtensor-tests.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 2604d69ee3..e6620ef726 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -64,7 +64,7 @@ jobs: # Job to run tests in parallel run-e2e-test: - name: ${{ matrix.test-file }} / Python ${{ matrix.python-version }} + name: ${{ steps.set-name.outputs.short-name }} / Python ${{ matrix.python-version }} needs: - find-tests - pull-docker-image @@ -79,6 +79,12 @@ jobs: test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: + - name: Set short name + id: set-name + run: | + SHORT_NAME=$(basename "${{ matrix.test-file }}") + echo "short-name=$SHORT_NAME" >> $GITHUB_OUTPUT + - name: Check-out repository uses: actions/checkout@v4 From 8a9e988b2061162d235f42875480232050652900 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 15:38:39 -0700 Subject: [PATCH 135/150] name uses just static names --- .github/workflows/e2e-subtensor-tests.yaml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index e6620ef726..bf57be4684 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -38,9 +38,9 @@ jobs: - name: Find test files id: get-tests run: | - # test_files=$(find tests/e2e_tests -name "test*.py" | jq -R -s -c 'split("\n") | map(select(. != ""))') + 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_(incentive|commit_weights|set_weights)\.py$' | jq -R -s -c 'split("\n") | map(select(. != ""))') echo "::set-output name=test-files::$test_files" shell: bash @@ -64,7 +64,7 @@ jobs: # Job to run tests in parallel run-e2e-test: - name: ${{ steps.set-name.outputs.short-name }} / Python ${{ matrix.python-version }} + name: ${{ matrix.test-file }} / Python ${{ matrix.python-version }} needs: - find-tests - pull-docker-image @@ -79,12 +79,6 @@ jobs: test-file: ${{ fromJson(needs.find-tests.outputs.test-files) }} python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - - name: Set short name - id: set-name - run: | - SHORT_NAME=$(basename "${{ matrix.test-file }}") - echo "short-name=$SHORT_NAME" >> $GITHUB_OUTPUT - - name: Check-out repository uses: actions/checkout@v4 From 5a998bbf431f40bf856615dbc143d02d7e9911be Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 10 Apr 2025 15:55:16 -0700 Subject: [PATCH 136/150] remove specific commit --- tests/e2e_tests/utils/e2e_test_utils.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/e2e_tests/utils/e2e_test_utils.py b/tests/e2e_tests/utils/e2e_test_utils.py index 1ad8001564..1336c66cb4 100644 --- a/tests/e2e_tests/utils/e2e_test_utils.py +++ b/tests/e2e_tests/utils/e2e_test_utils.py @@ -213,9 +213,7 @@ async def _reader(self): self.set_weights.set() def __init__(self): - self.dir = clone_or_update_templates( - specific_commit="92d5bdf1069286d97470362c5c22611aa0fa048c" - ) + self.dir = clone_or_update_templates() def __enter__(self): return self From 8799239375bc4d73b5c193963dde9115a51a8cfc Mon Sep 17 00:00:00 2001 From: sashaphmn Date: Fri, 11 Apr 2025 10:02:19 +0300 Subject: [PATCH 137/150] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1644701d83..8c5165a769 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ## Internet-scale Neural Networks -[Documentation](https://docs.bittensor.com) • [Network](https://taostats.io/) • [Research](https://bittensor.com/whitepaper) +[Discord](https://discord.gg/qasY3HA9F9) • [Network](https://taostats.io/) • [Research](https://bittensor.com/whitepaper) • [Documentation](https://docs.bittensor.com) From 0f7a0eeffa07bacad4bcbf5d5fe1f4be9ada10f7 Mon Sep 17 00:00:00 2001 From: Slava Date: Fri, 11 Apr 2025 09:44:06 +0200 Subject: [PATCH 138/150] f Update CONTRIBUTING.md --- contrib/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/CONTRIBUTING.md b/contrib/CONTRIBUTING.md index b27b426a09..7d7bb3fda0 100644 --- a/contrib/CONTRIBUTING.md +++ b/contrib/CONTRIBUTING.md @@ -252,7 +252,7 @@ Explain the problem and include additional details to help maintainers reproduce * **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior. * **Explain which behavior you expected to see instead and why.** * **Include screenshots and animated GIFs** which show you following the described steps and clearly demonstrate the problem. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. -* **If you're reporting that Bittensor crashed**, include a crash report with a stack trace from the operating system. On macOS, the crash report will be available in `Console.app` under "Diagnostic and usage information" > "User diagnostic reports". Include the crash report in the issue in a [code block](https://help.github.com/articles/markdown-basics/#multiple-lines), a [file attachment](https://help.github.com/articles/file-attachments-on-issues-and-pull-requests/), or put it in a [gist](https://gist.github.com/) and provide link to that gist. +* **If you're reporting that Bittensor crashed**, include a crash report with a stack trace from the operating system. On macOS, the crash report will be available in `Console.app` under "Diagnostic and usage information" > "User diagnostic reports". Include the crash report in the issue in a [code block](https://help.github.com/articles/markdown-basics/#multiple-lines), a [file attachment](https://docs.github.com/articles/file-attachments-on-issues-and-pull-requests/), or put it in a [gist](https://gist.github.com/) and provide link to that gist. * **If the problem is related to performance or memory**, include a CPU profile capture with your report, if you're using a GPU then include a GPU profile capture as well. Look into the [PyTorch Profiler](https://pytorch.org/tutorials/recipes/recipes/profiler_recipe.html) to look at memory usage of your model. * **If the problem wasn't triggered by a specific action**, describe what you were doing before the problem happened and share more information using the guidelines below. From 4c00111363eed612487507f5222ff4afa437e266 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 11 Apr 2025 11:03:30 +0200 Subject: [PATCH 139/150] Update requirements checking. --- .circleci/config.yml | 4 +- scripts/check_compatibility.sh | 76 --------------------------- scripts/check_requirements_changes.sh | 4 +- 3 files changed, 3 insertions(+), 81 deletions(-) delete mode 100755 scripts/check_compatibility.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index d35fe9cc65..a4c1114589 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -68,9 +68,7 @@ jobs: name: Install dependencies and Check compatibility command: | if [ "$REQUIREMENTS_CHANGED" == "true" ]; then - sudo apt-get update - sudo apt-get install -y jq curl - ./scripts/check_compatibility.sh << parameters.python_version >> + python -m pip install ".[dev,cli]" --dry-run --python-version --no-deps << parameters.python.version >> else echo "Skipping compatibility checks..." fi diff --git a/scripts/check_compatibility.sh b/scripts/check_compatibility.sh deleted file mode 100755 index b9c89c24dd..0000000000 --- a/scripts/check_compatibility.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash - -if [ -z "$1" ]; then - echo "Please provide a Python version as an argument." - exit 1 -fi - -python_version="$1" -all_passed=true - -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -RED='\033[0;31m' -NC='\033[0m' # No Color - -check_compatibility() { - all_supported=0 - - while read -r requirement; do - # Skip lines starting with git+ - if [[ "$requirement" == git+* ]]; then - continue - fi - - package_name=$(echo "$requirement" | awk -F'[!=<>~]' '{print $1}' | awk -F'[' '{print $1}') # Strip off brackets - echo -n "Checking $package_name... " - - url="https://pypi.org/pypi/$package_name/json" - response=$(curl -s $url) - status_code=$(curl -s -o /dev/null -w "%{http_code}" $url) - - if [ "$status_code" != "200" ]; then - echo -e "${RED}Information not available for $package_name. Failure.${NC}" - all_supported=1 - continue - fi - - classifiers=$(echo "$response" | jq -r '.info.classifiers[]') - requires_python=$(echo "$response" | jq -r '.info.requires_python') - - base_version="Programming Language :: Python :: ${python_version%%.*}" - specific_version="Programming Language :: Python :: $python_version" - - if echo "$classifiers" | grep -q "$specific_version" || echo "$classifiers" | grep -q "$base_version"; then - echo -e "${GREEN}Supported${NC}" - elif [ "$requires_python" != "null" ]; then - if echo "$requires_python" | grep -Eq "==$python_version|>=$python_version|<=$python_version"; then - echo -e "${GREEN}Supported${NC}" - else - echo -e "${RED}Not compatible with Python $python_version due to constraint $requires_python.${NC}" - all_supported=1 - fi - else - echo -e "${YELLOW}Warning: Specific version not listed, assuming compatibility${NC}" - fi - done < requirements/prod.txt - - return $all_supported -} - -echo "Checking compatibility for Python $python_version..." -check_compatibility -if [ $? -eq 0 ]; then - echo -e "${GREEN}All requirements are compatible with Python $python_version.${NC}" -else - echo -e "${RED}All requirements are NOT compatible with Python $python_version.${NC}" - all_passed=false -fi - -echo "" -if $all_passed; then - echo -e "${GREEN}All tests passed.${NC}" -else - echo -e "${RED}All tests did not pass.${NC}" - exit 1 -fi diff --git a/scripts/check_requirements_changes.sh b/scripts/check_requirements_changes.sh index 5fcd27ea3f..5b41f463c1 100755 --- a/scripts/check_requirements_changes.sh +++ b/scripts/check_requirements_changes.sh @@ -1,8 +1,8 @@ #!/bin/bash # Check if requirements files have changed in the last commit -if git diff --name-only HEAD~1 | grep -E 'requirements/prod.txt|requirements/dev.txt'; then - echo "Requirements files have changed. Running compatibility checks..." +if git diff --name-only HEAD~1 | grep -E 'pyproject.toml'; then + echo "Requirements files may have changed. Running compatibility checks..." echo 'export REQUIREMENTS_CHANGED="true"' >> $BASH_ENV else echo "Requirements files have not changed. Skipping compatibility checks..." From 14936be941b970e63170538b54253b7f2972eeea Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 11 Apr 2025 11:10:21 +0200 Subject: [PATCH 140/150] Typo --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a4c1114589..f19cd338b9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -68,7 +68,7 @@ jobs: name: Install dependencies and Check compatibility command: | if [ "$REQUIREMENTS_CHANGED" == "true" ]; then - python -m pip install ".[dev,cli]" --dry-run --python-version --no-deps << parameters.python.version >> + python -m pip install ".[dev,cli]" --dry-run --python-version --no-deps << parameters.python_version >> else echo "Skipping compatibility checks..." fi From e2d9a3e7af3b61c9b3e5de8f3a8d6a2380f78dbe Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 11 Apr 2025 11:25:02 +0200 Subject: [PATCH 141/150] Test (will be reverted) --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 549dd9b0ab..a441de27ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ authors = [ license = { file = "LICENSE" } requires-python = ">=3.9,<3.14" dependencies = [ + "bt-decode>=0.6.0", "wheel", "setuptools~=70.0.0", "aiohttp~=3.9", From d756fdb08f671e0773907d788af8872eb6271979 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 11 Apr 2025 11:26:59 +0200 Subject: [PATCH 142/150] Typo --- .circleci/config.yml | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f19cd338b9..5677de43b2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -68,7 +68,7 @@ jobs: name: Install dependencies and Check compatibility command: | if [ "$REQUIREMENTS_CHANGED" == "true" ]; then - python -m pip install ".[dev,cli]" --dry-run --python-version --no-deps << parameters.python_version >> + python -m pip install ".[dev,cli]" --dry-run --python-version << parameters.python_version >> --no-deps else echo "Skipping compatibility checks..." fi diff --git a/pyproject.toml b/pyproject.toml index a441de27ca..885b270e16 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ authors = [ license = { file = "LICENSE" } requires-python = ">=3.9,<3.14" dependencies = [ - "bt-decode>=0.6.0", + "wheel", "setuptools~=70.0.0", "aiohttp~=3.9", From f63bb3ef134e9a8aea8538996191e7d6d9c8bf96 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Fri, 11 Apr 2025 15:50:44 +0200 Subject: [PATCH 143/150] Remove unused extra --- .github/workflows/e2e-subtensor-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-subtensor-tests.yaml b/.github/workflows/e2e-subtensor-tests.yaml index 0c749fabaf..0adcc5ffbd 100644 --- a/.github/workflows/e2e-subtensor-tests.yaml +++ b/.github/workflows/e2e-subtensor-tests.yaml @@ -91,7 +91,7 @@ jobs: uses: astral-sh/setup-uv@v4 - name: install dependencies - run: uv sync --extra dev --extra torch --dev + run: uv sync --extra dev --dev - name: Download Cached Docker Image uses: actions/download-artifact@v4 From 09324155d18bf31e565ca455aa327094bdbb6e86 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 11 Apr 2025 10:57:23 -0700 Subject: [PATCH 144/150] sometimes it's still flaky because the chain returns data with time offset --- tests/e2e_tests/test_commit_reveal_v3.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_commit_reveal_v3.py b/tests/e2e_tests/test_commit_reveal_v3.py index 284dd4f192..460c943ad1 100644 --- a/tests/e2e_tests/test_commit_reveal_v3.py +++ b/tests/e2e_tests/test_commit_reveal_v3.py @@ -177,8 +177,8 @@ async def test_commit_and_reveal_weights_cr3(local_chain, subtensor, alice_walle f"Latest drand round after waiting for tempo: {latest_drand_round}" ) - # for fast-block 3 seconds (drand round period) is 12 fast blocks. Let's make sure this round passed. - subtensor.wait_for_block(subtensor.block + 12) + # for fast-block 6 seconds (drand round period) is 12 fast blocks. Let's make sure this round passed. + subtensor.wait_for_block(subtensor.block + 24) # Fetch weights on the chain as they should be revealed now revealed_weights_ = subtensor.weights(netuid=netuid) From 154cc5c5107d9e05fc9f0fb93b6eb2d849b8ace5 Mon Sep 17 00:00:00 2001 From: sashaphmn Date: Sat, 12 Apr 2025 09:42:40 +0300 Subject: [PATCH 145/150] Update CONTRIBUTING.md --- contrib/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/CONTRIBUTING.md b/contrib/CONTRIBUTING.md index b27b426a09..ef9dbde58e 100644 --- a/contrib/CONTRIBUTING.md +++ b/contrib/CONTRIBUTING.md @@ -18,7 +18,7 @@ The following is a set of guidelines for contributing to Bittensor, which are ho 1. [Refactoring](#refactoring) 1. [Peer Review](#peer-review) 1. [Reporting Bugs](#reporting-bugs) - 1. [Suggesting Features](#suggesting-enhancements) + 1. [Suggesting Features](#suggesting-enhancements-and-features) ## I don't want to read this whole thing I just have a question! From 237bd6fe43621bdbdd50a446969b2aec2c65bb84 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 14 Apr 2025 17:00:30 +0200 Subject: [PATCH 146/150] Update test config. --- .circleci/config.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 727cee6df2..74c29215b3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -285,11 +285,6 @@ workflows: release-branches-requirements: jobs: - - check-version-updated: - filters: - branches: - only: - - /^(release|hotfix)/.*/ - check-changelog-updated: filters: branches: From 685edf520376416c139487b0002d90e5f673f33d Mon Sep 17 00:00:00 2001 From: sashaphmn Date: Mon, 14 Apr 2025 20:28:18 +0300 Subject: [PATCH 147/150] Update CONTRIBUTING.md --- contrib/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/CONTRIBUTING.md b/contrib/CONTRIBUTING.md index ef9dbde58e..2f78da7eec 100644 --- a/contrib/CONTRIBUTING.md +++ b/contrib/CONTRIBUTING.md @@ -70,7 +70,7 @@ And also here. You can contribute to Bittensor in one of two main ways (as well as many others): 1. [Bug](#reporting-bugs) reporting and fixes -2. New features and Bittensor [enhancements](#suggesting-enhancements) +2. New features and Bittensor [suggesting-enhancements](#suggesting-enhancements) > Please follow the Bittensor [style guide](./STYLE.md) regardless of your contribution type. From c7dcb68e368f93152428843519306ed76e7b6277 Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 14 Apr 2025 19:52:29 +0200 Subject: [PATCH 148/150] Removed 'file' param from dependabot.yml --- .github/dependabot.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 190e4cd6c5..9ffce36ee7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,8 +1,7 @@ version: 2 updates: - package-ecosystem: "pip" - directory: "" - file: "pyproject.toml" + directory: "/" schedule: interval: "daily" open-pull-requests-limit: 0 # Only security updates will be opened as PRs From a0eb836403a1194e837f50083823f3677c2c0c0b Mon Sep 17 00:00:00 2001 From: Benjamin Himes Date: Mon, 14 Apr 2025 19:59:10 +0200 Subject: [PATCH 149/150] Updated other reference --- contrib/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/CONTRIBUTING.md b/contrib/CONTRIBUTING.md index 2f78da7eec..3561619f6e 100644 --- a/contrib/CONTRIBUTING.md +++ b/contrib/CONTRIBUTING.md @@ -70,7 +70,7 @@ And also here. You can contribute to Bittensor in one of two main ways (as well as many others): 1. [Bug](#reporting-bugs) reporting and fixes -2. New features and Bittensor [suggesting-enhancements](#suggesting-enhancements) +2. New features and Bittensor [enhancements](#suggesting-enhancements-and-features) > Please follow the Bittensor [style guide](./STYLE.md) regardless of your contribution type. From 7996f27a75afa59647370b612838b1f9211ae3f5 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Mon, 14 Apr 2025 11:22:58 -0700 Subject: [PATCH 150/150] updates changelog --- CHANGELOG.md | 19 +++++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84d7c10774..54c4b8fbdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 9.3.1a1 /2025-04-14 + +## What's Changed +* Release/9.3.0 by @ibraheem-abe in https://github.com/opentensor/bittensor/pull/2805 +* Fix for flaky behavior of `test_incentive`, `test_commit_weights` and `test_set_weights` by @basfroman in https://github.com/opentensor/bittensor/pull/2795 +* Add `get_next_epoch_start_block` method to Async/Subtensor by @basfroman in https://github.com/opentensor/bittensor/pull/2808 +* Adds compatibility for torch 2.6.0+ by @thewhaleking in https://github.com/opentensor/bittensor/pull/2811 +* f Update CONTRIBUTING.md by @Hack666r in https://github.com/opentensor/bittensor/pull/2813 +* docs: replaced discord link with documentation by @sashaphmn in https://github.com/opentensor/bittensor/pull/2809 +* sometimes it's still flaky because the chain returns data with time offset by @basfroman in https://github.com/opentensor/bittensor/pull/2816 +* Remove requirements directory by @thewhaleking in https://github.com/opentensor/bittensor/pull/2812 +* version in one place by @thewhaleking in https://github.com/opentensor/bittensor/pull/2806 +* Update CONTRIBUTING hyperlinks by @thewhaleking in https://github.com/opentensor/bittensor/pull/2820 + +## New Contributors +* @Hack666r made their first contribution in https://github.com/opentensor/bittensor/pull/2813 + +**Full Changelog**: https://github.com/opentensor/bittensor/compare/v9.3.0...v9.3.1a1 + ## 9.3.0 /2025-04-09 ## What's Changed diff --git a/pyproject.toml b/pyproject.toml index 885b270e16..b9e3541575 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "bittensor" -version = "9.3.0" +version = "9.3.1a1" description = "Bittensor" readme = "README.md" authors = [