Skip to content
This repository has been archived by the owner on Nov 20, 2023. It is now read-only.

Commit

Permalink
sync with upstream for shanghai changes
Browse files Browse the repository at this point in the history
  • Loading branch information
vimpunk committed May 3, 2023
1 parent 3ffc876 commit 76552e0
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 24 deletions.
18 changes: 17 additions & 1 deletion ethjson/src/spec/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,13 @@ pub enum ForkSpec {
Istanbul,
/// Berlin (#12,244,000, 2021-04-15)
Berlin,
/// London (To be announced)
/// London (#12,965,000, 2021-08-05)
London,
/// Paris - The Merge (#15,537,394, 2022-09-15)
Merge,
/// Shanghai (#17,034,870, 2023-04-12)
Shanghai,

/// Byzantium transition test-net
EIP158ToByzantiumAt5,
/// Homestead transition test-net
Expand All @@ -58,6 +63,17 @@ pub enum ForkSpec {
ConstantinopleFixToIstanbulAt5,
}

impl ForkSpec {
/// Returns true if the fork is at or after the merge.
pub fn is_eth2(&self) -> bool {
// NOTE: Include new forks in this match arm.
matches!(
*self,
ForkSpec::London | ForkSpec::Merge | ForkSpec::Shanghai
)
}
}

/// Spec deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
Expand Down
10 changes: 8 additions & 2 deletions ethjson/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ pub struct Env {
#[serde(rename = "currentBaseFee")]
#[serde(default)]
pub block_base_fee_per_gas: Uint,
/// Pre-seeded random value for testing
#[serde(rename = "currentRandom")]
#[serde(default)]
pub random: Option<Uint>,
}

#[cfg(test)]
Expand All @@ -145,7 +149,8 @@ mod tests {
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
"currentTimestamp" : "0x01",
"currentRandom" : "0x01"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
Expand Down Expand Up @@ -192,7 +197,8 @@ mod tests {
gas_limit: Uint(0x0f4240.into()),
number: Uint(0.into()),
timestamp: Uint(1.into()),
block_base_fee_per_gas: Uint(0.into())
block_base_fee_per_gas: Uint(0.into()),
random: Some(Uint(1.into())),
}
);
assert_eq!(
Expand Down
2 changes: 1 addition & 1 deletion jsontests/res/ethtests
53 changes: 41 additions & 12 deletions jsontests/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ impl Test {
}

pub fn unwrap_caller(&self) -> H160 {
let hash: H256 = self.0.transaction.secret.clone().unwrap().into();
let hash: H256 = self.0.transaction.secret.unwrap().into();
let mut secret_key = [0; 32];
secret_key.copy_from_slice(&hash.as_bytes()[..]);
secret_key.copy_from_slice(hash.as_bytes());
let secret = SecretKey::parse(&secret_key);
let public = libsecp256k1::PublicKey::from_secret_key(&secret.unwrap());
let mut res = [0u8; 64];
res.copy_from_slice(&public.serialize()[1..65]);

H160::from(H256::from_slice(Keccak256::digest(&res).as_slice()))
H160::from(H256::from_slice(Keccak256::digest(res).as_slice()))
}

pub fn unwrap_to_vicinity(&self, spec: &ForkSpec) -> Option<MemoryVicinity> {
Expand Down Expand Up @@ -70,17 +70,36 @@ impl Test {
return None;
}

let block_randomness = if spec.is_eth2() {
self.0.env.random.map(|r| {
// Convert between U256 and H256. U256 is in little-endian but since H256 is just
// a string-like byte array, it's big endian (MSB is the first element of the array).
//
// Byte order here is important because this opcode has the same value as DIFFICULTY
// (0x44), and so for older forks of Ethereum, the threshold value of 2^64 is used to
// distinguish between the two: if it's below, the value corresponds to the DIFFICULTY
// opcode, otherwise to the PREVRANDAO opcode.
let mut buf = [0u8; 32];
r.0.to_big_endian(&mut buf);
H256(buf)
})
} else {
None
};


Some(MemoryVicinity {
gas_price,
origin: self.unwrap_caller(),
block_hashes: Vec::new(),
block_number: self.0.env.number.clone().into(),
block_coinbase: self.0.env.author.clone().into(),
block_timestamp: self.0.env.timestamp.clone().into(),
block_difficulty: self.0.env.difficulty.clone().into(),
block_gas_limit: self.0.env.gas_limit.clone().into(),
block_number: self.0.env.number.into(),
block_coinbase: self.0.env.author.into(),
block_timestamp: self.0.env.timestamp.into(),
block_difficulty: self.0.env.difficulty.into(),
block_gas_limit: self.0.env.gas_limit.into(),
chain_id: U256::one(),
block_base_fee_per_gas,
block_randomness,
})
}
}
Expand Down Expand Up @@ -139,6 +158,10 @@ impl JsonPrecompile {
}
// precompiles for London and Berlin are the same
ForkSpec::London => Self::precompile(&ForkSpec::Berlin),
// precompiles for Merge and Berlin are the same
ForkSpec::Merge => Self::precompile(&ForkSpec::Berlin),
// precompiles for Shanghai and Berlin are the same
ForkSpec::Shanghai => Self::precompile(&ForkSpec::Berlin),
_ => None,
}
}
Expand Down Expand Up @@ -211,8 +234,10 @@ fn test_run(name: &str, test: Test) {
ethjson::spec::ForkSpec::Istanbul => (Config::istanbul(), true),
ethjson::spec::ForkSpec::Berlin => (Config::berlin(), true),
ethjson::spec::ForkSpec::London => (Config::london(), true),
ethjson::spec::ForkSpec::Merge => (Config::merge(), true),
ethjson::spec::ForkSpec::Shanghai => (Config::shanghai(), true),
spec => {
println!("Skip spec {:?}", spec);
println!("Skip spec {spec:?}");
continue;
}
};
Expand Down Expand Up @@ -288,8 +313,9 @@ fn test_run(name: &str, test: Test) {
}

