9 Commits

Author SHA1 Message Date
Luke Parker
0849d60f28 Run Bitcoin, Monero nodes on Alpine
While prior this didn't work well, presumably due to stack size limitations,
a shell script is included to raise the default stack size limit. This should
be tried again.
2025-12-08 02:30:34 -05:00
Luke Parker
3a792f9ce5 Update documentation on the serai-runtime build.rs 2025-12-08 02:22:29 -05:00
Luke Parker
50959fa0e3 Update the polkadot-sdk used
Removes `parity-wasm` as a dependency, closing
https://github.com/serai-dex/issues/227 and tidying our `deny.toml`.

This removes the `import-memory` flag from the linker as part of
`parity-wasm`'s usage was to map imports into exports
(5a1128b94b/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs (L91-L142)).
2025-12-08 02:22:25 -05:00
Luke Parker
2fb90ebe55 Extend crates we patch to be empty from the Ethereum ecosystem
`ruint` pulls in many versions of many crates. This has it pull in less.
2025-12-06 08:27:34 -05:00
Luke Parker
b24adcbd14 Add panic-on-poison to no-std std_shims::sync::Mutex
We already had this behavior on `std`. It was omitted when no-`std` due to
deferring to `spin::Mutex`, which does not track poisoning at all. This
increases the parity of the two.

Part of https://github.com/serai-dex/serai/issues/698.
2025-12-06 08:06:38 -05:00
Luke Parker
b791256648 Remove substrate-wasm-builder
By defining our own build script, we gain complete clarity and control over how
the WASM is built. This also removes the need to patch the upstream due to it
allowing pollution of the environment variables from the host.

