Skip to content

Commit

Permalink
BREAKING CHANGE: deprecate SELFDESTRUCT
Browse files Browse the repository at this point in the history
  • Loading branch information
IaroslavMazur committed Dec 29, 2023
1 parent 29053e6 commit cd19eec
Show file tree
Hide file tree
Showing 24 changed files with 59 additions and 849 deletions.
26 changes: 0 additions & 26 deletions crates/interpreter/src/gas/calc.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::constants::*;
use crate::inner_models::SelfDestructResult;
use crate::primitives::{Address, Spec, SpecId::*, U256};
use alloc::vec::Vec;

Expand Down Expand Up @@ -237,31 +236,6 @@ pub fn sstore_cost<SPEC: Spec>(
}
}

pub fn selfdestruct_cost<SPEC: Spec>(res: SelfDestructResult) -> u64 {
// EIP-161: State trie clearing (invariant-preserving alternative)
let should_charge_topup = if SPEC::enabled(SPURIOUS_DRAGON) {
res.had_value && !res.target_exists
} else {
!res.target_exists
};

// EIP-150: Gas cost changes for IO-heavy operations
let selfdestruct_gas_topup = if SPEC::enabled(TANGERINE) && should_charge_topup {
25000
} else {
0
};

// EIP-150: Gas cost changes for IO-heavy operations
let selfdestruct_gas = if SPEC::enabled(TANGERINE) { 5000 } else { 0 };

let mut gas = selfdestruct_gas + selfdestruct_gas_topup;
if SPEC::enabled(BERLIN) && res.is_cold {
gas += COLD_ACCOUNT_ACCESS_COST
}
gas
}

pub fn call_cost<SPEC: Spec>(
transfers_value: bool,
is_new: bool,
Expand Down
1 change: 0 additions & 1 deletion crates/interpreter/src/gas/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ pub const LOW: u64 = 5;
pub const MID: u64 = 8;
pub const HIGH: u64 = 10;
pub const JUMPDEST: u64 = 1;
pub const SELFDESTRUCT: i64 = 24000;
pub const CREATE: u64 = 32000;
pub const CALLVALUE: u64 = 9000;
pub const NEWACCOUNT: u64 = 25000;
Expand Down
8 changes: 1 addition & 7 deletions crates/interpreter/src/host.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use crate::{
primitives::{Address, Bytecode, Bytes, Env, B256, U256},
SelfDestructResult,
};
use crate::primitives::{Address, Bytecode, Bytes, Env, B256, U256};
use alloc::vec::Vec;

mod dummy;
Expand Down Expand Up @@ -51,9 +48,6 @@ pub trait Host {
/// Emit a log owned by `address` with given `topics` and `data`.
fn log(&mut self, address: Address, topics: Vec<B256>, data: Bytes);

/// Mark `address` to be deleted, with funds transferred to `target`.
fn selfdestruct(&mut self, address: Address, target: Address) -> Option<SelfDestructResult>;

/// Get asset balance of address and if account is cold loaded.
fn balanceof(&mut self, asset_id: B256, address: Address) -> Option<(U256, bool)>;

Expand Down
7 changes: 1 addition & 6 deletions crates/interpreter/src/host/dummy.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::primitives::{hash_map::Entry, Bytecode, Bytes, HashMap, U256};
use crate::{
primitives::{Address, Env, Log, B256, KECCAK_EMPTY},
Host, SelfDestructResult,
Host,
};
use alloc::vec::Vec;

Expand Down Expand Up @@ -114,11 +114,6 @@ impl Host for DummyHost {
})
}

#[inline]
fn selfdestruct(&mut self, _address: Address, _target: Address) -> Option<SelfDestructResult> {
panic!("Selfdestruct is not supported for this host")
}

#[inline]
fn balanceof(&mut self, _asset_id: B256, _address: Address) -> Option<(U256, bool)> {
Some((U256::ZERO, false))
Expand Down
10 changes: 0 additions & 10 deletions crates/interpreter/src/inner_models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,3 @@ pub struct Transfer {
/// The transfer value.
pub value: U256,
}

/// Result of a call that resulted in a self destruct.
#[derive(Default, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SelfDestructResult {
pub had_value: bool,
pub target_exists: bool,
pub is_cold: bool,
pub previously_destroyed: bool,
}
7 changes: 1 addition & 6 deletions crates/interpreter/src/instruction_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ pub enum InstructionResult {
Continue = 0x00,
Stop,
Return,
SelfDestruct,

// revert codes
Revert = 0x10, // revert opcode
Expand Down Expand Up @@ -149,7 +148,6 @@ impl From<InstructionResult> for SuccessOrHalt {
InstructionResult::Continue => Self::InternalContinue, // used only in interpreter loop
InstructionResult::Stop => Self::Success(Eval::Stop),
InstructionResult::Return => Self::Success(Eval::Return),
InstructionResult::SelfDestruct => Self::Success(Eval::SelfDestruct),
InstructionResult::Revert => Self::Revert,
InstructionResult::CallOrCreate => Self::InternalCallOrCreate, // used only in interpreter loop
InstructionResult::CallTooDeep => Self::Halt(HaltReason::CallTooDeep), // not gonna happen for first call
Expand Down Expand Up @@ -203,10 +201,7 @@ impl From<InstructionResult> for SuccessOrHalt {
#[macro_export]
macro_rules! return_ok {
() => {
InstructionResult::Continue
| InstructionResult::Stop
| InstructionResult::Return
| InstructionResult::SelfDestruct
InstructionResult::Continue | InstructionResult::Stop | InstructionResult::Return
};
}

Expand Down
5 changes: 0 additions & 5 deletions crates/interpreter/src/instructions/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,6 @@ pub fn log<const N: usize, H: Host>(interpreter: &mut Interpreter, host: &mut H)
host.log(interpreter.contract.address, topics, data);
}

/// DEPRECATED: the SELFDESTRUCT opcode is not available in the SabVM
pub fn selfdestruct<H: Host, SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut H) {
interpreter.instruction_result = InstructionResult::NotActivated;
}

pub fn create<const IS_CREATE2: bool, H: Host, SPEC: Spec>(
interpreter: &mut Interpreter,
host: &mut H,
Expand Down
5 changes: 2 additions & 3 deletions crates/interpreter/src/instructions/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,7 @@ opcodes! {
// 0xFB
// 0xFC
0xFD => REVERT => control::revert::<H, SPEC>,
0xFE => INVALID => control::invalid,
0xFF => SELFDESTRUCT => host::selfdestruct::<H, SPEC>,
0xFF => INVALID => control::invalid,
}

/// An EVM opcode.
Expand Down Expand Up @@ -846,8 +845,8 @@ const fn opcode_gas_info(opcode: u8, spec: SpecId) -> OpInfo {
0xFB => OpInfo::none(),
0xFC => OpInfo::none(),
REVERT => OpInfo::gas_block_end(0),
0xFE => OpInfo::none(),
INVALID => OpInfo::gas_block_end(0),
SELFDESTRUCT => OpInfo::gas_block_end(0),
}
}

Expand Down
1 change: 0 additions & 1 deletion crates/primitives/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,6 @@ impl fmt::Display for InvalidHeaderReason {
pub enum Eval {
Stop,
Return,
SelfDestruct,
}

/// Indicates that the EVM has experienced an exceptional halt. This causes execution to
Expand Down
21 changes: 2 additions & 19 deletions crates/primitives/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,11 @@ bitflags! {
/// When account is newly created we will not access database
/// to fetch storage values
const Created = 0b00000001;
/// If account is marked for self destruction.
const SelfDestructed = 0b00000010;
/// Only when account is marked as touched we will save it to database.
const Touched = 0b00000100;
const Touched = 0b00000010;
/// used only for pre spurious dragon hardforks where existing and empty were two separate states.
/// it became same state after EIP-161: State trie clearing
const LoadedAsNotExisting = 0b0001000;
const LoadedAsNotExisting = 0b00000100;
}
}

Expand All @@ -61,21 +59,6 @@ impl Account {
}
}

/// Mark account as self destructed.
pub fn mark_selfdestruct(&mut self) {
self.status |= AccountStatus::SelfDestructed;
}

/// Unmark account as self destructed.
pub fn unmark_selfdestruct(&mut self) {
self.status -= AccountStatus::SelfDestructed;
}

/// Is account marked for self destruct.
pub fn is_selfdestructed(&self) -> bool {
self.status.contains(AccountStatus::SelfDestructed)
}

/// Mark account as touched
pub fn mark_touch(&mut self) {
self.status |= AccountStatus::Touched;
Expand Down
11 changes: 2 additions & 9 deletions crates/revm/src/db/in_memory_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,6 @@ impl<ExtDB: DatabaseRef> DatabaseCommit for CacheDB<ExtDB> {
if !account.is_touched() {
continue;
}
if account.is_selfdestructed() {
let db_account = self.accounts.entry(address).or_default();
db_account.storage.clear();
db_account.account_state = AccountState::NotExisting;
db_account.info = AccountInfo::default();
continue;
}
let is_newly_created = account.is_created();
self.insert_contract(&mut account.info);

Expand Down Expand Up @@ -291,7 +284,7 @@ impl<ExtDB: DatabaseRef> DatabaseRef for CacheDB<ExtDB> {
#[derive(Debug, Clone, Default)]
pub struct DbAccount {
pub info: AccountInfo,
/// If account is selfdestructed or newly created, storage will be cleared.
/// If account is newly created, storage will be cleared.
pub account_state: AccountState,
/// storage slots
pub storage: HashMap<U256, U256>,
Expand Down Expand Up @@ -337,7 +330,7 @@ pub enum AccountState {
NotExisting,
/// EVM touched this account. For newer hardfork this means it can be cleared/removed from state.
Touched,
/// EVM cleared storage of this account, mostly by selfdestruct, we don't ask database for storage slots
/// EVM cleared storage of this account, we don't ask database for storage slots
/// and assume they are U256::ZERO
StorageCleared,
/// EVM didn't interacted with this account
Expand Down
Loading

0 comments on commit cd19eec

Please sign in to comment.