From 87202cdd5a384cdbd6001664a13c6a2ca30a9b40 Mon Sep 17 00:00:00 2001 From: franciscotobar <100875069+franciscotobar@users.noreply.github.com> Date: Mon, 2 Oct 2023 03:20:12 -0600 Subject: [PATCH] ROLLUP-437: complete withdrawals configuration (#104) * feat: complete withdrawals configuration --- .../src/api_server/rest/v02/config.rs | 2 + core/bin/zksync_eth_sender/src/lib.rs | 2 +- core/bin/zksync_eth_sender/src/tests/mock.rs | 20 ++++++++ core/bin/zksync_eth_sender/src/tests/mod.rs | 34 ++++++++++++- core/lib/config/src/configs/eth_sender.rs | 50 +++++++++++++++++-- core/lib/types/src/aggregated_operations.rs | 6 +-- core/tests/testkit/src/eth_account.rs | 2 +- etc/env/base/eth_sender.toml | 3 ++ etc/env/mainnet/api.toml | 2 +- etc/env/mainnet/chain.toml | 2 +- etc/env/mainnet/eth_sender.toml | 2 + etc/env/qa/eth_sender.toml | 2 + etc/env/testnet/eth_sender.toml | 2 + .../zk_original_configuration/eth_sender.toml | 2 + 14 files changed, 118 insertions(+), 13 deletions(-) diff --git a/core/bin/zksync_api/src/api_server/rest/v02/config.rs b/core/bin/zksync_api/src/api_server/rest/v02/config.rs index 50f0b78847..19fccca661 100644 --- a/core/bin/zksync_api/src/api_server/rest/v02/config.rs +++ b/core/bin/zksync_api/src/api_server/rest/v02/config.rs @@ -24,6 +24,7 @@ pub struct ApiConfigData { gov_contract: Address, deposit_confirmations: u64, zksync_version: ZksyncVersion, + complete_withdrawals: bool, // TODO: server_version (ZKS-627) } @@ -35,6 +36,7 @@ impl ApiConfigData { gov_contract: config.contracts.governance_addr, deposit_confirmations: config.eth_watch.confirmations_for_eth_event, zksync_version: ZksyncVersion::ContractV4, + complete_withdrawals: config.eth_sender.sender.complete_withdrawals, } } } diff --git a/core/bin/zksync_eth_sender/src/lib.rs b/core/bin/zksync_eth_sender/src/lib.rs index 94cac350b6..b7c9be6a06 100644 --- a/core/bin/zksync_eth_sender/src/lib.rs +++ b/core/bin/zksync_eth_sender/src/lib.rs @@ -772,7 +772,7 @@ impl ETHSender { .encode_tx_data("proveBlocks", args.as_slice()) } AggregatedOperation::ExecuteBlocks(operation) => { - let args = operation.get_eth_tx_args(); + let args = operation.get_eth_tx_args(self.options.sender.complete_withdrawals); self.rootstock .encode_tx_data("executeBlocks", args.as_slice()) } diff --git a/core/bin/zksync_eth_sender/src/tests/mock.rs b/core/bin/zksync_eth_sender/src/tests/mock.rs index 9d39c12e7d..d256ae800c 100644 --- a/core/bin/zksync_eth_sender/src/tests/mock.rs +++ b/core/bin/zksync_eth_sender/src/tests/mock.rs @@ -379,6 +379,7 @@ pub(crate) async fn default_eth_sender() -> ETHSender { Vec::new(), Vec::new(), default_eth_parameters(), + false, ) .await } @@ -393,6 +394,7 @@ pub(crate) async fn concurrent_eth_sender(max_txs_in_flight: u64) -> ETHSender, unprocessed_operations: Vec<(i64, AggregatedOperation)>, eth_parameters: ETHParams, + complete_withdrawals: bool, ) -> ETHSender { let rootstock = RootstockGateway::Mock(MockEthereum::default()); let db = MockDatabase::with_restorable_state( @@ -442,6 +446,7 @@ async fn build_eth_sender( is_enabled: true, operator_commit_eth_addr: Default::default(), operator_private_key: Default::default(), + complete_withdrawals, }, gas_price_limit: GasLimit { default: 1000, @@ -454,6 +459,21 @@ async fn build_eth_sender( ETHSender::new(options, db, rootstock).await } +/// Helper method for configurable creation of `ETHSender`. +pub(crate) async fn complete_withdrawals_eth_sender( + complete_withdrawals: bool, +) -> ETHSender { + build_eth_sender( + 1, + Vec::new(), + Vec::new(), + Vec::new(), + default_eth_parameters(), + complete_withdrawals, + ) + .await +} + /// Behaves the same as `ETHSender::sign_new_tx`, but does not affect nonce. /// This method should be used to create expected tx copies which won't affect /// the internal `ETHSender` state. diff --git a/core/bin/zksync_eth_sender/src/tests/mod.rs b/core/bin/zksync_eth_sender/src/tests/mod.rs index 18b3e2c099..803a0b56ba 100644 --- a/core/bin/zksync_eth_sender/src/tests/mod.rs +++ b/core/bin/zksync_eth_sender/src/tests/mod.rs @@ -1,7 +1,7 @@ // Local uses use self::mock::{ - concurrent_eth_sender, create_signed_tx, default_eth_parameters, default_eth_sender, - restored_eth_sender, + complete_withdrawals_eth_sender, concurrent_eth_sender, create_signed_tx, + default_eth_parameters, default_eth_sender, restored_eth_sender, }; use super::{transactions::TxCheckOutcome, ETHSender, TxCheckMode}; use web3::types::U64; @@ -972,3 +972,33 @@ async fn concurrent_operations_order() { } } } + +#[tokio::test] +async fn complete_withdrawals_true() { + let eth_sender = complete_withdrawals_eth_sender(true).await; + + let operations_count = 1; + let execute_operations = &test_data::EXECUTE_BLOCKS_OPERATIONS[..operations_count]; + let op = &execute_operations.first().unwrap().1; + + let raw_tx = eth_sender.operation_to_raw_tx(op); + + let complete_withdrawals = raw_tx[..64].last().unwrap(); + + assert!(*complete_withdrawals == 1); +} + +#[tokio::test] +async fn complete_withdrawals_false() { + let eth_sender = complete_withdrawals_eth_sender(false).await; + + let operations_count = 1; + let execute_operations = &test_data::EXECUTE_BLOCKS_OPERATIONS[..operations_count]; + let op = &execute_operations.first().unwrap().1; + + let raw_tx = eth_sender.operation_to_raw_tx(op); + + let complete_withdrawals = raw_tx[..64].last().unwrap(); + + assert!(*complete_withdrawals == 0); +} diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 8361e6e545..0c5b96487f 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -3,9 +3,9 @@ use std::time::Duration; // External uses use serde::Deserialize; // Workspace uses -use zksync_types::{Address, H256}; +use zksync_types::{network::Network, Address, H256}; // Local uses -use crate::envy_load; +use crate::{configs::chain::Eth, envy_load, ETHClientConfig}; /// Configuration for the Rootstock sender crate. #[derive(Debug, Deserialize, Clone, PartialEq)] @@ -18,8 +18,18 @@ pub struct ETHSenderConfig { impl ETHSenderConfig { pub fn from_env() -> Self { + let eth: Eth = envy_load!("eth", "CHAIN_ETH_"); + let sender: Sender = envy_load!("eth_sender", "ETH_SENDER_SENDER_"); + let client: ETHClientConfig = envy_load!("eth_client", "ETH_CLIENT_"); + + assert!( + !(sender.complete_withdrawals + && (eth.network == Network::Mainnet || client.chain_id == 30)), + "The withdrawals cannot be automatic in mainnet" + ); + Self { - sender: envy_load!("eth_sender", "ETH_SENDER_SENDER_"), + sender, gas_price_limit: envy_load!( "eth_sender.gas_price_limit", "ETH_SENDER_GAS_PRICE_LIMIT_" @@ -44,6 +54,8 @@ pub struct Sender { pub max_txs_in_flight: u64, /// Whether sender should interact with L1 or not. pub is_enabled: bool, + /// Automatic withdrawals in execute aggregated operation + pub complete_withdrawals: bool, } impl Sender { @@ -94,6 +106,7 @@ mod tests { "c1783a9a8222e47778911c58bb5aac1343eb425159ff140799e0a283bfb8fa16", ), operator_commit_eth_addr: addr("debe71e1de41fc77c44df4b6db940026e31b0e71"), + complete_withdrawals: false, }, gas_price_limit: GasLimit { default: 400000000000, @@ -112,12 +125,17 @@ ETH_SENDER_SENDER_EXPECTED_WAIT_TIME_BLOCK="30" ETH_SENDER_SENDER_TX_POLL_PERIOD="3" ETH_SENDER_SENDER_MAX_TXS_IN_FLIGHT="3" ETH_SENDER_SENDER_IS_ENABLED="true" +ETH_SENDER_SENDER_COMPLETE_WITHDRAWALS="false" ETH_SENDER_SENDER_OPERATOR_PRIVATE_KEY="0xc1783a9a8222e47778911c58bb5aac1343eb425159ff140799e0a283bfb8fa16" ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR="0xdebe71e1de41fc77c44df4b6db940026e31b0e71" ETH_SENDER_GAS_PRICE_LIMIT_DEFAULT="400000000000" ETH_SENDER_GAS_PRICE_LIMIT_UPDATE_INTERVAL="150" ETH_SENDER_GAS_PRICE_LIMIT_SAMPLE_INTERVAL="15" ETH_SENDER_GAS_PRICE_LIMIT_SCALE_FACTOR="1" +CHAIN_ETH_NETWORK="mainnet" +ETH_CLIENT_CHAIN_ID=30 +ETH_CLIENT_GAS_PRICE_FACTOR="1" +ETH_CLIENT_WEB3_URL="http://127.0.0.1:4444" "#; set_env(config); @@ -144,4 +162,30 @@ ETH_SENDER_GAS_PRICE_LIMIT_SCALE_FACTOR="1" Duration::from_secs(config.gas_price_limit.sample_interval) ); } + + #[test] + #[should_panic(expected = "The withdrawals cannot be automatic in mainnet")] + fn from_env_mainnet() { + let config = r#" +ETH_SENDER_SENDER_WAIT_CONFIRMATIONS="1" +ETH_SENDER_SENDER_EXPECTED_WAIT_TIME_BLOCK="30" +ETH_SENDER_SENDER_TX_POLL_PERIOD="3" +ETH_SENDER_SENDER_MAX_TXS_IN_FLIGHT="3" +ETH_SENDER_SENDER_IS_ENABLED="true" +ETH_SENDER_SENDER_COMPLETE_WITHDRAWALS="true" +ETH_SENDER_SENDER_OPERATOR_PRIVATE_KEY="0xc1783a9a8222e47778911c58bb5aac1343eb425159ff140799e0a283bfb8fa16" +ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR="0xdebe71e1de41fc77c44df4b6db940026e31b0e71" +ETH_SENDER_GAS_PRICE_LIMIT_DEFAULT="400000000000" +ETH_SENDER_GAS_PRICE_LIMIT_UPDATE_INTERVAL="150" +ETH_SENDER_GAS_PRICE_LIMIT_SAMPLE_INTERVAL="15" +ETH_SENDER_GAS_PRICE_LIMIT_SCALE_FACTOR="1" +CHAIN_ETH_NETWORK="mainnet" +ETH_CLIENT_CHAIN_ID=30 +ETH_CLIENT_GAS_PRICE_FACTOR="1" +ETH_CLIENT_WEB3_URL="http://127.0.0.1:4444" + "#; + set_env(config); + + ETHSenderConfig::from_env(); + } } diff --git a/core/lib/types/src/aggregated_operations.rs b/core/lib/types/src/aggregated_operations.rs index 36c0b22f78..d466e5ff3c 100644 --- a/core/lib/types/src/aggregated_operations.rs +++ b/core/lib/types/src/aggregated_operations.rs @@ -118,9 +118,7 @@ impl BlocksExecuteOperation { Token::Tuple(vec![stored_block, processable_ops_pubdata]) } - pub fn get_eth_tx_args(&self) -> Vec { - // Does not make automatic withdrawals in execute operation - let complete_withdrawals = Token::Bool(false); + pub fn get_eth_tx_args(&self, complete_withdrawals: bool) -> Vec { vec![ Token::Array( self.blocks @@ -128,7 +126,7 @@ impl BlocksExecuteOperation { .map(BlocksExecuteOperation::get_eth_tx_args_for_block) .collect(), ), - complete_withdrawals, + Token::Bool(complete_withdrawals), ] } diff --git a/core/tests/testkit/src/eth_account.rs b/core/tests/testkit/src/eth_account.rs index 7cde3a52c0..02a640578a 100644 --- a/core/tests/testkit/src/eth_account.rs +++ b/core/tests/testkit/src/eth_account.rs @@ -407,7 +407,7 @@ impl RootstockAccount { ) -> Result { let data = self.main_contract_eth_client.encode_tx_data( "executeBlocks", - execute_operation.get_eth_tx_args().as_slice(), + execute_operation.get_eth_tx_args(false).as_slice(), ); let signed_tx = self diff --git a/etc/env/base/eth_sender.toml b/etc/env/base/eth_sender.toml index 448824d49e..d996ed9171 100644 --- a/etc/env/base/eth_sender.toml +++ b/etc/env/base/eth_sender.toml @@ -17,6 +17,9 @@ tx_poll_period=1 max_txs_in_flight=1 # Whether sender should interact with L1 or not. is_enabled=true +# Automatic withdrawals in execute aggregated operation +complete_withdrawals=false + [eth_sender.gas_price_limit] # Gas price limit to be used by GasAdjuster until the statistics data is gathered. diff --git a/etc/env/mainnet/api.toml b/etc/env/mainnet/api.toml index f87debd097..a2d8667719 100644 --- a/etc/env/mainnet/api.toml +++ b/etc/env/mainnet/api.toml @@ -43,7 +43,6 @@ url="http://127.0.0.1:8080" port=3001 use_https=false url="https://127.0.0.1:3001" -chain_id=30 # Configuration for the JSON RPC server [api.json_rpc] @@ -59,6 +58,7 @@ ws_url="ws://127.0.0.1:3031" port=3002 url="http://127.0.0.1:3002" max_block_range=10 +chain_id=30 # Configuration for the core private server. [api.private] diff --git a/etc/env/mainnet/chain.toml b/etc/env/mainnet/chain.toml index 56abc6dde5..4f0a885b59 100644 --- a/etc/env/mainnet/chain.toml +++ b/etc/env/mainnet/chain.toml @@ -17,7 +17,7 @@ balance_tree_depth=32 [chain.eth] # Name of the used RSK network (since Ethers uses localhost for different works as Rootstock, different RSK networks are differentiated by its chain id in eth_client.toml) -network="localhost" +network="mainnet" [chain.state_keeper] # Block sizes to be generated by server. diff --git a/etc/env/mainnet/eth_sender.toml b/etc/env/mainnet/eth_sender.toml index dd0098bff9..0336c9f80d 100644 --- a/etc/env/mainnet/eth_sender.toml +++ b/etc/env/mainnet/eth_sender.toml @@ -16,6 +16,8 @@ tx_poll_period=3 max_txs_in_flight=1 # Whether sender should interact with L1 or not. is_enabled=true +# Automatic withdrawals in execute aggregated operation +complete_withdrawals=false [eth_sender.gas_price_limit] # Gas price limit to be used by GasAdjuster until the statistics data is gathered. diff --git a/etc/env/qa/eth_sender.toml b/etc/env/qa/eth_sender.toml index 8a2f9dbf8f..8b81478798 100644 --- a/etc/env/qa/eth_sender.toml +++ b/etc/env/qa/eth_sender.toml @@ -16,6 +16,8 @@ tx_poll_period=3 max_txs_in_flight=1 # Whether sender should interact with L1 or not. is_enabled=true +# Automatic withdrawals in execute aggregated operation +complete_withdrawals=true [eth_sender.gas_price_limit] # Gas price limit to be used by GasAdjuster until the statistics data is gathered. diff --git a/etc/env/testnet/eth_sender.toml b/etc/env/testnet/eth_sender.toml index 8a2f9dbf8f..8b81478798 100644 --- a/etc/env/testnet/eth_sender.toml +++ b/etc/env/testnet/eth_sender.toml @@ -16,6 +16,8 @@ tx_poll_period=3 max_txs_in_flight=1 # Whether sender should interact with L1 or not. is_enabled=true +# Automatic withdrawals in execute aggregated operation +complete_withdrawals=true [eth_sender.gas_price_limit] # Gas price limit to be used by GasAdjuster until the statistics data is gathered. diff --git a/etc/env/zk_original_configuration/eth_sender.toml b/etc/env/zk_original_configuration/eth_sender.toml index 685a3f162e..9aa02ffd88 100644 --- a/etc/env/zk_original_configuration/eth_sender.toml +++ b/etc/env/zk_original_configuration/eth_sender.toml @@ -16,6 +16,8 @@ tx_poll_period=3 max_txs_in_flight=3 # Whether sender should interact with L1 or not. is_enabled=true +# Automatic withdrawals in execute aggregated operation +complete_withdrawals=false [eth_sender.gas_price_limit] # Gas price limit to be used by GasAdjuster until the statistics data is gathered.