Skip to content

Commit

Permalink
fix(sym-exec): thread safe timeout impl
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon-Becker committed Jun 9, 2024
1 parent 0a4c219 commit b894f6c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 74 deletions.
17 changes: 2 additions & 15 deletions crates/common/src/utils/threading.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
use crossbeam_channel::unbounded;
use eyre::{eyre, Result};
use std::{
future::Future,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
thread,
time::Duration,
};
use tokio::{
sync::{oneshot, Mutex},
task,
time::timeout,
};

use std::{sync::Arc, thread};

/// A simple thread pool implementation that takes a vector of items, splits them into chunks, and
/// processes each chunk in a separate thread. The results are collected and returned.
Expand Down
94 changes: 46 additions & 48 deletions crates/vm/src/core/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&b.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&b.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand All @@ -328,8 +328,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&b.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&b.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand All @@ -346,8 +346,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&b.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&b.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand All @@ -367,8 +367,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&numerator.operation.opcode.code)
&& (0x5f..=0x7f).contains(&denominator.operation.opcode.code)
if (0x5f..=0x7f).contains(&numerator.operation.opcode.code) &&
(0x5f..=0x7f).contains(&denominator.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand All @@ -388,8 +388,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&numerator.operation.opcode.code)
&& (0x5f..=0x7f).contains(&denominator.operation.opcode.code)
if (0x5f..=0x7f).contains(&numerator.operation.opcode.code) &&
(0x5f..=0x7f).contains(&denominator.operation.opcode.code)
{
simplified_operation =
WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result.into_raw())])
Expand All @@ -410,8 +410,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&modulus.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&modulus.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand All @@ -431,8 +431,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&modulus.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&modulus.operation.opcode.code)
{
simplified_operation =
WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result.into_raw())])
Expand All @@ -454,8 +454,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&b.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&b.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand All @@ -476,8 +476,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&b.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&b.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand All @@ -494,8 +494,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&exponent.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&exponent.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand Down Expand Up @@ -598,8 +598,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&b.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&b.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand All @@ -616,8 +616,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&b.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&b.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand All @@ -634,8 +634,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&b.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&b.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand Down Expand Up @@ -684,8 +684,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&b.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&b.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand All @@ -704,8 +704,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&b.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&b.operation.opcode.code)
{
simplified_operation = WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result)])
}
Expand All @@ -728,8 +728,8 @@ impl VM {

// if both inputs are PUSH instructions, simplify the operation
let mut simplified_operation = operation;
if (0x5f..=0x7f).contains(&a.operation.opcode.code)
&& (0x5f..=0x7f).contains(&b.operation.opcode.code)
if (0x5f..=0x7f).contains(&a.operation.opcode.code) &&
(0x5f..=0x7f).contains(&b.operation.opcode.code)
{
simplified_operation =
WrappedOpcode::new(0x7f, vec![WrappedInput::Raw(result.into_raw())])
Expand Down Expand Up @@ -1092,13 +1092,12 @@ impl VM {
let pc: u128 = pc.try_into().unwrap_or(u128::MAX);

// Check if JUMPDEST is valid and throw with 790 if not (invalid jump destination)
if (pc
<= self
.bytecode
if (pc <=
self.bytecode
.len()
.try_into()
.expect("impossible case: bytecode is larger than u128::MAX"))
&& (self.bytecode[pc as usize] != 0x5b)
.expect("impossible case: bytecode is larger than u128::MAX")) &&
(self.bytecode[pc as usize] != 0x5b)
{
self.exit(790, Vec::new());
return Ok(Instruction {
Expand Down Expand Up @@ -1126,13 +1125,12 @@ impl VM {
if !condition.eq(&U256::from(0u8)) {
// Check if JUMPDEST is valid and throw with 790 if not (invalid jump
// destination)
if (pc
<= self
.bytecode
if (pc <=
self.bytecode
.len()
.try_into()
.expect("impossible case: bytecode is larger than u128::MAX"))
&& (self.bytecode[pc as usize] != 0x5b)
.expect("impossible case: bytecode is larger than u128::MAX")) &&
(self.bytecode[pc as usize] != 0x5b)
{
self.exit(790, Vec::new());
return Ok(Instruction {
Expand Down Expand Up @@ -1267,9 +1265,9 @@ impl VM {
let data = self.memory.read(offset, size);

// consume dynamic gas
let gas_cost = (375 * (topic_count as u128))
+ 8 * (size as u128)
+ self.memory.expansion_cost(offset, size);
let gas_cost = (375 * (topic_count as u128)) +
8 * (size as u128) +
self.memory.expansion_cost(offset, size);
self.consume_gas(gas_cost);

// no need for a panic check because the length of events should never be larger
Expand Down Expand Up @@ -1463,9 +1461,9 @@ impl VM {
let mut vm_clone = self.clone();

for _ in 0..n {
if vm_clone.bytecode.len() < vm_clone.instruction as usize
|| vm_clone.exitcode != 255
|| !vm_clone.returndata.is_empty()
if vm_clone.bytecode.len() < vm_clone.instruction as usize ||
vm_clone.exitcode != 255 ||
!vm_clone.returndata.is_empty()
{
break;
}
Expand Down
21 changes: 10 additions & 11 deletions crates/vm/src/ext/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@ use crate::{
},
},
};
use eyre::Result;
use eyre::{OptionExt, Result};
use heimdall_common::utils::strings::decode_hex;
use std::{
collections::HashMap,
time::{Duration, Instant},
};
use std::{collections::HashMap, time::Instant};
use tracing::{trace, warn};

#[derive(Clone, Debug, Default)]
Expand Down Expand Up @@ -59,7 +56,8 @@ impl VM {
// the VM is at the function entry point, begin tracing
let mut branch_count = 0;
Ok((
self.recursive_map(&mut branch_count, &mut HashMap::new(), &timeout)?.expect("s"),
self.recursive_map(&mut branch_count, &mut HashMap::new(), &timeout)
.map(|x| x.ok_or_eyre("symbolic execution failed"))??,
branch_count,
))
}
Expand All @@ -71,7 +69,8 @@ impl VM {
// the VM is at the function entry point, begin tracing
let mut branch_count = 0;
Ok((
self.recursive_map(&mut branch_count, &mut HashMap::new(), &timeout)?.expect("s"),
self.recursive_map(&mut branch_count, &mut HashMap::new(), &timeout)
.map(|x| x.ok_or_eyre("symbolic execution failed"))??,
branch_count,
))
}
Expand Down Expand Up @@ -269,7 +268,7 @@ impl VM {
// push a new vm trace to the children
let mut trace_vm = vm.clone();
trace_vm.instruction = last_instruction.inputs[0].as_u128() + 1;
match trace_vm.recursive_map(branch_count, handled_jumps, &timeout_at) {
match trace_vm.recursive_map(branch_count, handled_jumps, timeout_at) {
Ok(Some(child_trace)) => vm_trace.children.push(child_trace),
Ok(None) => {}
Err(e) => {
Expand All @@ -279,7 +278,7 @@ impl VM {
}

// push the current path onto the stack
match vm.recursive_map(branch_count, handled_jumps, &timeout_at) {
match vm.recursive_map(branch_count, handled_jumps, timeout_at) {
Ok(Some(child_trace)) => vm_trace.children.push(child_trace),
Ok(None) => {}
Err(e) => {
Expand All @@ -292,7 +291,7 @@ impl VM {
// push a new vm trace to the children
let mut trace_vm = vm.clone();
trace_vm.instruction = last_instruction.instruction + 1;
match trace_vm.recursive_map(branch_count, handled_jumps, &timeout_at) {
match trace_vm.recursive_map(branch_count, handled_jumps, timeout_at) {
Ok(Some(child_trace)) => vm_trace.children.push(child_trace),
Ok(None) => {}
Err(e) => {
Expand All @@ -302,7 +301,7 @@ impl VM {
}

// push the current path onto the stack
match vm.recursive_map(branch_count, handled_jumps, &timeout_at) {
match vm.recursive_map(branch_count, handled_jumps, timeout_at) {
Ok(Some(child_trace)) => vm_trace.children.push(child_trace),
Ok(None) => {}
Err(e) => {
Expand Down

0 comments on commit b894f6c

Please sign in to comment.