File size: 6,337 Bytes
4d944cb
41936a6
08e61b4
41936a6
8cdce17
 
4d944cb
8cdce17
5fb35aa
20dfdf1
5bbddad
 
41936a6
 
08e61b4
 
 
 
 
 
41936a6
 
 
 
08e61b4
41936a6
 
 
 
78f61d6
4d944cb
41936a6
8cdce17
08e61b4
 
41936a6
08e61b4
 
b343c97
41936a6
 
7511bc7
41936a6
 
8cdce17
41936a6
 
b343c97
41936a6
b343c97
 
4d944cb
 
 
 
08e61b4
 
 
 
4d944cb
08e61b4
 
 
 
 
 
 
 
 
 
 
4d944cb
 
41936a6
8cdce17
41936a6
4d944cb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08e61b4
 
4d944cb
08e61b4
4d944cb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08e61b4
4d944cb
 
 
 
 
 
 
 
 
 
08e61b4
4d944cb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41936a6
8cdce17
5bbddad
21a364f
 
5fb35aa
5bbddad
 
 
 
c36279d
21a364f
5bbddad
5fb35aa
63f8f2e
5fb35aa
21a364f
ccf9b3b
21a364f
 
 
41936a6
21a364f
78f61d6
41936a6
 
 
 
 
 
 
 
21a364f
 
8cdce17
 
 
20dfdf1
 
21a364f
2d3bb91
21a364f
 
8cdce17
21a364f
 
8cdce17
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
from collections import defaultdict
from enum import Enum
from enum import IntEnum

import gradio as gr
import pandas as pd
import plotly.graph_objects as go

from chain_data import sync_chain, fetch_commitments
from src import Key
from src.chain_data import get_neurons
from wandb_data import get_current_runs, Run, get_blacklisted_keys


class DuplicateStatus(IntEnum):
    SAFE = 0
    DUPLICATE = 1
    PENDING_VERIFICATION = 2


class SubmissionStatus(Enum):
    BLACKLISTED = ("Blacklisted", "gray")
    DUPLICATE = ("Duplicate", "gray")
    PENDING = ("Pending", "orange")
    VERIFYING = ("Verifying", "aqua")
    DONE = ("Done", "springgreen")
    INVALID = ("Invalid", "red")

    @staticmethod
    def get_status(run: Run, hotkey: Key, coldkey: Key, block: int, revision: str) -> "SubmissionStatus":
        if is_blacklisted(hotkey, coldkey):
            return SubmissionStatus.BLACKLISTED

        duplicate_status = is_duplicate_submission(hotkey, revision)
        if duplicate_status == DuplicateStatus.DUPLICATE:
            return SubmissionStatus.DUPLICATE
        elif duplicate_status == DuplicateStatus.PENDING_VERIFICATION:
            return SubmissionStatus.VERIFYING

        if hotkey in run.submissions and block > run.submissions[hotkey].info.block and hotkey not in run.invalid_submissions:
            return SubmissionStatus.PENDING

        if hotkey in run.submissions:
            return SubmissionStatus.DONE

        if hotkey in run.invalid_submissions:
            return SubmissionStatus.INVALID

        return SubmissionStatus.PENDING


def is_blacklisted(hotkey: Key, coldkey: Key) -> bool:
    return hotkey in get_blacklisted_keys().hotkeys or coldkey in get_blacklisted_keys().coldkeys


def is_duplicate_submission(hotkey: Key, revision: str) -> DuplicateStatus:
    duplicate_selection = get_blacklisted_keys().duplicate_selection

    if any(
        submission.hotkey == hotkey and submission.revision == revision
        for submission in duplicate_selection.duplicate_submissions
    ):
        return DuplicateStatus.DUPLICATE

    elif any(
        submission.hotkey == hotkey and submission.revision == revision
        for submission in duplicate_selection.safe_submissions
    ):
        return DuplicateStatus.SAFE

    return DuplicateStatus.PENDING_VERIFICATION


DROPDOWN_OPTIONS = [status.value[0] for status in SubmissionStatus]


