Skip to content

Commit

Permalink
Fix opcode ORIGIN & add real block env for onchain (#212)
Browse files Browse the repository at this point in the history
* fix opcode ORIGIN

* feature opcode COINBASE, TIMESTAMP, NUMBER, GASLIMIT, CHAINID in the on-chain mode
  • Loading branch information
MingxiYe authored Oct 1, 2023
1 parent 52110e6 commit f8b83a0
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/evm/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ impl EVMInput {
return MutationResult::Skipped;
} else {
input.set_caller(caller);
input.get_vm_env_mut().tx.caller = caller;
MutationResult::Mutated
}
}
Expand Down
75 changes: 75 additions & 0 deletions src/evm/onchain/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ pub struct OnChainConfig {
pub client: reqwest::blocking::Client,
pub chain_id: u32,
pub block_number: String,
pub timestamp: Option<String>,
pub coinbase: Option<String>,
pub gaslimit: Option<String>,
pub block_hash: Option<String>,

pub etherscan_api_key: Vec<String>,
Expand Down Expand Up @@ -274,6 +277,9 @@ impl OnChainConfig {
} else {
format!("0x{:x}", block_number)
},
timestamp: None,
coinbase: None,
gaslimit: None,
block_hash: None,
etherscan_api_key: vec![],
etherscan_base,
Expand Down Expand Up @@ -648,6 +654,75 @@ impl OnChainConfig {
balance
}

pub fn fetch_blk_timestamp(&mut self) -> EVMU256 {
if self.timestamp == None {
self.timestamp = {
let mut params = String::from("[");
params.push_str(&format!("\"{}\",false", self.block_number));
params.push_str("]");
let res = self._request("eth_getBlockByNumber".to_string(), params);
match res {
Some(res) => {
let blk_timestamp = res["timestamp"]
.as_str()
.expect("fail to find block timestamp")
.to_string();
Some(blk_timestamp)
}
None => panic!("fail to get block timestamp"),
}
}
}
let timestamp = EVMU256::from_str(&self.timestamp.as_ref().unwrap()).unwrap();
timestamp
}

pub fn fetch_blk_coinbase(&mut self) -> EVMAddress {
if self.coinbase == None {
self.coinbase = {
let mut params = String::from("[");
params.push_str(&format!("\"{}\",false", self.block_number));
params.push_str("]");
let res = self._request("eth_getBlockByNumber".to_string(), params);
match res {
Some(res) => {
let blk_coinbase = res["miner"]
.as_str()
.expect("fail to find block coinbase")
.to_string();
Some(blk_coinbase)
}
None => panic!("fail to get block coinbase"),
}
}
}
let coinbase = EVMAddress::from_str(&self.coinbase.as_ref().unwrap()).unwrap();
coinbase
}

pub fn fetch_blk_gaslimit(&mut self) -> EVMU256 {
if self.gaslimit == None {
self.gaslimit = {
let mut params = String::from("[");
params.push_str(&format!("\"{}\",false", self.block_number));
params.push_str("]");
let res = self._request("eth_getBlockByNumber".to_string(), params);
match res {
Some(res) => {
let blk_gaslimit = res["gasLimit"]
.as_str()
.expect("fail to find block coinbase")
.to_string();
Some(blk_gaslimit)
}
None => panic!("fail to get block coinbase"),
}
}
}
let gaslimit = EVMU256::from_str(&self.gaslimit.as_ref().unwrap()).unwrap();
gaslimit
}

pub fn get_contract_code(&mut self, address: EVMAddress, force_cache: bool) -> Bytecode {
if self.code_cache.contains_key(&address) {
return self.code_cache[&address].clone();
Expand Down
39 changes: 36 additions & 3 deletions src/evm/onchain/onchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ use crate::evm::corpus_initializer::ABIMap;
use crate::evm::onchain::flashloan::register_borrow_txn;
use crate::evm::types::{convert_u256_to_h160, EVMAddress, EVMU256};
use itertools::Itertools;
use revm_interpreter::Interpreter;
use revm_primitives::Bytecode;
use revm_interpreter::{Interpreter, Host};
use revm_primitives::{Bytecode, U256};
use std::rc::Rc;
use std::str::FromStr;
use std::sync::Arc;
Expand Down Expand Up @@ -239,8 +239,8 @@ where
),
};
}
// BALANCE
#[cfg(feature = "real_balance")]
// BALANCE
0x31 => {
let address = convert_u256_to_h160(interp.stack.peek(0).unwrap());
println!("onchain balance for {:?}", address);
Expand All @@ -255,6 +255,39 @@ where
// std::thread::sleep(std::time::Duration::from_secs(3));
host.next_slot = self.endpoint.get_balance(address);
}
#[cfg(feature = "real_block_env")]
// COINBASE
0x41 => {
if host.env().block.coinbase == EVMAddress::zero() {
host.env().block.coinbase = self.endpoint.fetch_blk_coinbase();
}
}
#[cfg(feature = "real_block_env")]
// TIMESTAMP
0x42 => {
if host.env().block.timestamp == EVMU256::from(1){
host.env().block.timestamp = self.endpoint.fetch_blk_timestamp();
}
}
#[cfg(feature = "real_block_env")]
// NUMBER
0x43 => {
if host.env().block.number == EVMU256::ZERO{
host.env().block.number = EVMU256::from_str(&self.endpoint.block_number).unwrap();
}
}
#[cfg(feature = "real_block_env")]
// GASLIMIT
0x45 => {
if host.env().block.gas_limit == U256::MAX {
host.env().block.gas_limit = self.endpoint.fetch_blk_gaslimit();
}
}
#[cfg(feature = "real_block_env")]
// CHAINID
0x46 => {
host.env().tx.chain_id = Some(self.endpoint.chain_id as u64);
}
// CALL | CALLCODE | DELEGATECALL | STATICCALL | EXTCODESIZE | EXTCODECOPY
0xf1 | 0xf2 | 0xf4 | 0xfa | 0x3b | 0x3c => {
let caller = interp.contract.address;
Expand Down
1 change: 1 addition & 0 deletions src/evm/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ where

self.host.evmstate = vm_state.clone();
self.host.env = input.get_vm_env().clone();
self.host.env.tx.caller = input.get_caller();
self.host.access_pattern = input.get_access_pattern().clone();
self.host.call_count = 0;
self.host.randomness = input.get_randomness();
Expand Down

0 comments on commit f8b83a0

Please sign in to comment.