Skip to content

Commit

Permalink
feat: make runner example runnable (#44)
Browse files Browse the repository at this point in the history
* feat: make runner example runnable

* com

* fix

* com
  • Loading branch information
DaniPopes authored Jun 28, 2024
1 parent 8cb73b6 commit bc5fda8
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 14 deletions.
2 changes: 1 addition & 1 deletion crates/revmc/src/tests/fibonacci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn run_fibonacci_test<B: Backend>(compiler: &mut EvmCompiler<B>, input: u16, dyn
}
let r = unsafe { f.call(Some(stack), Some(stack_len), ecx) };
assert_eq!(r, InstructionResult::Stop);
// Apparently the code does `fibonacci(input - 1)`.
// Apparently the code does `fibonacci(input + 1)`.
assert_eq!(*stack_len, 1);
assert_eq!(stack.as_slice()[0].to_u256(), fibonacci_rust(input + 1));
});
Expand Down
14 changes: 8 additions & 6 deletions examples/runner/build.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
use revmc::{primitives::SpecId, EvmCompiler, EvmLlvmBackend, OptimizationLevel, Result};
use revmc::{
primitives::{hex, SpecId},
EvmCompiler, EvmLlvmBackend, OptimizationLevel, Result,
};
use std::path::PathBuf;

include!("./src/common.rs");

fn main() -> Result<()> {
// Emit the configuration to run compiled bytecodes.
// This not used if we are only using statically linked bytecodes.
revmc_build::emit();

// Compile and statically link a bytecode.
let name = "fibonacci";
let bytecode = revmc::primitives::hex!(
"5f355f60015b8215601a578181019150909160019003916005565b9150505f5260205ff3"
);
println!("cargo:rustc-env=FIB_HASH={}", revmc::primitives::keccak256(bytecode));
let bytecode = FIBONACCI_CODE;

let out_dir = PathBuf::from(std::env::var("OUT_DIR")?);
let context = revmc::llvm::inkwell::context::Context::create();
let backend = EvmLlvmBackend::new(&context, true, OptimizationLevel::Aggressive)?;
let mut compiler = EvmCompiler::new(backend);
compiler.translate(Some(name), &bytecode, SpecId::CANCUN)?;
compiler.translate(Some(name), bytecode, SpecId::CANCUN)?;
let object = out_dir.join(name).with_extension("o");
compiler.write_object_to_file(&object)?;

Expand Down
6 changes: 6 additions & 0 deletions examples/runner/src/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#[allow(dead_code)]
const FIBONACCI_CODE: &[u8] =
&hex!("5f355f60015b8215601a578181019150909160019003916005565b9150505f5260205ff3");
#[allow(dead_code)]
const FIBONACCI_HASH: [u8; 32] =
hex!("ab1ad1211002e1ddb8d9a4ef58a902224851f6a0273ee3e87276a8d21e649ce8");
15 changes: 8 additions & 7 deletions examples/runner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ extern crate alloc;
use revmc_builtins as _;

use alloc::sync::Arc;
use revm::{handler::register::EvmHandler, primitives::B256, Database};
use revm::{
handler::register::EvmHandler,
primitives::{hex, B256},
Database,
};
use revmc_context::EvmCompilerFn;

include!("./common.rs");

// The bytecode we statically linked.
const FIB_HASH: B256 =
match revm::primitives::hex::const_decode_to_array(env!("FIB_HASH").as_bytes()) {
Ok(hash) => B256::new(hash),
Err(_err) => panic!(),
};
revmc_context::extern_revmc! {
fn fibonacci;
}
Expand All @@ -40,7 +41,7 @@ impl ExternalContext {

fn get_function(&self, bytecode_hash: B256) -> Option<EvmCompilerFn> {
// Can use any mapping between bytecode hash and function.
if bytecode_hash == FIB_HASH {
if bytecode_hash == FIBONACCI_HASH {
return Some(EvmCompilerFn::new(fibonacci));
}

Expand Down
32 changes: 32 additions & 0 deletions examples/runner/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use revm::{
db::{CacheDB, EmptyDB},
primitives::{address, hex, AccountInfo, Bytecode, TransactTo, U256},
};
use revmc_examples_runner::build_evm;

include!("./common.rs");

fn main() {
let num =
std::env::args().nth(1).map(|s| s.parse().unwrap()).unwrap_or_else(|| U256::from(100));
// The bytecode runs fib(input + 1), so we need to subtract 1.
let actual_num = num.saturating_sub(U256::from(1));

let db = CacheDB::new(EmptyDB::new());
let mut evm = build_evm(db);
let fibonacci_address = address!("0000000000000000000000000000000000001234");
evm.db_mut().insert_account_info(
fibonacci_address,
AccountInfo {
code_hash: FIBONACCI_HASH.into(),
code: Some(Bytecode::new_raw(FIBONACCI_CODE.into())),
..Default::default()
},
);
evm.context.evm.env.tx.transact_to = TransactTo::Call(fibonacci_address);
evm.context.evm.env.tx.data = actual_num.to_be_bytes_vec().into();
let result = evm.transact().unwrap();
// eprintln!("{:#?}", result.result);

println!("fib({num}) = {}", U256::from_be_slice(result.result.output().unwrap()));
}

0 comments on commit bc5fda8

Please sign in to comment.