|
6 | 6 | mod errors {
|
7 | 7 | const INVALID_BLOCK_NUMBER: felt252 = 'State: invalid block number';
|
8 | 8 | const INVALID_PREVIOUS_ROOT: felt252 = 'State: invalid previous root';
|
| 9 | + const INVALID_PREVIOUS_BLOCK_NUMBER: felt252 = 'State: invalid prev block num'; |
9 | 10 | }
|
10 | 11 |
|
11 | 12 | /// State component.
|
@@ -37,6 +38,8 @@ mod state_cpt {
|
37 | 38 | TContractState, +HasComponent<TContractState>,
|
38 | 39 | > of IState<ComponentState<TContractState>> {
|
39 | 40 | fn update(ref self: ComponentState<TContractState>, program_output: StarknetOsOutput) {
|
| 41 | + self.check_prev_block_number(@program_output); |
| 42 | + |
40 | 43 | // Check the blockNumber first as the error is less ambiguous then
|
41 | 44 | // INVALID_PREVIOUS_ROOT.
|
42 | 45 | self.block_number.write(self.block_number.read() + 1);
|
@@ -79,5 +82,31 @@ mod state_cpt {
|
79 | 82 | self.block_number.write(block_number);
|
80 | 83 | self.block_hash.write(block_hash);
|
81 | 84 | }
|
| 85 | + |
| 86 | + /// Validates that the previous block number that appears in the proof is the |
| 87 | + /// current block number in the state. |
| 88 | + fn check_prev_block_number( |
| 89 | + self: @ComponentState<TContractState>, program_output: @StarknetOsOutput |
| 90 | + ) { |
| 91 | + let mut expected_prev_block_number: felt252 = self.block_number.read(); |
| 92 | + let prev_state_root: felt252 = self.state_root.read(); |
| 93 | + let prev_block_hash: felt252 = self.block_hash.read(); |
| 94 | + |
| 95 | + // If block number and state root is 0, then we assume it hasn't been initialized yet |
| 96 | + // and the current program output belongs to the genesis block. |
| 97 | + if expected_prev_block_number == 0 && prev_state_root == 0 && prev_block_hash == 0 { |
| 98 | + // This is the maximum value for a felt252. |
| 99 | + // |
| 100 | + // See |
| 101 | + // https://github.com/starkware-libs/cairo-lang/blob/a86e92bfde9c171c0856d7b46580c66e004922f3/src/starkware/starknet/solidity/StarknetState.sol#L19-L39 |
| 102 | + expected_prev_block_number = |
| 103 | + 0x800000000000011000000000000000000000000000000000000000000000000; |
| 104 | + } |
| 105 | + |
| 106 | + assert( |
| 107 | + expected_prev_block_number == *program_output.prev_block_number, |
| 108 | + errors::INVALID_PREVIOUS_BLOCK_NUMBER |
| 109 | + ); |
| 110 | + } |
82 | 111 | }
|
83 | 112 | }
|
0 commit comments