Skip to content

Commit b6501b6

Browse files
committed
fix: send logs, messages, multichain_batch_roots when settling on gateway
1 parent 28f5e24 commit b6501b6

File tree

13 files changed

+138
-35
lines changed

13 files changed

+138
-35
lines changed

lib/batch_verification/src/tests/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ pub fn dummy_batch_metadata(batch_number: u64, from: u64, to: u64) -> BatchMetad
8181
execution_version: 1,
8282
protocol_version: ProtocolSemanticVersion::legacy_genesis_version(),
8383
computational_native_used: None,
84+
logs: vec![],
85+
messages: vec![],
86+
multichain_batch_root: Default::default(),
8487
}
8588
}
8689

lib/contract_interface/src/lib.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -290,27 +290,36 @@ alloy::sol! {
290290
bytes calldata _commitData
291291
) external;
292292

293-
function proofPayload(StoredBatchInfo old, StoredBatchInfo[] newInfo, uint256[] proof);
293+
function proofPayload(StoredBatchInfo old, StoredBatchInfo[] newInfo, uint256[] proof);
294294

295-
function proveBatchesSharedBridge(
295+
function proveBatchesSharedBridge(
296296
address _chainAddress,
297297
uint256 _processBatchFrom,
298298
uint256 _processBatchTo,
299299
bytes calldata _proofData
300-
);
300+
);
301+
302+
struct PriorityOpsBatchInfo {
303+
bytes32[] leftPath;
304+
bytes32[] rightPath;
305+
bytes32[] itemHashes;
306+
}
301307

302-
struct PriorityOpsBatchInfo {
303-
bytes32[] leftPath;
304-
bytes32[] rightPath;
305-
bytes32[] itemHashes;
308+
struct L2Log {
309+
uint8 l2ShardId;
310+
bool isService;
311+
uint16 txNumberInBatch;
312+
address sender;
313+
bytes32 key;
314+
bytes32 value;
306315
}
307316

308-
function executeBatchesSharedBridge(
309-
address _chainAddress,
310-
uint256 _processFrom,
311-
uint256 _processTo,
312-
bytes calldata _executeData
313-
);
317+
function executeBatchesSharedBridge(
318+
address _chainAddress,
319+
uint256 _processFrom,
320+
uint256 _processTo,
321+
bytes calldata _executeData
322+
);
314323
}
315324

316325
// taken from v29 version of `IExecutor.sol`

lib/contract_interface/src/models.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{IExecutor, IExecutorV29, IExecutorV30};
2-
use alloy::primitives::{B256, Bytes, U256, keccak256};
2+
use alloy::primitives::{Address, B256, Bytes, U256, keccak256};
33
use alloy::sol_types::SolValue;
44
use serde::{Deserialize, Serialize};
55
use std::fmt;
@@ -24,6 +24,30 @@ impl From<PriorityOpsBatchInfo> for IExecutor::PriorityOpsBatchInfo {
2424
}
2525
}
2626

