* Add EIP-3541 transition block parameter

* Implement EIP-3541

* Add a unit test for EIP-3541

* Add error type for attempt to deploy invalid code

* fmt
This commit is contained in:
Jochen Müller 2021-05-31 14:37:23 +02:00 committed by GitHub
parent f14d3e5a5c
commit 144b2293a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 0 deletions

View File

@ -444,6 +444,7 @@ impl<'a> CallCreateExecutive<'a> {
| Err(vm::Error::SubStackUnderflow { .. }) | Err(vm::Error::SubStackUnderflow { .. })
| Err(vm::Error::OutOfSubStack { .. }) | Err(vm::Error::OutOfSubStack { .. })
| Err(vm::Error::InvalidSubEntry) | Err(vm::Error::InvalidSubEntry)
| Err(vm::Error::InvalidCode)
| Ok(FinalizationResult { | Ok(FinalizationResult {
apply_state: false, .. apply_state: false, ..
}) => { }) => {

View File

@ -431,6 +431,12 @@ where
false => Ok(*gas), false => Ok(*gas),
}; };
} }
if self.schedule.eip3541 && data.get(0) == Some(&0xefu8) {
return match self.schedule.exceptional_failed_code_deposit {
true => Err(vm::Error::InvalidCode),
false => Ok(*gas),
};
}
self.state self.state
.init_code(&self.origin_info.address, data.to_vec())?; .init_code(&self.origin_info.address, data.to_vec())?;
Ok(*gas - return_cost) Ok(*gas - return_cost)
@ -913,4 +919,46 @@ mod tests {
Address::from_str("e33c0c7f7df4809055c3eba6c09cfe4baf1bd9e0").unwrap() Address::from_str("e33c0c7f7df4809055c3eba6c09cfe4baf1bd9e0").unwrap()
); );
} }
#[test]
fn eip_3541() {
let call_ret = |schedule: Schedule, data: &ReturnData| {
let mut setup = TestSetup::default();
setup.schedule = schedule;
let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer;
let origin = get_test_origin();
let ext = Externalities::new(
&mut setup.state,
&setup.env_info,
&setup.machine,
&setup.schedule,
0,
0,
&origin,
&mut setup.sub_state,
OutputPolicy::InitContract,
&mut tracer,
&mut vm_tracer,
false,
);
ext.ret(&U256::from(10000), &data, true)
};
let data = ReturnData::new(vec![0xefu8], 0, 1);
let result = call_ret(Schedule::new_berlin(), &data);
assert!(result.is_ok());
let result = call_ret(Schedule::new_london(), &data);
assert!(result.is_err());
let data = ReturnData::new(vec![0xefu8, 0x00u8, 0x00u8], 0, 3);
let result = call_ret(Schedule::new_london(), &data);
assert!(result.is_err());
let data = ReturnData::new(vec![0xee], 0, 1);
let result = call_ret(Schedule::new_london(), &data);
assert!(result.is_ok());
}
} }

View File

