diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs
index e932cd9819b9..89f8d459a1d9 100644
--- a/core/lib/config/src/configs/eth_sender.rs
+++ b/core/lib/config/src/configs/eth_sender.rs
@@ -24,7 +24,7 @@ impl EthConfig {
Self {
sender: Some(SenderConfig {
aggregated_proof_sizes: vec![1],
- wait_confirmations: Some(1),
+ wait_confirmations: Some(10),
tx_poll_period: 1,
aggregate_tx_poll_period: 1,
max_txs_in_flight: 30,
diff --git a/core/lib/dal/.sqlx/query-2a2680234c38904e5c19df45193a8c13d04079683e09c65f7f4e76a9987e2ab4.json b/core/lib/dal/.sqlx/query-0fede71ed258790cf70d6d6a32dcf9654c06dfef57863281601c947830ad448a.json
similarity index 81%
rename from core/lib/dal/.sqlx/query-2a2680234c38904e5c19df45193a8c13d04079683e09c65f7f4e76a9987e2ab4.json
rename to core/lib/dal/.sqlx/query-0fede71ed258790cf70d6d6a32dcf9654c06dfef57863281601c947830ad448a.json
index 8b984f4939a8..cdf425de713b 100644
--- a/core/lib/dal/.sqlx/query-2a2680234c38904e5c19df45193a8c13d04079683e09c65f7f4e76a9987e2ab4.json
+++ b/core/lib/dal/.sqlx/query-0fede71ed258790cf70d6d6a32dcf9654c06dfef57863281601c947830ad448a.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n INSERT INTO\n eth_txs (\n raw_tx,\n nonce,\n tx_type,\n contract_address,\n predicted_gas_cost,\n created_at,\n updated_at,\n from_addr,\n blob_sidecar\n )\n VALUES\n ($1, $2, $3, $4, $5, NOW(), NOW(), $6, $7)\n RETURNING\n *\n ",
+ "query": "\n INSERT INTO\n eth_txs (\n raw_tx,\n nonce,\n tx_type,\n contract_address,\n predicted_gas_cost,\n created_at,\n updated_at,\n from_addr,\n blob_sidecar,\n is_gateway\n )\n VALUES\n ($1, $2, $3, $4, $5, NOW(), NOW(), $6, $7, $8)\n RETURNING\n *\n ",
"describe": {
"columns": [
{
@@ -72,6 +72,11 @@
"ordinal": 13,
"name": "blob_sidecar",
"type_info": "Bytea"
+ },
+ {
+ "ordinal": 14,
+ "name": "is_gateway",
+ "type_info": "Bool"
}
],
"parameters": {
@@ -82,7 +87,8 @@
"Text",
"Int8",
"Bytea",
- "Bytea"
+ "Bytea",
+ "Bool"
]
},
"nullable": [
@@ -99,8 +105,9 @@
true,
false,
true,
- true
+ true,
+ false
]
},
- "hash": "2a2680234c38904e5c19df45193a8c13d04079683e09c65f7f4e76a9987e2ab4"
+ "hash": "0fede71ed258790cf70d6d6a32dcf9654c06dfef57863281601c947830ad448a"
}
diff --git a/core/lib/dal/.sqlx/query-5b7d2612dd2dd064ea0095b40669754ed7219a77459ef40cd99d7d4d0749e538.json b/core/lib/dal/.sqlx/query-5b7d2612dd2dd064ea0095b40669754ed7219a77459ef40cd99d7d4d0749e538.json
new file mode 100644
index 000000000000..88bac1a36022
--- /dev/null
+++ b/core/lib/dal/.sqlx/query-5b7d2612dd2dd064ea0095b40669754ed7219a77459ef40cd99d7d4d0749e538.json
@@ -0,0 +1,20 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "\n SELECT\n COUNT(*)\n FROM\n eth_txs\n WHERE\n confirmed_eth_tx_history_id IS NULL\n AND is_gateway = FALSE\n ",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "count",
+ "type_info": "Int8"
+ }
+ ],
+ "parameters": {
+ "Left": []
+ },
+ "nullable": [
+ null
+ ]
+ },
+ "hash": "5b7d2612dd2dd064ea0095b40669754ed7219a77459ef40cd99d7d4d0749e538"
+}
diff --git a/core/lib/dal/.sqlx/query-6692ff6c0fbb2fc94f5cd2837a43ce80f9b2b27758651ccfc09df61a4ae8a363.json b/core/lib/dal/.sqlx/query-6692ff6c0fbb2fc94f5cd2837a43ce80f9b2b27758651ccfc09df61a4ae8a363.json
index 985f998b439a..49578cd67bec 100644
--- a/core/lib/dal/.sqlx/query-6692ff6c0fbb2fc94f5cd2837a43ce80f9b2b27758651ccfc09df61a4ae8a363.json
+++ b/core/lib/dal/.sqlx/query-6692ff6c0fbb2fc94f5cd2837a43ce80f9b2b27758651ccfc09df61a4ae8a363.json
@@ -72,6 +72,11 @@
"ordinal": 13,
"name": "blob_sidecar",
"type_info": "Bytea"
+ },
+ {
+ "ordinal": 14,
+ "name": "is_gateway",
+ "type_info": "Bool"
}
],
"parameters": {
@@ -93,7 +98,8 @@
true,
false,
true,
- true
+ true,
+ false
]
},
"hash": "6692ff6c0fbb2fc94f5cd2837a43ce80f9b2b27758651ccfc09df61a4ae8a363"
diff --git a/core/lib/dal/.sqlx/query-6bb5eab89be2b08a08c00b5cd8d725208b0ecfe8065c8f893ff38c49072a21fc.json b/core/lib/dal/.sqlx/query-a71a87d91dcf0f624dbd64eb8828f65ff83204ebab2ea31847ae305a098823b0.json
similarity index 70%
rename from core/lib/dal/.sqlx/query-6bb5eab89be2b08a08c00b5cd8d725208b0ecfe8065c8f893ff38c49072a21fc.json
rename to core/lib/dal/.sqlx/query-a71a87d91dcf0f624dbd64eb8828f65ff83204ebab2ea31847ae305a098823b0.json
index 71318c9a1023..28058b9e42a7 100644
--- a/core/lib/dal/.sqlx/query-6bb5eab89be2b08a08c00b5cd8d725208b0ecfe8065c8f893ff38c49072a21fc.json
+++ b/core/lib/dal/.sqlx/query-a71a87d91dcf0f624dbd64eb8828f65ff83204ebab2ea31847ae305a098823b0.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n SELECT\n *\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 confirmed_eth_tx_history_id IS NULL\n AND id <= (\n SELECT\n COALESCE(MAX(eth_tx_id), 0)\n FROM\n eth_txs_history\n JOIN eth_txs ON eth_txs.id = eth_txs_history.eth_tx_id\n WHERE\n eth_txs_history.sent_at_block IS NOT NULL\n AND eth_txs.from_addr IS NOT DISTINCT FROM $1\n )\n ORDER BY\n id\n ",
+ "query": "\n SELECT\n *\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 confirmed_eth_tx_history_id IS NULL\n AND is_gateway = $2\n AND id <= (\n SELECT\n COALESCE(MAX(eth_tx_id), 0)\n FROM\n eth_txs_history\n JOIN eth_txs ON eth_txs.id = eth_txs_history.eth_tx_id\n WHERE\n eth_txs_history.sent_at_block IS NOT NULL\n AND eth_txs.from_addr IS NOT DISTINCT FROM $1\n AND is_gateway = $2\n )\n ORDER BY\n id\n ",
"describe": {
"columns": [
{
@@ -72,11 +72,17 @@
"ordinal": 13,
"name": "blob_sidecar",
"type_info": "Bytea"
+ },
+ {
+ "ordinal": 14,
+ "name": "is_gateway",
+ "type_info": "Bool"
}
],
"parameters": {
"Left": [
- "Bytea"
+ "Bytea",
+ "Bool"
]
},
"nullable": [
@@ -93,8 +99,9 @@
true,
false,
true,
- true
+ true,
+ false
]
},
- "hash": "6bb5eab89be2b08a08c00b5cd8d725208b0ecfe8065c8f893ff38c49072a21fc"
+ "hash": "a71a87d91dcf0f624dbd64eb8828f65ff83204ebab2ea31847ae305a098823b0"
}
diff --git a/core/lib/dal/.sqlx/query-4570e9ffd0b2973d0bc2986c391d0a59076dda4aa572ade2492f37e537fdf6ed.json b/core/lib/dal/.sqlx/query-eab36591af61369e36e3dab79025ac6758a0a4e367f93a9bd48ec82c51e09755.json
similarity index 68%
rename from core/lib/dal/.sqlx/query-4570e9ffd0b2973d0bc2986c391d0a59076dda4aa572ade2492f37e537fdf6ed.json
rename to core/lib/dal/.sqlx/query-eab36591af61369e36e3dab79025ac6758a0a4e367f93a9bd48ec82c51e09755.json
index 7297bcdcad23..fb6ea1d2d3e5 100644
--- a/core/lib/dal/.sqlx/query-4570e9ffd0b2973d0bc2986c391d0a59076dda4aa572ade2492f37e537fdf6ed.json
+++ b/core/lib/dal/.sqlx/query-eab36591af61369e36e3dab79025ac6758a0a4e367f93a9bd48ec82c51e09755.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n SELECT\n *\n FROM\n eth_txs\n WHERE\n from_addr IS NOT DISTINCT FROM $2 -- can't just use equality as NULL != NULL\n AND id > (\n SELECT\n COALESCE(MAX(eth_tx_id), 0)\n FROM\n eth_txs_history\n JOIN eth_txs ON eth_txs.id = eth_txs_history.eth_tx_id\n WHERE\n eth_txs_history.sent_at_block IS NOT NULL\n AND eth_txs.from_addr IS NOT DISTINCT FROM $2\n )\n ORDER BY\n id\n LIMIT\n $1\n ",
+ "query": "\n SELECT\n *\n FROM\n eth_txs\n WHERE\n from_addr IS NOT DISTINCT FROM $2 -- can't just use equality as NULL != NULL\n AND is_gateway = $3\n AND id > (\n SELECT\n COALESCE(MAX(eth_tx_id), 0)\n FROM\n eth_txs_history\n JOIN eth_txs ON eth_txs.id = eth_txs_history.eth_tx_id\n WHERE\n eth_txs_history.sent_at_block IS NOT NULL\n AND eth_txs.from_addr IS NOT DISTINCT FROM $2\n AND is_gateway = $3\n )\n ORDER BY\n id\n LIMIT\n $1\n ",
"describe": {
"columns": [
{
@@ -72,12 +72,18 @@
"ordinal": 13,
"name": "blob_sidecar",
"type_info": "Bytea"
+ },
+ {
+ "ordinal": 14,
+ "name": "is_gateway",
+ "type_info": "Bool"
}
],
"parameters": {
"Left": [
"Int8",
- "Bytea"
+ "Bytea",
+ "Bool"
]
},
"nullable": [
@@ -94,8 +100,9 @@
true,
false,
true,
- true
+ true,
+ false
]
},
- "hash": "4570e9ffd0b2973d0bc2986c391d0a59076dda4aa572ade2492f37e537fdf6ed"
+ "hash": "eab36591af61369e36e3dab79025ac6758a0a4e367f93a9bd48ec82c51e09755"
}
diff --git a/core/lib/dal/migrations/20240803083814_add_is_gateway_column_to_eth_txs.down.sql b/core/lib/dal/migrations/20240803083814_add_is_gateway_column_to_eth_txs.down.sql
new file mode 100644
index 000000000000..02fbc8cb075d
--- /dev/null
+++ b/core/lib/dal/migrations/20240803083814_add_is_gateway_column_to_eth_txs.down.sql
@@ -0,0 +1 @@
+ALTER TABLE eth_txs DROP COLUMN is_gateway;
diff --git a/core/lib/dal/migrations/20240803083814_add_is_gateway_column_to_eth_txs.up.sql b/core/lib/dal/migrations/20240803083814_add_is_gateway_column_to_eth_txs.up.sql
new file mode 100644
index 000000000000..af1ef835cf37
--- /dev/null
+++ b/core/lib/dal/migrations/20240803083814_add_is_gateway_column_to_eth_txs.up.sql
@@ -0,0 +1 @@
+ALTER TABLE eth_txs ADD COLUMN is_gateway BOOLEAN NOT NULL DEFAULT FALSE;
diff --git a/core/lib/dal/src/blocks_dal.rs b/core/lib/dal/src/blocks_dal.rs
index dbb56b42a463..60956101a8c5 100644
--- a/core/lib/dal/src/blocks_dal.rs
+++ b/core/lib/dal/src/blocks_dal.rs
@@ -2548,7 +2548,16 @@ mod tests {
async fn save_mock_eth_tx(action_type: AggregatedActionType, conn: &mut Connection<'_, Core>) {
conn.eth_sender_dal()
- .save_eth_tx(1, vec![], action_type, Address::default(), 1, None, None)
+ .save_eth_tx(
+ 1,
+ vec![],
+ action_type,
+ Address::default(),
+ 1,
+ None,
+ None,
+ false,
+ )
.await
.unwrap();
}
diff --git a/core/lib/dal/src/blocks_web3_dal.rs b/core/lib/dal/src/blocks_web3_dal.rs
index 54ea7cc11f16..36a4acc0a6db 100644
--- a/core/lib/dal/src/blocks_web3_dal.rs
+++ b/core/lib/dal/src/blocks_web3_dal.rs
@@ -977,6 +977,7 @@ mod tests {
0,
None,
None,
+ false,
)
.await
.unwrap();
diff --git a/core/lib/dal/src/eth_sender_dal.rs b/core/lib/dal/src/eth_sender_dal.rs
index f1ff515f506e..eb7e1cd642c1 100644
--- a/core/lib/dal/src/eth_sender_dal.rs
+++ b/core/lib/dal/src/eth_sender_dal.rs
@@ -25,6 +25,7 @@ impl EthSenderDal<'_, '_> {
pub async fn get_inflight_txs(
&mut self,
operator_address: Option
,
+ is_gateway: bool,
) -> sqlx::Result> {
let txs = sqlx::query_as!(
StorageEthTx,
@@ -36,6 +37,7 @@ impl EthSenderDal<'_, '_> {
WHERE
from_addr IS NOT DISTINCT FROM $1 -- can't just use equality as NULL != NULL
AND confirmed_eth_tx_history_id IS NULL
+ AND is_gateway = $2
AND id <= (
SELECT
COALESCE(MAX(eth_tx_id), 0)
@@ -45,17 +47,40 @@ impl EthSenderDal<'_, '_> {
WHERE
eth_txs_history.sent_at_block IS NOT NULL
AND eth_txs.from_addr IS NOT DISTINCT FROM $1
+ AND is_gateway = $2
)
ORDER BY
id
"#,
operator_address.as_ref().map(|h160| h160.as_bytes()),
+ is_gateway
)
.fetch_all(self.storage.conn())
.await?;
Ok(txs.into_iter().map(|tx| tx.into()).collect())
}
+ pub async fn get_non_gateway_inflight_txs_count_for_gateway_migration(
+ &mut self,
+ ) -> sqlx::Result {
+ let count = sqlx::query!(
+ r#"
+ SELECT
+ COUNT(*)
+ FROM
+ eth_txs
+ WHERE
+ confirmed_eth_tx_history_id IS NULL
+ AND is_gateway = FALSE
+ "#
+ )
+ .fetch_one(self.storage.conn())
+ .await?
+ .count
+ .unwrap();
+ Ok(count.try_into().unwrap())
+ }
+
pub async fn get_eth_l1_batches(&mut self) -> sqlx::Result {
struct EthTxRow {
number: i64,
@@ -132,6 +157,7 @@ impl EthSenderDal<'_, '_> {
&mut self,
limit: u64,
operator_address: &Option,
+ is_gateway: bool,
) -> sqlx::Result> {
let txs = sqlx::query_as!(
StorageEthTx,
@@ -142,6 +168,7 @@ impl EthSenderDal<'_, '_> {
eth_txs
WHERE
from_addr IS NOT DISTINCT FROM $2 -- can't just use equality as NULL != NULL
+ AND is_gateway = $3
AND id > (
SELECT
COALESCE(MAX(eth_tx_id), 0)
@@ -151,6 +178,7 @@ impl EthSenderDal<'_, '_> {
WHERE
eth_txs_history.sent_at_block IS NOT NULL
AND eth_txs.from_addr IS NOT DISTINCT FROM $2
+ AND is_gateway = $3
)
ORDER BY
id
@@ -159,6 +187,7 @@ impl EthSenderDal<'_, '_> {
"#,
limit as i64,
operator_address.as_ref().map(|h160| h160.as_bytes()),
+ is_gateway
)
.fetch_all(self.storage.conn())
.await?;
@@ -202,6 +231,7 @@ impl EthSenderDal<'_, '_> {
predicted_gas_cost: u32,
from_address: Option,
blob_sidecar: Option,
+ is_gateway: bool,
) -> sqlx::Result {
let address = format!("{:#x}", contract_address);
let eth_tx = sqlx::query_as!(
@@ -217,10 +247,11 @@ impl EthSenderDal<'_, '_> {
created_at,
updated_at,
from_addr,
- blob_sidecar
+ blob_sidecar,
+ is_gateway
)
VALUES
- ($1, $2, $3, $4, $5, NOW(), NOW(), $6, $7)
+ ($1, $2, $3, $4, $5, NOW(), NOW(), $6, $7, $8)
RETURNING
*
"#,
@@ -232,6 +263,7 @@ impl EthSenderDal<'_, '_> {
from_address.as_ref().map(Address::as_bytes),
blob_sidecar.map(|sidecar| bincode::serialize(&sidecar)
.expect("can always bincode serialize EthTxBlobSidecar; qed")),
+ is_gateway,
)
.fetch_one(self.storage.conn())
.await?;
diff --git a/core/lib/dal/src/models/storage_eth_tx.rs b/core/lib/dal/src/models/storage_eth_tx.rs
index 2654ffe0e0a7..c721f938838e 100644
--- a/core/lib/dal/src/models/storage_eth_tx.rs
+++ b/core/lib/dal/src/models/storage_eth_tx.rs
@@ -29,6 +29,7 @@ pub struct StorageEthTx {
//
// Format a `bincode`-encoded `EthTxBlobSidecar` enum.
pub blob_sidecar: Option>,
+ pub is_gateway: bool,
}
#[derive(Debug, Default)]
@@ -83,6 +84,7 @@ impl From for EthTx {
blob_sidecar: tx.blob_sidecar.map(|b| {
bincode::deserialize(&b).expect("EthTxBlobSidecar is encoded correctly; qed")
}),
+ is_gateway: tx.is_gateway,
}
}
}
diff --git a/core/lib/eth_client/src/clients/mock.rs b/core/lib/eth_client/src/clients/mock.rs
index 46ad5dc5310e..b33554b6292c 100644
--- a/core/lib/eth_client/src/clients/mock.rs
+++ b/core/lib/eth_client/src/clients/mock.rs
@@ -107,7 +107,7 @@ impl MockSettlementLayerInner {
self.block_number += confirmations;
let nonce = self.current_nonce;
self.current_nonce += 1;
- tracing::info!("Executing tx with hash {tx_hash:?}, success: {success}, current nonce: {}, confirmations: {confirmations}", self.current_nonce);
+ tracing::info!("Executing tx with hash {tx_hash:?} at block {}, success: {success}, current nonce: {}, confirmations: {confirmations}", self.block_number - confirmations, self.current_nonce);
let tx_nonce = self.sent_txs[&tx_hash].nonce;
if non_ordering_confirmations {
diff --git a/core/lib/types/src/eth_sender.rs b/core/lib/types/src/eth_sender.rs
index bab57165b3dc..09ea915283eb 100644
--- a/core/lib/types/src/eth_sender.rs
+++ b/core/lib/types/src/eth_sender.rs
@@ -51,6 +51,7 @@ pub struct EthTx {
/// this transaction. If it is set to `None` this transaction was sent by the main operator.
pub from_addr: Option,
pub blob_sidecar: Option,
+ pub is_gateway: bool,
}
impl std::fmt::Debug for EthTx {
diff --git a/core/node/eth_sender/src/abstract_l1_interface.rs b/core/node/eth_sender/src/abstract_l1_interface.rs
index 1f1956c9dd84..312f483fd29e 100644
--- a/core/node/eth_sender/src/abstract_l1_interface.rs
+++ b/core/node/eth_sender/src/abstract_l1_interface.rs
@@ -9,7 +9,6 @@ use zksync_eth_client::{
#[cfg(test)]
use zksync_types::web3;
use zksync_types::{
- aggregated_operations::AggregatedActionType,
eth_sender::{EthTx, EthTxBlobSidecar},
web3::{BlockId, BlockNumber},
Address, L1BlockNumber, Nonce, EIP_1559_TX_TYPE, EIP_4844_TX_TYPE, H256, U256,
@@ -37,14 +36,25 @@ pub(crate) struct L1BlockNumbers {
pub(crate) enum OperatorType {
NonBlob,
Blob,
+ Gateway,
}
#[async_trait]
pub(super) trait AbstractL1Interface: 'static + Sync + Send + fmt::Debug {
- async fn failure_reason(&self, tx_hash: H256) -> Option;
+ fn supported_operator_types(&self) -> Vec;
+
+ async fn failure_reason(
+ &self,
+ tx_hash: H256,
+ operator_type: OperatorType,
+ ) -> Option;
#[cfg(test)]
- async fn get_tx(&self, tx_hash: H256) -> EnrichedClientResult