bittensor.utils.registration

Contents

bittensor.utils.registration#

Attributes#

Exceptions#

CUDAException

An exception raised when an error occurs in the CUDA environment.

Classes#

LazyLoadedTorch

POWSolution

A solution to the registration PoW problem.

_SolverBase

A process that solves the registration PoW problem.

_Solver

A process that solves the registration PoW problem.

_CUDASolver

A process that solves the registration PoW problem.

RegistrationStatistics

Statistics for a registration.

RegistrationStatisticsLogger

Logs statistics for a registration.

_UsingSpawnStartMethod

Functions#

use_torch()

Force the use of torch over numpy for certain operations.

legacy_torch_api_compat(func)

Convert function operating on numpy Input&Output to legacy torch Input&Output API if use_torch() is True.

_get_real_torch()

log_no_torch_error()

_hex_bytes_to_u8_list(hex_bytes)

_create_seal_hash(block_and_hotkey_hash_bytes, nonce)

_seal_meets_difficulty(seal, difficulty, limit)

_solve_for_nonce_block_cuda(nonce_start, ...)

Tries to solve the POW on a CUDA device for a block of nonces (nonce_start, nonce_start + update_interval * tpb

_solve_for_nonce_block(nonce_start, nonce_end, ...)

Tries to solve the POW for a block of nonces (nonce_start, nonce_end)

_registration_diff_unpack(packed_diff)

Unpacks the packed two 32-bit integers into one 64-bit integer. Little endian.

_registration_diff_pack(diff, packed_diff)

Packs the difficulty into two 32-bit integers. Little endian.

_hash_block_with_hotkey(block_bytes, hotkey_bytes)

Hashes the block with the hotkey using Keccak-256 to get 32 bytes

_update_curr_block(curr_diff, curr_block, ...)

get_cpu_count()

_solve_for_difficulty_fast(subtensor, wallet, netuid)

Solves the POW for registration using multiprocessing.

_get_block_with_retry(subtensor, netuid)

Gets the current block number, difficulty, and block hash from the substrate node.

_check_for_newest_block_and_update(subtensor, netuid, ...)

Checks for a new block and updates the current block information if a new block is found.

_solve_for_difficulty_fast_cuda(subtensor, wallet, netuid)

Solves the registration fast using CUDA

_terminate_workers_and_wait_for_exit(workers)

create_pow(subtensor, wallet, netuid[, ...])

Creates a proof of work for the given subtensor and wallet.

Module Contents#

bittensor.utils.registration.use_torch()[source]#

Force the use of torch over numpy for certain operations.

Return type:

bool

bittensor.utils.registration.legacy_torch_api_compat(func)[source]#

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._get_real_torch()[source]#
bittensor.utils.registration.log_no_torch_error()[source]#
class bittensor.utils.registration.LazyLoadedTorch[source]#
__bool__()[source]#
__getattr__(name)[source]#
bittensor.utils.registration.torch#
exception bittensor.utils.registration.CUDAException[source]#

Bases: Exception

An exception raised when an error occurs in the CUDA environment.

Initialize self. See help(type(self)) for accurate signature.

bittensor.utils.registration._hex_bytes_to_u8_list(hex_bytes)[source]#
Parameters:

hex_bytes (bytes)

bittensor.utils.registration._create_seal_hash(block_and_hotkey_hash_bytes, nonce)[source]#
Parameters:
  • block_and_hotkey_hash_bytes (bytes)

  • nonce (int)

Return type:

bytes

bittensor.utils.registration._seal_meets_difficulty(seal, difficulty, limit)[source]#
Parameters:
class bittensor.utils.registration.POWSolution[source]#

A solution to the registration PoW problem.

nonce: int#
block_number: int#
difficulty: int#
seal: bytes#
is_stale(subtensor)[source]#

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.subtensor)

Return type:

bool

class bittensor.utils.registration._SolverBase(proc_num, num_proc, update_interval, finished_queue, solution_queue, stopEvent, curr_block, curr_block_num, curr_diff, check_block, limit)[source]#

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.

  • newBlockEvent – multiprocessing.Event The event to set by the main process when a new block is finalized in the network. The solver process will check for the event after each update_interval. The solver process will get the new block hash and difficulty and start solving for a new nonce.

  • 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.

proc_num: int#
num_proc: int#
update_interval: int#
finished_queue: multiprocessing.Queue#
solution_queue: multiprocessing.Queue#
newBlockEvent: multiprocessing.Event#
stopEvent: multiprocessing.Event#
hotkey_bytes: bytes#
curr_block: multiprocessing.Array#
curr_block_num: multiprocessing.Value#
curr_diff: multiprocessing.Array#
check_block: multiprocessing.Lock#
limit: int#
abstract run()[source]#

