From 7f9d1f4589453549fd0d4961d267d2905a51923e Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 14 Sep 2022 12:06:04 -0400 Subject: [PATCH 1/3] [Docs] Update old docs link to new link. Change discord invite to custom link (#915) * Update old docs link to new one This change deletes the old gitbooks documentation link and replaces it with the new one. * fix discord links Co-authored-by: Mac Thrasher <95183714+quac88@users.noreply.github.com> --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 57dd7e034f..e75e440efc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@
# **Bittensor** -[![Discord Chat](https://img.shields.io/discord/308323056592486420.svg)](https://discord.gg/3rUr6EcvbB) +[![Discord Chat](https://img.shields.io/discord/308323056592486420.svg)](https://discord.gg/bittensor) [![PyPI version](https://badge.fury.io/py/bittensor.svg)](https://badge.fury.io/py/bittensor) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) @@ -9,7 +9,7 @@ ### Internet-scale Neural Networks -[Discord](https://discord.gg/3rUr6EcvbB) • [Docs](https://app.gitbook.com/@opentensor/s/bittensor/) • [Network](https://www.bittensor.com/metagraph) • [Research](https://drive.google.com/file/d/1VnsobL6lIAAqcA1_Tbm8AYIQscfJV4KU) • [Code](https://github.com/opentensor/BitTensor) +[Discord](https://discord.gg/bittensor) • [Docs](https://docs.bittensor.com/) • [Network](https://www.bittensor.com/network) • [Research](https://drive.google.com/file/d/1VnsobL6lIAAqcA1_Tbm8AYIQscfJV4KU) • [Code](https://github.com/opentensor/BitTensor)
From c62a81d3f4c42abd557c127d5f2254d62b27d6bc Mon Sep 17 00:00:00 2001 From: Eugene-hu <85906264+Eugene-hu@users.noreply.github.com> Date: Wed, 14 Sep 2022 12:57:09 -0700 Subject: [PATCH 2/3] Fix for test_neuron.py (#917) prevents downloading from huggingface --- tests/unit_tests/bittensor_tests/test_neuron.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit_tests/bittensor_tests/test_neuron.py b/tests/unit_tests/bittensor_tests/test_neuron.py index 4d5195cb1f..0c9c86ae73 100644 --- a/tests/unit_tests/bittensor_tests/test_neuron.py +++ b/tests/unit_tests/bittensor_tests/test_neuron.py @@ -23,9 +23,9 @@ def __init__(self): self.encoder2 = TransformerEncoder( self.encoder_layers, nlayers_2 ) self.decoder = torch.nn.Linear( network_dim, vocab_size , bias=False) - core_server = bittensor._neuron.text.core_server.server() + core_server = bittensor._neuron.text.core_server.server(pretrained=False) # test for the basic default gpt2 case - assert core_server.set_fine_tuning_params() == (True, 'transformer.h.11') + assert core_server.set_fine_tuning_params() == (True, 'h.11') # test for the case when there are 2 modulelists core_server.pre_model = Model() From f9da8f1484c21020c08325b9a6694d86c5af5c2f Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Thu, 15 Sep 2022 10:37:12 -0400 Subject: [PATCH 3/3] [feature] add --seed option to regen_hotkey (#916) * add seed option to regen hotkey * make seed optional and fix docstring * add tests for both coldkey and hotkey regen w/seed * oops, make seed optional * fix old test, add config.seed --- bittensor/_cli/__init__.py | 15 ++++++++-- bittensor/_cli/cli_impl.py | 2 +- bittensor/_wallet/wallet_impl.py | 29 ++++++++++++------ tests/integration_tests/test_cli.py | 1 + .../unit_tests/bittensor_tests/test_wallet.py | 30 +++++++++++++++++++ 5 files changed, 64 insertions(+), 13 deletions(-) diff --git a/bittensor/_cli/__init__.py b/bittensor/_cli/__init__.py index 8e655d60cb..a69a65b65f 100644 --- a/bittensor/_cli/__init__.py +++ b/bittensor/_cli/__init__.py @@ -394,6 +394,12 @@ def config(args: List[str]) -> 'bittensor.config': nargs="+", help='Mnemonic used to regen your key i.e. horse cart dog ...' ) + regen_hotkey_parser.add_argument( + "--seed", + required=False, + default=None, + help='Seed hex string used to regen your key i.e. 0x1234...' + ) regen_hotkey_parser.add_argument( '--use_password', dest='use_password', @@ -891,8 +897,12 @@ def check_regen_hotkey_config( config: 'bittensor.Config' ): hotkey = Prompt.ask("Enter hotkey name", default = bittensor.defaults.wallet.hotkey) config.wallet.hotkey = str(hotkey) - if config.mnemonic == None: - config.mnemonic = Prompt.ask("Enter mnemonic") + if config.mnemonic == None and config.seed == None: + prompt_answer = Prompt.ask("Enter mnemonic or seed") + if prompt_answer.startswith("0x"): + config.seed = prompt_answer + else: + config.mnemonic = prompt_answer def check_regen_coldkey_config( config: 'bittensor.Config' ): if config.wallet.get('name') == bittensor.defaults.wallet.name and not config.no_prompt: @@ -900,7 +910,6 @@ def check_regen_coldkey_config( config: 'bittensor.Config' ): config.wallet.name = str(wallet_name) if config.mnemonic == None and config.seed == None: prompt_answer = Prompt.ask("Enter mnemonic or seed") - print(prompt_answer) if prompt_answer.startswith("0x"): config.seed = prompt_answer else: diff --git a/bittensor/_cli/cli_impl.py b/bittensor/_cli/cli_impl.py index bdc4744e1a..0425504486 100644 --- a/bittensor/_cli/cli_impl.py +++ b/bittensor/_cli/cli_impl.py @@ -114,7 +114,7 @@ def regen_hotkey ( self ): r""" Creates a new coldkey under this wallet. """ wallet = bittensor.wallet(config = self.config) - wallet.regenerate_hotkey( mnemonic = self.config.mnemonic, use_password = self.config.use_password, overwrite = self.config.overwrite_hotkey) + wallet.regenerate_hotkey( mnemonic = self.config.mnemonic, seed=self.config.seed, use_password = self.config.use_password, overwrite = self.config.overwrite_hotkey) def query ( self ): r""" Query an endpoint and get query time. diff --git a/bittensor/_wallet/wallet_impl.py b/bittensor/_wallet/wallet_impl.py index 993b09930a..5749c487ce 100644 --- a/bittensor/_wallet/wallet_impl.py +++ b/bittensor/_wallet/wallet_impl.py @@ -669,7 +669,7 @@ def regenerate_coldkeypub( self, ss58_address: Optional[str] = None, public_key: # Short name for regenerate_coldkeypub regen_coldkeypub = regenerate_coldkeypub - def regenerate_coldkey( self, mnemonic: Optional[Union[list, str]]=None, seed: Optional[str]=None, use_password: bool = True, overwrite:bool = False) -> 'Wallet': + def regenerate_coldkey( self, mnemonic: Optional[Union[list, str]] = None, seed: Optional[str] = None, use_password: bool = True, overwrite:bool = False) -> 'Wallet': """ Regenerates the coldkey from passed mnemonic, encrypts it with the user's password and save the file Args: mnemonic: (Union[list, str], optional): @@ -700,11 +700,13 @@ def regenerate_coldkey( self, mnemonic: Optional[Union[list, str]]=None, seed: O self.set_coldkeypub( keypair, overwrite = overwrite) return self - def regen_hotkey( self, mnemonic: Union[list, str], use_password: bool = True, overwrite:bool = False) -> 'Wallet': + def regen_hotkey( self, mnemonic: Optional[Union[list, str]], seed: Optional[str] = None, use_password: bool = True, overwrite:bool = False) -> 'Wallet': """ Regenerates the hotkey from passed mnemonic, encrypts it with the user's password and save the file Args: mnemonic: (Union[list, str], optional): Key mnemonic as list of words or string space separated words. + seed: (str, optional): + Seed as hex string. use_password (bool, optional): Is the created key password protected. overwrite (bool, optional): @@ -713,13 +715,15 @@ def regen_hotkey( self, mnemonic: Union[list, str], use_password: bool = True, o wallet (bittensor.Wallet): this object with newly created hotkey. """ - self.regenerate_hotkey(mnemonic, use_password, overwrite) + self.regenerate_hotkey(mnemonic, seed, use_password, overwrite) - def regenerate_hotkey( self, mnemonic: Union[list, str], use_password: bool = True, overwrite:bool = False) -> 'Wallet': + def regenerate_hotkey( self, mnemonic: Optional[Union[list, str]] = None, seed: Optional[str] = None, use_password: bool = True, overwrite:bool = False) -> 'Wallet': """ Regenerates the hotkey from passed mnemonic, encrypts it with the user's password and save the file Args: mnemonic: (Union[list, str], optional): Key mnemonic as list of words or string space separated words. + seed: (str, optional): + Seed as hex string. use_password (bool, optional): Is the created key password protected. overwrite (bool, optional): @@ -728,10 +732,17 @@ def regenerate_hotkey( self, mnemonic: Union[list, str], use_password: bool = Tr wallet (bittensor.Wallet): this object with newly created hotkey. """ - if isinstance( mnemonic, str): mnemonic = mnemonic.split() - if len(mnemonic) not in [12,15,18,21,24]: - raise ValueError("Mnemonic has invalid size. This should be 12,15,18,21 or 24 words") - keypair = Keypair.create_from_mnemonic(" ".join(mnemonic)) - display_mnemonic_msg( keypair, "hotkey" ) + if mnemonic is None and seed is None: + raise ValueError("Must pass either mnemonic or seed") + if mnemonic is not None: + if isinstance( mnemonic, str): mnemonic = mnemonic.split() + if len(mnemonic) not in [12,15,18,21,24]: + raise ValueError("Mnemonic has invalid size. This should be 12,15,18,21 or 24 words") + keypair = Keypair.create_from_mnemonic(" ".join(mnemonic)) + display_mnemonic_msg( keypair, "hotkey" ) + else: + # seed is not None + keypair = Keypair.create_from_seed(seed) + self.set_hotkey( keypair, encrypt=use_password, overwrite = overwrite) return self diff --git a/tests/integration_tests/test_cli.py b/tests/integration_tests/test_cli.py index 65bdd8f67a..febbcbf5e7 100644 --- a/tests/integration_tests/test_cli.py +++ b/tests/integration_tests/test_cli.py @@ -1185,6 +1185,7 @@ def test_regen_hotkey( self ): config.subtensor._mock = True config.model = "core_server" config.mnemonic = "faculty decade seven jelly gospel axis next radio grain radio remain gentle" + config.seed = None config.n_words = 12 config.use_password = False config.no_prompt = True diff --git a/tests/unit_tests/bittensor_tests/test_wallet.py b/tests/unit_tests/bittensor_tests/test_wallet.py index 6415966a5b..660eb5bf99 100644 --- a/tests/unit_tests/bittensor_tests/test_wallet.py +++ b/tests/unit_tests/bittensor_tests/test_wallet.py @@ -64,3 +64,33 @@ def test_regen_coldkeypub_no_pubkey(self): with pytest.raises(ValueError): # Must provide either public_key or ss58_address self.mock_wallet.regenerate_coldkeypub(ss58_address=None, public_key=None) + + def test_regen_coldkey_from_hex_seed_str(self): + ss58_addr = "5D5cwd8DX6ij7nouVcoxDuWtJfiR1BnzCkiBVTt7DU8ft5Ta" + seed_str = "0x659c024d5be809000d0d93fe378cfde020846150b01c49a201fc2a02041f7636" + with patch.object(self.mock_wallet, 'set_coldkey') as mock_set_coldkey: + self.mock_wallet.regenerate_coldkey(seed=seed_str) + + mock_set_coldkey.assert_called_once() + keypair: bittensor.Keypair = mock_set_coldkey.call_args_list[0][0][0] + self.assertEqual(keypair.seed_hex, seed_str) + self.assertEqual(keypair.ss58_address, ss58_addr) # Check that the ss58 address is correct + + seed_str_bad = "0x659c024d5be809000d0d93fe378cfde020846150b01c49a201fc2a02041f763" # 1 character short + with pytest.raises(ValueError): + self.mock_wallet.regenerate_coldkey(seed=seed_str_bad) + + def test_regen_hotkey_from_hex_seed_str(self): + ss58_addr = "5D5cwd8DX6ij7nouVcoxDuWtJfiR1BnzCkiBVTt7DU8ft5Ta" + seed_str = "0x659c024d5be809000d0d93fe378cfde020846150b01c49a201fc2a02041f7636" + with patch.object(self.mock_wallet, 'set_hotkey') as mock_set_hotkey: + self.mock_wallet.regenerate_hotkey(seed=seed_str) + + mock_set_hotkey.assert_called_once() + keypair: bittensor.Keypair = mock_set_hotkey.call_args_list[0][0][0] + self.assertEqual(keypair.seed_hex, seed_str) + self.assertEqual(keypair.ss58_address, ss58_addr) # Check that the ss58 address is correct + + seed_str_bad = "0x659c024d5be809000d0d93fe378cfde020846150b01c49a201fc2a02041f763" # 1 character short + with pytest.raises(ValueError): + self.mock_wallet.regenerate_hotkey(seed=seed_str_bad)