def create_duplicate_submissions_plot() -> gr.Plot:
    sync_chain()

    submissions_by_coldkey = defaultdict(lambda: ([], []))

    for hotkey, commitment in fetch_commitments().items():
        neuron = get_neurons().get(hotkey)
        if not neuron:
            continue

        coldkey = neuron.coldkey

        if is_blacklisted(hotkey, coldkey):
            continue

        duplicate_status = is_duplicate_submission(hotkey, commitment.revision)
        if duplicate_status == DuplicateStatus.DUPLICATE:
            submissions_by_coldkey[coldkey][0].append(commitment)
        elif duplicate_status == DuplicateStatus.SAFE:
            submissions_by_coldkey[coldkey][1].append(commitment)

    submissions_by_coldkey = dict(sorted(
        submissions_by_coldkey.items(),
        key=lambda x: len(x[1][0]) + len(x[1][1]),
        reverse=True
    ))

    figure = go.Figure()

    for coldkey, (duplicate_commitments, safe_commitments) in submissions_by_coldkey.items():
        urls_safe = [c.url for c in safe_commitments]
        figure.add_trace(go.Bar(
            x=[f"{coldkey[:6]}..."],
            y=[len(safe_commitments)],
            name="Safe",
            marker_color="green",  # type: ignore
            hovertemplate="<br>".join([
                "Submissions (%{y}):<br>" + "<br>".join(urls_safe)
            ]) + "<extra></extra>"
        ))

        urls_duplicate = [c.url for c in duplicate_commitments]
        figure.add_trace(go.Bar(
            x=[f"{coldkey[:6]}..."],
            y=[len(duplicate_commitments)],
            name="Duplicate",
            marker_color="red",  # type: ignore
            hovertemplate="<br>".join([
                "Submissions (%{y}):<br>" + "<br>".join(urls_duplicate)
            ]) + "<extra></extra>"
        ))

    figure.update_layout(
        title="Duplicate Submissions",
        xaxis_title="Coldkey",
        yaxis_title="# of Submissions",
        barmode="stack",
        showlegend=False,
        autosize=True,
        margin=dict(l=50, r=50, t=50, b=50),
        template="plotly_dark"
    )

    return gr.Plot(figure)


def create_submissions(submission_filters: list[str]) -> gr.Dataframe:
    data: list[list] = []
    sync_chain()
    runs = sorted(get_current_runs(), key=lambda run: run.uid)

    for hotkey, commitment in fetch_commitments().items():
        neuron = get_neurons().get(hotkey)
        if not neuron:
            continue
        coldkey = neuron.coldkey

        row = [
            neuron.uid,
            f"[{'/'.join(commitment.url.split('/')[-2:])}]({commitment.url})",
            f"[{commitment.block}](https://taostats.io/block/{commitment.block}/extrinsics)",
            f"[{commitment.revision}]({commitment.url}/commit/{commitment.revision})",
            f"[{hotkey[:6]}...](https://taostats.io/hotkey/{hotkey})",
            f"[{coldkey[:6]}...](https://taostats.io/coldkey/{coldkey})",
            commitment.contest.name,
        ]

        has_data = False
        for run in runs:
            status = SubmissionStatus.get_status(run, hotkey, coldkey, commitment.block, commitment.revision)
            if status.value[0] in submission_filters:
                row.append(f"<span style='color: {status.value[1]}'>{status.value[0]}</span>")
                has_data = True
            else:
                row.append("")

        if not has_data:
            continue

        data.append(row)

    data.sort(key=lambda x: int(x[2].split('[')[1].split(']')[0]), reverse=True)

    columns = ["UID", "Model", "Block", "Revision", "Hotkey", "Coldkey", "Contest"]
    datatype = ["number", "markdown", "markdown", "markdown", "markdown", "markdown", "markdown"]
    for run in runs:
        columns.append(f"{run.uid}")
        datatype.append("markdown")

    return gr.Dataframe(
        pd.DataFrame(data, columns=columns),
        datatype=datatype,
        interactive=False,
        max_height=800,
    )