6 Commits

Author SHA1 Message Date
Luke Parker
c52f7634de Patch librocksdb-sys to never enable jemalloc, which conflicts with mimalloc
Allows us to update mimalloc and enable the newly added guard pages.

Conflict identified by @PlasmaPower.
2025-11-11 23:04:05 -05:00
Luke Parker
21eaa5793d Error when not running the dev network if an explicit WASM runtime isn't provided 2025-11-11 23:02:20 -05:00
Luke Parker
c744a80d80 Check the finalized function doesn't claim unfinalized blocks are in fact finalized 2025-11-11 23:02:20 -05:00
Luke Parker
a34f9f6164 Build and run the message queue over Alpine
We prior stopped doing so for stability reasons, but this _should_ be tried
again.
2025-11-11 23:02:20 -05:00
Luke Parker
353683cfd2 revm 33 2025-11-11 23:02:16 -05:00
Luke Parker
d4f77159c4 Rust 1.91.1 due to the regression re: wasm builds 2025-11-11 09:08:30 -05:00
16 changed files with 150 additions and 44 deletions

View File

@@ -1 +1 @@
nightly-2025-11-01
nightly-2025-11-11

View File

@@ -171,10 +171,6 @@ ark-ff-4 = { package = "ark-ff", path = "patches/ethereum/ark-ff-0.4" }
c-kzg = { path = "patches/ethereum/c-kzg" }
secp256k1-30 = { package = "secp256k1", path = "patches/ethereum/secp256k1-30" }
# Updates to the latest version
darling = { path = "patches/darling" }
thiserror = { path = "patches/thiserror" }
# Dependencies from monero-oxide which originate from within our own tree
std-shims = { path = "patches/std-shims" }
simple-request = { path = "patches/simple-request" }
@@ -185,12 +181,18 @@ dalek-ff-group = { path = "crypto/dalek-ff-group" }
minimal-ed448 = { path = "crypto/ed448" }
modular-frost = { path = "crypto/frost" }
# Patch due to `std` now including the required functionality
is_terminal_polyfill = { path = "./patches/is_terminal_polyfill" }
# This has a non-deprecated `std` alternative since Rust's 2024 edition
home = { path = "patches/home" }
# Updates to the latest version
darling = { path = "patches/darling" }
thiserror = { path = "patches/thiserror" }
# https://github.com/rust-lang-nursery/lazy-static.rs/issues/201
lazy_static = { git = "https://github.com/rust-lang-nursery/lazy-static.rs", rev = "5735630d46572f1e5377c8f2ba0f79d18f53b10c" }
# These has an `std` alternative since Rust's 2024 edition
home = { path = "patches/home" }
# directories-next was created because directories was unmaintained
# directories-next is now unmaintained while directories is maintained
# The directories author pulls in ridiculously pointless crates and prefers
@@ -203,8 +205,8 @@ directories-next = { path = "patches/directories-next" }
k256 = { git = "https://github.com/kayabaNerve/elliptic-curves", rev = "4994c9ab163781a88cd4a49beae812a89a44e8c3" }
p256 = { git = "https://github.com/kayabaNerve/elliptic-curves", rev = "4994c9ab163781a88cd4a49beae812a89a44e8c3" }
# Patch due to `std` now including the required functionality
is_terminal_polyfill = { path = "./patches/is_terminal_polyfill" }
# `jemalloc` conflicts with `mimalloc`, so patch to a `rocksdb` which never uses `jemalloc`
librocksdb-sys = { path = "patches/librocksdb-sys" }
[workspace.lints.clippy]
incompatible_msrv = "allow" # Manually verified with a GitHub workflow

View File

