mirror of
https://github.com/serai-dex/serai.git
synced 2024-12-22 11:39:35 +00:00
Use the deterministically built wasm
Has the Dockerfile output to a volume. Has the node use the wasm from the volume, if it exists.
This commit is contained in:
parent
84cee06ac1
commit
fab7a0a7cb
6 changed files with 117 additions and 18 deletions
|
@ -1,17 +1,20 @@
|
|||
FROM --platform=linux/amd64 rust:1.77.0-slim-bookworm as builder
|
||||
# rust:1.77.0-slim-bookworm as of March 22nd, 2024 (GMT)
|
||||
FROM --platform=linux/amd64 rust@sha256:e785e4aa81f87bc1ee02fa2026ffbc491e0410bdaf6652cea74884373f452664 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/20240201T000000Z bookworm main" > /etc/apt/sources.list && \
|
||||
echo "deb [arch=amd64] http://snapshot.debian.org/archive/debian/20240301T000000Z bookworm main" > /etc/apt/sources.list && \
|
||||
apt update
|
||||
|
||||
# Install dependencies
|
||||
RUN apt install clang -y
|
||||
RUN apt update && apt upgrade && apt install clang -y
|
||||
|
||||
# Add the wasm toolchain
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
|
||||
FROM deterministic
|
||||
|
||||
# Add files for build
|
||||
ADD patches /serai/patches
|
||||
ADD common /serai/common
|
||||
|
@ -30,3 +33,8 @@ ADD Cargo.lock /serai
|
|||
ADD AGPL-3.0 /serai
|
||||
|
||||
WORKDIR /serai
|
||||
|
||||
# Build the runtime, copying it to the volume if it exists
|
||||
CMD cargo build --release -p serai-runtime && \
|
||||
mkdir -p /volume && \
|
||||
cp /serai/target/release/wbuild/serai-runtime/serai_runtime.wasm /volume/serai.wasm
|
||||
|
|
|
@ -325,6 +325,87 @@ fn start(network: Network, services: HashSet<String>) {
|
|||
_ => panic!("starting unrecognized service"),
|
||||
};
|
||||
|
||||
// If we're building the Serai service, first build the runtime
|
||||
let serai_runtime_volume = format!("serai-{}-runtime-volume", network.label());
|
||||
if name == "serai" {
|
||||
// Check if it's built by checking if the volume has the expected runtime file
|
||||
let built = || {
|
||||
if let Ok(path) = Command::new("docker")
|
||||
.arg("volume")
|
||||
.arg("inspect")
|
||||
.arg("-f")
|
||||
.arg("{{ .Mountpoint }}")
|
||||
.arg(&serai_runtime_volume)
|
||||
.output()
|
||||
{
|
||||
if let Ok(path) = String::from_utf8(path.stdout) {
|
||||
if let Ok(iter) = std::fs::read_dir(PathBuf::from(path.trim())) {
|
||||
for item in iter.flatten() {
|
||||
if item.file_name() == "serai.wasm" {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
};
|
||||
|
||||
if !built() {
|
||||
let mut repo_path = env::current_exe().unwrap();
|
||||
repo_path.pop();
|
||||
if repo_path.as_path().ends_with("deps") {
|
||||
repo_path.pop();
|
||||
}
|
||||
assert!(repo_path.as_path().ends_with("debug") || repo_path.as_path().ends_with("release"));
|
||||
repo_path.pop();
|
||||
assert!(repo_path.as_path().ends_with("target"));
|
||||
repo_path.pop();
|
||||
|
||||
// Build the image to build the runtime
|
||||
if !Command::new("docker")
|
||||
.current_dir(&repo_path)
|
||||
.arg("build")
|
||||
.arg("-f")
|
||||
.arg("orchestration/runtime/Dockerfile")
|
||||
.arg(".")
|
||||
.arg("-t")
|
||||
.arg(format!("serai-{}-runtime-img", network.label()))
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap()
|
||||
.success()
|
||||
{
|
||||
panic!("failed to build runtime image");
|
||||
}
|
||||
|
||||
// Run the image, building the runtime
|
||||
println!("Building the Serai runtime");
|
||||
let container_name = format!("serai-{}-runtime", network.label());
|
||||
let _ =
|
||||
Command::new("docker").arg("rm").arg("-f").arg(&container_name).spawn().unwrap().wait();
|
||||
let _ = Command::new("docker")
|
||||
.arg("run")
|
||||
.arg("--name")
|
||||
.arg(container_name)
|
||||
.arg("--volume")
|
||||
.arg(format!("{serai_runtime_volume}:/volume"))
|
||||
.arg(format!("serai-{}-runtime-img", network.label()))
|
||||
.spawn();
|
||||
|
||||
// Wait until its built
|
||||
let mut ticks = 0;
|
||||
while !built() {
|
||||
std::thread::sleep(core::time::Duration::from_secs(60));
|
||||
ticks += 1;
|
||||
if ticks > 6 * 60 {
|
||||
panic!("couldn't build the runtime after 6 hours")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build it
|
||||
println!("Building {service}");
|
||||
docker::build(&orchestration_path(network), network, name);
|
||||
|
@ -367,6 +448,7 @@ fn start(network: Network, services: HashSet<String>) {
|
|||
assert_eq!(network, Network::Dev, "monero-wallet-rpc is only for dev");
|
||||
command.arg("-p").arg("18082:18082")
|
||||
}
|
||||
"serai" => command.arg("--volume").arg(format!("{serai_runtime_volume}:/runtime")),
|
||||
_ => command,
|
||||
};
|
||||
assert!(
|
||||
|
|
|
@ -21,7 +21,7 @@ EXPOSE 30333 9615 9933 9944
|
|||
ADD /orchestration/{}/serai/run.sh /
|
||||
CMD ["/run.sh"]
|
||||
"#,
|
||||
network.label()
|
||||
network.label(),
|
||||
);
|
||||
|
||||
let run = os(Os::Debian, "", "serai") + &run_serai;
|
||||
|
|
|
@ -15,6 +15,14 @@ fn account_from_name(name: &'static str) -> PublicKey {
|
|||
insecure_pair_from_name(name).public()
|
||||
}
|
||||
|
||||
fn wasm_binary() -> Vec<u8> {
|
||||
// TODO: Accept a config of runtime path
|
||||
if let Ok(binary) = std::fs::read("/runtime/serai.wasm") {
|
||||
return binary;
|
||||
}
|
||||
WASM_BINARY.ok_or("compiled in wasm not available").unwrap().to_vec()
|
||||
}
|
||||
|
||||
fn testnet_genesis(
|
||||
wasm_binary: &[u8],
|
||||
validators: &[&'static str],
|
||||
|
@ -64,18 +72,18 @@ fn testnet_genesis(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn development_config() -> Result<ChainSpec, &'static str> {
|
||||
let wasm_binary = WASM_BINARY.ok_or("Development wasm not available")?;
|
||||
pub fn development_config() -> ChainSpec {
|
||||
let wasm_binary = wasm_binary();
|
||||
|
||||
Ok(ChainSpec::from_genesis(
|
||||
ChainSpec::from_genesis(
|
||||
// Name
|
||||
"Development Network",
|
||||
// ID
|
||||
"devnet",
|
||||
ChainType::Development,
|
||||
|| {
|
||||
move || {
|
||||
testnet_genesis(
|
||||
wasm_binary,
|
||||
&wasm_binary,
|
||||
&["Alice"],
|
||||
vec![
|
||||
account_from_name("Alice"),
|
||||
|
@ -99,21 +107,21 @@ pub fn development_config() -> Result<ChainSpec, &'static str> {
|
|||
None,
|
||||
// Extensions
|
||||
None,
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
pub fn testnet_config() -> Result<ChainSpec, &'static str> {
|
||||
let wasm_binary = WASM_BINARY.ok_or("Testnet wasm not available")?;
|
||||
pub fn testnet_config() -> ChainSpec {
|
||||
let wasm_binary = wasm_binary();
|
||||
|
||||
Ok(ChainSpec::from_genesis(
|
||||
ChainSpec::from_genesis(
|
||||
// Name
|
||||
"Local Test Network",
|
||||
// ID
|
||||
"local",
|
||||
ChainType::Local,
|
||||
|| {
|
||||
move || {
|
||||
testnet_genesis(
|
||||
wasm_binary,
|
||||
&wasm_binary,
|
||||
&["Alice", "Bob", "Charlie", "Dave"],
|
||||
vec![
|
||||
account_from_name("Alice"),
|
||||
|
@ -137,5 +145,5 @@ pub fn testnet_config() -> Result<ChainSpec, &'static str> {
|
|||
None,
|
||||
// Extensions
|
||||
None,
|
||||
))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ impl SubstrateCli for Cli {
|
|||
|
||||
fn load_spec(&self, id: &str) -> Result<Box<dyn sc_service::ChainSpec>, String> {
|
||||
match id {
|
||||
"dev" | "devnet" => Ok(Box::new(chain_spec::development_config()?)),
|
||||
"local" => Ok(Box::new(chain_spec::testnet_config()?)),
|
||||
"dev" | "devnet" => Ok(Box::new(chain_spec::development_config())),
|
||||
"local" => Ok(Box::new(chain_spec::testnet_config())),
|
||||
_ => panic!("Unknown network ID"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,6 +142,7 @@ pub mod pallet {
|
|||
}
|
||||
|
||||
// 80% threshold
|
||||
// TODO: Use 34% for halting a set (not 80%)
|
||||
const REQUIREMENT_NUMERATOR: u64 = 4;
|
||||
const REQUIREMENT_DIVISOR: u64 = 5;
|
||||
|
||||
|
|
Loading…
Reference in a new issue