Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate Rust Wallet — tests #158

Merged
merged 25 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b31aa2b
Added the `--help` message automatically when no command is specified…
thewhaleking Sep 30, 2024
e6fc91f
Merge pull request #137 from opentensor/feat/thewhaleking/help-when-n…
thewhaleking Sep 30, 2024
dc5cc1c
Adding PyPI badge
Sep 30, 2024
80114d9
Merge pull request #140 from opentensor/rajkaramchedu-patch-1
Oct 1, 2024
10d1eb8
Switch Keypair import to bittensor_wallet and update tests
Oct 2, 2024
b670373
add tests dir init
camfairchild Oct 2, 2024
add1b9b
use relative imports
camfairchild Oct 2, 2024
9aabc5c
change runner params and fix grab mne
camfairchild Oct 2, 2024
8b4294f
assert output of exception and stdout first
camfairchild Oct 2, 2024
597880d
Json tuple handling + ruff format.
thewhaleking Oct 2, 2024
7b629c7
change empty json handling
camfairchild Oct 2, 2024
ac6ee9e
json for regen hotkey
thewhaleking Oct 2, 2024
d958cfd
Asserting error in stderr
ibraheem-opentensor Oct 2, 2024
09b5ceb
lower wait time for mod check
camfairchild Oct 2, 2024
93e64e8
Fixed wallet path by ensuring that we expand the user dir, working wa…
thewhaleking Oct 3, 2024
2feb399
Merge branch 'staging' into opendansor/new_wallet_tests
thewhaleking Oct 3, 2024
99f61e5
Always ask for WALLET.PATH because the new Wallet doesn't handle None…
thewhaleking Oct 3, 2024
6c03689
Updated the helper text in wallet ask to let users know they can set …
thewhaleking Oct 3, 2024
4eb2a5e
Fixed new error (TypeError) in btwallet 2.0 causing .DS_Store
thewhaleking Oct 3, 2024
43e4dc4
Extend wallet_path fix to regen coldkey, coldkey pub + improve text l…
ibraheem-opentensor Oct 3, 2024
a5358c5
Add a 10 second sleep, which seems to be long enough to avoid flakine…
thewhaleking Oct 3, 2024
3c52ee8
Testing alpha release
ibraheem-opentensor Oct 3, 2024
51f911f
Bumping wallet version for testing
ibraheem-opentensor Oct 3, 2024
d5e3405
Wallet -> 2.0.0
ibraheem-opentensor Oct 4, 2024
28b334e
Removes comments
ibraheem-opentensor Oct 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 75 additions & 48 deletions bittensor_cli/cli.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bittensor_cli/src/bittensor/async_substrate_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from scalecodec.base import ScaleBytes, ScaleType, RuntimeConfigurationObject
from scalecodec.type_registry import load_type_registry_preset
from scalecodec.types import GenericCall
from substrateinterface import Keypair
from bittensor_wallet import Keypair
from substrateinterface.exceptions import (
SubstrateRequestException,
ExtrinsicNotFound,
Expand Down
2 changes: 1 addition & 1 deletion bittensor_cli/src/bittensor/extrinsics/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
from rich.prompt import Confirm
from rich.table import Table, Column
from scalecodec import ScaleBytes, U16, Vec
from substrateinterface import Keypair

from bittensor_wallet import Keypair
from bittensor_cli.src.bittensor.subtensor_interface import SubtensorInterface
from bittensor_cli.src.bittensor.extrinsics.registration import is_hotkey_registered
from bittensor_cli.src.bittensor.utils import (
Expand Down
6 changes: 3 additions & 3 deletions bittensor_cli/src/bittensor/extrinsics/transfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ async def do_transfer() -> tuple[bool, str, str]:
print_verbose("Fetching existential and fee", status)
block_hash = await subtensor.substrate.get_chain_head()
account_balance_, existential_deposit = await asyncio.gather(
subtensor.get_balance(wallet.coldkey.ss58_address, block_hash=block_hash),
subtensor.get_balance(wallet.coldkeypub.ss58_address, block_hash=block_hash),
subtensor.get_existential_deposit(block_hash=block_hash),
)
account_balance = account_balance_[wallet.coldkey.ss58_address]
account_balance = account_balance_[wallet.coldkeypub.ss58_address]
fee = await get_transfer_fee()

if not keep_alive:
Expand Down Expand Up @@ -176,7 +176,7 @@ async def do_transfer() -> tuple[bool, str, str]:
if success:
with console.status(":satellite: Checking Balance...", spinner="aesthetic"):
new_balance = await subtensor.get_balance(
wallet.coldkey.ss58_address, reuse_block=False
wallet.coldkeypub.ss58_address, reuse_block=False
)
console.print(
f"Balance:\n"
Expand Down
24 changes: 13 additions & 11 deletions bittensor_cli/src/bittensor/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@
import webbrowser
from pathlib import Path
from typing import TYPE_CHECKING, Any, Collection, Optional, Union, Callable
from urllib.parse import urlparse

import numpy as np
import scalecodec
import typer
from bittensor_wallet import Wallet
from bittensor_wallet.keyfile import Keypair
from bittensor_wallet.utils import SS58_FORMAT, ss58
from bittensor_wallet import Wallet, Keypair
from bittensor_wallet.utils import SS58_FORMAT
from bittensor_wallet import utils
from jinja2 import Template
from markupsafe import Markup
import numpy as np
from numpy.typing import NDArray
from rich.console import Console
import scalecodec
from scalecodec.base import RuntimeConfiguration
from scalecodec.type_registry import load_type_registry_preset
import typer


from bittensor_cli.src.bittensor.balances import Balance
from urllib.parse import urlparse


if TYPE_CHECKING:
from bittensor_cli.src.bittensor.chain_data import SubnetHyperparameters
Expand Down Expand Up @@ -219,6 +222,7 @@ def get_hotkey_wallets_for_wallet(
except (
UnicodeDecodeError,
AttributeError,
TypeError
): # usually an unrelated file like .DS_Store
continue

Expand Down Expand Up @@ -302,10 +306,8 @@ def is_valid_ss58_address(address: str) -> bool:
:return: `True` if the address is a valid ss58 address for Bittensor, `False` otherwise.
"""
try:
return ss58.is_valid_ss58_address(
address, valid_ss58_format=SS58_FORMAT
) or ss58.is_valid_ss58_address(
address, valid_ss58_format=42
return utils.is_valid_ss58_address(
address
) # Default substrate ss58 format (legacy)
except IndexError:
return False
Expand Down
4 changes: 2 additions & 2 deletions bittensor_cli/src/commands/wallets.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ async def regen_coldkey(
wallet.regenerate_coldkey(
mnemonic=mnemonic,
seed=seed,
json=(json_str, json_password),
json=(json_str, json_password) if all([json_str, json_password]) else None,
use_password=use_password,
overwrite=False,
)
Expand Down Expand Up @@ -123,7 +123,7 @@ async def regen_hotkey(
wallet.regenerate_hotkey(
mnemonic=mnemonic,
seed=seed,
json=(json_str, json_password),
json=(json_str, json_password) if all([json_str, json_password]) else None,
use_password=use_password,
overwrite=False,
)
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ scalecodec==1.2.11
substrate-interface~=1.7.9
typer~=0.12
websockets>=12.0
bittensor-wallet==1.0.0
bittensor-wallet==2.0.0
bt-decode==0.2.0a0
Empty file added tests/__init__.py
Empty file.
5 changes: 3 additions & 2 deletions tests/e2e_tests/test_root.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import time

from bittensor_cli.src.bittensor.balances import Balance
from tests.e2e_tests.utils import extract_coldkey_balance
from .utils import extract_coldkey_balance

"""
Verify commands:
Expand Down Expand Up @@ -217,10 +217,11 @@ def test_root_commands(local_chain, wallet_setup):
"--delegate-ss58key",
wallet_bob.hotkey.ss58_address,
"--amount",
f"10",
"10",
"--no-prompt",
],
)
time.sleep(10)
assert "✅ Finalized" in undelegate_alice.stdout

check_balance(
Expand Down
35 changes: 24 additions & 11 deletions tests/e2e_tests/test_wallet_creations.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,28 @@ def extract_mnemonics_from_commands(output: str) -> Dict[str, Optional[str]]:
dict: A dictionary keys 'coldkey' and 'hotkey', each containing their mnemonics.
"""
mnemonics: Dict[str, Optional[str]] = {"coldkey": None, "hotkey": None}
lines = output.splitlines()

key_types = ["coldkey", "hotkey"]
command_prefix = "btcli w regen-"

for line in lines:
line = line.strip().lower()
# We will assume the most recent match is the one we want
for key_type in key_types:
# Note: python's re needs this P before the group name
# See: https://stackoverflow.com/questions/10059673/named-regular-expression-group-pgroup-nameregexp-what-does-p-stand-for
pat = re.compile(rf"(?P<key_type>{key_type}).*?(?P<mnemonic>(\w+( |)){{12}})")
matches = pat.search(output)

groups = matches.groupdict()

if len(groups.keys()) == 0:
mnemonics[key_type] = None
continue

if line.startswith(command_prefix):
for key_type in key_types:
if line.startswith(f"{command_prefix}{key_type} --mnemonic "):
mnemonic_phrase = line.split("--mnemonic ")[1].strip().strip('"')
mnemonics[key_type] = mnemonic_phrase
break
key_type_str = groups["key_type"]
if key_type != key_type_str:
continue

mnemonic_phrase = groups["mnemonic"]
mnemonics[key_type] = mnemonic_phrase

return mnemonics

Expand Down Expand Up @@ -329,6 +337,11 @@ def test_wallet_regen(wallet_setup):
],
)

# Check for an exception first
assert result.exception is None
# Verify the command has output, as expected
assert result.stdout is not None

mnemonics = extract_mnemonics_from_commands(result.stdout)

wallet_status, message = verify_wallet_dir(
Expand Down Expand Up @@ -364,7 +377,7 @@ def test_wallet_regen(wallet_setup):
)

# Wait a bit to ensure file system updates modification time
time.sleep(1)
time.sleep(0.01)

new_coldkey_mod_time = os.path.getmtime(coldkey_path)

Expand Down
10 changes: 8 additions & 2 deletions tests/e2e_tests/test_wallet_interactions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from time import sleep

from bittensor_cli.src.bittensor.balances import Balance
from tests.e2e_tests.utils import (
from .utils import (
extract_coldkey_balance,
validate_wallet_inspect,
validate_wallet_overview,
Expand Down Expand Up @@ -58,6 +60,8 @@ def test_wallet_overview_inspect(local_chain, wallet_setup):
)
assert f"✅ Registered subnetwork with netuid: {netuid}" in result.stdout

sleep(3)

# List all the subnets in the network
subnets_list = exec_command(
command="subnets",
Expand All @@ -68,6 +72,8 @@ def test_wallet_overview_inspect(local_chain, wallet_setup):
],
)

sleep(3)

# Assert using regex that the subnet is visible in subnets list
assert verify_subnet_entry(subnets_list.stdout, netuid, keypair.ss58_address)

Expand Down Expand Up @@ -326,7 +332,7 @@ def test_wallet_transfer(local_chain, wallet_setup):
)

# This transfer is expected to fail due to low balance
assert "❌ Not enough balance" in result.stdout
assert "❌ Not enough balance" in result.stderr
print("✅Passed wallet transfer, balance command")


Expand Down
12 changes: 8 additions & 4 deletions tests/e2e_tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
from typing import List, Tuple, TYPE_CHECKING

from bittensor_cli.cli import CLIManager
from substrateinterface import Keypair
from bittensor_wallet import Keypair, Wallet
from typer.testing import CliRunner
from bittensor_wallet import Wallet

if TYPE_CHECKING:
from bittensor_cli.src.bittensor.async_substrate_interface import (
Expand All @@ -34,7 +33,8 @@ def exec_command(
inputs: List[str] = None,
):
cli_manager = CLIManager()
runner = CliRunner()
# Capture stderr separately from stdout
runner = CliRunner(mix_stderr=False)
# Prepare the command arguments
args = [
command,
Expand All @@ -48,7 +48,11 @@ def exec_command(

input_text = "\n".join(inputs) + "\n" if inputs else None
result = runner.invoke(
cli_manager.app, args, input=input_text, env={"COLUMNS": "700"}
cli_manager.app,
args,
input=input_text,
env={"COLUMNS": "700"},
catch_exceptions=False,
)
return result

Expand Down
Loading