-
-
Save garethtdavies/18ee98214bb3511bc2d59a9b8998ea17 to your computer and use it in GitHub Desktop.
Evaluate block producer performance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This script checks the performance of a block producer given the provable slots they won | |
# Producing a block is not the only metric, we also want to know they produced at the canonical height for this slot | |
from gql import gql, Client | |
from gql.transport.aiohttp import AIOHTTPTransport | |
from tabulate import tabulate | |
# Select your transport with a defined url endpoint | |
transport = AIOHTTPTransport(url="https://graphql.minaexplorer.com") | |
# Create a GraphQL client using the defined transport | |
client = Client(transport=transport, fetch_schema_from_transport=True) | |
# This is the block producer we are evaluating | |
creator = "B62qpge4uMq4Vv5Rvc8Gw9qSquUYd6xoW1pz7HQkMSHm6h1o7pvLPAN" | |
output = [] | |
# Get the slots won from the check output of VRF https://github.com/zkvalidator/mina-vrf-rs | |
slots = [ | |
14304, 14311, 14352, 14359, 14385, 14421, 14506, 14519, 14529, 14562, | |
14578, 14672, 14938, 15030, 15084, 15134, 15137, 15208, 15216, 15304, | |
15390, 15409, 15431, 15471, 15716, 15860, 15904, 15928, 15931, 15964, | |
16058, 16264, 16305, 16312, 16387, 16427, 16446, 16456, 16606, 16624, | |
16661, 16669, 16767, 16808, 16838, 16863, 16907, 16928, 16978, 16992, | |
17031, 17048, 17063, 17102, 17125, 17128, 17141, 17175, 17216, 17235, | |
17286, 17290, 17313, 17466, 17542, 17602, 17683, 17691, 17818, 17869, | |
17910, 17924, 17945, 18224, 18230, 18253, 18310, 18445, 18459, 18512, | |
18517, 18518, 18768, 18778, 18802, 18899, 18921, 18935, 18967, 19016, | |
19021, 19098, 19132, 19190, 19254, 19268, 19269, 19288, 19379, 19461, | |
19491, 19547, 19599, 19686, 19690, 19706, 19802, 19845, 19858, 19873, | |
19897, 19906, 19976, 20012, 20077, 20093, 20129, 20159, 20178, 20185, | |
20209, 20231, 20323, 20345, 20363, 20371, 20372, 20377, 20398, 20451, | |
20462, 20524, 20545, 20636, 20771, 20829, 20900, 20925, 20972, 20987, | |
20999, 21068, 21069, 21105, 21236, 21281, 21314, 21342, 21378 | |
] | |
for s in slots: | |
# GraphQL query to get the blocks produced for the current slot | |
query = gql(""" | |
query blocksForSlot {{ | |
blocks(query: {{protocolState: {{consensusState: {{slotSinceGenesis: {slot} }}}}}}) {{ | |
blockHeight | |
canonical | |
creator | |
dateTime | |
stateHash | |
}} | |
}} | |
""".format(slot=s)) | |
result = client.execute(query) | |
# What is the canonical height for this slot? | |
if result["blocks"]: | |
canonical_block = list( | |
filter(lambda d: d['canonical'] == True, result["blocks"])) | |
if canonical_block: | |
canonical_height = canonical_block[0]["blockHeight"] | |
# Did our creator produce at the right height - we might not have the canonical block | |
producer_blocks = list( | |
filter( | |
lambda d: d['creator'] == creator and d['blockHeight'] == | |
canonical_height, result["blocks"])) | |
if producer_blocks: | |
output.append( | |
[s, True, canonical_height, | |
len(result["blocks"])]) | |
else: | |
output.append( | |
[s, False, canonical_height, | |
len(result["blocks"])]) | |
else: | |
# No canonical block for this height - possible a later block reorged this | |
# Is this block produced at a height greater than the maximum we have seen? | |
# GraphQL query to get the canonical height at the time of the slot | |
query2 = gql(""" | |
query heightAtSlot {{ | |
blocks(limit: 1, query: {{canonical: true, protocolState: {{consensusState: {{slotSinceGenesis_lt: {slot} }}}}}}, sortBy: BLOCKHEIGHT_DESC) {{ | |
blockHeight | |
}} | |
}} | |
""".format(slot=s)) | |
result2 = client.execute(query2) | |
prior_height = result2["blocks"][0]["blockHeight"] | |
# Did we produce a block greater than the current height at this slot | |
producer_blocks = list( | |
filter( | |
lambda d: d['creator'] == creator and d['blockHeight'] > | |
prior_height, result["blocks"])) | |
# We produced a block(s) at greater than the current canonical tip and it was valid | |
if producer_blocks: | |
output.append( | |
[s, True, prior_height + 1, | |
len(result["blocks"])]) | |
# It was at the wrong height | |
else: | |
output.append( | |
[s, False, prior_height + 1, | |
len(result["blocks"])]) | |
else: | |
# No block for this slot so cannot have produced | |
output.append([s, False, None, len(result["blocks"])]) | |
produced_correct_height = list(filter(lambda d: d[1] == True, output)) | |
# Table headers | |
headers = [ | |
"Global Slot", "Canonical Height", "Block Height", "# Blocks at Height" | |
] | |
# Output a summary table for each slot | |
print(tabulate(output, headers=headers, tablefmt="pretty")) | |
performance_score = "{:.2%}".format(len(produced_correct_height) / len(output)) | |
print( | |
f"There were {len(output)} slots and the producer produced at the canonical height for {len(produced_correct_height)} slots and has a performance score of {performance_score}." | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sample output: