Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.

Commit 86c35ba

Browse files
authored
bus-mapping: improve self-destruct (privacy-scaling-explorations#1613)
### Description resolves privacy-scaling-explorations#1612 ### Issue Link [_link issue here_] ### Type of change - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update ### Contents - [_item_] ### Rationale [_design decisions and extended information_] ### How Has This Been Tested? tested with thousands of mainnet blocks (in scroll fork mainnet.rs tool)
1 parent 9867bf3 commit 86c35ba

File tree

3 files changed

+64
-12
lines changed

3 files changed

+64
-12
lines changed

bus-mapping/src/circuit_input_builder/input_state_ref.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,14 @@ impl<'a> CircuitInputStateRef<'a> {
370370
field: AccountField,
371371
value: Word,
372372
value_prev: Word,
373+
reversible: bool,
373374
) -> Result<(), Error> {
374375
let op = AccountOp::new(address, field, value, value_prev);
375-
self.push_op(step, RW::WRITE, op);
376+
if reversible {
377+
self.push_op_reversible(step, op)?;
378+
} else {
379+
self.push_op(step, RW::WRITE, op);
380+
}
376381
Ok(())
377382
}
378383

@@ -611,14 +616,15 @@ impl<'a> CircuitInputStateRef<'a> {
611616
)
612617
}
613618

614-
/// Transfer to an address irreversibly.
615-
pub fn transfer_to_irreversible(
619+
/// Transfer to an address. Create an account if it is not existed before.
620+
pub fn transfer_to(
616621
&mut self,
617622
step: &mut ExecStep,
618623
receiver: Address,
619624
receiver_exists: bool,
620625
must_create: bool,
621626
value: Word,
627+
reversible: bool,
622628
) -> Result<(), Error> {
623629
// If receiver doesn't exist, create it
624630
if (!receiver_exists && !value.is_zero()) || must_create {
@@ -628,6 +634,7 @@ impl<'a> CircuitInputStateRef<'a> {
628634
AccountField::CodeHash,
629635
CodeDB::empty_code_hash().to_word(),
630636
Word::zero(),
637+
reversible,
631638
)?;
632639
}
633640
if value.is_zero() {
@@ -643,6 +650,7 @@ impl<'a> CircuitInputStateRef<'a> {
643650
AccountField::Balance,
644651
receiver_balance,
645652
receiver_balance_prev,
653+
reversible,
646654
)?;
647655

648656
Ok(())
@@ -1186,7 +1194,11 @@ impl<'a> CircuitInputStateRef<'a> {
11861194
} else {
11871195
0
11881196
};
1189-
geth_step.gas - memory_expansion_gas_cost - code_deposit_cost
1197+
let constant_step_gas = match geth_step.op {
1198+
OpcodeId::SELFDESTRUCT => geth_step.gas_cost,
1199+
_ => 0, // RETURN/STOP/REVERT have no "constant_step_gas"
1200+
};
1201+
geth_step.gas - memory_expansion_gas_cost - code_deposit_cost - constant_step_gas
11901202
};
11911203

11921204
let caller_gas_left = if is_revert_or_return_call_success || call.is_success {

bus-mapping/src/evm/opcodes.rs

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use crate::{
33
circuit_input_builder::{CircuitInputStateRef, ExecState, ExecStep},
44
error::{DepthError, ExecError, InsufficientBalanceError, NonceUintOverflowError, OogError},
55
evm::OpcodeId,
6-
operation::TxAccessListAccountOp,
6+
operation::{AccountField, AccountOp, TxAccessListAccountOp},
77
Error,
88
};
99
use core::fmt::Debug;
10-
use eth_types::{evm_unimplemented, GethExecStep, ToAddress};
10+
use eth_types::{evm_unimplemented, GethExecStep, ToAddress, ToWord, Word};
1111

1212
mod address;
1313
mod balance;
@@ -447,23 +447,60 @@ fn dummy_gen_selfdestruct_ops(
447447
},
448448
)?;
449449

450-
let (found, _) = state.sdb.get_account(&receiver);
450+
let (found, receiver_account) = state.sdb.get_account(&receiver);
451451
if !found {
452452
return Err(Error::AccountNotFound(receiver));
453453
}
454+
let receiver_account = &receiver_account.clone();
454455
let (found, sender_account) = state.sdb.get_account(&sender);
455456
if !found {
456457
return Err(Error::AccountNotFound(sender));
457458
}
459+
let sender_account = &sender_account.clone();
458460
let value = sender_account.balance;
459-
// NOTE: In this dummy implementation we assume that the receiver already
460-
// exists.
461-
state.transfer(&mut exec_step, sender, receiver, true, false, value)?;
461+
462+
state.push_op_reversible(
463+
&mut exec_step,
464+
AccountOp {
465+
address: sender,
466+
field: AccountField::Balance,
467+
value: Word::zero(),
468+
value_prev: value,
469+
},
470+
)?;
471+
state.push_op_reversible(
472+
&mut exec_step,
473+
AccountOp {
474+
address: sender,
475+
field: AccountField::Nonce,
476+
value: Word::zero(),
477+
value_prev: sender_account.nonce.into(),
478+
},
479+
)?;
480+
state.push_op_reversible(
481+
&mut exec_step,
482+
AccountOp {
483+
address: sender,
484+
field: AccountField::CodeHash,
485+
value: Word::zero(),
486+
value_prev: sender_account.code_hash.to_word(),
487+
},
488+
)?;
489+
if receiver != sender {
490+
state.transfer_to(
491+
&mut exec_step,
492+
receiver,
493+
!receiver_account.is_empty(),
494+
false,
495+
value,
496+
true,
497+
)?;
498+
}
462499

463500
if state.call()?.is_persistent {
464501
state.sdb.destruct_account(sender);
465502
}
466503

467-
state.handle_return(&mut exec_step, geth_steps, false)?;
504+
state.handle_return(&mut exec_step, geth_steps, !state.call()?.is_root)?;
468505
Ok(vec![exec_step])
469506
}

bus-mapping/src/evm/opcodes/begin_end_tx.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ fn gen_begin_tx_steps(state: &mut CircuitInputStateRef) -> Result<ExecStep, Erro
5757
AccountField::Nonce,
5858
(nonce_prev + 1).into(),
5959
nonce_prev.into(),
60+
false,
6061
)?;
6162

6263
// Add caller, callee and coinbase (for EIP-3651) to access list.
@@ -270,6 +271,7 @@ fn gen_end_tx_steps(state: &mut CircuitInputStateRef) -> Result<ExecStep, Error>
270271
AccountField::Balance,
271272
caller_balance,
272273
caller_balance_prev,
274+
false,
273275
)?;
274276

275277
let effective_tip = state.tx.gas_price - state.block.base_fee;
@@ -289,12 +291,13 @@ fn gen_end_tx_steps(state: &mut CircuitInputStateRef) -> Result<ExecStep, Error>
289291
coinbase_account.code_hash.to_word()
290292
},
291293
);
292-
state.transfer_to_irreversible(
294+
state.transfer_to(
293295
&mut exec_step,
294296
state.block.coinbase,
295297
coinbase_exist,
296298
false,
297299
coinbase_transfer_value,
300+
false,
298301
)?;
299302

300303
// handle tx receipt tag

0 commit comments

Comments
 (0)