Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sequencer, charts)!: support uds for abci #1877

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion charts/sequencer/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion charts/sequencer/files/cometbft/config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}"
Expand Down
2 changes: 0 additions & 2 deletions charts/sequencer/files/scripts/init-cometbft.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,3 @@ if [ ! -d "/cometbft/config" ]; then
else
cp /config/* /cometbft/config/
fi

chmod -R 0777 /cometbft
18 changes: 16 additions & 2 deletions charts/sequencer/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
5 changes: 3 additions & 2 deletions charts/sequencer/templates/configmaps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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_LISTEN_URL: "{{ include "sequencer.abci_url" . }}"
{{- end }}
---
9 changes: 9 additions & 0 deletions charts/sequencer/templates/statefulsets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
5 changes: 3 additions & 2 deletions charts/sequencer/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ images:
repo: ghcr.io/astriaorg/sequencer
pullPolicy: IfNotPresent
tag: 1.0.0
devTag: latest
devTag: local

moniker: ""
genesis:
Expand Down Expand Up @@ -105,6 +105,7 @@ genesis:
# pubKey: lV57+rGs2vac7mvkGHP1oBFGHPJM3a+WoAzeFDCJDNU=

sequencer:
abciUDS: true
mempool:
parked:
maxTxCount: 200
Expand Down Expand Up @@ -311,7 +312,7 @@ storage:
local: true
entities:
sequencerSharedStorage:
size: "5Gi"
size: "50Gi"
persistentVolumeName: "sequencer-shared-storage"
path: "/data/sequencer-data"

Expand Down
8 changes: 8 additions & 0 deletions crates/astria-sequencer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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_LISTEN_URL config variable [#1877](https://github.com/astriaorg/astria/pull/1877)

## [1.0.0] - 2024-10-25

### Changed
Expand Down
1 change: 1 addition & 0 deletions crates/astria-sequencer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
8 changes: 5 additions & 3 deletions crates/astria-sequencer/local.env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Socket address to listen for ABCI requests from cometbft.
# This address corresponds to the `--proxy_app "tcp://<ASTRIA_SEQUENCER_LISTEN_ADDR>"`,
# 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 "<ASTRIA_SEQUENCER_ABCI_LISTEN_URL>"`,
# 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_LISTEN_URL="tcp://127.0.0.1:26658"

# Path to rocksdb
ASTRIA_SEQUENCER_DB_FILEPATH="/tmp/astria_db"
Expand Down
173 changes: 171 additions & 2 deletions crates/astria-sequencer/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
use std::path::PathBuf;
use std::{
net::SocketAddr,
path::PathBuf,
str::FromStr,
};

use serde::{
Deserialize,
Serialize,
};
use url::Url;

#[expect(
clippy::struct_excessive_bools,
Expand All @@ -13,7 +18,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_listen_url: AbciListenUrl,
/// The path to penumbra storage db.
pub db_filepath: PathBuf,
/// Log level: debug, info, warn, or error
Expand All @@ -38,14 +43,178 @@ impl config::Config for Config {
const PREFIX: &'static str = "ASTRIA_SEQUENCER_";
}

#[derive(Debug)]
pub enum AbciListenUrl {
Tcp(SocketAddr),
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::Unix(path) => write!(f, "unix://{}", 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 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, unix"
)]
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<Self, Self::Err> {
let abci_url = Url::parse(s)?;

match abci_url.scheme() {
"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) => Err(Self::Err::TcpButBadSocketAddr {
parsed: abci_url,
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 {
parsed: abci_url.clone(),
scheme: other.to_string(),
}),
}
}
}

impl<'de> Deserialize<'de> for AbciListenUrl {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
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<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
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::<Config>(EXAMPLE_ENV);
}

#[test]
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!("unix://{expected}")
.parse::<AbciListenUrl>()
.unwrap()
{
AbciListenUrl::Unix(actual) => {
assert_eq!(AsRef::<std::path::Path>::as_ref(expected), actual.as_path(),);
}
other => panic!("expected AbciListenUrl::Unix, got {other:?}"),
}
}

#[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::<AbciListenUrl>()
.unwrap()
{
AbciListenUrl::Tcp(actual) => {
assert_eq!(expected, actual.to_string());
}
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]
fn http_is_not_valid_abci_listen_scheme() {
match "http://astria.org".parse::<AbciListenUrl>().unwrap_err() {
super::AbciListenUrlParseError::UnsupportedScheme {
scheme, ..
} => assert_eq!("http", scheme),
other => panic!("expected AbciListenUrlParseError::UnsupportedScheme, got `{other:?}`"),
}
}
}
Loading
Loading