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

Pass L1 fee rate through Context and modify Stf ( and its blueprint) #1053

Merged
merged 18 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from 15 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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions bin/citrea/src/test_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ fn batch2_tx_receipts() -> Vec<TransactionReceipt<u32>> {
fn regular_test_helper(payload: serde_json::Value, expected: &serde_json::Value) {
let soft_confirmation_receipts = vec![
SoftConfirmationReceipt {
l2_height: 1,
da_slot_height: 0,
da_slot_hash: <MockDaSpec as DaSpec>::SlotHash::from([0u8; 32]),
da_slot_txs_commitment: <MockDaSpec as DaSpec>::SlotHash::from([1u8; 32]),
Expand Down Expand Up @@ -137,6 +138,7 @@ fn regular_test_helper(payload: serde_json::Value, expected: &serde_json::Value)
timestamp: 0,
},
SoftConfirmationReceipt {
l2_height: 2,
da_slot_height: 1,
da_slot_hash: <MockDaSpec as DaSpec>::SlotHash::from([2; 32]),
da_slot_txs_commitment: <MockDaSpec as DaSpec>::SlotHash::from([3; 32]),
Expand Down
21 changes: 15 additions & 6 deletions crates/citrea-stf/src/hooks_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,20 @@ impl<C: Context, Da: DaSpec> TxHooks for Runtime<C, Da> {
let RuntimeTxHook {
height,
sequencer,
current_spec: _current_spec,
current_spec,
l1_fee_rate,
} = arg;
let AccountsTxHook { sender, sequencer } =
self.accounts
.pre_dispatch_tx_hook(tx, working_set, sequencer)?;

Ok(C::new(sender, sequencer, *height))
Ok(C::new(
sender,
sequencer,
*height,
*current_spec,
*l1_fee_rate,
))
}

#[cfg_attr(feature = "native", instrument(level = "trace", skip_all, ret))]
Expand Down Expand Up @@ -79,24 +86,26 @@ impl<C: Context, Da: DaSpec> ApplySoftConfirmationHooks<Da> for Runtime<C, Da> {
)]
fn begin_soft_confirmation_hook(
&self,
soft_confirmation: &mut HookSoftConfirmationInfo,
soft_confirmation_info: &HookSoftConfirmationInfo,
working_set: &mut WorkingSet<Self::Context>,
) -> Result<(), SoftConfirmationError> {
self.soft_confirmation_rule_enforcer
.begin_soft_confirmation_hook(soft_confirmation, working_set)?;
.begin_soft_confirmation_hook(soft_confirmation_info, working_set)?;

self.evm
.begin_soft_confirmation_hook(soft_confirmation, working_set);
.begin_soft_confirmation_hook(soft_confirmation_info, working_set);

Ok(())
}

#[cfg_attr(feature = "native", instrument(level = "trace", skip_all, err, ret))]
fn end_soft_confirmation_hook(
&self,
soft_confirmation_info: HookSoftConfirmationInfo,
working_set: &mut WorkingSet<C>,
) -> Result<(), SoftConfirmationError> {
self.evm.end_soft_confirmation_hook(working_set);
self.evm
.end_soft_confirmation_hook(&soft_confirmation_info, working_set);
Ok(())
}
}
Expand Down
13 changes: 3 additions & 10 deletions crates/evm/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ impl<C: sov_modules_api::Context> Evm<C> {
pub(crate) fn execute_system_events(
&self,
system_events: Vec<SystemEvent>,
l1_fee_rate: u128,
working_set: &mut WorkingSet<C>,
) {
let block_env = self
Expand All @@ -43,11 +44,6 @@ impl<C: sov_modules_api::Context> Evm<C> {
let cfg = self.cfg.get(working_set).expect("Evm config must be set");
let cfg_env: CfgEnvWithHandlerCfg = get_cfg_env(&block_env, cfg);

let l1_fee_rate = self
.l1_fee_rate
.get(working_set)
.expect("L1 fee rate must be set");

let l1_block_hash_exists = self
.accounts
.get(&BitcoinLightClient::address(), working_set)
Expand Down Expand Up @@ -128,7 +124,7 @@ impl<C: sov_modules_api::Context> Evm<C> {
pub(crate) fn execute_call(
&self,
txs: Vec<RlpEvmTransaction>,
_context: &C,
context: &C,
working_set: &mut WorkingSet<C>,
) -> Result<CallResponse> {
let users_txs: Vec<TransactionSignedEcRecovered> = txs
Expand All @@ -147,10 +143,7 @@ impl<C: sov_modules_api::Context> Evm<C> {
let cfg = self.cfg.get(working_set).expect("Evm config must be set");
let cfg_env: CfgEnvWithHandlerCfg = get_cfg_env(&block_env, cfg);

let l1_fee_rate = self
.l1_fee_rate
.get(working_set)
.expect("L1 fee rate must be set");
let l1_fee_rate = context.l1_fee_rate();
let mut citrea_handler_ext = CitreaExternal::new(l1_fee_rate);

let block_number = block_env.number;
Expand Down
28 changes: 13 additions & 15 deletions crates/evm/src/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,13 @@ where
};

self.block_env.set(&new_pending_env, working_set);
self.l1_fee_rate
.set(&soft_confirmation_info.l1_fee_rate, working_set);

if !system_events.is_empty() {
self.execute_system_events(system_events, working_set);
self.execute_system_events(
system_events,
soft_confirmation_info.l1_fee_rate(),
working_set,
);
}

// if height > 256, start removing the oldest block
Expand All @@ -119,7 +121,11 @@ where
/// Logic executed at the end of the slot. Here, we generate an authenticated block and set it as the new head of the chain.
/// It's important to note that the state root hash is not known at this moment, so we postpone setting this field until the begin_slot_hook of the next slot.
#[cfg_attr(feature = "native", instrument(level = "trace", skip_all, ret))]
pub fn end_soft_confirmation_hook(&self, working_set: &mut WorkingSet<C>) {
pub fn end_soft_confirmation_hook(
&self,
soft_confirmation_info: &HookSoftConfirmationInfo,
working_set: &mut WorkingSet<C>,
) {
let cfg = self
.cfg
.get(working_set)
Expand All @@ -130,15 +136,7 @@ where
.get(working_set)
.expect("Pending block should always be set");

let l1_fee_rate = self
.l1_fee_rate
.get(working_set)
.expect("L1 fee rate must be set");

let l1_hash = self
.last_l1_hash
.get(working_set)
.expect("Last L1 hash must be set");
let l1_hash = soft_confirmation_info.da_slot_hash;

let parent_block = self
.head
Expand Down Expand Up @@ -216,8 +214,8 @@ where

let block = Block {
header,
l1_fee_rate,
l1_hash,
l1_fee_rate: soft_confirmation_info.l1_fee_rate(),
l1_hash: l1_hash.into(),
transactions: start_tx_index..start_tx_index + pending_transactions.len() as u64,
};

Expand Down
4 changes: 0 additions & 4 deletions crates/evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,6 @@ pub struct Evm<C: sov_modules_api::Context> {
#[state]
pub(crate) latest_block_hashes: sov_modules_api::StateMap<U256, B256, BcsCodec>,

/// L1 fee rate.
#[state]
pub(crate) l1_fee_rate: sov_modules_api::StateValue<u128, BcsCodec>,

/// Transaction's hash that failed to pay the L1 fee.
/// Used to prevent DOS attacks.
/// The vector is cleared in `finalize_hook`.
Expand Down
84 changes: 28 additions & 56 deletions crates/evm/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,35 +723,21 @@ impl<C: sov_modules_api::Context> Evm<C> {

let mut request = request.clone();

let (l1_fee_rate, mut block_env) = match block_number {
None | Some(BlockNumberOrTag::Pending | BlockNumberOrTag::Latest) => {
// so we don't unnecessarily set archival version
// if no block was produced yet, the l1 fee rate can unwrap to 0, we don't care, else just return the latest
let l1_fee_rate = self.l1_fee_rate.get(working_set).unwrap_or_default();
// if no block is produced yet, should default to genesis block env, else just return the lates
let block_env = self.block_env.get(working_set).unwrap_or_else(|| {
BlockEnv::from(
&self
.get_sealed_block_by_number(
Some(BlockNumberOrTag::Earliest),
working_set,
)
.unwrap()
.expect("Genesis block must be set"),
)
});
(l1_fee_rate, block_env)
}
_ => {
let block = match self.get_sealed_block_by_number(block_number, working_set)? {
Some(block) => block,
None => return Err(EthApiError::UnknownBlockNumber.into()),
};
let (l1_fee_rate, mut block_env, block_num) = {
let block = match self.get_sealed_block_by_number(block_number, working_set)? {
Some(block) => block,
None => return Err(EthApiError::UnknownBlockNumber.into()),
};
let l1_fee_rate = block.l1_fee_rate;
let block_env = BlockEnv::from(&block);

set_state_to_end_of_evm_block(block.header.number, working_set);
let l1_fee_rate = block.l1_fee_rate;
let block_env = BlockEnv::from(&block);
(l1_fee_rate, block_env)
(l1_fee_rate, block_env, block.header.number)
};

match block_number {
None | Some(BlockNumberOrTag::Pending | BlockNumberOrTag::Latest) => {}
_ => {
set_state_to_end_of_evm_block(block_num, working_set);
}
};

Expand Down Expand Up @@ -846,35 +832,21 @@ impl<C: sov_modules_api::Context> Evm<C> {
block_number: Option<BlockNumberOrTag>,
working_set: &mut WorkingSet<C>,
) -> RpcResult<EstimatedTxExpenses> {
let (l1_fee_rate, block_env) = match block_number {
None | Some(BlockNumberOrTag::Pending | BlockNumberOrTag::Latest) => {
// so we don't unnecessarily set archival version
// if no block was produced yet, the l1 fee rate can unwrap to 0, we don't care, else just return the latest
let l1_fee_rate = self.l1_fee_rate.get(working_set).unwrap_or_default();
// if no block is produced yet, should default to genesis block env, else just return the lates
let block_env = self.block_env.get(working_set).unwrap_or_else(|| {
BlockEnv::from(
&self
.get_sealed_block_by_number(
Some(BlockNumberOrTag::Earliest),
working_set,
)
.unwrap()
.expect("Genesis block must be set"),
)
});
(l1_fee_rate, block_env)
}
_ => {
let block = match self.get_sealed_block_by_number(block_number, working_set)? {
Some(block) => block,
None => return Err(EthApiError::UnknownBlockNumber.into()),
};
let (l1_fee_rate, block_env, block_num) = {
let block = match self.get_sealed_block_by_number(block_number, working_set)? {
Some(block) => block,
None => return Err(EthApiError::UnknownBlockNumber.into()),
};
let l1_fee_rate = block.l1_fee_rate;
let block_env = BlockEnv::from(&block);

set_state_to_end_of_evm_block(block.header.number, working_set);
let l1_fee_rate = block.l1_fee_rate;
let block_env = BlockEnv::from(&block);
(l1_fee_rate, block_env)
(l1_fee_rate, block_env, block.header.number)
};

match block_number {
None | Some(BlockNumberOrTag::Pending | BlockNumberOrTag::Latest) => {}
_ => {
set_state_to_end_of_evm_block(block_num, working_set);
}
};

Expand Down
Loading
Loading