/
l2_to_l1_messages.cairo
121 lines (98 loc) · 3.61 KB
/
l2_to_l1_messages.cairo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use traits::{Into, TryInto, PartialEq};
use array::{ArrayTrait, SpanTrait, SpanPartialEq};
use option::OptionTrait;
use result::ResultTrait;
use starknet::{testing, SyscallResultTrait};
use starknet::syscalls::{deploy_syscall, get_block_hash_syscall};
use starknet::class_hash::Felt252TryIntoClassHash;
use test::test_utils::{assert_eq, assert_ne};
use contract_with_messages_sent_to_l1::IContractWithMessagesSentToL1;
#[starknet::contract]
mod contract_with_messages_sent_to_l1 {
use traits::Into;
use array::ArrayTrait;
use super::generate_payload;
#[storage]
struct Storage {
value: u128,
}
#[constructor]
fn constructor(ref self: ContractState) {
self.value.write(0);
}
#[external(v0)]
#[generate_trait]
impl IContractWithMessagesSentToL1Impl of IContractWithMessagesSentToL1 {
fn send_message_to_l1(ref self: ContractState) {
let value_ = self.value.read();
starknet::send_message_to_l1_syscall(
to_address: value_.into(), payload: generate_payload(n: value_).span()
);
self.value.write(value_ + 1);
}
}
}
// Generates the array [0, 1, 2, ..., n]
fn generate_payload(n: u128) -> Array<felt252> {
let mut payload = array![];
let mut i: u128 = 0;
loop {
if (i > n) {
break;
}
payload.append(i.into());
i += 1;
};
payload
}
#[test]
#[available_gas(30000000)]
fn test_l2_to_l1_messages() {
// Set up.
let mut contract = contract_with_messages_sent_to_l1::unsafe_new_contract_state();
let contract_address = starknet::contract_address_const::<0x42>();
let other_contract_address = starknet::contract_address_const::<0xdead>();
testing::set_contract_address(contract_address);
// Send messages.
contract.send_message_to_l1();
contract.send_message_to_l1();
contract.send_message_to_l1();
// Assert other addresses did not sent messages.
assert(testing::pop_l2_to_l1_message(other_contract_address).is_none(), 'no messages');
// Pop messages.
assert_eq(
@testing::pop_l2_to_l1_message(contract_address).unwrap(),
@(0, array![0].span()),
'message == (0, [0])'
);
assert_eq(
@testing::pop_l2_to_l1_message(contract_address).unwrap(),
@(1, array![0, 1].span()),
'message == (1, [0, 1])'
);
assert_eq(
@testing::pop_l2_to_l1_message(contract_address).unwrap(),
@(2, array![0, 1, 2].span()),
'message == (2, [0, 1, 2])'
);
// Assert all messages have been popped.
assert(testing::pop_l2_to_l1_message(contract_address).is_none(), 'no more messages');
}
#[test]
#[available_gas(300000)]
fn test_pop_l2_to_l1_message() {
let contract_address = starknet::contract_address_const::<0x42>();
testing::set_contract_address(contract_address);
let mut to_address = 1234;
let mut payload = array![2345];
starknet::send_message_to_l1_syscall(to_address, payload.span());
starknet::send_message_to_l1_syscall(to_address, payload.span());
let (to_address, payload) = starknet::testing::pop_l2_to_l1_message(contract_address).unwrap();
assert_eq(@payload.len(), @1, 'unexpected payload size');
assert_eq(@to_address, @1234, 'unexpected to_address');
assert_eq(payload.at(0), @2345, 'unexpected payload');
let (to_address, payload) = starknet::testing::pop_l2_to_l1_message(contract_address).unwrap();
assert_eq(@payload.len(), @1, 'unexpected payload size');
assert_eq(@to_address, @1234, 'unexpected to_address');
assert_eq(payload.at(0), @2345, 'unexpected payload');
}