@ -141,6 +141,8 @@ pub struct CommonParams {
pub eip2930_transition: BlockNumber, pub eip2930_transition: BlockNumber,
/// Number of first block where EIP-3529 rules begin. /// Number of first block where EIP-3529 rules begin.
pub eip3529_transition: BlockNumber, pub eip3529_transition: BlockNumber,
/// Number of first block where EIP-3541 rule begins.
pub eip3541_transition: BlockNumber,
/// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin. /// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin.
pub dust_protection_transition: BlockNumber, pub dust_protection_transition: BlockNumber,
/// Nonce cap increase per block. Nonce cap is only checked if dust protection is enabled. /// Nonce cap increase per block. Nonce cap is only checked if dust protection is enabled.
@ -217,6 +219,7 @@ impl CommonParams {
schedule.have_subs = block_number >= self.eip2315_transition; schedule.have_subs = block_number >= self.eip2315_transition;
schedule.eip2929 = block_number >= self.eip2929_transition; schedule.eip2929 = block_number >= self.eip2929_transition;
schedule.eip2930 = block_number >= self.eip2930_transition; schedule.eip2930 = block_number >= self.eip2930_transition;
schedule.eip3541 = block_number >= self.eip3541_transition;
if block_number >= self.eip1884_transition { if block_number >= self.eip1884_transition {
schedule.have_selfbalance = true; schedule.have_selfbalance = true;
@ -388,6 +391,9 @@ impl From<ethjson::spec::Params> for CommonParams {
eip3529_transition: p eip3529_transition: p
.eip3529_transition .eip3529_transition
.map_or_else(BlockNumber::max_value, Into::into), .map_or_else(BlockNumber::max_value, Into::into),
eip3541_transition: p
.eip3541_transition
.map_or_else(BlockNumber::max_value, Into::into),
dust_protection_transition: p dust_protection_transition: p
.dust_protection_transition .dust_protection_transition
.map_or_else(BlockNumber::max_value, Into::into), .map_or_else(BlockNumber::max_value, Into::into),
@ -678,6 +684,7 @@ impl Spec {
params.eip2929_transition, params.eip2929_transition,
params.eip2930_transition, params.eip2930_transition,
params.eip3529_transition, params.eip3529_transition,
params.eip3541_transition,
params.dust_protection_transition, params.dust_protection_transition,
params.wasm_activation_transition, params.wasm_activation_transition,
params.wasm_disable_transition, params.wasm_disable_transition,

View File

@ -48,6 +48,8 @@ pub enum Error {
Internal, Internal,
/// When execution tries to modify the state in static context /// When execution tries to modify the state in static context
MutableCallInStaticContext, MutableCallInStaticContext,
/// When invalid code was attempted to deploy
InvalidCode,
/// Wasm error /// Wasm error
Wasm, Wasm,
/// Contract tried to access past the return data buffer. /// Contract tried to access past the return data buffer.
@ -68,6 +70,7 @@ impl<'a> From<&'a VmError> for Error {
VmError::OutOfSubStack { .. } => Error::OutOfSubStack, VmError::OutOfSubStack { .. } => Error::OutOfSubStack,
VmError::InvalidSubEntry { .. } => Error::InvalidSubEntry, VmError::InvalidSubEntry { .. } => Error::InvalidSubEntry,
VmError::BuiltIn { .. } => Error::BuiltIn, VmError::BuiltIn { .. } => Error::BuiltIn,
VmError::InvalidCode => Error::InvalidCode,
VmError::Wasm { .. } => Error::Wasm, VmError::Wasm { .. } => Error::Wasm,
VmError::Internal(_) => Error::Internal, VmError::Internal(_) => Error::Internal,
VmError::MutableCallInStaticContext => Error::MutableCallInStaticContext, VmError::MutableCallInStaticContext => Error::MutableCallInStaticContext,
@ -96,6 +99,7 @@ impl fmt::Display for Error {
OutOfSubStack => "Subroutine stack overflow", OutOfSubStack => "Subroutine stack overflow",
BuiltIn => "Built-in failed", BuiltIn => "Built-in failed",
InvalidSubEntry => "Invalid subroutine entry", InvalidSubEntry => "Invalid subroutine entry",
InvalidCode => "Invalid code",
Wasm => "Wasm runtime error", Wasm => "Wasm runtime error",
Internal => "Internal error", Internal => "Internal error",
MutableCallInStaticContext => "Mutable Call In Static Context", MutableCallInStaticContext => "Mutable Call In Static Context",
@ -124,6 +128,7 @@ impl Encodable for Error {
SubStackUnderflow => 11, SubStackUnderflow => 11,
OutOfSubStack => 12, OutOfSubStack => 12,
InvalidSubEntry => 13, InvalidSubEntry => 13,
InvalidCode => 14,
}; };
s.append_internal(&value); s.append_internal(&value);
@ -149,6 +154,7 @@ impl Decodable for Error {
11 => Ok(SubStackUnderflow), 11 => Ok(SubStackUnderflow),
12 => Ok(OutOfSubStack), 12 => Ok(OutOfSubStack),
13 => Ok(InvalidSubEntry), 13 => Ok(InvalidSubEntry),
14 => Ok(InvalidCode),
_ => Err(DecoderError::Custom("Invalid error type")), _ => Err(DecoderError::Custom("Invalid error type")),
} }
} }

View File

@ -114,6 +114,8 @@ pub struct Params {
/// See `CommonParams` docs. /// See `CommonParams` docs.
pub eip3529_transition: Option<Uint>, pub eip3529_transition: Option<Uint>,
/// See `CommonParams` docs. /// See `CommonParams` docs.
pub eip3541_transition: Option<Uint>,
/// See `CommonParams` docs.
pub dust_protection_transition: Option<Uint>, pub dust_protection_transition: Option<Uint>,
/// See `CommonParams` docs. /// See `CommonParams` docs.
pub nonce_cap_increment: Option<Uint>, pub nonce_cap_increment: Option<Uint>,

View File

@ -92,6 +92,8 @@ pub enum Error {
BuiltIn(&'static str), BuiltIn(&'static str),
/// When execution tries to modify the state in static context /// When execution tries to modify the state in static context
MutableCallInStaticContext, MutableCallInStaticContext,
/// Invalid code to deploy as a contract
InvalidCode,
/// Likely to cause consensus issues. /// Likely to cause consensus issues.
Internal(String), Internal(String),
/// Wasm runtime error /// Wasm runtime error
@ -145,6 +147,7 @@ impl fmt::Display for Error {
BuiltIn(name) => write!(f, "Built-in failed: {}", name), BuiltIn(name) => write!(f, "Built-in failed: {}", name),
Internal(ref msg) => write!(f, "Internal error: {}", msg), Internal(ref msg) => write!(f, "Internal error: {}", msg),
MutableCallInStaticContext => write!(f, "Mutable call in static context"), MutableCallInStaticContext => write!(f, "Mutable call in static context"),
InvalidCode => write!(f, "Invalid code to deploy as a contract"),
Wasm(ref msg) => write!(f, "Internal error: {}", msg), Wasm(ref msg) => write!(f, "Internal error: {}", msg),
OutOfBounds => write!(f, "Out of bounds"), OutOfBounds => write!(f, "Out of bounds"),
Reverted => write!(f, "Reverted"), Reverted => write!(f, "Reverted"),

View File

@ -163,6 +163,8 @@ pub struct Schedule {
pub eip2930: bool, pub eip2930: bool,
/// Gas used in transaction divided by this number is the maximum refundable amount. /// Gas used in transaction divided by this number is the maximum refundable amount.
pub max_refund_quotient: usize, pub max_refund_quotient: usize,
// Enable EIP-3541 rule
pub eip3541: bool,
} }
/// Wasm cost table /// Wasm cost table
@ -311,6 +313,7 @@ impl Schedule {
eip2929: false, eip2929: false,
eip2930: false, eip2930: false,
max_refund_quotient: MAX_REFUND_QUOTIENT, max_refund_quotient: MAX_REFUND_QUOTIENT,
eip3541: false,
} }
} }
@ -376,6 +379,8 @@ impl Schedule {
schedule.sstore_refund_gas = EIP3529_SSTORE_CLEARS_SCHEDULE; schedule.sstore_refund_gas = EIP3529_SSTORE_CLEARS_SCHEDULE;
schedule.max_refund_quotient = EIP3529_MAX_REFUND_QUOTIENT; schedule.max_refund_quotient = EIP3529_MAX_REFUND_QUOTIENT;
schedule.eip3541 = true;
schedule schedule
} }
@ -443,6 +448,7 @@ impl Schedule {
eip2929: false, eip2929: false,
eip2930: false, eip2930: false,
max_refund_quotient: MAX_REFUND_QUOTIENT, max_refund_quotient: MAX_REFUND_QUOTIENT,
eip3541: false,
} }
} }