From 3daee25d21f7d56ebff0aa95886aee768a0e2cc8 Mon Sep 17 00:00:00 2001 From: Jordan Oroshiba Date: Thu, 12 Dec 2024 18:18:47 -0800 Subject: [PATCH 1/8] feat(sequencer, charts)!: support uds for abci --- Cargo.lock | 1 + charts/sequencer/Chart.yaml | 2 +- .../files/cometbft/config/config.toml | 2 +- .../sequencer/files/scripts/init-cometbft.sh | 2 - charts/sequencer/templates/_helpers.tpl | 18 ++- charts/sequencer/templates/configmaps.yaml | 5 +- charts/sequencer/templates/statefulsets.yaml | 9 ++ charts/sequencer/values.yaml | 5 +- crates/astria-sequencer/CHANGELOG.md | 8 ++ crates/astria-sequencer/Cargo.toml | 1 + crates/astria-sequencer/local.env.example | 8 +- crates/astria-sequencer/src/config.rs | 2 +- crates/astria-sequencer/src/sequencer.rs | 123 +++++++++++++----- 13 files changed, 138 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 130b3bff21..7c746f9f02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,6 +863,7 @@ dependencies = [ "tower-actor", "tower-http", "tracing", + "url", ] [[package]] diff --git a/charts/sequencer/Chart.yaml b/charts/sequencer/Chart.yaml index 832ce7df76..5107f393d6 100644 --- a/charts/sequencer/Chart.yaml +++ b/charts/sequencer/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.0.1 +version: 1.0.2 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. diff --git a/charts/sequencer/files/cometbft/config/config.toml b/charts/sequencer/files/cometbft/config/config.toml index b6d8ae68e1..586227f6e9 100644 --- a/charts/sequencer/files/cometbft/config/config.toml +++ b/charts/sequencer/files/cometbft/config/config.toml @@ -16,7 +16,7 @@ version = "0.38.8" # TCP or UNIX socket address of the ABCI application, # or the name of an ABCI application compiled in with the CometBFT binary -proxy_app = "tcp://127.0.0.1:{{ .Values.ports.sequencerABCI }}" +proxy_app = "{{ include "sequencer.abci_url" . }}" # A custom human readable name for this node moniker = "{{ .Values.moniker }}" diff --git a/charts/sequencer/files/scripts/init-cometbft.sh b/charts/sequencer/files/scripts/init-cometbft.sh index 9cc643f81b..800f7daeeb 100644 --- a/charts/sequencer/files/scripts/init-cometbft.sh +++ b/charts/sequencer/files/scripts/init-cometbft.sh @@ -13,5 +13,3 @@ if [ ! -d "/cometbft/config" ]; then else cp /config/* /cometbft/config/ fi - -chmod -R 0777 /cometbft diff --git a/charts/sequencer/templates/_helpers.tpl b/charts/sequencer/templates/_helpers.tpl index 2dc1da25ab..109bf5cd2a 100644 --- a/charts/sequencer/templates/_helpers.tpl +++ b/charts/sequencer/templates/_helpers.tpl @@ -69,9 +69,23 @@ name: {{ .Values.moniker }}-sequencer-metrics {{- end }} {{/* New sequencer address */}} -{{- define "sequencer.address"}}{ "bech32m": "{{ . }}" } +{{- define "sequencer.address" -}} +{ "bech32m": "{{ . }}" } {{- end }} {{/* uint64 fee converted to a astria proto Uint128 with only lo set */}} -{{- define "sequencer.toUint128Proto"}}{ "lo": {{ . }} } +{{- define "sequencer.toUint128Proto" -}} +{ "lo": {{ . }} } +{{- end }} + +{{- define "sequencer.socket_directory" -}} +/sockets/ +{{- end }} + +{{- define "sequencer.abci_url" -}} +{{- if and .Values.global.dev .Values.sequencer.abciUDS -}} +unix://{{- include "sequencer.socket_directory" . }}abci.sock +{{- else -}} +tcp://127.0.0.1:{{ .Values.ports.sequencerABCI }} +{{- end }} {{- end }} diff --git a/charts/sequencer/templates/configmaps.yaml b/charts/sequencer/templates/configmaps.yaml index 89f9deedea..ad420b3bfa 100644 --- a/charts/sequencer/templates/configmaps.yaml +++ b/charts/sequencer/templates/configmaps.yaml @@ -54,8 +54,7 @@ metadata: name: {{ .Values.moniker }}-sequencer-env namespace: {{ include "sequencer.namespace" . }} data: - ASTRIA_SEQUENCER_LOG: "astria_sequencer=debug" - ASTRIA_SEQUENCER_LISTEN_ADDR: "127.0.0.1:{{ .Values.ports.sequencerABCI }}" + ASTRIA_SEQUENCER_LOG: "info" ASTRIA_SEQUENCER_DB_FILEPATH: "/sequencer/penumbra.db" ASTRIA_SEQUENCER_MEMPOOL_PARKED_MAX_TX_COUNT: "{{ .Values.sequencer.mempool.parked.maxTxCount }}" # Socket address for GRPC server @@ -74,6 +73,8 @@ data: OTEL_EXPORTER_OTLP_TRACE_HEADERS: "{{ .Values.sequencer.otel.traceHeaders }}" OTEL_SERVICE_NAME: "{{ tpl .Values.sequencer.otel.serviceName . }}" {{- if not .Values.global.dev }} + ASTRIA_SEQUENCER_LISTEN_ADDR: "127.0.0.1:{{ .Values.ports.sequencerABCI }}" {{- else }} + ASTRIA_SEQUENCER_ABCI_LISTENER_URL: "{{ include "sequencer.abci_url" . }}" {{- end }} --- diff --git a/charts/sequencer/templates/statefulsets.yaml b/charts/sequencer/templates/statefulsets.yaml index 362a410f61..097a7fc4a5 100644 --- a/charts/sequencer/templates/statefulsets.yaml +++ b/charts/sequencer/templates/statefulsets.yaml @@ -16,6 +16,9 @@ spec: labels: app: {{ .Values.moniker }}-sequencer spec: + securityContext: + runAsUser: 1000 + fsGroup: 2000 initContainers: - command: [ "/scripts/init-cometbft.sh" ] name: config-cometbft @@ -45,6 +48,8 @@ spec: - mountPath: /sequencer name: sequencer-shared-storage-vol subPath: {{ .Values.moniker }}/sequencer + - mountPath: {{ include "sequencer.socket_directory" . }} + name: socket-volume ports: - containerPort: {{ .Values.ports.sequencerABCI }} name: sequencer-abci @@ -78,6 +83,8 @@ spec: - mountPath: /secrets readOnly: true name: sequencer-secret-keys-vol + - mountPath: {{ include "sequencer.socket_directory" . }} + name: socket-volume ports: - containerPort: {{ .Values.ports.cometbftP2P }} name: cometbft-p2p @@ -95,6 +102,8 @@ spec: cpu: {{ .Values.resources.cometbft.limits.cpu }} memory: {{ .Values.resources.cometbft.limits.memory }} volumes: + - name: socket-volume + emptyDir: {} - name: cometbft-config-volume configMap: name: {{ .Values.moniker }}-cometbft-config diff --git a/charts/sequencer/values.yaml b/charts/sequencer/values.yaml index 80bd795258..45b89dbf95 100644 --- a/charts/sequencer/values.yaml +++ b/charts/sequencer/values.yaml @@ -24,7 +24,7 @@ images: repo: ghcr.io/astriaorg/sequencer pullPolicy: IfNotPresent tag: 1.0.0 - devTag: latest + devTag: local moniker: "" genesis: @@ -105,6 +105,7 @@ genesis: # pubKey: lV57+rGs2vac7mvkGHP1oBFGHPJM3a+WoAzeFDCJDNU= sequencer: + abciUDS: true mempool: parked: maxTxCount: 200 @@ -311,7 +312,7 @@ storage: local: true entities: sequencerSharedStorage: - size: "5Gi" + size: "50Gi" persistentVolumeName: "sequencer-shared-storage" path: "/data/sequencer-data" diff --git a/crates/astria-sequencer/CHANGELOG.md b/crates/astria-sequencer/CHANGELOG.md index c80e93586f..64e474d018 100644 --- a/crates/astria-sequencer/CHANGELOG.md +++ b/crates/astria-sequencer/CHANGELOG.md @@ -16,6 +16,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ensure all deposit assets are trace prefixed [#1807](https://github.com/astriaorg/astria/pull/1807). - Update `idna` dependency to resolve cargo audit warning [#1869](https://github.com/astriaorg/astria/pull/1869). +### Removed + +- Remove ASTRIA_SEQUENCER_LISTEN_ADDR config variable [#1877](https://github.com/astriaorg/astria/pull/1877) + +### Added + +- Add ASTRIA_SEQUENCER_ABCI_LISTENER_URL config variable [#1877](https://github.com/astriaorg/astria/pull/1877) + ## [1.0.0] - 2024-10-25 ### Changed diff --git a/crates/astria-sequencer/Cargo.toml b/crates/astria-sequencer/Cargo.toml index 56014df011..f46316c75c 100644 --- a/crates/astria-sequencer/Cargo.toml +++ b/crates/astria-sequencer/Cargo.toml @@ -42,6 +42,7 @@ tower = "0.4" tower-abci = "0.12.0" tower-actor = "0.1.0" tower-http = { version = "0.4", features = ["cors"] } +url = "2.5.4" async-trait = { workspace = true } base64 = { workspace = true } diff --git a/crates/astria-sequencer/local.env.example b/crates/astria-sequencer/local.env.example index 7a794e616a..b82ed73816 100644 --- a/crates/astria-sequencer/local.env.example +++ b/crates/astria-sequencer/local.env.example @@ -1,7 +1,9 @@ # Socket address to listen for ABCI requests from cometbft. -# This address corresponds to the `--proxy_app "tcp://"`, -# where `tcp://127.0.0.1:26658` is comebft's default. -ASTRIA_SEQUENCER_LISTEN_ADDR="127.0.0.1:26658" +# This address corresponds to the `--proxy_app ""`, +# where `tcp://127.0.0.1:26658` is comebft's default. Can also be configured to +# use a unix address ie `unix:///socket/astria_abci.sock`. Generally will see +# much higher performance with a unix socket. +ASTRIA_SEQUENCER_ABCI_LISTENER_URL="tcp://127.0.0.1:26658" # Path to rocksdb ASTRIA_SEQUENCER_DB_FILEPATH="/tmp/astria_db" diff --git a/crates/astria-sequencer/src/config.rs b/crates/astria-sequencer/src/config.rs index 00db5f637b..6132ad8e46 100644 --- a/crates/astria-sequencer/src/config.rs +++ b/crates/astria-sequencer/src/config.rs @@ -13,7 +13,7 @@ use serde::{ #[derive(Debug, Deserialize, Serialize)] pub struct Config { /// The endpoint on which Sequencer will listen for ABCI requests - pub listen_addr: String, + pub abci_listener_url: String, /// The path to penumbra storage db. pub db_filepath: PathBuf, /// Log level: debug, info, warn, or error diff --git a/crates/astria-sequencer/src/sequencer.rs b/crates/astria-sequencer/src/sequencer.rs index 92df49d470..230cc2c8e5 100644 --- a/crates/astria-sequencer/src/sequencer.rs +++ b/crates/astria-sequencer/src/sequencer.rs @@ -4,6 +4,7 @@ use astria_eyre::{ eyre::{ eyre, OptionExt as _, + Report, Result, WrapErr as _, }, @@ -33,6 +34,7 @@ use tracing::{ info, info_span, }; +use url::Url; use crate::{ app::App, @@ -95,26 +97,7 @@ impl Sequencer { .await .wrap_err("failed to initialize app")?; - let consensus_service = tower::ServiceBuilder::new() - .layer(request_span::layer(|req: &ConsensusRequest| { - req.create_span() - })) - .service(tower_actor::Actor::new(10, |queue: _| { - let storage = storage.clone(); - async move { service::Consensus::new(storage, app, queue).run().await } - })); let mempool_service = service::Mempool::new(storage.clone(), mempool.clone(), metrics); - let info_service = - service::Info::new(storage.clone()).wrap_err("failed initializing info service")?; - let snapshot_service = service::Snapshot; - - let server = Server::builder() - .consensus(consensus_service) - .info(info_service) - .mempool(mempool_service) - .snapshot(snapshot_service) - .finish() - .ok_or_eyre("server builder didn't return server; are all fields set?")?; let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel(); let (server_exit_tx, server_exit_rx) = tokio::sync::oneshot::channel(); @@ -125,20 +108,15 @@ impl Sequencer { .wrap_err("failed to parse grpc_addr address")?; let grpc_server_handle = start_grpc_server(&storage, mempool, grpc_addr, shutdown_rx); - span.in_scope(|| info!(config.listen_addr, "starting sequencer")); - let server_handle = tokio::spawn(async move { - match server.listen_tcp(&config.listen_addr).await { - Ok(()) => { - // this shouldn't happen, as there isn't a way for the ABCI server to exit - info_span!("abci_server").in_scope(|| info!("ABCI server exited successfully")); - } - Err(e) => { - error_span!("abci_server") - .in_scope(|| error!(err = e.as_ref(), "ABCI server exited with error")); - } - } - let _ = server_exit_tx.send(()); - }); + span.in_scope(|| info!(config.abci_listener_url, "starting abci sequencer")); + let abci_server_handle = start_abci_server( + &storage, + app, + mempool_service, + &config.abci_listener_url, + server_exit_tx, + ) + .wrap_err("failed to start ABCI server")?; select! { _ = signals.stop_rx.changed() => { @@ -157,7 +135,7 @@ impl Sequencer { .await .wrap_err("grpc server task failed")? .wrap_err("grpc server failed")?; - server_handle.abort(); + abci_server_handle.abort(); Ok(()) } } @@ -210,6 +188,83 @@ fn start_grpc_server( ) } +fn start_abci_server( + storage: &cnidarium::Storage, + app: App, + mempool_service: service::Mempool, + listen_url: &str, + server_exit_tx: oneshot::Sender<()>, +) -> Result, Report> { + // Setup services required for the ABCI server + let consensus_service = tower::ServiceBuilder::new() + .layer(request_span::layer(|req: &ConsensusRequest| { + req.create_span() + })) + .service(tower_actor::Actor::new(10, |queue: _| { + let storage = storage.clone(); + async move { service::Consensus::new(storage, app, queue).run().await } + })); + let info_service = + service::Info::new(storage.clone()).wrap_err("failed initializing info service")?; + let snapshot_service = service::Snapshot; + + // Builds the server but does not start listening. + let server = Server::builder() + .consensus(consensus_service) + .info(info_service) + .mempool(mempool_service) + .snapshot(snapshot_service) + .finish() + .ok_or_eyre("server builder didn't return server; are all fields set?")?; + + // Validate and parse the listen_url received from the config. + let abci_url = Url::parse(listen_url).wrap_err("failed to parse listen_addr")?; + let validated_listen_addr = match abci_url.scheme() { + "unix" => match abci_url.to_file_path() { + Ok(_) => Ok(abci_url.path().to_string()), + Err(e) => Err(eyre!( + "failed parsing unix listen_addr file path, error: {:?}", + e + )), + }, + "tcp" => { + let host_str = abci_url + .host_str() + .ok_or_eyre("missing host in tcp listen_addr")?; + let port = abci_url + .port() + .ok_or_eyre("missing port in tcp listen_addr")?; + Ok(format!("{host_str}:{port}")) + } + // If more options are added here will also need to update the server startup + // immediately below to support more than two protocols. + _ => Err(eyre!( + "unsupported protocol in `abci_listener_url`, only unix and tcp are supported" + )), + }?; + + let server_handle = tokio::spawn(async move { + let server_listen_result = if abci_url.scheme() == "unix" { + server.listen_unix(validated_listen_addr).await + } else { + server.listen_tcp(validated_listen_addr).await + }; + match server_listen_result { + Ok(()) => { + // this shouldn't happen, as there isn't a way for the ABCI server to exit + info_span!("abci_server").in_scope(|| info!("ABCI server exited successfully")); + } + Err(e) => { + error_span!("abci_server") + .in_scope(|| error!(err = e.as_ref(), "ABCI server exited with error")); + } + } + let _ = server_exit_tx.send(()); + }); + + Ok(server_handle) +} + struct SignalReceiver { stop_rx: watch::Receiver<()>, } From 9d53b1ce8654c2e390c23f41cf10610e250037a6 Mon Sep 17 00:00:00 2001 From: Richard Janis Goldschmidt Date: Thu, 16 Jan 2025 13:45:07 +0100 Subject: [PATCH 2/8] replace inline parsing enum; parse already in config --- crates/astria-sequencer/src/config.rs | 4 +- crates/astria-sequencer/src/sequencer.rs | 146 ++++++++++++++++++----- 2 files changed, 116 insertions(+), 34 deletions(-) diff --git a/crates/astria-sequencer/src/config.rs b/crates/astria-sequencer/src/config.rs index 6132ad8e46..7b688700f2 100644 --- a/crates/astria-sequencer/src/config.rs +++ b/crates/astria-sequencer/src/config.rs @@ -5,6 +5,8 @@ use serde::{ Serialize, }; +use crate::sequencer::AbciListenUrl; + #[expect( clippy::struct_excessive_bools, reason = "this is used as a container for deserialization. Making this a builder-pattern is \ @@ -13,7 +15,7 @@ use serde::{ #[derive(Debug, Deserialize, Serialize)] pub struct Config { /// The endpoint on which Sequencer will listen for ABCI requests - pub abci_listener_url: String, + pub abci_listener_url: AbciListenUrl, /// The path to penumbra storage db. pub db_filepath: PathBuf, /// Log level: debug, info, warn, or error diff --git a/crates/astria-sequencer/src/sequencer.rs b/crates/astria-sequencer/src/sequencer.rs index 230cc2c8e5..475c49f28e 100644 --- a/crates/astria-sequencer/src/sequencer.rs +++ b/crates/astria-sequencer/src/sequencer.rs @@ -1,3 +1,10 @@ +use std::{ + fmt::Display, + net::SocketAddr, + path::PathBuf, + str::FromStr, +}; + use astria_core::generated::astria::sequencerblock::v1::sequencer_service_server::SequencerServiceServer; use astria_eyre::{ anyhow_to_eyre, @@ -13,6 +20,10 @@ use penumbra_tower_trace::{ trace::request_span, v038::RequestExt as _, }; +use serde::{ + Deserialize, + Serialize, +}; use telemetry::metrics::register_histogram_global; use tendermint::v0_38::abci::ConsensusRequest; use tokio::{ @@ -108,12 +119,12 @@ impl Sequencer { .wrap_err("failed to parse grpc_addr address")?; let grpc_server_handle = start_grpc_server(&storage, mempool, grpc_addr, shutdown_rx); - span.in_scope(|| info!(config.abci_listener_url, "starting abci sequencer")); + span.in_scope(|| info!(%config.abci_listener_url, "starting abci sequencer")); let abci_server_handle = start_abci_server( &storage, app, mempool_service, - &config.abci_listener_url, + config.abci_listener_url, server_exit_tx, ) .wrap_err("failed to start ABCI server")?; @@ -192,7 +203,7 @@ fn start_abci_server( storage: &cnidarium::Storage, app: App, mempool_service: service::Mempool, - listen_url: &str, + listen_url: AbciListenUrl, server_exit_tx: oneshot::Sender<()>, ) -> Result, Report> { // Setup services required for the ABCI server @@ -217,37 +228,10 @@ fn start_abci_server( .finish() .ok_or_eyre("server builder didn't return server; are all fields set?")?; - // Validate and parse the listen_url received from the config. - let abci_url = Url::parse(listen_url).wrap_err("failed to parse listen_addr")?; - let validated_listen_addr = match abci_url.scheme() { - "unix" => match abci_url.to_file_path() { - Ok(_) => Ok(abci_url.path().to_string()), - Err(e) => Err(eyre!( - "failed parsing unix listen_addr file path, error: {:?}", - e - )), - }, - "tcp" => { - let host_str = abci_url - .host_str() - .ok_or_eyre("missing host in tcp listen_addr")?; - let port = abci_url - .port() - .ok_or_eyre("missing port in tcp listen_addr")?; - Ok(format!("{host_str}:{port}")) - } - // If more options are added here will also need to update the server startup - // immediately below to support more than two protocols. - _ => Err(eyre!( - "unsupported protocol in `abci_listener_url`, only unix and tcp are supported" - )), - }?; - let server_handle = tokio::spawn(async move { - let server_listen_result = if abci_url.scheme() == "unix" { - server.listen_unix(validated_listen_addr).await - } else { - server.listen_tcp(validated_listen_addr).await + let server_listen_result = match listen_url { + AbciListenUrl::Tcp(socket_addr) => server.listen_tcp(socket_addr).await, + AbciListenUrl::Uds(path) => server.listen_unix(path).await, }; match server_listen_result { Ok(()) => { @@ -296,3 +280,99 @@ fn spawn_signal_handler() -> SignalReceiver { stop_rx, } } + +#[derive(Debug)] +pub enum AbciListenUrl { + Tcp(SocketAddr), + Uds(PathBuf), +} + +impl Display for AbciListenUrl { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AbciListenUrl::Tcp(socket_addr) => write!(f, "tcp://{socket_addr}"), + AbciListenUrl::Uds(path) => write!(f, "uds://{}", path.display()), + } + } +} + +#[derive(Debug, thiserror::Error)] +pub enum AbciListenUrlParseError { + #[error( + "parsed input as a tcp address `{parsed}`, but could not turn it into a socket address" + )] + TcpButBadSocketAddr { parsed: Url, source: std::io::Error }, + #[error("parsed input as a uds address `{parsed}`, but could not turn it into a path")] + UdsButBadPath { parsed: Url }, + #[error( + "parsed input as `{parsed}`, but scheme `scheme` is not suppported; supported schemes are \ + tcp, uds" + )] + UnsupportedScheme { parsed: Url, scheme: String }, + #[error("failed parsing input as URL")] + Url { + #[from] + source: url::ParseError, + }, +} + +impl FromStr for AbciListenUrl { + type Err = AbciListenUrlParseError; + + fn from_str(s: &str) -> std::result::Result { + let abci_url = Url::parse(s)?; + + match abci_url.scheme() { + "uds" => { + if let Ok(path) = abci_url.to_file_path() { + Ok(Self::Uds(path)) + } else { + Err(Self::Err::UdsButBadPath { + parsed: abci_url, + }) + } + } + "tcp" => match abci_url.socket_addrs(|| None) { + Ok(mut socket_addrs) => { + let socket_addr = socket_addrs.pop().expect( + "the url crate is guaranteed to return vec with exactly one element \ + because it relies on std::net::ToSocketAddrs::to_socket_addr; if this is \ + no longer the case there was a breaking change in the url crate", + ); + Ok(Self::Tcp(socket_addr)) + } + Err(source) => { + return Err(Self::Err::TcpButBadSocketAddr { + parsed: abci_url, + source, + }); + } + }, + // If more options are added here will also need to update the server startup + // immediately below to support more than two protocols. + other => Err(Self::Err::UnsupportedScheme { + parsed: abci_url.clone(), + scheme: other.to_string(), + }), + } + } +} + +impl<'de> Deserialize<'de> for AbciListenUrl { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + let s = std::borrow::Cow::<'_, str>::deserialize(deserializer)?; + FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +impl Serialize for AbciListenUrl { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + serializer.collect_str(self) + } +} From d0074981fce9bb6d9f460d644d18a8bee65a71c5 Mon Sep 17 00:00:00 2001 From: Richard Janis Goldschmidt Date: Thu, 16 Jan 2025 13:45:18 +0100 Subject: [PATCH 3/8] add unit tests for happy path --- crates/astria-sequencer/src/sequencer.rs | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/crates/astria-sequencer/src/sequencer.rs b/crates/astria-sequencer/src/sequencer.rs index 475c49f28e..8a14f52ba6 100644 --- a/crates/astria-sequencer/src/sequencer.rs +++ b/crates/astria-sequencer/src/sequencer.rs @@ -376,3 +376,38 @@ impl Serialize for AbciListenUrl { serializer.collect_str(self) } } + +#[cfg(test)] +mod tests { + use std::path::Path; + + use super::AbciListenUrl; + + #[test] + fn uds_input_is_parsed_as_abci_listen_url() { + let expected = "/path/to/unix.sock"; + match format!("uds://{expected}") + .parse::() + .unwrap() + { + AbciListenUrl::Uds(actual) => { + assert_eq!(AsRef::::as_ref(expected), actual.as_path(),) + } + other => panic!("expected uds, got {other:?}"), + } + } + + #[test] + fn tcp_input_is_parsed_as_abci_listen_url() { + let expected = "127.0.0.1:0"; + match format!("tcp://{expected}") + .parse::() + .unwrap() + { + AbciListenUrl::Tcp(actual) => { + assert_eq!(expected, actual.to_string()); + } + other => panic!("expected tcp, got {other:?}"), + } + } +} From 5fc2db8733feab0fa7059338a7a3c4bce1ce7953 Mon Sep 17 00:00:00 2001 From: Richard Janis Goldschmidt Date: Thu, 16 Jan 2025 13:50:47 +0100 Subject: [PATCH 4/8] add error path test --- crates/astria-sequencer/src/sequencer.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/astria-sequencer/src/sequencer.rs b/crates/astria-sequencer/src/sequencer.rs index 8a14f52ba6..2360ffbbf0 100644 --- a/crates/astria-sequencer/src/sequencer.rs +++ b/crates/astria-sequencer/src/sequencer.rs @@ -410,4 +410,16 @@ mod tests { other => panic!("expected tcp, got {other:?}"), } } + + // NOTE: the only genuine new error variant is AbciListenUrl. Tests for other error paths are + // not provided because they are fundamentally wrappers of url crate errors. + #[test] + fn http_is_not_valid_abci_listen_scheme() { + match "http://astria.org".parse::().unwrap_err() { + super::AbciListenUrlParseError::UnsupportedScheme { + scheme, .. + } => assert_eq!("http", scheme), + other => panic!("expected AbciListenUrlParseError::UnsupportedScheme, got `{other:?}`"), + } + } } From 7f470b92b2ea518b63b1e92ac0c032055bde5a83 Mon Sep 17 00:00:00 2001 From: Richard Janis Goldschmidt Date: Thu, 16 Jan 2025 13:55:48 +0100 Subject: [PATCH 5/8] move abci listen url def to config module --- crates/astria-sequencer/src/config.rs | 147 +++++++++++++++++++- crates/astria-sequencer/src/sequencer.rs | 166 +---------------------- 2 files changed, 150 insertions(+), 163 deletions(-) diff --git a/crates/astria-sequencer/src/config.rs b/crates/astria-sequencer/src/config.rs index 7b688700f2..cb7a3e1dda 100644 --- a/crates/astria-sequencer/src/config.rs +++ b/crates/astria-sequencer/src/config.rs @@ -1,11 +1,14 @@ -use std::path::PathBuf; +use std::{ + net::SocketAddr, + path::PathBuf, + str::FromStr, +}; use serde::{ Deserialize, Serialize, }; - -use crate::sequencer::AbciListenUrl; +use url::Url; #[expect( clippy::struct_excessive_bools, @@ -40,14 +43,152 @@ impl config::Config for Config { const PREFIX: &'static str = "ASTRIA_SEQUENCER_"; } +#[derive(Debug)] +pub enum AbciListenUrl { + Tcp(SocketAddr), + Uds(PathBuf), +} + +impl std::fmt::Display for AbciListenUrl { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AbciListenUrl::Tcp(socket_addr) => write!(f, "tcp://{socket_addr}"), + AbciListenUrl::Uds(path) => write!(f, "uds://{}", path.display()), + } + } +} + +#[derive(Debug, thiserror::Error)] +pub enum AbciListenUrlParseError { + #[error( + "parsed input as a tcp address `{parsed}`, but could not turn it into a socket address" + )] + TcpButBadSocketAddr { parsed: Url, source: std::io::Error }, + #[error("parsed input as a uds address `{parsed}`, but could not turn it into a path")] + UdsButBadPath { parsed: Url }, + #[error( + "parsed input as `{parsed}`, but scheme `scheme` is not suppported; supported schemes are \ + tcp, uds" + )] + UnsupportedScheme { parsed: Url, scheme: String }, + #[error("failed parsing input as URL")] + Url { + #[from] + source: url::ParseError, + }, +} + +impl FromStr for AbciListenUrl { + type Err = AbciListenUrlParseError; + + fn from_str(s: &str) -> std::result::Result { + let abci_url = Url::parse(s)?; + + match abci_url.scheme() { + "uds" => { + if let Ok(path) = abci_url.to_file_path() { + Ok(Self::Uds(path)) + } else { + Err(Self::Err::UdsButBadPath { + parsed: abci_url, + }) + } + } + "tcp" => match abci_url.socket_addrs(|| None) { + Ok(mut socket_addrs) => { + let socket_addr = socket_addrs.pop().expect( + "the url crate is guaranteed to return vec with exactly one element \ + because it relies on std::net::ToSocketAddrs::to_socket_addr; if this is \ + no longer the case there was a breaking change in the url crate", + ); + Ok(Self::Tcp(socket_addr)) + } + Err(source) => { + return Err(Self::Err::TcpButBadSocketAddr { + parsed: abci_url, + source, + }); + } + }, + // If more options are added here will also need to update the server startup + // immediately below to support more than two protocols. + other => Err(Self::Err::UnsupportedScheme { + parsed: abci_url.clone(), + scheme: other.to_string(), + }), + } + } +} + +impl<'de> Deserialize<'de> for AbciListenUrl { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + let s = std::borrow::Cow::<'_, str>::deserialize(deserializer)?; + FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +impl Serialize for AbciListenUrl { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + serializer.collect_str(self) + } +} + #[cfg(test)] mod tests { use super::Config; const EXAMPLE_ENV: &str = include_str!("../local.env.example"); + use super::AbciListenUrl; + #[test] fn example_env_config_is_up_to_date() { config::tests::example_env_config_is_up_to_date::(EXAMPLE_ENV); } + + #[test] + fn uds_input_is_parsed_as_abci_listen_url() { + let expected = "/path/to/unix.sock"; + match format!("uds://{expected}") + .parse::() + .unwrap() + { + AbciListenUrl::Uds(actual) => { + assert_eq!(AsRef::::as_ref(expected), actual.as_path(),) + } + other => panic!("expected uds, got {other:?}"), + } + } + + #[test] + fn tcp_input_is_parsed_as_abci_listen_url() { + let expected = "127.0.0.1:0"; + match format!("tcp://{expected}") + .parse::() + .unwrap() + { + AbciListenUrl::Tcp(actual) => { + assert_eq!(expected, actual.to_string()); + } + other => panic!("expected tcp, got {other:?}"), + } + } + + // NOTE: the only genuine new error variant is AbciListenUrl. Tests for other error paths are + // not provided because they are fundamentally wrappers of url crate errors. + #[test] + fn http_is_not_valid_abci_listen_scheme() { + match "http://astria.org".parse::().unwrap_err() { + super::AbciListenUrlParseError::UnsupportedScheme { + scheme, .. + } => assert_eq!("http", scheme), + other => panic!("expected AbciListenUrlParseError::UnsupportedScheme, got `{other:?}`"), + } + } } diff --git a/crates/astria-sequencer/src/sequencer.rs b/crates/astria-sequencer/src/sequencer.rs index 2360ffbbf0..7265a71131 100644 --- a/crates/astria-sequencer/src/sequencer.rs +++ b/crates/astria-sequencer/src/sequencer.rs @@ -1,17 +1,10 @@ -use std::{ - fmt::Display, - net::SocketAddr, - path::PathBuf, - str::FromStr, -}; - use astria_core::generated::astria::sequencerblock::v1::sequencer_service_server::SequencerServiceServer; use astria_eyre::{ anyhow_to_eyre, eyre::{ + self, eyre, OptionExt as _, - Report, Result, WrapErr as _, }, @@ -20,10 +13,6 @@ use penumbra_tower_trace::{ trace::request_span, v038::RequestExt as _, }; -use serde::{ - Deserialize, - Serialize, -}; use telemetry::metrics::register_histogram_global; use tendermint::v0_38::abci::ConsensusRequest; use tokio::{ @@ -45,11 +34,13 @@ use tracing::{ info, info_span, }; -use url::Url; use crate::{ app::App, - config::Config, + config::{ + AbciListenUrl, + Config, + }, grpc::sequencer::SequencerServer, ibc::host_interface::AstriaHost, mempool::Mempool, @@ -205,8 +196,7 @@ fn start_abci_server( mempool_service: service::Mempool, listen_url: AbciListenUrl, server_exit_tx: oneshot::Sender<()>, -) -> Result, Report> { - // Setup services required for the ABCI server +) -> eyre::Result> { let consensus_service = tower::ServiceBuilder::new() .layer(request_span::layer(|req: &ConsensusRequest| { req.create_span() @@ -219,7 +209,6 @@ fn start_abci_server( service::Info::new(storage.clone()).wrap_err("failed initializing info service")?; let snapshot_service = service::Snapshot; - // Builds the server but does not start listening. let server = Server::builder() .consensus(consensus_service) .info(info_service) @@ -280,146 +269,3 @@ fn spawn_signal_handler() -> SignalReceiver { stop_rx, } } - -#[derive(Debug)] -pub enum AbciListenUrl { - Tcp(SocketAddr), - Uds(PathBuf), -} - -impl Display for AbciListenUrl { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - AbciListenUrl::Tcp(socket_addr) => write!(f, "tcp://{socket_addr}"), - AbciListenUrl::Uds(path) => write!(f, "uds://{}", path.display()), - } - } -} - -#[derive(Debug, thiserror::Error)] -pub enum AbciListenUrlParseError { - #[error( - "parsed input as a tcp address `{parsed}`, but could not turn it into a socket address" - )] - TcpButBadSocketAddr { parsed: Url, source: std::io::Error }, - #[error("parsed input as a uds address `{parsed}`, but could not turn it into a path")] - UdsButBadPath { parsed: Url }, - #[error( - "parsed input as `{parsed}`, but scheme `scheme` is not suppported; supported schemes are \ - tcp, uds" - )] - UnsupportedScheme { parsed: Url, scheme: String }, - #[error("failed parsing input as URL")] - Url { - #[from] - source: url::ParseError, - }, -} - -impl FromStr for AbciListenUrl { - type Err = AbciListenUrlParseError; - - fn from_str(s: &str) -> std::result::Result { - let abci_url = Url::parse(s)?; - - match abci_url.scheme() { - "uds" => { - if let Ok(path) = abci_url.to_file_path() { - Ok(Self::Uds(path)) - } else { - Err(Self::Err::UdsButBadPath { - parsed: abci_url, - }) - } - } - "tcp" => match abci_url.socket_addrs(|| None) { - Ok(mut socket_addrs) => { - let socket_addr = socket_addrs.pop().expect( - "the url crate is guaranteed to return vec with exactly one element \ - because it relies on std::net::ToSocketAddrs::to_socket_addr; if this is \ - no longer the case there was a breaking change in the url crate", - ); - Ok(Self::Tcp(socket_addr)) - } - Err(source) => { - return Err(Self::Err::TcpButBadSocketAddr { - parsed: abci_url, - source, - }); - } - }, - // If more options are added here will also need to update the server startup - // immediately below to support more than two protocols. - other => Err(Self::Err::UnsupportedScheme { - parsed: abci_url.clone(), - scheme: other.to_string(), - }), - } - } -} - -impl<'de> Deserialize<'de> for AbciListenUrl { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - let s = std::borrow::Cow::<'_, str>::deserialize(deserializer)?; - FromStr::from_str(&s).map_err(serde::de::Error::custom) - } -} - -impl Serialize for AbciListenUrl { - fn serialize(&self, serializer: S) -> std::result::Result - where - S: serde::Serializer, - { - serializer.collect_str(self) - } -} - -#[cfg(test)] -mod tests { - use std::path::Path; - - use super::AbciListenUrl; - - #[test] - fn uds_input_is_parsed_as_abci_listen_url() { - let expected = "/path/to/unix.sock"; - match format!("uds://{expected}") - .parse::() - .unwrap() - { - AbciListenUrl::Uds(actual) => { - assert_eq!(AsRef::::as_ref(expected), actual.as_path(),) - } - other => panic!("expected uds, got {other:?}"), - } - } - - #[test] - fn tcp_input_is_parsed_as_abci_listen_url() { - let expected = "127.0.0.1:0"; - match format!("tcp://{expected}") - .parse::() - .unwrap() - { - AbciListenUrl::Tcp(actual) => { - assert_eq!(expected, actual.to_string()); - } - other => panic!("expected tcp, got {other:?}"), - } - } - - // NOTE: the only genuine new error variant is AbciListenUrl. Tests for other error paths are - // not provided because they are fundamentally wrappers of url crate errors. - #[test] - fn http_is_not_valid_abci_listen_scheme() { - match "http://astria.org".parse::().unwrap_err() { - super::AbciListenUrlParseError::UnsupportedScheme { - scheme, .. - } => assert_eq!("http", scheme), - other => panic!("expected AbciListenUrlParseError::UnsupportedScheme, got `{other:?}`"), - } - } -} From ee48c78cc354f42613e13caec9e198d2aec2bde7 Mon Sep 17 00:00:00 2001 From: Richard Janis Goldschmidt Date: Thu, 16 Jan 2025 13:59:30 +0100 Subject: [PATCH 6/8] clippy --- crates/astria-sequencer/src/config.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/crates/astria-sequencer/src/config.rs b/crates/astria-sequencer/src/config.rs index cb7a3e1dda..dcc6933722 100644 --- a/crates/astria-sequencer/src/config.rs +++ b/crates/astria-sequencer/src/config.rs @@ -103,12 +103,10 @@ impl FromStr for AbciListenUrl { ); Ok(Self::Tcp(socket_addr)) } - Err(source) => { - return Err(Self::Err::TcpButBadSocketAddr { - parsed: abci_url, - source, - }); - } + Err(source) => Err(Self::Err::TcpButBadSocketAddr { + parsed: abci_url, + source, + }), }, // If more options are added here will also need to update the server startup // immediately below to support more than two protocols. @@ -155,12 +153,17 @@ mod tests { #[test] fn uds_input_is_parsed_as_abci_listen_url() { let expected = "/path/to/unix.sock"; + #[expect( + clippy::match_wildcard_for_single_variants, + reason = "intended to match all future variants because the test is only valid for a \ + single variant" + )] match format!("uds://{expected}") .parse::() .unwrap() { AbciListenUrl::Uds(actual) => { - assert_eq!(AsRef::::as_ref(expected), actual.as_path(),) + assert_eq!(AsRef::::as_ref(expected), actual.as_path(),); } other => panic!("expected uds, got {other:?}"), } @@ -169,6 +172,11 @@ mod tests { #[test] fn tcp_input_is_parsed_as_abci_listen_url() { let expected = "127.0.0.1:0"; + #[expect( + clippy::match_wildcard_for_single_variants, + reason = "intended to match all future variants because the test is only valid for a \ + single variant" + )] match format!("tcp://{expected}") .parse::() .unwrap() From aa95d0364d6bcafe7c6415f5d520067a79b18581 Mon Sep 17 00:00:00 2001 From: Richard Janis Goldschmidt Date: Thu, 16 Jan 2025 14:05:29 +0100 Subject: [PATCH 7/8] rename abci_listener_url -> abci_listen_url --- charts/sequencer/templates/configmaps.yaml | 2 +- crates/astria-sequencer/CHANGELOG.md | 2 +- crates/astria-sequencer/local.env.example | 4 ++-- crates/astria-sequencer/src/config.rs | 2 +- crates/astria-sequencer/src/sequencer.rs | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/charts/sequencer/templates/configmaps.yaml b/charts/sequencer/templates/configmaps.yaml index ad420b3bfa..1b4b994459 100644 --- a/charts/sequencer/templates/configmaps.yaml +++ b/charts/sequencer/templates/configmaps.yaml @@ -75,6 +75,6 @@ data: {{- if not .Values.global.dev }} ASTRIA_SEQUENCER_LISTEN_ADDR: "127.0.0.1:{{ .Values.ports.sequencerABCI }}" {{- else }} - ASTRIA_SEQUENCER_ABCI_LISTENER_URL: "{{ include "sequencer.abci_url" . }}" + ASTRIA_SEQUENCER_ABCI_LISTEN_URL: "{{ include "sequencer.abci_url" . }}" {{- end }} --- diff --git a/crates/astria-sequencer/CHANGELOG.md b/crates/astria-sequencer/CHANGELOG.md index 64e474d018..df65163a0e 100644 --- a/crates/astria-sequencer/CHANGELOG.md +++ b/crates/astria-sequencer/CHANGELOG.md @@ -22,7 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Add ASTRIA_SEQUENCER_ABCI_LISTENER_URL config variable [#1877](https://github.com/astriaorg/astria/pull/1877) +- Add ASTRIA_SEQUENCER_ABCI_LISTEN_URL config variable [#1877](https://github.com/astriaorg/astria/pull/1877) ## [1.0.0] - 2024-10-25 diff --git a/crates/astria-sequencer/local.env.example b/crates/astria-sequencer/local.env.example index b82ed73816..23223b5303 100644 --- a/crates/astria-sequencer/local.env.example +++ b/crates/astria-sequencer/local.env.example @@ -1,9 +1,9 @@ # Socket address to listen for ABCI requests from cometbft. -# This address corresponds to the `--proxy_app ""`, +# This address corresponds to the `--proxy_app ""`, # where `tcp://127.0.0.1:26658` is comebft's default. Can also be configured to # use a unix address ie `unix:///socket/astria_abci.sock`. Generally will see # much higher performance with a unix socket. -ASTRIA_SEQUENCER_ABCI_LISTENER_URL="tcp://127.0.0.1:26658" +ASTRIA_SEQUENCER_ABCI_LISTEN_URL="tcp://127.0.0.1:26658" # Path to rocksdb ASTRIA_SEQUENCER_DB_FILEPATH="/tmp/astria_db" diff --git a/crates/astria-sequencer/src/config.rs b/crates/astria-sequencer/src/config.rs index dcc6933722..da6857bdfb 100644 --- a/crates/astria-sequencer/src/config.rs +++ b/crates/astria-sequencer/src/config.rs @@ -18,7 +18,7 @@ use url::Url; #[derive(Debug, Deserialize, Serialize)] pub struct Config { /// The endpoint on which Sequencer will listen for ABCI requests - pub abci_listener_url: AbciListenUrl, + pub abci_listen_url: AbciListenUrl, /// The path to penumbra storage db. pub db_filepath: PathBuf, /// Log level: debug, info, warn, or error diff --git a/crates/astria-sequencer/src/sequencer.rs b/crates/astria-sequencer/src/sequencer.rs index 7265a71131..a9171684bf 100644 --- a/crates/astria-sequencer/src/sequencer.rs +++ b/crates/astria-sequencer/src/sequencer.rs @@ -110,12 +110,12 @@ impl Sequencer { .wrap_err("failed to parse grpc_addr address")?; let grpc_server_handle = start_grpc_server(&storage, mempool, grpc_addr, shutdown_rx); - span.in_scope(|| info!(%config.abci_listener_url, "starting abci sequencer")); + span.in_scope(|| info!(%config.abci_listen_url, "starting abci sequencer")); let abci_server_handle = start_abci_server( &storage, app, mempool_service, - config.abci_listener_url, + config.abci_listen_url, server_exit_tx, ) .wrap_err("failed to start ABCI server")?; From d1f07cbb02f29caff873abd03f3d73bf5b4ab6c4 Mon Sep 17 00:00:00 2001 From: Richard Janis Goldschmidt Date: Thu, 16 Jan 2025 18:12:44 +0100 Subject: [PATCH 8/8] change uds to unix everywhere; unix is the scheme name --- crates/astria-sequencer/src/config.rs | 56 ++++++++++++++++-------- crates/astria-sequencer/src/sequencer.rs | 2 +- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/crates/astria-sequencer/src/config.rs b/crates/astria-sequencer/src/config.rs index da6857bdfb..40b4423a18 100644 --- a/crates/astria-sequencer/src/config.rs +++ b/crates/astria-sequencer/src/config.rs @@ -46,14 +46,14 @@ impl config::Config for Config { #[derive(Debug)] pub enum AbciListenUrl { Tcp(SocketAddr), - Uds(PathBuf), + Unix(PathBuf), } impl std::fmt::Display for AbciListenUrl { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { AbciListenUrl::Tcp(socket_addr) => write!(f, "tcp://{socket_addr}"), - AbciListenUrl::Uds(path) => write!(f, "uds://{}", path.display()), + AbciListenUrl::Unix(path) => write!(f, "unix://{}", path.display()), } } } @@ -64,11 +64,13 @@ pub enum AbciListenUrlParseError { "parsed input as a tcp address `{parsed}`, but could not turn it into a socket address" )] TcpButBadSocketAddr { parsed: Url, source: std::io::Error }, - #[error("parsed input as a uds address `{parsed}`, but could not turn it into a path")] - UdsButBadPath { parsed: Url }, + #[error( + "parsed input as a unix domain socket URL `{parsed}`, but could not turn it into a path" + )] + UnixButBadPath { parsed: Url }, #[error( "parsed input as `{parsed}`, but scheme `scheme` is not suppported; supported schemes are \ - tcp, uds" + tcp, unix" )] UnsupportedScheme { parsed: Url, scheme: String }, #[error("failed parsing input as URL")] @@ -85,15 +87,6 @@ impl FromStr for AbciListenUrl { let abci_url = Url::parse(s)?; match abci_url.scheme() { - "uds" => { - if let Ok(path) = abci_url.to_file_path() { - Ok(Self::Uds(path)) - } else { - Err(Self::Err::UdsButBadPath { - parsed: abci_url, - }) - } - } "tcp" => match abci_url.socket_addrs(|| None) { Ok(mut socket_addrs) => { let socket_addr = socket_addrs.pop().expect( @@ -108,6 +101,15 @@ impl FromStr for AbciListenUrl { source, }), }, + "unix" => { + if let Ok(path) = abci_url.to_file_path() { + Ok(Self::Unix(path)) + } else { + Err(Self::Err::UnixButBadPath { + parsed: abci_url, + }) + } + } // If more options are added here will also need to update the server startup // immediately below to support more than two protocols. other => Err(Self::Err::UnsupportedScheme { @@ -151,21 +153,21 @@ mod tests { } #[test] - fn uds_input_is_parsed_as_abci_listen_url() { + fn unix_input_is_parsed_as_abci_listen_url() { let expected = "/path/to/unix.sock"; #[expect( clippy::match_wildcard_for_single_variants, reason = "intended to match all future variants because the test is only valid for a \ single variant" )] - match format!("uds://{expected}") + match format!("unix://{expected}") .parse::() .unwrap() { - AbciListenUrl::Uds(actual) => { + AbciListenUrl::Unix(actual) => { assert_eq!(AsRef::::as_ref(expected), actual.as_path(),); } - other => panic!("expected uds, got {other:?}"), + other => panic!("expected AbciListenUrl::Unix, got {other:?}"), } } @@ -184,10 +186,26 @@ mod tests { AbciListenUrl::Tcp(actual) => { assert_eq!(expected, actual.to_string()); } - other => panic!("expected tcp, got {other:?}"), + other => panic!("expected AbciListenUrl, got {other:?}"), } } + #[test] + fn tcp_listen_addr_format() { + assert_eq!( + "tcp://127.0.0.1:0", + &AbciListenUrl::Tcp(([127, 0, 0, 1], 0).into()).to_string() + ); + } + + #[test] + fn unix_listen_addr_format() { + assert_eq!( + "unix:///path/to/unix.sock", + &AbciListenUrl::Unix("/path/to/unix.sock".into()).to_string(), + ); + } + // NOTE: the only genuine new error variant is AbciListenUrl. Tests for other error paths are // not provided because they are fundamentally wrappers of url crate errors. #[test] diff --git a/crates/astria-sequencer/src/sequencer.rs b/crates/astria-sequencer/src/sequencer.rs index a9171684bf..eec1a10ee1 100644 --- a/crates/astria-sequencer/src/sequencer.rs +++ b/crates/astria-sequencer/src/sequencer.rs @@ -220,7 +220,7 @@ fn start_abci_server( let server_handle = tokio::spawn(async move { let server_listen_result = match listen_url { AbciListenUrl::Tcp(socket_addr) => server.listen_tcp(socket_addr).await, - AbciListenUrl::Uds(path) => server.listen_unix(path).await, + AbciListenUrl::Unix(path) => server.listen_unix(path).await, }; match server_listen_result { Ok(()) => {