@@ -29,6 +29,8 @@ use papyrus_base_layer::test_utils::{
2929use papyrus_base_layer:: BaseLayerContract ;
3030use utils:: { L1_CONTRACT_ADDRESS , L2_ENTRY_POINT } ;
3131
32+ use crate :: utils:: setup_anvil_base_layer;
33+
3234// This test requires that we do some manual work to produce the logs we expect to get from the
3335// Starknet L1 contract. The reason we don't just post events to L1 and have them scraped is that
3436// some of the log types don't correspond to actions we can just do to the base layer, like marking
@@ -132,6 +134,33 @@ async fn all_event_types_must_be_filtered_and_parsed() {
132134 }
133135}
134136
137+ #[ tokio:: test]
138+ async fn cannot_parse_log_message_to_l1 ( ) {
139+ // Setup.
140+ // Make a mock L1
141+ let asserter = Asserter :: new ( ) ;
142+ let provider = ProviderBuilder :: new ( ) . connect_mocked_client ( asserter. clone ( ) ) ;
143+
144+ let mut base_layer = EthereumBaseLayerContract :: new_with_provider (
145+ EthereumBaseLayerConfig :: default ( ) ,
146+ provider. root ( ) . clone ( ) ,
147+ ) ;
148+
149+ // We can just return the same block all the time, it will only affect the timestamps.
150+ let dummy_block: Block < B256 , Header > = dummy_block ( ) ;
151+
152+ // This log is for LogMessageToL1 event.
153+ let expected_message_to_l1_log =
154+ encode_log_message_to_l1_log ( & [ U256 :: from ( 15 ) , U256 :: from ( 202 ) ] ) ;
155+ asserter. push_success ( & vec ! [ expected_message_to_l1_log. clone( ) ] ) ;
156+ // asserter.push_success(&Vec::<Log>::new());
157+ asserter. push_success ( & dummy_block) ;
158+
159+ let result = base_layer. events ( 0 ..=1 , event_identifiers_to_track ( ) ) . await ;
160+
161+ assert ! ( result. is_err( ) , "expected error" ) ;
162+ }
163+
135164fn dummy_block < T > ( ) -> Block < T , Header > {
136165 Block {
137166 header : Header {
@@ -246,3 +275,48 @@ fn encode_message_into_log(
246275 removed : false ,
247276 }
248277}
278+
279+ // Generate a LogMessageToL1 log (which we do not filter on).
280+ fn encode_log_message_to_l1_log ( payload : & [ U256 ] ) -> Log {
281+ let selector = "LogMessageToL1(address,uint256[],uint256,uint256)" ;
282+ let block_number = 1 ;
283+ let starknet_address = DEFAULT_ANVIL_L1_ACCOUNT_ADDRESS . to_bigint ( ) . to_str_radix ( 16 ) ;
284+ let starknet_address = format ! ( "{:0>64}" , starknet_address) ;
285+
286+ let offset = U256 :: from ( 32u64 ) ;
287+
288+ let mut encoded = Vec :: new ( ) ;
289+ // Offset to the array data (96 bytes).
290+ encoded. extend_from_slice ( & offset. to_be_bytes :: < 32 > ( ) ) ;
291+
292+ // Tail section has the payload array data only. It starts with the length of the array.
293+ let array_len = U256 :: from ( payload. len ( ) ) ;
294+ encoded. extend_from_slice ( & array_len. to_be_bytes :: < 32 > ( ) ) ;
295+ // Finally, write the array elements.
296+ for item in payload {
297+ encoded. extend_from_slice ( & item. to_be_bytes :: < 32 > ( ) ) ;
298+ }
299+
300+ let log_data = Bytes :: from ( encoded) ;
301+
302+ Log {
303+ inner : LogInner {
304+ address : DEFAULT_ANVIL_L1_DEPLOYED_ADDRESS . parse ( ) . unwrap ( ) ,
305+ data : LogData :: new_unchecked (
306+ vec ! [
307+ filter_to_hash( selector) . parse( ) . unwrap( ) ,
308+ starknet_address. parse( ) . unwrap( ) ,
309+ U256 :: from( L1_CONTRACT_ADDRESS ) . into( ) ,
310+ ] ,
311+ log_data,
312+ ) ,
313+ } ,
314+ block_hash : Some ( BlockHash :: from_str ( FAKE_HASH ) . unwrap ( ) ) ,
315+ block_number : Some ( block_number) ,
316+ block_timestamp : None ,
317+ transaction_hash : Some ( TxHash :: from_str ( FAKE_HASH ) . unwrap ( ) ) ,
318+ transaction_index : Some ( block_number + 1 ) ,
319+ log_index : Some ( block_number + 2 ) ,
320+ removed : false ,
321+ }
322+ }
0 commit comments