Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Optional coinbase tip #625

Merged
merged 2 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crates/primitives/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ pub struct CfgEnv {
/// If some it will effects EIP-170: Contract code size limit. Useful to increase this because of tests.
/// By default it is 0x6000 (~25kb).
pub limit_contract_code_size: Option<usize>,
/// Disables the coinbase tip during the finalization of the transaction. This is useful for
/// rollups that redirect the tip to the sequencer.
pub disable_coinbase_tip: bool,
/// A hard memory limit in bytes beyond which [Memory] cannot be resized.
///
/// In cases where the gas limit may be extraordinarily high, it is recommended to set this to
Expand Down Expand Up @@ -188,6 +191,7 @@ impl Default for CfgEnv {
spec_id: SpecId::LATEST,
perf_analyse_created_bytecodes: Default::default(),
limit_contract_code_size: None,
disable_coinbase_tip: false,
#[cfg(feature = "memory_limit")]
memory_limit: 2u64.pow(32) - 1,
#[cfg(feature = "optional_balance_check")]
Expand Down
99 changes: 50 additions & 49 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,61 +251,62 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
fn finalize<SPEC: Spec>(&mut self, gas: &Gas) -> (HashMap<B160, Account>, Vec<Log>, u64, u64) {
let caller = self.data.env.tx.caller;
let coinbase = self.data.env.block.coinbase;
let (gas_used, gas_refunded) = if crate::USE_GAS {
let effective_gas_price = self.data.env.effective_gas_price();
let basefee = self.data.env.block.basefee;
let (gas_used, gas_refunded) =
if crate::USE_GAS {
let effective_gas_price = self.data.env.effective_gas_price();
let basefee = self.data.env.block.basefee;

let gas_refunded = if self.env().cfg.is_gas_refund_disabled() {
0
} else {
// EIP-3529: Reduction in refunds
let max_refund_quotient = if SPEC::enabled(LONDON) { 5 } else { 2 };
min(gas.refunded() as u64, gas.spend() / max_refund_quotient)
};
let gas_refunded = if self.env().cfg.is_gas_refund_disabled() {
0
} else {
// EIP-3529: Reduction in refunds
let max_refund_quotient = if SPEC::enabled(LONDON) { 5 } else { 2 };
min(gas.refunded() as u64, gas.spend() / max_refund_quotient)
};

// return balance of not spend gas.
let Ok((caller_account, _)) =
self.data.journaled_state.load_account(caller, self.data.db)
else {
panic!("caller account not found");
};
// return balance of not spend gas.
let Ok((caller_account, _)) =
self.data.journaled_state.load_account(caller, self.data.db)
else {
panic!("caller account not found");
};

caller_account.info.balance = caller_account
.info
.balance
.saturating_add(effective_gas_price * U256::from(gas.remaining() + gas_refunded));
caller_account.info.balance = caller_account.info.balance.saturating_add(
effective_gas_price * U256::from(gas.remaining() + gas_refunded),
);

// transfer fee to coinbase/beneficiary.
if !self.data.env.cfg.disable_coinbase_tip {
// EIP-1559 discard basefee for coinbase transfer. Basefee amount of gas is discarded.
let coinbase_gas_price = if SPEC::enabled(LONDON) {
effective_gas_price.saturating_sub(basefee)
} else {
effective_gas_price
};

// EIP-1559 discard basefee for coinbase transfer. Basefee amount of gas is discarded.
let coinbase_gas_price = if SPEC::enabled(LONDON) {
effective_gas_price.saturating_sub(basefee)
} else {
effective_gas_price
};
let Ok((coinbase_account, _)) = self
.data
.journaled_state
.load_account(coinbase, self.data.db)
else {
panic!("coinbase account not found");
};
coinbase_account.mark_touch();
coinbase_account.info.balance = coinbase_account.info.balance.saturating_add(
coinbase_gas_price * U256::from(gas.spend() - gas_refunded),
);
}

// transfer fee to coinbase/beneficiary.
let Ok((coinbase_account, _)) = self
.data
.journaled_state
.load_account(coinbase, self.data.db)
else {
panic!("coinbase account not found");
(gas.spend() - gas_refunded, gas_refunded)
} else {
// touch coinbase
let _ = self
.data
.journaled_state
.load_account(coinbase, self.data.db);
self.data.journaled_state.touch(&coinbase);
(0, 0)
};
coinbase_account.mark_touch();
coinbase_account.info.balance = coinbase_account
.info
.balance
.saturating_add(coinbase_gas_price * U256::from(gas.spend() - gas_refunded));

(gas.spend() - gas_refunded, gas_refunded)
} else {
// touch coinbase
let _ = self
.data
.journaled_state
.load_account(coinbase, self.data.db);
self.data.journaled_state.touch(&coinbase);
(0, 0)
};
let (new_state, logs) = self.data.journaled_state.finalize();
(new_state, logs, gas_used, gas_refunded)
}
Expand Down