Spaces:
Paused
Paused
import glob | |
import tqdm | |
import pickle | |
import os | |
import datetime | |
import torch | |
import bittensor as bt | |
import pandas as pd | |
import plotly.express as px | |
ROOT_DIR = './data/metagraph/' | |
def load_metagraphs(root_dir, netuid, block_min=0, block_max=3_000_000): | |
metagraphs = [] | |
match_path = os.path.join(root_dir, str(netuid), '*.pkl') | |
files = glob.glob(match_path) | |
print(f'Found {len(files)} metagraphs in {match_path}') | |
valid_files = [path for path in files if block_min <= int(path.split('/')[-1].split('.')[0]) <= block_max] | |
pbar = tqdm.tqdm(valid_files, desc=f'Loading {len(valid_files)} metagraph snapshots') | |
for path in pbar: | |
with open(path, 'rb') as f: | |
metagraph = pickle.load(f) | |
metagraphs.append(metagraph) | |
return sorted(metagraphs, key=lambda x: x.block) | |
def get_block_timestamp(block, subtensor): | |
info = subtensor.substrate.get_block(block_number=int(block)) | |
extrinsic_call = info['extrinsics'][0]['call'] | |
return extrinsic_call.value_serialized['call_args'][0]['value'] | |
def block_to_time(blocks, subtensor=None): | |
if not isinstance(blocks, pd.Series): | |
blocks = pd.Series(blocks) | |
if subtensor is None: | |
subtensor = bt.subtensor(network='archive') | |
timestamps = {} | |
unique_blocks = set(blocks) | |
for block in tqdm.tqdm(unique_blocks, desc=f'Mapping {len(unique_blocks)} blocks to timestamps'): | |
timestamps[block] = get_block_timestamp(block, subtensor) | |
return blocks.map(timestamps).apply(pd.to_datetime, unit='ms') | |
def make_dataframe(netuid, root_dir=ROOT_DIR, cols=None, block_min=0, block_max=3_000_000, weights=False): | |
if cols is None: | |
cols = ['stake','emission','trust','validator_trust','dividends','incentive','R', 'consensus','validator_permit'] | |
frames = [] | |
metagraphs = load_metagraphs(root_dir, netuid, block_min, block_max) | |
for m in metagraphs: | |
frame = pd.DataFrame({k: getattr(m, k) for k in cols}) | |
frame['block'] = m.block.item() | |
frame['netuid'] = netuid | |
frame['uid'] = range(len(frame)) | |
frame['hotkey'] = [axon.hotkey for axon in m.axons] | |
frame['coldkey'] = [axon.coldkey for axon in m.axons] | |
if weights and m.W is not None: | |
# convert NxN tensor to a list of lists so it fits into the dataframe | |
frame['weights'] = [w.tolist() for w in m.W] | |
frames.append(frame) | |
df = pd.concat(frames) | |
df['timestamp'] = block_to_time(df['block']) | |
return df.sort_values(by=['timestamp','block','uid']) | |