Notable appreciation is given to
https://github.com/rust-lang/rust/issues/145491 for identifying an issue
encountered here, with the associated PR clarifying the necessary flags for the
linker to fix this.
2025-12-04 23:23:38 -05:00
Luke Parker
36ac9c56a4 Remove workaround for lack of musl-dev now that musl-dev is provided in Rust Alpine images
Additionally, optimizes the build process a bit via leaving only the runtime
(and `busybox`) in the final image, and additionally building the runtime
without `std` (as we solely need the WASM blob from this process).
2025-12-04 11:58:38 -05:00
Luke Parker
57bf4984f8 panic = "abort"
`panic = "unwind"` was originally a requirement of Substrate, notably due to
its [native runtime](https://github.com/paritytech/substrate/issues/10874).
This does not mean all of Serai should use this setting however.

As the native runtime has been removed, we do no longer need this for the
Substrate node. With a review of our derivative, a panic guard is only used
when fetching the version from the runtime, causing an error on boot if a
panic occurs. Accordingly, we shouldn't have a need for `panic = "unwind"`
within the node, and the runtime itself should be fine.

The rest of Serai's services already registered bespoke hooks to ensure any
panic caused the process to exit. Those are left as-is, even though they're
now unnecessary.
2025-12-04 11:58:38 -05:00
Luke Parker
87750407de cargo-deny 0.18.8, remove bip39 git dependency
The former is necessary due to `cargo-deny` misinterpreting select licenses.
The latter is finally possible with the recent 2.2.1 release 🎉
2025-12-04 11:58:28 -05:00
32 changed files with 884 additions and 592 deletions

View File

@@ -52,7 +52,7 @@ runs:
- name: Install solc
shell: bash
run: |
cargo +1.91.1 install svm-rs --version =0.5.21
cargo +1.91.1 install svm-rs --version =0.5.22
svm install 0.8.29
svm use 0.8.29

View File

@@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # 6.0.0
- name: Install cargo deny
run: cargo +1.91.1 install cargo-deny --version =0.18.7
run: cargo +1.91.1 install cargo-deny --version =0.18.8
- name: Run cargo deny
run: cargo deny -L error --all-features check --hide-inclusion-graph

View File

@@ -46,7 +46,7 @@ jobs:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # 6.0.0
- name: Install cargo deny
run: cargo +1.91.1 install cargo-deny --version =0.18.7
run: cargo +1.91.1 install cargo-deny --version =0.18.8
- name: Run cargo deny
run: cargo deny -L error --all-features check --hide-inclusion-graph

459
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -116,6 +116,19 @@ members = [
"tests/reproducible-runtime",
]
[profile.dev]
panic = "abort"
overflow-checks = true
[profile.release]
panic = "abort"
overflow-checks = true
# These do not respect the `panic` configuration value, so we don't provide them
[profile.test]
# panic = "abort" # https://github.com/rust-lang/issues/67650
overflow-checks = true
[profile.bench]
overflow-checks = true
[profile.dev.package]
# Always compile Monero (and a variety of dependencies) with optimizations due
# to the extensive operations required for Bulletproofs
@@ -165,17 +178,17 @@ revm-precompile = { opt-level = 3 }
revm-primitives = { opt-level = 3 }
revm-state = { opt-level = 3 }
[profile.release]
panic = "unwind"
overflow-checks = true
[patch.crates-io]
# Point to empty crates for crates unused within in our tree
alloy-eip2124 = { path = "patches/ethereum/alloy-eip2124" }
ark-ff-3 = { package = "ark-ff", path = "patches/ethereum/ark-ff-0.3" }
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" }
fastrlp-3 = { package = "fastrlp", path = "patches/ethereum/fastrlp-0.3" }
fastrlp-4 = { package = "fastrlp", path = "patches/ethereum/fastrlp-0.4" }
primitive-types-12 = { package = "primitive-types", path = "patches/ethereum/primitive-types-0.12" }
rlp = { path = "patches/ethereum/rlp" }
secp256k1-30 = { package = "secp256k1", path = "patches/ethereum/secp256k1-0.30" }
# Dependencies from monero-oxide which originate from within our own tree, potentially shimmed to account for deviations since publishing
std-shims = { path = "patches/std-shims" }

View File

@@ -6,12 +6,63 @@ pub use std::sync::{Arc, Weak};
mod mutex_shim {
#[cfg(not(feature = "std"))]
pub use spin::{Mutex, MutexGuard};
mod spin_mutex {
use core::ops::{Deref, DerefMut};
// We wrap this in an `Option` so we can consider `None` as poisoned
pub(super) struct Mutex<T>(spin::Mutex<Option<T>>);
/// An acquired view of a `Mutex`.
pub struct MutexGuard<'mutex, T> {
mutex: spin::MutexGuard<'mutex, Option<T>>,
// This is `Some` for the lifetime of this guard, and is only represented as an `Option` due
// to needing to move it on `Drop` (which solely gives us a mutable reference to `self`)
value: Option<T>,
}
impl<T> Mutex<T> {
pub(super) const fn new(value: T) -> Self {
Self(spin::Mutex::new(Some(value)))
}
pub(super) fn lock(&self) -> MutexGuard<'_, T> {
let mut mutex = self.0.lock();
// Take from the `Mutex` so future acquisitions will see `None` unless this is restored
let value = mutex.take();
// Check the prior acquisition did in fact restore the value
if value.is_none() {
panic!("locking a `spin::Mutex` held by a thread which panicked");
}
MutexGuard { mutex, value }
}
}
impl<T> Deref for MutexGuard<'_, T> {
type Target = T;
fn deref(&self) -> &T {
self.value.as_ref().expect("no value yet checked upon lock acquisition")
}
}
impl<T> DerefMut for MutexGuard<'_, T> {
fn deref_mut(&mut self) -> &mut T {
self.value.as_mut().expect("no value yet checked upon lock acquisition")
}
}
impl<'mutex, T> Drop for MutexGuard<'mutex, T> {
fn drop(&mut self) {
// Restore the value
*self.mutex = self.value.take();
}
}
}
#[cfg(not(feature = "std"))]
pub use spin_mutex::*;
#[cfg(feature = "std")]
pub use std::sync::{Mutex, MutexGuard};
/// A shimmed `Mutex` with an API mutual to `spin` and `std`.
#[derive(Default, Debug)]
pub struct ShimMutex<T>(Mutex<T>);
impl<T> ShimMutex<T> {
/// Construct a new `Mutex`.
@@ -21,8 +72,9 @@ mod mutex_shim {
/// Acquire a lock on the contents of the `Mutex`.
///
/// On no-`std` environments, this may spin until the lock is acquired. On `std` environments,
/// this may panic if the `Mutex` was poisoned.
/// This will panic if the `Mutex` was poisoned.
///
/// On no-`std` environments, the implementation presumably defers to that of a spin lock.
pub fn lock(&self) -> MutexGuard<'_, T> {
#[cfg(feature = "std")]
let res = self.0.lock().unwrap();

View File

@@ -7,8 +7,7 @@ db-urls = ["https://github.com/rustsec/advisory-db"]
yanked = "deny"
ignore = [
"RUSTSEC-2022-0061", # https://github.com/serai-dex/serai/227
"RUSTSEC-2024-0370", # proc-macro-error is unmaintained
"RUSTSEC-2024-0370", # `proc-macro-error` is unmaintained, in-tree due to Substrate/`litep2p`
"RUSTSEC-2024-0436", # paste is unmaintained
]
@@ -79,7 +78,6 @@ exceptions = [
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator-libp2p-p2p" },
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator" },
{ allow = ["AGPL-3.0-only"], name = "pallet-session" },
{ allow = ["AGPL-3.0-only"], name = "substrate-median" },
{ allow = ["AGPL-3.0-only"], name = "serai-core-pallet" },
@@ -152,6 +150,5 @@ allow-git = [
"https://github.com/rust-lang-nursery/lazy-static.rs",
"https://github.com/kayabaNerve/elliptic-curves",
"https://github.com/monero-oxide/monero-oxide",
"https://github.com/rust-bitcoin/rust-bip39",
"https://github.com/serai-dex/patch-polkadot-sdk",
]

View File

@@ -0,0 +1,166 @@
# Raises `PT_GNU_STACK`'s memory to be at least 8 MB.
#
# This causes `musl` to use a 8 MB default for new threads, resolving the primary
# compatibility issue faced when executing a program on a `musl` system.
#
# See https://wiki.musl-libc.org/functional-differences-from-glibc.html#Thread-stack-size
# for reference. This differs that instead of setting at time of link, it
# patches the binary as an already-linked ELF executable.
#!/bin/bash
set -eo pipefail
ELF="$1"
if [ ! -f "$ELF" ]; then
echo "\`increase_default_stack_size.sh\` [ELF binary]"
echo ""
echo "Sets the \`PT_GNU_STACK\` program header to its existing value or 8 MB,"
echo "whichever is greater."
exit 1
fi
function hex {
hexdump -e '1 1 "%.2x"' -v
}
function read_bytes {
dd status=none bs=1 skip=$1 count=$2 if="$ELF" | hex
}
function write_bytes {
POS=$1
BYTES=$2
while [ ! $BYTES = "" ]; do
printf "\x$(printf $BYTES | head -c2)" | dd status=none conv=notrunc bs=1 seek=$POS of="$ELF"
# Start with the third byte, as in, after the first two bytes
BYTES=$(printf $BYTES | tail -c+3)
POS=$(($POS + 1))
done
}
# Magic
MAGIC=$(read_bytes 0 4)
if [ ! $MAGIC = $(printf "\x7fELF" | hex) ]; then
echo "Not ELF"
exit 2
fi
# 1 if 32-bit, 2 if 64-bit
BITS=$(read_bytes 4 1)
case $BITS in
"01") BITS=32;;
"02") BITS=64;;
*)
echo "Not 32- or 64- bit"
exit 3
;;
esac
# For `value_per_bits a b`, `a` if 32-bit and `b` if 64-bit
function value_per_bits {
RESULT=$(($1))
if [ $BITS = 64 ]; then
RESULT=$(($2))
fi
printf $RESULT
}
# Read an integer by its offset, differing depending on if 32- or 64-bit
function read_integer_by_offset {
OFFSET=$(value_per_bits $1 $2)
printf $(( 0x$(swap_native_endian $(read_bytes $OFFSET $3)) ))
}
# 1 if little-endian, 2 if big-endian
LITTLE_ENDIAN=$(read_bytes 5 1)
case $LITTLE_ENDIAN in
"01") LITTLE_ENDIAN=1;;
"02") LITTLE_ENDIAN=0;;
*)
echo "Not little- or big- endian"
exit 4
;;
esac
# While this script is written in big-endian, we need to work with the file in
# its declared endian. This function swaps from big to native, or vice versa,
# as necessary.
function swap_native_endian {
BYTES="$1"
if [ "$BYTES" = "" ]; then
read BYTES
fi
if [ $LITTLE_ENDIAN -eq 0 ]; then
printf $BYTES
return
fi
while [ ! $BYTES = "" ]; do
printf $(printf $BYTES | tail -c2)
BYTES=$(printf $BYTES | head -c-2)
done
}
ELF_VERSION=$(read_bytes 6 1)
if [ ! $ELF_VERSION = "01" ]; then
echo "Unknown ELF Version ($ELF_VERSION)"
exit 5
fi
ELF_VERSION_2=$(read_bytes $((0x14)) 4)
if [ ! $ELF_VERSION_2 = $(swap_native_endian 00000001) ]; then
echo "Unknown secondary ELF Version ($ELF_VERSION_2)"
exit 6
fi
# Find where the program headers are
PROGRAM_HEADERS_OFFSET=$(read_integer_by_offset 0x1c 0x20 $(value_per_bits 4 8))
PROGRAM_HEADER_SIZE=$(value_per_bits 0x20 0x38)
DECLARED_PROGRAM_HEADER_SIZE=$(read_integer_by_offset 0x2a 0x36 2)
if [ ! $PROGRAM_HEADER_SIZE -eq $DECLARED_PROGRAM_HEADER_SIZE ]; then
echo "Unexpected size of a program header ($DECLARED_PROGRAM_HEADER_SIZE)"
exit 7
fi
function program_header_start {
printf $(($PROGRAM_HEADERS_OFFSET + ($1 * $PROGRAM_HEADER_SIZE)))
}
function read_program_header {
read_bytes $(program_header_start $1) $PROGRAM_HEADER_SIZE
}
# Iterate over each program header
PROGRAM_HEADERS=$(read_integer_by_offset 0x2c 0x38 2)
NEXT_PROGRAM_HEADER=$(( $PROGRAM_HEADERS - 1 ))
FOUND=0
while [ $NEXT_PROGRAM_HEADER -ne -1 ]; do
THIS_PROGRAM_HEADER=$NEXT_PROGRAM_HEADER
NEXT_PROGRAM_HEADER=$(( $NEXT_PROGRAM_HEADER - 1 ))
PROGRAM_HEADER=$(read_program_header $THIS_PROGRAM_HEADER)
HEADER_TYPE=$(printf $PROGRAM_HEADER | head -c8)
# `PT_GNU_STACK`
# https://github.com/torvalds/linux/blob/c2f2b01b74be8b40a2173372bcd770723f87e7b2/include/uapi/linux/elf.h#L41
if [ ! "$(swap_native_endian $HEADER_TYPE)" = "6474e551" ]; then
continue
fi
FOUND=1
MEMSZ_OFFSET=$(( $(program_header_start $THIS_PROGRAM_HEADER) + $(value_per_bits 0x14 0x28) ))
MEMSZ_LEN=$(value_per_bits 4 8)
# `MEMSZ_OFFSET MEMSZ_OFFSET` as we've already derived it depending on the amount of bits
MEMSZ=$(read_integer_by_offset $MEMSZ_OFFSET $MEMSZ_OFFSET $MEMSZ_LEN)
DESIRED_STACK_SIZE=$((8 * 1024 * 1024))
# Only run if the inherent value is _smaller_
if [ $MEMSZ -lt $DESIRED_STACK_SIZE ]; then
# `2 *`, as this is its length in hexadecimal
HEX_MEMSZ=$(printf %."$((2 * $MEMSZ_LEN))"x $DESIRED_STACK_SIZE)
write_bytes $MEMSZ_OFFSET $(swap_native_endian $HEX_MEMSZ)
fi
done
if [ $FOUND -eq 0 ]; then
echo "\`PT_GNU_STACK\` program header not found"
exit 8
fi
echo "All instances of \`PT_GNU_STACK\` patched to be at least 8 MB"
exit 0

