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

Commit 54947fc

Browse files
authored
Merge pull request #19 from mandreyel/sync-upstream-shanghai
chore: sync with upstream for Shanghai changes
2 parents 3ffc876 + 76552e0 commit 54947fc

File tree

7 files changed

+90
-24
lines changed

7 files changed

+90
-24
lines changed

ethjson/src/spec/spec.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,13 @@ pub enum ForkSpec {
4242
Istanbul,
4343
/// Berlin (#12,244,000, 2021-04-15)
4444
Berlin,
45-
/// London (To be announced)
45+
/// London (#12,965,000, 2021-08-05)
4646
London,
47+
/// Paris - The Merge (#15,537,394, 2022-09-15)
48+
Merge,
49+
/// Shanghai (#17,034,870, 2023-04-12)
50+
Shanghai,
51+
4752
/// Byzantium transition test-net
4853
EIP158ToByzantiumAt5,
4954
/// Homestead transition test-net
@@ -58,6 +63,17 @@ pub enum ForkSpec {
5863
ConstantinopleFixToIstanbulAt5,
5964
}
6065

66+
impl ForkSpec {
67+
/// Returns true if the fork is at or after the merge.
68+
pub fn is_eth2(&self) -> bool {
69+
// NOTE: Include new forks in this match arm.
70+
matches!(
71+
*self,
72+
ForkSpec::London | ForkSpec::Merge | ForkSpec::Shanghai
73+
)
74+
}
75+
}
76+
6177
/// Spec deserialization.
6278
#[derive(Debug, PartialEq, Deserialize)]
6379
#[serde(deny_unknown_fields)]

ethjson/src/vm.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ pub struct Env {
121121
#[serde(rename = "currentBaseFee")]
122122
#[serde(default)]
123123
pub block_base_fee_per_gas: Uint,
124+
/// Pre-seeded random value for testing
125+
#[serde(rename = "currentRandom")]
126+
#[serde(default)]
127+
pub random: Option<Uint>,
124128
}
125129

126130
#[cfg(test)]
@@ -145,7 +149,8 @@ mod tests {
145149
"currentDifficulty" : "0x0100",
146150
"currentGasLimit" : "0x0f4240",
147151
"currentNumber" : "0x00",
148-
"currentTimestamp" : "0x01"
152+
"currentTimestamp" : "0x01",
153+
"currentRandom" : "0x01"
149154
},
150155
"exec" : {
151156
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
@@ -192,7 +197,8 @@ mod tests {
192197
gas_limit: Uint(0x0f4240.into()),
193198
number: Uint(0.into()),
194199
timestamp: Uint(1.into()),
195-
block_base_fee_per_gas: Uint(0.into())
200+
block_base_fee_per_gas: Uint(0.into()),
201+
random: Some(Uint(1.into())),
196202
}
197203
);
198204
assert_eq!(

jsontests/res/ethtests

jsontests/src/state.rs

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ impl Test {
2323
}
2424

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

34-
H160::from(H256::from_slice(Keccak256::digest(&res).as_slice()))
34+
H160::from(H256::from_slice(Keccak256::digest(res).as_slice()))
3535
}
3636

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

73+
let block_randomness = if spec.is_eth2() {
74+
self.0.env.random.map(|r| {
75+
// Convert between U256 and H256. U256 is in little-endian but since H256 is just
76+
// a string-like byte array, it's big endian (MSB is the first element of the array).
77+
//
78+
// Byte order here is important because this opcode has the same value as DIFFICULTY
79+
// (0x44), and so for older forks of Ethereum, the threshold value of 2^64 is used to
80+
// distinguish between the two: if it's below, the value corresponds to the DIFFICULTY
81+
// opcode, otherwise to the PREVRANDAO opcode.
82+
let mut buf = [0u8; 32];
83+
r.0.to_big_endian(&mut buf);
84+
H256(buf)
85+
})
86+
} else {
87+
None
88+
};
89+
90+
7391
Some(MemoryVicinity {
7492
gas_price,
7593
origin: self.unwrap_caller(),
7694
block_hashes: Vec::new(),
77-
block_number: self.0.env.number.clone().into(),
78-
block_coinbase: self.0.env.author.clone().into(),
79-
block_timestamp: self.0.env.timestamp.clone().into(),
80-
block_difficulty: self.0.env.difficulty.clone().into(),
81-
block_gas_limit: self.0.env.gas_limit.clone().into(),
95+
block_number: self.0.env.number.into(),
96+
block_coinbase: self.0.env.author.into(),
97+
block_timestamp: self.0.env.timestamp.into(),
98+
block_difficulty: self.0.env.difficulty.into(),
99+
block_gas_limit: self.0.env.gas_limit.into(),
82100
chain_id: U256::one(),
83101
block_base_fee_per_gas,
102+
block_randomness,
84103
})
85104
}
86105
}
@@ -139,6 +158,10 @@ impl JsonPrecompile {
139158
}
140159
// precompiles for London and Berlin are the same
141160
ForkSpec::London => Self::precompile(&ForkSpec::Berlin),
161+
// precompiles for Merge and Berlin are the same
162+
ForkSpec::Merge => Self::precompile(&ForkSpec::Berlin),
163+
// precompiles for Shanghai and Berlin are the same
164+
ForkSpec::Shanghai => Self::precompile(&ForkSpec::Berlin),
142165
_ => None,
143166
}
144167
}
@@ -211,8 +234,10 @@ fn test_run(name: &str, test: Test) {
211234
ethjson::spec::ForkSpec::Istanbul => (Config::istanbul(), true),
212235
ethjson::spec::ForkSpec::Berlin => (Config::berlin(), true),
213236
ethjson::spec::ForkSpec::London => (Config::london(), true),
237+
ethjson::spec::ForkSpec::Merge => (Config::merge(), true),
238+
ethjson::spec::ForkSpec::Shanghai => (Config::shanghai(), true),
214239
spec => {
215-
println!("Skip spec {:?}", spec);
240+
println!("Skip spec {spec:?}");
216241
continue;
217242
}
218243
};
@@ -288,8 +313,9 @@ fn test_run(name: &str, test: Test) {
288313
}
289314

