Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/hive.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
matrix:
include:
- simulation: rpc-compat
run_command: just run-hive ethereum/rpc-compat "/eth_chainId|eth_getTransactionByBlockHashAndIndex|eth_getTransactionByBlockNumberAndIndex|eth_getCode|eth_getStorageAt|eth_call|eth_getTransactionByHash|eth_getBlockByHash|eth_getBlockByNumber|eth_createAccessList|eth_getBlockTransactionCountByNumber|eth_getBlockTransactionCountByHash|eth_getBlockReceipts|eth_getTransactionReceipt|eth_blobGasPrice|eth_blockNumber"
run_command: just run-hive ethereum/rpc-compat "/eth_chainId|eth_getTransactionByBlockHashAndIndex|eth_getTransactionByBlockNumberAndIndex|eth_getCode|eth_getStorageAt|eth_call|eth_getTransactionByHash|eth_getBlockByHash|eth_getBlockByNumber|eth_createAccessList|eth_getBlockTransactionCountByNumber|eth_getBlockTransactionCountByHash|eth_getBlockReceipts|eth_getTransactionReceipt|eth_blobGasPrice|eth_blockNumber|ethGetTransactionCount"
steps:
- name: Checkout sources
uses: actions/checkout@v3
Expand Down
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,9 @@ kurtosis enclave stop lambdanet ; kurtosis enclave rm lambdanet
Add support to follow a post-Merge localnet as a read-only RPC Node. This first milestone will only support a canonical chain (every incoming block has to be the child of the current head).

RPC endpoints
- `debug_getRawBlock`
- `debug_getRawHeader`
- `debug_getRawReceipts`
- `debug_getRawTransaction`
- `engine_newPayloadV3` (excl. block building) ✅
- `eth_blobBaseFee`
- `eth_blockNumber` ✅
- `eth_blobBaseFee` ✅
- `eth_blockNumber` ✅
- `eth_call` (at head block) ✅
- `eth_chainId` ✅
- `eth_createAccessList` (at head block) ✅
Expand All @@ -103,7 +99,7 @@ RPC endpoints
- `eth_getTransactionByBlockHashAndIndex` ✅
- `eth_getTransactionByBlockNumberAndIndex` ✅
- `eth_getTransactionByHash` ✅
- `eth_getTransactionCount`
- `eth_getTransactionCount` ✅

See issues and progress: https://github.com/lambdaclass/ethereum_rust/milestone/1

Expand Down
36 changes: 36 additions & 0 deletions crates/rpc/eth/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ pub struct GetStorageAtRequest {
pub block: BlockIdentifierOrHash,
}

pub struct GetTransactionCountRequest {
pub address: Address,
pub block: BlockIdentifierOrHash,
}