@@ -1,10 +1,10 @@
# rust:1.91.0-slim-trixie as of November 8th, 2025 (GMT)
FROM --platform=linux/amd64 rust@sha256:e415522de69c288c462eaed441655a283cece8f5dd20df74600277fe9a27e7ed AS deterministic
# rust:1.91.1-slim-trixie as of November 11th, 2025 (GMT)
FROM --platform=linux/amd64 rust@sha256:ccdbe08a0b10498bc5f3cac3d736af7b8eb6cb0ecfc1e8a504e93d8ee76a8e8e AS deterministic
# Move to a Debian package snapshot
RUN rm -rf /etc/apt/sources.list.d/debian.sources && \
rm -rf /var/lib/apt/lists/* && \
echo "deb [arch=amd64] http://snapshot.debian.org/archive/debian/20251108T000000Z trixie main" > /etc/apt/sources.list && \
echo "deb [arch=amd64] http://snapshot.debian.org/archive/debian/20251111T000000Z trixie main" > /etc/apt/sources.list && \
apt update
# Install dependencies

View File

@@ -19,6 +19,7 @@ pub fn coordinator(
let setup = mimalloc(Os::Debian).to_string() +
&build_serai_service(
"",
Os::Debian,
network.release(),
&format!("{db} {longer_reattempts}"),
"serai-coordinator",

View File

@@ -4,7 +4,13 @@ use crate::{Network, Os, mimalloc, os, build_serai_service, write_dockerfile};
pub fn ethereum_relayer(orchestration_path: &Path, network: Network) {
let setup = mimalloc(Os::Debian).to_string() +
&build_serai_service("", network.release(), network.db(), "serai-ethereum-relayer");
&build_serai_service(
"",
Os::Debian,
network.release(),
network.db(),
"serai-ethereum-relayer",
);
let env_vars = [
("DB_PATH", "/volume/ethereum-relayer-db".to_string()),

View File

@@ -143,12 +143,19 @@ WORKDIR /home/{user}
}
}
fn build_serai_service(prelude: &str, release: bool, features: &str, package: &str) -> String {
fn build_serai_service(
prelude: &str,
os: Os,
release: bool,
features: &str,
package: &str,
) -> String {
let profile = if release { "release" } else { "debug" };
let profile_flag = if release { "--release" } else { "" };
format!(
r#"
(match os {
Os::Debian => {
r#"
FROM rust:1.91-slim-trixie AS builder
COPY --from=mimalloc-debian libmimalloc.so /usr/lib
@@ -161,7 +168,25 @@ RUN apt install -y pkg-config libclang-dev clang
# Dependencies for the Serai node
RUN apt install -y make protobuf-compiler
"#
}
Os::Alpine => {
r#"
FROM rust:1.91-alpine AS builder
COPY --from=mimalloc-alpine libmimalloc.so /usr/lib
ENV LD_PRELOAD=libmimalloc.so
RUN apk update && apk upgrade
# Add dev dependencies
RUN apk add clang-dev
"#
}
})
.to_owned() +
&format!(
r#"
# Add the wasm toolchain
RUN rustup component add rust-src
RUN rustup target add wasm32v1-none
@@ -196,7 +221,7 @@ RUN --mount=type=cache,target=/root/.cargo \
cargo build {profile_flag} --features "{features}" -p {package} && \
mv /serai/target/{profile}/{package} /serai/bin
"#
)
)
}
pub fn write_dockerfile(path: PathBuf, dockerfile: &str) {

View File

@@ -13,8 +13,8 @@ pub fn message_queue(
ethereum_key: <Ristretto as WrappedGroup>::G,
monero_key: <Ristretto as WrappedGroup>::G,
) {
let setup = mimalloc(Os::Debian).to_string() +
&build_serai_service("", network.release(), network.db(), "serai-message-queue");
let setup = mimalloc(Os::Alpine).to_string() +
&build_serai_service("", Os::Alpine, network.release(), network.db(), "serai-message-queue");
let env_vars = [
("COORDINATOR_KEY", hex::encode(coordinator_key.to_bytes())),
@@ -41,7 +41,7 @@ CMD {env_vars_str} serai-message-queue
"#
);
let run = os(Os::Debian, "", "messagequeue") + &run_message_queue;
let run = os(Os::Alpine, "", "messagequeue") + &run_message_queue;
let res = setup + &run;
let mut message_queue_path = orchestration_path.to_path_buf();

View File

@@ -7,10 +7,10 @@ FROM alpine:latest AS mimalloc-alpine
RUN apk update && apk upgrade && apk --no-cache add gcc g++ libc-dev make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
git checkout fbd8b99c2b828428947d70fdc046bb55609be93e && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
cmake -DMI_SECURE=ON -DMI_GUARDED=on ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
"#;
@@ -21,10 +21,10 @@ FROM debian:trixie-slim AS mimalloc-debian
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
RUN git clone https://github.com/microsoft/mimalloc && \
cd mimalloc && \
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
git checkout fbd8b99c2b828428947d70fdc046bb55609be93e && \
mkdir -p out/secure && \
cd out/secure && \
cmake -DMI_SECURE=ON ../.. && \
cmake -DMI_SECURE=ON -DMI_GUARDED=on ../.. && \
make && \
cp ./libmimalloc-secure.so ../../../libmimalloc.so
"#;

View File

@@ -28,6 +28,7 @@ RUN svm use 0.8.29
} else {
""
},
Os::Debian,
network.release(),
&format!("binaries {} {coin}", network.db()),
"serai-processor",

View File

@@ -12,7 +12,8 @@ pub fn serai(
serai_key: &Zeroizing<<Ristretto as WrappedGroup>::F>,
) {
// Always builds in release for performance reasons
let setup = mimalloc(Os::Debian).to_string() + &build_serai_service("", true, "", "serai-node");
let setup =
mimalloc(Os::Debian).to_string() + &build_serai_service("", Os::Debian, true, "", "serai-node");
let env_vars = [("KEY", hex::encode(serai_key.to_repr()))];
let mut env_vars_str = String::new();

View File

@@ -0,0 +1,35 @@
[package]
name = "librocksdb-sys"
version = "0.17.99"
description = "Replacement for `librocksdb-sys` which removes the `jemalloc` feature"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/patches/librocksdb-sys"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
keywords = []
edition = "2018"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[workspace]
[dependencies]
# librocksdb-sys 0.17.3+10.4.2, with the commit provided by crates.io in `cargo_vcs_info.json`
librocksdb-sys = { git = "https://github.com/rust-rocksdb/rust-rocksdb", commit = "bb7d2168eab1bc7849f23adbcb825e3aba1bd2f4", default-features = false }
[features]
default = ["librocksdb-sys/default"]
jemalloc = []
static = ["librocksdb-sys/static"]
bindgen-runtime = ["librocksdb-sys/bindgen-runtime"]
bindgen-static = ["librocksdb-sys/bindgen-static"]
mt_static = ["librocksdb-sys/mt_static"]
io-uring = ["librocksdb-sys/io-uring"]
snappy = ["librocksdb-sys/snappy"]
lz4 = ["librocksdb-sys/lz4"]
zstd = ["librocksdb-sys/zstd"]
zlib = ["librocksdb-sys/zlib"]
bzip2 = ["librocksdb-sys/bzip2"]
rtti = ["librocksdb-sys/rtti"]
lto = ["librocksdb-sys/lto"]

View File

@@ -0,0 +1 @@
pub use librocksdb_sys::*;

View File

@@ -33,7 +33,7 @@ alloy-rpc-types-eth = { version = "1", default-features = false }
alloy-transport = { version = "1", default-features = false }
alloy-provider = { version = "1", default-features = false }
revm = { version = "31", default-features = false }
revm = { version = "33", default-features = false }
ethereum-schnorr = { package = "ethereum-schnorr-contract", path = "../../../networks/ethereum/schnorr", default-features = false }

View File

@@ -1,5 +1,5 @@
[toolchain]
channel = "1.91"
channel = "1.91.1"
targets = ["wasm32v1-none"]
profile = "minimal"
components = ["rust-src", "rustfmt", "clippy"]

View File

@@ -22,7 +22,8 @@ async fn blockchain() {
.run_async(async |ops| {
let serai = serai_substrate_tests::rpc(&ops, handle).await;
let test_block = |number| {
// Check the sanity of fetching a block
let test_finalized_block = |number| {
let serai = &serai;
async move {
let block = serai.block_by_number(number).await.unwrap();
@@ -31,24 +32,52 @@ async fn blockchain() {
}
};
test_block(0).await;
test_finalized_block(0).await;
let finalized = serai.latest_finalized_block_number().await.unwrap();
test_block(finalized).await;
test_finalized_block(finalized).await;
let mut next_finalized;
{
let mut i = 0;
while {
next_finalized = serai.latest_finalized_block_number().await.unwrap();
next_finalized == finalized
} {
// Check unfinalized blocks are marked as unfinalized
'outer: {
for _ in 0 .. 10 {
tokio::time::sleep(core::time::Duration::from_secs(6)).await;
i += 1;
assert!(i < 50, "serai didn't finalize a block within five minutes");
let latest_finalized = serai.latest_finalized_block_number().await.unwrap();
// Fetch the unfinalized block after, if it exists
let Ok(block) = serai.block_by_number(latest_finalized + 1).await else {
continue;
};
// Check if it's considered finalized
let considered_finalized = serai.finalized(block.header.hash()).await.unwrap();
// Ensure the finalized block is the same, meaning this block didn't become finalized as
// we made these RPC requests
if latest_finalized != serai.latest_finalized_block_number().await.unwrap() {
continue;
}
// Check the block wasn't considered finalized
assert!(!considered_finalized);
break 'outer;
}
panic!("couldn't find an unfinalized block to check wasn't considered finalized");
};
// Check the finalized block advances
{
let mut next_finalized;
{
let mut i = 0;
while {
next_finalized = serai.latest_finalized_block_number().await.unwrap();
next_finalized == finalized
} {
tokio::time::sleep(core::time::Duration::from_secs(6)).await;
i += 1;
assert!(i < 50, "serai didn't finalize a block within five minutes");
}
}
assert!(next_finalized > finalized);
test_finalized_block(next_finalized).await;
}
assert!(next_finalized > finalized);
test_block(next_finalized).await;
println!("Finished `serai-client/blockchain` test");
})

View File

@@ -52,7 +52,7 @@ fn insecure_embedded_elliptic_curve_keys(
]
}
fn wasm_binary() -> Vec<u8> {
fn wasm_binary(dev: bool) -> Vec<u8> {
// TODO: Accept a config of runtime path
const DEFAULT_WASM_PATH: &str = "/runtime/serai.wasm";
let path = serai_env::var("SERAI_WASM").unwrap_or(DEFAULT_WASM_PATH.to_string());
@@ -60,6 +60,11 @@ fn wasm_binary() -> Vec<u8> {
log::info!("using {path} for the WASM");
return binary;
}
if !dev {
panic!("runtime WASM was not provided");
}
log::info!("using built-in wasm");
WASM_BINARY.ok_or("compiled in wasm not available").unwrap().to_vec()
}
@@ -167,7 +172,7 @@ fn genesis(
};
use sc_service::ChainSpec as _;
let bin = wasm_binary();
let bin = wasm_binary(matches!(chain_type, ChainType::Development));
let hash = sp_core::blake2_256(&bin).to_vec();
let mut chain_spec = sc_chain_spec::ChainSpecBuilder::new(&bin, None)