EIP 3541 (#422)
* 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:
		
							parent
							
								
									f14d3e5a5c
								
							
						
					
					
						commit
						144b2293a2
					
				@ -444,6 +444,7 @@ impl<'a> CallCreateExecutive<'a> {
 | 
			
		||||
            | Err(vm::Error::SubStackUnderflow { .. })
 | 
			
		||||
            | Err(vm::Error::OutOfSubStack { .. })
 | 
			
		||||
            | Err(vm::Error::InvalidSubEntry)
 | 
			
		||||
            | Err(vm::Error::InvalidCode)
 | 
			
		||||
            | Ok(FinalizationResult {
 | 
			
		||||
                apply_state: false, ..
 | 
			
		||||
            }) => {
 | 
			
		||||
 | 
			
		||||
@ -431,6 +431,12 @@ where
 | 
			
		||||
                        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
 | 
			
		||||
                    .init_code(&self.origin_info.address, data.to_vec())?;
 | 
			
		||||
                Ok(*gas - return_cost)
 | 
			
		||||
@ -913,4 +919,46 @@ mod tests {
 | 
			
		||||
            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());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -141,6 +141,8 @@ pub struct CommonParams {
 | 
			
		||||
    pub eip2930_transition: BlockNumber,
 | 
			
		||||
    /// Number of first block where EIP-3529 rules begin.
 | 
			
		||||
    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.
 | 
			
		||||
    pub dust_protection_transition: BlockNumber,
 | 
			
		||||
    /// 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.eip2929 = block_number >= self.eip2929_transition;
 | 
			
		||||
        schedule.eip2930 = block_number >= self.eip2930_transition;
 | 
			
		||||
        schedule.eip3541 = block_number >= self.eip3541_transition;
 | 
			
		||||
 | 
			
		||||
        if block_number >= self.eip1884_transition {
 | 
			
		||||
            schedule.have_selfbalance = true;
 | 
			
		||||
@ -388,6 +391,9 @@ impl From<ethjson::spec::Params> for CommonParams {
 | 
			
		||||
            eip3529_transition: p
 | 
			
		||||
                .eip3529_transition
 | 
			
		||||
                .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
 | 
			
		||||
                .map_or_else(BlockNumber::max_value, Into::into),
 | 
			
		||||
@ -678,6 +684,7 @@ impl Spec {
 | 
			
		||||
            params.eip2929_transition,
 | 
			
		||||
            params.eip2930_transition,
 | 
			
		||||
            params.eip3529_transition,
 | 
			
		||||
            params.eip3541_transition,
 | 
			
		||||
            params.dust_protection_transition,
 | 
			
		||||
            params.wasm_activation_transition,
 | 
			
		||||
            params.wasm_disable_transition,
 | 
			
		||||
 | 
			
		||||
@ -48,6 +48,8 @@ pub enum Error {
 | 
			
		||||
    Internal,
 | 
			
		||||
    /// When execution tries to modify the state in static context
 | 
			
		||||
    MutableCallInStaticContext,
 | 
			
		||||
    /// When invalid code was attempted to deploy
 | 
			
		||||
    InvalidCode,
 | 
			
		||||
    /// Wasm error
 | 
			
		||||
    Wasm,
 | 
			
		||||
    /// 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::InvalidSubEntry { .. } => Error::InvalidSubEntry,
 | 
			
		||||
            VmError::BuiltIn { .. } => Error::BuiltIn,
 | 
			
		||||
            VmError::InvalidCode => Error::InvalidCode,
 | 
			
		||||
            VmError::Wasm { .. } => Error::Wasm,
 | 
			
		||||
            VmError::Internal(_) => Error::Internal,
 | 
			
		||||
            VmError::MutableCallInStaticContext => Error::MutableCallInStaticContext,
 | 
			
		||||
@ -96,6 +99,7 @@ impl fmt::Display for Error {
 | 
			
		||||
            OutOfSubStack => "Subroutine stack overflow",
 | 
			
		||||
            BuiltIn => "Built-in failed",
 | 
			
		||||
            InvalidSubEntry => "Invalid subroutine entry",
 | 
			
		||||
            InvalidCode => "Invalid code",
 | 
			
		||||
            Wasm => "Wasm runtime error",
 | 
			
		||||
            Internal => "Internal error",
 | 
			
		||||
            MutableCallInStaticContext => "Mutable Call In Static Context",
 | 
			
		||||
@ -124,6 +128,7 @@ impl Encodable for Error {
 | 
			
		||||
            SubStackUnderflow => 11,
 | 
			
		||||
            OutOfSubStack => 12,
 | 
			
		||||
            InvalidSubEntry => 13,
 | 
			
		||||
            InvalidCode => 14,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        s.append_internal(&value);
 | 
			
		||||
@ -149,6 +154,7 @@ impl Decodable for Error {
 | 
			
		||||
            11 => Ok(SubStackUnderflow),
 | 
			
		||||
            12 => Ok(OutOfSubStack),
 | 
			
		||||
            13 => Ok(InvalidSubEntry),
 | 
			
		||||
            14 => Ok(InvalidCode),
 | 
			
		||||
            _ => Err(DecoderError::Custom("Invalid error type")),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -114,6 +114,8 @@ pub struct Params {
 | 
			
		||||
    /// See `CommonParams` docs.
 | 
			
		||||
    pub eip3529_transition: Option<Uint>,
 | 
			
		||||
    /// See `CommonParams` docs.
 | 
			
		||||
    pub eip3541_transition: Option<Uint>,
 | 
			
		||||
    /// See `CommonParams` docs.
 | 
			
		||||
    pub dust_protection_transition: Option<Uint>,
 | 
			
		||||
    /// See `CommonParams` docs.
 | 
			
		||||
    pub nonce_cap_increment: Option<Uint>,
 | 
			
		||||
 | 
			
		||||
@ -92,6 +92,8 @@ pub enum Error {
 | 
			
		||||
    BuiltIn(&'static str),
 | 
			
		||||
    /// When execution tries to modify the state in static context
 | 
			
		||||
    MutableCallInStaticContext,
 | 
			
		||||
    /// Invalid code to deploy as a contract
 | 
			
		||||
    InvalidCode,
 | 
			
		||||
    /// Likely to cause consensus issues.
 | 
			
		||||
    Internal(String),
 | 
			
		||||
    /// Wasm runtime error
 | 
			
		||||
@ -145,6 +147,7 @@ impl fmt::Display for Error {
 | 
			
		||||
            BuiltIn(name) => write!(f, "Built-in failed: {}", name),
 | 
			
		||||
            Internal(ref msg) => write!(f, "Internal error: {}", msg),
 | 
			
		||||
            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),
 | 
			
		||||
            OutOfBounds => write!(f, "Out of bounds"),
 | 
			
		||||
            Reverted => write!(f, "Reverted"),
 | 
			
		||||
 | 
			
		||||
@ -163,6 +163,8 @@ pub struct Schedule {
 | 
			
		||||
    pub eip2930: bool,
 | 
			
		||||
    /// Gas used in transaction divided by this number is the maximum refundable amount.
 | 
			
		||||
    pub max_refund_quotient: usize,
 | 
			
		||||
    // Enable EIP-3541 rule
 | 
			
		||||
    pub eip3541: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Wasm cost table
 | 
			
		||||
@ -311,6 +313,7 @@ impl Schedule {
 | 
			
		||||
            eip2929: false,
 | 
			
		||||
            eip2930: false,
 | 
			
		||||
            max_refund_quotient: MAX_REFUND_QUOTIENT,
 | 
			
		||||
            eip3541: false,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -376,6 +379,8 @@ impl Schedule {
 | 
			
		||||
        schedule.sstore_refund_gas = EIP3529_SSTORE_CLEARS_SCHEDULE;
 | 
			
		||||
        schedule.max_refund_quotient = EIP3529_MAX_REFUND_QUOTIENT;
 | 
			
		||||
 | 
			
		||||
        schedule.eip3541 = true;
 | 
			
		||||
 | 
			
		||||
        schedule
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -443,6 +448,7 @@ impl Schedule {
 | 
			
		||||
            eip2929: false,
 | 
			
		||||
            eip2930: false,
 | 
			
		||||
            max_refund_quotient: MAX_REFUND_QUOTIENT,
 | 
			
		||||
            eip3541: false,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user