bittensor.utils.registration.pow#
This module provides utilities for solving Proof-of-Work (PoW) challenges in Bittensor network.
Attributes#
Classes#
A process that solves the registration PoW problem. |
|
A lazy-loading proxy for the torch module. |
|
A solution to the registration PoW problem. |
|
Statistics for a registration. |
|
Logs statistics for a registration. |
|
A process that solves the registration PoW problem. |
|
A process that solves the registration PoW problem. |
Functions#
|
Checks for a new block and updates the current block information if a new block is found. |
|
Create a cryptographic seal hash from the given block and hotkey hash bytes and nonce. |
|
Gets the current block number, difficulty, and block hash from the substrate node. |
|
Hashes the block with the hotkey using Keccak-256 to get 32 bytes |
|
|
|
Packs the difficulty into two 32-bit integers. Little endian. |
|
Unpacks the packed two 32-bit integers into one 64-bit integer. Little endian. |
|
Determines if a seal meets the specified difficulty. |
|
Solves the POW for registration using multiprocessing. |
|
Solves the registration fast using CUDA. |
|
Tries to solve the POW for a block of nonces (nonce_start, nonce_end) |
|
Tries to solve the POW on a CUDA device for a block of nonces (nonce_start, nonce_start + update_interval * tpb |
|
Creates a proof of work for the given subtensor and wallet. |
Returns the number of CPUs in the system. |
|
|
Convert function operating on numpy Input&Output to legacy torch Input&Output API if use_torch() is True. |
|
|
|
Update the current block data with the provided block information and difficulty. |
Force the use of torch over numpy for certain operations. |
Module Contents#
- class bittensor.utils.registration.pow.CUDASolver(proc_num, num_proc, update_interval, finished_queue, solution_queue, stopEvent, curr_block, curr_block_num, curr_diff, check_block, limit, dev_id, tpb)#
Bases:
_SolverBase
A process that solves the registration PoW problem.
- Parameters:
proc_num (int) – The number of the process being created.
num_proc (int) – The total number of processes running.
update_interval (int) – The number of nonces to try to solve before checking for a new block.
finished_queue (multiprocessing.Queue) – The queue to put the process number when a process finishes each update_interval. Used for calculating the average time per update_interval across all processes.
solution_queue (multiprocessing.Queue) – The queue to put the solution the process has found during the pow solve.
stopEvent (multiprocessing.Event) – The event to set by the main process when all the solver processes should stop. The solver process will check for the event after each update_interval. The solver process will stop when the event is set. Used to stop the solver processes when a solution is found.
curr_block (multiprocessing.Array) – The array containing this process’s current block hash. The main process will set the array to the new block hash when a new block is finalized in the network. The solver process will get the new block hash from this array when newBlockEvent is set.
curr_block_num (multiprocessing.Value) – The value containing this process’s current block number. The main process will set the value to the new block number when a new block is finalized in the network. The solver process will get the new block number from this value when newBlockEvent is set.
curr_diff (multiprocessing.Array) – The array containing this process’s current difficulty. The main process will set the array to the new difficulty when a new block is finalized in the network. The solver process will get the new difficulty from this array when newBlockEvent is set.
check_block (multiprocessing.Lock) – The lock to prevent this process from getting the new block data while the main process is updating the data.
limit (int) – The limit of the pow solve for a valid solution.
dev_id (int)
tpb (int)
- run()#
Method to be run in sub-process; can be overridden in sub-class
- class bittensor.utils.registration.pow.LazyLoadedTorch#
A lazy-loading proxy for the torch module.
- __bool__()#
- __getattr__(name)#
- class bittensor.utils.registration.pow.POWSolution#
A solution to the registration PoW problem.
- is_stale(subtensor)#
Synchronous implementation. Returns True if the POW is stale.
This means the block the POW is solved for is within 3 blocks of the current block.
- Parameters:
subtensor (bittensor.core.subtensor.Subtensor)
- Return type:
- async is_stale_async(subtensor)#
Asynchronous implementation. Returns True if the POW is stale.
This means the block the POW is solved for is within 3 blocks of the current block.
- Parameters:
subtensor (bittensor.core.async_subtensor.AsyncSubtensor)
- Return type:
- class bittensor.utils.registration.pow.RegistrationStatistics#
Statistics for a registration.
- class bittensor.utils.registration.pow.RegistrationStatisticsLogger(console=None, output_in_place=True)#
Logs statistics for a registration.
- Parameters:
console (Optional[rich.console.Console])
output_in_place (bool)
- console#
- classmethod get_status_message(stats, verbose=False)#
Generates the status message based on registration statistics.
- Parameters:
stats (RegistrationStatistics)
verbose (bool)
- Return type:
- start()#
- Return type:
None
- stop()#
- Return type:
None
- update(stats, verbose=False)#
- Parameters:
stats (RegistrationStatistics)
verbose (bool)
- Return type:
None
- class bittensor.utils.registration.pow.Solver(proc_num, num_proc, update_interval, finished_queue, solution_queue, stopEvent, curr_block, curr_block_num, curr_diff, check_block, limit)#
Bases:
_SolverBase
A process that solves the registration PoW problem.
- Parameters:
proc_num (int) – The number of the process being created.
num_proc (int) – The total number of processes running.
update_interval (int) – The number of nonces to try to solve before checking for a new block.
finished_queue (multiprocessing.Queue) – The queue to put the process number when a process finishes each update_interval. Used for calculating the average time per update_interval across all processes.
solution_queue (multiprocessing.Queue) – The queue to put the solution the process has found during the pow solve.
stopEvent (multiprocessing.Event) – The event to set by the main process when all the solver processes should stop. The solver process will check for the event after each update_interval. The solver process will stop when the event is set. Used to stop the solver processes when a solution is found.
curr_block (multiprocessing.Array) – The array containing this process’s current block hash. The main process will set the array to the new block hash when a new block is finalized in the network. The solver process will get the new block hash from this array when newBlockEvent is set.
curr_block_num (multiprocessing.Value) – The value containing this process’s current block number. The main process will set the value to the new block number when a new block is finalized in the network. The solver process will get the new block number from this value when newBlockEvent is set.
curr_diff (multiprocessing.Array) – The array containing this process’s current difficulty. The main process will set the array to the new difficulty when a new block is finalized in the network. The solver process will get the new difficulty from this array when newBlockEvent is set.
check_block (multiprocessing.Lock) – The lock to prevent this process from getting the new block data while the main process is updating the data.
limit (int) – The limit of the pow solve for a valid solution.
- run()#
Method to be run in sub-process; can be overridden in sub-class
- class bittensor.utils.registration.pow.UsingSpawnStartMethod(force=False)#
- Parameters:
force (bool)
- __enter__()#
- __exit__(*args)#
- _force#
- _old_start_method = None#
- class bittensor.utils.registration.pow._SolverBase(proc_num, num_proc, update_interval, finished_queue, solution_queue, stopEvent, curr_block, curr_block_num, curr_diff, check_block, limit)#
Bases:
multiprocessing.Process
A process that solves the registration PoW problem.
- Parameters:
proc_num (int) – The number of the process being created.
num_proc (int) – The total number of processes running.
update_interval (int) – The number of nonces to try to solve before checking for a new block.
finished_queue (multiprocessing.Queue) – The queue to put the process number when a process finishes each update_interval. Used for calculating the average time per update_interval across all processes.
solution_queue (multiprocessing.Queue) – The queue to put the solution the process has found during the pow solve.
stopEvent (multiprocessing.Event) – The event to set by the main process when all the solver processes should stop. The solver process will check for the event after each update_interval. The solver process will stop when the event is set. Used to stop the solver processes when a solution is found.
curr_block (multiprocessing.Array) – The array containing this process’s current block hash. The main process will set the array to the new block hash when a new block is finalized in the network. The solver process will get the new block hash from this array when newBlockEvent is set.
curr_block_num (multiprocessing.Value) – The value containing this process’s current block number. The main process will set the value to the new block number when a new block is finalized in the network. The solver process will get the new block number from this value when newBlockEvent is set.
curr_diff (multiprocessing.Array) – The array containing this process’s current difficulty. The main process will set the array to the new difficulty when a new block is finalized in the network. The solver process will get the new difficulty from this array when newBlockEvent is set.
check_block (multiprocessing.Lock) – The lock to prevent this process from getting the new block data while the main process is updating the data.
limit (int) – The limit of the pow solve for a valid solution.
- check_block: multiprocessing.Lock#
Creates shared memory for the solver processes to use.
- Return type:
tuple[multiprocessing.Array, multiprocessing.Value, multiprocessing.Array]
- curr_block: multiprocessing.Array#
- curr_block_num: multiprocessing.Value#
- curr_diff: multiprocessing.Array#
- finished_queue: multiprocessing.Queue#
- newBlockEvent: multiprocessing.Event#
- abstract run()#
Method to be run in sub-process; can be overridden in sub-class
- solution_queue: multiprocessing.Queue#
- stopEvent: multiprocessing.Event#
- bittensor.utils.registration.pow._check_for_newest_block_and_update(subtensor, netuid, old_block_number, hotkey_bytes, curr_diff, curr_block, curr_block_num, update_curr_block_, check_block, solvers, curr_stats)#
Checks for a new block and updates the current block information if a new block is found.
- Parameters:
subtensor (bittensor.core.subtensor.Subtensor) – The subtensor object to use for getting the current block.
netuid (int) – The netuid to use for retrieving the difficulty.
old_block_number (int) – The old block number to check against.
hotkey_bytes (bytes) – The bytes of the hotkey’s pubkey.
curr_diff (multiprocessing.Array) – The current difficulty as a multiprocessing array.
curr_block (multiprocessing.Array) – Where the current block is stored as a multiprocessing array.
curr_block_num (multiprocessing.Value) – Where the current block number is stored as a multiprocessing value.
update_curr_block (Callable) – A function that updates the current block.
check_block (multiprocessing.Lock) – A mp lock that is used to check for a new block.
solvers (list[bittensor.utils.registration.Solver]) – A list of solvers to update the current block for.
curr_stats (bittensor.utils.registration.RegistrationStatistics) – The current registration statistics to update.
update_curr_block_ (Callable)
- Returns:
(int) The current block number.
- Return type:
- bittensor.utils.registration.pow._create_seal_hash(block_and_hotkey_hash_bytes, nonce)#
Create a cryptographic seal hash from the given block and hotkey hash bytes and nonce.
This function generates a seal hash by combining the given block and hotkey hash bytes with a nonce. It first converts the nonce to a byte representation, then concatenates it with the first 64 hex characters of the block and hotkey hash bytes. The result is then hashed using SHA-256 followed by the Keccak-256 algorithm to produce the final seal hash.
- bittensor.utils.registration.pow._get_block_with_retry(subtensor, netuid)#
Gets the current block number, difficulty, and block hash from the substrate node.
- Parameters:
subtensor (bittensor.core.subtensor.Subtensor) – The subtensor object to use to get the block number, difficulty, and block hash.
netuid (int) – The netuid of the network to get the block number, difficulty, and block hash from.
- Returns:
tuple[int, int, bytes] block_number (int): The current block number. difficulty (int): The current difficulty of the subnet. block_hash (bytes): The current block hash.
- Raises:
Exception – If the block hash is None.
ValueError – If the difficulty is None.
- Return type:
- bittensor.utils.registration.pow._get_real_torch()#
- bittensor.utils.registration.pow._hash_block_with_hotkey(block_bytes, hotkey_bytes)#
Hashes the block with the hotkey using Keccak-256 to get 32 bytes
- bittensor.utils.registration.pow._hex_bytes_to_u8_list(hex_bytes)#
- bittensor.utils.registration.pow._registration_diff_pack(diff, packed_diff)#
Packs the difficulty into two 32-bit integers. Little endian.
- Parameters:
diff (int)
packed_diff (multiprocessing.Array)
- bittensor.utils.registration.pow._registration_diff_unpack(packed_diff)#
Unpacks the packed two 32-bit integers into one 64-bit integer. Little endian.
- Parameters:
packed_diff (multiprocessing.Array)
- Return type:
- bittensor.utils.registration.pow._seal_meets_difficulty(seal, difficulty, limit)#
Determines if a seal meets the specified difficulty.
- bittensor.utils.registration.pow._solve_for_difficulty_fast(subtensor, wallet, netuid, output_in_place=True, num_processes=None, update_interval=None, n_samples=10, alpha_=0.8, log_verbose=False)#
Solves the POW for registration using multiprocessing.
- Parameters:
subtensor (bittensor.core.subtensor.Subtensor) – Subtensor instance to connect to for block information and to submit.
wallet (bittensor_wallet.Wallet) – wallet to use for registration.
netuid (int) – The netuid of the subnet to register to.
output_in_place (bool) – If true, prints the status in place. Otherwise, prints the status on a new line.
num_processes (int) – Number of processes to use.
update_interval (int) – Number of nonces to solve before updating block information.
n_samples (int) – The number of samples of the hash_rate to keep for the EWMA.
alpha (float) – The alpha for the EWMA for the hash_rate calculation.
log_verbose (bool) – If true, prints more verbose logging of the registration metrics.
alpha_ (float)
- Return type:
Optional[POWSolution]
Note: The hash rate is calculated as an exponentially weighted moving average in order to make the measure more robust. Note: We can also modify the update interval to do smaller blocks of work, while still updating the block information after a different number of nonces, to increase the transparency of the process while still keeping the speed.
- bittensor.utils.registration.pow._solve_for_difficulty_fast_cuda(subtensor, wallet, netuid, output_in_place=True, update_interval=50000, tpb=512, dev_id=0, n_samples=10, alpha_=0.8, log_verbose=False)#
Solves the registration fast using CUDA.
- Parameters:
subtensor (bittensor.core.subtensor.Subtensor) – The subtensor node to grab blocks.
wallet (bittensor_wallet.Wallet) – The wallet to register.
netuid (int) – The netuid of the subnet to register to.
output_in_place (bool)
update_interval (int) – The number of nonces to try before checking for more blocks.
tpb (int) – The number of threads per block. CUDA param that should match the GPU capability
dev_id (Union[list[int], int]) – The CUDA device IDs to execute the registration on, either a single device or a list of devices.
n_samples (int) – The number of samples of the hash_rate to keep for the EWMA.
alpha (float) – The alpha for the EWMA for the hash_rate calculation.
log_verbose (bool) – If true, prints more verbose logging of the registration metrics.
alpha_ (float)
- Return type:
Optional[POWSolution]
Note: The hash rate is calculated as an exponentially weighted moving average in order to make the measure more robust.
- bittensor.utils.registration.pow._solve_for_nonce_block(nonce_start, nonce_end, block_and_hotkey_hash_bytes, difficulty, limit, block_number)#
Tries to solve the POW for a block of nonces (nonce_start, nonce_end)
- bittensor.utils.registration.pow._solve_for_nonce_block_cuda(nonce_start, update_interval, block_and_hotkey_hash_bytes, difficulty, limit, block_number, dev_id, tpb)#
Tries to solve the POW on a CUDA device for a block of nonces (nonce_start, nonce_start + update_interval * tpb
- bittensor.utils.registration.pow.create_pow(subtensor, wallet, netuid, output_in_place=True, cuda=False, dev_id=0, tpb=256, num_processes=None, update_interval=None, log_verbose=False)#
Creates a proof of work for the given subtensor and wallet.
- Parameters:
subtensor (bittensor.core.subtensor.Subtensor) – The subtensor to create a proof of work for.
wallet (bittensor_wallet.Wallet) – The wallet to create a proof of work for.
netuid (int) – The netuid for the subnet to create a proof of work for.
output_in_place (bool) – If true, prints the progress of the proof of work to the console in-place. Meaning the progress is printed on the same lines. Default is
True
.cuda (bool) – If true, uses CUDA to solve the proof of work. Default is
False
.dev_id (Union[List[int], int]) – The CUDA device id(s) to use. If cuda is true and dev_id is a list, then multiple CUDA devices will be used to solve the proof of work. Default is
0
.tpb (int) – The number of threads per block to use when solving the proof of work. Should be a multiple of 32. Default is
256
.num_processes (Optional[int]) – The number of processes to use when solving the proof of work. If None, then the number of processes is equal to the number of CPU cores. Default is None.
update_interval (Optional[int]) – The number of nonces to run before checking for a new block. Default is
None
.log_verbose (bool) – If true, prints the progress of the proof of work more verbosely. Default is
False
.
- Returns:
The proof of work solution or None if the wallet is already registered or there is a different error.
- Return type:
Optional[Dict[str, Any]]
- Raises:
ValueError – If the subnet does not exist.
- bittensor.utils.registration.pow.get_cpu_count()#
Returns the number of CPUs in the system.
- Return type:
- bittensor.utils.registration.pow.legacy_torch_api_compat(func)#
Convert function operating on numpy Input&Output to legacy torch Input&Output API if use_torch() is True.
- Parameters:
func (function) – Function with numpy Input/Output to be decorated.
- Returns:
Decorated function.
- Return type:
decorated (function)
- bittensor.utils.registration.pow.log_no_torch_error()#
- bittensor.utils.registration.pow.terminate_workers_and_wait_for_exit(workers)#
- Parameters:
workers (list[Union[multiprocessing.Process, multiprocessing.queues.Queue]])
- Return type:
None
- bittensor.utils.registration.pow.torch#
- bittensor.utils.registration.pow.update_curr_block(curr_diff, curr_block, curr_block_num, block_number, block_bytes, diff, hotkey_bytes, lock)#
Update the current block data with the provided block information and difficulty.
This function updates the current block and its difficulty in a thread-safe manner. It sets the current block number, hashes the block with the hotkey, updates the current block bytes, and packs the difficulty.
- Parameters:
curr_diff (multiprocessing.Array) – Shared array to store the current difficulty.
curr_block (multiprocessing.Array) – Shared array to store the current block data.
curr_block_num (multiprocessing.Value) – Shared value to store the current block number.
block_number (int) – The block number to set as the current block number.
block_bytes (bytes) – The block data bytes to be hashed with the hotkey.
diff (int) – The difficulty value to be packed into the current difficulty array.
hotkey_bytes (bytes) – The hotkey bytes used for hashing the block.
lock (multiprocessing.Lock) – A lock to ensure thread-safe updates.