27+
/// User-friendly version of [`IExecutor::L2Log`].
28+
#[derive(Clone, Debug, Serialize, Deserialize)]
29+
pub struct L2Log {
30+
pub l2_shard_id: u8,
31+
pub is_service: bool,
32+
pub tx_number_in_batch: u16,
33+
pub sender: Address,
34+
pub key: B256,
35+
pub value: B256,
36+
}
37+
38+
impl From<L2Log> for IExecutor::L2Log {
39+
fn from(value: L2Log) -> Self {
40+
IExecutor::L2Log {
41+
l2ShardId: value.l2_shard_id,
42+
isService: value.is_service,
43+
txNumberInBatch: value.tx_number_in_batch,
44+
sender: value.sender,
45+
key: value.key,
46+
value: value.value,
47+
}
48+
}
49+
}
50+
2751
/// User-friendly version of [`crate::PubdataPricingMode`] with statically known possible variants.
2852
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
2953
pub enum BatchDaInputMode {

lib/l1_sender/src/batcher_model.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use crate::batcher_metrics::{BATCHER_METRICS, BatchExecutionStage};
2-
use alloy::primitives::Bytes;
2+
use alloy::primitives::{B256, Bytes};
33
use anyhow::Context as _;
44
use serde::{Deserialize, Serialize};
55
use std::fmt;
66
use std::fmt::{Debug, Formatter};
77
use std::time::SystemTime;
88
use time::UtcDateTime;
99
use zksync_os_batch_types::{BatchInfo, BatchSignatureSet};
10-
use zksync_os_contract_interface::models::StoredBatchInfo;
10+
use zksync_os_contract_interface::models::{L2Log, StoredBatchInfo};
1111
use zksync_os_observability::LatencyDistributionTracker;
1212
use zksync_os_types::PubdataMode;
1313
use zksync_os_types::{ProtocolSemanticVersion, ProvingVersion};
@@ -41,6 +41,12 @@ pub struct BatchMetadata {
4141
pub protocol_version: ProtocolSemanticVersion,
4242
#[serde(default)]
4343
pub computational_native_used: Option<u64>,
44+
#[serde(default)]
45+
pub logs: Vec<L2Log>,
46+
#[serde(default)]
47+
pub messages: Vec<Vec<u8>>,
48+
#[serde(default)]
49+
pub multichain_batch_root: B256,
4450
}
4551

4652
impl BatchMetadata {

lib/l1_sender/src/commands/commit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl SendToL1 for CommitCommand {
8080
const MINED_STAGE: BatchExecutionStage = BatchExecutionStage::CommitL1TxMined;
8181
const PASSTHROUGH_STAGE: BatchExecutionStage = BatchExecutionStage::CommitL1Passthrough;
8282

83-
fn solidity_call(&self) -> Bytes {
83+
fn solidity_call(&self, _gateway: bool) -> Bytes {
8484
if let Some(signatures_set) = &self.signatures {
8585
let mut signatures = signatures_set.to_vec().clone();
8686
signatures.sort_by(|a, b| a.signer().cmp(b.signer()));

lib/l1_sender/src/commands/execute.rs

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::batcher_metrics::BatchExecutionStage;
22
use crate::batcher_model::{FriProof, SignedBatchEnvelope};
33
use crate::commands::SendToL1;
4-
use alloy::primitives::{Bytes, FixedBytes, U256};
4+
use alloy::primitives::{Bytes, U256};
55
use alloy::sol_types::{SolCall, SolValue};
66
use std::fmt::Display;
77
use zksync_os_contract_interface::models::PriorityOpsBatchInfo;
@@ -33,12 +33,12 @@ impl SendToL1 for ExecuteCommand {
3333

3434
const PASSTHROUGH_STAGE: BatchExecutionStage = BatchExecutionStage::ExecuteL1Passthrough;
3535

36-
fn solidity_call(&self) -> Bytes {
36+
fn solidity_call(&self, gateway: bool) -> Bytes {
3737
IExecutor::executeBatchesSharedBridgeCall::new((
3838
self.batches.first().unwrap().batch.batch_info.chain_address,
3939
U256::from(self.batches.first().unwrap().batch_number()),
4040
U256::from(self.batches.last().unwrap().batch_number()),
41-
self.to_calldata_suffix().into(),
41+
self.to_calldata_suffix(gateway).into(),
4242
))
4343
.abi_encode()
4444
.into()
@@ -76,7 +76,7 @@ impl Display for ExecuteCommand {
7676
}
7777

7878
impl ExecuteCommand {
79-
fn to_calldata_suffix(&self) -> Vec<u8> {
79+
fn to_calldata_suffix(&self, gateway: bool) -> Vec<u8> {
8080
let stored_batch_infos = self
8181
.batches
8282
.iter()
@@ -102,19 +102,41 @@ impl ExecuteCommand {
102102
{
103103
29 | 30 => (stored_batch_infos, priority_ops, interop_roots).abi_encode_params(),
104104
31 | 32 => {
105-
// For now, these are not validated, so they can be empty.
106-
// IMPORTANT: the struct is not correct, it only works while the array is empty
107-
let logs: Vec<u8> = Default::default();
108-
let messages: Vec<Vec<u8>> = Default::default();
109-
let message_roots: Vec<FixedBytes<32>> = Default::default();
110-
105+
let mut logs = Vec::new();
106+
let mut messages = Vec::new();
107+
let mut multichain_batch_roots = Vec::new();
108+
if gateway {
109+
logs = self
110+
.batches
111+
.iter()
112+
.map(|batch| {
113+
batch
114+
.batch
115+
.logs
116+
.iter()
117+
.cloned()
118+
.map(IExecutor::L2Log::from)
119+
.collect::<Vec<_>>()
120+
})
121+
.collect::<Vec<_>>();
122+
messages = self
123+
.batches
124+
.iter()
125+
.map(|batch| batch.batch.messages.clone())
126+
.collect::<Vec<_>>();
127+
multichain_batch_roots = self
128+
.batches
129+
.iter()
130+
.map(|batch| batch.batch.multichain_batch_root)
131+
.collect::<Vec<_>>();
132+
}
111133
(
112134
stored_batch_infos,
113135
priority_ops,
114136
interop_roots,
115137
logs,
116138
messages,
117-
message_roots,
139+
multichain_batch_roots,
118140
)
119141
.abi_encode_params()
120142
}

lib/l1_sender/src/commands/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub trait SendToL1:
4444
const MINED_STAGE: BatchExecutionStage;
4545
const PASSTHROUGH_STAGE: BatchExecutionStage;
4646
/// We use `Bytes` instead of `SolCall`, because SolCall is a trait that cannot be dyn
47-
fn solidity_call(&self) -> Bytes;
47+
fn solidity_call(&self, gateway: bool) -> Bytes;
4848

4949
fn blob_sidecar(&self) -> Option<BlobTransactionSidecar> {
5050
None

lib/l1_sender/src/commands/prove.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl SendToL1 for ProofCommand {
3131
const MINED_STAGE: BatchExecutionStage = BatchExecutionStage::ProveL1TxMined;
3232
const PASSTHROUGH_STAGE: BatchExecutionStage = BatchExecutionStage::ProveL1Passthrough;
3333

34-
fn solidity_call(&self) -> Bytes {
34+
fn solidity_call(&self, _gateway: bool) -> Bytes {
3535
proveBatchesSharedBridgeCall::new((
3636
self.batches.first().unwrap().batch.batch_info.chain_address,
3737
U256::from(self.batches.first().unwrap().batch_number()),

lib/l1_sender/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub async fn run_l1_sender<Input: SendToL1>(
7272
impl Provider<Ethereum>,
7373
>,
7474
config: L1SenderConfig<Input>,
75+
gateway: bool,
7576
) -> anyhow::Result<()> {
7677
let latency_tracker =
7778
ComponentStateReporter::global().handle_for(Input::NAME, L1SenderState::WaitingRecv);
@@ -135,7 +136,7 @@ pub async fn run_l1_sender<Input: SendToL1>(
135136
)
136137
.await?
137138
.with_to(to_address)
138-
.with_input(cmd.solidity_call());
139+
.with_input(cmd.solidity_call(gateway));
139140

140141
if let Some(blob_sidecar) = cmd.blob_sidecar() {
141142
let fee_per_blob_gas = provider.get_blob_base_fee().await?;

lib/l1_sender/src/pipeline_component.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub struct L1Sender<F: TxFiller<Ethereum>, P: Provider<Ethereum>, C> {
1616
pub provider: FillProvider<F, P>,
1717
pub config: L1SenderConfig<C>,
1818
pub to_address: Address,
19+
pub gateway: bool,
1920
}
2021

2122
#[async_trait]
@@ -36,6 +37,14 @@ where
3637
input: PeekableReceiver<Self::Input>,
3738
output: mpsc::Sender<Self::Output>,
3839
) -> anyhow::Result<()> {
39-
run_l1_sender(input, output, self.to_address, self.provider, self.config).await
40+
run_l1_sender(
41+
input,
42+
output,
43+
self.to_address,
44+
self.provider,
45+
self.config,
46+
self.gateway,
47+
)
48+
.await
4049
}
4150
}

0 commit comments

Comments
 (0)