Method to be run in sub-process; can be overridden in sub-class

static create_shared_memory()[source]#

Creates shared memory for the solver processes to use.

Return type:

Tuple[multiprocessing.Array, multiprocessing.Value, multiprocessing.Array]

class bittensor.utils.registration._Solver(proc_num, num_proc, update_interval, finished_queue, solution_queue, stopEvent, curr_block, curr_block_num, curr_diff, check_block, limit)[source]#

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.

  • newBlockEvent – multiprocessing.Event The event to set by the main process when a new block is finalized in the network. The solver process will check for the event after each update_interval. The solver process will get the new block hash and difficulty and start solving for a new nonce.

  • 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()[source]#

Method to be run in sub-process; can be overridden in sub-class

class bittensor.utils.registration._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)[source]#

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.

  • newBlockEvent – multiprocessing.Event The event to set by the main process when a new block is finalized in the network. The solver process will check for the event after each update_interval. The solver process will get the new block hash and difficulty and start solving for a new nonce.

  • 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)

dev_id: int#
tpb: int#
run()[source]#

Method to be run in sub-process; can be overridden in sub-class

bittensor.utils.registration._solve_for_nonce_block_cuda(nonce_start, update_interval, block_and_hotkey_hash_bytes, difficulty, limit, block_number, dev_id, tpb)[source]#

Tries to solve the POW on a CUDA device for a block of nonces (nonce_start, nonce_start + update_interval * tpb

Parameters:
  • nonce_start (int)

  • update_interval (int)

  • block_and_hotkey_hash_bytes (bytes)

  • difficulty (int)

  • limit (int)

  • block_number (int)

  • dev_id (int)

  • tpb (int)

Return type:

Optional[POWSolution]

bittensor.utils.registration._solve_for_nonce_block(nonce_start, nonce_end, block_and_hotkey_hash_bytes, difficulty, limit, block_number)[source]#

Tries to solve the POW for a block of nonces (nonce_start, nonce_end)

Parameters:
  • nonce_start (int)

  • nonce_end (int)

  • block_and_hotkey_hash_bytes (bytes)

  • difficulty (int)

  • limit (int)

  • block_number (int)

Return type:

Optional[POWSolution]

bittensor.utils.registration._registration_diff_unpack(packed_diff)[source]#

Unpacks the packed two 32-bit integers into one 64-bit integer. Little endian.

Parameters:

packed_diff (multiprocessing.Array)

Return type:

int

bittensor.utils.registration._registration_diff_pack(diff, packed_diff)[source]#

Packs the difficulty into two 32-bit integers. Little endian.

Parameters:
  • diff (int)

  • packed_diff (multiprocessing.Array)

bittensor.utils.registration._hash_block_with_hotkey(block_bytes, hotkey_bytes)[source]#

Hashes the block with the hotkey using Keccak-256 to get 32 bytes

Parameters:
Return type:

bytes

bittensor.utils.registration._update_curr_block(curr_diff, curr_block, curr_block_num, block_number, block_bytes, diff, hotkey_bytes, lock)[source]#
Parameters:
  • curr_diff (multiprocessing.Array)

  • curr_block (multiprocessing.Array)

  • curr_block_num (multiprocessing.Value)

  • block_number (int)

  • block_bytes (bytes)

  • diff (int)

  • hotkey_bytes (bytes)

  • lock (multiprocessing.Lock)

bittensor.utils.registration.get_cpu_count()[source]#
Return type:

int

class bittensor.utils.registration.RegistrationStatistics[source]#

Statistics for a registration.

time_spent_total: float#
rounds_total: int#
time_average: float#
time_spent: float#
hash_rate_perpetual: float#
hash_rate: float#
difficulty: int#
block_number: int#
block_hash: bytes#
class bittensor.utils.registration.RegistrationStatisticsLogger(console, output_in_place=True)[source]#

Logs statistics for a registration.

Parameters:
  • console (rich.console.Console)

  • output_in_place (bool)

console: rich.console.Console#
status: rich.status.Status | None#
start()[source]#
Return type:

None

stop()[source]#
Return type:

None

get_status_message(stats, verbose=False)[source]#
Parameters:
Return type:

str

update(stats, verbose=False)[source]#
Parameters:
Return type:

None

bittensor.utils.registration._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)[source]#

