From 7f783db3ec0736d5bd4538c433d2a486401ed61d Mon Sep 17 00:00:00 2001 From: jayt106 Date: Tue, 9 Jul 2024 15:34:44 -0400 Subject: [PATCH] add signing mode in eth sender configs --- core/lib/config/src/configs/eth_sender.rs | 11 + core/lib/config/src/testonly.rs | 6 +- core/lib/env_config/src/eth_sender.rs | 4 +- core/lib/protobuf_config/src/eth.rs | 23 ++ .../src/proto/config/eth_sender.proto | 6 + core/lib/zksync_core/src/lib.rs | 384 +++++++++--------- etc/env/base/eth_sender.toml | 2 + 7 files changed, 249 insertions(+), 187 deletions(-) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index a7dce1959..347c2cfcb 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -42,6 +42,7 @@ impl EthConfig { max_acceptable_priority_fee_in_gwei: 100000000000, proof_loading_mode: ProofLoadingMode::OldProofFromDb, pubdata_sending_mode: PubdataSendingMode::Calldata, + signing_mode: SigningMode::PrivateKey, }), gas_adjuster: Some(GasAdjusterConfig { default_priority_fee_per_gas: 1000000000, @@ -86,6 +87,13 @@ pub enum PubdataSendingMode { Blobs, } +#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Default)] +pub enum SigningMode { + #[default] + PrivateKey, + GcloudKms, +} + #[derive(Debug, Deserialize, Clone, PartialEq)] pub struct SenderConfig { pub aggregated_proof_sizes: Vec, @@ -122,6 +130,9 @@ pub struct SenderConfig { /// The mode in which we send pubdata, either Calldata or Blobs pub pubdata_sending_mode: PubdataSendingMode, + + /// Type of signing client for Ethereum transactions. + pub signing_mode: SigningMode, } impl SenderConfig { diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index 77036cf86..87b77cbc7 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -6,7 +6,10 @@ use zksync_basic_types::{ }; use zksync_consensus_utils::EncodeDist; -use crate::configs::{self, eth_sender::PubdataSendingMode}; +use crate::configs::{ + self, + eth_sender::{PubdataSendingMode, SigningMode}, +}; trait Sample { fn sample(rng: &mut (impl Rng + ?Sized)) -> Self; @@ -384,6 +387,7 @@ impl Distribution for EncodeDist { max_acceptable_priority_fee_in_gwei: self.sample(rng), proof_loading_mode: self.sample(rng), pubdata_sending_mode: PubdataSendingMode::Calldata, + signing_mode: SigningMode::PrivateKey, } } } diff --git a/core/lib/env_config/src/eth_sender.rs b/core/lib/env_config/src/eth_sender.rs index 7f98ecf8f..90e8d5839 100644 --- a/core/lib/env_config/src/eth_sender.rs +++ b/core/lib/env_config/src/eth_sender.rs @@ -34,7 +34,7 @@ impl FromEnv for GasAdjusterConfig { #[cfg(test)] mod tests { use zksync_config::configs::eth_sender::{ - ProofLoadingMode, ProofSendingMode, PubdataSendingMode, + ProofLoadingMode, ProofSendingMode, PubdataSendingMode, SigningMode, }; use super::*; @@ -64,6 +64,7 @@ mod tests { max_acceptable_priority_fee_in_gwei: 100_000_000_000, proof_loading_mode: ProofLoadingMode::OldProofFromDb, pubdata_sending_mode: PubdataSendingMode::Calldata, + signing_mode: SigningMode::PrivateKey, }), gas_adjuster: Some(GasAdjusterConfig { default_priority_fee_per_gas: 20000000000, @@ -123,6 +124,7 @@ mod tests { ETH_SENDER_SENDER_MAX_ACCEPTABLE_PRIORITY_FEE_IN_GWEI="100000000000" ETH_SENDER_SENDER_PROOF_LOADING_MODE="OldProofFromDb" ETH_SENDER_SENDER_PUBDATA_SENDING_MODE="Calldata" + ETH_SENDER_SENDER_SIGNING_MODE="PrivateKey" ETH_CLIENT_WEB3_URL="http://127.0.0.1:8545" "#; diff --git a/core/lib/protobuf_config/src/eth.rs b/core/lib/protobuf_config/src/eth.rs index 0e3aacf16..80fd3c535 100644 --- a/core/lib/protobuf_config/src/eth.rs +++ b/core/lib/protobuf_config/src/eth.rs @@ -60,6 +60,24 @@ impl proto::PubdataSendingMode { } } +impl proto::SigningMode { + fn new(x: &configs::eth_sender::SigningMode) -> Self { + use configs::eth_sender::SigningMode as From; + match x { + From::PrivateKey => Self::PrivateKey, + From::GcloudKms => Self::GcloudKms, + } + } + + fn parse(&self) -> configs::eth_sender::SigningMode { + use configs::eth_sender::SigningMode as To; + match self { + Self::PrivateKey => To::PrivateKey, + Self::GcloudKms => To::GcloudKms, + } + } +} + impl ProtoRepr for proto::Eth { type Type = configs::eth_sender::EthConfig; @@ -136,6 +154,10 @@ impl ProtoRepr for proto::Sender { .and_then(|x| Ok(proto::ProofLoadingMode::try_from(*x)?)) .context("proof_loading_mode")? .parse(), + signing_mode: required(&self.signing_mode) + .and_then(|x| Ok(proto::SigningMode::try_from(*x)?)) + .context("signing_mode")? + .parse(), }) } @@ -167,6 +189,7 @@ impl ProtoRepr for proto::Sender { proto::PubdataSendingMode::new(&this.pubdata_sending_mode).into(), ), proof_loading_mode: Some(proto::ProofLoadingMode::new(&this.proof_loading_mode).into()), + signing_mode: Some(proto::SigningMode::new(&this.signing_mode).into()), } } } diff --git a/core/lib/protobuf_config/src/proto/config/eth_sender.proto b/core/lib/protobuf_config/src/proto/config/eth_sender.proto index d4db30682..c616532c6 100644 --- a/core/lib/protobuf_config/src/proto/config/eth_sender.proto +++ b/core/lib/protobuf_config/src/proto/config/eth_sender.proto @@ -25,6 +25,11 @@ enum PubdataSendingMode { BLOBS = 1; } +enum SigningMode { + PRIVATE_KEY = 0; + GCLOUD_KMS = 1; +} + message Sender { repeated uint64 aggregated_proof_sizes = 1; // ? optional uint64 wait_confirmations = 2; // optional @@ -44,6 +49,7 @@ message Sender { optional uint64 max_acceptable_priority_fee_in_gwei = 16; // required; gwei optional PubdataSendingMode pubdata_sending_mode = 18; // required optional ProofLoadingMode proof_loading_mode = 19; + optional SigningMode signing_mode = 99; // required } message GasAdjuster { diff --git a/core/lib/zksync_core/src/lib.rs b/core/lib/zksync_core/src/lib.rs index 8015ea596..e9261935e 100644 --- a/core/lib/zksync_core/src/lib.rs +++ b/core/lib/zksync_core/src/lib.rs @@ -37,6 +37,7 @@ use zksync_config::{ }, consensus::ConsensusConfig, database::{MerkleTreeConfig, MerkleTreeMode}, + eth_sender::SigningMode, wallets::{self, Wallets}, ContractsConfig, GeneralConfig, }, @@ -649,133 +650,138 @@ pub async fn initialize_components( .default_priority_fee_per_gas; let l1_chain_id = genesis_config.l1_chain_id; - let gkms_op_key_name = std::env::var(GOOGLE_KMS_OP_KEY_NAME).ok(); - tracing::info!("KMS op key name: {:?}", gkms_op_key_name); - - let use_gkms_signing_client = gkms_op_key_name.is_some(); - - if use_gkms_signing_client { - tracing::info!("Using KMSSigningClient"); - } else { - tracing::info!("Using PKSSigningClient"); - } + let eth_sender = configs + .eth + .clone() + .context("eth_config")? + .sender + .context("sender")?; - let eth_tx_aggregator_actor = if use_gkms_signing_client { - let eth_client = GKMSSigningClient::new_raw( - diamond_proxy_addr, - default_priority_fee_per_gas, - l1_chain_id, - query_client.clone(), - gkms_op_key_name - .expect("gkms_op_key_name is required but was None") - .to_string(), - ) - .await; + let signing_mode = eth_sender.signing_mode.clone(); + tracing::info!("Using signing mode: {:?}", signing_mode); - let l1_batch_commit_data_generator_mode = - genesis_config.l1_batch_commit_data_generator_mode; - ensure_l1_batch_commit_data_generation_mode( - l1_batch_commit_data_generator_mode, - contracts_config.diamond_proxy_addr, - eth_client.as_ref(), - ) - .await?; + let eth_tx_aggregator_actor = match signing_mode { + SigningMode::GcloudKms => { + let gkms_op_key_name = std::env::var(GOOGLE_KMS_OP_KEY_NAME).ok(); + tracing::info!("KMS op key name: {:?}", gkms_op_key_name); - let l1_batch_commit_data_generator: Arc = - match l1_batch_commit_data_generator_mode { - L1BatchCommitDataGeneratorMode::Rollup => { - Arc::new(RollupModeL1BatchCommitDataGenerator {}) - } - L1BatchCommitDataGeneratorMode::Validium => { - Arc::new(ValidiumModeL1BatchCommitDataGenerator {}) - } - }; - - let gkms_op_blob_key_name = std::env::var(GOOGLE_KMS_OP_BLOB_KEY_NAME).ok(); - tracing::info!("KMS op blob key name: {:?}", gkms_op_blob_key_name); - let operator_blobs_address = if let Some(key_name) = gkms_op_blob_key_name { - let eth_blob_client = GKMSSigningClient::new_raw( + let eth_client = GKMSSigningClient::new_raw( diamond_proxy_addr, default_priority_fee_per_gas, l1_chain_id, query_client.clone(), - key_name.to_string(), + gkms_op_key_name + .expect("gkms_op_key_name is required but was None") + .to_string(), ) .await; - Some(eth_blob_client.sender_account()) - } else { - None - }; - - let sender_config = eth.sender.clone().context("eth_sender")?; - EthTxAggregator::new( - eth_sender_pool, - sender_config.clone(), - Aggregator::new( - sender_config.clone(), - store_factory.create_store().await, - operator_blobs_address.is_some(), - l1_batch_commit_data_generator.clone(), - ), - Box::new(eth_client), - contracts_config.validator_timelock_addr, - contracts_config.l1_multicall3_addr, - diamond_proxy_addr, - l2_chain_id, - operator_blobs_address, - l1_batch_commit_data_generator, - ) - .await - } else { - let eth_client = PKSigningClient::new_raw( - operator_private_key.clone(), - diamond_proxy_addr, - default_priority_fee_per_gas, - l1_chain_id, - query_client.clone(), - ); - - let l1_batch_commit_data_generator_mode = - genesis_config.l1_batch_commit_data_generator_mode; - ensure_l1_batch_commit_data_generation_mode( - l1_batch_commit_data_generator_mode, - contracts_config.diamond_proxy_addr, - eth_client.as_ref(), - ) - .await?; + let l1_batch_commit_data_generator_mode = + genesis_config.l1_batch_commit_data_generator_mode; + ensure_l1_batch_commit_data_generation_mode( + l1_batch_commit_data_generator_mode, + contracts_config.diamond_proxy_addr, + eth_client.as_ref(), + ) + .await?; + + let l1_batch_commit_data_generator: Arc = + match l1_batch_commit_data_generator_mode { + L1BatchCommitDataGeneratorMode::Rollup => { + Arc::new(RollupModeL1BatchCommitDataGenerator {}) + } + L1BatchCommitDataGeneratorMode::Validium => { + Arc::new(ValidiumModeL1BatchCommitDataGenerator {}) + } + }; + + let gkms_op_blob_key_name = std::env::var(GOOGLE_KMS_OP_BLOB_KEY_NAME).ok(); + tracing::info!("KMS op blob key name: {:?}", gkms_op_blob_key_name); + let operator_blobs_address = if let Some(key_name) = gkms_op_blob_key_name { + let eth_blob_client = GKMSSigningClient::new_raw( + diamond_proxy_addr, + default_priority_fee_per_gas, + l1_chain_id, + query_client.clone(), + key_name.to_string(), + ) + .await; - let l1_batch_commit_data_generator: Arc = - match l1_batch_commit_data_generator_mode { - L1BatchCommitDataGeneratorMode::Rollup => { - Arc::new(RollupModeL1BatchCommitDataGenerator {}) - } - L1BatchCommitDataGeneratorMode::Validium => { - Arc::new(ValidiumModeL1BatchCommitDataGenerator {}) - } + Some(eth_blob_client.sender_account()) + } else { + None }; - let operator_blobs_address = eth_sender_wallets.blob_operator.map(|x| x.address()); + let sender_config = eth.sender.clone().context("eth_sender")?; + EthTxAggregator::new( + eth_sender_pool, + sender_config.clone(), + Aggregator::new( + sender_config.clone(), + store_factory.create_store().await, + operator_blobs_address.is_some(), + l1_batch_commit_data_generator.clone(), + ), + Box::new(eth_client), + contracts_config.validator_timelock_addr, + contracts_config.l1_multicall3_addr, + diamond_proxy_addr, + l2_chain_id, + operator_blobs_address, + l1_batch_commit_data_generator, + ) + .await + } + SigningMode::PrivateKey => { + let eth_client = PKSigningClient::new_raw( + operator_private_key.clone(), + diamond_proxy_addr, + default_priority_fee_per_gas, + l1_chain_id, + query_client.clone(), + ); - let sender_config = eth.sender.clone().context("eth_sender")?; - EthTxAggregator::new( - eth_sender_pool, - sender_config.clone(), - Aggregator::new( + let l1_batch_commit_data_generator_mode = + genesis_config.l1_batch_commit_data_generator_mode; + ensure_l1_batch_commit_data_generation_mode( + l1_batch_commit_data_generator_mode, + contracts_config.diamond_proxy_addr, + eth_client.as_ref(), + ) + .await?; + + let l1_batch_commit_data_generator: Arc = + match l1_batch_commit_data_generator_mode { + L1BatchCommitDataGeneratorMode::Rollup => { + Arc::new(RollupModeL1BatchCommitDataGenerator {}) + } + L1BatchCommitDataGeneratorMode::Validium => { + Arc::new(ValidiumModeL1BatchCommitDataGenerator {}) + } + }; + + let operator_blobs_address = eth_sender_wallets.blob_operator.map(|x| x.address()); + + let sender_config = eth.sender.clone().context("eth_sender")?; + EthTxAggregator::new( + eth_sender_pool, sender_config.clone(), - store_factory.create_store().await, - operator_blobs_address.is_some(), - l1_batch_commit_data_generator.clone(), - ), - Box::new(eth_client), - contracts_config.validator_timelock_addr, - contracts_config.l1_multicall3_addr, - diamond_proxy_addr, - l2_chain_id, - operator_blobs_address, - l1_batch_commit_data_generator, - ) - .await + Aggregator::new( + sender_config.clone(), + store_factory.create_store().await, + operator_blobs_address.is_some(), + l1_batch_commit_data_generator.clone(), + ), + Box::new(eth_client), + contracts_config.validator_timelock_addr, + contracts_config.l1_multicall3_addr, + diamond_proxy_addr, + l2_chain_id, + operator_blobs_address, + l1_batch_commit_data_generator, + ) + .await + } }; task_futures.push(tokio::spawn( @@ -803,86 +809,94 @@ pub async fn initialize_components( .default_priority_fee_per_gas; let l1_chain_id = genesis_config.l1_chain_id; - let gkms_op_key_name = std::env::var(GOOGLE_KMS_OP_KEY_NAME).ok(); - let use_gkms_signing_client = gkms_op_key_name.is_some(); - if use_gkms_signing_client { - tracing::info!("Using KMSSigningClient"); - } else { - tracing::info!("Using PKSSigningClient"); - } + let eth_sender_config = configs + .eth + .clone() + .context("eth_config")? + .sender + .context("sender")?; - let eth_tx_manager_actor = if use_gkms_signing_client { - let eth_client = GKMSSigningClient::new_raw( - diamond_proxy_addr, - default_priority_fee_per_gas, - l1_chain_id, - query_client.clone(), - gkms_op_key_name - .expect("gkms_op_key_name is required but was None") - .to_string(), - ) - .await; + let signing_mode = eth_sender_config.signing_mode.clone(); + tracing::info!("Using signing mode: {:?}", signing_mode); - let gkms_op_blob_key_name = std::env::var(GOOGLE_KMS_OP_BLOB_KEY_NAME).ok(); - let eth_client_blobs = if let Some(key_name) = gkms_op_blob_key_name { - let client = Box::new( - GKMSSigningClient::new_raw( - diamond_proxy_addr, - default_priority_fee_per_gas, - l1_chain_id, - query_client.clone(), - key_name.to_string(), - ) - .await, - ); - Some(client as Box) - } else { - None - }; + let eth_tx_manager_actor = match signing_mode { + SigningMode::GcloudKms => { + let gkms_op_key_name = std::env::var(GOOGLE_KMS_OP_KEY_NAME).ok(); - EthTxManager::new( - eth_manager_pool, - eth_sender.sender.clone().context("eth_sender")?, - gas_adjuster - .get_or_init() - .await - .context("gas_adjuster.get_or_init()")?, - Box::new(eth_client), - eth_client_blobs, - ) - } else { - let operator_private_key = eth_sender_wallets.operator.private_key(); - let eth_client = PKSigningClient::new_raw( - operator_private_key.clone(), - diamond_proxy_addr, - default_priority_fee_per_gas, - l1_chain_id, - query_client.clone(), - ); - let eth_client_blobs = if let Some(blob_operator) = eth_sender_wallets.blob_operator { - let operator_blob_private_key = blob_operator.private_key().clone(); - let client = Box::new(PKSigningClient::new_raw( - operator_blob_private_key, + let eth_client = GKMSSigningClient::new_raw( diamond_proxy_addr, default_priority_fee_per_gas, l1_chain_id, - query_client, - )); - Some(client as Box) - } else { - None - }; + query_client.clone(), + gkms_op_key_name + .expect("gkms_op_key_name is required but was None") + .to_string(), + ) + .await; - EthTxManager::new( - eth_manager_pool, - eth_sender.sender.clone().context("eth_sender")?, - gas_adjuster - .get_or_init() - .await - .context("gas_adjuster.get_or_init()")?, - Box::new(eth_client), - eth_client_blobs, - ) + let gkms_op_blob_key_name = std::env::var(GOOGLE_KMS_OP_BLOB_KEY_NAME).ok(); + let eth_client_blobs = if let Some(key_name) = gkms_op_blob_key_name { + let client = Box::new( + GKMSSigningClient::new_raw( + diamond_proxy_addr, + default_priority_fee_per_gas, + l1_chain_id, + query_client.clone(), + key_name.to_string(), + ) + .await, + ); + Some(client as Box) + } else { + None + }; + + EthTxManager::new( + eth_manager_pool, + eth_sender.sender.clone().context("eth_sender")?, + gas_adjuster + .get_or_init() + .await + .context("gas_adjuster.get_or_init()")?, + Box::new(eth_client), + eth_client_blobs, + ) + } + SigningMode::PrivateKey => { + let operator_private_key = eth_sender_wallets.operator.private_key(); + let eth_client = PKSigningClient::new_raw( + operator_private_key.clone(), + diamond_proxy_addr, + default_priority_fee_per_gas, + l1_chain_id, + query_client.clone(), + ); + let eth_client_blobs = if let Some(blob_operator) = eth_sender_wallets.blob_operator + { + let operator_blob_private_key = blob_operator.private_key().clone(); + let client = Box::new(PKSigningClient::new_raw( + operator_blob_private_key, + diamond_proxy_addr, + default_priority_fee_per_gas, + l1_chain_id, + query_client, + )); + Some(client as Box) + } else { + None + }; + + EthTxManager::new( + eth_manager_pool, + eth_sender.sender.clone().context("eth_sender")?, + gas_adjuster + .get_or_init() + .await + .context("gas_adjuster.get_or_init()")?, + Box::new(eth_client), + eth_client_blobs, + ) + } }; task_futures.extend([tokio::spawn( diff --git a/etc/env/base/eth_sender.toml b/etc/env/base/eth_sender.toml index 902efeca1..bffaf9e90 100644 --- a/etc/env/base/eth_sender.toml +++ b/etc/env/base/eth_sender.toml @@ -50,6 +50,8 @@ proof_loading_mode="FriProofFromGcs" pubdata_sending_mode = "Blobs" +signing_mode = "PrivateKey" + [eth_sender.gas_adjuster] # Priority fee to be used by GasAdjuster (in wei). default_priority_fee_per_gas = 1_000_000_000