290315
let actual_fee = executor.fee(vicinity.gas_price);
291-
let mniner_reward = if let ForkSpec::London = spec {
292-
// see EIP-1559
316+
// Forks after London burn miner rewards and thus have different gas fee
317+
// calculation (see EIP-1559)
318+
let miner_reward = if spec.is_eth2() {
293319
let max_priority_fee_per_gas = test.0.transaction.max_priority_fee_per_gas();
294320
let max_fee_per_gas = test.0.transaction.max_fee_per_gas();
295321
let base_fee_per_gas = vicinity.block_base_fee_per_gas;
@@ -299,11 +325,14 @@ fn test_run(name: &str, test: Test) {
299325
} else {
300326
actual_fee
301327
};
328+
302329
executor
303330
.state_mut()
304-
.deposit(vicinity.block_coinbase, mniner_reward);
331+
.deposit(vicinity.block_coinbase, miner_reward);
305332
executor.state_mut().deposit(caller, total_fee - actual_fee);
333+
306334
let (values, logs) = executor.into_state().deconstruct();
335+
307336
backend.apply(values, logs, delete_empty);
308337
}
309338

jsontests/src/utils.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ pub fn assert_valid_hash(h: &H256, b: &BTreeMap<H160, MemoryAccount>) {
144144
.collect::<Vec<_>>();
145145

146146
let root = ethereum::util::sec_trie_root(tree);
147-
let expect = h.clone().into();
147+
let expect = h;
148148

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

160-
io::stdout().flush().ok().expect("Could not flush stdout");
160+
io::stdout().flush().expect("Could not flush stdout");
161161
}
162162

163163
pub mod transaction {

jsontests/src/vm.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::utils::*;
22
use evm::backend::{ApplyBackend, MemoryAccount, MemoryBackend, MemoryVicinity};
33
use evm::executor::stack::{MemoryStackState, StackExecutor, StackSubstateMetadata};
44
use evm::Config;
5-
use primitive_types::{H160, U256};
5+
use primitive_types::{H160, H256, U256};
66
use serde::Deserialize;
77
use std::collections::BTreeMap;
88
use std::rc::Rc;
@@ -16,6 +16,19 @@ impl Test {
1616
}
1717

1818
pub fn unwrap_to_vicinity(&self) -> MemoryVicinity {
19+
let block_randomness = self.0.env.random.map(|r| {
20+
// Convert between U256 and H256. U256 is in little-endian but since H256 is just
21+
// a string-like byte array, it's big endian (MSB is the first element of the array).
22+
//
23+
// Byte order here is important because this opcode has the same value as DIFFICULTY
24+
// (0x44), and so for older forks of Ethereum, the threshold value of 2^64 is used to
25+
// distinguish between the two: if it's below, the value corresponds to the DIFFICULTY
26+
// opcode, otherwise to the PREVRANDAO opcode.
27+
let mut buf = [0u8; 32];
28+
r.0.to_big_endian(&mut buf);
29+
H256(buf)
30+
});
31+
1932
MemoryVicinity {
2033
gas_price: self.0.transaction.gas_price.clone().into(),
2134
origin: self.0.transaction.origin.clone().into(),
@@ -27,6 +40,7 @@ impl Test {
2740
block_gas_limit: self.0.env.gas_limit.clone().into(),
2841
chain_id: U256::zero(),
2942
block_base_fee_per_gas: self.0.transaction.gas_price.clone().into(),
43+
block_randomness,
3044
}
3145
}
3246

@@ -75,7 +89,8 @@ pub fn test(name: &str, test: Test) {
7589
let code = test.unwrap_to_code();
7690
let data = test.unwrap_to_data();
7791
let context = test.unwrap_to_context();
78-
let mut runtime = evm::Runtime::new(code, data, context, config.stack_limit, config.memory_limit);
92+
let mut runtime =
93+
evm::Runtime::new(code, data, context, config.stack_limit, config.memory_limit);
7994

8095
let reason = executor.execute(&mut runtime);
8196
let gas = executor.gas();

jsontests/tests/state.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub fn run(dir: &str) {
1313
for entry in fs::read_dir(dest).unwrap() {
1414
let entry = entry.unwrap();
1515
if let Some(s) = entry.file_name().to_str() {
16-
if s.starts_with(".") {
16+
if s.starts_with('.') {
1717
continue;
1818
}
1919
}
@@ -23,8 +23,8 @@ pub fn run(dir: &str) {
2323
let file = File::open(path).expect("Open file failed");
2424

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

2929
for (name, test) in coll {
3030
statetests::test(&name, test);

0 commit comments

Comments
 (0)