Skip to content
Snippets Groups Projects
Commit 69e36c14 authored by Éloïs's avatar Éloïs
Browse files

feat(xtask): add subcommand inject-runtime-code

parent eae67df6
Branches
Tags
No related merge requests found
...@@ -9000,9 +9000,12 @@ dependencies = [ ...@@ -9000,9 +9000,12 @@ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
"frame-metadata", "frame-metadata",
"hex",
"memmap2 0.5.0",
"parity-scale-codec", "parity-scale-codec",
"run_script", "run_script",
"scale-info", "scale-info",
"serde_json",
"version-compare", "version-compare",
"version_check", "version_check",
] ]
......
...@@ -17,7 +17,10 @@ anyhow = "1.0.32" ...@@ -17,7 +17,10 @@ anyhow = "1.0.32"
clap = { version = "3.0", features = ["derive"] } clap = { version = "3.0", features = ["derive"] }
codec = { package = "parity-scale-codec", version = "2", default-features = false, features = ["derive", "full", "bit-vec"] } codec = { package = "parity-scale-codec", version = "2", default-features = false, features = ["derive", "full", "bit-vec"] }
frame-metadata = "14.0.0" frame-metadata = "14.0.0"
hex = "0.4"
memmap2 = "0.5.0"
run_script = "0.6.3" run_script = "0.6.3"
scale-info = { version = "1.0.0", features = ["bit-vec"] } scale-info = { version = "1.0.0", features = ["bit-vec"] }
serde_json = "1.0"
version_check = "0.9.2" version_check = "0.9.2"
version-compare = "0.0.11" version-compare = "0.0.11"
...@@ -16,8 +16,10 @@ ...@@ -16,8 +16,10 @@
mod gen_calls_doc; mod gen_calls_doc;
use anyhow::Result; use anyhow::{Context, Result};
use clap::Parser; use clap::Parser;
use std::io::{BufReader, BufWriter, Read, Write};
use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
const MIN_RUST_VERSION: &str = "1.58.0"; const MIN_RUST_VERSION: &str = "1.58.0";
...@@ -37,6 +39,15 @@ enum DuniterXTaskCommand { ...@@ -37,6 +39,15 @@ enum DuniterXTaskCommand {
}, },
/// Generate calls documentation /// Generate calls documentation
GenCallsDoc, GenCallsDoc,
/// Inject runtime code in raw specs
InjectRuntimeCode {
#[clap(short, long, parse(from_os_str))]
/// Runtime filepath
runtime: PathBuf,
#[clap(short = 's', long, parse(from_os_str))]
/// Raw spec filepath
raw_spec: PathBuf,
},
/// Execute unit tests and integration tests /// Execute unit tests and integration tests
/// End2tests are skipped /// End2tests are skipped
Test, Test,
...@@ -60,10 +71,67 @@ fn main() -> Result<()> { ...@@ -60,10 +71,67 @@ fn main() -> Result<()> {
match args.command { match args.command {
DuniterXTaskCommand::Build { production } => build(production), DuniterXTaskCommand::Build { production } => build(production),
DuniterXTaskCommand::GenCallsDoc => gen_calls_doc::gen_calls_doc(), DuniterXTaskCommand::GenCallsDoc => gen_calls_doc::gen_calls_doc(),
DuniterXTaskCommand::InjectRuntimeCode { runtime, raw_spec } => {
inject_runtime_code(&raw_spec, &runtime)
}
DuniterXTaskCommand::Test => test(), DuniterXTaskCommand::Test => test(),
} }
} }
fn inject_runtime_code(raw_spec: &Path, runtime: &Path) -> Result<()> {
// Read runtime code
// SAFETY: `mmap` is fundamentally unsafe since technically the file can change
// underneath us while it is mapped; in practice it's unlikely to be a problem
let mut file =
std::fs::File::open(runtime).with_context(|| "Failed to open runtime wasm file")?;
let mut runtime_code =
unsafe { memmap2::Mmap::map(&file).with_context(|| "Failed to read runtime wasm file")? };
// Read raw spec
let mut file = std::fs::File::open(raw_spec).with_context(|| "Failed to open raw spec file")?;
let reader = BufReader::new(file);
let mut json: serde_json::Value =
serde_json::from_reader(reader).with_context(|| "Failed to read raw spec file")?;
println!("json raw specs loaded!");
let mut hex_runtime_code = String::with_capacity(2 + (runtime_code.len() * 2));
hex_runtime_code.push('0');
hex_runtime_code.push('x');
hex_runtime_code.push_str(&hex::encode(runtime_code));
//hex::encode_to_slice(runtime_code, &mut hex_runtime_code[2..])
//.with_context(|| "fail to convert runtime code to hex")?;
const CODE_KEY: &str = "0x3a636f6465";
json.as_object_mut()
.with_context(|| "invalid raw spec file")?
.get_mut("genesis")
.with_context(|| "invalid raw spec file: missing field genesis")?
.as_object_mut()
.with_context(|| "invalid raw spec file")?
.get_mut("raw")
.with_context(|| "invalid raw spec file: missing field raw")?
.as_object_mut()
.with_context(|| "invalid raw spec file")?
.get_mut("top")
.with_context(|| "invalid raw spec file: missing field top")?
.as_object_mut()
.with_context(|| "invalid raw spec file")?
.insert(
CODE_KEY.to_owned(),
serde_json::Value::String(unsafe { std::mem::transmute(hex_runtime_code) }),
);
// Write modified raw specs
let mut file = std::fs::File::create(raw_spec)?;
serde_json::to_writer_pretty(BufWriter::new(file), &json)
.with_context(|| "fail to write raw specs")?;
Ok(())
}
fn build(_production: bool) -> Result<()> { fn build(_production: bool) -> Result<()> {
exec_should_success(Command::new("cargo").args(&["clean", "-p", "duniter"]))?; exec_should_success(Command::new("cargo").args(&["clean", "-p", "duniter"]))?;
exec_should_success(Command::new("cargo").args(&["build", "--locked"]))?; exec_should_success(Command::new("cargo").args(&["build", "--locked"]))?;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment