mirror of
https://github.com/arnaucube/evm-rs.git
synced 2026-02-02 17:06:40 +01:00
Add jump_dest check, add opcode exceptions tests
This commit is contained in:
19
src/lib.rs
19
src/lib.rs
@@ -40,13 +40,13 @@ impl Stack {
|
||||
}
|
||||
}
|
||||
pub fn print_memory(&self) {
|
||||
if self.mem.len() > 0 {
|
||||
if !self.mem.is_empty() {
|
||||
println!("memory ({}):", self.mem.len());
|
||||
println!("{:?}", vec_u8_to_hex(self.mem.to_vec()));
|
||||
}
|
||||
}
|
||||
pub fn print_storage(&self) {
|
||||
if self.storage.len() > 0 {
|
||||
if !self.storage.is_empty() {
|
||||
println!("storage ({}):", self.storage.len());
|
||||
for (key, value) in self.storage.iter() {
|
||||
println!(
|
||||
@@ -79,9 +79,16 @@ impl Stack {
|
||||
pub fn pop(&mut self) -> Result<[u8; 32], String> {
|
||||
match self.stack.pop() {
|
||||
Some(x) => Ok(x),
|
||||
None => Err(format!("pop err")), // WIP
|
||||
None => Err("pop err".to_string()), // WIP
|
||||
}
|
||||
}
|
||||
pub fn substract_gas(&mut self, val: u64) -> Result<(), String> {
|
||||
if self.gas < val {
|
||||
return Err("out of gas".to_string());
|
||||
}
|
||||
self.gas -= val;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn execute(
|
||||
&mut self,
|
||||
@@ -150,8 +157,8 @@ impl Stack {
|
||||
0x51 => self.mload()?,
|
||||
0x52 => self.mstore()?,
|
||||
0x55 => self.sstore()?,
|
||||
0x56 => self.jump()?,
|
||||
0x57 => self.jump_i()?,
|
||||
0x56 => self.jump(code)?,
|
||||
0x57 => self.jump_i(code)?,
|
||||
0x5b => self.jump_dest()?,
|
||||
_ => return Err(format!("unimplemented {:x}", opcode)),
|
||||
}
|
||||
@@ -195,7 +202,7 @@ impl Stack {
|
||||
return Err(format!("unimplemented {:x}", opcode));
|
||||
}
|
||||
}
|
||||
self.gas -= self.opcodes.get(&opcode).unwrap().gas;
|
||||
self.substract_gas(self.opcodes.get(&opcode).unwrap().gas)?;
|
||||
}
|
||||
Ok(Vec::new())
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ impl Stack {
|
||||
Ok(())
|
||||
}
|
||||
pub fn sdiv(&mut self) -> Result<(), String> {
|
||||
Err(format!("unimplemented"))
|
||||
Err("unimplemented".to_string())
|
||||
}
|
||||
pub fn modulus(&mut self) -> Result<(), String> {
|
||||
let b0 = BigUint::from_bytes_be(&self.pop()?[..]);
|
||||
@@ -197,7 +197,7 @@ impl Stack {
|
||||
Ok(())
|
||||
}
|
||||
pub fn smod(&mut self) -> Result<(), String> {
|
||||
Err(format!("unimplemented"))
|
||||
Err("unimplemented".to_string())
|
||||
}
|
||||
pub fn add_mod(&mut self) -> Result<(), String> {
|
||||
let b0 = BigUint::from_bytes_be(&self.pop()?[..]);
|
||||
@@ -334,13 +334,20 @@ impl Stack {
|
||||
self.storage.insert(key, value.to_vec());
|
||||
Ok(())
|
||||
}
|
||||
pub fn jump(&mut self) -> Result<(), String> {
|
||||
pub fn jump(&mut self, code: &[u8]) -> Result<(), String> {
|
||||
// TODO that jump destination is valid
|
||||
self.pc = u256::u256_to_u64(self.pop()?) as usize;
|
||||
let new_pc = u256::u256_to_u64(self.pop()?) as usize;
|
||||
if !valid_dest(code, new_pc) {
|
||||
return Err(format!("not valid dest: {:02x}", new_pc));
|
||||
}
|
||||
self.pc = new_pc;
|
||||
Ok(())
|
||||
}
|
||||
pub fn jump_i(&mut self) -> Result<(), String> {
|
||||
pub fn jump_i(&mut self, code: &[u8]) -> Result<(), String> {
|
||||
let new_pc = u256::u256_to_u64(self.pop()?) as usize;
|
||||
if !valid_dest(code, new_pc) {
|
||||
return Err(format!("not valid dest: {:02x}", new_pc));
|
||||
}
|
||||
if !self.stack.is_empty() {
|
||||
let cond = u256::u256_to_u64(self.pop()?) as usize;
|
||||
if cond != 0 {
|
||||
@@ -357,6 +364,13 @@ impl Stack {
|
||||
}
|
||||
}
|
||||
|
||||
fn valid_dest(code: &[u8], pos: usize) -> bool {
|
||||
if code[pos] == 0x5b {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn upper_multiple_of_32(n: usize) -> usize {
|
||||
((n - 1) | 31) + 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user