Skip to content

Commit 51b8c2c

Browse files
authored
ExitError specify invalid opcode (#126)
* `ExitError` specify invalid opcode * Do not early return, propagate instead * `InvalidCode(Opcode)` * Use const * Use constant * clippy * Revert "Use const" This reverts commit 1c669ab. * Add 0xef const
1 parent 01bcbd2 commit 51b8c2c

File tree

5 files changed

+26
-20
lines changed

5 files changed

+26
-20
lines changed

core/src/error.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ pub enum ExitError {
127127
/// Create init code exceeds limit (runtime).
128128
#[cfg_attr(feature = "with-codec", codec(index = 7))]
129129
CreateContractLimit,
130-
/// Starting byte must not begin with 0xef. See [EIP-3541](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3541.md).
131-
#[cfg_attr(feature = "with-codec", codec(index = 14))]
132-
InvalidCode,
130+
/// Invalid opcode during execution or starting byte is 0xef. See [EIP-3541](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3541.md).
131+
#[cfg_attr(feature = "with-codec", codec(index = 15))]
132+
InvalidCode(Opcode),
133133

134134
/// An opcode accesses external information, but the request is off offset
135135
/// limit (runtime).

core/src/opcode.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
/// Opcode enum. One-to-one corresponding to an `u8` value.
22
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3+
#[cfg_attr(
4+
feature = "with-codec",
5+
derive(codec::Encode, codec::Decode, scale_info::TypeInfo)
6+
)]
7+
#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))]
38
pub struct Opcode(pub u8);
49

510
// Core opcodes.
@@ -166,6 +171,9 @@ impl Opcode {
166171

167172
/// `INVALID`
168173
pub const INVALID: Opcode = Opcode(0xfe);
174+
175+
/// See [EIP-3541](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3541.md)
176+
pub const EOFMAGIC: Opcode = Opcode(0xef);
169177
}
170178

171179
// External opcodes

gasometer/src/lib.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -450,19 +450,19 @@ pub fn dynamic_opcode_cost<H: Handler>(
450450
Opcode::MLOAD | Opcode::MSTORE | Opcode::MSTORE8 => GasCost::VeryLow,
451451

452452
Opcode::REVERT if config.has_revert => GasCost::Zero,
453-
Opcode::REVERT => GasCost::Invalid,
453+
Opcode::REVERT => GasCost::Invalid(opcode),
454454

455455
Opcode::CHAINID if config.has_chain_id => GasCost::Base,
456-
Opcode::CHAINID => GasCost::Invalid,
456+
Opcode::CHAINID => GasCost::Invalid(opcode),
457457

458458
Opcode::SHL | Opcode::SHR | Opcode::SAR if config.has_bitwise_shifting => GasCost::VeryLow,
459-
Opcode::SHL | Opcode::SHR | Opcode::SAR => GasCost::Invalid,
459+
Opcode::SHL | Opcode::SHR | Opcode::SAR => GasCost::Invalid(opcode),
460460

461461
Opcode::SELFBALANCE if config.has_self_balance => GasCost::Low,
462-
Opcode::SELFBALANCE => GasCost::Invalid,
462+
Opcode::SELFBALANCE => GasCost::Invalid(opcode),
463463

464464
Opcode::BASEFEE if config.has_base_fee => GasCost::Base,
465-
Opcode::BASEFEE => GasCost::Invalid,
465+
Opcode::BASEFEE => GasCost::Invalid(opcode),
466466

467467
Opcode::EXTCODESIZE => {
468468
let target = stack.peek(0)?.into();
@@ -487,7 +487,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
487487
target_is_cold: handler.is_cold(target, None),
488488
}
489489
}
490-
Opcode::EXTCODEHASH => GasCost::Invalid,
490+
Opcode::EXTCODEHASH => GasCost::Invalid(opcode),
491491

492492
Opcode::CALLCODE => {
493493
let target = stack.peek(1)?.into();
@@ -542,13 +542,13 @@ pub fn dynamic_opcode_cost<H: Handler>(
542542
target_exists: handler.exists(target),
543543
}
544544
}
545-
Opcode::DELEGATECALL => GasCost::Invalid,
545+
Opcode::DELEGATECALL => GasCost::Invalid(opcode),
546546

547547
Opcode::RETURNDATASIZE if config.has_return_data => GasCost::Base,
548548
Opcode::RETURNDATACOPY if config.has_return_data => GasCost::VeryLowCopy {
549549
len: U256::from_big_endian(&stack.peek(2)?[..]),
550550
},
551-
Opcode::RETURNDATASIZE | Opcode::RETURNDATACOPY => GasCost::Invalid,
551+
Opcode::RETURNDATASIZE | Opcode::RETURNDATACOPY => GasCost::Invalid(opcode),
552552

553553
Opcode::SSTORE if !is_static => {
554554
let index = stack.peek(0)?;
@@ -610,7 +610,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
610610
}
611611
}
612612

613-
_ => GasCost::Invalid,
613+
_ => GasCost::Invalid(opcode),
614614
};
615615

616616
let memory_cost = match opcode {
@@ -801,7 +801,7 @@ impl<'config> Inner<'config> {
801801
GasCost::Base => consts::G_BASE,
802802
GasCost::VeryLow => consts::G_VERYLOW,
803803
GasCost::Low => consts::G_LOW,
804-
GasCost::Invalid => return Err(ExitError::OutOfGas),
804+
GasCost::Invalid(opcode) => return Err(ExitError::InvalidCode(opcode)),
805805

806806
GasCost::ExtCodeSize { target_is_cold } => {
807807
costs::address_access_cost(target_is_cold, self.config.gas_ext_code, self.config)
@@ -852,7 +852,7 @@ pub enum GasCost {
852852
/// Low gas cost.
853853
Low,
854854
/// Fail the gasometer.
855-
Invalid,
855+
Invalid(Opcode),
856856

857857
/// Gas cost for `EXTCODESIZE`.
858858
ExtCodeSize {

runtime/src/handler.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ pub trait Handler {
115115
stack: &Stack,
116116
) -> Result<(), ExitError>;
117117
/// Handle other unknown external opcodes.
118-
fn other(&mut self, _opcode: Opcode, _stack: &mut Machine) -> Result<(), ExitError> {
119-
Err(ExitError::OutOfGas)
118+
fn other(&mut self, opcode: Opcode, _stack: &mut Machine) -> Result<(), ExitError> {
119+
Err(ExitError::InvalidCode(opcode))
120120
}
121121
}

src/executor/stack/executor.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -646,10 +646,8 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet>
646646
}
647647

648648
fn check_first_byte(config: &Config, code: &[u8]) -> Result<(), ExitError> {
649-
if config.disallow_executable_format {
650-
if let Some(0xef) = code.get(0) {
651-
return Err(ExitError::InvalidCode);
652-
}
649+
if config.disallow_executable_format && Some(&Opcode::EOFMAGIC.as_u8()) == code.get(0) {
650+
return Err(ExitError::InvalidCode(Opcode::EOFMAGIC));
653651
}
654652
Ok(())
655653
}

0 commit comments

Comments
 (0)