View File

@@ -1,28 +1,8 @@
#check=skip=FromPlatformFlagConstDisallowed
# We want to explicitly set the platform to ensure a constant host environment
# rust:1.91.1-alpine as of November 11th, 2025 (GMT)
FROM --platform=linux/amd64 rust@sha256:700c0959b23445f69c82676b72caa97ca4359decd075dca55b13339df27dc4d3
# In order to compile the runtime, including the `proc-macro`s and build scripts, we need the
# required development libraries. These are traditionally provided by `musl-dev` which is not
# inherently included with this image (https://github.com/rust-lang/docker-rust/issues/68). While we
# could install it here, we'd be unable to pin the installed package by its hash as desired.
#
# Rust does have self-contained libraries, intended to be used when the desired development files
# are not otherwise available. These can be enabled with `link-self-contained=yes`. Unfortunately,
# this doesn't work here (https://github.com/rust-lang/rust/issues/149371).
#
# While we can't set `link-self-contained=yes`, we can install Rust's self-contained libraries onto
# our system so they're generally available.
RUN echo '#!/bin/sh' > libs.sh
RUN echo 'set -e' >> libs.sh
RUN echo 'SYSROOT=$(rustc --print sysroot)' >> libs.sh
RUN echo 'LIBS=$SYSROOT/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained' >> libs.sh
RUN echo 'ln -s $LIBS/Scrt1.o $LIBS/crti.o $LIBS/crtn.o /usr/lib' >> libs.sh
# We also need `libc.so` which is already present on the system, just not under that name
RUN echo 'ln -s /lib/libc.musl-x86_64.so.1 /usr/lib/libc.so' >> libs.sh
RUN /bin/sh ./libs.sh
# rust:1.91.1-alpine as of December 4th, 2025 (GMT)
FROM --platform=linux/amd64 rust@sha256:84f263251b0ada72c1913d82a824d47be15a607f3faf015d8bdae48db544cdf2 AS builder
# Add the WASM toolchain
RUN rustup target add wasm32v1-none
@@ -47,11 +27,16 @@ ADD AGPL-3.0 /serai
WORKDIR /serai
# Build the runtime
RUN cargo build --release -p serai-runtime
# Copy the artifact
RUN cp /serai/target/release/wbuild/serai-runtime/serai_runtime.wasm /serai/serai.wasm
# Clean up the build directory
RUN cargo clean
RUN cargo build --release -p serai-runtime --no-default-features
# Copy the runtime to the provided volume
CMD ["cp", "/serai/serai.wasm", "/volume/serai.wasm"]
# Copy the artifact to its own image which solely exists to further export it
FROM scratch
# Copy `busybox`, including the necessary shared libraries, from the builder for a functioning `cp`
COPY --from=builder /lib/ld-musl-x86_64.so.1 /lib/libc.musl-x86_64.so.1 /lib/
COPY --from=builder /bin/busybox /bin/
ENV LD_LIBRARY_PATH=/lib/
ENV PATH=/bin
# Copy the artifact itself
COPY --from=builder /serai/target/release/serai_runtime.wasm /serai.wasm
# By default, copy the artifact to `/volume`, presumably a provided volume
CMD ["busybox", "cp", "/serai.wasm", "/volume/serai.wasm"]