impl RpcHandler for GetBalanceRequest {
fn parse(params: &Option<Vec<Value>>) -> Option<GetBalanceRequest> {
let params = params.as_ref()?;
Expand Down Expand Up @@ -158,6 +163,37 @@ impl RpcHandler for GetStorageAtRequest {
}
}

impl RpcHandler for GetTransactionCountRequest {
fn parse(params: &Option<Vec<Value>>) -> Option<GetTransactionCountRequest> {
let params = params.as_ref()?;
if params.len() != 2 {
return None;
};
Some(GetTransactionCountRequest {
address: serde_json::from_value(params[0].clone()).ok()?,
block: serde_json::from_value(params[1].clone()).ok()?,
})
}
fn handle(&self, storage: Store) -> Result<Value, RpcErr> {
info!(
"Requested nonce of account {} at block {}",
self.address, self.block
);

// TODO: implement historical querying
let is_latest = self.block.is_latest(&storage)?;
if !is_latest {
return Err(RpcErr::Internal);
}

let nonce = storage
.get_nonce_by_account_address(self.address)?
.unwrap_or_default();

serde_json::to_value(format!("0x{:x}", nonce)).map_err(|_| RpcErr::Internal)
}
}

impl Display for BlockIdentifierOrHash {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Expand Down
3 changes: 2 additions & 1 deletion crates/rpc/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use engine::{
ExchangeCapabilitiesRequest,
};
use eth::{
account::{GetBalanceRequest, GetCodeRequest, GetStorageAtRequest},
account::{GetBalanceRequest, GetCodeRequest, GetStorageAtRequest, GetTransactionCountRequest},
block::{
self, GetBlockByHashRequest, GetBlockByNumberRequest, GetBlockReceiptsRequest,
GetBlockTransactionCountRequest,
Expand Down Expand Up @@ -179,6 +179,7 @@ pub fn map_eth_requests(req: &RpcRequest, storage: Store) -> Result<Value, RpcEr
"eth_blockNumber" => block::block_number(storage),
"eth_call" => CallRequest::call(req, storage),
"eth_blobBaseFee" => block::get_blob_base_fee(&storage),
"eth_getTransactionCount" => GetTransactionCountRequest::call(req, storage),
_ => Err(RpcErr::MethodNotFound),
}
}
Expand Down
8 changes: 8 additions & 0 deletions crates/storage/engines/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ pub trait StoreEngine: Debug + Send {
self.get_account_code(code_hash)
}

/// Obtain account nonce via account address
fn get_nonce_by_account_address(&self, address: Address) -> Result<Option<u64>, StoreError> {
let nonce = self
.get_account_info(address)?
.map(|acc_info| acc_info.nonce);
Ok(nonce)
}

fn get_transaction_by_hash(
&self,
transaction_hash: H256,
Expand Down
10 changes: 10 additions & 0 deletions crates/storage/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,16 @@ impl Store {
.unwrap()
.get_code_by_account_address(address)
}
pub fn get_nonce_by_account_address(
&self,
address: Address,
) -> Result<Option<u64>, StoreError> {
self.engine
.clone()
.lock()
.unwrap()
.get_nonce_by_account_address(address)
}

pub fn add_account(&self, address: Address, account: Account) -> Result<(), StoreError> {
self.engine.lock().unwrap().add_account(address, account)
Expand Down
2 changes: 1 addition & 1 deletion hive
Submodule hive updated 38 files
+2 −2 .circleci/continue_config.yml
+2 −2 clients/besu/Dockerfile.git
+2 −2 clients/besu/Dockerfile.local
+1 −4 clients/besu/besu.sh
+0 −3 clients/erigon/erigon.sh
+1 −1 clients/ethereumjs/ethereumjs-local.sh
+1 −1 clients/ethereumjs/ethereumjs.sh
+1 −1 clients/trin-bridge/trin_bridge.sh
+1 −1 clients/trin/trin.sh
+3 −4 go.mod
+4 −9 go.sum
+11 −11 hivesim-rs/src/testapi.rs
+39 −0 hivesim-rs/src/types.rs
+1 −1 internal/libdocker/docker.go
+4 −4 internal/libhive/run.go
+20 −32 simulators/ethereum/engine/client/node/node.go
+6 −7 simulators/ethereum/engine/go.mod
+14 −16 simulators/ethereum/engine/go.sum
+1 −6 simulators/ethereum/engine/suites/engine/invalid_payload.go
+2 −2 simulators/ethereum/pyspec/Dockerfile
+6 −7 simulators/ethereum/pyspec/go.mod
+14 −16 simulators/ethereum/pyspec/go.sum
+665 −547 simulators/portal/Cargo.lock
+9 −8 simulators/portal/Cargo.toml
+2 −2 simulators/portal/Dockerfile
+2 −0 simulators/portal/src/suites/beacon/constants.rs
+56 −36 simulators/portal/src/suites/beacon/interop.rs
+11 −25 simulators/portal/src/suites/beacon/mesh.rs
+46 −49 simulators/portal/src/suites/beacon/rpc_compat.rs
+0 −34 simulators/portal/src/suites/environment.rs
+102 −30 simulators/portal/src/suites/history/interop.rs
+6 −5 simulators/portal/src/suites/history/mesh.rs
+29 −28 simulators/portal/src/suites/history/rpc_compat.rs
+3 −2 simulators/portal/src/suites/history/trin_bridge.rs
+0 −1 simulators/portal/src/suites/mod.rs
+2 −0 simulators/portal/src/suites/state/constants.rs
+108 −98 simulators/portal/src/suites/state/interop.rs
+46 −49 simulators/portal/src/suites/state/rpc_compat.rs