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

Commit c1e6512

Browse files
authored
Merge pull request #21 from mandreyel/fix/missing-eip-2718
fix: missing EIP-2718 support checking tx type
2 parents 54947fc + 4a66053 commit c1e6512

File tree

6 files changed

+72
-19
lines changed

6 files changed

+72
-19
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ethjson/src/test_helpers/state.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl MultiTransaction {
130130
r: Default::default(),
131131
s: Default::default(),
132132
v: Default::default(),
133-
secret: self.secret.clone(),
133+
secret: self.secret,
134134
access_list,
135135
}
136136
}
@@ -163,11 +163,16 @@ pub struct PostStateIndexes {
163163

164164
/// State test indexed state result deserialization.
165165
#[derive(Debug, PartialEq, Deserialize)]
166+
#[serde(rename_all = "camelCase")]
166167
pub struct PostStateResult {
167168
/// Post state hash
168169
pub hash: H256,
169170
/// Indexes
170171
pub indexes: PostStateIndexes,
172+
/// Expected error if the test is meant to fail
173+
pub expect_exception: Option<String>,
174+
/// Transaction bytes
175+
pub txbytes: Bytes,
171176
}
172177

173178
#[cfg(test)]
@@ -204,20 +209,24 @@ mod tests {
204209
"EIP150": [
205210
{
206211
"hash": "3e6dacc1575c6a8c76422255eca03529bbf4c0dda75dfc110b22d6dc4152396f",
212+
"txbytes" : "0xf861800a84042c1d8094b94f5374fce5edbc8e2a8697c15331677e6ebf0b80801ca0f141d67812db948c9a4ea43c27d695248205c121ae8d924d23517ab09e38f369a03fe3cfedb4c9a7e61340b6fec87917690e92082f752ad820ad5006c7d49185ed",
207213
"indexes": { "data": 0, "gas": 0, "value": 0 }
208214
},
209215
{
210216
"hash": "99a450d8ce5b987a71346d8a0a1203711f770745c7ef326912e46761f14cd764",
217+
"txbytes" : "0xf861800a84042c1d8094b94f5374fce5edbc8e2a8697c15331677e6ebf0b80801ca0f141d67812db948c9a4ea43c27d695248205c121ae8d924d23517ab09e38f369a03fe3cfedb4c9a7e61340b6fec87917690e92082f752ad820ad5006c7d49185ed",
211218
"indexes": { "data": 0, "gas": 0, "value": 1 }
212219
}
213220
],
214221
"EIP158": [
215222
{
216223
"hash": "3e6dacc1575c6a8c76422255eca03529bbf4c0dda75dfc110b22d6dc4152396f",
224+
"txbytes" : "0xf861800a84042c1d8094b94f5374fce5edbc8e2a8697c15331677e6ebf0b80801ca0f141d67812db948c9a4ea43c27d695248205c121ae8d924d23517ab09e38f369a03fe3cfedb4c9a7e61340b6fec87917690e92082f752ad820ad5006c7d49185ed",
217225
"indexes": { "data": 0, "gas": 0, "value": 0 }
218226
},
219227
{
220228
"hash": "99a450d8ce5b987a71346d8a0a1203711f770745c7ef326912e46761f14cd764",
229+
"txbytes" : "0xf861800a84042c1d8094b94f5374fce5edbc8e2a8697c15331677e6ebf0b80801ca0f141d67812db948c9a4ea43c27d695248205c121ae8d924d23517ab09e38f369a03fe3cfedb4c9a7e61340b6fec87917690e92082f752ad820ad5006c7d49185ed",
221230
"indexes": { "data": 0, "gas": 0, "value": 1 }
222231
}
223232
]

evm

Submodule evm updated from 01bcbd2 to e7138f7

jsontests/res/ethtests

jsontests/src/state.rs

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,19 @@ impl Test {
7272

7373
let block_randomness = if spec.is_eth2() {
7474
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-
})
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+
u256_to_h256(r.0)
83+
})
8684
} else {
8785
None
8886
};
8987

90-
9188
Some(MemoryVicinity {
9289
gas_price,
9390
origin: self.unwrap_caller(),
@@ -261,6 +258,25 @@ fn test_run(name: &str, test: Test) {
261258
let transaction = test.0.transaction.select(&state.indexes);
262259
let mut backend = MemoryBackend::new(&vicinity, original_state.clone());
263260

261+
// Test case may be expected to fail with an unsupported tx type if the current fork is
262+
// older than Berlin (see EIP-2718). However, this is not implemented in sputnik itself and rather
263+
// in the code hosting sputnik. https://github.com/rust-blockchain/evm/pull/40
264+
let tx_type = TxType::from_txbytes(&state.txbytes);
265+
if matches!(
266+
spec,
267+
ForkSpec::EIP150
268+
| ForkSpec::EIP158 | ForkSpec::Frontier
269+
| ForkSpec::Homestead
270+
| ForkSpec::Byzantium
271+
| ForkSpec::Constantinople
272+
| ForkSpec::ConstantinopleFix
273+
| ForkSpec::Istanbul
274+
) && tx_type != TxType::Legacy
275+
&& state.expect_exception == Some("TR_TypeNotSupported".to_string())
276+
{
277+
continue;
278+
}
279+
264280
// Only execute valid transactions
265281
if let Ok(transaction) = crate::utils::transaction::validate(
266282
transaction,
@@ -342,3 +358,31 @@ fn test_run(name: &str, test: Test) {
342358
}
343359
}
344360
}
361+
362+
/// Denotes the type of transaction.
363+
#[derive(Debug, PartialEq)]
364+
enum TxType {
365+
/// All transactions before EIP-2718 are legacy.
366+
Legacy,
367+
/// https://eips.ethereum.org/EIPS/eip-2718
368+
AccessList,
369+
/// https://eips.ethereum.org/EIPS/eip-1559
370+
DynamicFee,
371+
}
372+
373+
impl TxType {
374+
/// Whether this is a legacy, access list, dynamic fee, etc transaction
375+
// Taken from geth's core/types/transaction.go/UnmarshalBinary, but we only detect the transaction
376+
// type rather than unmarshal the entire payload.
377+
fn from_txbytes(txbytes: &[u8]) -> Self {
378+
match txbytes[0] {
379+
b if b > 0x7f => Self::Legacy,
380+
1 => Self::AccessList,
381+
2 => Self::DynamicFee,
382+
_ => panic!(
383+
"Unknown tx type. \
384+
You may need to update the TxType enum if Ethereum introduced new enveloped transaction types."
385+
),
386+
}
387+
}
388+
}

jsontests/src/utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub fn u256_to_h256(u: U256) -> H256 {
1212
pub fn unwrap_to_account(s: &ethjson::spec::Account) -> MemoryAccount {
1313
MemoryAccount {
1414
balance: s.balance.clone().unwrap().into(),
15-
nonce: s.nonce.clone().unwrap().into(),
15+
nonce: s.nonce.unwrap().0.as_u64(),
1616
code: s.code.clone().unwrap().into(),
1717
storage: s
1818
.storage
@@ -48,7 +48,7 @@ pub fn unwrap_to_state(a: &ethjson::spec::State) -> BTreeMap<H160, MemoryAccount
4848
#[derive(Debug, Clone, PartialEq, Eq)]
4949
pub struct TrieAccount {
5050
/// Nonce of the account.
51-
pub nonce: U256,
51+
pub nonce: u64,
5252
/// Balance of the account.
5353
pub balance: U256,
5454
/// Storage root of the account.

0 commit comments

Comments
 (0)