diff --git a/core/bin/external_node/src/config/mod.rs b/core/bin/external_node/src/config/mod.rs index d0249f7be5eb..ab780837ae06 100644 --- a/core/bin/external_node/src/config/mod.rs +++ b/core/bin/external_node/src/config/mod.rs @@ -13,14 +13,13 @@ use zksync_core::{ consensus, temp_config_store::decode_yaml, }; -use zksync_types::{api::BridgeAddresses, fee_model::FeeParams}; +use zksync_types::{api::BridgeAddresses, fee_model::FeeParams, ETHEREUM_ADDRESS}; use zksync_web3_decl::{ client::L2Client, - error::ClientRpcContext, + error::{ClientRpcContext, Web3Error}, jsonrpsee::http_client::HttpClientBuilder, namespaces::{EnNamespaceClient, EthNamespaceClient, ZksNamespaceClient}, }; - pub(crate) mod observability; #[cfg(test)] mod tests; @@ -43,6 +42,7 @@ pub(crate) struct RemoteENConfig { pub l2_testnet_paymaster_addr: Option
, pub l2_chain_id: L2ChainId, pub l1_chain_id: L1ChainId, + pub base_token_addr: Address, pub max_pubdata_per_batch: u64, pub l1_batch_commit_data_generator_mode: L1BatchCommitDataGeneratorMode, pub dummy_verifier: bool, @@ -64,6 +64,22 @@ impl RemoteENConfig { .get_main_contract() .rpc_context("get_main_contract") .await?; + let base_token_addr = match client.get_base_token_l1_address().await { + Err(ClientError::Call(err)) + if [ + ErrorCode::MethodNotFound.code(), + // This what Web3Error::NotImplemented gets + // casted into in the api server. + ErrorCode::InternalError.code(), + ] + .contains(&(err.code())) => + { + // This is the fallback case for when the EN tries to interact + // with a node that does not implement the zks_baseTokenL1Address endpoint. + ETHEREUM_ADDRESS + } + response => response.context("Failed to fetch base token address")?, + }; let l2_chain_id = client.chain_id().rpc_context("chain_id").await?; let l2_chain_id = L2ChainId::try_from(l2_chain_id.as_u64()) .map_err(|err| anyhow::anyhow!("invalid chain ID supplied by main node: {err}"))?; @@ -101,6 +117,7 @@ impl RemoteENConfig { l2_weth_bridge_addr: bridges.l2_weth_bridge, l2_chain_id, l1_chain_id, + base_token_addr, max_pubdata_per_batch, l1_batch_commit_data_generator_mode: genesis .as_ref() @@ -714,6 +731,7 @@ impl From for InternalApiConfig { l2_testnet_paymaster_addr: config.remote.l2_testnet_paymaster_addr, req_entities_limit: config.optional.req_entities_limit, fee_history_limit: config.optional.fee_history_limit, + base_token_address: Some(config.remote.base_token_addr), filters_disabled: config.optional.filters_disabled, mempool_cache_update_interval: config.optional.mempool_cache_update_interval(), mempool_cache_size: config.optional.mempool_cache_size, diff --git a/core/lib/config/src/configs/contracts.rs b/core/lib/config/src/configs/contracts.rs index 82ec4b1678b9..c3c4fce63b72 100644 --- a/core/lib/config/src/configs/contracts.rs +++ b/core/lib/config/src/configs/contracts.rs @@ -1,7 +1,7 @@ // External uses use serde::Deserialize; // Workspace uses -use zksync_basic_types::Address; +use zksync_basic_types::{Address, H256}; /// Data about deployed contracts. #[derive(Debug, Deserialize, Clone, PartialEq)] @@ -19,6 +19,7 @@ pub struct ContractsConfig { pub l2_weth_bridge_addr: Option
, pub l2_testnet_paymaster_addr: Option
, pub l1_multicall3_addr: Address, + pub base_token_addr: Option
} impl ContractsConfig { @@ -37,6 +38,7 @@ impl ContractsConfig { l2_testnet_paymaster_addr: Some(Address::repeat_byte(0x11)), l1_multicall3_addr: Address::repeat_byte(0x12), governance_addr: Address::repeat_byte(0x13), + base_token_addr: Some(Address::repeat_byte(0x14)), } } } diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index b058fed9ae20..95a7f3982ae8 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -243,6 +243,7 @@ impl Distribution for EncodeDist { l2_weth_bridge_addr: g.gen(), l2_testnet_paymaster_addr: g.gen(), l1_multicall3_addr: g.gen(), + base_token_addr: g.gen(), } } } diff --git a/core/lib/constants/src/contracts.rs b/core/lib/constants/src/contracts.rs index 29072d906fdd..1fc43d65884a 100644 --- a/core/lib/constants/src/contracts.rs +++ b/core/lib/constants/src/contracts.rs @@ -121,6 +121,10 @@ pub const MINT_AND_BURN_ADDRESS: H160 = H160::zero(); // The `storage_log.value` database value for a contract that was deployed in a failed transaction. pub const FAILED_CONTRACT_DEPLOYMENT_BYTECODE_HASH: H256 = H256::zero(); +pub const ETHEREUM_SHARED_BRIDGE_ADDRESS: Address = H160([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, +]); // Default ERA_CHAIN_ID. All hyeprchains starts with this chain id and later on // it will be changed to proper one pub const DEFAULT_ERA_CHAIN_ID: u32 = 270; diff --git a/core/lib/env_config/Cargo.toml b/core/lib/env_config/Cargo.toml index 0de13c90b5a4..e63b33ecae2d 100644 --- a/core/lib/env_config/Cargo.toml +++ b/core/lib/env_config/Cargo.toml @@ -10,6 +10,7 @@ keywords.workspace = true categories.workspace = true [dependencies] +zksync_system_constants.workspace = true zksync_basic_types.workspace = true zksync_config.workspace = true diff --git a/core/lib/env_config/src/contracts.rs b/core/lib/env_config/src/contracts.rs index edad9981f138..a90f84da5d45 100644 --- a/core/lib/env_config/src/contracts.rs +++ b/core/lib/env_config/src/contracts.rs @@ -10,6 +10,7 @@ impl FromEnv for ContractsConfig { #[cfg(test)] mod tests { + use zksync_system_constants::ETHEREUM_SHARED_BRIDGE_ADDRESS; use super::*; use crate::test_utils::{addr, EnvMutex}; @@ -30,6 +31,7 @@ mod tests { l2_shared_bridge_addr: addr("8656770FA78c830456B00B4fFCeE6b1De0e1b888"), l2_testnet_paymaster_addr: Some(addr("FC073319977e314F251EAE6ae6bE76B0B3BAeeCF")), l1_multicall3_addr: addr("0xcA11bde05977b3631167028862bE2a173976CA11"), + base_token_addr: Some(ETHEREUM_SHARED_BRIDGE_ADDRESS) } } @@ -66,6 +68,7 @@ CONTRACTS_FRI_RECURSION_NODE_LEVEL_VK_HASH="0x5a3ef282b21e12fe1f4438e5bb158fc506 CONTRACTS_FRI_RECURSION_LEAF_LEVEL_VK_HASH="0x72167c43a46cf38875b267d67716edc4563861364a3c03ab7aee73498421e828" CONTRACTS_PROVER_AT_GENESIS="fri" CONTRACTS_SNARK_WRAPPER_VK_HASH="0x4be443afd605a782b6e56d199df2460a025c81b3dea144e135bece83612563f2" +CONTRACTS_BASE_TOKEN_ADDR=0x0000000000000000000000000000000000000001 CONTRACTS_BRIDGEHUB_PROXY_ADDR="0x35ea7f92f4c5f433efe15284e99c040110cf6297" CONTRACTS_BRIDGEHUB_IMPL_ADDR="0x87d456da9ed212eb49d80d96afb44afddf36adf8" CONTRACTS_STATE_TRANSITION_PROXY_ADDR="0xd90f1c081c6117241624e97cb6147257c3cb2097" diff --git a/core/lib/protobuf_config/src/contracts.rs b/core/lib/protobuf_config/src/contracts.rs index 67febfcc0803..418d28610d85 100644 --- a/core/lib/protobuf_config/src/contracts.rs +++ b/core/lib/protobuf_config/src/contracts.rs @@ -14,6 +14,7 @@ impl ProtoRepr for proto::Contracts { let shared = required(&bridges.shared).context("shared")?; let erc20 = required(&bridges.erc20).context("erc20")?; let weth_bridge = required(&bridges.weth).context("weth_bridge")?; + // let base_token_address = &self.l2. Ok(Self::Type { governance_addr: required(&l1.governance_addr) .and_then(|x| parse_h160(x)) @@ -69,6 +70,12 @@ impl ProtoRepr for proto::Contracts { l1_multicall3_addr: required(&l1.multicall3_addr) .and_then(|x| parse_h160(x)) .context("l1_multicall3_addr")?, + base_token_addr: self + .base_token_address + .as_ref() + .map(|x| parse_h160(x)) + .transpose() + .context("base_token_addr")?, }) } diff --git a/core/lib/web3_decl/src/namespaces/zks.rs b/core/lib/web3_decl/src/namespaces/zks.rs index 3086d2ba1420..b896b11430ca 100644 --- a/core/lib/web3_decl/src/namespaces/zks.rs +++ b/core/lib/web3_decl/src/namespaces/zks.rs @@ -118,4 +118,7 @@ pub trait ZksNamespace { keys: Vec, l1_batch_number: L1BatchNumber, ) -> RpcResult>; + + #[method(name = "getBaseTokenL1Address")] + async fn get_base_token_l1_address(&self) -> RpcResult
; } diff --git a/core/lib/zksync_core/src/api_server/web3/backend_jsonrpsee/namespaces/zks.rs b/core/lib/zksync_core/src/api_server/web3/backend_jsonrpsee/namespaces/zks.rs index 580450288bd5..ba21fba770dc 100644 --- a/core/lib/zksync_core/src/api_server/web3/backend_jsonrpsee/namespaces/zks.rs +++ b/core/lib/zksync_core/src/api_server/web3/backend_jsonrpsee/namespaces/zks.rs @@ -167,4 +167,9 @@ impl ZksNamespaceServer for ZksNamespace { .await .map_err(|err| self.current_method().map_err(err)) } + + async fn get_base_token_l1_address(&self) -> RpcResult
{ + self.get_base_token_l1_address_impl() + .map_err(|err| self.current_method().map_err(err)) + } } diff --git a/core/lib/zksync_core/src/api_server/web3/namespaces/zks.rs b/core/lib/zksync_core/src/api_server/web3/namespaces/zks.rs index 7ccca7f2bee7..d97eadb92251 100644 --- a/core/lib/zksync_core/src/api_server/web3/namespaces/zks.rs +++ b/core/lib/zksync_core/src/api_server/web3/namespaces/zks.rs @@ -534,4 +534,12 @@ impl ZksNamespace { storage_proof, })) } + + #[tracing::instrument(skip_all)] + pub fn get_base_token_l1_address_impl(&self) -> Result { + self.state + .api_config + .base_token_address + .ok_or(Web3Error::NotImplemented) + } } diff --git a/core/lib/zksync_core/src/api_server/web3/state.rs b/core/lib/zksync_core/src/api_server/web3/state.rs index 3f564925079a..d859f95f834f 100644 --- a/core/lib/zksync_core/src/api_server/web3/state.rs +++ b/core/lib/zksync_core/src/api_server/web3/state.rs @@ -97,6 +97,7 @@ pub struct InternalApiConfig { pub l2_testnet_paymaster_addr: Option
, pub req_entities_limit: usize, pub fee_history_limit: u64, + pub base_token_address: Option
, pub filters_disabled: bool, pub mempool_cache_update_interval: Duration, pub mempool_cache_size: usize, @@ -141,6 +142,7 @@ impl InternalApiConfig { l2_testnet_paymaster_addr: contracts_config.l2_testnet_paymaster_addr, req_entities_limit: web3_config.req_entities_limit(), fee_history_limit: web3_config.fee_history_limit(), + base_token_address: contracts_config.base_token_addr, filters_disabled: web3_config.filters_disabled, mempool_cache_update_interval: web3_config.mempool_cache_update_interval(), mempool_cache_size: web3_config.mempool_cache_size(),