def test_add_stake_success(setup_chain): coldkeypair = Keypair.create_from_uri("//Alice") hotkeypair = Keypair.create_from_mnemonic(Keypair.generate_mnemonic()) wallet = generate_wallet(coldkey_pair=coldkeypair, hotkey_pair=hotkeypair) subtensor = connect(setup_chain) subtensor.is_connected() # Subscibe the hotkey using Alice's cold key, which has TAO subscribe(subtensor, wallet) uid = subtensor.get_uid_for_pubkey(hotkeypair.public_key) assert uid is not None result = subtensor.get_stake_for_uid(uid) assert int(result) == int(Balance(0)) # Get balance balance_pre = subtensor.get_balance(coldkeypair.ss58_address) # Timeout is 30, because 3 * blocktime does not work. result = subtensor.add_stake(wallet, Balance(4000), hotkeypair.public_key, wait_for_finalization=True, timeout=30) assert result == True # Check if the amount of stake end up in the hotkey account result = subtensor.get_stake_for_uid(uid) assert int(result) == int(Balance(4000)) # Check if the balances had reduced by the amount of stake balance_post = subtensor.get_balance(coldkeypair.ss58_address) assert int(balance_post) == int(balance_pre) - 4000
def test_transfer_success(setup_chain): coldkey_alice = Keypair.create_from_uri("//Alice") coldkey_bob = Keypair.create_from_uri("//Bob") subtensor = connect(setup_chain) subtensor.is_connected() balance_alice_pre = subtensor.get_balance(coldkey_alice.ss58_address) balance_bob_pre = subtensor.get_balance(coldkey_bob.ss58_address) wallet_alice = generate_wallet(coldkey_pair=coldkey_alice) result = subtensor.transfer(wallet=wallet_alice, dest=coldkey_bob.ss58_address, amount=Balance(10_000), wait_for_finalization=True, timeout=30) assert result is True balance_alice_post = subtensor.get_balance(coldkey_alice.ss58_address) balance_bob_post = subtensor.get_balance(coldkey_bob.ss58_address) assert int(balance_alice_post) < int( balance_alice_pre) - 10000 # Because of variable transaction fees assert int(balance_bob_post) == int(balance_bob_pre) + 10000
def test_unstake_success(setup_chain): coldkeypair = Keypair.create_from_uri('//Alice') hotkey_pair = Keypair.create_from_mnemonic(Keypair.generate_mnemonic()) wallet = generate_wallet(coldkey_pair=coldkeypair, hotkey_pair=hotkey_pair) subtensor = connect(setup_chain) subtensor.is_connected() subscribe(subtensor, wallet) # Get the balance for the cold key, we use this for later comparison balance = subtensor.get_balance(coldkeypair.public_key) add_stake(subtensor, wallet, Balance(4000)) result = subtensor.unstake(amount=Balance(3000), wallet=wallet, hotkey_id=hotkey_pair.public_key, wait_for_finalization=True, timeout=30) assert result is True # We have staked 4000, but unstaked 3000, so the balance should be 1000 less than before the staking operation new_balance = subtensor.get_balance(coldkeypair.ss58_address) assert int(new_balance) == int(balance) - 1000 uid = subtensor.get_uid_for_pubkey(hotkey_pair.public_key) stake = subtensor.get_stake_for_uid(uid) # When staked, this node will receive the full block reward. # We need to ignore this effect, hence the mod operator assert int(stake) % BLOCK_REWARD == 1000
def test_sign_and_verify_ed25519(self): mnemonic = Keypair.generate_mnemonic() keypair = Keypair.create_from_mnemonic(mnemonic, crypto_type=KeypairType.ED25519) signature = keypair.sign("Test123") self.assertTrue(keypair.verify("Test123", signature))
def test_sign_and_verify_scale_bytes(self): mnemonic = Keypair.generate_mnemonic() keypair = Keypair.create_from_mnemonic(mnemonic) data = ScaleBytes('0x1234') signature = keypair.sign(data) self.assertTrue(keypair.verify(data, signature))
def generate_wallet(coldkey_pair: 'Keypair' = None, hotkey_pair: 'Keypair' = None): if not coldkey_pair: coldkey_pair = Keypair.create_from_mnemonic( Keypair.generate_mnemonic()) if not hotkey_pair: hotkey_pair = Keypair.create_from_mnemonic(Keypair.generate_mnemonic()) return WalletStub(coldkey_pair=coldkey_pair, hotkey_pair=hotkey_pair)
def test_set_weights_success_transaction_fee(setup_chain): coldkeyA = Keypair.create_from_uri('//Alice') coldkeyB = Keypair.create_from_uri('//Bob') walletA = generate_wallet(coldkey_pair=coldkeyA) walletB = generate_wallet(coldkey_pair=coldkeyB) subtensorA = connect(setup_chain) subtensorB = connect(setup_chain) subtensorA.is_connected() subtensorB.is_connected() subscribe(subtensorA, walletA) # Sets a self weight of 1 subscribe(subtensorB, walletB) # Sets a self weight of 1 uidA = subtensorA.get_uid_for_pubkey(walletA.hotkey.public_key) uidB = subtensorB.get_uid_for_pubkey(walletB.hotkey.public_key) stake = 4000 transaction_fee = 14355 # Add stake to the hotkey account, so we can do tests on the transaction fees of the set_weights function # Keep in mind, this operation incurs transaction fees that are appended to the block_reward subtensorA.add_stake(wallet=walletA, amount=Balance(stake), hotkey_id=walletA.hotkey.public_key, wait_for_finalization=True, timeout=30) # At this point both neurons have equal stake, with self-weight set, so they receive each 50% of the block reward blocknr_pre = subtensorA.get_current_block() w_uids = [uidA, uidB] w_vals = [0, 1] subtensorA.set_weights(destinations=w_uids, values=w_vals, wait_for_finalization=True, timeout=4 * bittensor.__blocktime__, wallet=walletA) blocknr_post = subtensorA.get_current_block() blocks_passed = blocknr_post - blocknr_pre #logger.error(blocks_passed) # Check the stakes stakeA = subtensorA.get_stake_for_uid(uidA) expectation = int(stake + (0.99 * BLOCK_REWARD * 3) + 0.99 * TRANSACTION_FEE_ADD_STAKE) assert int(stakeA) == expectation # 1_485_018_355
def test_get_stake_for_uid___has_no_stake(setup_chain): hotkeypair = Keypair.create_from_mnemonic(Keypair.generate_mnemonic()) coldkeypair = Keypair.create_from_uri('//Alice') wallet = generate_wallet(coldkey_pair=coldkeypair, hotkey_pair=hotkeypair) subtensor = connect(setup_chain) subtensor.is_connected() subscribe(subtensor, wallet) uid = subtensor.get_uid_for_pubkey(hotkeypair.public_key) result = subtensor.get_stake_for_uid(uid) assert int(result) == 0
def create_hotkey_from_uri(self, uri: str, use_password: bool = True): # Create directory dir_path = os.path.expanduser( os.path.join(self.config.wallet.path, self.config.wallet.name, "hotkeys")) if not os.path.exists(dir_path): os.makedirs(dir_path) # Create cli_utils.validate_create_path(self.hotkeyfile) self._hotkey = Keypair.create_from_uri(uri) cli_utils.display_mnemonic_msg(self._hotkey) # Encrypt if use_password: password = cli_utils.input_password() print("Encrypting hotkey ... (this might take a few moments)") hotkey_json_data = json.dumps(self._hotkey.toDict()).encode() hotkey_data = encrypt(hotkey_json_data, password) del hotkey_json_data else: hotkey_data = json.dumps(self._hotkey.toDict()).encode() # Save cli_utils.save_keys(self.hotkeyfile, hotkey_data) cli_utils.set_file_permissions(self.hotkeyfile)
def create_coldkey_from_uri(self, uri: str, use_password: bool = True): # Create directory dir_path = os.path.expanduser( os.path.join(self.config.wallet.path, self.config.wallet.name)) if not os.path.exists(dir_path): os.makedirs(dir_path) # Create Key cli_utils.validate_create_path(self.coldkeyfile) self._coldkey = Keypair.create_from_uri(uri) cli_utils.display_mnemonic_msg(self._coldkey) cli_utils.write_pubkey_to_text_file(self.coldkeyfile, self._coldkey.public_key) # Encrypt if use_password: password = cli_utils.input_password() logger.info( "Encrypting coldkey ... (this might take a few moments)") coldkey_json_data = json.dumps(self._coldkey.toDict()).encode() coldkey_data = encrypt(coldkey_json_data, password) del coldkey_json_data else: coldkey_data = json.dumps(self._coldkey.toDict()).encode() # Save cli_utils.save_keys(self.coldkeyfile, coldkey_data) cli_utils.set_file_permissions(self.coldkeyfile)
def test_hdkd_default_to_dev_mnemonic(self): derivation_address = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY' derivation_path = '//Alice' derived_keypair = Keypair.create_from_uri(derivation_path) self.assertEqual(derivation_address, derived_keypair.ss58_address)
def test_hdkd_nested_hard_soft_path(self): derivation_address = '5CJGwWiKXSE16WJaxBdPZhWqUYkotgenLUALv7ZvqQ4TXeqf' derivation_path = '//Bob/test' derived_keypair = Keypair.create_from_uri(derivation_path) self.assertEqual(derivation_address, derived_keypair.ss58_address)
def test_hdkd_nested_soft_hard_path(self): derivation_address = '5Cwc8tShrshDJUp1P1M21dKUTcYQpV9GcfSa4hUBNmMdV3Cx' derivation_path = '/Bob//test' derived_keypair = Keypair.create_from_uri(derivation_path) self.assertEqual(derivation_address, derived_keypair.ss58_address)
def test_sign_unsupported_crypto_type(self): keypair = Keypair.create_from_private_key( ss58_address='16ADqpMa4yzfmWs3nuTSMhfZ2ckeGtvqhPWCNqECEGDcGgU2', private_key= '0x1f1995bdf3a17b60626a26cfe6f564b337d46056b7a1281b64c649d592ccda0a9cffd34d9fb01cae1fba61aeed184c817442a2186d5172416729a4b54dd4b84e', crypto_type=3) self.assertRaises(ConfigurationError, keypair.sign, "0x1234")
def test_hdkd_path_gt_32_bytes(self): derivation_address = '5GR5pfZeNs1uQiSWVxZaQiZou3wdZiX894eqgvfNfHbEh7W2' derivation_path = '//PathNameLongerThan32BytesWhichShouldBeHashed' derived_keypair = Keypair.create_from_uri(derivation_path) self.assertEqual(derivation_address, derived_keypair.ss58_address)
def test_hdkd_soft_path(self): mnemonic = 'old leopard transfer rib spatial phone calm indicate online fire caution review' derivation_address = '5GNXbA46ma5dg19GXdiKi5JH3mnkZ8Yea3bBtZAvj7t99P9i' derivation_path = '/Alice' derived_keypair = Keypair.create_from_uri(mnemonic + derivation_path) self.assertEqual(derivation_address, derived_keypair.ss58_address)
def test_hdkd_hard_path(self): mnemonic = 'old leopard transfer rib spatial phone calm indicate online fire caution review' derivation_address = '5FEiH8iuDUw271xbqWTWuB6WrDjv5dnCeDX1CyHubAniXDNN' derivation_path = '//Alice' derived_keypair = Keypair.create_from_uri(mnemonic + derivation_path) self.assertEqual(derivation_address, derived_keypair.ss58_address)
def test_create_ed25519_keypair(self): mnemonic = "old leopard transfer rib spatial phone calm indicate online fire caution review" keypair = Keypair.create_from_mnemonic(mnemonic, address_type=0, crypto_type=KeypairType.ED25519) self.assertEqual(keypair.ss58_address, "16dYRUXznyhvWHS1ktUENGfNAEjCawyDzHRtN9AdFnJRc38h")
def test_only_provide_public_key(self): keypair = Keypair( public_key= '0xe4359ad3e2716c539a1d663ebd0a51bdc5c98a12e663bb4c4402db47828c9446', address_type=0) self.assertEqual(keypair.ss58_address, '16ADqpMa4yzfmWs3nuTSMhfZ2ckeGtvqhPWCNqECEGDcGgU2')
def test_unstake_success(setup_chain): coldkeypair = Keypair.create_from_uri('//Alice') hotkey_pair = Keypair.create_from_mnemonic(Keypair.generate_mnemonic()) wallet = generate_wallet(coldkey_pair=coldkeypair, hotkey_pair=hotkey_pair) subtensor = connect(setup_chain) subtensor.is_connected() subscribe(subtensor, wallet) # Get the balance for the cold key, we use this for later comparison balance_pre = int(subtensor.get_balance(coldkeypair.public_key)) add_stake(subtensor, wallet, Balance(4000)) # Determine the cost of the add_stake transaction balance_post = int(subtensor.get_balance(coldkeypair.public_key)) transaction_fee_add_stake = balance_pre - balance_post - 4000 logger.error("Trans_fee add_stake: {}", transaction_fee_add_stake) # unstake incurs a transaction fee that is added to the block reward result = subtensor.unstake(amount=Balance(3000), wallet=wallet, hotkey_id=hotkey_pair.public_key, wait_for_finalization=True, timeout=30) assert result is True transaction_fee_unstake = balance_post - int( subtensor.get_balance(coldkeypair.public_key)) + 3000 logger.error("Trans_fee add_stake: {}", transaction_fee_unstake) assert int(transaction_fee_unstake) == TRANSACTION_FEE_UNSTAKE # At this point, the unstake transaction fee is in the transaction_fee_pool, and will make it into the block # reward the next block. However, in order to get this reward into the hotkey account of the neuron, # and emit needs to take place. This is why the expectation does not include the unstake transaction fee uid = subtensor.get_uid_for_pubkey(hotkey_pair.public_key) stake = subtensor.get_stake_for_uid(uid) expectation = 1000 + (3 * BLOCK_REWARD) + TRANSACTION_FEE_ADD_STAKE assert int(stake) == expectation
def load_keypair_from_data(data) -> Keypair: try: data = json.loads(data) if "secretSeed" not in data: raise KeyFileError("Keyfile corrupt") return Keypair.create_from_seed(data['secretSeed']) except BaseException as e: logger.debug(e) raise KeyFileError("Keyfile corrupt")
def test_create_keypair_from_private_key(self): keypair = Keypair.create_from_private_key( ss58_address='16ADqpMa4yzfmWs3nuTSMhfZ2ckeGtvqhPWCNqECEGDcGgU2', private_key= '0x1f1995bdf3a17b60626a26cfe6f564b337d46056b7a1281b64c649d592ccda0a9cffd34d9fb01cae1fba61aeed184c817442a2186d5172416729a4b54dd4b84e' ) self.assertEqual( keypair.public_key, '0xe4359ad3e2716c539a1d663ebd0a51bdc5c98a12e663bb4c4402db47828c9446' )
def validate_generate_mnemonic(mnemonic): if len(mnemonic) not in [12,15,18,21,24]: print(colored("Mnemonic has invalid size. This should be 12,15,18,21 or 24 words", 'red')) quit() try: keypair = Keypair.create_from_mnemonic(" ".join(mnemonic)) return keypair except ValueError as e: print(colored(str(e), "red")) quit()
def test_sign_and_verify_invalid_message(self): mnemonic = Keypair.generate_mnemonic() keypair = Keypair.create_from_mnemonic(mnemonic) signature = keypair.sign("Test123") self.assertFalse(keypair.verify("OtherMessage", signature))
def gen_new_key(words): mnemonic = Keypair.generate_mnemonic(words) keypair = Keypair.create_from_mnemonic(mnemonic) return keypair
def test_sign_missing_private_key(self): keypair = Keypair( ss58_address="5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY") self.assertRaises(ConfigurationError, keypair.sign, "0x1234")
def test_sign_and_verify_hex_data(self): mnemonic = Keypair.generate_mnemonic() keypair = Keypair.create_from_mnemonic(mnemonic) signature = keypair.sign("0x1234") self.assertTrue(keypair.verify("0x1234", signature))
def test_create_sr25519_keypair(self): mnemonic = "old leopard transfer rib spatial phone calm indicate online fire caution review" keypair = Keypair.create_from_mnemonic(mnemonic, address_type=0) self.assertEqual(keypair.ss58_address, "16ADqpMa4yzfmWs3nuTSMhfZ2ckeGtvqhPWCNqECEGDcGgU2")
def test_generate_mnemonic(self): mnemonic = Keypair.generate_mnemonic() self.assertTrue(bip39_validate(mnemonic))
def test_sign_and_verify_invalid_signature_ed25519(self): mnemonic = Keypair.generate_mnemonic() keypair = Keypair.create_from_mnemonic(mnemonic, crypto_type=KeypairType.ED25519) signature = "0x4c291bfb0bb9c1274e86d4b666d13b2ac99a0bacc04a4846fb8ea50bda114677f83c1f164af58fc184451e5140cc8160c4de626163b11451d3bbb208a1889f8a" self.assertFalse(keypair.verify("Test123", signature))