diff --git a/core/src/client/mod.rs b/core/src/client/mod.rs index e30e86f8..bf636aa5 100644 --- a/core/src/client/mod.rs +++ b/core/src/client/mod.rs @@ -135,6 +135,10 @@ impl> Client { self.node.get_filter_changes(filter_id).await } + pub async fn get_filter_logs(&self, filter_id: U256) -> Result> { + self.node.get_filter_logs(filter_id).await + } + pub async fn uninstall_filter(&self, filter_id: U256) -> Result { self.node.uninstall_filter(filter_id).await } diff --git a/core/src/client/node.rs b/core/src/client/node.rs index e4832b2a..a8164d47 100644 --- a/core/src/client/node.rs +++ b/core/src/client/node.rs @@ -170,6 +170,10 @@ impl> Node { self.execution.get_filter_changes(filter_id).await } + pub async fn get_filter_logs(&self, filter_id: U256) -> Result> { + self.execution.get_filter_logs(filter_id).await + } + pub async fn uninstall_filter(&self, filter_id: U256) -> Result { self.execution.uninstall_filter(filter_id).await } diff --git a/core/src/client/rpc.rs b/core/src/client/rpc.rs index 05dbf922..23f29ad4 100644 --- a/core/src/client/rpc.rs +++ b/core/src/client/rpc.rs @@ -123,6 +123,8 @@ trait EthRpc Result, ErrorObjectOwned>; #[method(name = "getFilterChanges")] async fn get_filter_changes(&self, filter_id: U256) -> Result, ErrorObjectOwned>; + #[method(name = "getFilterLogs")] + async fn get_filter_logs(&self, filter_id: U256) -> Result, ErrorObjectOwned>; #[method(name = "uninstallFilter")] async fn uninstall_filter(&self, filter_id: U256) -> Result; #[method(name = "getNewFilter")] @@ -329,6 +331,10 @@ impl> convert_err(self.node.get_filter_changes(filter_id).await) } + async fn get_filter_logs(&self, filter_id: U256) -> Result, ErrorObjectOwned> { + convert_err(self.node.get_filter_logs(filter_id).await) + } + async fn uninstall_filter(&self, filter_id: U256) -> Result { convert_err(self.node.uninstall_filter(filter_id).await) } diff --git a/core/src/execution/mod.rs b/core/src/execution/mod.rs index 9bb10bea..dbd99884 100644 --- a/core/src/execution/mod.rs +++ b/core/src/execution/mod.rs @@ -308,6 +308,17 @@ impl> ExecutionClient { Ok(logs) } + pub async fn get_filter_logs(&self, filter_id: U256) -> Result> { + let logs = self.rpc.get_filter_logs(filter_id).await?; + if logs.len() > MAX_SUPPORTED_LOGS_NUMBER { + return Err( + ExecutionError::TooManyLogsToProve(logs.len(), MAX_SUPPORTED_LOGS_NUMBER).into(), + ); + } + self.verify_logs(&logs).await?; + Ok(logs) + } + pub async fn uninstall_filter(&self, filter_id: U256) -> Result { self.rpc.uninstall_filter(filter_id).await } diff --git a/core/src/execution/rpc/http_rpc.rs b/core/src/execution/rpc/http_rpc.rs index 525e76f4..69d89668 100644 --- a/core/src/execution/rpc/http_rpc.rs +++ b/core/src/execution/rpc/http_rpc.rs @@ -158,6 +158,14 @@ impl ExecutionRpc for HttpRpc { .map_err(|e| RpcError::new("get_filter_changes", e))?) } + async fn get_filter_logs(&self, filter_id: U256) -> Result> { + Ok(self + .provider + .raw_request("eth_getFilterLogs".into(), (filter_id,)) + .await + .map_err(|e| RpcError::new("get_filter_logs", e))?) + } + async fn uninstall_filter(&self, _filter_id: U256) -> Result { // TODO: support uninstalling Ok(true) diff --git a/core/src/execution/rpc/mock_rpc.rs b/core/src/execution/rpc/mock_rpc.rs index 1d0406c0..305f3598 100644 --- a/core/src/execution/rpc/mock_rpc.rs +++ b/core/src/execution/rpc/mock_rpc.rs @@ -77,6 +77,11 @@ impl ExecutionRpc for MockRpc { Ok(serde_json::from_str(&logs)?) } + async fn get_filter_logs(&self, _filter_id: U256) -> Result> { + let logs = read_to_string(self.path.join("logs.json"))?; + Ok(serde_json::from_str(&logs)?) + } + async fn uninstall_filter(&self, _filter_id: U256) -> Result { Err(eyre!("not implemented")) } diff --git a/core/src/execution/rpc/mod.rs b/core/src/execution/rpc/mod.rs index e4709e45..b9df878b 100644 --- a/core/src/execution/rpc/mod.rs +++ b/core/src/execution/rpc/mod.rs @@ -36,6 +36,7 @@ pub trait ExecutionRpc: Send + Clone + Sync + 'static { async fn get_transaction(&self, tx_hash: B256) -> Result>; async fn get_logs(&self, filter: &Filter) -> Result>; async fn get_filter_changes(&self, filter_id: U256) -> Result>; + async fn get_filter_logs(&self, filter_id: U256) -> Result>; async fn uninstall_filter(&self, filter_id: U256) -> Result; async fn get_new_filter(&self, filter: &Filter) -> Result; async fn get_new_block_filter(&self) -> Result; 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, diff --git a/rpc.md b/rpc.md index 01138e1d..44128557 100644 --- a/rpc.md +++ b/rpc.md @@ -24,6 +24,8 @@ Helios provides a variety of RPC methods for interacting with the Ethereum netwo | `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_getFilterChanges` | `get_filter_changes` | Polling method for a filter, which returns an array of logs which occurred since last poll. | `client.get_filter_changes(&self, filter_id: H256)` | +| `eth_getFilterLogs` | `get_filter_logs` | Returns an array of all logs matching filter with given id. | `client.get_filter_logs(&self, filter_id: H256)` | | `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)` | | `eth_getBlockTransactionCountByHash` | `get_block_transaction_count_by_hash` | Returns the number of transactions in a block from a block matching the transaction hash. | `client.get_block_transaction_count_by_hash(&self, hash: &str)` | | `eth_getBlockTransactionCountByNumber` | `get_block_transaction_count_by_number` | Returns the number of transactions in a block from a block matching the block number. | `client.get_block_transaction_count_by_number(&self, block: BlockTag)` |