Solves the POW for registration using multiprocessing. :param subtensor: Subtensor to connect to for block information and to submit. :param wallet: wallet to use for registration. :param netuid: int

The netuid of the subnet to register to.

Parameters:
  • output_in_place (bool) – bool If true, prints the status in place. Otherwise, prints the status on a new line.

  • num_processes (Optional[int]) – int Number of processes to use.

  • update_interval (Optional[int]) – int Number of nonces to solve before updating block information.

  • n_samples (int) – 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) – bool If true, prints more verbose logging of the registration metrics.

  • wallet (bittensor.wallet)

  • netuid (int)

  • 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._get_block_with_retry(subtensor, netuid)[source]#

Gets the current block number, difficulty, and block hash from the substrate node.

Parameters:
  • subtensor (bittensor.subtensor, required) – The subtensor object to use to get the block number, difficulty, and block hash.

  • netuid (int, required) – The netuid of the network to get the block number, difficulty, and block hash from.

Returns:

The current block number.

difficulty (int):

The current difficulty of the subnet.

block_hash (bytes):

The current block hash.

Return type:

block_number (int)

Raises:
class bittensor.utils.registration._UsingSpawnStartMethod(force=False)[source]#
Parameters:

force (bool)

_old_start_method = None#
_force#
__enter__()[source]#
__exit__(*args)[source]#
bittensor.utils.registration._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)[source]#

Checks for a new block and updates the current block information if a new block is found.

Parameters:
  • subtensor (bittensor.subtensor, required) – The subtensor object to use for getting the current block.

  • netuid (int, required) – The netuid to use for retrieving the difficulty.

  • old_block_number (int, required) – The old block number to check against.

  • hotkey_bytes (bytes, required) – The bytes of the hotkey’s pubkey.

  • curr_diff (multiprocessing.Array, required) – The current difficulty as a multiprocessing array.

  • curr_block (multiprocessing.Array, required) – Where the current block is stored as a multiprocessing array.

  • curr_block_num (multiprocessing.Value, required) – Where the current block number is stored as a multiprocessing value.

  • update_curr_block (Callable, required) – A function that updates the current block.

  • check_block (multiprocessing.Lock, required) – A mp lock that is used to check for a new block.

  • solvers (List[_Solver], required) – A list of solvers to update the current block for.

  • curr_stats (RegistrationStatistics, required) – The current registration statistics to update.

Returns:

(int) The current block number.

Return type:

int

bittensor.utils.registration._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)[source]#

Solves the registration fast using CUDA :param subtensor: bittensor.subtensor

The subtensor node to grab blocks

Parameters:
  • wallet (bittensor.wallet) – bittensor.wallet The wallet to register

  • netuid (int) – int The netuid of the subnet to register to.

  • output_in_place (bool) – bool If true, prints the output in place, otherwise prints to new lines

  • update_interval (int) – int The number of nonces to try before checking for more blocks

  • tpb (int) – int The number of threads per block. CUDA param that should match the GPU capability

  • dev_id (Union[List[int], int]) – 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) – 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) – bool If true, prints more verbose logging of the registration metrics.

  • subtensor (bittensor.subtensor)

  • 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._terminate_workers_and_wait_for_exit(workers)[source]#
Parameters:

workers (List[Union[multiprocessing.Process, multiprocessing.queues.Queue]])

Return type:

None

bittensor.utils.registration.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)[source]#

Creates a proof of work for the given subtensor and wallet. :param subtensor: The subtensor to create a proof of work for. :type subtensor: bittensor.subtensor.subtensor, required :param wallet: The wallet to create a proof of work for. :type wallet: bittensor.wallet.wallet, required :param netuid: The netuid for the subnet to create a proof of work for. :type netuid: int, required :param output_in_place:

If true, prints the progress of the proof of work to the console

in-place. Meaning the progress is printed on the same lines.

Parameters:
  • cuda (bool, optional, defaults to False) – If true, uses CUDA to solve the proof of work.

  • dev_id (Union[List[int], int], optional, defaults to 0) –

    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.

  • tpb (int, optional, defaults to 256) – The number of threads per block to use when solving the proof of work. Should be a multiple of 32.

  • num_processes (int, optional, defaults to None) –

    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.

  • update_interval (int, optional, defaults to None) – The number of nonces to run before checking for a new block.

  • log_verbose (bool, optional, defaults to False) – If true, prints the progress of the proof of work more verbosely.

  • netuid (int)

  • output_in_place (bool, optional, defaults to True)

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.