From 89602d1208162a1f7fb666cd7dbcc66165501a66 Mon Sep 17 00:00:00 2001 From: Julian Ventura <43799596+JulianVentura@users.noreply.github.com> Date: Wed, 27 Nov 2024 20:00:05 -0300 Subject: [PATCH 1/9] fix: parse error codes from createNewTask ethereum contract function (#1503) Co-authored-by: Julian Ventura Co-authored-by: avilagaston9 Co-authored-by: Urix <43704209+uri-99@users.noreply.github.com> --- .../src/retry/batcher_retryables.rs | 8 +-- batcher/aligned-batcher/src/types/errors.rs | 71 ++++++++++++++++++- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/batcher/aligned-batcher/src/retry/batcher_retryables.rs b/batcher/aligned-batcher/src/retry/batcher_retryables.rs index d63637abea..564408ef0d 100644 --- a/batcher/aligned-batcher/src/retry/batcher_retryables.rs +++ b/batcher/aligned-batcher/src/retry/batcher_retryables.rs @@ -10,7 +10,7 @@ use crate::{ utils::get_current_nonce, }, retry::RetryError, - types::errors::BatcherError, + types::errors::{BatcherError, TransactionSendError}, }; pub async fn get_user_balance_retryable( @@ -130,7 +130,7 @@ pub async fn create_new_task_retryable( // Since transaction was reverted, we don't want to retry with fallback. warn!("Transaction reverted {:?}", err); return Err(RetryError::Permanent(BatcherError::TransactionSendError( - err.to_string(), + TransactionSendError::from(err), ))); } _ => { @@ -149,12 +149,12 @@ pub async fn create_new_task_retryable( Err(ContractError::Revert(err)) => { warn!("Transaction reverted {:?}", err); return Err(RetryError::Permanent(BatcherError::TransactionSendError( - err.to_string(), + TransactionSendError::from(err), ))); } Err(err) => { return Err(RetryError::Transient(BatcherError::TransactionSendError( - err.to_string(), + TransactionSendError::Generic(err.to_string()), ))) } } diff --git a/batcher/aligned-batcher/src/types/errors.rs b/batcher/aligned-batcher/src/types/errors.rs index b20fc45bba..768684fca9 100644 --- a/batcher/aligned-batcher/src/types/errors.rs +++ b/batcher/aligned-batcher/src/types/errors.rs @@ -1,8 +1,44 @@ use std::fmt; -use ethers::types::{Address, SignatureError}; +use ethers::types::{Address, Bytes, SignatureError}; use tokio_tungstenite::tungstenite; +pub enum TransactionSendError { + NoProofSubmitters, + NoFeePerProof, + InsufficientFeeForAggregator, + SubmissionInsufficientBalance, + BatchAlreadySubmitted, + InsufficientFunds, + OnlyBatcherAllowed, + Generic(String), +} + +impl From for TransactionSendError { + fn from(e: Bytes) -> Self { + let byte_string = e.to_string(); + let str_code = if byte_string.len() >= 10 { + &byte_string[..10] // Extract the error code only + } else { + "" // Not gonna match + }; + match str_code { + "0xc43ac290" => TransactionSendError::NoProofSubmitters, // can't happen, don't flush + "0xa3a8658a" => TransactionSendError::NoFeePerProof, // can't happen, don't flush + "0x7899ec71" => TransactionSendError::InsufficientFeeForAggregator, // shouldn't happen, don't flush + // returning the proofs and retrying later may help + "0x4f779ceb" => TransactionSendError::SubmissionInsufficientBalance, // shouldn't happen, + // flush can help if something went wrong + "0x3102f10c" => TransactionSendError::BatchAlreadySubmitted, // can happen, don't flush + "0x5c54305e" => TransactionSendError::InsufficientFunds, // shouldn't happen, don't flush + "0x152bc288" => TransactionSendError::OnlyBatcherAllowed, // won't happen, don't flush + _ => { + TransactionSendError::Generic(format!("Unknown bytestring error: {}", byte_string)) + } + } + } +} + pub enum BatcherError { TcpListenerError(String), ConnectionError(tungstenite::Error), @@ -12,7 +48,7 @@ pub enum BatcherError { BatchUploadError(String), TaskCreationError(String), ReceiptNotFoundError, - TransactionSendError(String), + TransactionSendError(TransactionSendError), MaxRetriesReachedError, SerializationError(String), GasPriceError, @@ -101,3 +137,34 @@ impl fmt::Debug for BatcherError { } } } + +impl fmt::Display for TransactionSendError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + TransactionSendError::NoProofSubmitters => { + write!(f, "No proof submitter error") + } + TransactionSendError::NoFeePerProof => { + write!(f, "No fee per proof") + } + TransactionSendError::InsufficientFeeForAggregator => { + write!(f, "Insufficient fee for aggregator") + } + TransactionSendError::SubmissionInsufficientBalance => { + write!(f, "Submission insufficient balance") + } + TransactionSendError::BatchAlreadySubmitted => { + write!(f, "Batch already submitted") + } + TransactionSendError::InsufficientFunds => { + write!(f, "Insufficient funds") + } + TransactionSendError::OnlyBatcherAllowed => { + write!(f, "Only batcher allowed") + } + TransactionSendError::Generic(e) => { + write!(f, "Generic error: {}", e) + } + } + } +} From ddaf2337b8469c4e0bae15a379b1dd2e8d40cc02 Mon Sep 17 00:00:00 2001 From: Marcos Nicolau <76252340+MarcosNicolau@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:23:46 -0300 Subject: [PATCH 2/9] ci: address clippy warnings (#1515) --- batcher/aligned-batcher/src/zk_utils/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/batcher/aligned-batcher/src/zk_utils/mod.rs b/batcher/aligned-batcher/src/zk_utils/mod.rs index 41bc6fe109..1844e8e956 100644 --- a/batcher/aligned-batcher/src/zk_utils/mod.rs +++ b/batcher/aligned-batcher/src/zk_utils/mod.rs @@ -34,11 +34,7 @@ fn verify_internal(verification_data: &VerificationData) -> bool { let mut image_id = [0u8; 32]; image_id.copy_from_slice(image_id_slice.as_slice()); - return verify_risc_zero_proof( - verification_data.proof.as_slice(), - &image_id, - &pub_input, - ); + verify_risc_zero_proof(verification_data.proof.as_slice(), &image_id, &pub_input) } ProvingSystemId::GnarkPlonkBls12_381 | ProvingSystemId::GnarkPlonkBn254 From c29136355426d4ccf00a4100d675a45b9fe106bf Mon Sep 17 00:00:00 2001 From: Julian Arce <52429267+JuArce@users.noreply.github.com> Date: Thu, 28 Nov 2024 12:51:49 -0300 Subject: [PATCH 3/9] fix: contract addresses files (#1519) --- .../output/holesky/alignedlayer_deployment_output.stage.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/script/output/holesky/alignedlayer_deployment_output.stage.json b/contracts/script/output/holesky/alignedlayer_deployment_output.stage.json index fd1fa126c5..85d255d793 100644 --- a/contracts/script/output/holesky/alignedlayer_deployment_output.stage.json +++ b/contracts/script/output/holesky/alignedlayer_deployment_output.stage.json @@ -14,7 +14,7 @@ "stakeRegistry": "0x1b0C9b87b094d821911500F91914B1A1D2856F14", "stakeRegistryImplementation": "0x52A9e264b98fe2d53805937Bc094a981E7eB6BeE", "batcherPaymentService": "0x7577Ec4ccC1E6C529162ec8019A49C13F6DAd98b", - "batcherPaymentServiceImplementation": "0x230FF8F073C188732856990b070485FD1A9b1039" + "batcherPaymentServiceImplementation": "0x230FF8F073C188732856990b070485FD1A9b1039", "pauserRegistry": "0xBCd09a605906a13F917230F82BdAC15B778A5B03" }, "chainInfo": { From 052ac25c311d50378828356663356ece567c465e Mon Sep 17 00:00:00 2001 From: Julian Arce <52429267+JuArce@users.noreply.github.com> Date: Thu, 28 Nov 2024 13:59:40 -0300 Subject: [PATCH 4/9] refactor: grafana dashboard (#1511) --- .../aligned/aggregator_batcher.json | 1828 +++++++++++------ 1 file changed, 1238 insertions(+), 590 deletions(-) diff --git a/grafana/provisioning/dashboards/aligned/aggregator_batcher.json b/grafana/provisioning/dashboards/aligned/aggregator_batcher.json index b4eb8f3bfa..fc1c087239 100644 --- a/grafana/provisioning/dashboards/aligned/aggregator_batcher.json +++ b/grafana/provisioning/dashboards/aligned/aggregator_batcher.json @@ -23,97 +23,69 @@ "liveNow": false, "panels": [ { - "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, "gridPos": { - "h": 1, - "w": 24, + "h": 2, + "w": 15, "x": 0, "y": 0 }, - "id": 11, - "panels": [], - "title": "Batcher", - "type": "row" + "id": 34, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "

\n ETHEREUM\n

", + "mode": "html" + }, + "pluginVersion": "11.2.2+security-01", + "transparent": true, + "type": "text" }, { "datasource": { "type": "prometheus", "uid": "prometheus" }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - } - ] - } - }, - "overrides": [] - }, "gridPos": { - "h": 6, - "w": 4, - "x": 0, - "y": 1 + "h": 2, + "w": 8, + "x": 16, + "y": 0 }, - "id": 12, + "id": 35, "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true + "content": "

\n HISTORIC DATA\n

", + "mode": "html" }, "pluginVersion": "11.2.2+security-01", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "floor(increase(received_proofs{job=\"aligned-batcher\"}[10y]))", - "fullMetaSearch": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "__auto", - "range": true, - "refId": "A", - "useBackend": false - } - ], - "title": "Total Proofs Received", - "type": "stat" + "transparent": true, + "type": "text" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, + "description": "Ethereum Gas Price in GWEI", "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" + "fixedColor": "green", + "mode": "fixed" }, + "fieldMinMax": false, "mappings": [], "thresholds": { "mode": "absolute", @@ -124,24 +96,27 @@ }, { "color": "red", - "value": 256 + "value": 80 } ] - } + }, + "unit": "GWEI" }, "overrides": [] }, "gridPos": { "h": 6, "w": 4, - "x": 4, - "y": 1 + "x": 0, + "y": 2 }, - "id": 17, + "id": 32, "options": { - "minVizHeight": 75, - "minVizWidth": 75, + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", "orientation": "auto", + "percentChangeColorMode": "inverted", "reduceOptions": { "calcs": [ "lastNotNull" @@ -149,9 +124,9 @@ "fields": "", "values": false }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, "pluginVersion": "11.2.2+security-01", "targets": [ @@ -161,8 +136,10 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "open_connections{job=\"aligned-batcher\"}", + "editorMode": "code", + "exemplar": false, + "expr": "gas_price{job=\"aligned-tracker\"} * 10^-9", + "format": "time_series", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -172,18 +149,21 @@ "useBackend": false } ], - "title": "Open Connections", - "type": "gauge" + "title": "Ethereum Gas Price [GWEI]", + "type": "stat" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, + "description": "Ethereum Gas Price evolution in GWEI", "fieldConfig": { "defaults": { "color": { - "mode": "palette-classic" + "fixedColor": "green", + "mode": "fixed" }, "custom": { "axisBorderShow": false, @@ -191,6 +171,7 @@ "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", + "axisSoftMin": 2, "barAlignment": 0, "barWidthFactor": 0.6, "drawStyle": "line", @@ -209,7 +190,7 @@ "type": "linear" }, "showPoints": "auto", - "spanNulls": false, + "spanNulls": true, "stacking": { "group": "A", "mode": "none" @@ -218,6 +199,7 @@ "mode": "off" } }, + "fieldMinMax": false, "mappings": [], "thresholds": { "mode": "absolute", @@ -225,26 +207,26 @@ { "color": "green", "value": null - }, - { - "color": "red", - "value": 80 } ] - } + }, + "unit": "GWEI" }, "overrides": [] }, "gridPos": { "h": 6, - "w": 13, - "x": 8, - "y": 1 + "w": 11, + "x": 4, + "y": 2 }, - "id": 16, + "id": 31, "options": { "legend": { - "calcs": [], + "calcs": [ + "lastNotNull", + "max" + ], "displayMode": "list", "placement": "bottom", "showLegend": true @@ -254,7 +236,7 @@ "sort": "none" } }, - "pluginVersion": "10.1.10", + "pluginVersion": "11.2.2+security-01", "targets": [ { "datasource": { @@ -263,17 +245,19 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(batcher_started{job=\"aligned-batcher\"}[$__range]))", + "exemplar": false, + "expr": "round(gas_price{job=\"aligned-tracker\"} * 10^-9 != 0, 0.00001)", + "format": "time_series", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "__auto", + "legendFormat": ".", "range": true, "refId": "A", "useBackend": false } ], - "title": "Total Batcher Restarts", + "title": "Ethereum Gas Price [GWEI]", "type": "timeseries" }, { @@ -293,14 +277,6 @@ { "color": "green", "value": null - }, - { - "color": "dark-red", - "value": 0 - }, - { - "color": "green", - "value": 1 } ] } @@ -310,10 +286,10 @@ "gridPos": { "h": 6, "w": 4, - "x": 0, - "y": 7 + "x": 16, + "y": 2 }, - "id": 14, + "id": 12, "options": { "colorMode": "value", "graphMode": "none", @@ -339,8 +315,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "code", - "expr": "floor(increase(sent_batches{job=\"aligned-batcher\"}[$__range]))", + "editorMode": "builder", + "expr": "floor(increase(received_proofs{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -350,51 +326,19 @@ "useBackend": false } ], - "title": "Batches Sent", + "title": "Total Proofs Received", "type": "stat" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "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": "none" - }, - "thresholdsStyle": { - "mode": "off" - } + "mode": "thresholds" }, "mappings": [], "thresholds": { @@ -405,8 +349,12 @@ "value": null }, { - "color": "red", - "value": 80 + "color": "dark-red", + "value": 0 + }, + { + "color": "green", + "value": 1 } ] } @@ -415,23 +363,29 @@ }, "gridPos": { "h": 6, - "w": 9, - "x": 4, - "y": 7 + "w": 4, + "x": 20, + "y": 2 }, - "id": 13, + "id": 41, "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false }, - "tooltip": { - "mode": "single", - "sort": "none" - } + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, + "pluginVersion": "11.2.2+security-01", "targets": [ { "datasource": { @@ -451,50 +405,18 @@ } ], "title": "Batches Sent", - "type": "timeseries" + "type": "stat" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 25, - "gradientMode": "none", - "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": "none" - }, - "thresholdsStyle": { - "mode": "off" - } + "mode": "thresholds" }, "mappings": [], "thresholds": { @@ -503,29 +425,136 @@ { "color": "green", "value": null - }, - { - "color": "red", - "value": 80 } ] - } + }, + "unit": "GWEI" }, "overrides": [] }, "gridPos": { - "h": 12, - "w": 8, - "x": 13, - "y": 7 + "h": 6, + "w": 4, + "x": 0, + "y": 8 }, - "id": 18, + "id": 33, "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.2.2+security-01", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "gas_price_used_on_latest_batch{job=\"aligned-batcher\"} * 10^-9", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Gas Price on Latest Batch Sent [GWEI]", + "type": "stat" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "GWEI" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 11, + "x": 4, + "y": 8 + }, + "id": 29, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "max" + ], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, "tooltip": { "mode": "single", @@ -540,21 +569,539 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "gas_price_used_on_latest_batch{job=\"aligned-batcher\"}", + "exemplar": false, + "expr": "round(gas_price_used_on_latest_batch{job=\"aligned-batcher\"} * 10^-9 != 0, 0.00001)", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "interval": "", + "legendFormat": "{{job}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Gas Price on Latest Batch Sent [GWEI]", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 4, + "x": 16, + "y": 8 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.2.2+security-01", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "floor(increase(aligned_aggregator_received_tasks{bot=\"aggregator\"}[10y]))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Total Tasks Received", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 4, + "x": 20, + "y": 8 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.2.2+security-01", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "disableTextWrap": false, + "editorMode": "builder", + "exemplar": false, + "expr": "floor(increase(aligned_aggregated_responses{bot=\"aggregator\"}[10y]))", + "format": "table", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, + "interval": "", "legendFormat": "__auto", "range": true, "refId": "A", "useBackend": false } ], - "title": "Gas price on latest batch", - "type": "timeseries" + "title": "Total Tasks Verified", + "type": "stat" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "prometheus" + }, + "description": "Accumulated gas cost the aggregator paid for the batcher when the tx cost was higher than the respondToTaskFeeLimit.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ETH" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 7, + "x": 0, + "y": 14 + }, + "id": 30, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.2.2+security-01", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "increase(aligned_aggregator_gas_cost_paid_for_batcher{bot=\"aggregator\"}[10y])", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Accumulated Aggregator Extra Cost Paid [ETH]", + "type": "stat" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "prometheus" + }, + "description": "Number of times the aggregator paid for the batcher when the tx cost was higher than the respondToTaskFeeLimit", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 7, + "x": 0, + "y": 17 + }, + "id": 26, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.2.2+security-01", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "floor(increase(aligned_aggregator_num_times_paid_for_batcher{bot=\"aggregator\"}[10y]))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "# Times Aggregator Paid Extra Cost", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 2, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 38, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "

\n SYSTEM STATUS\n

", + "mode": "html" + }, + "pluginVersion": "11.2.2+security-01", + "transparent": true, + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 256 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 7, + "y": 22 + }, + "id": 17, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.2+security-01", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "open_connections{job=\"aligned-batcher\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Batcher Open Connections", + "type": "gauge" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-red", + "value": null + }, + { + "color": "green", + "value": 0 + }, + { + "color": "yellow", + "value": 1 + }, + { + "color": "dark-red", + "value": 2 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 10, + "y": 22 + }, + "id": 9, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.2.2+security-01", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "disableTextWrap": false, + "editorMode": "code", + "exemplar": false, + "expr": "floor(increase(aligned_aggregator_received_tasks{job=\"aligned-aggregator\"}[$__range]))", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "interval": "", + "legendFormat": "{{label_name}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "floor(increase(aligned_aggregated_responses{job=\"aligned-aggregator\"}[$__range]))", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "name": "Expression", + "type": "__expr__", + "uid": "__expr__" + }, + "expression": "$A - $B", + "hide": false, + "reducer": "last", + "refId": "C", + "type": "math" + } + ], + "title": "Tasks Not Verified", + "transformations": [ + { + "id": "filterByValue", + "options": { + "filters": [ + { + "config": { + "id": "lower", + "options": { + "value": 0 + } + }, + "fieldName": "C {bot=\"aggregator\", instance=\"host.docker.internal:9091\", job=\"aligned-aggregator\"}" + } + ], + "match": "any", + "type": "exclude" + } + } + ], + "type": "stat" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -571,13 +1118,9 @@ "color": "green", "value": null }, - { - "color": "#FF9830", - "value": 3 - }, { "color": "red", - "value": 5 + "value": 80 } ] } @@ -585,12 +1128,12 @@ "overrides": [] }, "gridPos": { - "h": 6, + "h": 5, "w": 4, - "x": 0, - "y": 13 + "x": 13, + "y": 22 }, - "id": 15, + "id": 42, "options": { "colorMode": "value", "graphMode": "none", @@ -617,7 +1160,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(reverted_batches{job=\"aligned-batcher\"}[$__range]))", + "expr": "floor(increase(batcher_started{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -627,11 +1170,12 @@ "useBackend": false } ], - "title": "Reverted Batches", + "title": "Total Batcher Restarts", "type": "stat" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -692,11 +1236,11 @@ }, "gridPos": { "h": 6, - "w": 9, - "x": 4, - "y": 13 + "w": 10, + "x": 7, + "y": 27 }, - "id": 19, + "id": 16, "options": { "legend": { "calcs": [], @@ -709,6 +1253,7 @@ "sort": "none" } }, + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -716,23 +1261,97 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "floor(increase(reverted_batches{job=\"aligned-batcher\"}[10y]))", + "editorMode": "code", + "expr": "floor(increase(batcher_started{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "__auto", + "legendFormat": "{{job}}", "range": true, "refId": "A", "useBackend": false } ], - "title": "Batches Reverted", + "title": "Total Batcher Restarts", "type": "timeseries" }, { "datasource": { - "default": true, + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 33 + }, + "id": 39, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "

\n SYSTEM STATUS\n

", + "mode": "html" + }, + "pluginVersion": "11.2.2+security-01", + "transparent": true, + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 2, + "w": 12, + "x": 0, + "y": 34 + }, + "id": 36, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "

\n BATCHER\n

", + "mode": "html" + }, + "pluginVersion": "11.2.2+security-01", + "transparent": true, + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { + "h": 2, + "w": 12, + "x": 12, + "y": 34 + }, + "id": 37, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "

\n AGGREGATOR\n

", + "mode": "html" + }, + "pluginVersion": "11.2.2+security-01", + "transparent": true, + "type": "text" + }, + { + "datasource": { "type": "prometheus", "uid": "prometheus" }, @@ -750,12 +1369,12 @@ "value": null }, { - "color": "#EAB839", - "value": 3 + "color": "dark-red", + "value": 0 }, { - "color": "red", - "value": 5 + "color": "green", + "value": 1 } ] } @@ -764,11 +1383,11 @@ }, "gridPos": { "h": 6, - "w": 4, + "w": 3, "x": 0, - "y": 19 + "y": 36 }, - "id": 22, + "id": 14, "options": { "colorMode": "value", "graphMode": "none", @@ -795,7 +1414,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(canceled_batches{job=\"aligned-batcher\"}[$__range]))", + "expr": "floor(increase(sent_batches{job=\"aligned-batcher\"}[$__range]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -805,7 +1424,7 @@ "useBackend": false } ], - "title": "Canceled Batches", + "title": "Batches Sent", "type": "stat" }, { @@ -871,10 +1490,10 @@ "gridPos": { "h": 6, "w": 9, - "x": 4, - "y": 19 + "x": 3, + "y": 36 }, - "id": 21, + "id": 13, "options": { "legend": { "calcs": [], @@ -894,8 +1513,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "canceled_batches", + "editorMode": "code", + "expr": "floor(increase(sent_batches{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -905,7 +1524,7 @@ "useBackend": false } ], - "title": "Batches Canceled", + "title": "Batches Sent", "type": "timeseries" }, { @@ -913,44 +1532,11 @@ "type": "prometheus", "uid": "prometheus" }, - "description": "Measures websocket connections that were abnormally disconnected.", + "description": "", "fieldConfig": { "defaults": { "color": { - "mode": "palette-classic" - }, - "custom": { - "axisBorderShow": false, - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "barWidthFactor": 0.6, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "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": "none" - }, - "thresholdsStyle": { - "mode": "off" - } + "mode": "thresholds" }, "mappings": [], "thresholds": { @@ -959,10 +1545,6 @@ { "color": "green", "value": null - }, - { - "color": "red", - "value": 80 } ] } @@ -970,25 +1552,30 @@ "overrides": [] }, "gridPos": { - "h": 8, - "w": 10, - "x": 0, - "y": 25 + "h": 6, + "w": 3, + "x": 12, + "y": 36 }, - "id": 20, - "interval": "1m", + "id": 7, "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false }, - "tooltip": { - "mode": "single", - "sort": "none" - } + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, + "pluginVersion": "11.2.2+security-01", "targets": [ { "datasource": { @@ -997,7 +1584,7 @@ }, "disableTextWrap": false, "editorMode": "builder", - "expr": "broken_ws_connections{job=\"aligned-batcher\"}", + "expr": "floor(increase(aligned_aggregator_received_tasks{bot=\"aggregator\"}[$__range]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1007,8 +1594,8 @@ "useBackend": false } ], - "title": "Broken websocket connections", - "type": "timeseries" + "title": "Tasks Received", + "type": "stat" }, { "datasource": { @@ -1071,20 +1658,21 @@ "overrides": [] }, "gridPos": { - "h": 8, - "w": 11, - "x": 10, - "y": 25 + "h": 6, + "w": 9, + "x": 15, + "y": 36 }, - "id": 24, + "id": 40, "options": { "legend": { "calcs": [], "displayMode": "list", - "placement": "right", + "placement": "bottom", "showLegend": true }, "tooltip": { + "maxHeight": 600, "mode": "single", "sort": "none" } @@ -1093,71 +1681,23 @@ { "datasource": { "type": "prometheus", - "uid": "prometheus" - }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "user_errors", - "fullMetaSearch": false, - "includeNullMetadata": true, - "instant": false, - "legendFormat": "{{error_type}}", - "range": true, - "refId": "A", - "useBackend": false - } - ], - "title": "User Error Count", - "transformations": [ - { - "id": "calculateField", - "options": { - "alias": "proof_rejected", - "mode": "reduceRow", - "reduce": { - "include": [ - "rejected_proof" - ], - "reducer": "sum" - } - } - }, - { - "id": "organize", - "options": { - "excludeByName": { - "rejected_proof": true - }, - "indexByName": {}, - "renameByName": {} - } - }, - { - "id": "calculateField", - "options": { - "alias": "total", - "mode": "reduceRow", - "reduce": { - "reducer": "sum" - } - } + "uid": "prometheus" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "floor(increase(aligned_aggregated_responses{bot=\"aggregator\"}[10y]))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false } ], + "title": "Verified Tasks", "type": "timeseries" }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 33 - }, - "id": 10, - "panels": [], - "title": "Aggregator", - "type": "row" - }, { "datasource": { "type": "prometheus", @@ -1172,21 +1712,17 @@ "thresholds": { "mode": "absolute", "steps": [ - { - "color": "dark-red", - "value": null - }, { "color": "green", - "value": 0 + "value": null }, { - "color": "yellow", - "value": 1 + "color": "#FF9830", + "value": 3 }, { - "color": "dark-red", - "value": 2 + "color": "red", + "value": 5 } ] } @@ -1194,12 +1730,12 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 10, + "h": 6, + "w": 3, "x": 0, - "y": 34 + "y": 42 }, - "id": 9, + "id": 15, "options": { "colorMode": "value", "graphMode": "none", @@ -1225,70 +1761,18 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "exemplar": false, - "expr": "floor(increase(aligned_aggregator_received_tasks{job=\"aligned-aggregator\"}[$__range]))", - "fullMetaSearch": false, - "hide": true, - "includeNullMetadata": true, - "instant": false, - "interval": "", - "legendFormat": "{{label_name}}", - "range": true, - "refId": "A", - "useBackend": false - }, - { - "datasource": { - "type": "prometheus", - "uid": "prometheus" - }, - "disableTextWrap": false, - "editorMode": "builder", - "expr": "floor(increase(aligned_aggregated_responses{bot=\"aggregator\"}[$__range]))", + "editorMode": "code", + "expr": "floor(increase(reverted_batches{job=\"aligned-batcher\"}[$__range]))", "fullMetaSearch": false, - "hide": true, "includeNullMetadata": true, "instant": false, "legendFormat": "__auto", "range": true, - "refId": "B", + "refId": "A", "useBackend": false - }, - { - "datasource": { - "name": "Expression", - "type": "__expr__", - "uid": "__expr__" - }, - "expression": "$A - $B", - "hide": false, - "reducer": "last", - "refId": "C", - "type": "math" - } - ], - "title": "Tasks Not Verified", - "transformations": [ - { - "id": "filterByValue", - "options": { - "filters": [ - { - "config": { - "id": "lower", - "options": { - "value": 0 - } - }, - "fieldName": "C {bot=\"aggregator\", instance=\"host.docker.internal:9091\", job=\"aligned-aggregator\"}" - } - ], - "match": "any", - "type": "exclude" - } } ], + "title": "Reverted Batches", "type": "stat" }, { @@ -1352,12 +1836,12 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 10, - "x": 10, - "y": 34 + "h": 6, + "w": 9, + "x": 3, + "y": 42 }, - "id": 1, + "id": 19, "options": { "legend": { "calcs": [], @@ -1366,7 +1850,6 @@ "showLegend": true }, "tooltip": { - "maxHeight": 600, "mode": "single", "sort": "none" } @@ -1379,7 +1862,7 @@ }, "disableTextWrap": false, "editorMode": "builder", - "expr": "floor(increase(aligned_aggregated_responses{bot=\"aggregator\"}[10y]))", + "expr": "floor(increase(reverted_batches{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1389,7 +1872,7 @@ "useBackend": false } ], - "title": "Verified Tasks", + "title": "Batches Reverted", "type": "timeseries" }, { @@ -1397,7 +1880,6 @@ "type": "prometheus", "uid": "prometheus" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -1417,12 +1899,12 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 5, - "x": 0, - "y": 41 + "h": 6, + "w": 3, + "x": 12, + "y": 42 }, - "id": 8, + "id": 5, "options": { "colorMode": "value", "graphMode": "none", @@ -1449,7 +1931,8 @@ }, "disableTextWrap": false, "editorMode": "builder", - "expr": "floor(increase(aligned_aggregator_received_tasks{bot=\"aggregator\"}[10y]))", + "exemplar": false, + "expr": "floor(increase(aligned_aggregated_responses{bot=\"aggregator\"}[$__range]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1459,19 +1942,52 @@ "useBackend": false } ], - "title": "Total Tasks Received", + "title": "Tasks Verified", "type": "stat" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, - "description": "", "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": 0, + "gradientMode": "none", + "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": "none" + }, + "thresholdsStyle": { + "mode": "off" + } }, "mappings": [], "thresholds": { @@ -1491,30 +2007,25 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 5, - "x": 5, - "y": 41 + "h": 6, + "w": 9, + "x": 15, + "y": 42 }, - "id": 7, + "id": 1, "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } }, - "pluginVersion": "11.2.2+security-01", "targets": [ { "datasource": { @@ -1522,8 +2033,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "floor(increase(aligned_aggregator_received_tasks{bot=\"aggregator\"}[$__range]))", + "editorMode": "code", + "expr": "floor(increase(aligned_aggregator_received_tasks{bot=\"aggregator\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1533,15 +2044,15 @@ "useBackend": false } ], - "title": "Tasks Received", - "type": "stat" + "title": "Received Tasks", + "type": "timeseries" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, - "description": "Accumulated gas cost the aggregator paid for the batcher when the tx cost was higher than the respondToTaskFeeLimit.", "fieldConfig": { "defaults": { "color": { @@ -1554,20 +2065,27 @@ { "color": "green", "value": null + }, + { + "color": "#EAB839", + "value": 3 + }, + { + "color": "red", + "value": 5 } ] - }, - "unit": "ETH" + } }, "overrides": [] }, "gridPos": { - "h": 7, - "w": 5, - "x": 10, - "y": 41 + "h": 6, + "w": 3, + "x": 0, + "y": 48 }, - "id": 27, + "id": 22, "options": { "colorMode": "value", "graphMode": "none", @@ -1593,8 +2111,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "aligned_aggregator_gas_cost_paid_for_batcher{bot=\"aggregator\"}", + "editorMode": "code", + "expr": "floor(increase(canceled_batches{job=\"aligned-batcher\"}[$__range]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1604,19 +2122,52 @@ "useBackend": false } ], - "title": "Accumulated GasCost paid for batcher", + "title": "Canceled Batches", "type": "stat" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, - "description": "Number of times the aggregator paid for the batcher when the tx cost was higher than the respondToTaskFeeLimit", "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": 0, + "gradientMode": "none", + "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": "none" + }, + "thresholdsStyle": { + "mode": "off" + } }, "mappings": [], "thresholds": { @@ -1625,6 +2176,10 @@ { "color": "green", "value": null + }, + { + "color": "red", + "value": 80 } ] } @@ -1632,30 +2187,24 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 5, - "x": 15, - "y": 41 + "h": 6, + "w": 9, + "x": 3, + "y": 48 }, - "id": 26, + "id": 21, "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true + "tooltip": { + "mode": "single", + "sort": "none" + } }, - "pluginVersion": "11.2.2+security-01", "targets": [ { "datasource": { @@ -1663,8 +2212,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "aligned_aggregator_num_times_paid_for_batcher{bot=\"aggregator\"}", + "editorMode": "code", + "expr": "floor(increase(canceled_batches{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1674,18 +2223,53 @@ "useBackend": false } ], - "title": "Times aggregator paid for batcher", - "type": "stat" + "title": "Batches Canceled", + "type": "timeseries" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, + "description": "Number of times gas price was bumped while sending an aggregated response.", "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": 0, + "gradientMode": "none", + "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": "none" + }, + "thresholdsStyle": { + "mode": "off" + } }, "mappings": [], "thresholds": { @@ -1694,6 +2278,10 @@ { "color": "green", "value": null + }, + { + "color": "red", + "value": 80 } ] } @@ -1701,30 +2289,25 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 5, - "x": 0, + "h": 6, + "w": 10, + "x": 12, "y": 48 }, - "id": 2, + "id": 25, + "interval": "36", "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true + "tooltip": { + "mode": "single", + "sort": "none" + } }, - "pluginVersion": "11.2.2+security-01", "targets": [ { "datasource": { @@ -1732,32 +2315,64 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "exemplar": false, - "expr": "floor(increase(aligned_aggregated_responses{bot=\"aggregator\"}[10y]))", - "format": "table", + "editorMode": "code", + "expr": "floor(increase(aligned_respond_to_task_gas_price_bumped{bot=\"aggregator\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "interval": "", "legendFormat": "__auto", "range": true, "refId": "A", "useBackend": false } ], - "title": "Total Tasks Verified", - "type": "stat" + "title": "# Bumps Sending Responses to Ethereum", + "type": "timeseries" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, + "description": "Measures websocket connections that were abnormally disconnected.", "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": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 1, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } }, "mappings": [], "thresholds": { @@ -1766,6 +2381,10 @@ { "color": "green", "value": null + }, + { + "color": "red", + "value": 80 } ] } @@ -1774,29 +2393,24 @@ }, "gridPos": { "h": 7, - "w": 5, - "x": 5, - "y": 48 + "w": 12, + "x": 0, + "y": 54 }, - "id": 5, + "id": 20, + "interval": "1m", "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "percentChangeColorMode": "standard", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, - "showPercentChange": false, - "textMode": "auto", - "wideLayout": true + "tooltip": { + "mode": "single", + "sort": "none" + } }, - "pluginVersion": "11.2.2+security-01", "targets": [ { "datasource": { @@ -1804,9 +2418,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "exemplar": false, - "expr": "floor(increase(aligned_aggregated_responses{bot=\"aggregator\"}[$__range]))", + "editorMode": "code", + "expr": "floor(increase(broken_ws_connections{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1816,11 +2429,12 @@ "useBackend": false } ], - "title": "Tasks Verified", - "type": "stat" + "title": "Broken websocket connections", + "type": "timeseries" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -1879,8 +2493,8 @@ "gridPos": { "h": 7, "w": 10, - "x": 10, - "y": 48 + "x": 12, + "y": 54 }, "id": 28, "options": { @@ -1902,8 +2516,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "aligned_aggregator_num_times_paid_for_batcher{bot=\"aggregator\"}", + "editorMode": "code", + "expr": "floor(increase(aligned_aggregator_num_times_paid_for_batcher{bot=\"aggregator\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1913,15 +2527,15 @@ "useBackend": false } ], - "title": "Aggregator paid for batcher time series", + "title": "# Times Aggregator Paid Extra Cost", "type": "timeseries" }, { "datasource": { + "default": true, "type": "prometheus", "uid": "prometheus" }, - "description": "Number of times gas price was bumped while sending an aggregated response.", "fieldConfig": { "defaults": { "color": { @@ -1978,18 +2592,17 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 10, + "h": 8, + "w": 12, "x": 0, - "y": 55 + "y": 61 }, - "id": 25, - "interval": "36", + "id": 24, "options": { "legend": { "calcs": [], "displayMode": "list", - "placement": "bottom", + "placement": "right", "showLegend": true }, "tooltip": { @@ -2004,18 +2617,53 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "aligned_respond_to_task_gas_price_bumped{bot=\"aggregator\"}", + "editorMode": "code", + "expr": "floor(increase(user_errors{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "__auto", + "legendFormat": "{{error_type}}", "range": true, "refId": "A", "useBackend": false } ], - "title": "Bumped gas price for aggregated responses", + "title": "# User Errors", + "transformations": [ + { + "id": "calculateField", + "options": { + "alias": "proof_rejected", + "mode": "reduceRow", + "reduce": { + "include": [ + "rejected_proof" + ], + "reducer": "sum" + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "rejected_proof": true + }, + "indexByName": {}, + "renameByName": {} + } + }, + { + "id": "calculateField", + "options": { + "alias": "total", + "mode": "reduceRow", + "reduce": { + "reducer": "sum" + } + } + } + ], "type": "timeseries" } ], @@ -2026,13 +2674,13 @@ "list": [] }, "time": { - "from": "now-5m", + "from": "now-30m", "to": "now" }, "timepicker": {}, "timezone": "browser", - "title": "Aggregator Data", + "title": "System Data", "uid": "aggregator", - "version": 3, + "version": 8, "weekStart": "" -} +} \ No newline at end of file From 5a24c5e5f440205430791e43ad987fa41ff06868 Mon Sep 17 00:00:00 2001 From: Julian Ventura <43799596+JulianVentura@users.noreply.github.com> Date: Thu, 28 Nov 2024 14:59:33 -0300 Subject: [PATCH 5/9] feat: add simulate_create_new_task (#1506) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Julian Ventura Co-authored-by: Marcos Nicolau <76252340+MarcosNicolau@users.noreply.github.com> Co-authored-by: Avila Gastón <72628438+avilagaston9@users.noreply.github.com> Co-authored-by: avilagaston9 --- batcher/aligned-batcher/src/lib.rs | 24 +++++++- .../src/retry/batcher_retryables.rs | 57 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/batcher/aligned-batcher/src/lib.rs b/batcher/aligned-batcher/src/lib.rs index a532aab73e..27de99667a 100644 --- a/batcher/aligned-batcher/src/lib.rs +++ b/batcher/aligned-batcher/src/lib.rs @@ -8,7 +8,8 @@ use ethers::contract::ContractError; use ethers::signers::Signer; use retry::batcher_retryables::{ cancel_create_new_task_retryable, create_new_task_retryable, get_user_balance_retryable, - get_user_nonce_from_ethereum_retryable, user_balance_is_unlocked_retryable, + get_user_nonce_from_ethereum_retryable, simulate_create_new_task_retryable, + user_balance_is_unlocked_retryable, }; use retry::{retry_function, RetryError}; use tokio::time::timeout; @@ -1479,6 +1480,27 @@ impl Batcher { proof_submitters: Vec
, fee_params: CreateNewTaskFeeParams, ) -> Result { + // First, we simulate the tx + retry_function( + || { + simulate_create_new_task_retryable( + batch_merkle_root, + batch_data_pointer.clone(), + proof_submitters.clone(), + fee_params.clone(), + &self.payment_service, + &self.payment_service_fallback, + ) + }, + ETHEREUM_CALL_MIN_RETRY_DELAY, + ETHEREUM_CALL_BACKOFF_FACTOR, + ETHEREUM_CALL_MAX_RETRIES, + ETHEREUM_CALL_MAX_RETRY_DELAY, + ) + .await + .map_err(|e| e.inner())?; + + // Then, we send the real tx let result = retry_function( || { create_new_task_retryable( diff --git a/batcher/aligned-batcher/src/retry/batcher_retryables.rs b/batcher/aligned-batcher/src/retry/batcher_retryables.rs index 564408ef0d..677698dd3e 100644 --- a/batcher/aligned-batcher/src/retry/batcher_retryables.rs +++ b/batcher/aligned-batcher/src/retry/batcher_retryables.rs @@ -175,6 +175,63 @@ pub async fn create_new_task_retryable( .ok_or(RetryError::Permanent(BatcherError::ReceiptNotFoundError)) } +pub async fn simulate_create_new_task_retryable( + batch_merkle_root: [u8; 32], + batch_data_pointer: String, + proofs_submitters: Vec
, + fee_params: CreateNewTaskFeeParams, + payment_service: &BatcherPaymentService, + payment_service_fallback: &BatcherPaymentService, +) -> Result<(), RetryError> { + info!("Simulating task for: 0x{}", hex::encode(batch_merkle_root)); + let simulation_fallback; + let simulation = payment_service + .create_new_task( + batch_merkle_root, + batch_data_pointer.clone(), + proofs_submitters.clone(), + fee_params.fee_for_aggregator, + fee_params.fee_per_proof, + fee_params.respond_to_task_fee_limit, + ) + .gas_price(fee_params.gas_price); + // sends an `eth_call` request to the node + match simulation.call().await { + Ok(_) => Ok(()), + Err(ContractError::Revert(err)) => { + // Since transaction was reverted, we don't want to retry with fallback. + warn!("Simulated transaction reverted {:?}", err); + Err(RetryError::Permanent(BatcherError::TransactionSendError( + TransactionSendError::from(err), + ))) + } + _ => { + simulation_fallback = payment_service_fallback + .create_new_task( + batch_merkle_root, + batch_data_pointer, + proofs_submitters, + fee_params.fee_for_aggregator, + fee_params.fee_per_proof, + fee_params.respond_to_task_fee_limit, + ) + .gas_price(fee_params.gas_price); + match simulation_fallback.call().await { + Ok(_) => Ok(()), + Err(ContractError::Revert(err)) => { + warn!("Simulated transaction reverted {:?}", err); + Err(RetryError::Permanent(BatcherError::TransactionSendError( + TransactionSendError::from(err), + ))) + } + Err(err) => Err(RetryError::Transient(BatcherError::TransactionSendError( + TransactionSendError::Generic(err.to_string()), + ))), + } + } + } +} + pub async fn cancel_create_new_task_retryable( batcher_signer: &SignerMiddlewareT, batcher_signer_fallback: &SignerMiddlewareT, From 256bb3bd910922ed2c47f021c240530f1ef923c0 Mon Sep 17 00:00:00 2001 From: Julian Arce <52429267+JuArce@users.noreply.github.com> Date: Fri, 29 Nov 2024 09:27:51 -0300 Subject: [PATCH 6/9] fix: grafana warnings (#1514) Co-authored-by: Julian Ventura --- batcher/aligned-batcher/src/metrics.rs | 19 ++- .../aligned/aggregator_batcher.json | 157 +++++++----------- .../dashboards/aligned/operator.json | 28 ++-- metrics/metrics.go | 12 +- 4 files changed, 90 insertions(+), 126 deletions(-) diff --git a/batcher/aligned-batcher/src/metrics.rs b/batcher/aligned-batcher/src/metrics.rs index 231a4795f6..a7c6f26e34 100644 --- a/batcher/aligned-batcher/src/metrics.rs +++ b/batcher/aligned-batcher/src/metrics.rs @@ -25,22 +25,25 @@ impl BatcherMetrics { pub fn start(metrics_port: u16) -> anyhow::Result { let registry = prometheus::Registry::new(); - let open_connections = register_int_gauge!(opts!("open_connections", "Open Connections"))?; - let received_proofs = register_int_counter!(opts!("received_proofs", "Received Proofs"))?; - let sent_batches = register_int_counter!(opts!("sent_batches", "Sent Batches"))?; + let open_connections = + register_int_gauge!(opts!("open_connections_count", "Open Connections"))?; + let received_proofs = + register_int_counter!(opts!("received_proofs_count", "Received Proofs"))?; + let sent_batches = register_int_counter!(opts!("sent_batches_count", "Sent Batches"))?; let reverted_batches = - register_int_counter!(opts!("reverted_batches", "Reverted Batches"))?; + register_int_counter!(opts!("reverted_batches_count", "Reverted Batches"))?; let canceled_batches = - register_int_counter!(opts!("canceled_batches", "Canceled Batches"))?; + register_int_counter!(opts!("canceled_batches_count", "Canceled Batches"))?; let user_errors = register_int_counter_vec!( - opts!("user_errors", "User Errors"), + opts!("user_errors_count", "User Errors"), &["error_type", "proving_system"] )?; - let batcher_started = register_int_counter!(opts!("batcher_started", "Batcher Started"))?; + let batcher_started = + register_int_counter!(opts!("batcher_started_count", "Batcher Started"))?; let gas_price_used_on_latest_batch = register_int_gauge!(opts!("gas_price_used_on_latest_batch", "Gas Price"))?; let broken_ws_connections = register_int_counter!(opts!( - "broken_ws_connections", + "broken_ws_connections_count", "Broken websocket connections" ))?; diff --git a/grafana/provisioning/dashboards/aligned/aggregator_batcher.json b/grafana/provisioning/dashboards/aligned/aggregator_batcher.json index fc1c087239..929ff29eac 100644 --- a/grafana/provisioning/dashboards/aligned/aggregator_batcher.json +++ b/grafana/provisioning/dashboards/aligned/aggregator_batcher.json @@ -18,7 +18,7 @@ "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, - "id": 2, + "id": 4, "links": [], "liveNow": false, "panels": [ @@ -43,7 +43,7 @@ "content": "

\n ETHEREUM\n

", "mode": "html" }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "transparent": true, "type": "text" }, @@ -68,7 +68,7 @@ "content": "

\n HISTORIC DATA\n

", "mode": "html" }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "transparent": true, "type": "text" }, @@ -85,7 +85,6 @@ "fixedColor": "green", "mode": "fixed" }, - "fieldMinMax": false, "mappings": [], "thresholds": { "mode": "absolute", @@ -128,7 +127,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -166,14 +165,12 @@ "mode": "fixed" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "axisSoftMin": 2, "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -199,7 +196,6 @@ "mode": "off" } }, - "fieldMinMax": false, "mappings": [], "thresholds": { "mode": "absolute", @@ -307,7 +303,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -315,8 +311,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "floor(increase(received_proofs{job=\"aligned-batcher\"}[10y]))", + "editorMode": "code", + "expr": "floor(increase(received_proofs_count{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -331,7 +327,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -385,7 +380,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -394,7 +389,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(sent_batches{job=\"aligned-batcher\"}[10y]))", + "expr": "floor(increase(sent_batches_count{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -456,7 +451,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -480,7 +475,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -490,13 +484,11 @@ "mode": "palette-classic" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -632,7 +624,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -640,8 +632,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "floor(increase(aligned_aggregator_received_tasks{bot=\"aggregator\"}[10y]))", + "editorMode": "code", + "expr": "floor(increase(aligned_aggregator_received_tasks_count{bot=\"aggregator\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -701,7 +693,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -709,9 +701,9 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", + "editorMode": "code", "exemplar": false, - "expr": "floor(increase(aligned_aggregated_responses{bot=\"aggregator\"}[10y]))", + "expr": "floor(increase(aligned_aggregated_responses_count{bot=\"aggregator\"}[10y]))", "format": "table", "fullMetaSearch": false, "includeNullMetadata": true, @@ -728,7 +720,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -776,7 +767,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -785,7 +776,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "increase(aligned_aggregator_gas_cost_paid_for_batcher{bot=\"aggregator\"}[10y])", + "expr": "increase(aligned_aggregator_gas_cost_paid_for_batcher_sum{bot=\"aggregator\"}[10y])", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -800,7 +791,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -847,7 +837,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -856,7 +846,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(aligned_aggregator_num_times_paid_for_batcher{bot=\"aggregator\"}[10y]))", + "expr": "floor(increase(aligned_aggregator_num_times_paid_for_batcher_count{bot=\"aggregator\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -890,7 +880,7 @@ "content": "

\n SYSTEM STATUS\n

", "mode": "html" }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "transparent": true, "type": "text" }, @@ -943,7 +933,7 @@ "showThresholdMarkers": true, "sizing": "auto" }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -951,8 +941,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "open_connections{job=\"aligned-batcher\"}", + "editorMode": "code", + "expr": "open_connections_count{job=\"aligned-batcher\"}", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -967,7 +957,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -1025,7 +1014,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -1035,7 +1024,7 @@ "disableTextWrap": false, "editorMode": "code", "exemplar": false, - "expr": "floor(increase(aligned_aggregator_received_tasks{job=\"aligned-aggregator\"}[$__range]))", + "expr": "floor(increase(aligned_aggregator_received_tasks_count{job=\"aligned-aggregator\"}[$__range]))", "fullMetaSearch": false, "hide": true, "includeNullMetadata": true, @@ -1053,7 +1042,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(aligned_aggregated_responses{job=\"aligned-aggregator\"}[$__range]))", + "expr": "floor(increase(aligned_aggregated_responses_count{job=\"aligned-aggregator\"}[$__range]))", "fullMetaSearch": false, "hide": true, "includeNullMetadata": true, @@ -1101,7 +1090,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -1151,7 +1139,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -1160,7 +1148,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(batcher_started{job=\"aligned-batcher\"}[10y]))", + "expr": "floor(increase(batcher_started_count{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1175,7 +1163,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -1185,13 +1172,11 @@ "mode": "palette-classic" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -1262,7 +1247,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(batcher_started{job=\"aligned-batcher\"}[10y]))", + "expr": "floor(increase(batcher_started_count{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1296,7 +1281,7 @@ "content": "

\n SYSTEM STATUS\n

", "mode": "html" }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "transparent": true, "type": "text" }, @@ -1321,7 +1306,7 @@ "content": "

\n BATCHER\n

", "mode": "html" }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "transparent": true, "type": "text" }, @@ -1346,7 +1331,7 @@ "content": "

\n AGGREGATOR\n

", "mode": "html" }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "transparent": true, "type": "text" }, @@ -1405,7 +1390,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -1414,7 +1399,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(sent_batches{job=\"aligned-batcher\"}[$__range]))", + "expr": "floor(increase(sent_batches_count{job=\"aligned-batcher\"}[$__range]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1438,13 +1423,11 @@ "mode": "palette-classic" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -1514,7 +1497,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(sent_batches{job=\"aligned-batcher\"}[10y]))", + "expr": "floor(increase(sent_batches_count{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1575,7 +1558,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -1583,8 +1566,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "floor(increase(aligned_aggregator_received_tasks{bot=\"aggregator\"}[$__range]))", + "editorMode": "code", + "expr": "floor(increase(aligned_aggregator_received_tasks_count{bot=\"aggregator\"}[$__range]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1608,13 +1591,11 @@ "mode": "palette-classic" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -1684,8 +1665,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "floor(increase(aligned_aggregated_responses{bot=\"aggregator\"}[10y]))", + "editorMode": "code", + "expr": "floor(increase(aligned_aggregated_responses_count{bot=\"aggregator\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1753,7 +1734,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -1762,7 +1743,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(reverted_batches{job=\"aligned-batcher\"}[$__range]))", + "expr": "floor(increase(reverted_batches_count{job=\"aligned-batcher\"}[$__range]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1786,13 +1767,11 @@ "mode": "palette-classic" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -1861,8 +1840,8 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "floor(increase(reverted_batches{job=\"aligned-batcher\"}[10y]))", + "editorMode": "code", + "expr": "floor(increase(reverted_batches_count{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1922,7 +1901,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -1930,9 +1909,9 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", + "editorMode": "code", "exemplar": false, - "expr": "floor(increase(aligned_aggregated_responses{bot=\"aggregator\"}[$__range]))", + "expr": "floor(increase(aligned_aggregated_responses_count{bot=\"aggregator\"}[$__range]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -1947,7 +1926,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -1957,13 +1935,11 @@ "mode": "palette-classic" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -2034,7 +2010,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(aligned_aggregator_received_tasks{bot=\"aggregator\"}[10y]))", + "expr": "floor(increase(aligned_aggregator_received_tasks_count{bot=\"aggregator\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -2049,7 +2025,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -2103,7 +2078,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.2.2+security-01", + "pluginVersion": "10.1.10", "targets": [ { "datasource": { @@ -2112,7 +2087,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(canceled_batches{job=\"aligned-batcher\"}[$__range]))", + "expr": "floor(increase(canceled_batches_count{job=\"aligned-batcher\"}[$__range]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -2127,7 +2102,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -2137,13 +2111,11 @@ "mode": "palette-classic" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -2213,7 +2185,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(canceled_batches{job=\"aligned-batcher\"}[10y]))", + "expr": "floor(increase(canceled_batches_count{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -2228,7 +2200,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -2239,13 +2210,11 @@ "mode": "palette-classic" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -2316,7 +2285,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(aligned_respond_to_task_gas_price_bumped{bot=\"aggregator\"}[10y]))", + "expr": "floor(increase(aligned_respond_to_task_gas_price_bumped_count{bot=\"aggregator\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -2331,7 +2300,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -2342,13 +2310,11 @@ "mode": "palette-classic" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -2419,7 +2385,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(broken_ws_connections{job=\"aligned-batcher\"}[10y]))", + "expr": "floor(increase(broken_ws_connections_count{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -2434,7 +2400,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -2445,13 +2410,11 @@ "mode": "palette-classic" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -2517,7 +2480,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(aligned_aggregator_num_times_paid_for_batcher{bot=\"aggregator\"}[10y]))", + "expr": "floor(increase(aligned_aggregator_num_times_paid_for_batcher_count{bot=\"aggregator\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -2532,7 +2495,6 @@ }, { "datasource": { - "default": true, "type": "prometheus", "uid": "prometheus" }, @@ -2542,13 +2504,11 @@ "mode": "palette-classic" }, "custom": { - "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, - "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -2618,7 +2578,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "floor(increase(user_errors{job=\"aligned-batcher\"}[10y]))", + "expr": "floor(increase(user_errors_count{job=\"aligned-batcher\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -2668,7 +2628,8 @@ } ], "refresh": "5s", - "schemaVersion": 39, + "schemaVersion": 38, + "style": "dark", "tags": [], "templating": { "list": [] @@ -2681,6 +2642,6 @@ "timezone": "browser", "title": "System Data", "uid": "aggregator", - "version": 8, + "version": 9, "weekStart": "" } \ No newline at end of file diff --git a/grafana/provisioning/dashboards/aligned/operator.json b/grafana/provisioning/dashboards/aligned/operator.json index bb229c98a1..3b54409820 100644 --- a/grafana/provisioning/dashboards/aligned/operator.json +++ b/grafana/provisioning/dashboards/aligned/operator.json @@ -18,7 +18,7 @@ "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, - "id": 2, + "id": 3, "links": [], "liveNow": false, "panels": [ @@ -76,9 +76,9 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", + "editorMode": "code", "exemplar": false, - "expr": "floor(increase(aligned_operator_responses{bot=\"operator\"}[10y]))", + "expr": "floor(increase(aligned_operator_responses_count{bot=\"operator\"}[10y]))", "format": "table", "fullMetaSearch": false, "includeNullMetadata": true, @@ -147,9 +147,9 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", + "editorMode": "code", "exemplar": false, - "expr": "floor(increase(aligned_operator_responses{bot=\"operator\"}[$__range]))", + "expr": "floor(increase(aligned_operator_responses_count{bot=\"operator\"}[$__range]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -247,18 +247,18 @@ "uid": "prometheus" }, "disableTextWrap": false, - "editorMode": "builder", - "expr": "floor(increase(aligned_operator_responses{bot=\"operator\"}[10y]))", + "editorMode": "code", + "expr": "floor(increase(aligned_operator_responses_count{bot=\"operator\"}[10y]))", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, - "legendFormat": "__auto", + "legendFormat": "{{job}}", "range": true, "refId": "A", "useBackend": false } ], - "title": "Operator", + "title": "Operator Responses", "type": "timeseries" }, { @@ -319,7 +319,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "rate(aligned_operator_responses{bot=\"operator\"}[1m]) * 60", + "expr": "rate(aligned_operator_responses_count{bot=\"operator\"}[1m]) * 60", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -385,7 +385,7 @@ "uid": "prometheus" }, "editorMode": "code", - "expr": "rate(aligned_operator_responses{bot=\"operator\"}[1m])", + "expr": "rate(aligned_operator_responses_count{bot=\"operator\"}[1m])", "instant": false, "legendFormat": "__auto", "range": true, @@ -481,7 +481,7 @@ }, "disableTextWrap": false, "editorMode": "code", - "expr": "rate(aligned_operator_responses{bot=\"operator\"}[1m]) * 60", + "expr": "rate(aligned_operator_responses_count{bot=\"operator\"}[1m]) * 60", "fullMetaSearch": false, "includeNullMetadata": true, "instant": false, @@ -495,7 +495,7 @@ "type": "timeseries" } ], - "refresh": "auto", + "refresh": "5s", "schemaVersion": 38, "style": "dark", "tags": [], @@ -510,6 +510,6 @@ "timezone": "browser", "title": "Operator Data", "uid": "operator", - "version": 3, + "version": 4, "weekStart": "" } \ No newline at end of file diff --git a/metrics/metrics.go b/metrics/metrics.go index e76d83b7be..dda2f7a04a 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -31,32 +31,32 @@ func NewMetrics(ipPortAddress string, reg prometheus.Registerer, logger logging. logger: logger, numAggregatedResponses: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Namespace: alignedNamespace, - Name: "aggregated_responses", + Name: "aggregated_responses_count", Help: "Number of aggregated responses sent to the Aligned Service Manager", }), numOperatorTaskResponses: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Namespace: alignedNamespace, - Name: "operator_responses", + Name: "operator_responses_count", Help: "Number of proof verified by the operator and sent to the Aligned Service Manager", }), numAggregatorReceivedTasks: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Namespace: alignedNamespace, - Name: "aggregator_received_tasks", + Name: "aggregator_received_tasks_count", Help: "Number of tasks received by the Service Manager", }), aggregatorGasCostPaidForBatcherTotal: promauto.With(reg).NewGauge(prometheus.GaugeOpts{ Namespace: alignedNamespace, - Name: "aggregator_gas_cost_paid_for_batcher", + Name: "aggregator_gas_cost_paid_for_batcher_sum", Help: "Accumulated gas cost the aggregator paid for the batcher when the tx cost was higher than the respondToTaskFeeLimit", }), aggregatorNumTimesPaidForBatcher: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Namespace: alignedNamespace, - Name: "aggregator_num_times_paid_for_batcher", + Name: "aggregator_num_times_paid_for_batcher_count", Help: "Number of times the aggregator paid for the batcher when the tx cost was higher than the respondToTaskFeeLimit", }), numBumpedGasPriceForAggregatedResponse: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Namespace: alignedNamespace, - Name: "respond_to_task_gas_price_bumped", + Name: "respond_to_task_gas_price_bumped_count", Help: "Number of times gas price was bumped while sending aggregated response", }), } From 94fcec9da1710a474f9c0a2aa8d43f0bc22a76a5 Mon Sep 17 00:00:00 2001 From: Uriel Mihura <43704209+uri-99@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:13:00 -0300 Subject: [PATCH 7/9] fix: flush batcher queue only when needed (#1512) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Julian Ventura Co-authored-by: avilagaston9 Co-authored-by: Marcos Nicolau <76252340+MarcosNicolau@users.noreply.github.com> Co-authored-by: Marcos Nicolau Co-authored-by: Avila Gastón <72628438+avilagaston9@users.noreply.github.com> --- batcher/aligned-batcher/src/lib.rs | 92 +++++++++++++------ .../aligned-batcher/src/types/batch_queue.rs | 74 +++++++-------- batcher/aligned-batcher/src/types/errors.rs | 9 +- 3 files changed, 107 insertions(+), 68 deletions(-) diff --git a/batcher/aligned-batcher/src/lib.rs b/batcher/aligned-batcher/src/lib.rs index 27de99667a..4ba6e8f0f0 100644 --- a/batcher/aligned-batcher/src/lib.rs +++ b/batcher/aligned-batcher/src/lib.rs @@ -48,7 +48,7 @@ use tokio::net::{TcpListener, TcpStream}; use tokio::sync::{Mutex, MutexGuard, RwLock}; use tokio_tungstenite::tungstenite::{Error, Message}; use types::batch_queue::{self, BatchQueueEntry, BatchQueueEntryPriority}; -use types::errors::BatcherError; +use types::errors::{BatcherError, TransactionSendError}; use crate::config::{ConfigFromYaml, ContractDeploymentOutput}; use crate::telemetry::sender::TelemetrySender; @@ -1116,12 +1116,13 @@ impl Batcher { /// an empty batch, even if the block interval has been reached. /// Once the batch meets the conditions for submission, the finalized batch is then passed to the /// `finalize_batch` function. + /// This function doesn't remove the proofs from the queue. async fn is_batch_ready( &self, block_number: u64, gas_price: U256, ) -> Option> { - let mut batch_state_lock = self.batch_state.lock().await; + let batch_state_lock = self.batch_state.lock().await; let current_batch_len = batch_state_lock.batch_queue.len(); let last_uploaded_batch_block_lock = self.last_uploaded_batch_block.lock().await; @@ -1153,7 +1154,7 @@ impl Batcher { // Set the batch posting flag to true *batch_posting = true; let batch_queue_copy = batch_state_lock.batch_queue.clone(); - let (resulting_batch_queue, finalized_batch) = batch_queue::try_build_batch( + let finalized_batch = batch_queue::try_build_batch( batch_queue_copy, gas_price, self.max_batch_byte_size, @@ -1173,7 +1174,26 @@ impl Batcher { }) .ok()?; - batch_state_lock.batch_queue = resulting_batch_queue; + Some(finalized_batch) + } + + /// Takes the submitted proofs and removes them from the queue. + /// This function should be called only AFTER the submission was confirmed onchain + async fn remove_proofs_from_queue( + &self, + finalized_batch: Vec, + ) -> Result<(), BatcherError> { + info!("Removing proofs from queue..."); + let mut batch_state_lock = self.batch_state.lock().await; + + finalized_batch.iter().for_each(|entry| { + if batch_state_lock.batch_queue.remove(entry).is_none() { + // If this happens, we have a bug in our code + error!("Some proofs were not found in the queue. This should not happen."); + } + }); + + // now we calculate the new user_states let new_user_states = // proofs, max_fee_limit, total_fees_in_queue batch_state_lock.calculate_new_user_states_data(); @@ -1189,17 +1209,33 @@ impl Batcher { // informative error. // Now we update the user states related to the batch (proof count in batch and min fee in batch) - batch_state_lock.update_user_proof_count(addr, *proof_count)?; - batch_state_lock.update_user_max_fee_limit(addr, *max_fee_limit)?; - batch_state_lock.update_user_total_fees_in_queue(addr, *total_fees_in_queue)?; + batch_state_lock + .update_user_proof_count(addr, *proof_count) + .ok_or(BatcherError::QueueRemoveError( + "Could not update_user_proof_count".into(), + ))?; + batch_state_lock + .update_user_max_fee_limit(addr, *max_fee_limit) + .ok_or(BatcherError::QueueRemoveError( + "Could not update_user_max_fee_limit".into(), + ))?; + batch_state_lock + .update_user_total_fees_in_queue(addr, *total_fees_in_queue) + .ok_or(BatcherError::QueueRemoveError( + "Could not update_user_total_fees_in_queue".into(), + ))?; } - Some(finalized_batch) + Ok(()) } - /// Takes the finalized batch as input and builds the merkle tree, posts verification data batch - /// to s3, creates new task in Aligned contract and sends responses to all clients that added proofs - /// to the batch. The last uploaded batch block is updated once the task is created in Aligned. + /// Takes the finalized batch as input and: + /// builds the merkle tree + /// posts verification data batch to s3 + /// creates new task in Aligned contract + /// removes the proofs from the queue, once they are succesfully submitted on-chain + /// sends responses to all clients that added proofs to the batch. + /// The last uploaded batch block is updated once the task is created in Aligned. async fn finalize_batch( &self, block_number: u64, @@ -1257,6 +1293,7 @@ impl Batcher { warn!("Failed to initialize task trace on telemetry: {:?}", e); } + // Here we submit the batch on-chain if let Err(e) = self .submit_batch( &batch_bytes, @@ -1275,27 +1312,30 @@ impl Batcher { { warn!("Failed to send task status to telemetry: {:?}", e); } - for entry in finalized_batch.into_iter() { - if let Some(ws_sink) = entry.messaging_sink { - let merkle_root = hex::encode(batch_merkle_tree.root); - send_message( - ws_sink.clone(), - SubmitProofResponseMessage::CreateNewTaskError( - merkle_root, - format!("{:?}", e), - ), - ) - .await - } else { - warn!("Websocket sink was found empty. This should only happen in tests"); + + // decide if i want to flush the queue: + match e { + BatcherError::TransactionSendError( + TransactionSendError::SubmissionInsufficientBalance, + ) => { + // TODO calling remove_proofs_from_queue here is a better solution, flushing only the failed batch + // this would also need a message sent to the clients + self.flush_queue_and_clear_nonce_cache().await; + } + _ => { + // Add more cases here if we want in the future } } - self.flush_queue_and_clear_nonce_cache().await; - return Err(e); }; + // Once the submit is succesfull, we remove the submitted proofs from the queue + // TODO handle error case: + if let Err(e) = self.remove_proofs_from_queue(finalized_batch.clone()).await { + error!("Unexpected error while updating queue: {:?}", e); + } + connection::send_batch_inclusion_data_responses(finalized_batch, &batch_merkle_tree).await } diff --git a/batcher/aligned-batcher/src/types/batch_queue.rs b/batcher/aligned-batcher/src/types/batch_queue.rs index 17918e7a21..3ed9dca291 100644 --- a/batcher/aligned-batcher/src/types/batch_queue.rs +++ b/batcher/aligned-batcher/src/types/batch_queue.rs @@ -134,27 +134,25 @@ pub(crate) fn calculate_batch_size(batch_queue: &BatchQueue) -> Result Result<(BatchQueue, Vec), BatcherError> { - let mut batch_queue = batch_queue; - let mut batch_size = calculate_batch_size(&batch_queue)?; - let mut resulting_priority_queue = BatchQueue::new(); +) -> Result, BatcherError> { + let mut finalized_batch = batch_queue; + let mut batch_size = calculate_batch_size(&finalized_batch)?; - while let Some((entry, _)) = batch_queue.peek() { - let batch_len = batch_queue.len(); + while let Some((entry, _)) = finalized_batch.peek() { + let batch_len = finalized_batch.len(); let fee_per_proof = calculate_fee_per_proof(batch_len, gas_price); if batch_size > max_batch_byte_size @@ -173,8 +171,7 @@ pub(crate) fn try_build_batch( .len(); batch_size -= verification_data_size; - let (not_working_entry, not_working_priority) = batch_queue.pop().unwrap(); - resulting_priority_queue.push(not_working_entry, not_working_priority); + finalized_batch.pop(); continue; } @@ -183,16 +180,13 @@ pub(crate) fn try_build_batch( break; } - // If `batch_queue_copy` is empty, this means that all the batch queue was traversed and we didn't find + // If `finalized_batch` is empty, this means that all the batch queue was traversed and we didn't find // any user willing to pay fot the fee per proof. - if batch_queue.is_empty() { + if finalized_batch.is_empty() { return Err(BatcherError::BatchCostTooHigh); } - Ok(( - resulting_priority_queue, - batch_queue.clone().into_sorted_vec(), - )) + Ok(finalized_batch.clone().into_sorted_vec()) } fn calculate_fee_per_proof(batch_len: usize, gas_price: U256) -> U256 { @@ -301,14 +295,20 @@ mod test { batch_queue.push(entry_3, batch_priority_3); let gas_price = U256::from(1); - let (resulting_batch_queue, batch) = - try_build_batch(batch_queue, gas_price, 5000000, 50).unwrap(); + let finalized_batch = try_build_batch(batch_queue, gas_price, 5000000, 50).unwrap(); - assert!(resulting_batch_queue.is_empty()); - - assert_eq!(batch[0].nonced_verification_data.max_fee, max_fee_3); - assert_eq!(batch[1].nonced_verification_data.max_fee, max_fee_2); - assert_eq!(batch[2].nonced_verification_data.max_fee, max_fee_1); + assert_eq!( + finalized_batch[0].nonced_verification_data.max_fee, + max_fee_3 + ); + assert_eq!( + finalized_batch[1].nonced_verification_data.max_fee, + max_fee_2 + ); + assert_eq!( + finalized_batch[2].nonced_verification_data.max_fee, + max_fee_1 + ); } #[test] @@ -404,13 +404,11 @@ mod test { batch_queue.push(entry_3, batch_priority_3); let gas_price = U256::from(1); - let (resulting_batch_queue, finalized_batch) = - try_build_batch(batch_queue, gas_price, 5000000, 50).unwrap(); + let finalized_batch = try_build_batch(batch_queue.clone(), gas_price, 5000000, 50).unwrap(); - // The resulting batch queue (entries from the old batch queue that were not willing to pay - // in this batch), should be empty and hence, all entries from the batch queue should be in + // All entries from the batch queue should be in // the finalized batch. - assert!(resulting_batch_queue.is_empty()); + assert_eq!(batch_queue.len(), 3); assert_eq!(finalized_batch.len(), 3); assert_eq!( finalized_batch[0].nonced_verification_data.max_fee, @@ -515,14 +513,10 @@ mod test { batch_queue.push(entry_3, batch_priority_3); let gas_price = U256::from(1); - let (resulting_batch_queue, finalized_batch) = - try_build_batch(batch_queue, gas_price, 5000000, 50).unwrap(); - - // The resulting batch queue (entries from the old batch queue that were not willing to pay - // in this batch), should be empty and hence, all entries from the batch queue should be in - // the finalized batch. + let finalized_batch = try_build_batch(batch_queue.clone(), gas_price, 5000000, 50).unwrap(); - assert_eq!(resulting_batch_queue.len(), 1); + // All but one entries from the batch queue should be in the finalized batch. + assert_eq!(batch_queue.len(), 3); assert_eq!(finalized_batch.len(), 2); assert_eq!( finalized_batch[0].nonced_verification_data.max_fee, @@ -628,10 +622,10 @@ mod test { // The max batch len is 2, so the algorithm should stop at the second entry. let max_batch_proof_qty = 2; - let (resulting_batch_queue, finalized_batch) = - try_build_batch(batch_queue, gas_price, 5000000, max_batch_proof_qty).unwrap(); + let finalized_batch = + try_build_batch(batch_queue.clone(), gas_price, 5000000, max_batch_proof_qty).unwrap(); - assert_eq!(resulting_batch_queue.len(), 1); + assert_eq!(batch_queue.len(), 3); assert_eq!(finalized_batch.len(), 2); assert_eq!( finalized_batch[0].nonced_verification_data.max_fee, diff --git a/batcher/aligned-batcher/src/types/errors.rs b/batcher/aligned-batcher/src/types/errors.rs index 768684fca9..1262045d64 100644 --- a/batcher/aligned-batcher/src/types/errors.rs +++ b/batcher/aligned-batcher/src/types/errors.rs @@ -27,12 +27,13 @@ impl From for TransactionSendError { "0xa3a8658a" => TransactionSendError::NoFeePerProof, // can't happen, don't flush "0x7899ec71" => TransactionSendError::InsufficientFeeForAggregator, // shouldn't happen, don't flush // returning the proofs and retrying later may help - "0x4f779ceb" => TransactionSendError::SubmissionInsufficientBalance, // shouldn't happen, - // flush can help if something went wrong "0x3102f10c" => TransactionSendError::BatchAlreadySubmitted, // can happen, don't flush "0x5c54305e" => TransactionSendError::InsufficientFunds, // shouldn't happen, don't flush "0x152bc288" => TransactionSendError::OnlyBatcherAllowed, // won't happen, don't flush + "0x4f779ceb" => TransactionSendError::SubmissionInsufficientBalance, // shouldn't happen, + // flush can help if something went wrong _ => { + // flush because unkown error TransactionSendError::Generic(format!("Unknown bytestring error: {}", byte_string)) } } @@ -56,6 +57,7 @@ pub enum BatcherError { BatchCostTooHigh, WsSinkEmpty, AddressNotFoundInUserStates(Address), + QueueRemoveError(String), } impl From for BatcherError { @@ -134,6 +136,9 @@ impl fmt::Debug for BatcherError { reason ) } + BatcherError::QueueRemoveError(e) => { + write!(f, "Error while removing entry from queue: {}", e) + } } } } From 15bf1af54ff62eb6b6237126d49329d94aa0594e Mon Sep 17 00:00:00 2001 From: Urix <43704209+uri-99@users.noreply.github.com> Date: Wed, 4 Dec 2024 14:56:54 -0300 Subject: [PATCH 8/9] feat: sdk function --- batcher/aligned-sdk/src/core/errors.rs | 9 ++++ batcher/aligned-sdk/src/core/types.rs | 19 ++++++++ batcher/aligned-sdk/src/sdk.rs | 64 ++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/batcher/aligned-sdk/src/core/errors.rs b/batcher/aligned-sdk/src/core/errors.rs index 8712009c65..943ae90749 100644 --- a/batcher/aligned-sdk/src/core/errors.rs +++ b/batcher/aligned-sdk/src/core/errors.rs @@ -352,3 +352,12 @@ impl fmt::Display for FileError { } } } + +pub enum BumpError { + WebSocketConnectionError(tokio_tungstenite::tungstenite::Error), + InvalidBumpUnit, + SerializationError(String), + ConnectionFailed(String), + EthRpcError(String), + InvalidRequest(String), +} diff --git a/batcher/aligned-sdk/src/core/types.rs b/batcher/aligned-sdk/src/core/types.rs index ab392df51c..1cecf9bae8 100644 --- a/batcher/aligned-sdk/src/core/types.rs +++ b/batcher/aligned-sdk/src/core/types.rs @@ -231,6 +231,7 @@ pub enum ClientMessage { // Needs to be wrapped in box as the message is 3x bigger than the others // see https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant SubmitProof(Box), + BumpFee(BumpUnit, U256, usize), // BumpUnit, value, proof_qty } impl Display for ClientMessage { @@ -239,6 +240,7 @@ impl Display for ClientMessage { match self { ClientMessage::GetNonceForAddress(_) => write!(f, "GetNonceForAddress"), ClientMessage::SubmitProof(_) => write!(f, "SubmitProof"), + ClientMessage::BumpFee(_, _, _) => write!(f, "BumpFee"), } } } @@ -396,6 +398,23 @@ pub enum GetNonceResponseMessage { InvalidRequest(String), } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum BumpFeeResponseMessage { + Ok(), + EthRpcError(String), + InvalidRequest(String), +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub enum BumpUnit { + Percentage, + Wei, + Gwei, + Eth, + NewMaxFee, + BatchSize, +} + #[derive(Debug, Clone, Copy)] pub enum Network { Devnet, diff --git a/batcher/aligned-sdk/src/sdk.rs b/batcher/aligned-sdk/src/sdk.rs index a9a0ad5a03..445de5dff3 100644 --- a/batcher/aligned-sdk/src/sdk.rs +++ b/batcher/aligned-sdk/src/sdk.rs @@ -10,10 +10,10 @@ use crate::{ ADDITIONAL_SUBMISSION_GAS_COST_PER_PROOF, CONSTANT_GAS_COST, MAX_FEE_BATCH_PROOF_NUMBER, MAX_FEE_DEFAULT_PROOF_NUMBER, }, - errors::{self, GetNonceError}, + errors::{self, BumpError, GetNonceError}, types::{ - AlignedVerificationData, ClientMessage, GetNonceResponseMessage, Network, - PriceEstimate, ProvingSystemId, VerificationData, + AlignedVerificationData, BumpFeeResponseMessage, BumpUnit, ClientMessage, + GetNonceResponseMessage, Network, PriceEstimate, ProvingSystemId, VerificationData, }, }, eth::{ @@ -466,6 +466,64 @@ pub async fn submit( } } +pub async fn bump_user_fees( + network: Network, + bump_unit: BumpUnit, + bump_amount: U256, + proof_qty: usize, // Number of proofs to bump fees, from oldest to newest + // maybe also i will need a signature here +) -> Result<(), errors::BumpError> { + // let batcher_url = network.get_batcher_url(); // This is in a PR + let batcher_url = "network.get_batcher_url()"; + // let (ws_stream, _) = match connect_async(batcher_url).await { + // Ok((ws_stream, response)) => (ws_stream, response), + // Err(e) => return Err(BumpError::WebSocketConnectionError(e)), + // }; + let (ws_stream, _) = connect_async(batcher_url) + .await + .map_err(|e| BumpError::WebSocketConnectionError(e))?; + debug!("WebSocket handshake has been successfully completed"); + let (mut ws_write, ws_read) = ws_stream.split(); + + let msg = ClientMessage::BumpFee(bump_unit, bump_amount, proof_qty); + + let msg_bin = cbor_serialize(&msg) + .map_err(|_| BumpError::SerializationError("Failed to serialize msg".to_string()))?; + + ws_write + .send(Message::Binary(msg_bin.clone())) + .await + .map_err(|_| { + BumpError::ConnectionFailed( + "Ws connection failed to send message to batcher".to_string(), + ) + })?; + + let mut response_stream: ResponseStream = + ws_read.try_filter(|msg| futures_util::future::ready(msg.is_binary())); + + let response_msg = match response_stream.next().await { + Some(Ok(msg)) => msg, + _ => { + return Err(BumpError::ConnectionFailed( + "Connection was closed without close message before receiving all messages" + .to_string(), + )); + } + }; + + let _ = ws_write.close().await; + + match cbor_deserialize(response_msg.into_data().as_slice()) { + Ok(BumpFeeResponseMessage::Ok()) => Ok(()), + Ok(BumpFeeResponseMessage::EthRpcError(e)) => Err(BumpError::EthRpcError(e)), + Ok(BumpFeeResponseMessage::InvalidRequest(e)) => Err(BumpError::InvalidRequest(e)), + Err(_) => Err(BumpError::SerializationError( + "Failed to deserialize batcher response message".to_string(), + )), + } +} + /// Checks if the proof has been verified with Aligned and is included in the batch. /// # Arguments /// * `aligned_verification_data` - The aligned verification data obtained when submitting the proofs. From 4b6f5f40bb4e4432bd3824691594e811c98be398 Mon Sep 17 00:00:00 2001 From: Urix <43704209+uri-99@users.noreply.github.com> Date: Wed, 4 Dec 2024 16:11:06 -0300 Subject: [PATCH 9/9] feat: wip logic in batcher --- batcher/aligned-batcher/src/eth/utils.rs | 38 +++++++++- batcher/aligned-batcher/src/lib.rs | 90 +++++++++++++++++++++++- batcher/aligned-sdk/src/core/types.rs | 67 +++++++++++++++++- 3 files changed, 189 insertions(+), 6 deletions(-) diff --git a/batcher/aligned-batcher/src/eth/utils.rs b/batcher/aligned-batcher/src/eth/utils.rs index 6f5c671940..08c54afc7d 100644 --- a/batcher/aligned-batcher/src/eth/utils.rs +++ b/batcher/aligned-batcher/src/eth/utils.rs @@ -8,11 +8,11 @@ use crate::{ retry_function, }, }; -use aligned_sdk::core::constants::{ +use aligned_sdk::core::{constants::{ ETHEREUM_CALL_BACKOFF_FACTOR, ETHEREUM_CALL_MAX_RETRIES, ETHEREUM_CALL_MAX_RETRY_DELAY, ETHEREUM_CALL_MIN_RETRY_DELAY, GAS_PRICE_INCREMENT_PERCENTAGE_PER_ITERATION, OVERRIDE_GAS_PRICE_PERCENTAGE_MULTIPLIER, PERCENTAGE_DIVIDER, -}; +}, errors::BumpError, types::BumpUnit}; use ethers::prelude::*; use ethers::providers::{Http, Provider}; use log::error; @@ -103,6 +103,40 @@ pub async fn get_gas_price( e.inner() }) } + +pub async fn calculate_bumped_proof_cost( + current_gas_price: U256, + bump_unit: BumpUnit, + amount: U256, +) -> Result { + let new_max_fee = match bump_unit { + BumpUnit::NewMaxFee => { + amount + } + BumpUnit::Wei => { + current_gas_price + amount + } + BumpUnit::Gwei => { + current_gas_price + (amount * U256::from(1_000_000_000)) + } + BumpUnit::Eth => { + current_gas_price + (amount * U256::from(1_000_000_000_000_000_000)) + } + BumpUnit::Percentage => { + current_gas_price + (current_gas_price * amount / U256::from(PERCENTAGE_DIVIDER)) + } + // TODO once Pats pr is done: + // BumpUnit::BatchSize => { + + // } + _ => { + warn!("Invalid bump unit: {bump_unit:?}"); + return Err(BumpError::InvalidBumpUnit); + } + }; + Ok(new_max_fee) +} + #[cfg(test)] mod tests { use super::*; diff --git a/batcher/aligned-batcher/src/lib.rs b/batcher/aligned-batcher/src/lib.rs index b760d9c82b..f7297710e8 100644 --- a/batcher/aligned-batcher/src/lib.rs +++ b/batcher/aligned-batcher/src/lib.rs @@ -31,9 +31,7 @@ use aligned_sdk::core::constants::{ RESPOND_TO_TASK_FEE_LIMIT_PERCENTAGE_MULTIPLIER, }; use aligned_sdk::core::types::{ - ClientMessage, GetNonceResponseMessage, NoncedVerificationData, ProofInvalidReason, - ProvingSystemId, SubmitProofMessage, SubmitProofResponseMessage, VerificationCommitmentBatch, - VerificationData, VerificationDataCommitment, + BumpFeeResponseMessage, BumpUnit, ClientMessage, GetNonceResponseMessage, NoncedVerificationData, ProofInvalidReason, ProvingSystemId, SubmitProofMessage, SubmitProofResponseMessage, VerificationCommitmentBatch, VerificationData, VerificationDataCommitment }; use aws_sdk_s3::client::Client as S3Client; @@ -473,6 +471,11 @@ impl Batcher { .handle_submit_proof_msg(msg, ws_conn_sink) .await } + ClientMessage::BumpFee(bump_unit, amout, proof_qty) => { + self.clone() + .handle_bump_fee_msg(bump_unit, amout, proof_qty, ws_conn_sink) + .await + } } } @@ -783,6 +786,9 @@ impl Batcher { // In this case, the message might be a replacement one. If it is valid, // we replace the old entry with the new from the replacement message. + + // TODO DISABLE THIS FUNCTIONALITY + // IT IS BEING REPLACED WITH BumpFee() if expected_nonce > msg_nonce { info!("Possible replacement message received: Expected nonce {expected_nonce:?} - message nonce: {msg_nonce:?}"); self.handle_replacement_message( @@ -833,6 +839,84 @@ impl Batcher { Ok(()) } + + // TODO add signature + async fn handle_bump_fee_msg( + bump_unit: BumpUnit, + amount: U256, + proof_qty: usize, + signature: Signature, //TODO add this + signature_content: Vec, //TODO add this + ws_conn_sink: WsMessageSink, + ) -> Result<(), Error> { + + // /// The signature of the message is verified, and when it correct, the + // /// recovered address from the signature is returned. + // pub fn verify_signature(&self) -> Result { + // // Recovers the address from the signed data + // let recovered = self.signature.recover_typed_data(&self.verification_data)?; + + // let hashed_data = self.verification_data.encode_eip712()?; + + // self.signature.verify(hashed_data, recovered)?; + // Ok(recovered) + // } + + info!("Verifying Bump Fee signature..."); + let Ok(addr) = verify_bump_signature(signature, signature_content) else { + error!("Signature verification error"); + send_message( + ws_conn_sink.clone(), + BumpFeeResponseMessage::InvalidSignature, + ) + .await; + self.metrics.user_error(&["invalid_bump_fee_signature", ""]); + return Ok(()); + }; + info!("Bump Fee signature verified"); + + + let from_proof_nonce = self.get_first_proof(); + let to_proof_nonce = from_proof_nonce + proof_qty; // exclusive + + let batch_state_lock = self.batch_state.lock().await; + let batch_queue_copy = batch_state_lock.batch_queue.clone(); + + // TODO check if user has enough funds + while let Some((entry, _)) = batch_state_lock.batch_queue.peek() { + let entry_nonce = entry.nonced_verification_data.nonce; + if entry_nonce >= from_proof_nonce && entry_nonce < to_proof_nonce { + if let Err(bumped_fee) = calculate_bumped_proof_cost(entry.nonced_verification_data.max_fee, bump_unit, amount) { + send_message( + ws_conn_sink.clone(), + BumpFeeResponseMessage::InvalidBumpUnit, + ) + .await; + self.metrics.user_error(&["invalid_bump_fee_unit", ""]); + return Ok(()); + } + let new_entry = entry.clone(); + new_entry.nonced_verification_data.max_fee = bumped_fee; + + batch_state_lock.update_user_total_fees_in_queue_of_replacement_message(sender_address, entry_nonce.clone(), bumped_fee).await?; + batch_state_lock.replace_entry(entry, new_entry); + } + }; + return; + + } + + fn verify_bump_signature( + &self, + signature: Signature, + bump_unit: BumpUnit, + amount: U256, + proof_qty: usize, + ) -> bool { + // TODO + true + } + async fn is_verifier_disabled(&self, verifier: ProvingSystemId) -> bool { let disabled_verifiers = self.disabled_verifiers.lock().await; zk_utils::is_verifier_disabled(*disabled_verifiers, verifier) diff --git a/batcher/aligned-sdk/src/core/types.rs b/batcher/aligned-sdk/src/core/types.rs index 1cecf9bae8..2e21c43508 100644 --- a/batcher/aligned-sdk/src/core/types.rs +++ b/batcher/aligned-sdk/src/core/types.rs @@ -2,6 +2,7 @@ use std::fmt; use std::fmt::Display; use std::fmt::Formatter; use std::str::FromStr; +use std::time::{SystemTime, UNIX_EPOCH}; use ethers::core::k256::ecdsa::SigningKey; use ethers::signers::Signer; @@ -231,7 +232,8 @@ pub enum ClientMessage { // Needs to be wrapped in box as the message is 3x bigger than the others // see https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant SubmitProof(Box), - BumpFee(BumpUnit, U256, usize), // BumpUnit, value, proof_qty + // BumpFee(BumpUnit, U256, usize), // BumpUnit, value, proof_qty + BumpFee(BumpFeeMessage), // BumpUnit, value, proof_qty } impl Display for ClientMessage { @@ -398,11 +400,74 @@ pub enum GetNonceResponseMessage { InvalidRequest(String), } +pub struct BumpFeeMessage { + pub conent: BumpFeeMessageContent, + pub signature: Signature, +} + +pub struct BumpFeeMessageContent { + pub bump_unit: BumpUnit, + pub value: U256, + pub proof_qty: usize, + pub timestamp: u64, +} + +impl EIP712 for BumpFeeMessageContent { + type Error = Eip712Error; + fn domain(&self) -> Result { + Ok(EIP712Domain { + name: Some("Aligned".into()), + version: Some("1".into()), + chain_id: Some(self.chain_id), + verifying_contract: Some("0x00"), + salt: None, + }) + } + fn type_hash() -> Result<[u8; 32], Self::Error> { + let mut hasher = Keccak256::new(); + hasher.update(NONCED_VERIFICATION_DATA_TYPE); + Ok(hasher.finalize().into()) + } + + pub fn new(bump_unit: BumpUnit, value: U256, proof_qty: usize) -> Self { + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards"); + let timestamp = now.as_secs(); // Seconds since UNIX_EPOCH + + Self { + bump_unit, + value, + proof_qty, + timestamp, + } + } +} + +impl BumpFeeMessage { + pub fn new( + bump_unit: BumpUnit, + value: U256, + proof_qty: usize, + wallet: Wallet + ) -> Self { + let signature = wallet.sign_typed_data(&BumpFeeMessageContent::new(bump_unit, value, proof_qty)).unwrap(); + + Self { + bump_unit, + value, + proof_qty, + timestamp, + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub enum BumpFeeResponseMessage { Ok(), EthRpcError(String), InvalidRequest(String), + InvalidBumpUnit, } #[derive(Debug, Serialize, Deserialize, Clone)]