Skip to content

Commit

Permalink
pallet-revive: Use custom target to build test fixtures (paritytech#6266
Browse files Browse the repository at this point in the history
)

This removes the need to use a custom toolchain to build the contract
test fixtures. Instead, we supply a custom target and use the currently
in use upstream toolchain.

---------

Co-authored-by: Jan Bujak <jan@parity.io>
Co-authored-by: Cyrill Leutwiler <cyrill@parity.io>
Co-authored-by: command-bot <>
  • Loading branch information
3 people authored and mordamax committed Oct 29, 2024
1 parent 938eefc commit d7681f0
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 53 deletions.
56 changes: 35 additions & 21 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions substrate/frame/revive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ targets = ["x86_64-unknown-linux-gnu"]
environmental = { workspace = true }
paste = { workspace = true }
polkavm = { version = "0.13.0", default-features = false }
polkavm-common = { version = "0.13.0", default-features = false }
bitflags = { workspace = true }
codec = { features = ["derive", "max-encoded-len"], workspace = true }
scale-info = { features = ["derive"], workspace = true }
Expand Down Expand Up @@ -100,7 +99,6 @@ std = [
"pallet-timestamp/std",
"pallet-transaction-payment/std",
"pallet-utility/std",
"polkavm-common/std",
"polkavm/std",
"rlp/std",
"scale-info/std",
Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/revive/fixtures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ log = { workspace = true }
parity-wasm = { workspace = true }
tempfile = { workspace = true }
toml = { workspace = true }
polkavm-linker = { version = "0.13.0" }
polkavm-linker = { version = "0.14.0" }
anyhow = { workspace = true, default-features = true }

[features]
Expand Down
55 changes: 31 additions & 24 deletions substrate/frame/revive/fixtures/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ mod build {
process::Command,
};

const OVERRIDE_RUSTUP_TOOLCHAIN_ENV_VAR: &str = "PALLET_REVIVE_FIXTURES_RUSTUP_TOOLCHAIN";
const OVERRIDE_STRIP_ENV_VAR: &str = "PALLET_REVIVE_FIXTURES_STRIP";
const OVERRIDE_OPTIMIZE_ENV_VAR: &str = "PALLET_REVIVE_FIXTURES_OPTIMIZE";

/// A contract entry.
struct Entry {
/// The path to the contract source file.
Expand Down Expand Up @@ -112,54 +116,50 @@ mod build {
fs::write(output_dir.join("Cargo.toml"), cargo_toml).map_err(Into::into)
}

fn invoke_build(current_dir: &Path) -> Result<()> {
let encoded_rustflags = [
"-Dwarnings",
"-Crelocation-model=pie",
"-Clink-arg=--emit-relocs",
"-Clink-arg=--export-dynamic-symbol=__polkavm_symbol_export_hack__*",
]
.join("\x1f");
fn invoke_build(target: &Path, current_dir: &Path) -> Result<()> {
let encoded_rustflags = ["-Dwarnings"].join("\x1f");

let build_res = Command::new(env::var("CARGO")?)
let mut build_command = Command::new(env::var("CARGO")?);
build_command
.current_dir(current_dir)
.env_clear()
.env("PATH", env::var("PATH").unwrap_or_default())
.env("CARGO_ENCODED_RUSTFLAGS", encoded_rustflags)
.env("RUSTUP_TOOLCHAIN", "rve-nightly")
.env("RUSTC_BOOTSTRAP", "1")
.env("RUSTUP_HOME", env::var("RUSTUP_HOME").unwrap_or_default())
.args([
"build",
"--release",
"--target=riscv32ema-unknown-none-elf",
"-Zbuild-std=core",
"-Zbuild-std-features=panic_immediate_abort",
])
.output()
.expect("failed to execute process");
.arg("--target")
.arg(target);

if let Ok(toolchain) = env::var(OVERRIDE_RUSTUP_TOOLCHAIN_ENV_VAR) {
build_command.env("RUSTUP_TOOLCHAIN", &toolchain);
}

let build_res = build_command.output().expect("failed to execute process");

if build_res.status.success() {
return Ok(())
}

let stderr = String::from_utf8_lossy(&build_res.stderr);

if stderr.contains("'rve-nightly' is not installed") {
eprintln!("RISC-V toolchain is not installed.\nDownload and install toolchain from https://github.com/paritytech/rustc-rv32e-toolchain.");
eprintln!("{}", stderr);
} else {
eprintln!("{}", stderr);
}
eprintln!("{}", stderr);

bail!("Failed to build contracts");
}

/// Post-process the compiled code.
fn post_process(input_path: &Path, output_path: &Path) -> Result<()> {
let strip = std::env::var(OVERRIDE_STRIP_ENV_VAR).map_or(false, |value| value == "1");
let optimize = std::env::var(OVERRIDE_OPTIMIZE_ENV_VAR).map_or(true, |value| value == "1");

let mut config = polkavm_linker::Config::default();
config.set_strip(false);
config.set_optimize(true);
config.set_strip(strip);
config.set_optimize(optimize);
let orig =
fs::read(input_path).with_context(|| format!("Failed to read {:?}", input_path))?;
let linked = polkavm_linker::program_from_elf(config, orig.as_ref())
Expand All @@ -171,7 +171,9 @@ mod build {
fn write_output(build_dir: &Path, out_dir: &Path, entries: Vec<Entry>) -> Result<()> {
for entry in entries {
post_process(
&build_dir.join("target/riscv32ema-unknown-none-elf/release").join(entry.name()),
&build_dir
.join("target/riscv32emac-unknown-none-polkavm/release")
.join(entry.name()),
&out_dir.join(entry.out_filename()),
)?;
}
Expand All @@ -183,6 +185,11 @@ mod build {
let fixtures_dir: PathBuf = env::var("CARGO_MANIFEST_DIR")?.into();
let contracts_dir = fixtures_dir.join("contracts");
let out_dir: PathBuf = env::var("OUT_DIR")?.into();
let target = fixtures_dir.join("riscv32emac-unknown-none-polkavm.json");

println!("cargo::rerun-if-env-changed={OVERRIDE_RUSTUP_TOOLCHAIN_ENV_VAR}");
println!("cargo::rerun-if-env-changed={OVERRIDE_STRIP_ENV_VAR}");
println!("cargo::rerun-if-env-changed={OVERRIDE_OPTIMIZE_ENV_VAR}");

// the fixtures have a dependency on the uapi crate
println!("cargo::rerun-if-changed={}", fixtures_dir.display());
Expand All @@ -200,7 +207,7 @@ mod build {
let tmp_dir_path = tmp_dir.path();

create_cargo_toml(&fixtures_dir, entries.iter(), tmp_dir.path())?;
invoke_build(tmp_dir_path)?;
invoke_build(&target, tmp_dir_path)?;

write_output(tmp_dir_path, &out_dir, entries)?;

Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/revive/fixtures/build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ edition = "2021"
[dependencies]
uapi = { package = 'pallet-revive-uapi', path = "", default-features = false }
common = { package = 'pallet-revive-fixtures-common', path = "" }
polkavm-derive = { version = "0.13.0" }
polkavm-derive = { version = "0.14.0" }

[profile.release]
opt-level = 3
Expand Down
7 changes: 6 additions & 1 deletion substrate/frame/revive/fixtures/contracts/oom_rw_included.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,16 @@ use uapi::{HostFn, HostFnImpl as api, ReturnFlags};

static mut BUFFER: [u8; 513 * 1024] = [42; 513 * 1024];

unsafe fn buffer() -> &'static [u8; 513 * 1024] {
let ptr = core::ptr::addr_of!(BUFFER);
&*ptr
}

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub unsafe extern "C" fn call_never() {
// make sure the buffer is not optimized away
api::return_value(ReturnFlags::empty(), &BUFFER);
api::return_value(ReturnFlags::empty(), buffer());
}

#[no_mangle]
Expand Down
7 changes: 6 additions & 1 deletion substrate/frame/revive/fixtures/contracts/oom_rw_trailing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,16 @@ use uapi::{HostFn, HostFnImpl as api, ReturnFlags};

static mut BUFFER: [u8; 2 * 1025 * 1024] = [0; 2 * 1025 * 1024];

unsafe fn buffer() -> &'static [u8; 2 * 1025 * 1024] {
let ptr = core::ptr::addr_of!(BUFFER);
&*ptr
}

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub unsafe extern "C" fn call_never() {
// make sure the buffer is not optimized away
api::return_value(ReturnFlags::empty(), &BUFFER);
api::return_value(ReturnFlags::empty(), buffer());
}

#[no_mangle]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"arch": "riscv32",
"cpu": "generic-rv32",
"crt-objects-fallback": "false",
"data-layout": "e-m:e-p:32:32-i64:64-n32-S32",
"eh-frame-header": false,
"emit-debug-gdb-scripts": false,
"features": "+e,+m,+a,+c,+lui-addi-fusion,+fast-unaligned-access,+xtheadcondmov",
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"llvm-abiname": "ilp32e",
"llvm-target": "riscv32",
"max-atomic-width": 32,
"panic-strategy": "abort",
"relocation-model": "pie",
"target-pointer-width": "32",
"singlethread": true,
"pre-link-args": {
"ld": [
"--emit-relocs",
"--unique",
"--relocatable"
]
},
"env": "polkavm"
}
2 changes: 1 addition & 1 deletion substrate/frame/revive/src/limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ pub mod code {
// This scans the whole program but we only do it once on code deployment.
// It is safe to do unchecked math in u32 because the size of the program
// was already checked above.
use polkavm_common::program::ISA32_V1_NoSbrk as ISA;
use polkavm::program::ISA32_V1_NoSbrk as ISA;
let mut num_instructions: u32 = 0;
let mut max_basic_block_size: u32 = 0;
let mut basic_block_size: u32 = 0;
Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/revive/uapi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ codec = { features = [
], optional = true, workspace = true }

[target.'cfg(target_arch = "riscv32")'.dependencies]
polkavm-derive = { version = "0.13.0" }
polkavm-derive = { version = "0.14.0" }

[package.metadata.docs.rs]
default-target = ["wasm32-unknown-unknown"]
Expand Down

0 comments on commit d7681f0

Please sign in to comment.