@@ -6,7 +6,7 @@ pub mod CometClientComponent {
66 use cometbft :: verifier :: {verify_misbehaviour_header, verify_update_header};
77 use core :: num :: traits :: Zero ;
88 use ics23 :: {
9- MerkleProof , Proof , array_u8_to_byte_array, byte_array_to_array_u8 ,
9+ ArrayFelt252Store , MerkleProof , Proof , array_u8_to_byte_array, byte_array_to_array_u8 ,
1010 verify_membership as ics23_verify_membership,
1111 verify_non_membership as ics23_verify_non_membership,
1212 };
@@ -20,9 +20,8 @@ pub mod CometClientComponent {
2020 use starknet :: {ContractAddress , get_block_number, get_block_timestamp, get_caller_address};
2121 use starknet_ibc_clients :: cometbft :: {
2222 ClientMessage , CometClientState , CometClientStateImpl , CometConsensusState ,
23- CometConsensusStateImpl , CometConsensusStateStore , CometConsensusStateToStore ,
24- CometConsensusStateZero , CometErrors , CometHeader , CometHeaderImpl ,
25- CometHeaderIntoConsensusState , Misbehaviour , MisbehaviourImpl , StoreToCometConsensusState ,
23+ CometConsensusStateImpl , CometConsensusStateZero , CometErrors , CometHeader , CometHeaderImpl ,
24+ CometHeaderIntoConsensusState , Misbehaviour , MisbehaviourImpl ,
2625 };
2726 use starknet_ibc_core :: client :: {
2827 CreateResponse , CreateResponseImpl , Height , HeightImpl , HeightPartialOrd , HeightZero ,
@@ -32,15 +31,17 @@ pub mod CometClientComponent {
3231 UpdateResponse ,
3332 };
3433 use starknet_ibc_core :: commitment :: {StateProof , StateRoot , StateValue };
35- use starknet_ibc_core :: host :: ClientIdImpl ;
34+ use starknet_ibc_core :: host :: {
35+ BasePrefix , ClientIdImpl , client_upgrade_path, consensus_upgrade_path,
36+ };
3637 use starknet_ibc_utils :: ValidateBasic ;
3738
3839 #[storage]
3940 pub struct Storage {
4041 next_client_sequence : u64 ,
4142 update_heights : Map <u64 , Array <Height >>,
4243 client_states : Map <u64 , CometClientState >,
43- consensus_states : Map <(u64 , Height ), CometConsensusStateStore >,
44+ consensus_states : Map <(u64 , Height ), CometConsensusState >,
4445 client_processed_times : Map <(u64 , Height ), u64 >,
4546 client_processed_heights : Map <(u64 , Height ), u64 >,
4647 }
@@ -83,7 +84,8 @@ pub mod CometClientComponent {
8384 }
8485
8586 fn upgrade_client (ref self : ComponentState <TContractState >, msg : MsgUpgradeClient ) {
86- self . assert_owner ();
87+ self . upgrade_validate (msg . clone ());
88+ self . upgrade_execute (msg );
8789 }
8890 }
8991
@@ -190,8 +192,7 @@ pub mod CometClientComponent {
190192 let mut serialized : Array <felt252 > = ArrayTrait :: new ();
191193
192194 let consensus_state : CometConsensusState = self
193- . read_consensus_state (client_sequence , height )
194- . into ();
195+ . read_consensus_state (client_sequence , height );
195196
196197 consensus_state . serialize (ref serialized );
197198
@@ -363,9 +364,23 @@ pub mod CometClientComponent {
363364 > of UpgradeClientTrait <TContractState > {
364365 fn upgrade_validate (self : @ ComponentState <TContractState >, msg : MsgUpgradeClient ) {
365366 msg . validate_basic ();
367+
368+ self
369+ . verify_upgrade (
370+ msg . client_id. sequence,
371+ msg . upgraded_client_state,
372+ msg . upgraded_consensus_state,
373+ msg . proof_upgrade_client,
374+ msg . proof_upgrade_consensus,
375+ );
366376 }
367377
368- fn upgrade_execute (ref self : ComponentState <TContractState >, msg : MsgUpgradeClient ) {}
378+ fn upgrade_execute (ref self : ComponentState <TContractState >, msg : MsgUpgradeClient ) {
379+ self
380+ . update_on_upgrade (
381+ msg . client_id. sequence, msg . upgraded_client_state, msg . upgraded_consensus_state,
382+ );
383+ }
369384 }
370385
371386 // -----------------------------------------------------------
@@ -468,12 +483,82 @@ pub mod CometClientComponent {
468483
469484 fn verify_upgrade (
470485 self : @ ComponentState <TContractState >,
486+ client_sequence : u64 ,
471487 upgrade_client_state : Array <felt252 >,
472488 upgrade_consensus_state : Array <felt252 >,
473- proof_upgrade_client : Array <felt252 >,
474- proof_upgrade_consensus : Array <felt252 >,
475- root : ByteArray ,
476- ) {}
489+ proof_upgrade_client : StateProof ,
490+ proof_upgrade_consensus : StateProof ,
491+ ) {
492+ let comet_client_state : CometClientState = self . read_client_state (client_sequence );
493+ let latest_height = comet_client_state . latest_height. clone ();
494+
495+ let latest_consensus_state = self
496+ . read_consensus_state (client_sequence , comet_client_state . latest_height. clone ());
497+
498+ let root = latest_consensus_state . root. clone ();
499+
500+ let upgrade_path = comet_client_state . upgrade_path. clone ();
501+
502+ let status = self . _status (comet_client_state , latest_consensus_state , client_sequence );
503+
504+ assert (status . is_active (), CometErrors :: INACTIVE_CLIENT );
505+
506+ assert (
507+ upgrade_path . len () == 1 || upgrade_path . len () == 2 ,
508+ CometErrors :: INVALID_UPGRADE_PATH_LENGTH ,
509+ );
510+
511+ let (prefix , upgrade_path ) = if upgrade_path . len () == 1 {
512+ ("" , upgrade_path [0 ]. clone ())
513+ } else {
514+ (upgrade_path [0 ]. clone (), upgrade_path [1 ]. clone ())
515+ };
516+
517+ let base_prefix = BasePrefix { prefix };
518+
519+ let upgraded_client_path = client_upgrade_path (
520+ base_prefix . clone (), latest_height . revision_height, upgrade_path . clone (),
521+ );
522+
523+ let upgraded_consensus_path = consensus_upgrade_path (
524+ base_prefix , latest_height . revision_height, upgrade_path ,
525+ );
526+
527+ let upgraded_client_state = CometClientStateImpl :: deserialize (upgrade_client_state );
528+
529+ let upgraded_consensus_state = CometConsensusStateImpl :: deserialize (
530+ upgrade_consensus_state ,
531+ );
532+
533+ let upgraded_height = upgraded_client_state . latest_height. clone ();
534+
535+ assert (upgraded_height > latest_height , CometErrors :: INVALID_UPGRADE_HEIGHT );
536+
537+ let upgraded_client_protobuf = StateValue {
538+ value : ics23 :: byte_array_to_array_u8 (@ upgraded_client_state . protobuf_bytes ()),
539+ };
540+ let upgraded_consensus_protobuf = StateValue {
541+ value : ics23 :: byte_array_to_array_u8 (@ upgraded_consensus_state . protobuf_bytes ()),
542+ };
543+
544+ self
545+ . verify_membership (
546+ client_sequence ,
547+ upgraded_client_path ,
548+ upgraded_client_protobuf ,
549+ proof_upgrade_client ,
550+ root . clone (),
551+ );
552+
553+ self
554+ . verify_membership (
555+ client_sequence ,
556+ upgraded_consensus_path ,
557+ upgraded_consensus_protobuf ,
558+ proof_upgrade_consensus ,
559+ root ,
560+ );
561+ }
477562 }
478563
479564 #[embeddable_as(CometClientExecution )]
@@ -652,7 +737,32 @@ pub mod CometClientComponent {
652737 client_sequence : u64 ,
653738 new_client_state : Array <felt252 >,
654739 new_consensus_state : Array <felt252 >,
655- ) {}
740+ ) {
741+ let update_heights = self . read_update_heights (client_sequence );
742+
743+ if update_heights . len () > 0 {
744+ let mut update_heights_span = update_heights . span ();
745+
746+ while let Option :: Some (height ) = update_heights_span . pop_front () {
747+ self . remove_consensus_state (client_sequence , height . clone ());
748+ }
749+
750+ self . update_heights. write (client_sequence , array! []);
751+ }
752+
753+ let new_client_state = CometClientStateImpl :: deserialize (new_client_state );
754+ let new_consensus_state = CometConsensusStateImpl :: deserialize (new_consensus_state );
755+
756+ self
757+ . _update_state (
758+ client_sequence ,
759+ new_client_state . latest_height,
760+ new_client_state ,
761+ new_consensus_state ,
762+ get_block_number (),
763+ get_block_timestamp (),
764+ );
765+ }
656766 }
657767
658768 // -----------------------------------------------------------
@@ -880,8 +990,7 @@ pub mod CometClientComponent {
880990 ) -> CometConsensusState {
881991 let consensus_state : CometConsensusState = self
882992 . consensus_states
883- . read ((client_sequence , height ))
884- . into ();
993+ . read ((client_sequence , height ));
885994
886995 assert (consensus_state . is_non_zero (), CometErrors :: MISSING_CONSENSUS_STATE );
887996
@@ -893,8 +1002,7 @@ pub mod CometClientComponent {
8931002 ) -> bool {
8941003 let consensus_state : CometConsensusState = self
8951004 . consensus_states
896- . read ((client_sequence , height ))
897- . into ();
1005+ . read ((client_sequence , height ));
8981006
8991007 consensus_state . is_non_zero ()
9001008 }
@@ -1000,7 +1108,7 @@ pub mod CometClientComponent {
10001108 processed_height : u64 ,
10011109 processed_time : u64 ,
10021110 ) {
1003- self . consensus_states. write ((client_sequence , height . clone ()), consensus_state . into () );
1111+ self . consensus_states. write ((client_sequence , height . clone ()), consensus_state );
10041112 self
10051113 . client_processed_heights
10061114 . write ((client_sequence , height . clone ()), processed_height );
@@ -1011,7 +1119,7 @@ pub mod CometClientComponent {
10111119 ref self : ComponentState <TContractState >, client_sequence : u64 , height : Height ,
10121120 ) {
10131121 let consensus_zero = CometConsensusStateZero :: zero ();
1014- self . consensus_states. write ((client_sequence , height ), consensus_zero . into () );
1122+ self . consensus_states. write ((client_sequence , height ), consensus_zero );
10151123 self . client_processed_times. write ((client_sequence , height ), 0 );
10161124 self . client_processed_heights. write ((client_sequence , height ), 0 );
10171125 }
0 commit comments