From 3927ffd6ea8810b2c58020859dec46c1db491c9b Mon Sep 17 00:00:00 2001 From: tuyennhv Date: Tue, 9 Jan 2024 17:31:45 +0700 Subject: [PATCH 1/3] chore: update Grafana panels for gossip validation (#6255) --- dashboards/lodestar_networking.json | 187 +++++++++++----------------- 1 file changed, 76 insertions(+), 111 deletions(-) diff --git a/dashboards/lodestar_networking.json b/dashboards/lodestar_networking.json index 77e4be04048f..e17cabf32048 100644 --- a/dashboards/lodestar_networking.json +++ b/dashboards/lodestar_networking.json @@ -104,6 +104,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 4, @@ -189,6 +190,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -270,6 +272,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -351,6 +354,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -534,9 +538,10 @@ "values": false }, "showUnfilled": true, - "text": {} + "text": {}, + "valueMode": "color" }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "targets": [ { "datasource": { @@ -588,9 +593,10 @@ "values": false }, "showUnfilled": true, - "text": {} + "text": {}, + "valueMode": "color" }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "targets": [ { "datasource": { @@ -631,6 +637,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -711,6 +718,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -829,7 +837,7 @@ "reverse": false } }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "targets": [ { "datasource": { @@ -886,6 +894,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -1000,6 +1009,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -1138,6 +1148,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 4, @@ -1223,6 +1234,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 4, @@ -1309,6 +1321,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineStyle": { "fill": "solid" @@ -1450,7 +1463,7 @@ "unit": "short" } }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "reverseYBuckets": false, "targets": [ { @@ -1508,6 +1521,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 4, @@ -1648,7 +1662,7 @@ "unit": "short" } }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "reverseYBuckets": false, "targets": [ { @@ -1760,7 +1774,7 @@ "unit": "short" } }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "reverseYBuckets": false, "targets": [ { @@ -1818,6 +1832,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 4, @@ -1931,6 +1946,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -2015,6 +2031,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -2141,7 +2158,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -2251,7 +2268,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -2347,7 +2364,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "pointradius": 2, "points": false, "renderer": "flot", @@ -2426,6 +2443,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -2505,6 +2523,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -2635,6 +2654,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -2718,6 +2738,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -2801,6 +2822,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -2886,6 +2908,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -2967,6 +2990,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -3050,6 +3074,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -3135,6 +3160,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -3230,6 +3256,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -3348,6 +3375,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -3476,6 +3504,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -3556,6 +3585,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -3674,7 +3704,7 @@ "reverse": false } }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "targets": [ { "datasource": { @@ -3717,6 +3747,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -3799,86 +3830,7 @@ "tooltip": false, "viz": false }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "unit": "percentunit" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 154 - }, - "id": 540, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "multi", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "lodestar_gossip_validation_queue_current_drop_ratio", - "legendFormat": "{{topic}}", - "range": true, - "refId": "A" - } - ], - "title": "Drop Ratio", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -3971,6 +3923,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -4050,6 +4003,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -4159,6 +4113,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -4263,6 +4218,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -4342,6 +4298,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -4450,6 +4407,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -4558,6 +4516,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -4574,7 +4533,8 @@ "mode": "off" } }, - "mappings": [] + "mappings": [], + "unit": "percentunit" }, "overrides": [] }, @@ -4584,7 +4544,7 @@ "x": 0, "y": 187 }, - "id": 615, + "id": 624, "options": { "legend": { "calcs": [], @@ -4604,25 +4564,14 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(lodestar_gossip_attestation_use_head_block_state_count{caller=\"validateGossipAttestation\"}[$rate_interval])", - "legendFormat": "head_state", + "expr": "rate(lodestar_gossip_attestation_shuffling_cache_hit_count[$rate_interval])\n/\n(\n rate(lodestar_gossip_attestation_shuffling_cache_hit_count[$rate_interval])\n +\n (\n rate(lodestar_gossip_attestation_shuffling_cache_miss_count[$rate_interval])\n or\n vector(0)\n )\n)\nor\nvector(1)\n", + "instant": false, + "legendFormat": "hit_percentage", "range": true, "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "rate(lodestar_gossip_attestation_use_head_block_state_dialed_to_target_epoch_count{caller=\"validateGossipAttestation\"}[$rate_interval])", - "hide": false, - "legendFormat": "head_state_dialed_to_target_epoch", - "range": true, - "refId": "B" } ], - "title": "Used States", + "title": "Shuffling Cache Hit", "type": "timeseries" }, { @@ -4649,6 +4598,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -4770,6 +4720,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -4886,7 +4837,7 @@ "reverse": false } }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "targets": [ { "datasource": { @@ -4943,6 +4894,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -5071,6 +5023,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -5199,6 +5152,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -5303,6 +5257,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -5409,6 +5364,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -5489,6 +5445,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -5570,6 +5527,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -5651,6 +5609,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -5732,6 +5691,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -5815,6 +5775,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -5898,6 +5859,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -5979,6 +5941,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -6060,6 +6023,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -6141,6 +6105,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -6199,7 +6164,7 @@ } ], "refresh": "10s", - "schemaVersion": 37, + "schemaVersion": 38, "style": "dark", "tags": [ "lodestar" From 55bc136944b841d45b4d76d6f5dafff0a6b99c2e Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Tue, 9 Jan 2024 14:37:14 +0100 Subject: [PATCH 2/3] chore: fix block production step time panels (#6271) --- dashboards/lodestar_block_production.json | 531 +++++++++++----------- 1 file changed, 270 insertions(+), 261 deletions(-) diff --git a/dashboards/lodestar_block_production.json b/dashboards/lodestar_block_production.json index b999e47a33d4..96ab44c6a550 100644 --- a/dashboards/lodestar_block_production.json +++ b/dashboards/lodestar_block_production.json @@ -54,180 +54,206 @@ "liveNow": false, "panels": [ { - "type": "timeseries", - "title": "Full block production avg time with steps", + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, "gridPos": { + "h": 1, + "w": 24, "x": 0, - "y": 1, - "w": 12, - "h": 8 + "y": 0 }, + "id": 166, + "panels": [], + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "refId": "A" + } + ], + "title": "Block Production", + "type": "row" + }, + { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 30, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 1 + }, "id": 546, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, "targets": [ { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "refId": "proposerSlashing", - "expr": "rate(beacon_block_production_execution_steps_seconds{step=\"proposerSlashing\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds{step=\"proposerSlashing\"}[$rate_interval])", - "range": true, - "instant": false, - "hide": false, "editorMode": "code", + "exemplar": false, + "expr": "rate(beacon_block_production_execution_steps_seconds_sum{step=\"proposerSlashing\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds_count{step=\"proposerSlashing\"}[$rate_interval])", + "hide": false, + "instant": false, "legendFormat": "{{step}}", - "exemplar": false + "range": true, + "refId": "proposerSlashing" }, { - "refId": "attesterSlashings", - "expr": "rate(beacon_block_production_execution_steps_seconds{step=\"attesterSlashings\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds{step=\"attesterSlashings\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_execution_steps_seconds_sum{step=\"attesterSlashings\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds_count{step=\"attesterSlashings\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "attesterSlashings" }, { - "refId": "voluntaryExits", - "expr": "rate(beacon_block_production_execution_steps_seconds{step=\"voluntaryExits\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds{step=\"voluntaryExits\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_execution_steps_seconds_sum{step=\"voluntaryExits\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds_count{step=\"voluntaryExits\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "voluntaryExits" }, { - "refId": "blsToExecutionChanges", - "expr": "rate(beacon_block_production_execution_steps_seconds{step=\"blsToExecutionChanges\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds{step=\"blsToExecutionChanges\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_execution_steps_seconds_sum{step=\"blsToExecutionChanges\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds_count{step=\"blsToExecutionChanges\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "blsToExecutionChanges" }, { - "refId": "attestations", - "expr": "rate(beacon_block_production_execution_steps_seconds{step=\"attestations\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds{step=\"attestations\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_execution_steps_seconds_sum{step=\"attestations\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds_count{step=\"attestations\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "attestations" }, { - "refId": "eth1DataAndDeposits", - "expr": "rate(beacon_block_production_execution_steps_seconds{step=\"eth1DataAndDeposits\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds{step=\"eth1DataAndDeposits\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_execution_steps_seconds_sum{step=\"eth1DataAndDeposits\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds_count{step=\"eth1DataAndDeposits\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "eth1DataAndDeposits" }, { - "refId": "syncAggregate", - "expr": "rate(beacon_block_production_execution_steps_seconds{step=\"syncAggregate\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds{step=\"syncAggregate\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_execution_steps_seconds_sum{step=\"syncAggregate\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds_count{step=\"syncAggregate\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "syncAggregate" }, { - "refId": "executionPayload", - "expr": "rate(beacon_block_production_execution_steps_seconds{step=\"executionPayload\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds{step=\"executionPayload\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_execution_steps_seconds_sum{step=\"executionPayload\"}[$rate_interval])\n/\nrate(beacon_block_production_execution_steps_seconds_count{step=\"executionPayload\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "executionPayload" } ], - "options": { - "tooltip": { - "mode": "multi", - "sort": "none" - }, - "legend": { - "showLegend": true, - "displayMode": "list", - "placement": "bottom", - "calcs": [] - } - }, - "fieldConfig": { - "defaults": { - "custom": { - "drawStyle": "line", - "lineInterpolation": "linear", - "barAlignment": 0, - "lineWidth": 1, - "fillOpacity": 30, - "gradientMode": "opacity", - "spanNulls": false, - "insertNulls": false, - "showPoints": "auto", - "pointSize": 5, - "stacking": { - "mode": "normal", - "group": "A" - }, - "axisPlacement": "auto", - "axisLabel": "", - "axisColorMode": "text", - "scaleDistribution": { - "type": "linear" - }, - "axisCenteredZero": false, - "hideFrom": { - "tooltip": false, - "viz": false, - "legend": false - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "color": { - "mode": "palette-classic" - }, - "mappings": [], - "unit": "s" - }, - "overrides": [] - }, - "transformations": [] + "title": "Full block production avg time with steps", + "transformations": [], + "type": "timeseries" }, { "datasource": { @@ -236,62 +262,62 @@ }, "fieldConfig": { "defaults": { + "color": { + "mode": "palette-classic" + }, "custom": { - "drawStyle": "line", - "lineInterpolation": "linear", + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", "barAlignment": 0, - "lineWidth": 1, + "drawStyle": "line", "fillOpacity": 30, "gradientMode": "opacity", - "spanNulls": false, + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, "insertNulls": false, - "showPoints": "auto", + "lineInterpolation": "linear", + "lineWidth": 1, "pointSize": 5, - "stacking": { - "mode": "normal", - "group": "A" - }, - "axisPlacement": "auto", - "axisLabel": "", - "axisColorMode": "text", "scaleDistribution": { "type": "linear" }, - "axisCenteredZero": false, - "hideFrom": { - "tooltip": false, - "viz": false, - "legend": false + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" }, "thresholdsStyle": { "mode": "off" } }, - "color": { - "mode": "palette-classic" - }, "mappings": [], "unit": "s" }, "overrides": [] }, "gridPos": { - "x": 12, - "y": 1, + "h": 8, "w": 12, - "h": 8 + "x": 12, + "y": 1 }, "id": 547, "options": { - "tooltip": { - "mode": "multi", - "sort": "none" - }, "legend": { - "showLegend": true, + "calcs": [], "displayMode": "list", "placement": "bottom", - "calcs": [] + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" } }, "targets": [ @@ -300,136 +326,110 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "refId": "proposerSlashing", - "expr": "rate(beacon_block_production_builder_steps_seconds{step=\"proposerSlashing\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds{step=\"proposerSlashing\"}[$rate_interval])", - "range": true, - "instant": false, - "hide": false, "editorMode": "code", + "exemplar": false, + "expr": "rate(beacon_block_production_builder_steps_seconds_sum{step=\"proposerSlashing\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds_count{step=\"proposerSlashing\"}[$rate_interval])", + "hide": false, + "instant": false, "legendFormat": "{{step}}", - "exemplar": false - }, - { - "refId": "attesterSlashings", - "expr": "rate(beacon_block_production_builder_steps_seconds{step=\"attesterSlashings\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds{step=\"attesterSlashings\"}[$rate_interval])", "range": true, - "instant": false, - "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" - }, - "hide": false, - "editorMode": "code", - "legendFormat": "{{step}}" + "refId": "proposerSlashing" }, { - "refId": "voluntaryExits", - "expr": "rate(beacon_block_production_builder_steps_seconds{step=\"voluntaryExits\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds{step=\"voluntaryExits\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_builder_steps_seconds_sum{step=\"attesterSlashings\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds_count{step=\"attesterSlashings\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "attesterSlashings" }, { - "refId": "blsToExecutionChanges", - "expr": "rate(beacon_block_production_builder_steps_seconds{step=\"blsToExecutionChanges\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds{step=\"blsToExecutionChanges\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_builder_steps_seconds_sum{step=\"voluntaryExits\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds_count{step=\"voluntaryExits\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "voluntaryExits" }, { - "refId": "attestations", - "expr": "rate(beacon_block_production_builder_steps_seconds{step=\"attestations\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds{step=\"attestations\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_builder_steps_seconds_sum{step=\"blsToExecutionChanges\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds_count{step=\"blsToExecutionChanges\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "blsToExecutionChanges" }, { - "refId": "eth1DataAndDeposits", - "expr": "rate(beacon_block_production_builder_steps_seconds{step=\"eth1DataAndDeposits\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds{step=\"eth1DataAndDeposits\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_builder_steps_seconds_sum{step=\"attestations\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds_count{step=\"attestations\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "attestations" }, { - "refId": "syncAggregate", - "expr": "rate(beacon_block_production_builder_steps_seconds{step=\"syncAggregate\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds{step=\"syncAggregate\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" + "expr": "rate(beacon_block_production_builder_steps_seconds_sum{step=\"eth1DataAndDeposits\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds_count{step=\"eth1DataAndDeposits\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "eth1DataAndDeposits" }, { - "refId": "executionPayload", - "expr": "rate(beacon_block_production_builder_steps_seconds{step=\"executionPayload\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds{step=\"executionPayload\"}[$rate_interval])", - "range": true, - "instant": false, "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "hide": false, "editorMode": "code", - "legendFormat": "{{step}}" - } - ], - "title": "Blinded block production avg time with steps", - "type": "timeseries", - "transformations": [] - }, - { - "collapsed": false, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 166, - "panels": [], - "targets": [ + "expr": "rate(beacon_block_production_builder_steps_seconds_sum{step=\"syncAggregate\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds_count{step=\"syncAggregate\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "syncAggregate" + }, { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "refId": "A" + "editorMode": "code", + "expr": "rate(beacon_block_production_builder_steps_seconds_sum{step=\"executionPayload\"}[$rate_interval])\n/\nrate(beacon_block_production_builder_steps_seconds_count{step=\"executionPayload\"}[$rate_interval])", + "hide": false, + "instant": false, + "legendFormat": "{{step}}", + "range": true, + "refId": "executionPayload" } ], - "title": "Block Production", - "type": "row" + "title": "Blinded block production avg time with steps", + "transformations": [], + "type": "timeseries" }, { "datasource": { @@ -455,6 +455,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -540,7 +541,7 @@ "h": 8, "w": 12, "x": 0, - "y": 1 + "y": 9 }, "id": 168, "options": { @@ -611,6 +612,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -636,7 +638,7 @@ "h": 8, "w": 12, "x": 12, - "y": 1 + "y": 9 }, "id": 170, "options": { @@ -657,11 +659,13 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, + "editorMode": "code", "exemplar": false, "expr": "rate(beacon_block_production_seconds_sum[$rate_interval])\n/\nrate(beacon_block_production_seconds_count[$rate_interval])", "format": "heatmap", "interval": "", - "legendFormat": "{{instance}} - {{source}}", + "legendFormat": "{{source}}", + "range": true, "refId": "A" } ], @@ -692,6 +696,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -716,7 +721,7 @@ "h": 8, "w": 12, "x": 0, - "y": 9 + "y": 17 }, "id": 528, "options": { @@ -780,7 +785,7 @@ "h": 8, "w": 12, "x": 12, - "y": 9 + "y": 17 }, "heatmap": {}, "hideZeroBuckets": false, @@ -826,7 +831,7 @@ "unit": "s" } }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "reverseYBuckets": false, "targets": [ { @@ -882,6 +887,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -906,7 +912,7 @@ "h": 8, "w": 12, "x": 0, - "y": 17 + "y": 25 }, "id": 511, "options": { @@ -1036,7 +1042,7 @@ "h": 8, "w": 12, "x": 12, - "y": 17 + "y": 25 }, "hiddenSeries": false, "id": 378, @@ -1056,7 +1062,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "pointradius": 0.5, "points": true, "renderer": "flot", @@ -1131,7 +1137,7 @@ "h": 8, "w": 12, "x": 0, - "y": 25 + "y": 33 }, "hiddenSeries": false, "id": 376, @@ -1153,7 +1159,7 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "9.3.2", + "pluginVersion": "10.1.1", "pointradius": 0.5, "points": true, "renderer": "flot", @@ -1233,6 +1239,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -1257,7 +1264,7 @@ "h": 8, "w": 12, "x": 12, - "y": 25 + "y": 33 }, "id": 532, "options": { @@ -1334,6 +1341,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -1358,7 +1366,7 @@ "h": 7, "w": 12, "x": 0, - "y": 33 + "y": 41 }, "id": 531, "options": { @@ -1441,6 +1449,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -1465,7 +1474,7 @@ "h": 7, "w": 12, "x": 12, - "y": 33 + "y": 41 }, "id": 534, "options": { @@ -1516,7 +1525,7 @@ "h": 6, "w": 12, "x": 0, - "y": 40 + "y": 48 }, "id": 535, "options": { @@ -1620,7 +1629,7 @@ "h": 8, "w": 12, "x": 12, - "y": 40 + "y": 48 }, "id": 537, "options": { @@ -1669,7 +1678,7 @@ "h": 1, "w": 24, "x": 0, - "y": 48 + "y": 56 }, "id": 541, "panels": [], @@ -1700,7 +1709,7 @@ "h": 8, "w": 12, "x": 0, - "y": 49 + "y": 57 }, "id": 543, "options": { @@ -1778,7 +1787,7 @@ "h": 8, "w": 12, "x": 12, - "y": 49 + "y": 57 }, "id": 545, "options": { @@ -1880,7 +1889,7 @@ "h": 8, "w": 12, "x": 0, - "y": 57 + "y": 65 }, "id": 539, "options": { @@ -1925,7 +1934,7 @@ } ], "refresh": "10s", - "schemaVersion": 37, + "schemaVersion": 38, "style": "dark", "tags": [ "lodestar" From 0f377dd75102f82da4612ff267ed751e63b6b210 Mon Sep 17 00:00:00 2001 From: g11tech Date: Tue, 9 Jan 2024 19:57:22 +0530 Subject: [PATCH 3/3] feat: reject builder blocks if engine indicates censorship (#6258) * feat: reject builder blocks if engine indicates censorship * apply feeback * fix tests * small refac and test fixes and selection test extenstion for override combinations * make typing tighter for blindedblock * apply feedbac * Fix typo --------- Co-authored-by: Nico Flaig --- .../src/api/impl/validator/index.ts | 35 ++++++++++--- packages/beacon-node/src/chain/chain.ts | 51 ++++++++++++------- packages/beacon-node/src/chain/interface.ts | 17 ++++--- .../chain/produceBlock/produceBlockBody.ts | 16 ++++-- .../beacon-node/src/execution/engine/http.ts | 7 ++- .../src/execution/engine/interface.ts | 7 ++- .../beacon-node/src/execution/engine/types.ts | 14 ++++- .../api/impl/validator/produceBlockV2.test.ts | 6 ++- .../api/impl/validator/produceBlockV3.test.ts | 44 +++++++++++----- 9 files changed, 143 insertions(+), 54 deletions(-) diff --git a/packages/beacon-node/src/api/impl/validator/index.ts b/packages/beacon-node/src/api/impl/validator/index.ts index 9f98c606d525..839c1df7c463 100644 --- a/packages/beacon-node/src/api/impl/validator/index.ts +++ b/packages/beacon-node/src/api/impl/validator/index.ts @@ -353,7 +353,7 @@ export function getValidatorApi({ strictFeeRecipientCheck, skipHeadChecksAndUpdate, }: Omit & {skipHeadChecksAndUpdate?: boolean} = {} - ): Promise { + ): Promise { const source = ProducedBlockSource.engine; metrics?.blockProductionRequests.inc({source}); @@ -371,7 +371,7 @@ export function getValidatorApi({ let timer; try { timer = metrics?.blockProductionTime.startTimer(); - const {block, executionPayloadValue, consensusBlockValue} = await chain.produceBlock({ + const {block, executionPayloadValue, consensusBlockValue, shouldOverrideBuilder} = await chain.produceBlock({ slot, randaoReveal, graffiti: toGraffitiBuffer(graffiti || ""), @@ -408,9 +408,10 @@ export function getValidatorApi({ version, executionPayloadValue, consensusBlockValue, + shouldOverrideBuilder, }; } else { - return {data: block, version, executionPayloadValue, consensusBlockValue}; + return {data: block, version, executionPayloadValue, consensusBlockValue, shouldOverrideBuilder}; } } finally { if (timer) timer({source}); @@ -504,7 +505,10 @@ export function getValidatorApi({ // reference index of promises in the race const promisesOrder = [ProducedBlockSource.builder, ProducedBlockSource.engine]; [blindedBlock, fullBlock] = await racePromisesWithCutoff< - routes.validator.ProduceBlockOrContentsRes | routes.validator.ProduceBlindedBlockRes | null + | ((routes.validator.ProduceBlockOrContentsRes | routes.validator.ProduceBlindedBlockRes) & { + shouldOverrideBuilder?: boolean; + }) + | null >( [blindedBlockPromise, fullBlockPromise], BLOCK_PRODUCTION_RACE_CUTOFF_MS, @@ -552,8 +556,20 @@ export function getValidatorApi({ const blockValueEngine = enginePayloadValue + gweiToWei(consensusBlockValueEngine); // Total block value is in wei let executionPayloadSource: ProducedBlockSource | null = null; + const shouldOverrideBuilder = fullBlock?.shouldOverrideBuilder ?? false; - if (fullBlock && blindedBlock) { + // handle the builder override case separately + if (shouldOverrideBuilder === true) { + executionPayloadSource = ProducedBlockSource.engine; + logger.info("Selected engine block as censorship suspected in builder blocks", { + // winston logger doesn't like bigint + enginePayloadValue: `${enginePayloadValue}`, + consensusBlockValueEngine: `${consensusBlockValueEngine}`, + blockValueEngine: `${blockValueEngine}`, + shouldOverrideBuilder, + slot, + }); + } else if (fullBlock && blindedBlock) { switch (builderSelection) { case routes.validator.BuilderSelection.MaxProfit: { if ( @@ -579,7 +595,7 @@ export function getValidatorApi({ executionPayloadSource = ProducedBlockSource.builder; } } - logger.verbose(`Selected executionPayloadSource=${executionPayloadSource} block`, { + logger.info(`Selected executionPayloadSource=${executionPayloadSource} block`, { builderSelection, // winston logger doesn't like bigint builderBoostFactor: `${builderBoostFactor}`, @@ -589,24 +605,27 @@ export function getValidatorApi({ consensusBlockValueBuilder: `${consensusBlockValueBuilder}`, blockValueEngine: `${blockValueEngine}`, blockValueBuilder: `${blockValueBuilder}`, + shouldOverrideBuilder, slot, }); } else if (fullBlock && !blindedBlock) { executionPayloadSource = ProducedBlockSource.engine; - logger.verbose("Selected engine block: no builder block produced", { + logger.info("Selected engine block: no builder block produced", { // winston logger doesn't like bigint enginePayloadValue: `${enginePayloadValue}`, consensusBlockValueEngine: `${consensusBlockValueEngine}`, blockValueEngine: `${blockValueEngine}`, + shouldOverrideBuilder, slot, }); } else if (blindedBlock && !fullBlock) { executionPayloadSource = ProducedBlockSource.builder; - logger.verbose("Selected builder block: no engine block produced", { + logger.info("Selected builder block: no engine block produced", { // winston logger doesn't like bigint builderPayloadValue: `${builderPayloadValue}`, consensusBlockValueBuilder: `${consensusBlockValueBuilder}`, blockValueBuilder: `${blockValueBuilder}`, + shouldOverrideBuilder, slot, }); } diff --git a/packages/beacon-node/src/chain/chain.ts b/packages/beacon-node/src/chain/chain.ts index 456bfef70b0a..ac2f97128c16 100644 --- a/packages/beacon-node/src/chain/chain.ts +++ b/packages/beacon-node/src/chain/chain.ts @@ -470,22 +470,32 @@ export class BeaconChain implements IBeaconChain { return data && {block: data, executionOptimistic: false}; } - produceBlock( - blockAttributes: BlockAttributes - ): Promise<{block: allForks.BeaconBlock; executionPayloadValue: Wei; consensusBlockValue: Gwei}> { + produceBlock(blockAttributes: BlockAttributes): Promise<{ + block: allForks.BeaconBlock; + executionPayloadValue: Wei; + consensusBlockValue: Gwei; + shouldOverrideBuilder?: boolean; + }> { return this.produceBlockWrapper(BlockType.Full, blockAttributes); } - produceBlindedBlock( - blockAttributes: BlockAttributes - ): Promise<{block: allForks.BlindedBeaconBlock; executionPayloadValue: Wei; consensusBlockValue: Gwei}> { + produceBlindedBlock(blockAttributes: BlockAttributes): Promise<{ + block: allForks.BlindedBeaconBlock; + executionPayloadValue: Wei; + consensusBlockValue: Gwei; + }> { return this.produceBlockWrapper(BlockType.Blinded, blockAttributes); } async produceBlockWrapper( blockType: T, {randaoReveal, graffiti, slot, feeRecipient}: BlockAttributes - ): Promise<{block: AssembledBlockType; executionPayloadValue: Wei; consensusBlockValue: Gwei}> { + ): Promise<{ + block: AssembledBlockType; + executionPayloadValue: Wei; + consensusBlockValue: Gwei; + shouldOverrideBuilder?: boolean; + }> { const head = this.forkChoice.getHead(); const state = await this.regen.getBlockSlotState( head.blockRoot, @@ -497,16 +507,21 @@ export class BeaconChain implements IBeaconChain { const proposerIndex = state.epochCtx.getBeaconProposer(slot); const proposerPubKey = state.epochCtx.index2pubkey[proposerIndex].toBytes(); - const {body, blobs, executionPayloadValue} = await produceBlockBody.call(this, blockType, state, { - randaoReveal, - graffiti, - slot, - feeRecipient, - parentSlot: slot - 1, - parentBlockRoot, - proposerIndex, - proposerPubKey, - }); + const {body, blobs, executionPayloadValue, shouldOverrideBuilder} = await produceBlockBody.call( + this, + blockType, + state, + { + randaoReveal, + graffiti, + slot, + feeRecipient, + parentSlot: slot - 1, + parentBlockRoot, + proposerIndex, + proposerPubKey, + } + ); // The hashtree root computed here for debug log will get cached and hence won't introduce additional delays const bodyRoot = @@ -557,7 +572,7 @@ export class BeaconChain implements IBeaconChain { this.metrics?.blockProductionCaches.producedContentsCache.set(this.producedContentsCache.size); } - return {block, executionPayloadValue, consensusBlockValue: proposerReward}; + return {block, executionPayloadValue, consensusBlockValue: proposerReward, shouldOverrideBuilder}; } /** diff --git a/packages/beacon-node/src/chain/interface.ts b/packages/beacon-node/src/chain/interface.ts index 880a5e86071a..a2f7fba34093 100644 --- a/packages/beacon-node/src/chain/interface.ts +++ b/packages/beacon-node/src/chain/interface.ts @@ -154,12 +154,17 @@ export interface IBeaconChain { getContents(beaconBlock: deneb.BeaconBlock): deneb.Contents; - produceBlock( - blockAttributes: BlockAttributes - ): Promise<{block: allForks.BeaconBlock; executionPayloadValue: Wei; consensusBlockValue: Gwei}>; - produceBlindedBlock( - blockAttributes: BlockAttributes - ): Promise<{block: allForks.BlindedBeaconBlock; executionPayloadValue: Wei; consensusBlockValue: Gwei}>; + produceBlock(blockAttributes: BlockAttributes): Promise<{ + block: allForks.BeaconBlock; + executionPayloadValue: Wei; + consensusBlockValue: Gwei; + shouldOverrideBuilder?: boolean; + }>; + produceBlindedBlock(blockAttributes: BlockAttributes): Promise<{ + block: allForks.BlindedBeaconBlock; + executionPayloadValue: Wei; + consensusBlockValue: Gwei; + }>; /** Process a block until complete */ processBlock(block: BlockInput, opts?: ImportBlockOpts): Promise; diff --git a/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts b/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts index 3c2bec223eca..0b6ff7b1316b 100644 --- a/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts +++ b/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts @@ -109,12 +109,20 @@ export async function produceBlockBody( proposerIndex: ValidatorIndex; proposerPubKey: BLSPubkey; } -): Promise<{body: AssembledBodyType; blobs: BlobsResult; executionPayloadValue: Wei}> { +): Promise<{ + body: AssembledBodyType; + blobs: BlobsResult; + executionPayloadValue: Wei; + shouldOverrideBuilder?: boolean; +}> { // Type-safe for blobs variable. Translate 'null' value into 'preDeneb' enum // TODO: Not ideal, but better than just using null. // TODO: Does not guarantee that preDeneb enum goes with a preDeneb block let blobsResult: BlobsResult; let executionPayloadValue: Wei; + // even though shouldOverrideBuilder is relevant for the engine response, for simplicity of typing + // we just return it undefined for the builder which anyway doesn't get consumed downstream + let shouldOverrideBuilder: boolean | undefined; const fork = currentState.config.getForkName(blockSlot); const logMeta: Record = { @@ -295,9 +303,11 @@ export async function produceBlockBody( const engineRes = await this.executionEngine.getPayload(fork, payloadId); const {executionPayload, blobsBundle} = engineRes; + shouldOverrideBuilder = engineRes.shouldOverrideBuilder; + (blockBody as allForks.ExecutionBlockBody).executionPayload = executionPayload; executionPayloadValue = engineRes.executionPayloadValue; - Object.assign(logMeta, {transactions: executionPayload.transactions.length}); + Object.assign(logMeta, {transactions: executionPayload.transactions.length, shouldOverrideBuilder}); const fetchedTime = Date.now() / 1000 - computeTimeAtSlot(this.config, blockSlot, this.genesisTime); this.metrics?.blockPayload.payloadFetchedTime.observe({prepType}, fetchedTime); @@ -380,7 +390,7 @@ export async function produceBlockBody( Object.assign(logMeta, {executionPayloadValue}); this.logger.verbose("Produced beacon block body", logMeta); - return {body: blockBody as AssembledBodyType, blobs: blobsResult, executionPayloadValue}; + return {body: blockBody as AssembledBodyType, blobs: blobsResult, executionPayloadValue, shouldOverrideBuilder}; } /** diff --git a/packages/beacon-node/src/execution/engine/http.ts b/packages/beacon-node/src/execution/engine/http.ts index 70df97ba1e4a..91ceabaf2770 100644 --- a/packages/beacon-node/src/execution/engine/http.ts +++ b/packages/beacon-node/src/execution/engine/http.ts @@ -363,7 +363,12 @@ export class ExecutionEngineHttp implements IExecutionEngine { async getPayload( fork: ForkName, payloadId: PayloadId - ): Promise<{executionPayload: allForks.ExecutionPayload; executionPayloadValue: Wei; blobsBundle?: BlobsBundle}> { + ): Promise<{ + executionPayload: allForks.ExecutionPayload; + executionPayloadValue: Wei; + blobsBundle?: BlobsBundle; + shouldOverrideBuilder?: boolean; + }> { const method = ForkSeq[fork] >= ForkSeq.deneb ? "engine_getPayloadV3" diff --git a/packages/beacon-node/src/execution/engine/interface.ts b/packages/beacon-node/src/execution/engine/interface.ts index 9a7ee3963379..e5f612fc0965 100644 --- a/packages/beacon-node/src/execution/engine/interface.ts +++ b/packages/beacon-node/src/execution/engine/interface.ts @@ -136,7 +136,12 @@ export interface IExecutionEngine { getPayload( fork: ForkName, payloadId: PayloadId - ): Promise<{executionPayload: allForks.ExecutionPayload; executionPayloadValue: Wei; blobsBundle?: BlobsBundle}>; + ): Promise<{ + executionPayload: allForks.ExecutionPayload; + executionPayloadValue: Wei; + blobsBundle?: BlobsBundle; + shouldOverrideBuilder?: boolean; + }>; getPayloadBodiesByHash(blockHash: DATA[]): Promise<(ExecutionPayloadBody | null)[]>; diff --git a/packages/beacon-node/src/execution/engine/types.ts b/packages/beacon-node/src/execution/engine/types.ts index 4f24480e0b96..72a0100f7a51 100644 --- a/packages/beacon-node/src/execution/engine/types.ts +++ b/packages/beacon-node/src/execution/engine/types.ts @@ -107,6 +107,7 @@ type ExecutionPayloadRpcWithValue = { // even though CL tracks this as executionPayloadValue, EL returns this as blockValue blockValue: QUANTITY; blobsBundle?: BlobsBundleRpc; + shouldOverrideBuilder?: boolean; }; type ExecutionPayloadResponse = ExecutionPayloadRpc | ExecutionPayloadRpcWithValue; @@ -207,19 +208,28 @@ export function hasPayloadValue(response: ExecutionPayloadResponse): response is export function parseExecutionPayload( fork: ForkName, response: ExecutionPayloadResponse -): {executionPayload: allForks.ExecutionPayload; executionPayloadValue: Wei; blobsBundle?: BlobsBundle} { +): { + executionPayload: allForks.ExecutionPayload; + executionPayloadValue: Wei; + blobsBundle?: BlobsBundle; + shouldOverrideBuilder?: boolean; +} { let data: ExecutionPayloadRpc; let executionPayloadValue: Wei; let blobsBundle: BlobsBundle | undefined; + let shouldOverrideBuilder: boolean; + if (hasPayloadValue(response)) { executionPayloadValue = quantityToBigint(response.blockValue); data = response.executionPayload; blobsBundle = response.blobsBundle ? parseBlobsBundle(response.blobsBundle) : undefined; + shouldOverrideBuilder = response.shouldOverrideBuilder ?? false; } else { data = response; // Just set it to zero as default executionPayloadValue = BigInt(0); blobsBundle = undefined; + shouldOverrideBuilder = false; } const executionPayload = { @@ -269,7 +279,7 @@ export function parseExecutionPayload( (executionPayload as deneb.ExecutionPayload).excessBlobGas = quantityToBigint(excessBlobGas); } - return {executionPayload, executionPayloadValue, blobsBundle}; + return {executionPayload, executionPayloadValue, blobsBundle, shouldOverrideBuilder}; } export function serializePayloadAttributes(data: PayloadAttributes): PayloadAttributesRpc { diff --git a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts index 3e96f3b932c8..9ca426672efe 100644 --- a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts +++ b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts @@ -85,7 +85,11 @@ describe("api/validator - produceBlockV2", function () { const feeRecipient = "0xcccccccccccccccccccccccccccccccccccccccc"; const api = getValidatorApi(modules); - server.chainStub.produceBlock.mockResolvedValue({block: fullBlock, executionPayloadValue, consensusBlockValue}); + server.chainStub.produceBlock.mockResolvedValue({ + block: fullBlock, + executionPayloadValue, + consensusBlockValue, + }); // check if expectedFeeRecipient is passed to produceBlock await api.produceBlockV2(slot, randaoReveal, graffiti, {feeRecipient}); diff --git a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts index 83e1e7887510..3a87b709b741 100644 --- a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts +++ b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts @@ -41,23 +41,38 @@ describe("api/validator - produceBlockV3", function () { vi.clearAllMocks(); }); - const testCases: [routes.validator.BuilderSelection, number | null, number | null, number, string][] = [ - [routes.validator.BuilderSelection.MaxProfit, 1, 0, 0, "builder"], - [routes.validator.BuilderSelection.MaxProfit, 1, 2, 1, "engine"], - [routes.validator.BuilderSelection.MaxProfit, null, 0, 0, "engine"], - [routes.validator.BuilderSelection.MaxProfit, 0, null, 1, "builder"], - - [routes.validator.BuilderSelection.BuilderAlways, 1, 2, 0, "builder"], - [routes.validator.BuilderSelection.BuilderAlways, 1, 0, 1, "builder"], - [routes.validator.BuilderSelection.BuilderAlways, null, 0, 0, "engine"], - [routes.validator.BuilderSelection.BuilderAlways, 0, null, 1, "builder"], - - [routes.validator.BuilderSelection.BuilderOnly, 0, 2, 0, "builder"], - [routes.validator.BuilderSelection.ExecutionOnly, 2, 0, 1, "execution"], + const testCases: [routes.validator.BuilderSelection, number | null, number | null, number, boolean, string][] = [ + [routes.validator.BuilderSelection.MaxProfit, 1, 0, 0, false, "builder"], + [routes.validator.BuilderSelection.MaxProfit, 1, 2, 1, false, "engine"], + [routes.validator.BuilderSelection.MaxProfit, null, 0, 0, false, "engine"], + [routes.validator.BuilderSelection.MaxProfit, 0, null, 1, false, "builder"], + [routes.validator.BuilderSelection.MaxProfit, 0, null, 1, true, "builder"], + [routes.validator.BuilderSelection.MaxProfit, 1, 1, 1, true, "engine"], + [routes.validator.BuilderSelection.MaxProfit, 2, 1, 1, true, "engine"], + + [routes.validator.BuilderSelection.BuilderAlways, 1, 2, 0, false, "builder"], + [routes.validator.BuilderSelection.BuilderAlways, 1, 0, 1, false, "builder"], + [routes.validator.BuilderSelection.BuilderAlways, null, 0, 0, false, "engine"], + [routes.validator.BuilderSelection.BuilderAlways, 0, null, 1, false, "builder"], + [routes.validator.BuilderSelection.BuilderAlways, 0, 1, 1, true, "engine"], + [routes.validator.BuilderSelection.BuilderAlways, 1, 1, 1, true, "engine"], + [routes.validator.BuilderSelection.BuilderAlways, 1, null, 1, true, "builder"], + + [routes.validator.BuilderSelection.BuilderOnly, 0, 2, 0, false, "builder"], + [routes.validator.BuilderSelection.ExecutionOnly, 2, 0, 1, false, "engine"], + [routes.validator.BuilderSelection.BuilderOnly, 1, 1, 0, true, "builder"], + [routes.validator.BuilderSelection.ExecutionOnly, 1, 1, 1, true, "engine"], ]; testCases.forEach( - ([builderSelection, builderPayloadValue, enginePayloadValue, consensusBlockValue, finalSelection]) => { + ([ + builderSelection, + builderPayloadValue, + enginePayloadValue, + consensusBlockValue, + shouldOverrideBuilder, + finalSelection, + ]) => { it(`produceBlockV3 - ${finalSelection} produces block`, async () => { syncStub = server.syncStub; modules = { @@ -89,6 +104,7 @@ describe("api/validator - produceBlockV3", function () { block: fullBlock, executionPayloadValue: BigInt(enginePayloadValue), consensusBlockValue: BigInt(consensusBlockValue), + shouldOverrideBuilder, }); } else { chainStub.produceBlock.mockRejectedValue(Error("not produced"));