alloy_zksync/provider/
mod.rs

1//! ZKsync provider.
2
3pub use self::{
4    deposit::{DepositExecutor, DepositRequest},
5    l1_communication_error::L1CommunicationError,
6    l1_transaction_receipt::L1TransactionReceipt,
7    provider_builder_ext::ProviderBuilderExt,
8};
9use crate::{
10    network::{Zksync, transaction_request::TransactionRequest},
11    types::*,
12};
13use alloy::{
14    network::Ethereum,
15    primitives::{Address, B256, Bytes, U64, U256},
16    providers::{
17        Identity, Provider, ProviderBuilder, ProviderCall, WalletProvider,
18        fillers::{ChainIdFiller, JoinFill, NonceFiller, RecommendedFillers},
19    },
20    rpc::client::NoParams,
21    transports::{BoxTransport, Transport},
22};
23use fillers::Eip712FeeFiller;
24use std::collections::HashMap;
25
26mod deposit;
27pub mod fillers;
28mod l1_communication_error;
29mod l1_transaction_receipt;
30pub mod layers;
31mod provider_builder_ext;
32
33type GetMsgProofRequest = (u64, Address, B256, Option<usize>);
34
35/// ZKsync provider is an extension trait for the [`Provider`](https://docs.rs/alloy/latest/alloy/providers/trait.Provider.html)
36/// trait that adds ZKsync-specific methods.
37///
38/// This trait has a blanket implementation for any type that implements
39/// `Provider` trait. It means that it can be built using normal [`ProviderBuilder`](https://docs.rs/alloy/latest/alloy/providers/struct.ProviderBuilder.html)
40/// by specifying the network generic parameter.
41///
42/// For convenience, you can use [`zksync_provider`] function instead.
43#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
44#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
45pub trait ZksyncProvider<T = BoxTransport>: Provider<Zksync>
46where
47    T: Transport + Clone,
48{
49    /// Gets the address of the main ZKsync contract on L1.
50    fn get_main_contract(&self) -> ProviderCall<NoParams, Address> {
51        self.client().request_noparams("zks_getMainContract").into()
52    }
53
54    /// Gets the address of the testnet paymaster ZKsync contract on L2, if it's present on the network.
55    fn get_testnet_paymaster(&self) -> ProviderCall<NoParams, Option<Address>> {
56        self.client()
57            .request_noparams("zks_getTestnetPaymaster")
58            .into()
59    }
60
61    /// Gets the L1 Chain ID.
62    fn get_l1_chain_id(&self) -> ProviderCall<NoParams, U64> {
63        self.client().request_noparams("zks_L1ChainId").into()
64    }
65
66    /// Gets the latest L1 batch number.
67    fn get_l1_batch_number(&self) -> ProviderCall<NoParams, U64> {
68        self.client().request_noparams("zks_L1BatchNumber").into()
69    }
70
71    /// Estimates transaction gas for a transaction.
72    fn estimate_fee(
73        &self,
74        tx: TransactionRequest,
75    ) -> ProviderCall<(TransactionRequest,), Eip712Fee> {
76        self.client().request("zks_estimateFee", (tx,)).into()
77    }
78
79    /// Estimates the gas required for an L1 to L2 transaction.
80    fn estimate_gas_l1_to_l2(
81        &self,
82        tx: TransactionRequest,
83    ) -> ProviderCall<(TransactionRequest,), U256> {
84        self.client().request("zks_estimateGasL1ToL2", (tx,)).into()
85    }
86
87    /// Retrieves the bridge hub contract address.
88    fn get_bridgehub_contract(&self) -> ProviderCall<NoParams, Option<Address>> {
89        self.client()
90            .request_noparams("zks_getBridgehubContract")
91            .into()
92    }
93
94    /// Retrieves the addresses of canonical bridge contracts for ZKsync Era.
95    fn get_bridge_contracts(&self) -> ProviderCall<NoParams, BridgeAddresses> {
96        self.client()
97            .request_noparams("zks_getBridgeContracts")
98            .into()
99    }
100
101    /// Retrieves the L1 base token address.
102    fn get_base_token_l1_address(&self) -> ProviderCall<NoParams, Address> {
103        self.client()
104            .request_noparams("zks_getBaseTokenL1Address")
105            .into()
106    }
107
108    /// Gets all account balances for a given address.
109    ///
110    /// ## Parameters
111    ///
112    /// - `address`: an account address.
113    ///
114    /// ## Returns
115    ///
116    /// A hashmap with token addresses as keys and their corresponding balances as values.
117    /// Each key-value pair represents the balance of a specific token held by the account.
118    fn get_all_account_balances(
119        &self,
120        address: Address,
121    ) -> ProviderCall<(Address,), HashMap<Address, U256>> {
122        self.client()
123            .request("zks_getAllAccountBalances", (address,))
124            .into()
125    }
126
127    /// Retrieves the proof for an L2 to L1 message.
128    ///
129    /// ## Parameters
130    ///
131    /// - `block_number`: the block number where the message was emitted.
132    /// - `sender`: The sender of the message.
133    /// - `msg`: The keccak256 hash of the sent message.
134    /// - `l2_log_position`:  Optional: The index in the block of the event that was emitted by the L1Messenger when submitting this message.
135    /// If it is omitted, the proof for the first message is returned.
136    fn get_l2_to_l1_msg_proof(
137        &self,
138        block_number: u64,
139        sender: Address,
140        msg: B256,
141        l2_log_position: Option<usize>,
142    ) -> ProviderCall<GetMsgProofRequest, Option<L2ToL1LogProof>> {
143        self.client()
144            .request(
145                "zks_getL2ToL1MsgProof",
146                (block_number, sender, msg, l2_log_position),
147            )
148            .into()
149    }
150
151    /// Retrieves the log proof for an L2 to L1 transaction.
152    ///
153    /// # Parameters
154    ///
155    /// - `tx_hash`: hash of the L2 transaction the L2 to L1 log was produced in.
156    /// - `l2_to_l1_log_index`: Optional: The index of the L2 to L1 log in the transaction.
157    fn get_l2_to_l1_log_proof(
158        &self,
159        tx_hash: B256,
160        l2_to_l1_log_index: Option<usize>,
161    ) -> ProviderCall<(B256, Option<usize>), Option<L2ToL1LogProof>> {
162        self.client()
163            .request("zks_getL2ToL1LogProof", (tx_hash, l2_to_l1_log_index))
164            .into()
165    }
166
167    /// Retrieves details for a given L2 block.
168    fn get_block_details(&self, block_number: u64) -> ProviderCall<(u64,), Option<BlockDetails>> {
169        self.client()
170            .request("zks_getBlockDetails", (block_number,))
171            .into()
172    }
173
174    /// Retrieves details for a given transaction.
175    fn get_transaction_details(
176        &self,
177        tx_hash: B256,
178    ) -> ProviderCall<(B256,), Option<TransactionDetails>> {
179        self.client()
180            .request("zks_getTransactionDetails", (tx_hash,))
181            .into()
182    }
183
184    /// Lists transactions in a native encoding (e.g. that has more details, but does not
185    /// adhere to the "common" Web3 Transaction interface).
186    fn get_raw_block_transactions(
187        &self,
188        block_number: u64,
189    ) -> ProviderCall<(u64,), Vec<Transaction>> {
190        self.client()
191            .request("zks_getRawBlockTransactions", (block_number,))
192            .into()
193    }
194
195    /// Retrieves details for a given L1 batch.
196    fn get_l1_batch_details(
197        &self,
198        l1_batch_number: u64,
199    ) -> ProviderCall<(u64,), Option<L1BatchDetails>> {
200        self.client()
201            .request("zks_getL1BatchDetails", (l1_batch_number,))
202            .into()
203    }
204
205    /// Retrieves the bytecode of a transaction by its hash.
206    fn get_bytecode_by_hash(&self, tx_hash: B256) -> ProviderCall<(B256,), Option<Bytes>> {
207        self.client()
208            .request("zks_getBytecodeByHash", (tx_hash,))
209            .into()
210    }
211
212    /// Returns the range of blocks contained within a batch given by the batch number.
213    fn get_l1_batch_block_range(
214        &self,
215        l1_batch_number: u64,
216    ) -> ProviderCall<(u64,), Option<(U64, U64)>> {
217        self.client()
218            .request("zks_getL1BatchBlockRange", (l1_batch_number,))
219            .into()
220    }
221
222    /// Retrieves the current L1 gas price.
223    fn get_l1_gas_price(&self) -> ProviderCall<NoParams, U256> {
224        self.client().request_noparams("zks_getL1GasPrice").into()
225    }
226
227    /// Retrieves the current fee parameters.
228    fn get_fee_params(&self) -> ProviderCall<NoParams, FeeParams> {
229        self.client().request_noparams("zks_getFeeParams").into()
230    }
231
232    /// Gets the protocol version.
233    fn get_protocol_version(
234        &self,
235        version_id: Option<u16>,
236    ) -> ProviderCall<(Option<u16>,), Option<ProtocolVersion>> {
237        self.client()
238            .request("zks_getProtocolVersion", (version_id,))
239            .into()
240    }
241
242    /// Generates Merkle proofs for one or more storage values associated with a specific account,
243    /// accompanied by a proof of their authenticity. It verifies that these values remain unaltered.
244    ///
245    /// ## Parameters
246    ///
247    /// - `address`: account address to fetch storage values and proofs for.
248    /// - `keys`: the keys in the account.
249    /// - `l1_batch_number`: number of the L1 batch specifying the point in time at which the requested values are returned.
250    ///
251    /// ## Returns
252    ///
253    /// The account details and proofs for storage keys.
254    fn get_proof(
255        &self,
256        address: Address,
257        keys: Vec<B256>,
258        l1_batch_number: u64,
259    ) -> ProviderCall<(Address, Vec<B256>, u64), Option<Proof>> {
260        self.client()
261            .request("zks_getProof", (address, keys, l1_batch_number))
262            .into()
263    }
264}
265
266/// Trait for ZKsync provider with populated wallet
267/// Contains provider methods that need a wallet
268#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
269#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
270pub trait ZksyncProviderWithWallet<T = BoxTransport>:
271    ZksyncProvider + WalletProvider<Zksync>
272{
273    /// Deposits specified L1 token to the L2 address.
274    ///
275    /// ## Parameters
276    ///
277    /// - `deposit_request`: deposit request which contains deposit params including amount, token to deposit etc.
278    /// - `l1_provider`: reference to the L1 provider.
279    ///
280    /// ## Returns
281    ///
282    /// L1TransactionReceipt.
283    /// Hint: use returned L1 transaction receipt to get corresponding L2 transaction and wait for its receipt
284    /// E.g.: deposit_l1_receipt.get_l2_tx()?.with_required_confirmations(1).with_timeout(Some(std::time::Duration::from_secs(60 * 5))).get_receipt()
285    async fn deposit<P>(
286        &self,
287        deposit_request: &DepositRequest,
288        l1_provider: &P,
289    ) -> Result<L1TransactionReceipt, L1CommunicationError>
290    where
291        P: alloy::providers::Provider<Ethereum>,
292    {
293        let deposit_executor = DepositExecutor::new(l1_provider, self, deposit_request);
294        deposit_executor.execute().await
295    }
296}
297
298impl<P> ZksyncProviderWithWallet for P where P: WalletProvider<Zksync> + Provider<Zksync> {}
299
300impl<P> ZksyncProvider for P where P: Provider<Zksync> {}
301
302impl RecommendedFillers for Zksync {
303    type RecommendedFillers = JoinFill<Eip712FeeFiller, JoinFill<NonceFiller, ChainIdFiller>>;
304
305    fn recommended_fillers() -> Self::RecommendedFillers {
306        JoinFill::new(
307            Eip712FeeFiller::default(),
308            JoinFill::new(NonceFiller::default(), ChainIdFiller::default()),
309        )
310    }
311}
312
313/// Convenience function to initialize provider builder for ZKsync network.
314pub fn zksync_provider() -> ProviderBuilder<Identity, Identity, Zksync> {
315    ProviderBuilder::<Identity, Identity, Zksync>::default()
316}
317
318#[cfg(test)]
319mod tests {
320    use std::str::FromStr;
321
322    use super::*;
323    use alloy::hex::FromHex;
324    use alloy::primitives::address;
325    use alloy::primitives::{Address, Bytes, U256};
326    use alloy::providers::{RootProvider, fillers::FillProvider};
327    use std::net::SocketAddr;
328
329    use crate::network::unsigned_tx::eip712::PaymasterParams;
330    use alloy::network::TransactionBuilder;
331    use chrono::{DateTime, Utc};
332    use jsonrpsee::core::RpcResult;
333    use jsonrpsee::server::{RpcModule, Server};
334    use std::future::Future;
335
336    fn str_to_utc(date_utc_str: &str) -> DateTime<Utc> {
337        DateTime::parse_from_rfc3339(date_utc_str)
338            .unwrap()
339            .with_timezone(&Utc)
340    }
341    type ZKsyncTestProvider = FillProvider<
342        JoinFill<Identity, JoinFill<Eip712FeeFiller, JoinFill<NonceFiller, ChainIdFiller>>>,
343        RootProvider<Zksync>,
344        Zksync,
345    >;
346    async fn run_server_and_test<Fut>(
347        register_rpc_module_fn: impl FnOnce(&mut RpcModule<()>),
348        test_fn: impl FnOnce(ZKsyncTestProvider) -> Fut,
349    ) where
350        Fut: Future<Output = ()>,
351    {
352        let server = Server::builder()
353            .build("127.0.0.1:0".parse::<SocketAddr>().unwrap())
354            .await
355            .unwrap();
356        let mut module = RpcModule::new(());
357        register_rpc_module_fn(&mut module);
358
359        let server_addr: SocketAddr = server.local_addr().unwrap();
360        let handle = server.start(module);
361        let full_addr = format!("http://{server_addr}");
362        tokio::spawn(handle.stopped());
363
364        let provider = zksync_provider()
365            .with_recommended_fillers()
366            .connect_http(full_addr.parse().unwrap());
367        test_fn(provider).await;
368    }
369
370    #[tokio::test(flavor = "multi_thread")]
371    async fn get_main_contract_test() {
372        let network_main_contract_address = address!("32400084c286cf3e17e7b677ea9583e60a000324");
373        run_server_and_test(
374            |module| {
375                module
376                    .register_method::<RpcResult<Address>, _>(
377                        "zks_getMainContract",
378                        move |_, _, _| Ok(network_main_contract_address),
379                    )
380                    .unwrap();
381            },
382            |provider: ZKsyncTestProvider| async move {
383                let received_main_contract_address = provider.get_main_contract().await.unwrap();
384                assert_eq!(
385                    network_main_contract_address,
386                    received_main_contract_address
387                );
388            },
389        )
390        .await;
391    }
392
393    #[tokio::test(flavor = "multi_thread")]
394    async fn get_testnet_paymaster_when_its_not_set() {
395        run_server_and_test(
396            |module| {
397                module
398                    .register_method::<RpcResult<Option<Address>>, _>(
399                        "zks_getTestnetPaymaster",
400                        move |_, _, _| Ok(None),
401                    )
402                    .unwrap();
403            },
404            |provider: ZKsyncTestProvider| async move {
405                let received_paymaster_address = provider.get_testnet_paymaster().await.unwrap();
406                assert_eq!(received_paymaster_address, None);
407            },
408        )
409        .await;
410    }
411
412    #[tokio::test(flavor = "multi_thread")]
413    async fn get_testnet_paymaster_when_its_set() {
414        let network_testnet_address = address!("3cb2b87d10ac01736a65688f3e0fb1b070b3eea3");
415        run_server_and_test(
416            |module| {
417                module
418                    .register_method::<RpcResult<Option<Address>>, _>(
419                        "zks_getTestnetPaymaster",
420                        move |_, _, _| Ok(Some(network_testnet_address)),
421                    )
422                    .unwrap();
423            },
424            |provider: ZKsyncTestProvider| async move {
425                let received_paymaster_address = provider.get_testnet_paymaster().await.unwrap();
426                assert_eq!(received_paymaster_address.unwrap(), network_testnet_address);
427            },
428        )
429        .await;
430    }
431
432    #[tokio::test(flavor = "multi_thread")]
433    async fn get_l1_chain_id_test() {
434        let network_l1_chain_id = U64::from(1);
435        run_server_and_test(
436            |module| {
437                module
438                    .register_method::<RpcResult<U64>, _>("zks_L1ChainId", move |_, _, _| {
439                        Ok(network_l1_chain_id)
440                    })
441                    .unwrap();
442            },
443            |provider: ZKsyncTestProvider| async move {
444                let received_l1_chain_id = provider.get_l1_chain_id().await.unwrap();
445                assert_eq!(network_l1_chain_id, received_l1_chain_id);
446            },
447        )
448        .await;
449    }
450
451    #[tokio::test(flavor = "multi_thread")]
452    async fn get_l1_batch_number_test() {
453        let network_l1_batch_number = U64::from(12345);
454        run_server_and_test(
455            |module| {
456                module
457                    .register_method::<RpcResult<U64>, _>("zks_L1BatchNumber", move |_, _, _| {
458                        Ok(network_l1_batch_number)
459                    })
460                    .unwrap();
461            },
462            |provider: ZKsyncTestProvider| async move {
463                let received_l1_batch_number = provider.get_l1_batch_number().await.unwrap();
464                assert_eq!(network_l1_batch_number, received_l1_batch_number);
465            },
466        )
467        .await;
468    }
469
470    #[tokio::test(flavor = "multi_thread")]
471    async fn estimate_fee_test() {
472        let network_fee = Eip712Fee {
473            gas_limit: 40000,
474            gas_per_pubdata_limit: U256::from(90000),
475            max_fee_per_gas: 60000,
476            max_priority_fee_per_gas: 70000,
477        };
478
479        let tx_request = TransactionRequest::default()
480            .with_to(address!("1111111111111111111111111111111111111111"))
481            .with_from(address!("2222222222222222222222222222222222222222"));
482        let network_fee_rpc_response = network_fee.clone();
483
484        run_server_and_test(
485            move |module| {
486                module
487                    .register_method::<RpcResult<Eip712Fee>, _>(
488                        "zks_estimateFee",
489                        move |params, _, _| {
490                            let (tx_request_param,) =
491                                params.parse::<(TransactionRequest,)>().unwrap();
492                            assert_eq!(
493                                tx_request_param.to().unwrap(),
494                                address!("1111111111111111111111111111111111111111")
495                            );
496                            assert_eq!(
497                                tx_request_param.from().unwrap(),
498                                address!("2222222222222222222222222222222222222222")
499                            );
500                            Ok(network_fee_rpc_response.clone())
501                        },
502                    )
503                    .unwrap();
504            },
505            |provider: ZKsyncTestProvider| async move {
506                let received_fee = provider.estimate_fee(tx_request).await.unwrap();
507                assert_eq!(network_fee, received_fee);
508            },
509        )
510        .await;
511    }
512
513    #[tokio::test(flavor = "multi_thread")]
514    async fn estimate_gas_l1_to_l2_test() {
515        let network_gas_estimation = U256::from(6789);
516
517        let tx_request = TransactionRequest::default()
518            .with_to(address!("1111111111111111111111111111111111111111"))
519            .with_from(address!("2222222222222222222222222222222222222222"));
520
521        run_server_and_test(
522            |module| {
523                module
524                    .register_method::<RpcResult<U256>, _>(
525                        "zks_estimateGasL1ToL2",
526                        move |params, _, _| {
527                            let (tx_request,) = params.parse::<(TransactionRequest,)>().unwrap();
528                            assert_eq!(
529                                tx_request.to().unwrap(),
530                                address!("1111111111111111111111111111111111111111")
531                            );
532                            assert_eq!(
533                                tx_request.from().unwrap(),
534                                address!("2222222222222222222222222222222222222222")
535                            );
536                            Ok(network_gas_estimation)
537                        },
538                    )
539                    .unwrap();
540            },
541            |provider: ZKsyncTestProvider| async move {
542                let received_gas_estimation =
543                    provider.estimate_gas_l1_to_l2(tx_request).await.unwrap();
544                assert_eq!(network_gas_estimation, received_gas_estimation);
545            },
546        )
547        .await;
548    }
549
550    #[tokio::test(flavor = "multi_thread")]
551    async fn get_bridgehub_contract_when_its_not_set() {
552        run_server_and_test(
553            |module| {
554                module
555                    .register_method::<RpcResult<Option<Address>>, _>(
556                        "zks_getBridgehubContract",
557                        move |_, _, _| Ok(None),
558                    )
559                    .unwrap();
560            },
561            |provider: ZKsyncTestProvider| async move {
562                let received_bridge_hub_address = provider.get_bridgehub_contract().await.unwrap();
563                assert_eq!(received_bridge_hub_address, None);
564            },
565        )
566        .await;
567    }
568
569    #[tokio::test(flavor = "multi_thread")]
570    async fn get_bridgehub_contract_when_its_set() {
571        let network_bridge_hub_address = address!("3cb2b87d10ac01736a65688f3e0fb1b070b3eea3");
572        run_server_and_test(
573            |module| {
574                module
575                    .register_method::<RpcResult<Option<Address>>, _>(
576                        "zks_getBridgehubContract",
577                        move |_, _, _| Ok(Some(network_bridge_hub_address)),
578                    )
579                    .unwrap();
580            },
581            |provider: ZKsyncTestProvider| async move {
582                let received_bridge_hub_address = provider.get_bridgehub_contract().await.unwrap();
583                assert_eq!(
584                    received_bridge_hub_address.unwrap(),
585                    network_bridge_hub_address
586                );
587            },
588        )
589        .await;
590    }
591
592    #[tokio::test(flavor = "multi_thread")]
593    async fn get_bridge_contracts_test() {
594        let network_bridge_addresses = BridgeAddresses {
595            l1_shared_default_bridge: Some(address!("1111111111111111111111111111111111111111")),
596            l2_shared_default_bridge: Some(address!("2222222222222222222222222222222222222222")),
597            l1_erc20_default_bridge: Some(address!("3333333333333333333333333333333333333333")),
598            l2_erc20_default_bridge: Some(address!("4444444444444444444444444444444444444444")),
599            l1_weth_bridge: Some(address!("5555555555555555555555555555555555555555")),
600            l2_weth_bridge: Some(address!("6666666666666666666666666666666666666666")),
601            l2_legacy_shared_bridge: Some(address!("7777777777777777777777777777777777777777")),
602        };
603
604        let network_bridge_addresses_rpc_response = network_bridge_addresses.clone();
605        run_server_and_test(
606            |module| {
607                module
608                    .register_method::<RpcResult<BridgeAddresses>, _>(
609                        "zks_getBridgeContracts",
610                        move |_, _, _| Ok(network_bridge_addresses_rpc_response.clone()),
611                    )
612                    .unwrap();
613            },
614            |provider: ZKsyncTestProvider| async move {
615                let received_bridge_addresses = provider.get_bridge_contracts().await.unwrap();
616                assert_eq!(received_bridge_addresses, network_bridge_addresses);
617            },
618        )
619        .await;
620    }
621
622    #[tokio::test(flavor = "multi_thread")]
623    async fn get_base_token_l1_address_test() {
624        let network_base_token_l1_address = address!("7777777777777777777777777777777777777777");
625        run_server_and_test(
626            |module| {
627                module
628                    .register_method::<RpcResult<Address>, _>(
629                        "zks_getBaseTokenL1Address",
630                        move |_, _, _| Ok(network_base_token_l1_address),
631                    )
632                    .unwrap();
633            },
634            |provider: ZKsyncTestProvider| async move {
635                let received_base_token_l1_address =
636                    provider.get_base_token_l1_address().await.unwrap();
637                assert_eq!(
638                    network_base_token_l1_address,
639                    received_base_token_l1_address
640                );
641            },
642        )
643        .await;
644    }
645
646    #[tokio::test(flavor = "multi_thread")]
647    async fn get_all_account_balances_test() {
648        let address = address!("7777777777777777777777777777777777777777");
649        let address_balances: HashMap<Address, U256> = vec![
650            (
651                address!("1111111111111111111111111111111111111111"),
652                U256::from(11111),
653            ),
654            (
655                address!("2222222222222222222222222222222222222222"),
656                U256::from(22222),
657            ),
658            (
659                address!("3333333333333333333333333333333333333333"),
660                U256::from(33333),
661            ),
662        ]
663        .into_iter()
664        .collect();
665
666        let address_balances_rpc_response = address_balances.clone();
667        run_server_and_test(
668            |module| {
669                module
670                    .register_method::<RpcResult<HashMap<Address, U256>>, _>(
671                        "zks_getAllAccountBalances",
672                        move |params, _, _| {
673                            let (address,) = params.parse::<(Address,)>().unwrap();
674                            assert_eq!(
675                                address,
676                                address!("7777777777777777777777777777777777777777")
677                            );
678                            Ok(address_balances_rpc_response.clone())
679                        },
680                    )
681                    .unwrap();
682            },
683            |provider: ZKsyncTestProvider| async move {
684                let received_address_balances =
685                    provider.get_all_account_balances(address).await.unwrap();
686                assert_eq!(address_balances, received_address_balances);
687            },
688        )
689        .await;
690    }
691
692    #[tokio::test(flavor = "multi_thread")]
693    async fn get_l2_to_l1_msg_proof_when_it_exists() {
694        let block_number = 10000_u64;
695        let sender = address!("3333333333333333333333333333333333333333");
696        let msg =
697            B256::from_str("0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9")
698                .unwrap();
699        let l2_log_position = Some(10);
700        let network_msg_proof = L2ToL1LogProof {
701            proof: vec![
702                B256::from_str(
703                    "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e",
704                )
705                .unwrap(),
706                B256::from_str(
707                    "0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
708                )
709                .unwrap(),
710            ],
711            id: 3000,
712            root: B256::from_str(
713                "0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12",
714            )
715            .unwrap(),
716        };
717        let network_msg_proof_rpc_response = network_msg_proof.clone();
718        run_server_and_test(
719            |module| {
720                module
721                    .register_method::<RpcResult<Option<L2ToL1LogProof>>, _>(
722                        "zks_getL2ToL1MsgProof",
723                        move |params, _, _| {
724                            let (block_num_param, sender_param, msg_param, log_position_param) =
725                                params.parse::<GetMsgProofRequest>().unwrap();
726                            assert_eq!(block_num_param, block_number);
727                            assert_eq!(sender_param, sender);
728                            assert_eq!(msg_param, msg);
729                            assert_eq!(log_position_param, l2_log_position);
730                            Ok(Some(network_msg_proof_rpc_response.clone()))
731                        },
732                    )
733                    .unwrap();
734            },
735            |provider: ZKsyncTestProvider| async move {
736                let received_msg_proof = provider
737                    .get_l2_to_l1_msg_proof(block_number, sender, msg, l2_log_position)
738                    .await
739                    .unwrap();
740                assert_eq!(network_msg_proof, received_msg_proof.unwrap());
741            },
742        )
743        .await;
744    }
745
746    #[tokio::test(flavor = "multi_thread")]
747    async fn get_l2_to_l1_msg_proof_when_it_does_not_exist() {
748        let block_number = 10000_u64;
749        let sender = address!("3333333333333333333333333333333333333333");
750        let msg =
751            B256::from_str("0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9")
752                .unwrap();
753        let l2_log_position = Some(10);
754
755        run_server_and_test(
756            |module| {
757                module
758                    .register_method::<RpcResult<Option<L2ToL1LogProof>>, _>(
759                        "zks_getL2ToL1MsgProof",
760                        move |params, _, _| {
761                            let (block_num_param, sender_param, msg_param, log_position_param) =
762                                params.parse::<GetMsgProofRequest>().unwrap();
763                            assert_eq!(block_num_param, block_number);
764                            assert_eq!(sender_param, sender);
765                            assert_eq!(msg_param, msg);
766                            assert_eq!(log_position_param, l2_log_position);
767                            Ok(None)
768                        },
769                    )
770                    .unwrap();
771            },
772            |provider: ZKsyncTestProvider| async move {
773                let received_msg_proof = provider
774                    .get_l2_to_l1_msg_proof(block_number, sender, msg, l2_log_position)
775                    .await
776                    .unwrap();
777                assert_eq!(received_msg_proof, None);
778            },
779        )
780        .await;
781    }
782
783    #[tokio::test(flavor = "multi_thread")]
784    async fn get_l2_to_l1_log_proof_when_it_exists() {
785        let tx_hash =
786            B256::from_str("0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9")
787                .unwrap();
788        let index = Some(10);
789        let network_log_proof = L2ToL1LogProof {
790            proof: vec![
791                B256::from_str(
792                    "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e",
793                )
794                .unwrap(),
795                B256::from_str(
796                    "0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
797                )
798                .unwrap(),
799            ],
800            id: 3000,
801            root: B256::from_str(
802                "0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12",
803            )
804            .unwrap(),
805        };
806        let network_log_proof_rpc_response = network_log_proof.clone();
807        run_server_and_test(
808            |module| {
809                module
810                    .register_method::<RpcResult<Option<L2ToL1LogProof>>, _>(
811                        "zks_getL2ToL1LogProof",
812                        move |params, _, _| {
813                            let (tx_hash_param, index_param) =
814                                params.parse::<(B256, Option<usize>)>().unwrap();
815                            assert_eq!(tx_hash_param, tx_hash);
816                            assert_eq!(index_param, index);
817                            Ok(Some(network_log_proof_rpc_response.clone()))
818                        },
819                    )
820                    .unwrap();
821            },
822            |provider: ZKsyncTestProvider| async move {
823                let received_log_proof = provider
824                    .get_l2_to_l1_log_proof(tx_hash, index)
825                    .await
826                    .unwrap();
827                assert_eq!(network_log_proof, received_log_proof.unwrap());
828            },
829        )
830        .await;
831    }
832
833    #[tokio::test(flavor = "multi_thread")]
834    async fn get_l2_to_l1_log_proof_when_it_does_not_exist() {
835        let tx_hash =
836            B256::from_str("0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9")
837                .unwrap();
838        let index = Some(10);
839
840        run_server_and_test(
841            |module| {
842                module
843                    .register_method::<RpcResult<Option<L2ToL1LogProof>>, _>(
844                        "zks_getL2ToL1LogProof",
845                        move |params, _, _| {
846                            let (tx_hash_param, index_param) =
847                                params.parse::<(B256, Option<usize>)>().unwrap();
848                            assert_eq!(tx_hash_param, tx_hash);
849                            assert_eq!(index_param, index);
850                            Ok(None)
851                        },
852                    )
853                    .unwrap();
854            },
855            |provider: ZKsyncTestProvider| async move {
856                let received_log_proof = provider
857                    .get_l2_to_l1_log_proof(tx_hash, index)
858                    .await
859                    .unwrap();
860                assert_eq!(received_log_proof, None);
861            },
862        )
863        .await;
864    }
865
866    #[tokio::test(flavor = "multi_thread")]
867    async fn get_block_details_when_exist() {
868        let network_block_details = Some(BlockDetails {
869            number: 140599,
870            l1_batch_number: 1617,
871            l1_tx_count: 0,
872            l2_tx_count: 20,
873            timestamp: 1679815038,
874            fair_pubdata_price: Some(U256::from(7069038)),
875            root_hash: Some(
876                B256::from_str(
877                    "0xf1adac176fc939313eea4b72055db0622a10bbd9b7a83097286e84e471d2e7df",
878                )
879                .unwrap(),
880            ),
881            status: BlockStatus::Verified,
882            commit_tx_hash: Some(
883                B256::from_str(
884                    "0xd045e3698f018cb233c3817eb53a41a4c5b28784ffe659da246aa33bda34350c",
885                )
886                .unwrap(),
887            ),
888            committed_at: Some(str_to_utc("2023-03-26T07:21:21.046817Z")),
889            prove_tx_hash: Some(
890                B256::from_str(
891                    "0x1591e9b16ff6eb029cc865614094b2e6dd872c8be40b15cc56164941ed723a1a",
892                )
893                .unwrap(),
894            ),
895            proven_at: Some(str_to_utc("2023-03-26T19:48:35.200565Z")),
896            execute_tx_hash: Some(
897                B256::from_str(
898                    "0xbb66aa75f437bb4255cf751badfc6b142e8d4d3a4e531c7b2e737a22870ff19e",
899                )
900                .unwrap(),
901            ),
902            executed_at: Some(str_to_utc("2023-03-27T07:44:52.187764Z")),
903            l1_gas_price: U256::from(2069038),
904            l2_fair_gas_price: U256::from(250000000),
905            base_system_contracts_hashes: BaseSystemContractsHashes {
906                bootloader: B256::from_str(
907                    "0x010007793a328ef16cc7086708f7f3292ff9b5eed9e7e539c184228f461bf4ef",
908                )
909                .unwrap(),
910                default_aa: B256::from_str(
911                    "0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
912                )
913                .unwrap(),
914                evm_emulator: Some(
915                    B256::from_str(
916                        "0x0100057d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
917                    )
918                    .unwrap(),
919                ),
920            },
921            operator_address: address!("feee860e7aae671124e9a4e61139f3a5085dfeee"),
922            protocol_version: Some("Version5".to_string()),
923        });
924
925        let network_block_details_rpc_response = network_block_details.clone();
926        run_server_and_test(
927            |module| {
928                module
929                    .register_method::<RpcResult<Option<BlockDetails>>, _>(
930                        "zks_getBlockDetails",
931                        move |params, _, _| {
932                            let (block_number,) = params.parse::<(u64,)>().unwrap();
933                            assert_eq!(block_number, 100);
934                            Ok(network_block_details_rpc_response.clone())
935                        },
936                    )
937                    .unwrap();
938            },
939            |provider: ZKsyncTestProvider| async move {
940                let received_block_details = provider.get_block_details(100).await.unwrap();
941                assert_eq!(received_block_details, network_block_details);
942            },
943        )
944        .await;
945    }
946
947    #[tokio::test(flavor = "multi_thread")]
948    async fn get_block_details_when_do_not_exist() {
949        run_server_and_test(
950            |module| {
951                module
952                    .register_method::<RpcResult<Option<BlockDetails>>, _>(
953                        "zks_getBlockDetails",
954                        move |params, _, _| {
955                            let (block_number,) = params.parse::<(u64,)>().unwrap();
956                            assert_eq!(block_number, 100);
957                            Ok(None)
958                        },
959                    )
960                    .unwrap();
961            },
962            |provider: ZKsyncTestProvider| async move {
963                let received_block_details = provider.get_block_details(100).await.unwrap();
964                assert_eq!(None, received_block_details);
965            },
966        )
967        .await;
968    }
969
970    #[tokio::test(flavor = "multi_thread")]
971    async fn get_transaction_details_when_exist() {
972        let tx_hash =
973            B256::from_str("0xf1adac176fc939313eea4b72055db0622a10bbd9b7a83097286e84e471d2e7df")
974                .unwrap();
975
976        let tx_details = Some(TransactionDetails {
977            is_l1_originated: false,
978            status: TransactionStatus::Included,
979            fee: U256::from(10000),
980            gas_per_pubdata: U256::from(20000),
981            initiator_address: address!("3333333333333333333333333333333333333333"),
982            received_at: str_to_utc("2023-03-03T23:52:24.169Z"),
983            eth_commit_tx_hash: Some(
984                B256::from_str(
985                    "0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12",
986                )
987                .unwrap(),
988            ),
989            eth_prove_tx_hash: Some(
990                B256::from_str(
991                    "0xd045e3698f018cb233c3817eb53a41a4c5b28784ffe659da246aa33bda34350c",
992                )
993                .unwrap(),
994            ),
995            eth_execute_tx_hash: Some(
996                B256::from_str(
997                    "0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9",
998                )
999                .unwrap(),
1000            ),
1001        });
1002        let tx_details_rpc_response = tx_details.clone();
1003        run_server_and_test(
1004            |module| {
1005                module
1006                    .register_method::<RpcResult<Option<TransactionDetails>>, _>(
1007                        "zks_getTransactionDetails",
1008                        move |params, _, _| {
1009                            let (tx_hash_param,) = params.parse::<(B256,)>().unwrap();
1010                            assert_eq!(tx_hash_param, tx_hash);
1011                            Ok(tx_details_rpc_response.clone())
1012                        },
1013                    )
1014                    .unwrap();
1015            },
1016            |provider: ZKsyncTestProvider| async move {
1017                let received_tx_details = provider.get_transaction_details(tx_hash).await.unwrap();
1018                assert_eq!(tx_details, received_tx_details);
1019            },
1020        )
1021        .await;
1022    }
1023
1024    #[tokio::test(flavor = "multi_thread")]
1025    async fn get_transaction_details_when_do_not_exist() {
1026        let tx_hash =
1027            B256::from_str("0xf1adac176fc939313eea4b72055db0622a10bbd9b7a83097286e84e471d2e7df")
1028                .unwrap();
1029        run_server_and_test(
1030            |module| {
1031                module
1032                    .register_method::<RpcResult<Option<TransactionDetails>>, _>(
1033                        "zks_getTransactionDetails",
1034                        move |params, _, _| {
1035                            let (tx_hash_param,) = params.parse::<(B256,)>().unwrap();
1036                            assert_eq!(tx_hash_param, tx_hash);
1037                            Ok(None)
1038                        },
1039                    )
1040                    .unwrap();
1041            },
1042            |provider: ZKsyncTestProvider| async move {
1043                let received_tx_details = provider.get_transaction_details(tx_hash).await.unwrap();
1044                assert_eq!(received_tx_details, None);
1045            },
1046        )
1047        .await;
1048    }
1049
1050    #[tokio::test(flavor = "multi_thread")]
1051    async fn get_raw_block_transactions_test() {
1052        let block_number = 10000;
1053        let block_txs = vec![
1054            Transaction {
1055                common_data: ExecuteTransactionCommon::L2(L2TxCommonData {
1056                    nonce: 1,
1057                    fee: Eip712Fee {
1058                        gas_limit: 1111111,
1059                        gas_per_pubdata_limit: U256::from(1111112),
1060                        max_fee_per_gas: 1111113,
1061                        max_priority_fee_per_gas: 1111114,
1062                    },
1063                    initiator_address: address!("a111111111111111111111111111111111111111"),
1064                    signature: Bytes::from_str(
1065                        "0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9",
1066                    )
1067                    .unwrap(),
1068                    transaction_type: "L2 tx".to_string(),
1069                    input: Some(InputData {
1070                        hash: B256::from_str(
1071                            "0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
1072                        )
1073                        .unwrap(),
1074                        data: Bytes::from_str(
1075                            "0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12",
1076                        )
1077                        .unwrap(),
1078                    }),
1079                    paymaster_params: PaymasterParams {
1080                        paymaster: address!("b111111111111111111111111111111111111111"),
1081                        paymaster_input: Bytes::from_str(
1082                            "0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9",
1083                        )
1084                        .unwrap(),
1085                    },
1086                }),
1087                execute: Execute {
1088                    contract_address: Some(address!("1111111111111111111111111111111111111111")),
1089                    calldata: Bytes::from_hex(
1090                        "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e",
1091                    )
1092                    .unwrap(),
1093                    value: U256::from(11111),
1094                    factory_deps: vec![
1095                        Bytes::from_hex(
1096                            "0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9",
1097                        )
1098                        .unwrap(),
1099                        Bytes::from_hex(
1100                            "0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
1101                        )
1102                        .unwrap(),
1103                        Bytes::from_hex(
1104                            "0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12",
1105                        )
1106                        .unwrap(),
1107                    ],
1108                },
1109                received_timestamp_ms: 20000,
1110                raw_bytes: Some(
1111                    Bytes::from_str(
1112                        "0xf1adac176fc939313eea4b72055db0622a10bbd9b7a83097286e84e471d2e7df",
1113                    )
1114                    .unwrap(),
1115                ),
1116            },
1117            Transaction {
1118                common_data: ExecuteTransactionCommon::L1(L1TxCommonData {
1119                    sender: address!("a222222222222222222222222222222222222222"),
1120                    serial_id: 123,
1121                    layer_2_tip_fee: U256::from(2222222),
1122                    full_fee: U256::from(2222223),
1123                    max_fee_per_gas: U256::from(2222224),
1124                    gas_limit: U256::from(2222225),
1125                    gas_per_pubdata_limit: U256::from(2222226),
1126                    op_processing_type: OpProcessingType::Common,
1127                    priority_queue_type: PriorityQueueType::Heap,
1128                    canonical_tx_hash: B256::from_str(
1129                        "0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9",
1130                    )
1131                    .unwrap(),
1132                    to_mint: U256::from(222226),
1133                    refund_recipient: address!("b222222222222222222222222222222222222222"),
1134                }),
1135                execute: Execute {
1136                    contract_address: Some(address!("2222222222222222222222222222222222222222")),
1137                    calldata: Bytes::from_hex("0x2222222222222222222222222222222222222222")
1138                        .unwrap(),
1139                    value: U256::from(22222),
1140                    factory_deps: vec![
1141                        Bytes::from_hex(
1142                            "0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
1143                        )
1144                        .unwrap(),
1145                        Bytes::from_hex(
1146                            "0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12",
1147                        )
1148                        .unwrap(),
1149                        Bytes::from_hex(
1150                            "0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9",
1151                        )
1152                        .unwrap(),
1153                    ],
1154                },
1155                received_timestamp_ms: 30000,
1156                raw_bytes: Some(
1157                    Bytes::from_hex(
1158                        "0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
1159                    )
1160                    .unwrap(),
1161                ),
1162            },
1163            Transaction {
1164                common_data: ExecuteTransactionCommon::ProtocolUpgrade(
1165                    ProtocolUpgradeTxCommonData {
1166                        sender: address!("a333333333333333333333333333333333333333"),
1167                        upgrade_id: "upgrade id".to_string(),
1168                        max_fee_per_gas: U256::from(33333334),
1169                        gas_limit: U256::from(33333335),
1170                        gas_per_pubdata_limit: U256::from(33333336),
1171                        eth_block: 345,
1172                        canonical_tx_hash: B256::from_str(
1173                            "0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12",
1174                        )
1175                        .unwrap(),
1176                        to_mint: U256::from(33333337),
1177                        refund_recipient: address!("b333333333333333333333333333333333333333"),
1178                    },
1179                ),
1180                execute: Execute {
1181                    contract_address: Some(address!("3333333333333333333333333333333333333333")),
1182                    calldata: Bytes::from_hex(
1183                        "0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9",
1184                    )
1185                    .unwrap(),
1186                    value: U256::from(22222),
1187                    factory_deps: vec![
1188                        Bytes::from_hex(
1189                            "0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
1190                        )
1191                        .unwrap(),
1192                        Bytes::from_hex(
1193                            "0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12",
1194                        )
1195                        .unwrap(),
1196                        Bytes::from_hex(
1197                            "0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9",
1198                        )
1199                        .unwrap(),
1200                    ],
1201                },
1202                received_timestamp_ms: 50000,
1203                raw_bytes: Some(
1204                    Bytes::from_hex(
1205                        "0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
1206                    )
1207                    .unwrap(),
1208                ),
1209            },
1210        ];
1211        let block_txs_rpc_response = block_txs.clone();
1212        run_server_and_test(
1213            |module| {
1214                module
1215                    .register_method::<RpcResult<Vec<Transaction>>, _>(
1216                        "zks_getRawBlockTransactions",
1217                        move |params, _, _| {
1218                            let (block_number_param,) = params.parse::<(u64,)>().unwrap();
1219                            assert_eq!(block_number_param, block_number);
1220                            Ok(block_txs_rpc_response.clone())
1221                        },
1222                    )
1223                    .unwrap();
1224            },
1225            |provider: ZKsyncTestProvider| async move {
1226                let received_block_txs = provider
1227                    .get_raw_block_transactions(block_number)
1228                    .await
1229                    .unwrap();
1230                assert_eq!(block_txs, received_block_txs);
1231            },
1232        )
1233        .await;
1234    }
1235
1236    #[tokio::test(flavor = "multi_thread")]
1237    async fn get_l1_batch_details_when_exist() {
1238        let batch_number = 6578_u64;
1239        let network_batch_details = Some(L1BatchDetails {
1240            number: 468355,
1241            timestamp: 1711649164,
1242            l1_tx_count: 1,
1243            l2_tx_count: 2363,
1244            root_hash: Some(
1245                B256::from_str(
1246                    "0x7b31ef880f09238f13b71a0f6bfea340b9c76d01bba0712af6aa0a4f224be167",
1247                )
1248                .unwrap(),
1249            ),
1250            status: BlockStatus::Verified,
1251            commit_tx_hash: Some(
1252                B256::from_str(
1253                    "0x5b2598bf1260d498c1c6a05326f7416ef2a602b8a1ac0f75b583cd6e08ae83cb",
1254                )
1255                .unwrap(),
1256            ),
1257            committed_at: Some(str_to_utc("2024-03-28T18:24:49.713730Z")),
1258            prove_tx_hash: Some(
1259                B256::from_str(
1260                    "0xc02563331d0a83d634bc4190750e920fc26b57096ec72dd100af2ab037b43912",
1261                )
1262                .unwrap(),
1263            ),
1264            proven_at: Some(str_to_utc("2024-03-29T03:09:19.634524Z")),
1265            execute_tx_hash: Some(
1266                B256::from_str(
1267                    "0xbe1ba1fdd17c2421cf2dabe2908fafa26ff4fa2190a7724d16295dd9df72b144",
1268                )
1269                .unwrap(),
1270            ),
1271            executed_at: Some(str_to_utc("2024-03-29T18:18:04.204270Z")),
1272            l1_gas_price: U256::from(47875552051_u64),
1273            l2_fair_gas_price: U256::from(25000000),
1274            fair_pubdata_price: Some(U256::from(725000000)),
1275            base_system_contracts_hashes: BaseSystemContractsHashes {
1276                bootloader: B256::from_str(
1277                    "0x010007ede999d096c84553fb514d3d6ca76fbf39789dda76bfeda9f3ae06236e",
1278                )
1279                .unwrap(),
1280                default_aa: B256::from_str(
1281                    "0x0100055b041eb28aff6e3a6e0f37c31fd053fc9ef142683b05e5f0aee6934066",
1282                )
1283                .unwrap(),
1284                evm_emulator: Some(
1285                    B256::from_str(
1286                        "0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
1287                    )
1288                    .unwrap(),
1289                ),
1290            },
1291        });
1292        let network_batch_details_rpc_response = network_batch_details.clone();
1293        run_server_and_test(
1294            |module| {
1295                module
1296                    .register_method::<RpcResult<Option<L1BatchDetails>>, _>(
1297                        "zks_getL1BatchDetails",
1298                        move |params, _, _| {
1299                            let (batch_number_param,) = params.parse::<(u64,)>().unwrap();
1300                            assert_eq!(batch_number_param, batch_number);
1301                            Ok(network_batch_details_rpc_response.clone())
1302                        },
1303                    )
1304                    .unwrap();
1305            },
1306            |provider: ZKsyncTestProvider| async move {
1307                let received_batch_details =
1308                    provider.get_l1_batch_details(batch_number).await.unwrap();
1309                assert_eq!(network_batch_details, received_batch_details);
1310            },
1311        )
1312        .await;
1313    }
1314
1315    #[tokio::test(flavor = "multi_thread")]
1316    async fn get_l1_batch_details_when_do_not_exist() {
1317        let batch_number = 6578_u64;
1318        run_server_and_test(
1319            |module| {
1320                module
1321                    .register_method::<RpcResult<Option<L1BatchDetails>>, _>(
1322                        "zks_getL1BatchDetails",
1323                        move |params, _, _| {
1324                            let (batch_number_param,) = params.parse::<(u64,)>().unwrap();
1325                            assert_eq!(batch_number_param, batch_number);
1326                            Ok(None)
1327                        },
1328                    )
1329                    .unwrap();
1330            },
1331            |provider: ZKsyncTestProvider| async move {
1332                let received_batch_details =
1333                    provider.get_l1_batch_details(batch_number).await.unwrap();
1334                assert_eq!(received_batch_details, None);
1335            },
1336        )
1337        .await;
1338    }
1339
1340    #[tokio::test(flavor = "multi_thread")]
1341    async fn get_bytecode_by_hash_when_exists() {
1342        let tx_hash =
1343            B256::from_str("0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc")
1344                .unwrap();
1345        let network_tx_bytecode = Some(
1346            Bytes::from_str("0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc")
1347                .unwrap(),
1348        );
1349        let network_tx_bytecode_rpc_response = network_tx_bytecode.clone();
1350        run_server_and_test(
1351            |module| {
1352                module
1353                    .register_method::<RpcResult<Option<Bytes>>, _>(
1354                        "zks_getBytecodeByHash",
1355                        move |params, _, _| {
1356                            let (tx_hash_param,) = params.parse::<(B256,)>().unwrap();
1357                            assert_eq!(tx_hash_param, tx_hash);
1358                            Ok(network_tx_bytecode_rpc_response.clone())
1359                        },
1360                    )
1361                    .unwrap();
1362            },
1363            |provider: ZKsyncTestProvider| async move {
1364                let received_tx_bytecode = provider.get_bytecode_by_hash(tx_hash).await.unwrap();
1365                assert_eq!(network_tx_bytecode, received_tx_bytecode);
1366            },
1367        )
1368        .await;
1369    }
1370
1371    #[tokio::test(flavor = "multi_thread")]
1372    async fn get_bytecode_by_hash_when_does_not_exist() {
1373        let tx_hash =
1374            B256::from_str("0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc")
1375                .unwrap();
1376        run_server_and_test(
1377            |module| {
1378                module
1379                    .register_method::<RpcResult<Option<Bytes>>, _>(
1380                        "zks_getBytecodeByHash",
1381                        move |params, _, _| {
1382                            let (tx_hash_param,) = params.parse::<(B256,)>().unwrap();
1383                            assert_eq!(tx_hash_param, tx_hash);
1384                            Ok(None)
1385                        },
1386                    )
1387                    .unwrap();
1388            },
1389            |provider: ZKsyncTestProvider| async move {
1390                let received_tx_bytecode = provider.get_bytecode_by_hash(tx_hash).await.unwrap();
1391                assert_eq!(received_tx_bytecode, None);
1392            },
1393        )
1394        .await;
1395    }
1396
1397    #[tokio::test(flavor = "multi_thread")]
1398    async fn get_l1_batch_block_range_when_exists() {
1399        let l1_batch_number = 123_u64;
1400        let block_range = Some((U64::from(1000), U64::from(2000)));
1401
1402        run_server_and_test(
1403            |module| {
1404                module
1405                    .register_method::<RpcResult<Option<(U64, U64)>>, _>(
1406                        "zks_getL1BatchBlockRange",
1407                        move |params, _, _| {
1408                            let (batch_number_param,) = params.parse::<(u64,)>().unwrap();
1409                            assert_eq!(batch_number_param, l1_batch_number);
1410                            Ok(block_range)
1411                        },
1412                    )
1413                    .unwrap();
1414            },
1415            |provider: ZKsyncTestProvider| async move {
1416                let received_blocks_range = provider
1417                    .get_l1_batch_block_range(l1_batch_number)
1418                    .await
1419                    .unwrap();
1420                assert_eq!(block_range, received_blocks_range);
1421            },
1422        )
1423        .await;
1424    }
1425
1426    #[tokio::test(flavor = "multi_thread")]
1427    async fn get_l1_batch_block_range_when_does_not_exist() {
1428        let l1_batch_number = 123_u64;
1429
1430        run_server_and_test(
1431            |module| {
1432                module
1433                    .register_method::<RpcResult<Option<(U64, U64)>>, _>(
1434                        "zks_getL1BatchBlockRange",
1435                        move |params, _, _| {
1436                            let (batch_number_param,) = params.parse::<(u64,)>().unwrap();
1437                            assert_eq!(batch_number_param, l1_batch_number);
1438                            Ok(None)
1439                        },
1440                    )
1441                    .unwrap();
1442            },
1443            |provider: ZKsyncTestProvider| async move {
1444                let received_blocks_range = provider
1445                    .get_l1_batch_block_range(l1_batch_number)
1446                    .await
1447                    .unwrap();
1448                assert_eq!(received_blocks_range, None);
1449            },
1450        )
1451        .await;
1452    }
1453
1454    #[tokio::test(flavor = "multi_thread")]
1455    async fn get_l1_gas_price_test() {
1456        let network_l1_gas_price = U256::from(13456);
1457        run_server_and_test(
1458            |module| {
1459                module
1460                    .register_method::<RpcResult<U256>, _>("zks_getL1GasPrice", move |_, _, _| {
1461                        Ok(network_l1_gas_price)
1462                    })
1463                    .unwrap();
1464            },
1465            |provider: ZKsyncTestProvider| async move {
1466                let received_l1_gas_price = provider.get_l1_gas_price().await.unwrap();
1467                assert_eq!(network_l1_gas_price, received_l1_gas_price);
1468            },
1469        )
1470        .await;
1471    }
1472
1473    #[tokio::test(flavor = "multi_thread")]
1474    async fn get_fee_params_test() {
1475        let network_fee_params = FeeParams::V2(FeeParamsV2 {
1476            config: FeeModelConfigV2 {
1477                minimal_l2_gas_price: U256::from(111111),
1478                compute_overhead_part: 12345_f64,
1479                pubdata_overhead_part: 23456_f64,
1480                batch_overhead_l1_gas: U256::from(222222),
1481                max_gas_per_batch: U256::from(3333333),
1482                max_pubdata_per_batch: U256::from(44444),
1483            },
1484            l1_gas_price: U256::from(555555),
1485            l1_pubdata_price: U256::from(66666),
1486            conversion_ratio: BaseTokenConversionRatio {
1487                numerator: 3456345_u64,
1488                denominator: 234344_u64,
1489            },
1490        });
1491        let network_fee_params_rpc_response = network_fee_params.clone();
1492        run_server_and_test(
1493            |module| {
1494                module
1495                    .register_method::<RpcResult<FeeParams>, _>(
1496                        "zks_getFeeParams",
1497                        move |_, _, _| Ok(network_fee_params_rpc_response.clone()),
1498                    )
1499                    .unwrap();
1500            },
1501            |provider: ZKsyncTestProvider| async move {
1502                let received_fee_params = provider.get_fee_params().await.unwrap();
1503                assert_eq!(network_fee_params, received_fee_params);
1504            },
1505        )
1506        .await;
1507    }
1508
1509    #[tokio::test(flavor = "multi_thread")]
1510    async fn get_protocol_version_when_available() {
1511        let protocol_id = Some(123_u16);
1512        let network_protocol_version = Some(ProtocolVersion {
1513            minor_version: Some(123_u16),
1514            timestamp: 456778_u64,
1515            verification_keys_hashes: Some(L1VerifierConfig {
1516                recursion_scheduler_level_vk_hash: B256::from_str(
1517                    "0x063c6fb5c70404c2867f413a8e35563ad3d040b1ad8c11786231bfdba7b472c7",
1518                )
1519                .unwrap(),
1520            }),
1521            base_system_contracts: Some(BaseSystemContractsHashes {
1522                bootloader: B256::from_str(
1523                    "0x010007793a328ef16cc7086708f7f3292ff9b5eed9e7e539c184228f461bf4ef",
1524                )
1525                .unwrap(),
1526                default_aa: B256::from_str(
1527                    "0x0100067d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
1528                )
1529                .unwrap(),
1530                evm_emulator: Some(
1531                    B256::from_str(
1532                        "0x0100057d861e2f5717a12c3e869cfb657793b86bbb0caa05cc1421f16c5217bc",
1533                    )
1534                    .unwrap(),
1535                ),
1536            }),
1537            bootloader_code_hash: Some(
1538                B256::from_str(
1539                    "0x010007ede999d096c84553fb514d3d6ca76fbf39789dda76bfeda9f3ae06236e",
1540                )
1541                .unwrap(),
1542            ),
1543            default_account_code_hash: Some(
1544                B256::from_str(
1545                    "0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12",
1546                )
1547                .unwrap(),
1548            ),
1549            evm_emulator_code_hash: Some(
1550                B256::from_str(
1551                    "0x22de7debaa98758afdaee89f447ff43bab5da3de6acca7528b281cc2f1be2ee9",
1552                )
1553                .unwrap(),
1554            ),
1555            l2_system_upgrade_tx_hash: Some(
1556                B256::from_str(
1557                    "0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12",
1558                )
1559                .unwrap(),
1560            ),
1561        });
1562        let network_protocol_version_rpc_response = network_protocol_version.clone();
1563        run_server_and_test(
1564            |module| {
1565                module
1566                    .register_method::<RpcResult<Option<ProtocolVersion>>, _>(
1567                        "zks_getProtocolVersion",
1568                        move |params, _, _| {
1569                            let (protocol_id_param,) = params.parse::<(Option<u16>,)>().unwrap();
1570                            assert_eq!(protocol_id_param, protocol_id);
1571                            Ok(network_protocol_version_rpc_response.clone())
1572                        },
1573                    )
1574                    .unwrap();
1575            },
1576            |provider: ZKsyncTestProvider| async move {
1577                let received_protocol_version =
1578                    provider.get_protocol_version(protocol_id).await.unwrap();
1579                assert_eq!(network_protocol_version, received_protocol_version);
1580            },
1581        )
1582        .await;
1583    }
1584
1585    #[tokio::test(flavor = "multi_thread")]
1586    async fn get_protocol_version_when_not_available() {
1587        let protocol_id = Some(123_u16);
1588        run_server_and_test(
1589            |module| {
1590                module
1591                    .register_method::<RpcResult<Option<ProtocolVersion>>, _>(
1592                        "zks_getProtocolVersion",
1593                        move |_, _, _| Ok(None),
1594                    )
1595                    .unwrap();
1596            },
1597            |provider: ZKsyncTestProvider| async move {
1598                let received_protocol_version =
1599                    provider.get_protocol_version(protocol_id).await.unwrap();
1600                assert_eq!(received_protocol_version, None);
1601            },
1602        )
1603        .await;
1604    }
1605
1606    #[tokio::test(flavor = "multi_thread")]
1607    async fn get_proof_when_available() {
1608        let address = address!("0000000000000000000000000000000000008003");
1609        let keys = vec![
1610            B256::from_str("0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12")
1611                .unwrap(),
1612        ];
1613        let l1_batch_number = 354895_u64;
1614        let proof = Some(Proof {
1615            address: address!("0000000000000000000000000000000000008003"),
1616            storage_proof: vec![StorageProof {
1617                key: B256::from_str(
1618                    "0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12",
1619                )
1620                .unwrap(),
1621                proof: vec![
1622                    B256::from_str(
1623                        "0xe3e8e49a998b3abf8926f62a5a832d829aadc1b7e059f1ea59ffbab8e11edfb7",
1624                    )
1625                    .unwrap(),
1626                ],
1627                value: B256::from_str(
1628                    "0x0000000000000000000000000000000000000000000000000000000000000060",
1629                )
1630                .unwrap(),
1631                index: 27900957_u64,
1632            }],
1633        });
1634        let proof_rpc_response = proof.clone();
1635        let keys_rpc_request = keys.clone();
1636        run_server_and_test(
1637            |module| {
1638                module
1639                    .register_method::<RpcResult<Option<Proof>>, _>(
1640                        "zks_getProof",
1641                        move |params, _, _| {
1642                            let (address_param, keys_param, batch_num_param) =
1643                                params.parse::<(Address, Vec<B256>, u64)>().unwrap();
1644                            assert_eq!(address_param, address);
1645                            assert_eq!(keys_param, keys_rpc_request);
1646                            assert_eq!(batch_num_param, l1_batch_number);
1647                            Ok(proof_rpc_response.clone())
1648                        },
1649                    )
1650                    .unwrap();
1651            },
1652            |provider: ZKsyncTestProvider| async move {
1653                let received_proof =
1654                    ZksyncProvider::get_proof(&provider, address, keys, l1_batch_number)
1655                        .await
1656                        .unwrap();
1657                assert_eq!(proof, received_proof);
1658            },
1659        )
1660        .await;
1661    }
1662
1663    #[tokio::test(flavor = "multi_thread")]
1664    async fn get_proof_when_not_available() {
1665        let address = address!("0000000000000000000000000000000000008003");
1666        let keys = vec![
1667            B256::from_str("0x8b65c0cf1012ea9f393197eb24619fd814379b298b238285649e14f936a5eb12")
1668                .unwrap(),
1669        ];
1670        let l1_batch_number = 354895_u64;
1671        let keys_rpc_request = keys.clone();
1672        run_server_and_test(
1673            |module| {
1674                module
1675                    .register_method::<RpcResult<Option<Proof>>, _>(
1676                        "zks_getProof",
1677                        move |params, _, _| {
1678                            let (address_param, keys_param, batch_num_param) =
1679                                params.parse::<(Address, Vec<B256>, u64)>().unwrap();
1680                            assert_eq!(address_param, address);
1681                            assert_eq!(keys_param, keys_rpc_request);
1682                            assert_eq!(batch_num_param, l1_batch_number);
1683                            Ok(None)
1684                        },
1685                    )
1686                    .unwrap();
1687            },
1688            |provider: ZKsyncTestProvider| async move {
1689                let received_proof =
1690                    ZksyncProvider::get_proof(&provider, address, keys, l1_batch_number)
1691                        .await
1692                        .unwrap();
1693                assert_eq!(received_proof, None);
1694            },
1695        )
1696        .await;
1697    }
1698}