From 3ce826b3a1301d140f6145f8d864d8f1a59bb99d Mon Sep 17 00:00:00 2001 From: Eshaan Bansal Date: Sat, 23 Nov 2024 01:47:47 +0530 Subject: [PATCH 1/2] feat: implement eth_getTransactionByBlockNumberAndIndex --- core/src/client/mod.rs | 10 ++++++++++ core/src/client/node.rs | 13 +++++++++++++ core/src/client/rpc.rs | 18 ++++++++++++++++++ core/src/execution/mod.rs | 12 +++++++++++- core/src/execution/state.rs | 19 +++++++++++++++++-- helios-ts/lib.ts | 6 ++++++ helios-ts/src/ethereum.rs | 16 ++++++++++++++++ helios-ts/src/opstack.rs | 16 ++++++++++++++++ rpc.md | 1 + 9 files changed, 108 insertions(+), 3 deletions(-) diff --git a/core/src/client/mod.rs b/core/src/client/mod.rs index 778c1c1b..e30e86f8 100644 --- a/core/src/client/mod.rs +++ b/core/src/client/mod.rs @@ -193,6 +193,16 @@ impl> Client { .await } + pub async fn get_transaction_by_block_number_and_index( + &self, + block: BlockTag, + index: u64, + ) -> Result> { + self.node + .get_transaction_by_block_number_and_index(block, index) + .await + } + pub async fn chain_id(&self) -> u64 { self.node.chain_id() } diff --git a/core/src/client/node.rs b/core/src/client/node.rs index 60e70a60..e4832b2a 100644 --- a/core/src/client/node.rs +++ b/core/src/client/node.rs @@ -144,6 +144,19 @@ impl> Node { .await } + pub async fn get_transaction_by_block_number_and_index( + &self, + block: BlockTag, + index: u64, + ) -> Result> { + self.check_blocktag_age(&block).await?; + + Ok(self + .execution + .get_transaction_by_block_number_and_index(block, index) + .await) + } + pub async fn get_logs(&self, filter: &Filter) -> Result> { self.execution.get_logs(filter).await } diff --git a/core/src/client/rpc.rs b/core/src/client/rpc.rs index 353874df..05dbf922 100644 --- a/core/src/client/rpc.rs +++ b/core/src/client/rpc.rs @@ -113,6 +113,12 @@ trait EthRpc Result, ErrorObjectOwned>; + #[method(name = "getTransactionByBlockNumberAndIndex")] + async fn get_transaction_by_block_number_and_index( + &self, + block: BlockTag, + index: U64, + ) -> Result, ErrorObjectOwned>; #[method(name = "getLogs")] async fn get_logs(&self, filter: Filter) -> Result, ErrorObjectOwned>; #[method(name = "getFilterChanges")] @@ -295,6 +301,18 @@ impl> .await) } + async fn get_transaction_by_block_number_and_index( + &self, + block: BlockTag, + index: U64, + ) -> Result, ErrorObjectOwned> { + convert_err( + self.node + .get_transaction_by_block_number_and_index(block, index.to()) + .await, + ) + } + async fn coinbase(&self) -> Result { convert_err(self.node.get_coinbase().await) } diff --git a/core/src/execution/mod.rs b/core/src/execution/mod.rs index 1a9ea612..9bb10bea 100644 --- a/core/src/execution/mod.rs +++ b/core/src/execution/mod.rs @@ -175,7 +175,17 @@ impl> ExecutionClient { index: u64, ) -> Option { self.state - .get_transaction_by_block_and_index(block_hash, index) + .get_transaction_by_block_hash_and_index(block_hash, index) + .await + } + + pub async fn get_transaction_by_block_number_and_index( + &self, + tag: BlockTag, + index: u64, + ) -> Option { + self.state + .get_transaction_by_block_and_index(tag, index) .await } diff --git a/core/src/execution/state.rs b/core/src/execution/state.rs index 3b89afa3..df053908 100644 --- a/core/src/execution/state.rs +++ b/core/src/execution/state.rs @@ -3,7 +3,10 @@ use std::{ sync::Arc, }; -use alloy::primitives::{Address, B256, U256}; +use alloy::{ + primitives::{Address, B256, U256}, + signers::k256::elliptic_curve::rand_core::block, +}; use eyre::{eyre, Result}; use tokio::{ select, @@ -108,7 +111,7 @@ impl> State { .cloned() } - pub async fn get_transaction_by_block_and_index( + pub async fn get_transaction_by_block_hash_and_index( &self, block_hash: B256, index: u64, @@ -125,6 +128,18 @@ impl> State { .cloned() } + pub async fn get_transaction_by_block_and_index( + &self, + tag: BlockTag, + index: u64, + ) -> Option { + let block = self.get_block(tag).await?; + match &block.transactions { + Transactions::Full(txs) => txs.get(index as usize).cloned(), + Transactions::Hashes(_) => unreachable!(), + } + } + // block field fetch pub async fn get_state_root(&self, tag: BlockTag) -> Option { diff --git a/helios-ts/lib.ts b/helios-ts/lib.ts index 805baee1..374e3ca3 100644 --- a/helios-ts/lib.ts +++ b/helios-ts/lib.ts @@ -110,6 +110,12 @@ export class HeliosProvider { req.params[1] ); } + case "eth_getTransactionByBlockNumberAndIndex": { + return this.#client.get_transaction_by_block_number_and_index( + req.params[0], + req.params[1] + ); + } case "eth_getBlockReceipts": { return this.#client.get_block_receipts(req.params[0]); } diff --git a/helios-ts/src/ethereum.rs b/helios-ts/src/ethereum.rs index 4a6f8b84..c4a7e9f5 100644 --- a/helios-ts/src/ethereum.rs +++ b/helios-ts/src/ethereum.rs @@ -157,6 +157,22 @@ impl EthereumClient { Ok(serde_wasm_bindgen::to_value(&tx)?) } + #[wasm_bindgen] + pub async fn get_transaction_by_block_number_and_index( + &self, + block: JsValue, + index: JsValue, + ) -> Result { + let block: BlockTag = serde_wasm_bindgen::from_value(block)?; + let index: u64 = serde_wasm_bindgen::from_value(index)?; + let tx = map_err( + self.inner + .get_transaction_by_block_number_and_index(block, index) + .await, + )?; + Ok(serde_wasm_bindgen::to_value(&tx)?) + } + #[wasm_bindgen] pub async fn get_transaction_count( &self, diff --git a/helios-ts/src/opstack.rs b/helios-ts/src/opstack.rs index b88cb329..ef3b7d14 100644 --- a/helios-ts/src/opstack.rs +++ b/helios-ts/src/opstack.rs @@ -100,6 +100,22 @@ impl OpStackClient { Ok(serde_wasm_bindgen::to_value(&tx)?) } + #[wasm_bindgen] + pub async fn get_transaction_by_block_number_and_index( + &self, + block: JsValue, + index: JsValue, + ) -> Result { + let block: BlockTag = serde_wasm_bindgen::from_value(block)?; + let index: u64 = serde_wasm_bindgen::from_value(index)?; + let tx = map_err( + self.inner + .get_transaction_by_block_number_and_index(block, index) + .await, + )?; + Ok(serde_wasm_bindgen::to_value(&tx)?) + } + #[wasm_bindgen] pub async fn get_transaction_count( &self, diff --git a/rpc.md b/rpc.md index eb5ab535..01138e1d 100644 --- a/rpc.md +++ b/rpc.md @@ -21,6 +21,7 @@ Helios provides a variety of RPC methods for interacting with the Ethereum netwo | `eth_getTransactionReceipt` | `get_transaction_receipt` | Returns the receipt of a transaction by transaction hash. | `client.get_transaction_receipt(&self, hash: &str)` | | `eth_getTransactionByHash` | `get_transaction_by_hash` | Returns the information about a transaction requested by transaction hash. | `client.get_transaction_by_hash(&self, hash: &str)` | `eth_getTransactionByBlockHashAndIndex` | `get_transaction_by_block_hash_and_index` | Returns information about a transaction by block hash and transaction index position. | `client.get_transaction_by_block_hash_and_index(&self, hash: &str, index: u64)` +| `eth_getTransactionByBlockNumberAndIndex` | `get_transaction_by_block_number_and_index` | Returns information about a transaction by block number and transaction index position. | `client.get_transaction_by_block_number_and_index(&self, block: BlockTag, index: u64)` | `eth_getBlockReceipts` | `get_block_receipts` | Returns all transaction receipts of a block by number. | `client.get_block_receipts(&self, block: BlockTag)` | | `eth_getLogs` | `get_logs` | Returns an array of logs matching the filter. | `client.get_logs(&self, filter: Filter)` | | `eth_getStorageAt` | `get_storage_at` | Returns the value from a storage position at a given address. | `client.get_storage_at(&self, address: &str, slot: H256, block: BlockTag)` | From 023ac6acedeb7257b93bfda1d5c28833237d3e10 Mon Sep 17 00:00:00 2001 From: Eshaan Bansal Date: Sun, 24 Nov 2024 00:30:01 +0530 Subject: [PATCH 2/2] fixup! imports --- core/src/execution/state.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/src/execution/state.rs b/core/src/execution/state.rs index df053908..61976443 100644 --- a/core/src/execution/state.rs +++ b/core/src/execution/state.rs @@ -3,10 +3,7 @@ use std::{ sync::Arc, }; -use alloy::{ - primitives::{Address, B256, U256}, - signers::k256::elliptic_curve::rand_core::block, -}; +use alloy::primitives::{Address, B256, U256}; use eyre::{eyre, Result}; use tokio::{ select,