let actual_fee = executor.fee(vicinity.gas_price);
let mniner_reward = if let ForkSpec::London = spec {
// see EIP-1559
// Forks after London burn miner rewards and thus have different gas fee
// calculation (see EIP-1559)
let miner_reward = if spec.is_eth2() {
let max_priority_fee_per_gas = test.0.transaction.max_priority_fee_per_gas();
let max_fee_per_gas = test.0.transaction.max_fee_per_gas();
let base_fee_per_gas = vicinity.block_base_fee_per_gas;
Expand All @@ -299,11 +325,14 @@ fn test_run(name: &str, test: Test) {
} else {
actual_fee
};

executor
.state_mut()
.deposit(vicinity.block_coinbase, mniner_reward);
.deposit(vicinity.block_coinbase, miner_reward);
executor.state_mut().deposit(caller, total_fee - actual_fee);

let (values, logs) = executor.into_state().deconstruct();

backend.apply(values, logs, delete_empty);
}

Expand Down
6 changes: 3 additions & 3 deletions jsontests/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ pub fn assert_valid_hash(h: &H256, b: &BTreeMap<H160, MemoryAccount>) {
.collect::<Vec<_>>();

let root = ethereum::util::sec_trie_root(tree);
let expect = h.clone().into();
let expect = h;

if root != expect {
if root != *expect {
panic!(
"Hash not equal; calculated: {:?}, expect: {:?}\nState: {:#x?}",
root, expect, b
Expand All @@ -157,7 +157,7 @@ pub fn assert_valid_hash(h: &H256, b: &BTreeMap<H160, MemoryAccount>) {
pub fn flush() {
use std::io::{self, Write};

io::stdout().flush().ok().expect("Could not flush stdout");
io::stdout().flush().expect("Could not flush stdout");
}

pub mod transaction {
Expand Down
19 changes: 17 additions & 2 deletions jsontests/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::utils::*;
use evm::backend::{ApplyBackend, MemoryAccount, MemoryBackend, MemoryVicinity};
use evm::executor::stack::{MemoryStackState, StackExecutor, StackSubstateMetadata};
use evm::Config;
use primitive_types::{H160, U256};
use primitive_types::{H160, H256, U256};
use serde::Deserialize;
use std::collections::BTreeMap;
use std::rc::Rc;
Expand All @@ -16,6 +16,19 @@ impl Test {
}

pub fn unwrap_to_vicinity(&self) -> MemoryVicinity {
let block_randomness = self.0.env.random.map(|r| {
// Convert between U256 and H256. U256 is in little-endian but since H256 is just
// a string-like byte array, it's big endian (MSB is the first element of the array).
//
// Byte order here is important because this opcode has the same value as DIFFICULTY
// (0x44), and so for older forks of Ethereum, the threshold value of 2^64 is used to
// distinguish between the two: if it's below, the value corresponds to the DIFFICULTY
// opcode, otherwise to the PREVRANDAO opcode.
let mut buf = [0u8; 32];
r.0.to_big_endian(&mut buf);
H256(buf)
});

MemoryVicinity {
gas_price: self.0.transaction.gas_price.clone().into(),
origin: self.0.transaction.origin.clone().into(),
Expand All @@ -27,6 +40,7 @@ impl Test {
block_gas_limit: self.0.env.gas_limit.clone().into(),
chain_id: U256::zero(),
block_base_fee_per_gas: self.0.transaction.gas_price.clone().into(),
block_randomness,
}
}

Expand Down Expand Up @@ -75,7 +89,8 @@ pub fn test(name: &str, test: Test) {
let code = test.unwrap_to_code();
let data = test.unwrap_to_data();
let context = test.unwrap_to_context();
let mut runtime = evm::Runtime::new(code, data, context, config.stack_limit, config.memory_limit);
let mut runtime =
evm::Runtime::new(code, data, context, config.stack_limit, config.memory_limit);

let reason = executor.execute(&mut runtime);
let gas = executor.gas();
Expand Down
6 changes: 3 additions & 3 deletions jsontests/tests/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub fn run(dir: &str) {
for entry in fs::read_dir(dest).unwrap() {
let entry = entry.unwrap();
if let Some(s) = entry.file_name().to_str() {
if s.starts_with(".") {
if s.starts_with('.') {
continue;
}
}
Expand All @@ -23,8 +23,8 @@ pub fn run(dir: &str) {
let file = File::open(path).expect("Open file failed");

let reader = BufReader::new(file);
let coll = serde_json::from_reader::<_, HashMap<String, statetests::Test>>(reader)
.expect("Parse test cases failed");
let coll: HashMap<String, statetests::Test> =
serde_json::from_reader(reader).expect("Parse test cases failed");

for (name, test) in coll {
statetests::test(&name, test);
Expand Down

0 comments on commit 76552e0

Please sign in to comment.