@@ -33,6 +33,10 @@ pub struct BlockRollupPublicInputsComposer {
3333 start_msg_sponge : L1ToL2MessageSponge ,
3434 end_msg_sponge : L1ToL2MessageSponge ,
3535 new_l1_to_l2 : AppendOnlyTreeSnapshot ,
36+ // Set by `with_message_bundle` and asserted by `finish`. Without it, a variant that forgot to apply its bundle
37+ // would emit `previous_l1_to_l2 == new_l1_to_l2 == constants.l1_to_l2_tree_snapshot`: a silent no-op append that
38+ // still satisfies the snapshot check against the constants.
39+ bundle_applied : bool ,
3640}
3741
3842impl BlockRollupPublicInputsComposer {
@@ -65,6 +69,7 @@ impl BlockRollupPublicInputsComposer {
6569 start_msg_sponge : L1ToL2MessageSponge ::new (),
6670 end_msg_sponge : L1ToL2MessageSponge ::new (),
6771 new_l1_to_l2 : previous_state .l1_to_l2_message_tree ,
72+ bundle_applied : false ,
6873 }
6974 }
7075
@@ -103,6 +108,7 @@ impl BlockRollupPublicInputsComposer {
103108 start_msg_sponge : L1ToL2MessageSponge ::new (),
104109 end_msg_sponge : L1ToL2MessageSponge ::new (),
105110 new_l1_to_l2 : rollup .constants .l1_to_l2_tree_snapshot ,
111+ bundle_applied : false ,
106112 }
107113 }
108114
@@ -129,6 +135,7 @@ impl BlockRollupPublicInputsComposer {
129135 ) -> Self {
130136 self .is_first_block = is_first_block ;
131137 self .previous_l1_to_l2 = previous_l1_to_l2 ;
138+ self .bundle_applied = true ;
132139
133140 // Append the bundle to the l1-to-l2 message tree at its current (arbitrary) next-available index.
134141 self .new_l1_to_l2 = append_only_tree:: append_leaves_to_snapshot ::<L1_TO_L2_MSG_TREE_HEIGHT , MAX_L1_TO_L2_MSGS_PER_BLOCK >(
@@ -157,6 +164,13 @@ impl BlockRollupPublicInputsComposer {
157164 self ,
158165 new_archive_sibling_path : [Field ; ARCHIVE_HEIGHT ],
159166 ) -> BlockRollupPublicInputs {
167+ // Every block transitions the l1-to-l2 message tree, even when its bundle is empty, so the append is not
168+ // optional: skipping it would leave the start and end snapshots trivially equal.
169+ assert (
170+ self .bundle_applied ,
171+ "with_message_bundle must be called before finishing the block rollup" ,
172+ );
173+
160174 // Build the header of this block and then insert its hash to the archive tree.
161175 let (block_header , end_sponge_blob ) = self .create_block_header_and_end_sponge_blob ();
162176 let block_header_hash = block_header .hash ();
0 commit comments