mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-27 08:08:15 -05:00
fix: getAccount (#10402)
This commit is contained in:
@@ -175,6 +175,7 @@ where
|
||||
EthApiClient::protocol_version(client).await.unwrap();
|
||||
EthApiClient::chain_id(client).await.unwrap();
|
||||
EthApiClient::accounts(client).await.unwrap();
|
||||
EthApiClient::get_account(client, address, block_number.into()).await.unwrap();
|
||||
EthApiClient::block_number(client).await.unwrap();
|
||||
EthApiClient::get_code(client, address, None).await.unwrap();
|
||||
EthApiClient::send_raw_transaction(client, tx).await.unwrap();
|
||||
|
||||
@@ -262,7 +262,7 @@ pub trait EthApi {
|
||||
&self,
|
||||
address: Address,
|
||||
block: BlockId,
|
||||
) -> RpcResult<reth_rpc_types::Account>;
|
||||
) -> RpcResult<Option<reth_rpc_types::Account>>;
|
||||
|
||||
/// Introduced in EIP-1559, returns suggestion for the priority for dynamic fee transactions.
|
||||
#[method(name = "maxPriorityFeePerGas")]
|
||||
@@ -652,7 +652,7 @@ where
|
||||
&self,
|
||||
address: Address,
|
||||
block: BlockId,
|
||||
) -> RpcResult<reth_rpc_types::Account> {
|
||||
) -> RpcResult<Option<reth_rpc_types::Account>> {
|
||||
trace!(target: "rpc::eth", "Serving eth_getAccount");
|
||||
Ok(EthState::get_account(self, address, block).await?)
|
||||
}
|
||||
|
||||
@@ -134,14 +134,13 @@ pub trait EthState: LoadState + SpawnBlocking {
|
||||
&self,
|
||||
address: Address,
|
||||
block_id: BlockId,
|
||||
) -> impl Future<Output = Result<Account, Self::Error>> + Send {
|
||||
) -> impl Future<Output = Result<Option<Account>, Self::Error>> + Send {
|
||||
self.spawn_blocking_io(move |this| {
|
||||
let state = this.state_at_block_id(block_id)?;
|
||||
|
||||
let account = state
|
||||
.basic_account(address)
|
||||
.map_err(Self::Error::from_eth_err)?
|
||||
.unwrap_or_default();
|
||||
let account = state.basic_account(address).map_err(Self::Error::from_eth_err)?;
|
||||
let Some(account) = account else { return Ok(None) };
|
||||
|
||||
let balance = account.balance;
|
||||
let nonce = account.nonce;
|
||||
let code_hash = account.bytecode_hash.unwrap_or(KECCAK_EMPTY);
|
||||
@@ -152,7 +151,7 @@ pub trait EthState: LoadState + SpawnBlocking {
|
||||
.hashed_storage_root(address, Default::default())
|
||||
.map_err(Self::Error::from_eth_err)?;
|
||||
|
||||
Ok(Account { balance, nonce, code_hash, storage_root })
|
||||
Ok(Some(Account { balance, nonce, code_hash, storage_root }))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ mod tests {
|
||||
use super::*;
|
||||
use reth_evm_ethereum::EthEvmConfig;
|
||||
use reth_primitives::{
|
||||
constants::ETHEREUM_BLOCK_GAS_LIMIT, Address, StorageKey, StorageValue, U256,
|
||||
constants::ETHEREUM_BLOCK_GAS_LIMIT, Address, StorageKey, StorageValue, KECCAK_EMPTY, U256,
|
||||
};
|
||||
use reth_provider::test_utils::{ExtendedAccount, MockEthProvider, NoopProvider};
|
||||
use reth_rpc_eth_api::helpers::EthState;
|
||||
@@ -53,19 +53,17 @@ mod tests {
|
||||
};
|
||||
use reth_rpc_server_types::constants::{DEFAULT_ETH_PROOF_WINDOW, DEFAULT_PROOF_PERMITS};
|
||||
use reth_tasks::pool::BlockingTaskPool;
|
||||
use reth_transaction_pool::test_utils::testing_pool;
|
||||
use reth_transaction_pool::test_utils::{testing_pool, TestPool};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_storage() {
|
||||
// === Noop ===
|
||||
fn noop_eth_api() -> EthApi<NoopProvider, TestPool, (), EthEvmConfig> {
|
||||
let pool = testing_pool();
|
||||
let evm_config = EthEvmConfig::default();
|
||||
|
||||
let cache = EthStateCache::spawn(NoopProvider::default(), Default::default(), evm_config);
|
||||
let eth_api = EthApi::new(
|
||||
EthApi::new(
|
||||
NoopProvider::default(),
|
||||
pool.clone(),
|
||||
pool,
|
||||
(),
|
||||
cache.clone(),
|
||||
GasPriceOracle::new(NoopProvider::default(), Default::default(), cache.clone()),
|
||||
@@ -76,21 +74,20 @@ mod tests {
|
||||
evm_config,
|
||||
None,
|
||||
DEFAULT_PROOF_PERMITS,
|
||||
);
|
||||
let address = Address::random();
|
||||
let storage = eth_api.storage_at(address, U256::ZERO.into(), None).await.unwrap();
|
||||
assert_eq!(storage, U256::ZERO.to_be_bytes());
|
||||
)
|
||||
}
|
||||
|
||||
fn mock_eth_api(
|
||||
accounts: HashMap<Address, ExtendedAccount>,
|
||||
) -> EthApi<MockEthProvider, TestPool, (), EthEvmConfig> {
|
||||
let pool = testing_pool();
|
||||
let evm_config = EthEvmConfig::default();
|
||||
|
||||
// === Mock ===
|
||||
let mock_provider = MockEthProvider::default();
|
||||
let storage_value = StorageValue::from(1337);
|
||||
let storage_key = StorageKey::random();
|
||||
let storage = HashMap::from([(storage_key, storage_value)]);
|
||||
let account = ExtendedAccount::new(0, U256::ZERO).extend_storage(storage);
|
||||
mock_provider.add_account(address, account);
|
||||
mock_provider.extend_accounts(accounts);
|
||||
|
||||
let cache = EthStateCache::spawn(mock_provider.clone(), Default::default(), evm_config);
|
||||
let eth_api = EthApi::new(
|
||||
EthApi::new(
|
||||
mock_provider.clone(),
|
||||
pool,
|
||||
(),
|
||||
@@ -103,10 +100,48 @@ mod tests {
|
||||
evm_config,
|
||||
None,
|
||||
DEFAULT_PROOF_PERMITS,
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_storage() {
|
||||
// === Noop ===
|
||||
let eth_api = noop_eth_api();
|
||||
let address = Address::random();
|
||||
let storage = eth_api.storage_at(address, U256::ZERO.into(), None).await.unwrap();
|
||||
assert_eq!(storage, U256::ZERO.to_be_bytes());
|
||||
|
||||
// === Mock ===
|
||||
let storage_value = StorageValue::from(1337);
|
||||
let storage_key = StorageKey::random();
|
||||
let storage = HashMap::from([(storage_key, storage_value)]);
|
||||
|
||||
let accounts =
|
||||
HashMap::from([(address, ExtendedAccount::new(0, U256::ZERO).extend_storage(storage))]);
|
||||
let eth_api = mock_eth_api(accounts);
|
||||
|
||||
let storage_key: U256 = storage_key.into();
|
||||
let storage = eth_api.storage_at(address, storage_key.into(), None).await.unwrap();
|
||||
assert_eq!(storage, storage_value.to_be_bytes());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_account_missing() {
|
||||
let eth_api = noop_eth_api();
|
||||
let address = Address::random();
|
||||
let account = eth_api.get_account(address, Default::default()).await.unwrap();
|
||||
assert!(account.is_none());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_account_empty() {
|
||||
let address = Address::random();
|
||||
let accounts = HashMap::from([(address, ExtendedAccount::new(0, U256::ZERO))]);
|
||||
let eth_api = mock_eth_api(accounts);
|
||||
|
||||
let account = eth_api.get_account(address, Default::default()).await.unwrap();
|
||||
let expected_account =
|
||||
reth_rpc_types::Account { code_hash: KECCAK_EMPTY, ..Default::default() };
|
||||
assert_eq!(Some(expected_account), account);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user