Skip to content

Commit

Permalink
feat: add insert method on instruction table (#1167)
Browse files Browse the repository at this point in the history
* feat: add insert method on instruction table

* fix test

* nits refactor in tests

* clippy
  • Loading branch information
Rjected authored Mar 8, 2024
1 parent b60f796 commit 93557e9
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
15 changes: 15 additions & 0 deletions crates/interpreter/src/instructions/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ impl<H: Host> InstructionTables<'_, H> {
}
}

impl<'a, H: Host + 'a> InstructionTables<'a, H> {
/// Inserts the instruction into the table with the specified index.
#[inline]
pub fn insert(&mut self, opcode: u8, instruction: Instruction<H>) {
match self {
Self::Plain(table) => {
table[opcode as usize] = instruction;
}
Self::Boxed(table) => {
table[opcode as usize] = Box::new(instruction);
}
}
}
}

/// Make instruction table.
#[inline]
pub const fn make_instruction_table<H: Host, SPEC: Spec>() -> InstructionTable<H> {
Expand Down
38 changes: 36 additions & 2 deletions crates/revm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,11 +443,45 @@ mod test {
db::EmptyDB,
inspector::inspector_handle_register,
inspectors::NoOpInspector,
primitives::{Address, Bytes, PrecompileResult},
Context, ContextPrecompile, ContextStatefulPrecompile, Evm, EvmContext,
primitives::{
address, AccountInfo, Address, Bytecode, Bytes, PrecompileResult, TransactTo, U256,
},
Context, ContextPrecompile, ContextStatefulPrecompile, Evm, EvmContext, InMemoryDB,
};
use revm_interpreter::{Host, Interpreter};
use std::sync::Arc;

#[test]
fn simple_add_instruction() {
const CUSTOM_INSTRUCTION_COST: u64 = 133;
const INITIAL_TX_GAS: u64 = 21000;
const EXPECTED_RESULT_GAS: u64 = INITIAL_TX_GAS + CUSTOM_INSTRUCTION_COST;
fn custom_instruction(interp: &mut Interpreter, _host: &mut impl Host) {
// just spend some gas
interp.gas.record_cost(CUSTOM_INSTRUCTION_COST);
}

let code = Bytecode::new_raw([0xEF, 0x00].into());
let code_hash = code.hash_slow();
let to_addr = address!("ffffffffffffffffffffffffffffffffffffffff");

let mut evm = Evm::builder()
.with_db(InMemoryDB::default())
.modify_db(|db| {
db.insert_account_info(to_addr, AccountInfo::new(U256::ZERO, 0, code_hash, code))
})
.modify_tx_env(|tx| tx.transact_to = TransactTo::Call(to_addr))
.append_handler_register(|handler| {
if let Some(ref mut table) = handler.instruction_table {
table.insert(0xEF, custom_instruction)
}
})
.build();

let result_and_state = evm.transact().unwrap();
assert_eq!(result_and_state.result.gas_used(), EXPECTED_RESULT_GAS);
}

#[test]
fn simple_build() {
// build without external with latest spec
Expand Down

0 comments on commit 93557e9

Please sign in to comment.