@@ -8,7 +8,7 @@ use alloy::{
88 eips:: BlockNumberOrTag ,
99 network:: { BlockResponse , ReceiptResponse } ,
1010 primitives:: { Address , B256 , U256 } ,
11- rpc:: types:: { BlockId , BlockTransactionsKind , Log } ,
11+ rpc:: types:: { BlockId , BlockTransactionsKind , FilterChanges , Log } ,
1212} ;
1313use axum:: {
1414 extract:: { Path , Query , State } ,
@@ -20,7 +20,7 @@ use futures::future::try_join_all;
2020use serde:: { de:: DeserializeOwned , Deserialize , Serialize } ;
2121use serde_json:: json;
2222
23- use helios_core:: { execution:: rpc:: ExecutionRpc , network_spec:: NetworkSpec , types :: BlockTag } ;
23+ use helios_core:: { execution:: rpc:: ExecutionRpc , network_spec:: NetworkSpec } ;
2424use helios_verifiable_api:: { proof:: create_receipt_proof, rpc_client:: ExecutionClient , types:: * } ;
2525
2626use crate :: ApiState ;
@@ -42,6 +42,34 @@ pub struct BlockQuery {
4242 block : Option < BlockId > ,
4343}
4444
45+ #[ derive( Deserialize ) ]
46+ pub struct AccountProofQuery {
47+ pub block : Option < BlockId > ,
48+ pub storage_keys : Vec < B256 > ,
49+ }
50+
51+ /// This method returns the account proof for a given address.
52+ ///
53+ /// Replaces the `eth_getProof` RPC method.
54+ pub async fn get_account_proof < N : NetworkSpec , R : ExecutionRpc < N > > (
55+ Path ( address) : Path < Address > ,
56+ Query ( AccountProofQuery {
57+ block,
58+ storage_keys,
59+ } ) : Query < AccountProofQuery > ,
60+ State ( ApiState { execution_client } ) : State < ApiState < N , R > > ,
61+ ) -> Response < GetAccountProofResponse > {
62+ let block = block. unwrap_or ( BlockId :: latest ( ) ) ;
63+
64+ let proof = execution_client
65+ . rpc
66+ . get_proof ( address, & storage_keys, block)
67+ . await
68+ . map_err ( map_server_err) ?;
69+
70+ Ok ( Json ( proof) )
71+ }
72+
4573/// This method returns the balance of an account for a given address,
4674/// along with the Merkle proof of the account's inclusion in the state trie.
4775///
@@ -178,7 +206,7 @@ pub async fn get_storage_at<N: NetworkSpec, R: ExecutionRpc<N>>(
178206
179207 let proof = execution_client
180208 . rpc
181- . get_proof ( address, & [ storage_slot. into ( ) ] , block)
209+ . get_proof ( address, & [ storage_slot] , block)
182210 . await
183211 . map_err ( map_server_err) ?;
184212
@@ -204,6 +232,25 @@ pub async fn get_storage_at<N: NetworkSpec, R: ExecutionRpc<N>>(
204232 } ) )
205233}
206234
235+ /// This method returns all transaction receipts for a given block.
236+ ///
237+ /// Replaces the `eth_getBlockReceipts` RPC method.
238+ pub async fn get_block_receipts < N : NetworkSpec , R : ExecutionRpc < N > > (
239+ Path ( block) : Path < Option < BlockId > > ,
240+ State ( ApiState { execution_client } ) : State < ApiState < N , R > > ,
241+ ) -> Response < GetBlockReceiptsResponse < N > > {
242+ let block = block. unwrap_or ( BlockId :: latest ( ) ) ;
243+
244+ let receipts = execution_client
245+ . rpc
246+ . get_block_receipts ( block)
247+ . await
248+ . map_err ( map_server_err) ?
249+ . unwrap_or ( vec ! [ ] ) ;
250+
251+ Ok ( Json ( receipts) )
252+ }
253+
207254/// This method returns the receipt of a transaction along with a Merkle proof of its inclusion.
208255///
209256/// Replaces the `eth_getTransactionReceipt` RPC method.
@@ -225,7 +272,7 @@ pub async fn get_transaction_receipt<N: NetworkSpec, R: ExecutionRpc<N>>(
225272
226273 let receipts = execution_client
227274 . rpc
228- . get_block_receipts ( BlockTag :: Number ( receipt. block_number ( ) . unwrap ( ) ) )
275+ . get_block_receipts ( BlockId :: from ( receipt. block_number ( ) . unwrap ( ) ) )
229276 . await
230277 . map_err ( map_server_err) ?
231278 . ok_or_else ( || {
@@ -270,6 +317,41 @@ pub async fn get_filter_logs<N: NetworkSpec, R: ExecutionRpc<N>>(
270317 } ) )
271318}
272319
320+ /// This method returns the changes since the last poll for a given filter id.
321+ /// If filter is of logs type, then corresponding to each log,
322+ /// it also returns the transaction receipt and a Merkle proof of its inclusion..
323+ ///
324+ /// Replaces the `eth_getFilterChanges` RPC method.
325+ pub async fn get_filter_changes < N : NetworkSpec , R : ExecutionRpc < N > > (
326+ Path ( filter_id) : Path < U256 > ,
327+ State ( ApiState { execution_client } ) : State < ApiState < N , R > > ,
328+ ) -> Response < GetFilterChangesResponse < N > > {
329+ let filter_changes = execution_client
330+ . rpc
331+ . get_filter_changes ( filter_id)
332+ . await
333+ . map_err ( map_server_err) ?;
334+
335+ Ok ( Json ( match filter_changes {
336+ FilterChanges :: Logs ( logs) => {
337+ // Create receipt proofs for each log
338+ let receipt_proofs = create_receipt_proofs_for_logs ( & logs, execution_client)
339+ . await
340+ . map_err ( map_server_err) ?;
341+
342+ GetFilterChangesResponse :: Logs ( GetFilterLogsResponse {
343+ logs,
344+ receipt_proofs,
345+ } )
346+ }
347+ FilterChanges :: Hashes ( hashes) => GetFilterChangesResponse :: Hashes ( hashes) ,
348+ FilterChanges :: Empty => GetFilterChangesResponse :: Hashes ( vec ! [ ] ) ,
349+ FilterChanges :: Transactions ( txs) => GetFilterChangesResponse :: Hashes (
350+ txs. into_iter ( ) . map ( |t| t. inner . tx_hash ( ) . clone ( ) ) . collect ( ) ,
351+ ) ,
352+ } ) )
353+ }
354+
273355async fn create_receipt_proofs_for_logs < N : NetworkSpec , R : ExecutionRpc < N > > (
274356 logs : & [ Log ] ,
275357 execution_client : Arc < ExecutionClient < N , R > > ,
@@ -284,8 +366,8 @@ async fn create_receipt_proofs_for_logs<N: NetworkSpec, R: ExecutionRpc<N>>(
284366 let blocks_receipts_fut = block_nums. into_iter ( ) . map ( |block_num| {
285367 let execution_client = Arc :: clone ( & execution_client) ;
286368 async move {
287- let tag = BlockTag :: Number ( block_num) ;
288- let receipts = execution_client. rpc . get_block_receipts ( tag ) . await ?;
369+ let block_id = BlockId :: from ( block_num) ;
370+ let receipts = execution_client. rpc . get_block_receipts ( block_id ) . await ?;
289371 receipts
290372 . ok_or_eyre ( "No receipts found for the block" )
291373 . map ( |receipts| ( block_num, receipts) )
0 commit comments