forked from paradigmxyz/reth
-
Notifications
You must be signed in to change notification settings - Fork 7
feat(feynman): upgrade gas oracle predeploy #254
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
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
4c220f4
feat(feynman): upgrade gas oracle predeploy
Thegaram a8bd191
adjust
Thegaram 94a804f
lint
Thegaram c8c2859
lint
Thegaram 7a31b73
nit
Thegaram 609ce73
Merge branch 'scroll' into feat-feynman-upgrade-gas-oracle-predeploy
Thegaram 26499c8
temporarily disable book unit tests
Thegaram File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,182 @@ | ||
| //! Feynman fork transition for Scroll. | ||
| use alloc::vec; | ||
| use revm::{ | ||
| bytecode::Bytecode, | ||
| database::{states::StorageSlot, State}, | ||
| primitives::{bytes, Bytes, U256}, | ||
| state::AccountInfo, | ||
| Database, | ||
| }; | ||
|
|
||
| use super::curie::L1_GAS_PRICE_ORACLE_ADDRESS; | ||
|
|
||
| /// Bytecode of L1 gas price oracle at Feynman transition. | ||
| const FEYNMAN_L1_GAS_PRICE_ORACLE_BYTECODE: Bytes = bytes!("608060405234801561000f575f80fd5b50600436106101a1575f3560e01c806384189161116100f3578063c63b9e2d11610093578063e88a60ad1161006e578063e88a60ad1461032e578063f2fde38b14610341578063f45e65d814610354578063fe5b04151461035d575f80fd5b8063c63b9e2d146102ff578063c91e514914610312578063de26c4a11461031b575f80fd5b8063944b247f116100ce578063944b247f146102be578063a911d77f146102d1578063aa5e9334146102d9578063bede39b5146102ec575f80fd5b806384189161146102785780638da5cb5b1461028157806393e59dc1146102ab575f80fd5b80633d0f963e1161015e5780636112d6db116101395780636112d6db1461024b5780636a5e67e514610254578063704655971461025d578063715018a614610270575f80fd5b80633d0f963e1461021c57806349948e0e1461022f578063519b4bd314610242575f80fd5b80630c18c162146101a557806313dad5be146101c157806323e524ac146101de5780633577afc5146101e757806339455d3a146101fc5780633b7656bb1461020f575b5f80fd5b6101ae60025481565b6040519081526020015b60405180910390f35b6008546101ce9060ff1681565b60405190151581526020016101b8565b6101ae60065481565b6101fa6101f5366004610c73565b610365565b005b6101fa61020a366004610c8a565b6103f7565b600b546101ce9060ff1681565b6101fa61022a366004610caa565b6104f4565b6101ae61023d366004610ceb565b610577565b6101ae60015481565b6101ae600a5481565b6101ae60075481565b6101fa61026b366004610c73565b6105b0565b6101fa61063e565b6101ae60055481565b5f54610293906001600160a01b031681565b6040516001600160a01b0390911681526020016101b8565b600454610293906001600160a01b031681565b6101fa6102cc366004610c73565b610672565b6101fa6106fe565b6101fa6102e7366004610c73565b61075a565b6101fa6102fa366004610c73565b6107f4565b6101fa61030d366004610c73565b6108b1565b6101ae60095481565b6101ae610329366004610ceb565b61094a565b6101fa61033c366004610c73565b610974565b6101fa61034f366004610caa565b610a00565b6101ae60035481565b6101fa610a8b565b5f546001600160a01b031633146103975760405162461bcd60e51b815260040161038e90610d96565b60405180910390fd5b621c9c388111156103bb57604051635742c80560e11b815260040160405180910390fd5b60028190556040518181527f32740b35c0ea213650f60d44366b4fb211c9033b50714e4a1d34e65d5beb9bb4906020015b60405180910390a150565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa15801561043e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104629190610dcd565b61047f576040516326b3506d60e11b815260040160405180910390fd5b600182905560058190556040518281527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c449060200160405180910390a16040518181527f9a14bfb5d18c4c3cf14cae19c23d7cf1bcede357ea40ca1f75cd49542c71c214906020015b60405180910390a15050565b5f546001600160a01b0316331461051d5760405162461bcd60e51b815260040161038e90610d96565b600480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f22d1c35fe072d2e42c3c8f9bd4a0d34aa84a0101d020a62517b33fdb3174e5f791016104e8565b600b545f9060ff16156105935761058d82610ae7565b92915050565b60085460ff16156105a75761058d82610b45565b61058d82610b81565b5f546001600160a01b031633146105d95760405162461bcd60e51b815260040161038e90610d96565b6105e9633b9aca006103e8610e00565b81111561060957604051631e44fdeb60e11b815260040160405180910390fd5b60038190556040518181527f3336cd9708eaf2769a0f0dc0679f30e80f15dcd88d1921b5a16858e8b85c591a906020016103ec565b5f546001600160a01b031633146106675760405162461bcd60e51b815260040161038e90610d96565b6106705f610bc4565b565b5f546001600160a01b0316331461069b5760405162461bcd60e51b815260040161038e90610d96565b6106a9633b9aca0080610e00565b8111156106c95760405163874f603160e01b815260040160405180910390fd5b60068190556040518181527f2ab3f5a4ebbcbf3c24f62f5454f52f10e1a8c9dcc5acac8f19199ce881a6a108906020016103ec565b5f546001600160a01b031633146107275760405162461bcd60e51b815260040161038e90610d96565b60085460ff161561074b576040516379f9c57560e01b815260040160405180910390fd5b6008805460ff19166001179055565b5f546001600160a01b031633146107835760405162461bcd60e51b815260040161038e90610d96565b633b9aca008110806107a1575061079e633b9aca0080610e00565b81115b156107bf5760405163d9b5dcdf60e01b815260040160405180910390fd5b60098190556040518181527fd50d3079c77df569cd58d55d4e5614bfe7066449009425d22bde8e75242f50bb906020016103ec565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa15801561083b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061085f9190610dcd565b61087c576040516326b3506d60e11b815260040160405180910390fd5b60018190556040518181527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c44906020016103ec565b5f546001600160a01b031633146108da5760405162461bcd60e51b815260040161038e90610d96565b633b9aca008110806108f857506108f5633b9aca0080610e00565b81115b156109155760405162ae184360e01b815260040160405180910390fd5b600a8190556040518181527f8647cebb7e57360673a28415c0bed2f68c42a86c5035f1c9b2eda2b09509288a906020016103ec565b600b545f9060ff168061095f575060085460ff165b1561096b57505f919050565b61058d82610c13565b5f546001600160a01b0316331461099d5760405162461bcd60e51b815260040161038e90610d96565b6109ab633b9aca0080610e00565b8111156109cb5760405163f37ec21560e01b815260040160405180910390fd5b60078190556040518181527f6b332a036d8c3ead57dcb06c87243bd7a2aed015ddf2d0528c2501dae56331aa906020016103ec565b5f546001600160a01b03163314610a295760405162461bcd60e51b815260040161038e90610d96565b6001600160a01b038116610a7f5760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161038e565b610a8881610bc4565b50565b5f546001600160a01b03163314610ab45760405162461bcd60e51b815260040161038e90610d96565b600b5460ff1615610ad857604051631a7c228b60e21b815260040160405180910390fd5b600b805460ff19166001179055565b5f633b9aca0080600a548451600554600754610b039190610e00565b600154600654610b139190610e00565b610b1d9190610e17565b610b279190610e00565b610b319190610e00565b610b3b9190610e2a565b61058d9190610e2a565b5f633b9aca006005548351600754610b5d9190610e00565b610b679190610e00565b600154600654610b779190610e00565b610b3b9190610e17565b5f80610b8c83610c13565b90505f60015482610b9d9190610e00565b9050633b9aca0060035482610bb29190610e00565b610bbc9190610e2a565b949350505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80515f908190815b81811015610c6457848181518110610c3557610c35610e49565b01602001516001600160f81b0319165f03610c5557600483019250610c5c565b6010830192505b600101610c1b565b50506002540160400192915050565b5f60208284031215610c83575f80fd5b5035919050565b5f8060408385031215610c9b575f80fd5b50508035926020909101359150565b5f60208284031215610cba575f80fd5b81356001600160a01b0381168114610cd0575f80fd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215610cfb575f80fd5b813567ffffffffffffffff80821115610d12575f80fd5b818401915084601f830112610d25575f80fd5b813581811115610d3757610d37610cd7565b604051601f8201601f19908116603f01168101908382118183101715610d5f57610d5f610cd7565b81604052828152876020848701011115610d77575f80fd5b826020860160208301375f928101602001929092525095945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b5f60208284031215610ddd575f80fd5b81518015158114610cd0575f80fd5b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761058d5761058d610dec565b8082018082111561058d5761058d610dec565b5f82610e4457634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffdfea164736f6c6343000818000a"); | ||
|
|
||
| /// L1 gas price oracle compression penalty threshold slot. Added in the Feynman fork. | ||
| const PENALTY_THRESHOLD_SLOT: U256 = U256::from_limbs([9, 0, 0, 0]); | ||
| /// L1 gas price oracle compression penalty factor slot. Added in the Feynman fork. | ||
| const PENALTY_FACTOR_SLOT: U256 = U256::from_limbs([10, 0, 0, 0]); | ||
| /// L1 gas price oracle "is Feynman" slot. Added in the Feynman fork. | ||
| const IS_FEYNMAN_SLOT: U256 = U256::from_limbs([11, 0, 0, 0]); | ||
|
|
||
| /// The initial compression penalty threshold used by the oracle contract. | ||
| const INITIAL_PENALTY_THRESHOLD: U256 = U256::from_limbs([1_000_000_000, 0, 0, 0]); | ||
| /// The initial compression penalty factor used by the oracle contract. | ||
| const INITIAL_PENALTY_FACTOR: U256 = U256::from_limbs([1_000_000_000, 0, 0, 0]); | ||
| /// Feynman slot is set to 1 (true) after the Feynman block fork. | ||
| const IS_FEYNMAN: U256 = U256::from_limbs([1, 0, 0, 0]); | ||
|
|
||
| /// Storage update of L1 gas price oracle at Feynman transition. | ||
| const FEYNMAN_L1_GAS_PRICE_ORACLE_STORAGE: [(U256, U256); 3] = [ | ||
| (PENALTY_THRESHOLD_SLOT, INITIAL_PENALTY_THRESHOLD), | ||
| (PENALTY_FACTOR_SLOT, INITIAL_PENALTY_FACTOR), | ||
| (IS_FEYNMAN_SLOT, IS_FEYNMAN), | ||
| ]; | ||
|
|
||
| /// Applies the Scroll Feynman hard fork to the state: | ||
| /// - Updates the L1 oracle contract bytecode to reflect the DA cost reduction. | ||
| /// - Sets the initial compression penalty threshold and penalty factor values. | ||
| /// - Sets the `isFeynman` slot to 1 (true). | ||
| pub(super) fn apply_feynman_hard_fork<DB: Database>( | ||
| state: &mut State<DB>, | ||
| ) -> Result<(), DB::Error> { | ||
| let oracle = state.load_cache_account(L1_GAS_PRICE_ORACLE_ADDRESS)?; | ||
|
|
||
| // No-op if already applied. | ||
| // Note: This requires a storage read for every Feynman block, and it means this | ||
| // read needs to be included in the execution witness. Unfortunately, there is no | ||
| // other reliable way to apply the change only at the transition block, since | ||
| // `ScrollBlockExecutor` does not have access to the parent timestamp. | ||
| if matches!(oracle.storage_slot(IS_FEYNMAN_SLOT), Some(val) if val == IS_FEYNMAN) { | ||
| return Ok(()) | ||
| } | ||
|
|
||
| // compute the code hash | ||
| let bytecode = Bytecode::new_raw(FEYNMAN_L1_GAS_PRICE_ORACLE_BYTECODE); | ||
| let code_hash = bytecode.hash_slow(); | ||
|
|
||
| // get the old oracle account info | ||
| let old_oracle_info = oracle.account_info().unwrap_or_default(); | ||
|
|
||
| // init new oracle account information | ||
| let new_oracle_info = AccountInfo { code_hash, code: Some(bytecode), ..old_oracle_info }; | ||
|
|
||
| // init new storage | ||
| let new_storage = FEYNMAN_L1_GAS_PRICE_ORACLE_STORAGE | ||
| .into_iter() | ||
| .map(|(slot, present_value)| { | ||
| ( | ||
| slot, | ||
| StorageSlot { | ||
| present_value, | ||
| previous_or_original_value: oracle.storage_slot(slot).unwrap_or_default(), | ||
| }, | ||
| ) | ||
| }) | ||
| .collect(); | ||
|
|
||
| // create transition for oracle new account info and storage | ||
| let transition = oracle.change(new_oracle_info, new_storage); | ||
|
|
||
| // add transition | ||
| if let Some(s) = state.transition_state.as_mut() { | ||
| s.add_transitions(vec![(L1_GAS_PRICE_ORACLE_ADDRESS, transition)]) | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
| use revm::{ | ||
| database::{ | ||
| states::{bundle_state::BundleRetention, plain_account::PlainStorage, StorageSlot}, | ||
| EmptyDB, State, | ||
| }, | ||
| primitives::{keccak256, U256}, | ||
| state::{AccountInfo, Bytecode}, | ||
| Database, | ||
| }; | ||
| use std::str::FromStr; | ||
|
|
||
| use super::super::curie::CURIE_L1_GAS_PRICE_ORACLE_BYTECODE; | ||
|
|
||
| #[test] | ||
| fn test_apply_feynman_fork() -> eyre::Result<()> { | ||
| // init state | ||
| let db = EmptyDB::new(); | ||
| let mut state = | ||
| State::builder().with_database(db).with_bundle_update().without_state_clear().build(); | ||
|
|
||
| // oracle pre fork state | ||
| let bytecode_pre_fork = Bytecode::new_raw(CURIE_L1_GAS_PRICE_ORACLE_BYTECODE); | ||
| let oracle_pre_fork = AccountInfo { | ||
| code_hash: bytecode_pre_fork.hash_slow(), | ||
| code: Some(bytecode_pre_fork), | ||
| ..Default::default() | ||
| }; | ||
| let oracle_storage_pre_fork = PlainStorage::from_iter([ | ||
| // owner | ||
| (U256::ZERO, U256::from_str("0x13d24a7ff6f5ec5ff0e9c40fc3b8c9c01c65437b")?), | ||
| // l1BaseFee | ||
| (U256::from(1), U256::from(0x15f50e5e)), | ||
| // overhead | ||
| (U256::from(2), U256::from(0x38)), | ||
| // scalar | ||
| (U256::from(3), U256::from(0x3e95ba80)), | ||
| // whitelist | ||
| (U256::from(4), U256::from_str("0x5300000000000000000000000000000000000003")?), | ||
| // l1BlobBaseFee | ||
| (U256::from(5), U256::from(0x15f50e5e)), | ||
| // commitScalar | ||
| (U256::from(6), U256::from(0x3e95ba80)), | ||
| // blobScalar | ||
| (U256::from(7), U256::from(0x3e95ba80)), | ||
| // isCurie | ||
| (U256::from(8), U256::from(1)), | ||
| ]); | ||
| state.insert_account_with_storage( | ||
| L1_GAS_PRICE_ORACLE_ADDRESS, | ||
| oracle_pre_fork.clone(), | ||
| oracle_storage_pre_fork.clone(), | ||
| ); | ||
|
|
||
| // apply feynman fork | ||
| apply_feynman_hard_fork(&mut state)?; | ||
|
|
||
| // merge transitions | ||
| state.merge_transitions(BundleRetention::Reverts); | ||
| let bundle = state.take_bundle(); | ||
|
|
||
| // check oracle account info | ||
| let oracle = bundle.state.get(&L1_GAS_PRICE_ORACLE_ADDRESS).unwrap().clone(); | ||
| let code_hash = keccak256(&FEYNMAN_L1_GAS_PRICE_ORACLE_BYTECODE); | ||
| let bytecode = Bytecode::new_raw(FEYNMAN_L1_GAS_PRICE_ORACLE_BYTECODE); | ||
| let expected_oracle_info = | ||
| AccountInfo { code_hash, code: Some(bytecode.clone()), ..Default::default() }; | ||
|
|
||
| assert_eq!(oracle.original_info.unwrap(), oracle_pre_fork); | ||
| assert_eq!(oracle.info.unwrap(), expected_oracle_info); | ||
|
|
||
| // check oracle storage changeset | ||
| let mut storage = oracle.storage.into_iter().collect::<Vec<(U256, StorageSlot)>>(); | ||
| storage.sort_by(|(a, _), (b, _)| a.cmp(b)); | ||
| for (got, expected) in storage.into_iter().zip(FEYNMAN_L1_GAS_PRICE_ORACLE_STORAGE) { | ||
| assert_eq!(got.0, expected.0); | ||
| assert_eq!(got.1, StorageSlot { present_value: expected.1, ..Default::default() }); | ||
| } | ||
|
|
||
| // check oracle original storage | ||
| for (slot, value) in oracle_storage_pre_fork { | ||
| assert_eq!(state.storage(L1_GAS_PRICE_ORACLE_ADDRESS, slot)?, value) | ||
| } | ||
|
|
||
| // check deployed contract | ||
| assert_eq!(bundle.contracts.get(&code_hash).unwrap().clone(), bytecode); | ||
|
|
||
| Ok(()) | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.