From 3f1c71a0d01a1bd93ef915fd7ef48bf57105264e Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Mon, 2 Dec 2024 19:36:01 -0800 Subject: [PATCH 1/7] Multiple improvements for miner and validator --- miner.py | 2 +- validator.py | 23 +++-------------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/miner.py b/miner.py index efb859a..80e0c76 100644 --- a/miner.py +++ b/miner.py @@ -90,7 +90,7 @@ def dummy(self, synapse: Dummy) -> Dummy: def setup_axon(self): # Build and link miner functions to the axon. - self.axon = bt.axon(wallet=self.wallet, port=self.config.axon.port) + self.axon = bt.axon(wallet=self.wallet, config=self.config) # Attach functions to the axon. bt.logging.info(f"Attaching forward function to axon.") diff --git a/validator.py b/validator.py index e05beb7..3f43c6b 100644 --- a/validator.py +++ b/validator.py @@ -5,7 +5,6 @@ import bittensor as bt from protocol import Dummy -from substrateinterface import SubstrateInterface class Validator: @@ -13,15 +12,12 @@ def __init__(self): self.config = self.get_config() self.setup_logging() self.setup_bittensor_objects() - self.last_update = 0 self.my_uid = self.metagraph.hotkeys.index(self.wallet.hotkey.ss58_address) self.scores = [1.0] * len(self.metagraph.S) - self.last_update = 0 - self.current_block = 0 - self.tempo = self.node_query('SubtensorModule', 'Tempo', [self.config.netuid]) + self.last_update = self.subtensor.blocks_since_last_update(self.config.netuid, self.my_uid) + self.tempo = self.subtensor.tempo(self.config.netuid) self.moving_avg_scores = [1.0] * len(self.metagraph.S) self.alpha = 0.1 - self.node = SubstrateInterface(url=self.config.subtensor.chain_endpoint) def get_config(self): # Set up the configuration parser. @@ -92,17 +88,6 @@ def setup_bittensor_objects(self): self.scores = [1.0] * len(self.metagraph.S) bt.logging.info(f"Weights: {self.scores}") - def node_query(self, module, method, params): - try: - result = self.node.query(module, method, params).value - - except Exception: - # reinitilize node - self.node = SubstrateInterface(url=self.config.subtensor.chain_endpoint) - result = self.node.query(module, method, params).value - - return result - def run(self): # The Main Validation Loop. bt.logging.info("Starting validator loop.") @@ -130,9 +115,7 @@ def run(self): self.moving_avg_scores[i] = (1 - self.alpha) * self.moving_avg_scores[i] + self.alpha * current_score bt.logging.info(f"Moving Average Scores: {self.moving_avg_scores}") - - self.current_block = self.node_query('System', 'Number', []) - self.last_update = self.current_block - self.node_query('SubtensorModule', 'LastUpdate', [self.config.netuid])[self.my_uid] + self.last_update = self.subtensor.blocks_since_last_update(self.config.netuid, self.my_uid) # set weights once every tempo + 1 if self.last_update > self.tempo + 1: From fef7c873d0e2d22a8bf8c0f61db292cb9276e364 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Tue, 3 Dec 2024 12:14:02 -0800 Subject: [PATCH 2/7] Bumps bittensor version --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5eb622e..eb56247 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -bittensor>=7.4.0 \ No newline at end of file +bittensor>=8.4.3 \ No newline at end of file From dd52cf6d2d360cca779da165268b81426004db5e Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Tue, 17 Dec 2024 14:22:14 -0800 Subject: [PATCH 3/7] Updates vali and miner --- miner.py | 50 ++++++++++++++++++++++++++++++++------------- validator.py | 57 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 79 insertions(+), 28 deletions(-) diff --git a/miner.py b/miner.py index 80e0c76..c2096a0 100644 --- a/miner.py +++ b/miner.py @@ -7,6 +7,7 @@ from protocol import Dummy + class Miner: def __init__(self): self.config = self.get_config() @@ -17,9 +18,15 @@ def get_config(self): # Set up the configuration parser parser = argparse.ArgumentParser() # TODO: Add your custom miner arguments to the parser. - parser.add_argument('--custom', default='my_custom_value', help='Adds a custom value to the parser.') + parser.add_argument( + "--custom", + default="my_custom_value", + help="Adds a custom value to the parser.", + ) # Adds override arguments for network and netuid. - parser.add_argument('--netuid', type=int, default=1, help="The chain subnet uid.") + parser.add_argument( + "--netuid", type=int, default=1, help="The chain subnet uid." + ) # Adds subtensor specific arguments. bt.subtensor.add_args(parser) # Adds logging specific arguments. @@ -37,7 +44,7 @@ def get_config(self): config.wallet.name, config.wallet.hotkey_str, config.netuid, - 'miner', + "miner", ) ) # Ensure the directory for logging exists. @@ -47,7 +54,9 @@ def get_config(self): def setup_logging(self): # Activate Bittensor's logging with the set configurations. bt.logging(config=self.config, logging_dir=self.config.full_path) - bt.logging.info(f"Running miner for subnet: {self.config.netuid} on network: {self.config.subtensor.network} with config:") + bt.logging.info( + f"Running miner for subnet: {self.config.netuid} on network: {self.config.subtensor.network} with config:" + ) bt.logging.info(self.config) def setup_bittensor_objects(self): @@ -67,25 +76,35 @@ def setup_bittensor_objects(self): bt.logging.info(f"Metagraph: {self.metagraph}") if self.wallet.hotkey.ss58_address not in self.metagraph.hotkeys: - bt.logging.error(f"\nYour miner: {self.wallet} is not registered to chain connection: {self.subtensor} \nRun 'btcli register' and try again.") + bt.logging.error( + f"\nYour miner: {self.wallet} is not registered to chain connection: {self.subtensor} \nRun 'btcli register' and try again." + ) exit() else: # Each miner gets a unique identity (UID) in the network. - self.my_subnet_uid = self.metagraph.hotkeys.index(self.wallet.hotkey.ss58_address) + self.my_subnet_uid = self.metagraph.hotkeys.index( + self.wallet.hotkey.ss58_address + ) bt.logging.info(f"Running miner on uid: {self.my_subnet_uid}") def blacklist_fn(self, synapse: Dummy) -> Tuple[bool, str]: # Ignore requests from unrecognized entities. if synapse.dendrite.hotkey not in self.metagraph.hotkeys: - bt.logging.trace(f'Blacklisting unrecognized hotkey {synapse.dendrite.hotkey}') + bt.logging.trace( + f"Blacklisting unrecognized hotkey {synapse.dendrite.hotkey}" + ) return True, None - bt.logging.trace(f'Not blacklisting recognized hotkey {synapse.dendrite.hotkey}') + bt.logging.trace( + f"Not blacklisting recognized hotkey {synapse.dendrite.hotkey}" + ) return False, None def dummy(self, synapse: Dummy) -> Dummy: # Simple logic: return the input value multiplied by 2. synapse.dummy_output = synapse.dummy_input * 2 - bt.logging.info(f"Received input: {synapse.dummy_input}, sending output: {synapse.dummy_output}") + bt.logging.info( + f"Received input: {synapse.dummy_input}, sending output: {synapse.dummy_output}" + ) return synapse def setup_axon(self): @@ -93,14 +112,16 @@ def setup_axon(self): self.axon = bt.axon(wallet=self.wallet, config=self.config) # Attach functions to the axon. - bt.logging.info(f"Attaching forward function to axon.") + bt.logging.info("Attaching forward function to axon.") self.axon.attach( forward_fn=self.dummy, blacklist_fn=self.blacklist_fn, ) # Serve the axon. - bt.logging.info(f"Serving axon on network: {self.config.subtensor.network} with netuid: {self.config.netuid}") + bt.logging.info( + f"Serving axon on network: {self.config.subtensor.network} with netuid: {self.config.netuid}" + ) self.axon.serve(netuid=self.config.netuid, subtensor=self.subtensor) bt.logging.info(f"Axon: {self.axon}") @@ -120,8 +141,8 @@ def run(self): if step % 60 == 0: self.metagraph.sync() log = ( - f'Block: {self.metagraph.block.item()} | ' - f'Incentive: {self.metagraph.I[self.my_subnet_uid]} | ' + f"Block: {self.metagraph.block.item()} | " + f"Incentive: {self.metagraph.I[self.my_subnet_uid]} | " ) bt.logging.info(log) step += 1 @@ -129,12 +150,13 @@ def run(self): except KeyboardInterrupt: self.axon.stop() - bt.logging.success('Miner killed by keyboard interrupt.') + bt.logging.success("Miner killed by keyboard interrupt.") break except Exception as e: bt.logging.error(traceback.format_exc()) continue + # Run the miner. if __name__ == "__main__": miner = Miner() diff --git a/validator.py b/validator.py index 3f43c6b..481054b 100644 --- a/validator.py +++ b/validator.py @@ -1,4 +1,5 @@ import os +import time import random import argparse import traceback @@ -14,7 +15,9 @@ def __init__(self): self.setup_bittensor_objects() self.my_uid = self.metagraph.hotkeys.index(self.wallet.hotkey.ss58_address) self.scores = [1.0] * len(self.metagraph.S) - self.last_update = self.subtensor.blocks_since_last_update(self.config.netuid, self.my_uid) + self.last_update = self.subtensor.blocks_since_last_update( + self.config.netuid, self.my_uid + ) self.tempo = self.subtensor.tempo(self.config.netuid) self.moving_avg_scores = [1.0] * len(self.metagraph.S) self.alpha = 0.1 @@ -23,9 +26,15 @@ def get_config(self): # Set up the configuration parser. parser = argparse.ArgumentParser() # TODO: Add your custom validator arguments to the parser. - parser.add_argument('--custom', default='my_custom_value', help='Adds a custom value to the parser.') + parser.add_argument( + "--custom", + default="my_custom_value", + help="Adds a custom value to the parser.", + ) # Adds override arguments for network and netuid. - parser.add_argument('--netuid', type=int, default=1, help="The chain subnet uid.") + parser.add_argument( + "--netuid", type=int, default=1, help="The chain subnet uid." + ) # Adds subtensor specific arguments. bt.subtensor.add_args(parser) # Adds logging specific arguments. @@ -41,7 +50,7 @@ def get_config(self): config.wallet.name, config.wallet.hotkey_str, config.netuid, - 'validator', + "validator", ) ) # Ensure the logging directory exists. @@ -51,7 +60,9 @@ def get_config(self): def setup_logging(self): # Set up logging. bt.logging(config=self.config, logging_dir=self.config.full_path) - bt.logging.info(f"Running validator for subnet: {self.config.netuid} on network: {self.config.subtensor.network} with config:") + bt.logging.info( + f"Running validator for subnet: {self.config.netuid} on network: {self.config.subtensor.network} with config:" + ) bt.logging.info(self.config) def setup_bittensor_objects(self): @@ -76,11 +87,15 @@ def setup_bittensor_objects(self): # Connect the validator to the network. if self.wallet.hotkey.ss58_address not in self.metagraph.hotkeys: - bt.logging.error(f"\nYour validator: {self.wallet} is not registered to chain connection: {self.subtensor} \nRun 'btcli register' and try again.") + bt.logging.error( + f"\nYour validator: {self.wallet} is not registered to chain connection: {self.subtensor} \nRun 'btcli register' and try again." + ) exit() else: # Each validator gets a unique identity (UID) in the network. - self.my_subnet_uid = self.metagraph.hotkeys.index(self.wallet.hotkey.ss58_address) + self.my_subnet_uid = self.metagraph.hotkeys.index( + self.wallet.hotkey.ss58_address + ) bt.logging.info(f"Running validator on uid: {self.my_subnet_uid}") # Set up initial scoring weights for validation. @@ -98,24 +113,36 @@ def run(self): # Broadcast a query to all miners on the network. responses = self.dendrite.query( - axons=self.metagraph.axons, - synapse=synapse, - timeout=12 + axons=self.metagraph.axons, synapse=synapse, timeout=12 ) bt.logging.info(f"sending input {synapse.dummy_input}") if responses: - responses = [response.dummy_output for response in responses if response is not None] + responses = [ + response.dummy_output + for response in responses + if response is not None + ] # Log the results. bt.logging.info(f"Received dummy responses: {responses}") + # Adjust the length of moving_avg_scores to match the number of responses + if len(self.moving_avg_scores) < len(responses): + self.moving_avg_scores.extend( + [1] * (len(responses) - len(self.moving_avg_scores)) + ) + # Adjust the scores based on responses from miners and update moving average. for i, resp_i in enumerate(responses): current_score = 1 if resp_i == synapse.dummy_input * 2 else 0 - self.moving_avg_scores[i] = (1 - self.alpha) * self.moving_avg_scores[i] + self.alpha * current_score + self.moving_avg_scores[i] = ( + 1 - self.alpha + ) * self.moving_avg_scores[i] + self.alpha * current_score bt.logging.info(f"Moving Average Scores: {self.moving_avg_scores}") - self.last_update = self.subtensor.blocks_since_last_update(self.config.netuid, self.my_uid) + self.last_update = self.subtensor.blocks_since_last_update( + self.config.netuid, self.my_uid + ) # set weights once every tempo + 1 if self.last_update > self.tempo + 1: @@ -128,9 +155,10 @@ def run(self): wallet=self.wallet, uids=self.metagraph.uids, weights=weights, - wait_for_inclusion=True + wait_for_inclusion=True, ) self.metagraph.sync() + time.sleep(5) except RuntimeError as e: bt.logging.error(e) @@ -140,6 +168,7 @@ def run(self): bt.logging.success("Keyboard interrupt detected. Exiting validator.") exit() + # Run the validator. if __name__ == "__main__": validator = Validator() From dec2f8d0e061740dca247bf741eb5a94174a4f99 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Tue, 17 Dec 2024 14:29:54 -0800 Subject: [PATCH 4/7] Bumps bittensor --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index eb56247..9d63786 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -bittensor>=8.4.3 \ No newline at end of file +bittensor>=8.5.1 \ No newline at end of file From 3a28e4ddd543399ea95f43a08c183d9be9a788a3 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Tue, 17 Dec 2024 14:35:04 -0800 Subject: [PATCH 5/7] Suggestions impl --- validator.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/validator.py b/validator.py index 481054b..f5accbf 100644 --- a/validator.py +++ b/validator.py @@ -44,15 +44,16 @@ def get_config(self): # Parse the config. config = bt.config(parser) # Set up logging directory. - config.full_path = os.path.expanduser( - "{}/{}/{}/netuid{}/{}".format( - config.logging.logging_dir, - config.wallet.name, - config.wallet.hotkey_str, - config.netuid, - "validator", - ) + + logging_path = "{}/{}/{}/netuid{}/{}".format( + config.logging.logging_dir, + config.wallet.name, + config.wallet.hotkey_str, + config.netuid, + "validator", ) + config.full_path = os.path.expanduser(logging_path) + # Ensure the logging directory exists. os.makedirs(config.full_path, exist_ok=True) return config @@ -88,7 +89,7 @@ def setup_bittensor_objects(self): # Connect the validator to the network. if self.wallet.hotkey.ss58_address not in self.metagraph.hotkeys: bt.logging.error( - f"\nYour validator: {self.wallet} is not registered to chain connection: {self.subtensor} \nRun 'btcli register' and try again." + f"Your validator: {self.wallet} is not registered to chain connection: {self.subtensor} \nRun 'btcli register' and try again." ) exit() else: From 8c97e0ed7a85a80bc535623c7057d96cf464532d Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Tue, 17 Dec 2024 14:42:16 -0800 Subject: [PATCH 6/7] Blue for setting weights + improv --- validator.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/validator.py b/validator.py index f5accbf..1f8ede1 100644 --- a/validator.py +++ b/validator.py @@ -44,16 +44,14 @@ def get_config(self): # Parse the config. config = bt.config(parser) # Set up logging directory. - - logging_path = "{}/{}/{}/netuid{}/{}".format( - config.logging.logging_dir, - config.wallet.name, - config.wallet.hotkey_str, - config.netuid, - "validator", + config.full_path = os.path.expanduser( + "{}/{}/{}/netuid{}/validator".format( + config.logging.logging_dir, + config.wallet.name, + config.wallet.hotkey_str, + config.netuid, + ) ) - config.full_path = os.path.expanduser(logging_path) - # Ensure the logging directory exists. os.makedirs(config.full_path, exist_ok=True) return config @@ -89,7 +87,7 @@ def setup_bittensor_objects(self): # Connect the validator to the network. if self.wallet.hotkey.ss58_address not in self.metagraph.hotkeys: bt.logging.error( - f"Your validator: {self.wallet} is not registered to chain connection: {self.subtensor} \nRun 'btcli register' and try again." + f"\nYour validator: {self.wallet} is not registered to chain connection: {self.subtensor} \nRun 'btcli register' and try again." ) exit() else: @@ -149,7 +147,7 @@ def run(self): if self.last_update > self.tempo + 1: total = sum(self.moving_avg_scores) weights = [score / total for score in self.moving_avg_scores] - bt.logging.info(f"Setting weights: {weights}") + bt.logging.info(f"[blue]Setting weights: {weights}[/blue]") # Update the incentive mechanism on the Bittensor blockchain. result = self.subtensor.set_weights( netuid=self.config.netuid, From 29ba5cbffac1c08a7a6172efd524261986d91c32 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Tue, 17 Dec 2024 14:43:47 -0800 Subject: [PATCH 7/7] Remove line break --- validator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validator.py b/validator.py index 1f8ede1..11799d1 100644 --- a/validator.py +++ b/validator.py @@ -87,7 +87,7 @@ def setup_bittensor_objects(self): # Connect the validator to the network. if self.wallet.hotkey.ss58_address not in self.metagraph.hotkeys: bt.logging.error( - f"\nYour validator: {self.wallet} is not registered to chain connection: {self.subtensor} \nRun 'btcli register' and try again." + f"Your validator: {self.wallet} is not registered to chain connection: {self.subtensor} \nRun 'btcli register' and try again." ) exit() else: