From 36ac9c56a4c6fb1a2b678932a8a4eda240222841 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Wed, 3 Dec 2025 20:02:03 -0500 Subject: [PATCH] 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). --- orchestration/runtime/Dockerfile | 43 ++--- substrate/runtime/Cargo.toml | 36 ++-- substrate/runtime/build.rs | 2 +- substrate/runtime/src/common.rs | 39 ++++ substrate/runtime/src/lib.rs | 224 ++--------------------- substrate/runtime/src/std_runtime_api.rs | 174 ++++++++++++++++++ tests/reproducible-runtime/src/lib.rs | 3 +- 7 files changed, 268 insertions(+), 253 deletions(-) create mode 100644 substrate/runtime/src/common.rs create mode 100644 substrate/runtime/src/std_runtime_api.rs diff --git a/orchestration/runtime/Dockerfile b/orchestration/runtime/Dockerfile index cf3e4e95..084b55ba 100644 --- a/orchestration/runtime/Dockerfile +++ b/orchestration/runtime/Dockerfile @@ -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/wbuild/serai-runtime/serai_runtime.wasm /serai.wasm +# By default, copy the artifact to `/volume`, presumably a provided volume +CMD ["busybox", "cp", "/serai.wasm", "/volume/serai.wasm"] diff --git a/substrate/runtime/Cargo.toml b/substrate/runtime/Cargo.toml index 454e85cb..d404f3c4 100644 --- a/substrate/runtime/Cargo.toml +++ b/substrate/runtime/Cargo.toml @@ -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 } @@ -72,6 +85,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", diff --git a/substrate/runtime/build.rs b/substrate/runtime/build.rs index 9aafd17d..71bee10e 100644 --- a/substrate/runtime/build.rs +++ b/substrate/runtime/build.rs @@ -1,4 +1,4 @@ fn main() { - #[cfg(feature = "std")] + #[cfg(not(target_family = "wasm"))] substrate_wasm_builder::WasmBuilder::build_using_defaults(); } diff --git a/substrate/runtime/src/common.rs b/substrate/runtime/src/common.rs new file mode 100644 index 00000000..fc453c1d --- /dev/null +++ b/substrate/runtime/src/common.rs @@ -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)>, + /// 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>>; + fn validators(network: NetworkId) -> Vec; + fn current_session(network: NetworkId) -> Option; + fn current_stake(network: NetworkId) -> Option; + fn keys(set: ExternalValidatorSet) -> Option; + fn current_validators(network: NetworkId) -> Option>; + fn pending_slash_report(network: ExternalNetworkId) -> bool; + fn embedded_elliptic_curve_keys( + validator: SeraiAddress, + network: ExternalNetworkId, + ) -> Option; + } +} diff --git a/substrate/runtime/src/lib.rs b/substrate/runtime/src/lib.rs index 35bc10cb..37aa3e4c 100644 --- a/substrate/runtime/src/lib.rs +++ b/substrate/runtime/src/lib.rs @@ -1,222 +1,24 @@ #![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)>, - /// 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>>; - fn validators(network: NetworkId) -> Vec; - fn current_session(network: NetworkId) -> Option; - fn current_stake(network: NetworkId) -> Option; - fn keys(set: ExternalValidatorSet) -> Option; - fn current_validators(network: NetworkId) -> Option>; - fn pending_slash_report(network: ExternalNetworkId) -> bool; - fn embedded_elliptic_curve_keys( - validator: SeraiAddress, - network: ExternalNetworkId, - ) -> Option; - } -} - -// We stub `impl_runtime_apis` to generate the `RuntimeApi` object the node needs +// If this isn't WASM, regardless of what it is, we include the WASM blob from the build script #[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 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 for Runtime { - fn apply_extrinsic( - extrinsic: ::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<::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 for Runtime { - fn validate_transaction( - source: sp_runtime::transaction_validity::TransactionSource, - tx: ::Extrinsic, - block_hash: ::Hash, - ) -> sp_runtime::transaction_validity::TransactionValidity { - unimplemented!("runtime is only implemented when WASM") - } - } - - impl sp_consensus_babe::BabeApi 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 { - unimplemented!("runtime is only implemented when WASM") - } - - fn submit_report_equivocation_unsigned_extrinsic( - equivocation_proof: sp_consensus_babe::EquivocationProof
, - _: sp_consensus_babe::OpaqueKeyOwnershipProof, - ) -> Option<()> { - unimplemented!("runtime is only implemented when WASM") - } - } - - impl sp_consensus_grandpa::GrandpaApi 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 { - unimplemented!("runtime is only implemented when WASM") - } - - fn submit_report_equivocation_unsigned_extrinsic( - equivocation_proof: sp_consensus_grandpa::EquivocationProof< - ::Hash, - u64, - >, - _: sp_consensus_grandpa::OpaqueKeyOwnershipProof, - ) -> Option<()> { - unimplemented!("runtime is only implemented when WASM") - } - } - - impl sp_authority_discovery::AuthorityDiscoveryApi for Runtime { - fn authorities() -> Vec { - unimplemented!("runtime is only implemented when WASM") - } - } - - impl crate::SeraiApi for Runtime { - fn events() -> Vec>> { - unimplemented!("runtime is only implemented when WASM") - } - fn validators( - network: NetworkId - ) -> Vec { - unimplemented!("runtime is only implemented when WASM") - } - fn current_session(network: NetworkId) -> Option { - unimplemented!("runtime is only implemented when WASM") - } - fn current_stake(network: NetworkId) -> Option { - unimplemented!("runtime is only implemented when WASM") - } - fn keys(set: ExternalValidatorSet) -> Option { - unimplemented!("runtime is only implemented when WASM") - } - fn current_validators(network: NetworkId) -> Option> { - 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 { - unimplemented!("runtime is only implemented when WASM") - } - } - } -} -#[cfg(not(target_family = "wasm"))] -pub use apis::RuntimeApi; +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); diff --git a/substrate/runtime/src/std_runtime_api.rs b/substrate/runtime/src/std_runtime_api.rs new file mode 100644 index 00000000..045f990d --- /dev/null +++ b/substrate/runtime/src/std_runtime_api.rs @@ -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 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 for Runtime { + fn apply_extrinsic( + extrinsic: ::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<::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 for Runtime { + fn validate_transaction( + source: sp_runtime::transaction_validity::TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> sp_runtime::transaction_validity::TransactionValidity { + unimplemented!("runtime is only implemented when WASM") + } + } + + impl sp_consensus_babe::BabeApi 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 { + unimplemented!("runtime is only implemented when WASM") + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: sp_consensus_babe::EquivocationProof
, + _: sp_consensus_babe::OpaqueKeyOwnershipProof, + ) -> Option<()> { + unimplemented!("runtime is only implemented when WASM") + } + } + + impl sp_consensus_grandpa::GrandpaApi 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 { + unimplemented!("runtime is only implemented when WASM") + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: sp_consensus_grandpa::EquivocationProof< + ::Hash, + u64, + >, + _: sp_consensus_grandpa::OpaqueKeyOwnershipProof, + ) -> Option<()> { + unimplemented!("runtime is only implemented when WASM") + } + } + + impl sp_authority_discovery::AuthorityDiscoveryApi for Runtime { + fn authorities() -> Vec { + unimplemented!("runtime is only implemented when WASM") + } + } + + impl crate::SeraiApi for Runtime { + fn events() -> Vec>> { + unimplemented!("runtime is only implemented when WASM") + } + fn validators( + network: NetworkId + ) -> Vec { + unimplemented!("runtime is only implemented when WASM") + } + fn current_session(network: NetworkId) -> Option { + unimplemented!("runtime is only implemented when WASM") + } + fn current_stake(network: NetworkId) -> Option { + unimplemented!("runtime is only implemented when WASM") + } + fn keys(set: ExternalValidatorSet) -> Option { + unimplemented!("runtime is only implemented when WASM") + } + fn current_validators(network: NetworkId) -> Option> { + 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 { + unimplemented!("runtime is only implemented when WASM") + } + } +} diff --git a/tests/reproducible-runtime/src/lib.rs b/tests/reproducible-runtime/src/lib.rs index 25e693a0..682aa6c6 100644 --- a/tests/reproducible-runtime/src/lib.rs +++ b/tests/reproducible-runtime/src/lib.rs @@ -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