diff --git a/spartan/metrics/grafana/dashboards/l1_fees.json b/spartan/metrics/grafana/dashboards/l1_fees.json index 33747c63c2ed..39e7d204dee7 100644 --- a/spartan/metrics/grafana/dashboards/l1_fees.json +++ b/spartan/metrics/grafana/dashboards/l1_fees.json @@ -1218,7 +1218,99 @@ "type": "prometheus", "uid": "${data_source}" }, - "description": "Inclusion rate by strategy for blocks that reached 100% blob capacity", + "description": "Current maximum number of blobs per L1 block based on Ethereum upgrade schedule (Pectra: 9, Fusaka: 9, BPO1: 15, BPO2: 21)", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "9": { + "color": "blue", + "text": "9 blobs (Pectra/Fusaka)" + }, + "15": { + "color": "green", + "text": "15 blobs (BPO1)" + }, + "21": { + "color": "purple", + "text": "21 blobs (BPO2)" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": 0 + }, + { + "color": "green", + "value": 10 + }, + { + "color": "purple", + "value": 16 + } + ] + }, + "unit": "blobs" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 46 + }, + "id": 67, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "editorMode": "code", + "expr": "max(max_over_time(aztec_fisherman_fee_analysis_max_blob_capacity{k8s_namespace_name=\"$namespace\"}[$__range]))", + "legendFormat": "Current Max", + "range": true, + "refId": "A" + } + ], + "title": "L1 Max Blob Capacity", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "description": "Inclusion rate by strategy when blocks reached 100% blob capacity", "fieldConfig": { "defaults": { "color": { @@ -1276,8 +1368,8 @@ }, "gridPos": { "h": 9, - "w": 24, - "x": 0, + "w": 20, + "x": 4, "y": 46 }, "id": 61, @@ -1288,7 +1380,7 @@ "mean" ], "displayMode": "table", - "placement": "right", + "placement": "bottom", "showLegend": true }, "tooltip": { @@ -1305,7 +1397,7 @@ "uid": "${data_source}" }, "editorMode": "code", - "expr": "sum by(aztec_fisherman_strategy_id) (\n increase(aztec_fisherman_fee_analysis_would_be_included{k8s_namespace_name=\"$namespace\",aztec_ok=\"true\"}[$__rate_interval])\n * on() group_left()\n (aztec_fisherman_fee_analysis_block_blobs_full{k8s_namespace_name=\"$namespace\",aztec_ok=\"true\"} > 0)\n) / sum by(aztec_fisherman_strategy_id) (\n increase(aztec_fisherman_fee_analysis_would_be_included{k8s_namespace_name=\"$namespace\"}[$__rate_interval])\n * on() group_left()\n (aztec_fisherman_fee_analysis_block_blobs_full{k8s_namespace_name=\"$namespace\"} > 0)\n)", + "expr": "sum by(aztec_fisherman_strategy_id) (increase(aztec_fisherman_fee_analysis_would_be_included{k8s_namespace_name=\"$namespace\",aztec_ok=\"true\",aztec_block_full=\"true\"}[$__rate_interval])) / sum by(aztec_fisherman_strategy_id) (increase(aztec_fisherman_fee_analysis_would_be_included{k8s_namespace_name=\"$namespace\",aztec_block_full=\"true\"}[$__rate_interval]))", "legendFormat": "{{aztec_fisherman_strategy_id}}", "range": true, "refId": "A" @@ -1314,41 +1406,118 @@ "title": "Inclusion Rate by Strategy (Full Blocks Only)", "type": "timeseries" }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 55 - }, - "id": 50, - "panels": [], - "title": "Mined Block Transaction Fees", - "type": "row" - }, { "datasource": { "type": "prometheus", "uid": "${data_source}" }, - "description": "Distribution of total transaction costs for blob transactions in mined blocks", + "description": "How much more priority fee (in Gwei) would have been needed to get included in full blocks", "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" + "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 20, + "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, "scaleDistribution": { "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" } }, "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + }, + "unit": "gwei" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 55 + }, + "id": 63, + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "editorMode": "code", + "expr": "sum by(aztec_fisherman_strategy_id) (increase(aztec_fisherman_fee_analysis_priority_fee_delta_gwei_sum{k8s_namespace_name=\"$namespace\",aztec_block_full=\"true\"}[$__rate_interval])) / sum by(aztec_fisherman_strategy_id) (increase(aztec_fisherman_fee_analysis_priority_fee_delta_gwei_count{k8s_namespace_name=\"$namespace\",aztec_block_full=\"true\"}[$__rate_interval]))", + "legendFormat": "{{aztec_fisherman_strategy_id}}", + "range": true, + "refId": "A" + } + ], + "title": "Average Priority Fee Gap by Strategy (Full Blocks - Negative = Underpaid)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${data_source}" + }, + "description": "Total number of blocks that reached 100% blob capacity", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], "thresholds": { "mode": "absolute", "steps": [ @@ -1358,11 +1527,11 @@ }, { "color": "yellow", - "value": 0.005 + "value": 10 }, { "color": "red", - "value": 0.01 + "value": 50 } ] } @@ -1370,49 +1539,28 @@ "overrides": [] }, "gridPos": { - "h": 10, - "w": 12, + "h": 6, + "w": 6, "x": 0, - "y": 56 + "y": 64 }, - "id": 51, + "id": 64, "options": { - "calculate": false, - "cellGap": 2, - "cellValues": {}, - "color": { - "exponent": 0.5, - "fill": "dark-orange", - "mode": "scheme", - "reverse": false, - "scale": "exponential", - "scheme": "Spectral", - "steps": 128 - }, - "exemplars": { - "color": "rgba(255,0,255,0.7)" - }, - "filterValues": { - "le": 1e-9 - }, - "legend": { - "show": true - }, - "rowsFrame": { - "layout": "auto" - }, - "showValue": "never", - "tooltip": { - "mode": "single", - "showColorScale": false, - "yHistogram": true + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false }, - "yAxis": { - "axisLabel": "Total Cost (ETH)", - "axisPlacement": "left", - "reverse": false, - "unit": "ETH" - } + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, "pluginVersion": "12.3.0", "targets": [ @@ -1422,35 +1570,58 @@ "uid": "${data_source}" }, "editorMode": "code", - "expr": "sum by(le) (rate(aztec_fisherman_fee_analysis_mined_blob_tx_total_cost_eth_bucket{k8s_namespace_name=\"$namespace\"}[$__rate_interval]))", - "format": "heatmap", - "legendFormat": "{{le}}", + "expr": "sum(increase(aztec_fisherman_fee_analysis_block_blobs_full{k8s_namespace_name=\"$namespace\",aztec_ok=\"true\"}[$__range])) / count(count by(aztec_fisherman_strategy_id) (aztec_fisherman_fee_analysis_block_blobs_full{k8s_namespace_name=\"$namespace\"}))", + "legendFormat": "Total Full Blocks", "range": true, "refId": "A" } ], - "title": "Total Transaction Cost Distribution (Blob Txs)", - "type": "heatmap" + "title": "Total Full Blocks Analyzed", + "type": "stat" }, { "datasource": { "type": "prometheus", "uid": "${data_source}" }, - "description": "Distribution of priority fee per gas for blob transactions in mined blocks", + "description": "Rate of full blocks over time - shows when congestion is happening", "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" + "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "bars", + "fillOpacity": 80, + "gradientMode": "none", "hideFrom": { "legend": false, "tooltip": false, "viz": false }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, "scaleDistribution": { "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" } }, "mappings": [], @@ -1460,63 +1631,34 @@ { "color": "green", "value": 0 - }, - { - "color": "yellow", - "value": 10 - }, - { - "color": "red", - "value": 50 } ] - } + }, + "unit": "short" }, "overrides": [] }, "gridPos": { - "h": 10, - "w": 12, - "x": 12, - "y": 56 + "h": 6, + "w": 18, + "x": 6, + "y": 64 }, - "id": 52, + "id": 66, "options": { - "calculate": false, - "cellGap": 2, - "cellValues": {}, - "color": { - "exponent": 0.5, - "fill": "dark-orange", - "mode": "scheme", - "reverse": false, - "scale": "exponential", - "scheme": "Spectral", - "steps": 128 - }, - "exemplars": { - "color": "rgba(255,0,255,0.7)" - }, - "filterValues": { - "le": 1e-9 - }, "legend": { - "show": true - }, - "rowsFrame": { - "layout": "auto" + "calcs": [ + "sum", + "mean" + ], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, - "showValue": "never", "tooltip": { + "hideZeros": false, "mode": "single", - "showColorScale": false, - "yHistogram": true - }, - "yAxis": { - "axisLabel": "Priority Fee (Gwei)", - "axisPlacement": "left", - "reverse": false, - "unit": "gwei" + "sort": "none" } }, "pluginVersion": "12.3.0", @@ -1527,15 +1669,27 @@ "uid": "${data_source}" }, "editorMode": "code", - "expr": "sum by(le) (rate(aztec_fisherman_fee_analysis_mined_blob_tx_priority_fee_gwei_bucket{k8s_namespace_name=\"$namespace\"}[$__rate_interval]))", - "format": "heatmap", - "legendFormat": "{{le}}", + "expr": "sum(increase(aztec_fisherman_fee_analysis_block_blobs_full{k8s_namespace_name=\"$namespace\",aztec_ok=\"true\"}[$__rate_interval])) / count(count by(aztec_fisherman_strategy_id) (aztec_fisherman_fee_analysis_block_blobs_full{k8s_namespace_name=\"$namespace\"}))", + "legendFormat": "Full Blocks per Interval", "range": true, "refId": "A" } ], - "title": "Priority Fee per Gas Distribution (Blob Txs)", - "type": "heatmap" + "title": "Full Block Rate Over Time", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 70 + }, + "id": 50, + "panels": [], + "title": "Mined Block Transaction Fees", + "type": "row" }, { "collapsed": false, @@ -1543,7 +1697,7 @@ "h": 1, "w": 24, "x": 0, - "y": 66 + "y": 71 }, "id": 40, "panels": [], @@ -1671,7 +1825,7 @@ "h": 9, "w": 24, "x": 0, - "y": 67 + "y": 72 }, "id": 41, "options": { diff --git a/yarn-project/sequencer-client/src/sequencer/metrics.ts b/yarn-project/sequencer-client/src/sequencer/metrics.ts index 2758074d3bdd..788f764e70bd 100644 --- a/yarn-project/sequencer-client/src/sequencer/metrics.ts +++ b/yarn-project/sequencer-client/src/sequencer/metrics.ts @@ -54,6 +54,7 @@ export class SequencerMetrics { private fishermanPendingBlobCount: Histogram; private fishermanIncludedBlobCount: Histogram; private fishermanBlockBlobsFull: UpDownCounter; + private fishermanMaxBlobCapacity: Histogram; private fishermanCalculatedPriorityFee: Histogram; private fishermanPriorityFeeDelta: Histogram; private fishermanEstimatedCost: Histogram; @@ -134,6 +135,7 @@ export class SequencerMetrics { Metrics.FISHERMAN_FEE_ANALYSIS_WOULD_BE_INCLUDED, { [Attributes.OK]: [true, false], + [Attributes.BLOCK_FULL]: ['true', 'false'], }, ); @@ -176,6 +178,8 @@ export class SequencerMetrics { [Attributes.OK]: [true, false], }, ); + + this.fishermanMaxBlobCapacity = this.meter.createHistogram(Metrics.FISHERMAN_FEE_ANALYSIS_MAX_BLOB_CAPACITY); } public recordRequiredAttestations(requiredAttestationsCount: number, allowanceMs: number) { @@ -342,13 +346,21 @@ export class SequencerMetrics { this.fishermanBlockBlobsFull.add(1, { ...strategyAttributes, [Attributes.OK]: false }); } + // Record the max blob capacity for this block + this.fishermanMaxBlobCapacity.record(analysis.analysis.maxBlobCapacity, strategyAttributes); + // Record strategy-specific inclusion result if (strategyResult.wouldBeIncluded !== undefined) { + const inclusionAttributes = { + ...strategyAttributes, + [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false', + }; + if (strategyResult.wouldBeIncluded) { - this.fishermanWouldBeIncluded.add(1, { ...strategyAttributes, [Attributes.OK]: true }); + this.fishermanWouldBeIncluded.add(1, { ...inclusionAttributes, [Attributes.OK]: true }); } else { this.fishermanWouldBeIncluded.add(1, { - ...strategyAttributes, + ...inclusionAttributes, [Attributes.OK]: false, ...(strategyResult.exclusionReason && { [Attributes.ERROR_TYPE]: strategyResult.exclusionReason }), }); @@ -358,17 +370,29 @@ export class SequencerMetrics { // Record strategy-specific priority fee delta if (strategyResult.priorityFeeDelta !== undefined) { const priorityFeeDeltaGwei = Number(strategyResult.priorityFeeDelta) / 1e9; - this.fishermanPriorityFeeDelta.record(priorityFeeDeltaGwei, strategyAttributes); + const deltaAttributes = { + ...strategyAttributes, + [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false', + }; + this.fishermanPriorityFeeDelta.record(priorityFeeDeltaGwei, deltaAttributes); } // Record estimated cost if available if (strategyResult.estimatedCostEth !== undefined) { - this.fishermanEstimatedCost.record(strategyResult.estimatedCostEth, strategyAttributes); + const costAttributes = { + ...strategyAttributes, + [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false', + }; + this.fishermanEstimatedCost.record(strategyResult.estimatedCostEth, costAttributes); } // Record estimated overpayment if available if (strategyResult.estimatedOverpaymentEth !== undefined) { - this.fishermanEstimatedOverpayment.record(strategyResult.estimatedOverpaymentEth, strategyAttributes); + const overpaymentAttributes = { + ...strategyAttributes, + [Attributes.BLOCK_FULL]: analysis.analysis.blockBlobsFull ? 'true' : 'false', + }; + this.fishermanEstimatedOverpayment.record(strategyResult.estimatedOverpaymentEth, overpaymentAttributes); } } } diff --git a/yarn-project/telemetry-client/src/attributes.ts b/yarn-project/telemetry-client/src/attributes.ts index 4e9a843ba6e7..77b1d019f22c 100644 --- a/yarn-project/telemetry-client/src/attributes.ts +++ b/yarn-project/telemetry-client/src/attributes.ts @@ -139,6 +139,9 @@ export const IS_COMMITTEE_MEMBER = 'aztec.is_committee_member'; /** Fisherman fee analysis strategy identifier */ export const FISHERMAN_FEE_STRATEGY_ID = 'aztec.fisherman.strategy_id'; +/** Whether the analyzed block reached 100% blob capacity */ +export const BLOCK_FULL = 'aztec.block_full'; + /** The L1 transaction target for block proposal */ export const L1_BLOCK_PROPOSAL_TX_TARGET = 'aztec.l1.block_proposal_tx_target'; diff --git a/yarn-project/telemetry-client/src/metrics.ts b/yarn-project/telemetry-client/src/metrics.ts index fa482558bdb4..c76fc0926ed5 100644 --- a/yarn-project/telemetry-client/src/metrics.ts +++ b/yarn-project/telemetry-client/src/metrics.ts @@ -491,6 +491,12 @@ export const FISHERMAN_FEE_ANALYSIS_BLOCK_BLOBS_FULL: MetricDefinition = { description: 'Whether the mined block reached 100% blob capacity', valueType: ValueType.INT, }; +export const FISHERMAN_FEE_ANALYSIS_MAX_BLOB_CAPACITY: MetricDefinition = { + name: 'aztec.fisherman.fee_analysis.max_blob_capacity', + description: 'Maximum blob capacity for the analyzed block based on L1 upgrade schedule', + unit: 'blobs', + valueType: ValueType.INT, +}; export const VALIDATOR_INVALID_ATTESTATION_RECEIVED_COUNT: MetricDefinition = { name: 'aztec.validator.invalid_attestation_received_count',