bittensor icon indicating copy to clipboard operation
bittensor copied to clipboard

Set Subnet Specific Takes

Open distributedstatemachine opened this issue 1 year ago • 0 comments

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

  • Implement a new CLI command to set subnet-specific take rates for delegates
  • Allow delegates to specify multiple subnet-take pairs in a single command

Tasks

  • [ ] Create a new CLI command btcli delegate set_takes
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
  • [ ] Implement input parsing for subnet-take pairs
@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
  • [ ] Add validation for subnet existence and take rate limits
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}")
  • [ ] Integrate with the set_delegate_takes extrinsic
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:

distributedstatemachine avatar Jul 01 '24 09:07 distributedstatemachine