opentensor / bittensor

Internet-scale Neural Networks
https://www.bittensor.com/
MIT License
816 stars 274 forks source link

Set Subnet Specific Takes #2088

Open distributedstatemachine opened 2 days ago

distributedstatemachine commented 2 days ago

Description

Currently, delegates can only set a global take rate that applies to all subnets. To provide more flexibility and allow delegates to optimize their strategies for different subnets, we need to implement a feature that enables delegates to set subnet-specific take rates via the command line. This is required for the Child Keys feature.

This feature will utilize the set_delegate_takes extrinsic, which allows setting take rates for multiple subnets simultaneously. The implementation should include proper error handling, rate limiting, and validation to ensure the takes do not exceed the initial default take.

Acceptance Criteria

Tasks

class SetDelegateTakesCommand:
    @staticmethod
    def run(cli: "bittensor.cli"):
        r"""Set subnet-specific take rates for a delegate."""
        wallet = bittensor.wallet(config=cli.config)
        subtensor = bittensor.subtensor(config=cli.config)
        SetDelegateTakesCommand._run(cli, subtensor, wallet)

    @staticmethod
    def _run(cli: "bittensor.cli", subtensor: "bittensor.subtensor", wallet: "bittensor.wallet"):
        # Implementation details here
@staticmethod
def add_args(parser: argparse.ArgumentParser):
    parser.add_argument(
        '--subnet_take_pairs',
        type=str,
        nargs='+',
        help='List of subnet-take pairs in the format "netuid:take_rate"'
    )

@staticmethod
def check_config(config: "bittensor.config"):
    if not config.is_set('subnet_take_pairs'):
        raise ValueError("--subnet_take_pairs argument is required")

    subnet_take_pairs = []
    for pair in config.subnet_take_pairs:
        netuid, take_rate = pair.split(':')
        subnet_take_pairs.append((int(netuid), int(float(take_rate) * 65535)))

    config.subnet_take_pairs = subnet_take_pairs
def validate_subnet_take_pairs(subtensor: "bittensor.subtensor", subnet_take_pairs: List[Tuple[int, int]]):
    for netuid, take_rate in subnet_take_pairs:
        if not subtensor.subnet_exists(netuid):
            raise ValueError(f"Subnet with netuid {netuid} does not exist")

        max_take_rate = subtensor.get_max_take_rate()
        if take_rate > max_take_rate:
            raise ValueError(f"Take rate for subnet {netuid} exceeds the maximum allowed rate of {max_take_rate / 65535:.4f}")
def set_delegate_takes(subtensor: "bittensor.subtensor", wallet: "bittensor.wallet", subnet_take_pairs: List[Tuple[int, int]]):
    success = subtensor._do_set_delegate_takes(
        wallet=wallet,
        hotkey_ss58=wallet.hotkey.ss58_address,
        takes=subnet_take_pairs,
        wait_for_inclusion=True,
        wait_for_finalization=True,
    )
    return success

Related links: