Skip to content

Commit 9438111

Browse files
authored
feat: genesis state update (#48)
* genesis state update * comment
1 parent 28ece19 commit 9438111

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

src/state/component.cairo

+29
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
mod errors {
77
const INVALID_BLOCK_NUMBER: felt252 = 'State: invalid block number';
88
const INVALID_PREVIOUS_ROOT: felt252 = 'State: invalid previous root';
9+
const INVALID_PREVIOUS_BLOCK_NUMBER: felt252 = 'State: invalid prev block num';
910
}
1011

1112
/// State component.
@@ -37,6 +38,8 @@ mod state_cpt {
3738
TContractState, +HasComponent<TContractState>,
3839
> of IState<ComponentState<TContractState>> {
3940
fn update(ref self: ComponentState<TContractState>, program_output: StarknetOsOutput) {
41+
self.check_prev_block_number(@program_output);
42+
4043
// Check the blockNumber first as the error is less ambiguous then
4144
// INVALID_PREVIOUS_ROOT.
4245
self.block_number.write(self.block_number.read() + 1);
@@ -79,5 +82,31 @@ mod state_cpt {
7982
self.block_number.write(block_number);
8083
self.block_hash.write(block_hash);
8184
}
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+
}
82111
}
83112
}

src/state/tests/test_state.cairo

+28
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,34 @@ fn state_update_ok() {
4545
assert(block_hash == 2, 'invalid block hash');
4646
}
4747

48+
#[test]
49+
fn genesis_state_update_ok() {
50+
let mock = deploy_mock_with_state(state_root: 0, block_number: 0, block_hash: 0,);
51+
let os_output = StarknetOsOutput {
52+
initial_root: 0,
53+
final_root: 1,
54+
prev_block_number: 0x800000000000011000000000000000000000000000000000000000000000000,
55+
new_block_number: 1,
56+
prev_block_hash: 0,
57+
new_block_hash: 1,
58+
os_program_hash: 1,
59+
starknet_os_config_hash: 1,
60+
use_kzg_da: 0,
61+
full_output: 0,
62+
messages_to_l1: array![].span(),
63+
messages_to_l2: array![].span(),
64+
contracts: array![],
65+
classes: array![],
66+
};
67+
mock.update(os_output);
68+
69+
let (state_root, block_number, block_hash) = mock.get_state();
70+
71+
assert(state_root == 1, 'invalid state root');
72+
assert(block_number == 1, 'invalid block number');
73+
assert(block_hash == 1, 'invalid block hash');
74+
}
75+
4876
#[test]
4977
#[should_panic(expected: ('State: invalid block number',))]
5078
fn state_update_invalid_block_number() {

tests/test_appchain.cairo

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ fn deploy_with_owner_and_state(
3232
owner: felt252, state_root: felt252, block_number: felt252, block_hash: felt252,
3333
) -> (IAppchainDispatcher, EventSpy) {
3434
let contract = snf::declare("appchain").unwrap();
35+
let block_number: felt252 = block_number.into();
3536
let calldata = array![owner, state_root, block_number, block_hash];
3637
let (contract_address, _) = contract.deploy(@calldata).unwrap();
3738

0 commit comments

Comments
 (0)