Skip to content

Commit

Permalink
polkatool jam-service [compiledcode]
Browse files Browse the repository at this point in the history
Currently gives:
ERROR: Failed to create program from ELF: the program contains no code (linking empty programs is not supported!)
  • Loading branch information
sourabhniyogi committed Sep 25, 2024
1 parent 4aa1c44 commit bbf4c11
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 22 deletions.
8 changes: 8 additions & 0 deletions guest-programs/Cargo.lock

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

1 change: 1 addition & 0 deletions guest-programs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ resolver = "2"
members = [
# Examples:
"example-hello-world",
"jam-service-fib",

# Benchmarks:
"bench-minimal",
Expand Down
9 changes: 4 additions & 5 deletions guest-programs/jam-service-fib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
cargo-features = ["edition2024"]

[package]
name = "jam-service-fib"
version = "0.1.0"
edition = "2024"
publish = false

[lib]
name = "fib"
path = "src/main.rs"
crate-type = ["cdylib"]

[[bin]]
name = "jam-service-fib"
path = "src/main.rs"

[dependencies]
polkavm-derive = { path = "../../crates/polkavm-derive" }
simplealloc = { path = "../../crates/simplealloc" }
##alloc = "0.5.0"

71 changes: 55 additions & 16 deletions guest-programs/jam-service-fib/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
#![no_std]
#![no_main]

extern crate alloc;

use alloc::vec::Vec;
use simplealloc::SimpleAlloc;

#[global_allocator]
static ALLOCATOR: SimpleAlloc<4096> = SimpleAlloc::new();

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
core::arch::asm!("unimp", options(noreturn));
}
}

#[polkavm_derive::polkavm_import]
extern "C" {
#[polkavm_import(index = 0)]
Expand Down Expand Up @@ -59,11 +74,11 @@ extern "C" {
pub fn sha2_256(data: *const u8, data_len: u32, hash_ptr: *mut u8) -> u32;
}

fn is_authorized() -> bool {
pub fn is_authorized() -> bool {
true
}

fn refine() -> [u8; 12] {
pub fn refine() -> [u8; 12] {
let mut buffer = [0u8; 12];
let result = unsafe { import(0, buffer.as_mut_ptr(), buffer.len() as u32) };

Expand All @@ -73,13 +88,11 @@ fn refine() -> [u8; 12] {
let fib_n_minus_1 = u32::from_le_bytes(buffer[8..12].try_into().unwrap());

let new_fib_n = fib_n + fib_n_minus_1;

let new_buffer = [
(n + 1).to_le_bytes(),
new_fib_n.to_le_bytes(),
fib_n.to_le_bytes(),
]
.concat();
let new_buffer: Vec<u8> = [(n + 1).to_le_bytes(), new_fib_n.to_le_bytes(), fib_n.to_le_bytes()]
.iter()
.flat_map(|array| array.iter())
.copied()
.collect();

buffer.copy_from_slice(&new_buffer);
} else {
Expand All @@ -93,8 +106,8 @@ fn refine() -> [u8; 12] {
buffer
}

fn accumulate() -> [u8; 12] {
let mut buffer = [0u8; 12];
pub fn accumulate() -> [u8; 12] {
let buffer = [0u8; 12];
let key = [0u8; 1];

unsafe {
Expand All @@ -104,11 +117,37 @@ fn accumulate() -> [u8; 12] {
buffer
}

fn on_transfer() -> bool {
pub fn on_transfer() -> bool {
true
}

// TODO: (1) Get toolchain instructions sufficient to get above Rust compiled into PVM with
// (a) ecalli 16/17/3 in place of import/export (refine) + write (accumulate)
// (b) entrypoints 0/5/10/15 going into is_authorized/refine/accumulate/on_transfer
// (2) get polkatool to output .pvm byte code with (1b) streamlined
pub fn main() {
refine();
accumulate();
}

/*
(1) cargo build works but you have to get toolchain
https://github.com/paritytech/rustc-rv32e-toolchain/
and untar into ~/.rustup/toolchains/
Then to use it:
export RUSTUP_TOOLCHAIN=rve-nightly
I had to adjust the repo a bit to refer to the above
TODO:
(1) Get PVM out with ecalli 16/17/3 in place of import/export (refine) + write (accumulate)
(2) Here is Jan's advice: To emit the JAM entry points and a raw program blob without the .polkavm container then you do need to postprocess the output of the compilation.
let mut config = polkavm_linker::Config::default();
config.set_strip(true);
config.set_dispatch_table(vec![
b"is_authorized_ext".into(),
b"refine_ext".into(),
b"accumulate_ext".into(),
b"on_transfer_ext".into(),
]);
let elf = fs::read("target/riscv32ema-unknown-none-elf/release/jam-service-fib").unwrap();
let raw_blob = polkavm_linker::program_from_elf(config, elf.as_ref()).unwrap();
let parts = polkavm_linker::ProgramParts::from_bytes(raw_blob.into()).unwrap();
std::fs::write("blob.pvm", &parts.code_and_jump_table).unwrap();
*/
5 changes: 4 additions & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[toolchain]
channel = "1.75.0"
channel = "rve-nightly"
components = ["rustc", "cargo", "rust-std"]
targets = ["riscv32imc-unknown-none-elf"]

34 changes: 34 additions & 0 deletions tools/polkatool/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ enum Args {
/// The input files.
inputs: Vec<PathBuf>,
},

/// Builds JAM-ready polkavm file
JAMService {
/// The input file.
input: PathBuf,
},
}

macro_rules! bail {
Expand Down Expand Up @@ -90,6 +96,7 @@ fn main() {
} => main_disassemble(input, format, display_gas, show_raw_bytes, output),
Args::Assemble { input, output } => main_assemble(input, output),
Args::Stats { inputs } => main_stats(inputs),
Args::JAMService { input } => main_jam_service(input),
};

if let Err(error) = result {
Expand Down Expand Up @@ -233,3 +240,30 @@ fn main_assemble(input_path: PathBuf, output_path: PathBuf) -> Result<(), String

Ok(())
}

fn main_jam_service(input_path: PathBuf) -> Result<(), String> {
if !input_path.exists() {
bail!("File does not exist: {input_path:?}");
}

use std::fs;

let mut config = polkavm_linker::Config::default();
config.set_strip(true);
config.set_dispatch_table(vec![
b"is_authorized_ext".into(),
b"refine_ext".into(),
b"accumulate_ext".into(),
b"on_transfer_ext".into(),
]);

let elf = fs::read(input_path).map_err(|err| format!("Failed to read ELF file: {}", err))?;
let raw_blob =
polkavm_linker::program_from_elf(config, elf.as_ref()).map_err(|err| format!("Failed to create program from ELF: {}", err))?;
let parts =
polkavm_linker::ProgramParts::from_bytes(raw_blob.into()).map_err(|err| format!("Failed to parse program parts: {}", err))?;

fs::write("jam_service.pvm", &parts.code_and_jump_table).map_err(|err| format!("Failed to write jam_service.pvm: {}", err))?;

Ok(())
}

0 comments on commit bbf4c11

Please sign in to comment.