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

Commit

Permalink
fix: missing EIP-2718 support checking tx type
Browse files Browse the repository at this point in the history
  • Loading branch information
vimpunk committed May 9, 2023
1 parent 54947fc commit 08fdea3
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 17 deletions.
8 changes: 6 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion ethjson/src/test_helpers/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl MultiTransaction {
r: Default::default(),
s: Default::default(),
v: Default::default(),
secret: self.secret.clone(),
secret: self.secret,
access_list,
}
}
Expand Down Expand Up @@ -163,11 +163,16 @@ pub struct PostStateIndexes {

/// State test indexed state result deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PostStateResult {
/// Post state hash
pub hash: H256,
/// Indexes
pub indexes: PostStateIndexes,
/// Expected error if the test is meant to fail
pub expect_exception: Option<String>,
/// Transaction bytes
pub txbytes: Bytes,
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion evm
Submodule evm updated from 01bcbd to e7138f
2 changes: 1 addition & 1 deletion jsontests/res/ethtests
70 changes: 58 additions & 12 deletions jsontests/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,21 @@ impl Test {

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)
})
// 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(),
Expand Down Expand Up @@ -261,6 +260,25 @@ fn test_run(name: &str, test: Test) {
let transaction = test.0.transaction.select(&state.indexes);
let mut backend = MemoryBackend::new(&vicinity, original_state.clone());

// Test case may be expected to fail with an unsupported tx type if the current fork is
// older than Berlin (see EIP-2718). However, this is not implemented in sputnik itself and rather
// in the code hosting sputnik. https://github.com/rust-blockchain/evm/pull/40
let tx_type = TxType::from_txbytes(&state.txbytes);
if matches!(
spec,
ForkSpec::EIP150
| ForkSpec::EIP158 | ForkSpec::Frontier
| ForkSpec::Homestead
| ForkSpec::Byzantium
| ForkSpec::Constantinople
| ForkSpec::ConstantinopleFix
| ForkSpec::Istanbul
) && tx_type != TxType::Legacy
&& state.expect_exception == Some("TR_TypeNotSupported".to_string())
{
continue;
}

// Only execute valid transactions
if let Ok(transaction) = crate::utils::transaction::validate(
transaction,
Expand Down Expand Up @@ -342,3 +360,31 @@ fn test_run(name: &str, test: Test) {
}
}
}

/// Denotes the type of transaction.
#[derive(Debug, PartialEq)]
enum TxType {
/// All transactions before EIP-2718 are legacy.
Legacy,
/// https://eips.ethereum.org/EIPS/eip-2718
AccessList,
/// https://eips.ethereum.org/EIPS/eip-1559
DynamicFee,
}

impl TxType {
/// Whether this is a legacy, access list, dynamic fee, etc transaction
// Taken from geth's core/types/transaction.go/UnmarshalBinary, but we only detect the transaction
// type rather than unmarshal the entire payload.
fn from_txbytes(txbytes: &[u8]) -> Self {
match txbytes[0] {
b if b > 0x7f => Self::Legacy,
1 => Self::AccessList,
2 => Self::DynamicFee,
_ => panic!(
"Unknown tx type. \
You may need to update the TxType enum if Ethereum introduced new enveloped transaction types."
),
}
}
}

0 comments on commit 08fdea3

Please sign in to comment.