@@ -12,161 +12,19 @@ use anvil::{NodeConfig, spawn};
1212#[ tokio:: test( flavor = "multi_thread" ) ]
1313async fn test_beacon_api_get_blob_sidecars ( ) {
1414 let node_config = NodeConfig :: test ( ) . with_hardfork ( Some ( EthereumHardfork :: Cancun . into ( ) ) ) ;
15- let ( api, handle) = spawn ( node_config) . await ;
16-
17- // Disable auto-mining so we can include multiple transactions in the same block
18- api. anvil_set_auto_mine ( false ) . await . unwrap ( ) ;
19-
20- let wallets = handle. dev_wallets ( ) . collect :: < Vec < _ > > ( ) ;
21- let from = wallets[ 0 ] . address ( ) ;
22- let to = wallets[ 1 ] . address ( ) ;
23-
24- let provider = http_provider ( & handle. http_endpoint ( ) ) ;
25-
26- let eip1559_est = provider. estimate_eip1559_fees ( ) . await . unwrap ( ) ;
27- let gas_price = provider. get_gas_price ( ) . await . unwrap ( ) ;
28-
29- // Create multiple blob transactions to be included in the same block
30- let blob_data =
31- [ b"Hello Beacon API - Blob 1" , b"Hello Beacon API - Blob 2" , b"Hello Beacon API - Blob 3" ] ;
32-
33- let mut pending_txs = Vec :: new ( ) ;
34-
35- // Send all transactions without waiting for receipts
36- for ( i, data) in blob_data. iter ( ) . enumerate ( ) {
37- let sidecar: SidecarBuilder < SimpleCoder > = SidecarBuilder :: from_slice ( data. as_slice ( ) ) ;
38- let sidecar = sidecar. build ( ) . unwrap ( ) ;
39-
40- let tx = TransactionRequest :: default ( )
41- . with_from ( from)
42- . with_to ( to)
43- . with_nonce ( i as u64 )
44- . with_max_fee_per_blob_gas ( gas_price + 1 )
45- . with_max_fee_per_gas ( eip1559_est. max_fee_per_gas )
46- . with_max_priority_fee_per_gas ( eip1559_est. max_priority_fee_per_gas )
47- . with_blob_sidecar ( sidecar)
48- . value ( U256 :: from ( 100 ) ) ;
49-
50- let mut tx = WithOtherFields :: new ( tx) ;
51- tx. populate_blob_hashes ( ) ;
52-
53- let pending = provider. send_transaction ( tx) . await . unwrap ( ) ;
54- pending_txs. push ( pending) ;
55- }
56-
57- // Mine a block to include all transactions
58- api. evm_mine ( None ) . await . unwrap ( ) ;
59-
60- // Get receipts for all transactions
61- let mut receipts = Vec :: new ( ) ;
62- for pending in pending_txs {
63- let receipt = pending. get_receipt ( ) . await . unwrap ( ) ;
64- receipts. push ( receipt) ;
65- }
66-
67- // Verify all transactions were included in the same block
68- let block_number = receipts[ 0 ] . block_number . unwrap ( ) ;
69- for ( i, receipt) in receipts. iter ( ) . enumerate ( ) {
70- assert_eq ! (
71- receipt. block_number. unwrap( ) ,
72- block_number,
73- "Transaction {i} was not included in block {block_number}"
74- ) ;
75- }
15+ let ( _api, handle) = spawn ( node_config) . await ;
7616
7717 // Test Beacon API endpoint using HTTP client
7818 let client = reqwest:: Client :: new ( ) ;
79- let url = format ! ( "{}/eth/v1/beacon/blob_sidecars/{} " , handle. http_endpoint( ) , block_number ) ;
19+ let url = format ! ( "{}/eth/v1/beacon/blob_sidecars/latest " , handle. http_endpoint( ) ) ;
8020
21+ // This endpoint is deprecated, so we expect a 410 Gone response
8122 let response = client. get ( & url) . send ( ) . await . unwrap ( ) ;
82- assert_eq ! ( response. status( ) , reqwest:: StatusCode :: OK ) ;
83-
84- let body: serde_json:: Value = response. json ( ) . await . unwrap ( ) ;
85-
86- // Verify response structure
87- assert ! ( body[ "data" ] . is_array( ) ) ;
88- assert ! ( body[ "execution_optimistic" ] . is_boolean( ) ) ;
89- assert ! ( body[ "finalized" ] . is_boolean( ) ) ;
90-
91- // Verify we have blob data from all transactions
92- let blobs = body[ "data" ] . as_array ( ) . unwrap ( ) ;
93- assert_eq ! ( blobs. len( ) , 3 , "Expected 3 blob sidecars from 3 transactions" ) ;
94-
95- // Verify blob structure for each blob
96- for ( i, blob) in blobs. iter ( ) . enumerate ( ) {
97- assert ! ( blob[ "index" ] . is_string( ) , "Blob {i} missing index" ) ;
98- assert ! ( blob[ "blob" ] . is_string( ) , "Blob {i} missing blob data" ) ;
99- assert ! ( blob[ "kzg_commitment" ] . is_string( ) , "Blob {i} missing kzg_commitment" ) ;
100- assert ! ( blob[ "kzg_proof" ] . is_string( ) , "Blob {i} missing kzg_proof" ) ;
101- }
102-
103- // Test filtering with indices query parameter - single index
104- let url = format ! (
105- "{}/eth/v1/beacon/blob_sidecars/{}?indices=1" ,
106- handle. http_endpoint( ) ,
107- block_number
108- ) ;
109- let response = client. get ( & url) . send ( ) . await . unwrap ( ) ;
110- let status = response. status ( ) ;
111- if status != reqwest:: StatusCode :: OK {
112- let error_body = response. text ( ) . await . unwrap ( ) ;
113- panic ! ( "Expected OK status, got {status}: {error_body}" ) ;
114- }
115- let body: serde_json:: Value = response. json ( ) . await . unwrap ( ) ;
116- let filtered_blobs = body[ "data" ] . as_array ( ) . unwrap ( ) ;
117- assert_eq ! ( filtered_blobs. len( ) , 1 , "Expected 1 blob sidecar when filtering by indices=1" ) ;
118- assert_eq ! ( filtered_blobs[ 0 ] [ "index" ] . as_str( ) . unwrap( ) , "1" ) ;
119-
120- // Test filtering with indices query parameter - multiple indices (comma-separated)
121- let url = format ! (
122- "{}/eth/v1/beacon/blob_sidecars/{}?indices=0,2" ,
123- handle. http_endpoint( ) ,
124- block_number
125- ) ;
126- let response = client. get ( & url) . send ( ) . await . unwrap ( ) ;
127- assert_eq ! ( response. status( ) , reqwest:: StatusCode :: OK ) ;
128- let body: serde_json:: Value = response. json ( ) . await . unwrap ( ) ;
129- let filtered_blobs = body[ "data" ] . as_array ( ) . unwrap ( ) ;
130- assert_eq ! ( filtered_blobs. len( ) , 2 , "Expected 2 blob sidecars when filtering by indices=0,2" ) ;
131- let indices: Vec < String > =
132- filtered_blobs. iter ( ) . map ( |b| b[ "index" ] . as_str ( ) . unwrap ( ) . to_string ( ) ) . collect ( ) ;
133- assert ! ( indices. contains( & "0" . to_string( ) ) , "Expected index 0 in results" ) ;
134- assert ! ( indices. contains( & "2" . to_string( ) ) , "Expected index 2 in results" ) ;
135-
136- // Test filtering with non-existent index
137- let url = format ! (
138- "{}/eth/v1/beacon/blob_sidecars/{}?indices=99" ,
139- handle. http_endpoint( ) ,
140- block_number
141- ) ;
142- let response = client. get ( & url) . send ( ) . await . unwrap ( ) ;
143- assert_eq ! ( response. status( ) , reqwest:: StatusCode :: OK ) ;
144- let body: serde_json:: Value = response. json ( ) . await . unwrap ( ) ;
145- let filtered_blobs = body[ "data" ] . as_array ( ) . unwrap ( ) ;
14623 assert_eq ! (
147- filtered_blobs . len ( ) ,
148- 0 ,
149- "Expected 0 blob sidecars when filtering by non-existent index "
24+ response . text ( ) . await . unwrap ( ) ,
25+ r#"{"code":410,"message":"This endpoint is deprecated. Use `GET /eth/v1/beacon/blobs/{block_id}` instead."}"# ,
26+ "Expected deprecation message for blob_sidecars endpoint "
15027 ) ;
151-
152- // Test with special block identifiers
153- let test_ids = vec ! [ "latest" , "finalized" , "safe" , "earliest" ] ;
154- for block_id in test_ids {
155- let url = format ! ( "{}/eth/v1/beacon/blob_sidecars/{}" , handle. http_endpoint( ) , block_id) ;
156- assert_eq ! ( client. get( & url) . send( ) . await . unwrap( ) . status( ) , reqwest:: StatusCode :: OK ) ;
157- }
158- let url = format ! ( "{}/eth/v1/beacon/blob_sidecars/pending" , handle. http_endpoint( ) ) ;
159- assert_eq ! ( client. get( & url) . send( ) . await . unwrap( ) . status( ) , reqwest:: StatusCode :: NOT_FOUND ) ;
160-
161- // Test with hex block number
162- let url = format ! ( "{}/eth/v1/beacon/blob_sidecars/0x{block_number:x}" , handle. http_endpoint( ) ) ;
163- let response = client. get ( & url) . send ( ) . await . unwrap ( ) ;
164- assert_eq ! ( response. status( ) , reqwest:: StatusCode :: OK ) ;
165-
166- // Test with non-existent block
167- let url = format ! ( "{}/eth/v1/beacon/blob_sidecars/999999" , handle. http_endpoint( ) ) ;
168- let response = client. get ( & url) . send ( ) . await . unwrap ( ) ;
169- assert_eq ! ( response. status( ) , reqwest:: StatusCode :: NOT_FOUND ) ;
17028}
17129
17230#[ tokio:: test( flavor = "multi_thread" ) ]
0 commit comments