Skip to content

Commit

Permalink
polkatool jam-service [compiledcode]
Browse files Browse the repository at this point in the history
Sample execution: (after cargo build of jam-service-fib)
./target/release/polkatool jam-service ~/polkavm/guest-programs/jam-service-fib/target/riscv32ema-unknown-none-elf/release/jam-service-fib
  • Loading branch information
sourabhniyogi committed Sep 26, 2024
1 parent 4aa1c44 commit 706c34a
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 27 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,3 +1,5 @@
cargo-features = ["edition2024"]

[package]
name = "jam-service-fib"
version = "0.1.0"
Expand All @@ -7,12 +9,9 @@ publish = false
[lib]
name = "fib"
path = "src/main.rs"
crate-type = ["cdylib"]

[[bin]]
name = "jam-service-fib"
path = "src/main.rs"
crate-type = ["staticlib", "rlib"]

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

54 changes: 33 additions & 21 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,13 @@ extern "C" {
pub fn sha2_256(data: *const u8, data_len: u32, hash_ptr: *mut u8) -> u32;
}

fn is_authorized() -> bool {
true
#[polkavm_derive::polkavm_export]
extern "C" fn is_authorized_ext() -> u32 {
0
}

fn refine() -> [u8; 12] {
#[polkavm_derive::polkavm_export]
extern "C" fn refine_ext() -> u32 {
let mut buffer = [0u8; 12];
let result = unsafe { import(0, buffer.as_mut_ptr(), buffer.len() as u32) };

Expand All @@ -73,13 +90,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 @@ -90,25 +105,22 @@ fn refine() -> [u8; 12] {
export(buffer.as_mut_ptr(), buffer.len() as u32);
}

buffer
0
}

fn accumulate() -> [u8; 12] {
let mut buffer = [0u8; 12];
#[polkavm_derive::polkavm_export]
extern "C" fn accumulate_ext() -> u32 {
let buffer = [0u8; 12];
let key = [0u8; 1];

unsafe {
write(key.as_ptr(), 1, buffer.as_ptr(), buffer.len() as u32);
}

buffer
0
}

fn on_transfer() -> bool {
true
#[polkavm_derive::polkavm_export]
extern "C" fn on_transfer_ext() -> u32 {
0
}

// 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
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"]

Binary file added tools/polkatool/jam_service.pvm
Binary file not shown.
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 706c34a

Please sign in to comment.