View File

@@ -29,7 +29,7 @@ RUN tar xzvf bitcoin-${BITCOIN_VERSION}-$(uname -m)-linux-gnu.tar.gz
RUN mv bitcoin-${BITCOIN_VERSION}/bin/bitcoind .
"#;
let setup = mimalloc(Os::Debian) + DOWNLOAD_BITCOIN;
let setup = mimalloc(Os::Alpine) + DOWNLOAD_BITCOIN;
let run_bitcoin = format!(
r#"
@@ -43,7 +43,7 @@ CMD ["/run.sh"]
network.label()
);
let run = os(Os::Debian, "", "bitcoin") + &run_bitcoin;
let run = os(Os::Alpine, "", "bitcoin") + &run_bitcoin;
let res = setup + &run;
let mut bitcoin_path = orchestration_path.to_path_buf();

View File

@@ -21,7 +21,7 @@ fn monero_internal(
};
#[rustfmt::skip]
let download_monero = format!(r#"
let mut download_monero = format!(r#"
FROM alpine:latest AS monero
RUN apk --no-cache add wget gnupg
@@ -41,6 +41,16 @@ RUN tar -xvjf monero-linux-{arch}-v{MONERO_VERSION}.tar.bz2 --strip-components=1
network.label(),
);
if os == Os::Alpine {
// Increase the default stack size, as Monero does heavily use its stack
download_monero += &format!(
r#"
ADD orchestration/increase_default_stack_size.sh .
RUN ./increase_default_stack_size.sh {monero_binary}
"#
);
}
let setup = mimalloc(os) + &download_monero;
let run_monero = format!(
@@ -69,13 +79,13 @@ CMD ["/run.sh"]
}
pub fn monero(orchestration_path: &Path, network: Network) {
monero_internal(network, Os::Debian, orchestration_path, "monero", "monerod", "18080 18081")
monero_internal(network, Os::Alpine, orchestration_path, "monero", "monerod", "18080 18081")
}
pub fn monero_wallet_rpc(orchestration_path: &Path) {
monero_internal(
Network::Dev,
Os::Debian,
Os::Alpine,
orchestration_path,
"monero-wallet-rpc",
"monero-wallet-rpc",

View File

@@ -0,0 +1,19 @@
[package]
name = "fastrlp"
version = "0.3.99"
description = "Patch to an empty crate"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/fastrlp-0.3"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
keywords = []
edition = "2021"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[workspace]
[features]
alloc = []
std = []

View File

@@ -0,0 +1,19 @@
[package]
name = "fastrlp"
version = "0.4.99"
description = "Patch to an empty crate"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/fastrlp-0.4"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
keywords = []
edition = "2021"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[workspace]
[features]
alloc = []
std = []

View File

@@ -0,0 +1 @@
const _NEVER_COMPILED: [(); 0 - 1] = [(); 0 - 1];

View File

@@ -0,0 +1,18 @@
[package]
name = "primitive-types"
version = "0.12.99"
description = "Patch to an empty crate"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/primitive-types"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
keywords = []
edition = "2021"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[workspace]
[features]
std = []

View File

@@ -0,0 +1 @@
const _NEVER_COMPILED: [(); 0 - 1] = [(); 0 - 1];

View File

@@ -0,0 +1,18 @@
[package]
name = "rlp"
version = "0.5.99"
description = "Patch to an empty crate"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/rlp"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
keywords = []
edition = "2021"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[workspace]
[features]
std = []

View File

@@ -0,0 +1 @@
const _NEVER_COMPILED: [(); 0 - 1] = [(); 0 - 1];

View File

@@ -3,7 +3,7 @@ name = "secp256k1"
version = "0.30.99"
description = "Patch to an empty crate"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/secp256k1-30"
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/secp256k1-0.30"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
keywords = []
edition = "2021"

View File

@@ -0,0 +1 @@
const _NEVER_COMPILED: [(); 0 - 1] = [(); 0 - 1];

View File

@@ -15,7 +15,7 @@ rustdoc-args = ["--cfg", "docsrs"]
[workspace]
[dependencies]
bip39 = { git = "https://github.com/rust-bitcoin/rust-bip39", commit = "f735e2559f30049f6738d1bf68c69a0b7bd7b858", default-features = false }
bip39 = { version = "2.2.1", default-features = false }
[features]
default = ["bip39/default"]

View File

@@ -1,3 +1,3 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![no_std]
pub use bip39::*;

View File

@@ -74,7 +74,7 @@ fn wasm_binary(dev: bool) -> Vec<u8> {
}
log::info!("using built-in wasm");
serai_runtime::WASM_BINARY.ok_or("compiled in wasm not available").unwrap().to_vec()
serai_runtime::WASM.to_vec()
}
fn devnet_genesis(validators: &[&'static str], endowed_accounts: Vec<Public>) -> GenesisConfig {

View File

@@ -6,7 +6,7 @@ use sp_timestamp::InherentDataProvider as TimestampInherent;
use sp_consensus_babe::{SlotDuration, inherents::InherentDataProvider as BabeInherent};
use sp_io::SubstrateHostFunctions;
use sc_executor::{sp_wasm_interface::ExtendedHostFunctions, WasmExecutor};
use sc_executor::{sp_wasm_interface::ExtendedHostFunctions, HeapAllocStrategy, WasmExecutor};
use sc_network::{Event, NetworkEventStream, NetworkBackend};
use sc_service::{error::Error as ServiceError, Configuration, TaskManager, TFullClient};
@@ -99,14 +99,13 @@ pub fn new_partial(
})
.transpose()?;
#[allow(deprecated)]
let executor = Executor::new(
config.executor.wasm_method,
config.executor.default_heap_pages,
config.executor.max_runtime_instances,
None,
config.executor.runtime_cache_size,
);
let executor = Executor::builder()
.with_execution_method(config.executor.wasm_method)
.with_onchain_heap_alloc_strategy(HeapAllocStrategy::Dynamic { maximum_pages: None })
.with_offchain_heap_alloc_strategy(HeapAllocStrategy::Dynamic { maximum_pages: None })
.with_max_runtime_instances(config.executor.max_runtime_instances)
.with_runtime_cache_size(config.executor.runtime_cache_size)
.build();
let (client, backend, keystore_container, task_manager) = {
let telemetry = telemetry.as_ref().map(|(_, telemetry)| telemetry.handle());

View File

@@ -17,11 +17,31 @@ ignored = ["scale"]
[lints]
workspace = true
[dependencies]
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
[target.'cfg(not(target_family = "wasm"))'.dependencies]
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"], optional = true }
sp-version = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false, optional = true }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false, optional = true }
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false, optional = true }
sp-transaction-pool = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false, optional = true }
sp-inherents = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false, optional = true }
sp-block-builder = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false, optional = true }
sp-consensus-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false, optional = true }
sp-consensus-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false, optional = true }
sp-authority-discovery = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false, optional = true }
serai-abi = { path = "../abi", default-features = false, features = ["substrate"], optional = true }
[target.'cfg(target_family = "wasm")'.dependencies]
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
borsh = { version = "1", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
sp-version = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
sp-session = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
sp-timestamp = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
sp-api = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
sp-transaction-pool = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
@@ -31,15 +51,6 @@ sp-consensus-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", d
sp-consensus-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
sp-authority-discovery = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
serai-abi = { path = "../abi", default-features = false, features = ["substrate"] }
[target.'cfg(target_family = "wasm")'.dependencies]
borsh = { version = "1", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
sp-session = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
sp-timestamp = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
frame-executive = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
@@ -49,6 +60,8 @@ pallet-session = { git = "https://github.com/serai-dex/patch-polkadot-sdk", defa
pallet-babe = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
pallet-grandpa = { git = "https://github.com/serai-dex/patch-polkadot-sdk", default-features = false }
serai-abi = { path = "../abi", default-features = false, features = ["substrate"] }
serai-core-pallet = { path = "../core", default-features = false }
serai-coins-pallet = { path = "../coins", default-features = false }
serai-validator-sets-pallet = { path = "../validator-sets", default-features = false }
@@ -57,9 +70,6 @@ serai-dex-pallet = { path = "../dex", default-features = false }
serai-genesis-liquidity-pallet = { path = "../genesis-liquidity", default-features = false }
serai-in-instructions-pallet = { path = "../in-instructions", default-features = false }
[build-dependencies]
substrate-wasm-builder = { git = "https://github.com/serai-dex/patch-polkadot-sdk" }
[features]
std = [
"scale/std",
@@ -72,6 +82,7 @@ std = [
"sp-runtime/std",
"sp-api/std",
"sp-transaction-pool/std",
"sp-inherents/std",
"sp-block-builder/std",
"sp-consensus-babe/std",
"sp-consensus-grandpa/std",

View File

@@ -1,4 +1,101 @@
fn main() {
#[cfg(feature = "std")]
substrate_wasm_builder::WasmBuilder::build_using_defaults();
use std::{path::PathBuf, fs, env, process::Command};
// Prevent recursing infinitely
if env::var("TARGET").unwrap() == "wasm32v1-none" {
return;
}
// https://github.com/rust-lang/rust/issues/145491
const ONE_45491: &str = "-C link-arg=--mllvm=-mcpu=mvp,--mllvm=-mattr=+mutable-globals";
const WASM: &str = "-C link-arg=--export-table";
const REQUIRED_BY_SUBSTRATE: &str = "--cfg substrate_runtime";
const SAFETY: &str = "-C overflow-checks=true -C panic=abort";
// `symbol-mangling-version` is defined to provide an explicit, canonical definition of symbols.
// `embed-bitcode=false` is set as the bitcode is unnecessary yet takes notable time to compile.
/*
Rust's LTO requires bitcode, forcing us to defer to the linker's LTO. While this would suggest
we _should_ set `embed-bitcode=true`, Rust's documentation suggests that's likely not desired
and should solely be done when compiling one library with mixed methods of linking. When
compiling and linking just once (as seen here), it's suggested to use the linker's LTO instead.
https://doc.rust-lang.org/1.91.1/rustc/codegen-options/index.html#embed-bitcode
*/
const COMPILATION: &str =
"-C symbol-mangling-version=v0 -C embed-bitcode=false -C linker-plugin-lto=true";
let profile = env::var("PROFILE").unwrap();
let release = profile == "release";
let rustflags = format!("{ONE_45491} {WASM} {REQUIRED_BY_SUBSTRATE} {SAFETY} {COMPILATION}");
let rustflags = if release {
format!("{rustflags} -C codegen-units=1 -C strip=symbols -C debug-assertions=false")
} else {
rustflags
};
let target_dir = PathBuf::from(env::var("OUT_DIR").unwrap()).join("target");
let cargo_command = || {
let cargo = env::var("CARGO").unwrap();
let mut command = Command::new(&cargo);
command
.current_dir(env::var("CARGO_MANIFEST_DIR").unwrap())
.env_clear()
.env("PATH", env::var("PATH").unwrap())
.env("CARGO", cargo)
.env("RUSTC", env::var("RUSTC").unwrap())
.env("RUSTFLAGS", &rustflags)
.env("CARGO_TARGET_DIR", &target_dir);
command
};
let workspace = {
let workspace = cargo_command()
.arg("locate-project")
.arg("--workspace")
.arg("--message-format")
.arg("plain")
.output()
.unwrap();
assert!(workspace.status.success());
let mut workspace = PathBuf::from(String::from_utf8(workspace.stdout).unwrap().trim());
assert_eq!(workspace.file_name().unwrap(), "Cargo.toml");
assert!(workspace.pop());
workspace
};
// Re-run anytime the workspace changes
// TODO: Re-run anytime `Cargo.lock` or specifically the `src` folders change
println!("cargo::rerun-if-changed={}", workspace.display());
let mut command = cargo_command();
command
.arg("rustc")
.arg("--package")
.arg(env::var("CARGO_PKG_NAME").unwrap())
.arg("--target")
.arg("wasm32v1-none")
.arg("--crate-type")
.arg("cdylib")
.arg("--no-default-features");
if release {
command.arg("--release");
}
assert!(command.status().unwrap().success());
// Place the resulting WASM blob into the parent `target` directory
{
let wasm_file = env::var("CARGO_PKG_NAME").unwrap().replace('-', "_") + ".wasm";
let src_file = target_dir.join("wasm32v1-none").join(&profile).join(&wasm_file);
let dst_file = {
// TODO: This sets `dst_dir` to the default target directory, not the actual
let mut dst_dir = workspace.clone();
// e.g. workspace/target/debug
dst_dir.extend(["target", &profile]);
let _ = fs::create_dir_all(&dst_dir);
// e.g. workspace/target/debug/serai_runtime.wasm
dst_dir.join(&wasm_file)
};
fs::copy(&src_file, &dst_file).unwrap();
}
}

View File

@@ -0,0 +1,39 @@
use alloc::vec::Vec;
use serai_abi::{
primitives::{
crypto::{Public, EmbeddedEllipticCurveKeys, SignedEmbeddedEllipticCurveKeys, KeyPair},
network_id::{ExternalNetworkId, NetworkId},
validator_sets::{Session, ExternalValidatorSet, ValidatorSet},
balance::{Amount, Balance},
address::SeraiAddress,
},
Event,
};
/// The genesis configuration for Serai.
#[derive(scale::Encode, scale::Decode)]
pub struct GenesisConfig {
/// The genesis validators for the network.
pub validators: Vec<(Public, Vec<SignedEmbeddedEllipticCurveKeys>)>,
/// The accounts to start with balances, intended solely for testing purposes.
pub coins: Vec<(Public, Balance)>,
}
sp_api::decl_runtime_apis! {
pub trait GenesisApi {
fn build(genesis: GenesisConfig);
}
pub trait SeraiApi {
fn events() -> Vec<Vec<Vec<u8>>>;
fn validators(network: NetworkId) -> Vec<Public>;
fn current_session(network: NetworkId) -> Option<Session>;
fn current_stake(network: NetworkId) -> Option<Amount>;
fn keys(set: ExternalValidatorSet) -> Option<KeyPair>;
fn current_validators(network: NetworkId) -> Option<Vec<SeraiAddress>>;
fn pending_slash_report(network: ExternalNetworkId) -> bool;
fn embedded_elliptic_curve_keys(
validator: SeraiAddress,
network: ExternalNetworkId,
) -> Option<EmbeddedEllipticCurveKeys>;
}
}

View File

@@ -1,222 +1,28 @@
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(any(feature = "std", target_family = "wasm"))]
extern crate alloc;
use alloc::vec::Vec;
use serai_abi::{
primitives::{
crypto::{Public, EmbeddedEllipticCurveKeys, SignedEmbeddedEllipticCurveKeys, KeyPair},
network_id::{ExternalNetworkId, NetworkId},
validator_sets::{Session, ExternalValidatorSet, ValidatorSet},
balance::{Amount, Balance},
address::SeraiAddress,
},
Event,
};
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
#[cfg(any(feature = "std", target_family = "wasm"))]
mod common;
#[cfg(any(feature = "std", target_family = "wasm"))]
pub use common::*;
// If this is WASM, we build the runtime proper
#[cfg(target_family = "wasm")]
mod wasm;
/// The genesis configuration for Serai.
#[derive(scale::Encode, scale::Decode)]
pub struct GenesisConfig {
/// The genesis validators for the network.
pub validators: Vec<(Public, Vec<SignedEmbeddedEllipticCurveKeys>)>,
/// The accounts to start with balances, intended solely for testing purposes.
pub coins: Vec<(Public, Balance)>,
}
// If this is `std`, we solely stub with `impl_runtime_apis` for the `RuntimeApi` the node requires
#[cfg(feature = "std")]
mod std_runtime_api;
#[cfg(feature = "std")]
pub use std_runtime_api::RuntimeApi;
sp_api::decl_runtime_apis! {
pub trait GenesisApi {
fn build(genesis: GenesisConfig);
}
pub trait SeraiApi {
fn events() -> Vec<Vec<Vec<u8>>>;
fn validators(network: NetworkId) -> Vec<Public>;
fn current_session(network: NetworkId) -> Option<Session>;
fn current_stake(network: NetworkId) -> Option<Amount>;
fn keys(set: ExternalValidatorSet) -> Option<KeyPair>;
fn current_validators(network: NetworkId) -> Option<Vec<SeraiAddress>>;
fn pending_slash_report(network: ExternalNetworkId) -> bool;
fn embedded_elliptic_curve_keys(
validator: SeraiAddress,
network: ExternalNetworkId,
) -> Option<EmbeddedEllipticCurveKeys>;
}
}
// We stub `impl_runtime_apis` to generate the `RuntimeApi` object the node needs
#[cfg(not(target_family = "wasm"))]
mod apis {
use alloc::borrow::Cow;
use serai_abi::{SubstrateHeader as Header, SubstrateBlock as Block};
use super::*;
#[sp_version::runtime_version]
pub const VERSION: sp_version::RuntimeVersion = sp_version::RuntimeVersion {
spec_name: Cow::Borrowed("serai"),
impl_name: Cow::Borrowed("core"),
authoring_version: 0,
// Use the highest possible value so the node doesn't attempt to use this in place of the WASM
spec_version: 0xffffffff,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 0,
system_version: 0,
};
/// A `struct` representing the runtime as necessary to define the available APIs.
pub struct Runtime;
sp_api::impl_runtime_apis! {
impl sp_api::Core<Block> for Runtime {
fn version() -> sp_version::RuntimeVersion {
VERSION
}
fn initialize_block(header: &Header) -> sp_runtime::ExtrinsicInclusionMode {
unimplemented!("runtime is only implemented when WASM")
}
fn execute_block(block: Block) {
unimplemented!("runtime is only implemented when WASM")
}
}
impl sp_block_builder::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(
extrinsic: <Block as sp_runtime::traits::Block>::Extrinsic,
) -> sp_runtime::ApplyExtrinsicResult {
unimplemented!("runtime is only implemented when WASM")
}
fn finalize_block() -> Header {
unimplemented!("runtime is only implemented when WASM")
}
fn inherent_extrinsics(
data: sp_inherents::InherentData,
) -> Vec<<Block as sp_runtime::traits::Block>::Extrinsic> {
unimplemented!("runtime is only implemented when WASM")
}
fn check_inherents(
block: Block,
data: sp_inherents::InherentData,
) -> sp_inherents::CheckInherentsResult {
unimplemented!("runtime is only implemented when WASM")
}
}
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(
source: sp_runtime::transaction_validity::TransactionSource,
tx: <Block as sp_runtime::traits::Block>::Extrinsic,
block_hash: <Block as sp_runtime::traits::Block>::Hash,
) -> sp_runtime::transaction_validity::TransactionValidity {
unimplemented!("runtime is only implemented when WASM")
}
}
impl sp_consensus_babe::BabeApi<Block> for Runtime {
fn configuration() -> sp_consensus_babe::BabeConfiguration {
unimplemented!("runtime is only implemented when WASM")
}
fn current_epoch_start() -> sp_consensus_babe::Slot {
unimplemented!("runtime is only implemented when WASM")
}
fn current_epoch() -> sp_consensus_babe::Epoch {
unimplemented!("runtime is only implemented when WASM")
}
fn next_epoch() -> sp_consensus_babe::Epoch {
unimplemented!("runtime is only implemented when WASM")
}
fn generate_key_ownership_proof(
_slot: sp_consensus_babe::Slot,
_authority_id: sp_consensus_babe::AuthorityId,
) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
unimplemented!("runtime is only implemented when WASM")
}
fn submit_report_equivocation_unsigned_extrinsic(
equivocation_proof: sp_consensus_babe::EquivocationProof<Header>,
_: sp_consensus_babe::OpaqueKeyOwnershipProof,
) -> Option<()> {
unimplemented!("runtime is only implemented when WASM")
}
}
impl sp_consensus_grandpa::GrandpaApi<Block> for Runtime {
fn grandpa_authorities() -> sp_consensus_grandpa::AuthorityList {
unimplemented!("runtime is only implemented when WASM")
}
fn current_set_id() -> sp_consensus_grandpa::SetId {
unimplemented!("runtime is only implemented when WASM")
}
fn generate_key_ownership_proof(
_set_id: sp_consensus_grandpa::SetId,
_authority_id: sp_consensus_grandpa::AuthorityId,
) -> Option<sp_consensus_grandpa::OpaqueKeyOwnershipProof> {
unimplemented!("runtime is only implemented when WASM")
}
fn submit_report_equivocation_unsigned_extrinsic(
equivocation_proof: sp_consensus_grandpa::EquivocationProof<
<Block as sp_runtime::traits::Block>::Hash,
u64,
>,
_: sp_consensus_grandpa::OpaqueKeyOwnershipProof,
) -> Option<()> {
unimplemented!("runtime is only implemented when WASM")
}
}
impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
fn authorities() -> Vec<sp_authority_discovery::AuthorityId> {
unimplemented!("runtime is only implemented when WASM")
}
}
impl crate::SeraiApi<Block> for Runtime {
fn events() -> Vec<Vec<Vec<u8>>> {
unimplemented!("runtime is only implemented when WASM")
}
fn validators(
network: NetworkId
) -> Vec<serai_abi::primitives::crypto::Public> {
unimplemented!("runtime is only implemented when WASM")
}
fn current_session(network: NetworkId) -> Option<Session> {
unimplemented!("runtime is only implemented when WASM")
}
fn current_stake(network: NetworkId) -> Option<Amount> {
unimplemented!("runtime is only implemented when WASM")
}
fn keys(set: ExternalValidatorSet) -> Option<KeyPair> {
unimplemented!("runtime is only implemented when WASM")
}
fn current_validators(network: NetworkId) -> Option<Vec<SeraiAddress>> {
unimplemented!("runtime is only implemented when WASM")
}
fn pending_slash_report(network: ExternalNetworkId) -> bool {
unimplemented!("runtime is only implemented when WASM")
}
fn embedded_elliptic_curve_keys(
validator: SeraiAddress,
network: ExternalNetworkId,
) -> Option<EmbeddedEllipticCurveKeys> {
unimplemented!("runtime is only implemented when WASM")
}
}
}
}
#[cfg(not(target_family = "wasm"))]
pub use apis::RuntimeApi;
// If this isn't WASM, regardless of what it is, we include the WASM blob from the build script
#[cfg(all(not(target_family = "wasm"), debug_assertions))]
pub const WASM: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/target/wasm32v1-none/debug/serai_runtime.wasm"));
#[cfg(all(not(target_family = "wasm"), not(debug_assertions)))]
pub const WASM: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/target/wasm32v1-none/release/serai_runtime.wasm"));

