Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions bittensor/extrinsics/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,8 @@ def run_faucet_extrinsic(
if attempts == max_allowed_attempts:
raise MaxAttemptsException
attempts += 1
# Wait a bit before trying again
time.sleep(1)

# Successful registration
else:
Expand All @@ -472,6 +474,8 @@ def run_faucet_extrinsic(

if successes == 3:
raise MaxSuccessException

attempts = 1 # Reset attempts on success
successes += 1

except KeyboardInterrupt:
Expand Down
50 changes: 45 additions & 5 deletions bittensor/extrinsics/staking.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,34 @@
import bittensor
from rich.prompt import Confirm
from time import sleep
from typing import List, Union, Optional
from typing import List, Union, Optional, Tuple
from bittensor.utils.balance import Balance


def _check_threshold_amount(
subtensor: "bittensor.subtensor", stake_balance: Balance
) -> Tuple[bool, Balance]:
"""
Checks if the new stake balance will be above the minimum required stake threshold.

Args:
stake_balance (Balance):
the balance to check for threshold limits.

Returns:
success, threshold (bool, Balance):
``true`` if the staking balance is above the threshold, or ``false`` if the
staking balance is below the threshold.
The threshold balance required to stake.
"""
min_req_stake: Balance = subtensor.get_minimum_required_stake()

if min_req_stake > stake_balance:
return False, min_req_stake
else:
return True, min_req_stake


def add_stake_extrinsic(
subtensor: "bittensor.subtensor",
wallet: "bittensor.wallet",
Expand Down Expand Up @@ -91,6 +115,9 @@ def add_stake_extrinsic(
coldkey_ss58=wallet.coldkeypub.ss58_address, hotkey_ss58=hotkey_ss58
)

# Grab the existential deposit.
existential_deposit = subtensor.get_existential_deposit()

# Convert to bittensor.Balance
if amount is None:
# Stake it all.
Expand All @@ -100,9 +127,10 @@ def add_stake_extrinsic(
else:
staking_balance = amount

# Remove existential balance to keep key alive.
if staking_balance > bittensor.Balance.from_rao(1000):
staking_balance = staking_balance - bittensor.Balance.from_rao(1000)
# Leave existential balance to keep key alive.
if staking_balance > old_balance - existential_deposit:
# If we are staking all, we need to leave at least the existential deposit.
staking_balance = old_balance - existential_deposit
else:
staking_balance = staking_balance

Expand All @@ -115,6 +143,18 @@ def add_stake_extrinsic(
)
return False

# If nominating, we need to check if the new stake balance will be above the minimum required stake threshold.
if not own_hotkey:
new_stake_balance = old_stake + staking_balance
is_above_threshold, threshold = _check_threshold_amount(
subtensor, new_stake_balance
)
if not is_above_threshold:
bittensor.__console__.print(
f":cross_mark: [red]New stake balance of {new_stake_balance} is below the minimum required nomination stake threshold {threshold}.[/red]"
)
return False

# Ask before moving on.
if prompt:
if not own_hotkey:
Expand Down Expand Up @@ -167,7 +207,7 @@ def add_stake_extrinsic(
block = subtensor.get_current_block()
new_stake = subtensor.get_stake_for_coldkey_and_hotkey(
coldkey_ss58=wallet.coldkeypub.ss58_address,
hotkey_ss58=wallet.hotkey.ss58_address,
hotkey_ss58=hotkey_ss58,
block=block,
) # Get current stake

Expand Down
41 changes: 28 additions & 13 deletions bittensor/extrinsics/unstaking.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ def __do_remove_stake_single(


def check_threshold_amount(
subtensor: "bittensor.subtensor", unstaking_balance: Balance
subtensor: "bittensor.subtensor", stake_balance: Balance
) -> bool:
"""
Checks if the unstaking amount is above the threshold or 0
Checks if the remaining stake balance is above the minimum required stake threshold.

Args:
unstaking_balance (Balance):
stake_balance (Balance):
the balance to check for threshold limits.

Returns:
Expand All @@ -88,9 +88,9 @@ def check_threshold_amount(
"""
min_req_stake: Balance = subtensor.get_minimum_required_stake()

if min_req_stake > unstaking_balance > 0:
if min_req_stake > stake_balance > 0:
bittensor.__console__.print(
f":cross_mark: [red]Unstaking balance of {unstaking_balance} less than minimum of {min_req_stake} TAO[/red]"
f":cross_mark: [yellow]Remaining stake balance of {stake_balance} less than minimum of {min_req_stake} TAO[/yellow]"
)
return False
else:
Expand Down Expand Up @@ -141,6 +141,9 @@ def unstake_extrinsic(
coldkey_ss58=wallet.coldkeypub.ss58_address, hotkey_ss58=hotkey_ss58
)

hotkey_owner = subtensor.get_hotkey_owner(hotkey_ss58)
own_hotkey: bool = wallet.coldkeypub.ss58_address == hotkey_owner

# Convert to bittensor.Balance
if amount is None:
# Unstake it all.
Expand All @@ -160,10 +163,14 @@ def unstake_extrinsic(
)
return False

if not check_threshold_amount(
subtensor=subtensor, unstaking_balance=unstaking_balance
# If nomination stake, check threshold.
if not own_hotkey and not check_threshold_amount(
subtensor=subtensor, stake_balance=(stake_on_uid - unstaking_balance)
):
return False
bittensor.__console__.print(
f":warning: [yellow]This action will unstake the entire staked balance![/yellow]"
)
unstaking_balance = stake_on_uid

# Ask before moving on.
if prompt:
Expand Down Expand Up @@ -300,6 +307,7 @@ def unstake_multiple_extrinsic(
wallet.coldkey

old_stakes = []
own_hotkeys = []
with bittensor.__console__.status(
":satellite: Syncing with chain: [white]{}[/white] ...".format(
subtensor.network
Expand All @@ -313,9 +321,12 @@ def unstake_multiple_extrinsic(
) # Get stake on hotkey.
old_stakes.append(old_stake) # None if not registered.

hotkey_owner = subtensor.get_hotkey_owner(hotkey_ss58)
own_hotkeys.append(wallet.coldkeypub.ss58_address == hotkey_owner)

successful_unstakes = 0
for idx, (hotkey_ss58, amount, old_stake) in enumerate(
zip(hotkey_ss58s, amounts, old_stakes)
for idx, (hotkey_ss58, amount, old_stake, own_hotkey) in enumerate(
zip(hotkey_ss58s, amounts, old_stakes, own_hotkeys)
):
# Covert to bittensor.Balance
if amount is None:
Expand All @@ -336,10 +347,14 @@ def unstake_multiple_extrinsic(
)
continue

if not check_threshold_amount(
subtensor=subtensor, unstaking_balance=unstaking_balance
# If nomination stake, check threshold.
if not own_hotkey and not check_threshold_amount(
subtensor=subtensor, stake_balance=(stake_on_uid - unstaking_balance)
):
return False
bittensor.__console__.print(
f":warning: [yellow]This action will unstake the entire staked balance![/yellow]"
)
unstaking_balance = stake_on_uid

# Ask before moving on.
if prompt:
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e_tests/multistep/test_dendrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ async def test_dendrite(local_chain):
metagraph = bittensor.metagraph(netuid=1, network="ws://localhost:9945")
neuron = metagraph.neurons[0]
# assert stake is 10000
assert neuron.stake.tao == 9999.999999
assert neuron.stake.tao == 10_000.0

# assert neuron is not validator
assert neuron.active is True
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e_tests/multistep/test_incentive.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ async def validator_write_output(stream):
alice_neuron = metagraph.neurons[0]
assert alice_neuron.validator_permit is False
assert alice_neuron.dividends == 0
assert alice_neuron.stake.tao == 9999.999999
assert alice_neuron.stake.tao == 10_000.0
assert alice_neuron.validator_trust == 0

# wait until 360 blocks pass (subnet tempo)
Expand Down Expand Up @@ -287,7 +287,7 @@ async def validator_write_output(stream):
alice_neuron = metagraph.neurons[0]
assert alice_neuron.validator_permit is True
assert alice_neuron.dividends == 1
assert alice_neuron.stake.tao == 9999.999999
assert alice_neuron.stake.tao == 10_000.0
assert alice_neuron.validator_trust == 1


Expand Down
2 changes: 1 addition & 1 deletion tests/e2e_tests/subcommands/weights/test_commit_weights.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def test_commit_and_reveal_weights(local_chain):
"--wallet.path",
"/tmp/btcli-wallet2",
"--amount",
"999998998",
"100000",
],
)

Expand Down
Loading