31
31
from bittensor .core .chain_data .delegate_info import DelegatedInfo
32
32
from bittensor .core .chain_data .utils import decode_metadata
33
33
from bittensor .core .config import Config
34
- from bittensor .core .errors import SubstrateRequestException
34
+ from bittensor .core .errors import ChainError , SubstrateRequestException
35
35
from bittensor .core .extrinsics .asyncex .commit_reveal import commit_reveal_v3_extrinsic
36
36
from bittensor .core .extrinsics .asyncex .registration import (
37
37
burned_register_extrinsic ,
57
57
add_stake_extrinsic ,
58
58
add_stake_multiple_extrinsic ,
59
59
)
60
+ from bittensor .core .extrinsics .asyncex .take import (
61
+ decrease_take_extrinsic ,
62
+ increase_take_extrinsic ,
63
+ )
60
64
from bittensor .core .extrinsics .asyncex .transfer import transfer_extrinsic
61
65
from bittensor .core .extrinsics .asyncex .unstaking import (
62
66
unstake_extrinsic ,
@@ -1111,7 +1115,7 @@ async def get_delegate_take(
1111
1115
block : Optional [int ] = None ,
1112
1116
block_hash : Optional [str ] = None ,
1113
1117
reuse_block : bool = False ,
1114
- ) -> Optional [ float ] :
1118
+ ) -> float :
1115
1119
"""
1116
1120
Retrieves the delegate 'take' percentage for a neuron identified by its hotkey. The 'take' represents the
1117
1121
percentage of rewards that the delegate claims from its nominators' stakes.
@@ -1123,7 +1127,7 @@ async def get_delegate_take(
1123
1127
reuse_block (bool): Whether to reuse the last-used block hash.
1124
1128
1125
1129
Returns:
1126
- Optional[ float] : The delegate take percentage, None if not available .
1130
+ float: The delegate take percentage.
1127
1131
1128
1132
The delegate take is a critical parameter in the network's incentive structure, influencing the distribution of
1129
1133
rewards among neurons and their nominators.
@@ -1135,11 +1139,8 @@ async def get_delegate_take(
1135
1139
reuse_block = reuse_block ,
1136
1140
params = [hotkey_ss58 ],
1137
1141
)
1138
- return (
1139
- None
1140
- if result is None
1141
- else u16_normalized_float (getattr (result , "value" , 0 ))
1142
- )
1142
+
1143
+ return u16_normalized_float (result .value ) # type: ignore
1143
1144
1144
1145
async def get_delegated (
1145
1146
self ,
@@ -2748,6 +2749,7 @@ async def sign_and_send_extrinsic(
2748
2749
use_nonce : bool = False ,
2749
2750
period : Optional [int ] = None ,
2750
2751
nonce_key : str = "hotkey" ,
2752
+ raise_error : bool = False ,
2751
2753
) -> tuple [bool , str ]:
2752
2754
"""
2753
2755
Helper method to sign and submit an extrinsic call to chain.
@@ -2758,6 +2760,7 @@ async def sign_and_send_extrinsic(
2758
2760
wait_for_inclusion (bool): whether to wait until the extrinsic call is included on the chain
2759
2761
wait_for_finalization (bool): whether to wait until the extrinsic call is finalized on the chain
2760
2762
sign_with: the wallet's keypair to use for the signing. Options are "coldkey", "hotkey", "coldkeypub"
2763
+ raise_error: raises relevant exception rather than returning `False` if unsuccessful.
2761
2764
2762
2765
Returns:
2763
2766
(success, error message)
@@ -2795,9 +2798,15 @@ async def sign_and_send_extrinsic(
2795
2798
if await response .is_success :
2796
2799
return True , ""
2797
2800
2801
+ if raise_error :
2802
+ raise ChainError .from_error (response .error_message )
2803
+
2798
2804
return False , format_error_message (await response .error_message )
2799
2805
2800
2806
except SubstrateRequestException as e :
2807
+ if raise_error :
2808
+ raise
2809
+
2801
2810
return False , format_error_message (e )
2802
2811
2803
2812
# Extrinsics =======================================================================================================
@@ -2812,7 +2821,7 @@ async def add_stake(
2812
2821
wait_for_finalization : bool = False ,
2813
2822
safe_staking : bool = False ,
2814
2823
allow_partial_stake : bool = False ,
2815
- rate_threshold : float = 0.005 ,
2824
+ rate_tolerance : float = 0.005 ,
2816
2825
) -> bool :
2817
2826
"""
2818
2827
Adds the specified amount of stake to a neuron identified by the hotkey ``SS58`` address.
@@ -2827,11 +2836,11 @@ async def add_stake(
2827
2836
wait_for_inclusion (bool): Waits for the transaction to be included in a block.
2828
2837
wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
2829
2838
safe_staking (bool): If true, enables price safety checks to protect against fluctuating prices. The stake
2830
- will only execute if the price change doesn't exceed the rate threshold . Default is False.
2839
+ will only execute if the price change doesn't exceed the rate tolerance . Default is False.
2831
2840
allow_partial_stake (bool): If true and safe_staking is enabled, allows partial staking when
2832
2841
the full amount would exceed the price threshold. If false, the entire stake fails if it would
2833
2842
exceed the threshold. Default is False.
2834
- rate_threshold (float): The maximum allowed price change ratio when staking. For example,
2843
+ rate_tolerance (float): The maximum allowed price change ratio when staking. For example,
2835
2844
0.005 = 0.5% maximum price increase. Only used when safe_staking is True. Default is 0.005.
2836
2845
2837
2846
Returns:
@@ -2852,7 +2861,7 @@ async def add_stake(
2852
2861
wait_for_finalization = wait_for_finalization ,
2853
2862
safe_staking = safe_staking ,
2854
2863
allow_partial_stake = allow_partial_stake ,
2855
- rate_threshold = rate_threshold ,
2864
+ rate_tolerance = rate_tolerance ,
2856
2865
)
2857
2866
2858
2867
async def add_stake_multiple (
@@ -2915,6 +2924,14 @@ async def burned_register(
2915
2924
bool: ``True`` if the registration is successful, False otherwise.
2916
2925
"""
2917
2926
async with self :
2927
+ if netuid == 0 :
2928
+ return await root_register_extrinsic (
2929
+ subtensor = self ,
2930
+ wallet = wallet ,
2931
+ wait_for_inclusion = wait_for_inclusion ,
2932
+ wait_for_finalization = wait_for_finalization ,
2933
+ )
2934
+
2918
2935
return await burned_register_extrinsic (
2919
2936
subtensor = self ,
2920
2937
wallet = wallet ,
@@ -3205,35 +3222,6 @@ async def root_register(
3205
3222
Returns:
3206
3223
`True` if registration was successful, otherwise `False`.
3207
3224
"""
3208
- netuid = 0
3209
- logging .info (
3210
- f"Registering on netuid [blue]0[/blue] on network: [blue]{ self .network } [/blue]"
3211
- )
3212
-
3213
- # Check current recycle amount
3214
- logging .info ("Fetching recycle amount & balance." )
3215
- block_hash = block_hash if block_hash else await self .get_block_hash ()
3216
-
3217
- try :
3218
- recycle_call , balance = await asyncio .gather (
3219
- self .get_hyperparameter (
3220
- param_name = "Burn" , netuid = netuid , block_hash = block_hash
3221
- ),
3222
- self .get_balance (wallet .coldkeypub .ss58_address , block_hash = block_hash ),
3223
- )
3224
- except TypeError as e :
3225
- logging .error (f"Unable to retrieve current recycle. { e } " )
3226
- return False
3227
-
3228
- current_recycle = Balance .from_rao (int (recycle_call ))
3229
-
3230
- # Check balance is sufficient
3231
- if balance < current_recycle :
3232
- logging .error (
3233
- f"[red]Insufficient balance { balance } to register neuron. "
3234
- f"Current recycle is { current_recycle } TAO[/red]."
3235
- )
3236
- return False
3237
3225
3238
3226
return await root_register_extrinsic (
3239
3227
subtensor = self ,
@@ -3281,6 +3269,82 @@ async def root_set_weights(
3281
3269
wait_for_inclusion = wait_for_inclusion ,
3282
3270
)
3283
3271
3272
+ async def set_delegate_take (
3273
+ self ,
3274
+ wallet : "Wallet" ,
3275
+ hotkey_ss58 : str ,
3276
+ take : float ,
3277
+ wait_for_inclusion : bool = True ,
3278
+ wait_for_finalization : bool = True ,
3279
+ raise_error : bool = False ,
3280
+ ) -> tuple [bool , str ]:
3281
+ """
3282
+ Sets the delegate 'take' percentage for a neuron identified by its hotkey.
3283
+ The 'take' represents the percentage of rewards that the delegate claims from its nominators' stakes.
3284
+
3285
+ Arguments:
3286
+ wallet (bittensor_wallet.Wallet): bittensor wallet instance.
3287
+ hotkey_ss58 (str): The ``SS58`` address of the neuron's hotkey.
3288
+ take (float): Percentage reward for the delegate.
3289
+ wait_for_inclusion (bool): Waits for the transaction to be included in a block.
3290
+ wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
3291
+ raise_error: Raises relevant exception rather than returning `False` if unsuccessful.
3292
+
3293
+ Returns:
3294
+ tuple[bool, str]: A tuple where the first element is a boolean indicating success or failure of the
3295
+ operation, and the second element is a message providing additional information.
3296
+
3297
+ Raises:
3298
+ DelegateTakeTooHigh: Delegate take is too high.
3299
+ DelegateTakeTooLow: Delegate take is too low.
3300
+ DelegateTxRateLimitExceeded: A transactor exceeded the rate limit for delegate transaction.
3301
+ HotKeyAccountNotExists: The hotkey does not exists.
3302
+ NonAssociatedColdKey: Request to stake, unstake or subscribe is made by a coldkey that is not associated with the hotkey account.
3303
+ bittensor_wallet.errors.PasswordError: Decryption failed or wrong password for decryption provided.
3304
+ bittensor_wallet.errors.KeyFileError: Failed to decode keyfile data.
3305
+
3306
+ The delegate take is a critical parameter in the network's incentive structure, influencing the distribution of
3307
+ rewards among neurons and their nominators.
3308
+ """
3309
+
3310
+ # u16 representation of the take
3311
+ take_u16 = int (take * 0xFFFF )
3312
+
3313
+ current_take = await self .get_delegate_take (hotkey_ss58 )
3314
+ current_take_u16 = int (current_take * 0xFFFF )
3315
+
3316
+ if current_take_u16 == take_u16 :
3317
+ logging .info (":white_heavy_check_mark: [green]Already Set[/green]" )
3318
+ return True , ""
3319
+
3320
+ logging .info (f"Updating { hotkey_ss58 } take: current={ current_take } new={ take } " )
3321
+
3322
+ if current_take_u16 < take_u16 :
3323
+ success , error = await increase_take_extrinsic (
3324
+ self ,
3325
+ wallet ,
3326
+ hotkey_ss58 ,
3327
+ take_u16 ,
3328
+ wait_for_finalization = wait_for_finalization ,
3329
+ wait_for_inclusion = wait_for_inclusion ,
3330
+ raise_error = raise_error ,
3331
+ )
3332
+ else :
3333
+ success , error = await decrease_take_extrinsic (
3334
+ self ,
3335
+ wallet ,
3336
+ hotkey_ss58 ,
3337
+ take_u16 ,
3338
+ wait_for_finalization = wait_for_finalization ,
3339
+ wait_for_inclusion = wait_for_inclusion ,
3340
+ raise_error = raise_error ,
3341
+ )
3342
+
3343
+ if success :
3344
+ logging .info (":white_heavy_check_mark: [green]Take Updated[/green]" )
3345
+
3346
+ return success , error
3347
+
3284
3348
async def set_subnet_identity (
3285
3349
self ,
3286
3350
wallet : "Wallet" ,
@@ -3476,7 +3540,7 @@ async def swap_stake(
3476
3540
wait_for_finalization : bool = False ,
3477
3541
safe_staking : bool = False ,
3478
3542
allow_partial_stake : bool = False ,
3479
- rate_threshold : float = 0.005 ,
3543
+ rate_tolerance : float = 0.005 ,
3480
3544
) -> bool :
3481
3545
"""
3482
3546
Moves stake between subnets while keeping the same coldkey-hotkey pair ownership.
@@ -3491,12 +3555,12 @@ async def swap_stake(
3491
3555
wait_for_inclusion (bool): Waits for the transaction to be included in a block.
3492
3556
wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
3493
3557
safe_staking (bool): If true, enables price safety checks to protect against fluctuating prices. The swap
3494
- will only execute if the price ratio between subnets doesn't exceed the rate threshold .
3558
+ will only execute if the price ratio between subnets doesn't exceed the rate tolerance .
3495
3559
Default is False.
3496
3560
allow_partial_stake (bool): If true and safe_staking is enabled, allows partial stake swaps when
3497
3561
the full amount would exceed the price threshold. If false, the entire swap fails if it would
3498
3562
exceed the threshold. Default is False.
3499
- rate_threshold (float): The maximum allowed increase in the price ratio between subnets
3563
+ rate_tolerance (float): The maximum allowed increase in the price ratio between subnets
3500
3564
(origin_price/destination_price). For example, 0.005 = 0.5% maximum increase. Only used
3501
3565
when safe_staking is True. Default is 0.005.
3502
3566
@@ -3506,9 +3570,9 @@ async def swap_stake(
3506
3570
The price ratio for swap_stake in safe mode is calculated as: origin_subnet_price / destination_subnet_price
3507
3571
When safe_staking is enabled, the swap will only execute if:
3508
3572
- With allow_partial_stake=False: The entire swap amount can be executed without the price ratio
3509
- increasing more than rate_threshold
3573
+ increasing more than rate_tolerance
3510
3574
- With allow_partial_stake=True: A partial amount will be swapped up to the point where the
3511
- price ratio would increase by rate_threshold
3575
+ price ratio would increase by rate_tolerance
3512
3576
"""
3513
3577
amount = check_and_convert_to_balance (amount )
3514
3578
return await swap_stake_extrinsic (
@@ -3522,7 +3586,7 @@ async def swap_stake(
3522
3586
wait_for_finalization = wait_for_finalization ,
3523
3587
safe_staking = safe_staking ,
3524
3588
allow_partial_stake = allow_partial_stake ,
3525
- rate_threshold = rate_threshold ,
3589
+ rate_tolerance = rate_tolerance ,
3526
3590
)
3527
3591
3528
3592
async def transfer_stake (
@@ -3613,7 +3677,7 @@ async def unstake(
3613
3677
wait_for_finalization : bool = False ,
3614
3678
safe_staking : bool = False ,
3615
3679
allow_partial_stake : bool = False ,
3616
- rate_threshold : float = 0.005 ,
3680
+ rate_tolerance : float = 0.005 ,
3617
3681
) -> bool :
3618
3682
"""
3619
3683
Removes a specified amount of stake from a single hotkey account. This function is critical for adjusting
@@ -3628,11 +3692,11 @@ async def unstake(
3628
3692
wait_for_inclusion (bool): Waits for the transaction to be included in a block.
3629
3693
wait_for_finalization (bool): Waits for the transaction to be finalized on the blockchain.
3630
3694
safe_staking (bool): If true, enables price safety checks to protect against fluctuating prices. The unstake
3631
- will only execute if the price change doesn't exceed the rate threshold . Default is False.
3695
+ will only execute if the price change doesn't exceed the rate tolerance . Default is False.
3632
3696
allow_partial_stake (bool): If true and safe_staking is enabled, allows partial unstaking when
3633
3697
the full amount would exceed the price threshold. If false, the entire unstake fails if it would
3634
3698
exceed the threshold. Default is False.
3635
- rate_threshold (float): The maximum allowed price change ratio when unstaking. For example,
3699
+ rate_tolerance (float): The maximum allowed price change ratio when unstaking. For example,
3636
3700
0.005 = 0.5% maximum price decrease. Only used when safe_staking is True. Default is 0.005.
3637
3701
3638
3702
Returns:
@@ -3652,7 +3716,7 @@ async def unstake(
3652
3716
wait_for_finalization = wait_for_finalization ,
3653
3717
safe_staking = safe_staking ,
3654
3718
allow_partial_stake = allow_partial_stake ,
3655
- rate_threshold = rate_threshold ,
3719
+ rate_tolerance = rate_tolerance ,
3656
3720
)
3657
3721
3658
3722
async def unstake_multiple (
0 commit comments