View File

@@ -0,0 +1,174 @@
use alloc::borrow::Cow;
use serai_abi::{
primitives::{
crypto::{KeyPair, EmbeddedEllipticCurveKeys},
network_id::{ExternalNetworkId, NetworkId},
validator_sets::{Session, ExternalValidatorSet},
balance::Amount,
address::SeraiAddress,
},
SubstrateHeader as Header, SubstrateBlock as Block,
};
use super::*;
#[sp_version::runtime_version]
pub const VERSION: sp_version::RuntimeVersion = sp_version::RuntimeVersion {
spec_name: Cow::Borrowed("serai"),
impl_name: Cow::Borrowed("core"),
authoring_version: 0,
// Use the highest possible value so the node doesn't attempt to use this in place of the WASM
spec_version: 0xffffffff,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 0,
system_version: 0,
};
/// A `struct` representing the runtime as necessary to define the available APIs.
pub struct Runtime;
sp_api::impl_runtime_apis! {
impl sp_api::Core<Block> for Runtime {
fn version() -> sp_version::RuntimeVersion {
VERSION
}
fn initialize_block(header: &Header) -> sp_runtime::ExtrinsicInclusionMode {
unimplemented!("runtime is only implemented when WASM")
}
fn execute_block(block: Block) {
unimplemented!("runtime is only implemented when WASM")
}
}
impl sp_block_builder::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(
extrinsic: <Block as sp_runtime::traits::Block>::Extrinsic,
) -> sp_runtime::ApplyExtrinsicResult {
unimplemented!("runtime is only implemented when WASM")
}
fn finalize_block() -> Header {
unimplemented!("runtime is only implemented when WASM")
}
fn inherent_extrinsics(
data: sp_inherents::InherentData,
) -> Vec<<Block as sp_runtime::traits::Block>::Extrinsic> {
unimplemented!("runtime is only implemented when WASM")
}
fn check_inherents(
block: Block,
data: sp_inherents::InherentData,
) -> sp_inherents::CheckInherentsResult {
unimplemented!("runtime is only implemented when WASM")
}
}
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(
source: sp_runtime::transaction_validity::TransactionSource,
tx: <Block as sp_runtime::traits::Block>::Extrinsic,
block_hash: <Block as sp_runtime::traits::Block>::Hash,
) -> sp_runtime::transaction_validity::TransactionValidity {
unimplemented!("runtime is only implemented when WASM")
}
}
impl sp_consensus_babe::BabeApi<Block> for Runtime {
fn configuration() -> sp_consensus_babe::BabeConfiguration {
unimplemented!("runtime is only implemented when WASM")
}
fn current_epoch_start() -> sp_consensus_babe::Slot {
unimplemented!("runtime is only implemented when WASM")
}
fn current_epoch() -> sp_consensus_babe::Epoch {
unimplemented!("runtime is only implemented when WASM")
}
fn next_epoch() -> sp_consensus_babe::Epoch {
unimplemented!("runtime is only implemented when WASM")
}
fn generate_key_ownership_proof(
_slot: sp_consensus_babe::Slot,
_authority_id: sp_consensus_babe::AuthorityId,
) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
unimplemented!("runtime is only implemented when WASM")
}
fn submit_report_equivocation_unsigned_extrinsic(
equivocation_proof: sp_consensus_babe::EquivocationProof<Header>,
_: sp_consensus_babe::OpaqueKeyOwnershipProof,
) -> Option<()> {
unimplemented!("runtime is only implemented when WASM")
}
}
impl sp_consensus_grandpa::GrandpaApi<Block> for Runtime {
fn grandpa_authorities() -> sp_consensus_grandpa::AuthorityList {
unimplemented!("runtime is only implemented when WASM")
}
fn current_set_id() -> sp_consensus_grandpa::SetId {
unimplemented!("runtime is only implemented when WASM")
}
fn generate_key_ownership_proof(
_set_id: sp_consensus_grandpa::SetId,
_authority_id: sp_consensus_grandpa::AuthorityId,
) -> Option<sp_consensus_grandpa::OpaqueKeyOwnershipProof> {
unimplemented!("runtime is only implemented when WASM")
}
fn submit_report_equivocation_unsigned_extrinsic(
equivocation_proof: sp_consensus_grandpa::EquivocationProof<
<Block as sp_runtime::traits::Block>::Hash,
u64,
>,
_: sp_consensus_grandpa::OpaqueKeyOwnershipProof,
) -> Option<()> {
unimplemented!("runtime is only implemented when WASM")
}
}
impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
fn authorities() -> Vec<sp_authority_discovery::AuthorityId> {
unimplemented!("runtime is only implemented when WASM")
}
}
impl crate::SeraiApi<Block> for Runtime {
fn events() -> Vec<Vec<Vec<u8>>> {
unimplemented!("runtime is only implemented when WASM")
}
fn validators(
network: NetworkId
) -> Vec<serai_abi::primitives::crypto::Public> {
unimplemented!("runtime is only implemented when WASM")
}
fn current_session(network: NetworkId) -> Option<Session> {
unimplemented!("runtime is only implemented when WASM")
}
fn current_stake(network: NetworkId) -> Option<Amount> {
unimplemented!("runtime is only implemented when WASM")
}
fn keys(set: ExternalValidatorSet) -> Option<KeyPair> {
unimplemented!("runtime is only implemented when WASM")
}
fn current_validators(network: NetworkId) -> Option<Vec<SeraiAddress>> {
unimplemented!("runtime is only implemented when WASM")
}
fn pending_slash_report(network: ExternalNetworkId) -> bool {
unimplemented!("runtime is only implemented when WASM")
}
fn embedded_elliptic_curve_keys(
validator: SeraiAddress,
network: ExternalNetworkId,
) -> Option<EmbeddedEllipticCurveKeys> {
unimplemented!("runtime is only implemented when WASM")
}
}
}

View File

@@ -73,11 +73,10 @@ impl frame_system::Config for Runtime {
// We assume `serai-node` will be run using the RocksDB backend
type DbWeight = frame_support::weights::constants::RocksDbWeight;
/*
Serai does not expose `frame_system::Call` nor does it use transaction extensions. We
accordingly have no consequence to using the default weights for these accordingly.
Serai does not expose `frame_system::Call`. We accordingly have no consequence to using the
default weights for these accordingly.
*/
type SystemWeightInfo = ();
type ExtensionsWeightInfo = ();
// We also don't use `frame_system`'s account system at all, leaving us to bottom these out.
type AccountData = ();

View File

@@ -54,8 +54,9 @@ pub fn reproducibly_builds() {
.arg("--quiet")
.arg("--rm")
.arg(&image)
.arg("busybox")
.arg("sha256sum")
.arg("/serai/serai.wasm")
.arg("/serai.wasm")
.output(),
);
// Attempt to clean up the image