-
Notifications
You must be signed in to change notification settings - Fork 2.5k
feat: add bal rpc methods #23330
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: add bal rpc methods #23330
Changes from 2 commits
38c9794
a4fad4b
a8a07b3
14c3308
d234275
3e09a81
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| //! Helpers for `eth_blockAccessList` RPC method. | ||
| use alloy_consensus::BlockHeader; | ||
| use alloy_eips::eip7928::BlockAccessList; | ||
| use alloy_primitives::B256; | ||
| use reth_chainspec::{ChainSpecProvider, EthereumHardforks}; | ||
| use reth_errors::RethError; | ||
| use reth_evm::{block::BlockExecutor, ConfigureEvm, Evm}; | ||
| use reth_revm::{database::StateProviderDatabase, State}; | ||
| use reth_rpc_eth_types::{ | ||
| cache::db::StateProviderTraitObjWrapper, error::FromEthApiError, EthApiError, | ||
| }; | ||
| use reth_storage_api::{BlockNumReader, StateProviderFactory}; | ||
|
|
||
| use crate::{ | ||
| helpers::{Call, LoadBlock, Trace}, | ||
| RpcNodeCore, | ||
| }; | ||
|
|
||
| /// Helper trait for `eth_blockAccessList` RPC method. | ||
| pub trait GetBlockAccessList: Trace + Call + LoadBlock { | ||
| /// Retrieves the block access list for a block identified by its hash. | ||
| fn get_block_access_list( | ||
| &self, | ||
| block_hash: B256, | ||
| ) -> impl Future<Output = Result<Option<BlockAccessList>, Self::Error>> + Send { | ||
| async move { | ||
| let block = self | ||
| .recovered_block(block_hash.into()) | ||
| .await? | ||
| .ok_or_else(|| EthApiError::HeaderNotFound(block_hash.into()))?; | ||
|
|
||
| // Check if the block has been pruned (EIP-4444) | ||
| let earliest_block = self.provider().earliest_block_number()?; | ||
| if block.header().number() < earliest_block { | ||
| return Err(EthApiError::PrunedHistoryUnavailable.into()); | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can remove this because this is now checked by recovered_block already |
||
| // Check if the block is pre-Amsterdam, as access lists are not available for those | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry I'm catching up to all this BAL work, I'm guessing we have some way of pre-enabling this for development/testing?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was in the specs, i dont think there is a way to enable it ..we can just remove the check for now if you want
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will defer to @mattsse, but yeah having some way to get BALs for pre-amsterdam blocks is a requirement for big block testing. Maybe we enable that via a CLI arg or something.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Soubhik-10 lets remove this check for now, because this endpoint will come in handy for pre fork testing |
||
| // blocks | ||
| if !self.provider().chain_spec().is_amsterdam_active_at_timestamp(block.timestamp()) { | ||
| return Err(EthApiError::BlockAccessListNotAvailablePreAmsterdam.into()); | ||
| } | ||
|
|
||
| self.spawn_blocking_io(move |eth_api| { | ||
| let state = eth_api | ||
| .provider() | ||
| .state_by_block_id(block.parent_hash().into()) | ||
| .map_err(Self::Error::from_eth_err)?; | ||
|
|
||
| let mut db = State::builder() | ||
| .with_database(StateProviderDatabase::new(StateProviderTraitObjWrapper(state))) | ||
| .with_bal_builder() | ||
| .build(); | ||
|
|
||
| let block_txs = block.transactions_recovered(); | ||
| let mut executor = RpcNodeCore::evm_config(ð_api) | ||
| .executor_for_block(&mut db, block.sealed_block()) | ||
| .map_err(RethError::other) | ||
| .map_err(Self::Error::from_eth_err)?; | ||
|
|
||
| executor.apply_pre_execution_changes().map_err(Self::Error::from_eth_err)?; | ||
| executor.evm_mut().db_mut().bump_bal_index(); | ||
|
|
||
| // replay all transactions prior to the targeted transaction | ||
| for block_tx in block_txs { | ||
| executor.execute_transaction(block_tx).map_err(Self::Error::from_eth_err)?; | ||
| executor.evm_mut().db_mut().bump_bal_index(); | ||
| } | ||
|
|
||
| executor | ||
| .apply_post_execution_changes() | ||
| .map_err(|err| EthApiError::Internal(err.into()))?; | ||
|
|
||
| let bal = db.take_built_alloy_bal(); | ||
| Ok(bal) | ||
| }) | ||
| .await | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| //! Contains RPC handler implementations specific to block access lists. | ||
|
|
||
| use reth_rpc_convert::RpcConvert; | ||
| use reth_rpc_eth_api::{helpers::bal::GetBlockAccessList, FromEvmError, RpcNodeCore}; | ||
| use reth_rpc_eth_types::EthApiError; | ||
|
|
||
| use crate::EthApi; | ||
|
|
||
| impl<N, Rpc> GetBlockAccessList for EthApi<N, Rpc> | ||
| where | ||
| N: RpcNodeCore, | ||
| EthApiError: FromEvmError<N::Evm>, | ||
| Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError, Evm = N::Evm>, | ||
| { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ pub mod signer; | |
| pub mod sync_listener; | ||
| pub mod types; | ||
|
|
||
| mod bal; | ||
| mod block; | ||
| mod call; | ||
| mod fees; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think returning value here makes sense for now, but it has some overhead because we then need to serialize this as string again.
but lets keep it for now