From 97aa6fb9a01c7e43d8f9a8d33f78fc6dca61548b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Grze=C5=9Bkiewicz?= Date: Tue, 20 Aug 2024 17:03:10 +0200 Subject: [PATCH] feat(eth-sender): added chain_id column to eth_txs + support for gateway in tx_aggregator (#2685) Signed-off-by: tomg10 --- core/bin/zksync_server/src/node_builder.rs | 5 ++ ...cf9654c06dfef57863281601c947830ad448a.json | 8 ++- ...98012b034605dfb4c48379844085b71e9e381.json | 22 ------- ...a75893ee5b1b94b6d0f25f1db5342888a2a30.json | 15 +++++ ...8ab71005d70f13ed32172e47166f71b3aef80.json | 23 ++++++++ ...3ce80f9b2b27758651ccfc09df61a4ae8a363.json | 8 ++- ...98fa893dbc9654d15753e4a538f021af67b60.json | 20 ------- ...8f65ff83204ebab2ea31847ae305a098823b0.json | 8 ++- ...5ac6758a0a4e367f93a9bd48ec82c51e09755.json | 8 ++- ...819150019_add_chain_id_to_eth_txs.down.sql | 1 + ...40819150019_add_chain_id_to_eth_txs.up.sql | 1 + core/lib/dal/src/eth_sender_dal.rs | 59 ++++++++++++------- core/lib/dal/src/models/storage_eth_tx.rs | 6 +- core/lib/types/src/eth_sender.rs | 3 + core/node/eth_sender/src/eth_tx_aggregator.rs | 20 ++++++- core/node/eth_sender/src/tester.rs | 5 +- .../layers/eth_sender/aggregator.rs | 20 +++++-- 17 files changed, 156 insertions(+), 76 deletions(-) delete mode 100644 core/lib/dal/.sqlx/query-254d17b5402c123cca0edd6fcdc98012b034605dfb4c48379844085b71e9e381.json create mode 100644 core/lib/dal/.sqlx/query-45372b701c23ce782695f11f846a75893ee5b1b94b6d0f25f1db5342888a2a30.json create mode 100644 core/lib/dal/.sqlx/query-4aeb7dcd79000540c03fb12c0608ab71005d70f13ed32172e47166f71b3aef80.json delete mode 100644 core/lib/dal/.sqlx/query-93725851350146c6ec253a59af598fa893dbc9654d15753e4a538f021af67b60.json create mode 100644 core/lib/dal/migrations/20240819150019_add_chain_id_to_eth_txs.down.sql create mode 100644 core/lib/dal/migrations/20240819150019_add_chain_id_to_eth_txs.up.sql diff --git a/core/bin/zksync_server/src/node_builder.rs b/core/bin/zksync_server/src/node_builder.rs index add114c170a4..7c1140bc5a04 100644 --- a/core/bin/zksync_server/src/node_builder.rs +++ b/core/bin/zksync_server/src/node_builder.rs @@ -434,6 +434,11 @@ impl MainNodeBuilder { self.contracts_config.clone(), self.genesis_config.l2_chain_id, self.genesis_config.l1_batch_commit_data_generator_mode, + self.configs + .eth + .as_ref() + .and_then(|x| Some(x.gas_adjuster?.settlement_mode)) + .unwrap_or(SettlementMode::SettlesToL1), )); Ok(self) diff --git a/core/lib/dal/.sqlx/query-0fede71ed258790cf70d6d6a32dcf9654c06dfef57863281601c947830ad448a.json b/core/lib/dal/.sqlx/query-0fede71ed258790cf70d6d6a32dcf9654c06dfef57863281601c947830ad448a.json index cdf425de713b..6a3174958db8 100644 --- a/core/lib/dal/.sqlx/query-0fede71ed258790cf70d6d6a32dcf9654c06dfef57863281601c947830ad448a.json +++ b/core/lib/dal/.sqlx/query-0fede71ed258790cf70d6d6a32dcf9654c06dfef57863281601c947830ad448a.json @@ -77,6 +77,11 @@ "ordinal": 14, "name": "is_gateway", "type_info": "Bool" + }, + { + "ordinal": 15, + "name": "chain_id", + "type_info": "Int8" } ], "parameters": { @@ -106,7 +111,8 @@ false, true, true, - false + false, + true ] }, "hash": "0fede71ed258790cf70d6d6a32dcf9654c06dfef57863281601c947830ad448a" diff --git a/core/lib/dal/.sqlx/query-254d17b5402c123cca0edd6fcdc98012b034605dfb4c48379844085b71e9e381.json b/core/lib/dal/.sqlx/query-254d17b5402c123cca0edd6fcdc98012b034605dfb4c48379844085b71e9e381.json deleted file mode 100644 index 8734598cc6f6..000000000000 --- a/core/lib/dal/.sqlx/query-254d17b5402c123cca0edd6fcdc98012b034605dfb4c48379844085b71e9e381.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT nonce FROM eth_txs WHERE from_addr = $1::bytea ORDER BY id DESC LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "nonce", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Bytea" - ] - }, - "nullable": [ - false - ] - }, - "hash": "254d17b5402c123cca0edd6fcdc98012b034605dfb4c48379844085b71e9e381" -} diff --git a/core/lib/dal/.sqlx/query-45372b701c23ce782695f11f846a75893ee5b1b94b6d0f25f1db5342888a2a30.json b/core/lib/dal/.sqlx/query-45372b701c23ce782695f11f846a75893ee5b1b94b6d0f25f1db5342888a2a30.json new file mode 100644 index 000000000000..0567a415ac16 --- /dev/null +++ b/core/lib/dal/.sqlx/query-45372b701c23ce782695f11f846a75893ee5b1b94b6d0f25f1db5342888a2a30.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "\n UPDATE eth_txs\n SET\n chain_id = $1\n WHERE\n id = $2\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Int4" + ] + }, + "nullable": [] + }, + "hash": "45372b701c23ce782695f11f846a75893ee5b1b94b6d0f25f1db5342888a2a30" +} diff --git a/core/lib/dal/.sqlx/query-4aeb7dcd79000540c03fb12c0608ab71005d70f13ed32172e47166f71b3aef80.json b/core/lib/dal/.sqlx/query-4aeb7dcd79000540c03fb12c0608ab71005d70f13ed32172e47166f71b3aef80.json new file mode 100644 index 000000000000..feb8f29855e4 --- /dev/null +++ b/core/lib/dal/.sqlx/query-4aeb7dcd79000540c03fb12c0608ab71005d70f13ed32172e47166f71b3aef80.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n nonce\n FROM\n eth_txs\n WHERE\n from_addr IS NOT DISTINCT FROM $1 -- can't just use equality as NULL != NULL\\\n AND is_gateway = $2\n ORDER BY\n id DESC\n LIMIT\n 1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "nonce", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Bytea", + "Bool" + ] + }, + "nullable": [ + false + ] + }, + "hash": "4aeb7dcd79000540c03fb12c0608ab71005d70f13ed32172e47166f71b3aef80" +} diff --git a/core/lib/dal/.sqlx/query-6692ff6c0fbb2fc94f5cd2837a43ce80f9b2b27758651ccfc09df61a4ae8a363.json b/core/lib/dal/.sqlx/query-6692ff6c0fbb2fc94f5cd2837a43ce80f9b2b27758651ccfc09df61a4ae8a363.json index 49578cd67bec..1a3c160cee1b 100644 --- a/core/lib/dal/.sqlx/query-6692ff6c0fbb2fc94f5cd2837a43ce80f9b2b27758651ccfc09df61a4ae8a363.json +++ b/core/lib/dal/.sqlx/query-6692ff6c0fbb2fc94f5cd2837a43ce80f9b2b27758651ccfc09df61a4ae8a363.json @@ -77,6 +77,11 @@ "ordinal": 14, "name": "is_gateway", "type_info": "Bool" + }, + { + "ordinal": 15, + "name": "chain_id", + "type_info": "Int8" } ], "parameters": { @@ -99,7 +104,8 @@ false, true, true, - false + false, + true ] }, "hash": "6692ff6c0fbb2fc94f5cd2837a43ce80f9b2b27758651ccfc09df61a4ae8a363" diff --git a/core/lib/dal/.sqlx/query-93725851350146c6ec253a59af598fa893dbc9654d15753e4a538f021af67b60.json b/core/lib/dal/.sqlx/query-93725851350146c6ec253a59af598fa893dbc9654d15753e4a538f021af67b60.json deleted file mode 100644 index 80788846fe69..000000000000 --- a/core/lib/dal/.sqlx/query-93725851350146c6ec253a59af598fa893dbc9654d15753e4a538f021af67b60.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT nonce FROM eth_txs WHERE from_addr IS NULL ORDER BY id DESC LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "nonce", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - false - ] - }, - "hash": "93725851350146c6ec253a59af598fa893dbc9654d15753e4a538f021af67b60" -} diff --git a/core/lib/dal/.sqlx/query-a71a87d91dcf0f624dbd64eb8828f65ff83204ebab2ea31847ae305a098823b0.json b/core/lib/dal/.sqlx/query-a71a87d91dcf0f624dbd64eb8828f65ff83204ebab2ea31847ae305a098823b0.json index 28058b9e42a7..272f20e5268a 100644 --- a/core/lib/dal/.sqlx/query-a71a87d91dcf0f624dbd64eb8828f65ff83204ebab2ea31847ae305a098823b0.json +++ b/core/lib/dal/.sqlx/query-a71a87d91dcf0f624dbd64eb8828f65ff83204ebab2ea31847ae305a098823b0.json @@ -77,6 +77,11 @@ "ordinal": 14, "name": "is_gateway", "type_info": "Bool" + }, + { + "ordinal": 15, + "name": "chain_id", + "type_info": "Int8" } ], "parameters": { @@ -100,7 +105,8 @@ false, true, true, - false + false, + true ] }, "hash": "a71a87d91dcf0f624dbd64eb8828f65ff83204ebab2ea31847ae305a098823b0" diff --git a/core/lib/dal/.sqlx/query-eab36591af61369e36e3dab79025ac6758a0a4e367f93a9bd48ec82c51e09755.json b/core/lib/dal/.sqlx/query-eab36591af61369e36e3dab79025ac6758a0a4e367f93a9bd48ec82c51e09755.json index fb6ea1d2d3e5..b9783f771a7a 100644 --- a/core/lib/dal/.sqlx/query-eab36591af61369e36e3dab79025ac6758a0a4e367f93a9bd48ec82c51e09755.json +++ b/core/lib/dal/.sqlx/query-eab36591af61369e36e3dab79025ac6758a0a4e367f93a9bd48ec82c51e09755.json @@ -77,6 +77,11 @@ "ordinal": 14, "name": "is_gateway", "type_info": "Bool" + }, + { + "ordinal": 15, + "name": "chain_id", + "type_info": "Int8" } ], "parameters": { @@ -101,7 +106,8 @@ false, true, true, - false + false, + true ] }, "hash": "eab36591af61369e36e3dab79025ac6758a0a4e367f93a9bd48ec82c51e09755" diff --git a/core/lib/dal/migrations/20240819150019_add_chain_id_to_eth_txs.down.sql b/core/lib/dal/migrations/20240819150019_add_chain_id_to_eth_txs.down.sql new file mode 100644 index 000000000000..65fcdc9cfcdf --- /dev/null +++ b/core/lib/dal/migrations/20240819150019_add_chain_id_to_eth_txs.down.sql @@ -0,0 +1 @@ +ALTER TABLE eth_txs DROP COLUMN chain_id; diff --git a/core/lib/dal/migrations/20240819150019_add_chain_id_to_eth_txs.up.sql b/core/lib/dal/migrations/20240819150019_add_chain_id_to_eth_txs.up.sql new file mode 100644 index 000000000000..bbcfe41a58c1 --- /dev/null +++ b/core/lib/dal/migrations/20240819150019_add_chain_id_to_eth_txs.up.sql @@ -0,0 +1 @@ +ALTER TABLE eth_txs ADD COLUMN chain_id BIGINT; diff --git a/core/lib/dal/src/eth_sender_dal.rs b/core/lib/dal/src/eth_sender_dal.rs index eb7e1cd642c1..c76547422d8f 100644 --- a/core/lib/dal/src/eth_sender_dal.rs +++ b/core/lib/dal/src/eth_sender_dal.rs @@ -404,6 +404,23 @@ impl EthSenderDal<'_, '_> { Ok(()) } + pub async fn set_chain_id(&mut self, eth_tx_id: u32, chain_id: u64) -> anyhow::Result<()> { + sqlx::query!( + r#" + UPDATE eth_txs + SET + chain_id = $1 + WHERE + id = $2 + "#, + eth_tx_id as i32, + chain_id as i64, + ) + .execute(self.storage.conn()) + .await?; + Ok(()) + } + pub async fn get_confirmed_tx_hash_by_eth_tx_id( &mut self, eth_tx_id: u32, @@ -610,29 +627,29 @@ impl EthSenderDal<'_, '_> { pub async fn get_next_nonce( &mut self, from_address: Option
, + is_gateway: bool, ) -> sqlx::Result> { - struct NonceRow { - nonce: i64, - } - - let query = match_query_as!( - NonceRow, - [ - "SELECT nonce FROM eth_txs WHERE ", - _, // WHERE condition - " ORDER BY id DESC LIMIT 1" - ], - match (from_address) { - Some(address) => ("from_addr = $1::bytea"; address.as_bytes()), - None => ("from_addr IS NULL";), - } - ); + let nonce = sqlx::query!( + r#" + SELECT + nonce + FROM + eth_txs + WHERE + from_addr IS NOT DISTINCT FROM $1 -- can't just use equality as NULL != NULL\ + AND is_gateway = $2 + ORDER BY + id DESC + LIMIT + 1 + "#, + from_address.as_ref().map(|h160| h160.as_bytes()), + is_gateway + ) + .fetch_optional(self.storage.conn()) + .await?; - let nonce = query - .fetch_optional(self.storage.conn()) - .await? - .map(|row| row.nonce as u64); - Ok(nonce.map(|n| n + 1)) + Ok(nonce.map(|row| row.nonce as u64 + 1)) } pub async fn mark_failed_transaction(&mut self, eth_tx_id: u32) -> sqlx::Result<()> { diff --git a/core/lib/dal/src/models/storage_eth_tx.rs b/core/lib/dal/src/models/storage_eth_tx.rs index c721f938838e..a47f6acfff46 100644 --- a/core/lib/dal/src/models/storage_eth_tx.rs +++ b/core/lib/dal/src/models/storage_eth_tx.rs @@ -4,7 +4,7 @@ use sqlx::types::chrono::NaiveDateTime; use zksync_types::{ aggregated_operations::AggregatedActionType, eth_sender::{EthTx, TxHistory, TxHistoryToSend}, - Address, L1BatchNumber, Nonce, H256, + Address, L1BatchNumber, Nonce, SLChainId, H256, }; #[derive(Debug, Clone)] @@ -30,6 +30,7 @@ pub struct StorageEthTx { // Format a `bincode`-encoded `EthTxBlobSidecar` enum. pub blob_sidecar: Option>, pub is_gateway: bool, + pub chain_id: Option, } #[derive(Debug, Default)] @@ -85,6 +86,9 @@ impl From for EthTx { bincode::deserialize(&b).expect("EthTxBlobSidecar is encoded correctly; qed") }), is_gateway: tx.is_gateway, + chain_id: tx + .chain_id + .map(|chain_id| SLChainId(chain_id.try_into().unwrap())), } } } diff --git a/core/lib/types/src/eth_sender.rs b/core/lib/types/src/eth_sender.rs index 09ea915283eb..12a5a5a8fb13 100644 --- a/core/lib/types/src/eth_sender.rs +++ b/core/lib/types/src/eth_sender.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use zksync_basic_types::SLChainId; use crate::{aggregated_operations::AggregatedActionType, Address, Nonce, H256}; @@ -52,6 +53,7 @@ pub struct EthTx { pub from_addr: Option
, pub blob_sidecar: Option, pub is_gateway: bool, + pub chain_id: Option, } impl std::fmt::Debug for EthTx { @@ -64,6 +66,7 @@ impl std::fmt::Debug for EthTx { .field("tx_type", &self.tx_type) .field("created_at_timestamp", &self.created_at_timestamp) .field("predicted_gas_cost", &self.predicted_gas_cost) + .field("chain_id", &self.chain_id) .finish() } } diff --git a/core/node/eth_sender/src/eth_tx_aggregator.rs b/core/node/eth_sender/src/eth_tx_aggregator.rs index 856b79eb5c93..7d6a6b234742 100644 --- a/core/node/eth_sender/src/eth_tx_aggregator.rs +++ b/core/node/eth_sender/src/eth_tx_aggregator.rs @@ -20,8 +20,9 @@ use zksync_types::{ l2_to_l1_log::UserL2ToL1Log, protocol_version::{L1VerifierConfig, PACKED_SEMVER_MINOR_MASK}, pubdata_da::PubdataDA, + settlement::SettlementMode, web3::{contract::Error as Web3ContractError, BlockNumber}, - Address, L2ChainId, ProtocolVersionId, H256, U256, + Address, L2ChainId, ProtocolVersionId, SLChainId, H256, U256, }; use super::aggregated_operations::AggregatedOperation; @@ -62,6 +63,8 @@ pub struct EthTxAggregator { /// address. custom_commit_sender_addr: Option
, pool: ConnectionPool, + settlement_mode: SettlementMode, + sl_chain_id: SLChainId, } struct TxData { @@ -81,6 +84,7 @@ impl EthTxAggregator { state_transition_chain_contract: Address, rollup_chain_id: L2ChainId, custom_commit_sender_addr: Option
, + settlement_mode: SettlementMode, ) -> Self { let eth_client = eth_client.for_component("eth_tx_aggregator"); let functions = ZkSyncFunctions::default(); @@ -97,6 +101,9 @@ impl EthTxAggregator { ), None => None, }; + + let sl_chain_id = (*eth_client).as_ref().fetch_chain_id().await.unwrap(); + Self { config, aggregator, @@ -110,6 +117,8 @@ impl EthTxAggregator { rollup_chain_id, custom_commit_sender_addr, pool, + settlement_mode, + sl_chain_id, } } @@ -578,6 +587,12 @@ impl EthTxAggregator { .await .unwrap(); + transaction + .eth_sender_dal() + .set_chain_id(eth_tx.id, self.sl_chain_id.0) + .await + .unwrap(); + transaction .blocks_dal() .set_eth_tx_id(l1_batch_number_range, eth_tx.id, op_type) @@ -592,9 +607,10 @@ impl EthTxAggregator { storage: &mut Connection<'_, Core>, from_addr: Option
, ) -> Result { + let is_gateway = self.settlement_mode.is_gateway(); let db_nonce = storage .eth_sender_dal() - .get_next_nonce(from_addr) + .get_next_nonce(from_addr, is_gateway) .await .unwrap() .unwrap_or(0); diff --git a/core/node/eth_sender/src/tester.rs b/core/node/eth_sender/src/tester.rs index 508a38e61732..c6d993a9c97f 100644 --- a/core/node/eth_sender/src/tester.rs +++ b/core/node/eth_sender/src/tester.rs @@ -12,8 +12,8 @@ use zksync_node_test_utils::{create_l1_batch, l1_batch_metadata_to_commitment_ar use zksync_object_store::MockObjectStore; use zksync_types::{ aggregated_operations::AggregatedActionType, block::L1BatchHeader, - commitment::L1BatchCommitmentMode, eth_sender::EthTx, pubdata_da::PubdataDA, Address, - L1BatchNumber, ProtocolVersion, H256, + commitment::L1BatchCommitmentMode, eth_sender::EthTx, pubdata_da::PubdataDA, + settlement::SettlementMode, Address, L1BatchNumber, ProtocolVersion, H256, }; use crate::{ @@ -264,6 +264,7 @@ impl EthSenderTester { Address::random(), Default::default(), custom_commit_sender_addr, + SettlementMode::SettlesToL1, ) .await; diff --git a/core/node/node_framework/src/implementations/layers/eth_sender/aggregator.rs b/core/node/node_framework/src/implementations/layers/eth_sender/aggregator.rs index 96fffcaf6a84..cfe701326bd6 100644 --- a/core/node/node_framework/src/implementations/layers/eth_sender/aggregator.rs +++ b/core/node/node_framework/src/implementations/layers/eth_sender/aggregator.rs @@ -3,12 +3,15 @@ use zksync_circuit_breaker::l1_txs::FailedL1TransactionChecker; use zksync_config::configs::{eth_sender::EthConfig, ContractsConfig}; use zksync_eth_client::BoundEthInterface; use zksync_eth_sender::{Aggregator, EthTxAggregator}; -use zksync_types::{commitment::L1BatchCommitmentMode, L2ChainId}; +use zksync_types::{commitment::L1BatchCommitmentMode, settlement::SettlementMode, L2ChainId}; use crate::{ implementations::resources::{ circuit_breakers::CircuitBreakersResource, - eth_interface::{BoundEthInterfaceForBlobsResource, BoundEthInterfaceResource}, + eth_interface::{ + BoundEthInterfaceForBlobsResource, BoundEthInterfaceForL2Resource, + BoundEthInterfaceResource, + }, object_store::ObjectStoreResource, pools::{MasterPool, PoolResource, ReplicaPool}, }, @@ -42,6 +45,7 @@ pub struct EthTxAggregatorLayer { contracts_config: ContractsConfig, zksync_network_id: L2ChainId, l1_batch_commit_data_generator_mode: L1BatchCommitmentMode, + settlement_mode: SettlementMode, } #[derive(Debug, FromContext)] @@ -49,8 +53,9 @@ pub struct EthTxAggregatorLayer { pub struct Input { pub master_pool: PoolResource, pub replica_pool: PoolResource, - pub eth_client: BoundEthInterfaceResource, + pub eth_client: Option, pub eth_client_blobs: Option, + pub eth_client_l2: Option, pub object_store: ObjectStoreResource, #[context(default)] pub circuit_breakers: CircuitBreakersResource, @@ -69,12 +74,14 @@ impl EthTxAggregatorLayer { contracts_config: ContractsConfig, zksync_network_id: L2ChainId, l1_batch_commit_data_generator_mode: L1BatchCommitmentMode, + settlement_mode: SettlementMode, ) -> Self { Self { eth_sender_config, contracts_config, zksync_network_id, l1_batch_commit_data_generator_mode, + settlement_mode, } } } @@ -93,7 +100,11 @@ impl WiringLayer for EthTxAggregatorLayer { let master_pool = input.master_pool.get().await.unwrap(); let replica_pool = input.replica_pool.get().await.unwrap(); - let eth_client = input.eth_client.0; + let eth_client = if self.settlement_mode.is_gateway() { + input.eth_client_l2.context("l2_client must be provided")?.0 + } else { + input.eth_client.context("l1_client must be provided")?.0 + }; let eth_client_blobs = input.eth_client_blobs.map(|c| c.0); let object_store = input.object_store.0; @@ -120,6 +131,7 @@ impl WiringLayer for EthTxAggregatorLayer { self.contracts_config.diamond_proxy_addr, self.zksync_network_id, eth_client_blobs_addr, + self.settlement_mode, ) .await;