@@ -78,56 +78,7 @@ contract TokiLCPClientTest is BasicTest {
7878 return ;
7979 }
8080 string memory clientId = "lcp-zkdcap " ;
81- Options memory opts;
82- opts.constructorData = abi.encode (
83- address (this ), false , ZKDCAPTestHelper.dummyIntelRootCACert (), address (new NopRiscZeroVerifier ())
84- );
85- address proxy = Upgrades.deployUUPSProxy (
86- "LCPClientZKDCAPOwnableUpgradeable.sol " ,
87- abi.encodePacked (LCPClientZKDCAPOwnableUpgradeable.initialize.selector ),
88- opts
89- );
90- LCPClientZKDCAPOwnableUpgradeable lc = LCPClientZKDCAPOwnableUpgradeable (proxy);
91- IbcLightclientsLcpV1ClientState.Data memory clientState = defaultClientState ();
92- clientState.allowed_quote_statuses = new string [](2 );
93- clientState.allowed_quote_statuses[0 ] = DCAPValidator.TCB_STATUS_CONFIGURATION_NEEDED_STRING;
94- clientState.allowed_quote_statuses[1 ] = DCAPValidator.TCB_STATUS_OUT_OF_DATE_STRING;
95- clientState.allowed_advisory_ids = new string [](2 );
96- clientState.allowed_advisory_ids[0 ] = "INTEL-SA-0001 " ;
97- clientState.allowed_advisory_ids[1 ] = "INTEL-SA-0003 " ;
98- lc.initializeClient (
99- clientId, LCPProtoMarshaler.marshal (clientState), LCPProtoMarshaler.marshal (defaultConsensusState ())
100- );
101- DCAPValidator.Output memory output = ZKDCAPTestHelper.qvOutput ();
102- output.advisoryIDs = clientState.allowed_advisory_ids;
103- Vm.Wallet memory ek0 = vm.createWallet ("ek0 " );
104- output.enclaveKey = ek0.addr;
105- // warp to the time of `output.validityNotBefore`
106- vm.warp (output.validityNotBefore);
107- lc.zkDCAPRegisterEnclaveKey (clientId, registerEnclaveKeyMessage (output));
108- {
109- LCPCommitment.UpdateStateProxyMessage memory updateStateMessage;
110- updateStateMessage.prevHeight = Height.Data (0 , 0 );
111- updateStateMessage.prevStateId = bytes32 (0 );
112- updateStateMessage.postHeight = Height.Data (0 , 1 );
113- updateStateMessage.postStateId = keccak256 ("state-1 " );
114- updateStateMessage.timestamp = 1 ;
115- LCPCommitment.ValidationContext memory vc;
116- updateStateMessage.context = abi.encode (vc);
117- updateStateMessage.emittedStates = new LCPCommitment.EmittedState [](1 );
118-
119- LCPCommitment.HeaderedProxyMessage memory headeredMessage;
120- headeredMessage.header = LCPCommitment.LCP_MESSAGE_HEADER_UPDATE_STATE;
121- headeredMessage.message = abi.encode (updateStateMessage);
122-
123- IbcLightclientsLcpV1UpdateClientMessage.Data memory message;
124- message.proxy_message = abi.encode (headeredMessage);
125-
126- (uint8 v , bytes32 r , bytes32 s ) = vm.sign (ek0, keccak256 (message.proxy_message));
127- message.signatures = new bytes [](1 );
128- message.signatures[0 ] = abi.encodePacked (r, s, v);
129- lc.updateClient (clientId, message);
130- }
81+ LCPClientZKDCAPOwnableUpgradeable lc = contractUpgradeCommon (clientId);
13182
13283 TokiLCPClientZKDCAP.NewClientState memory newClientState;
13384 newClientState.clientId = clientId;
@@ -143,8 +94,12 @@ contract TokiLCPClientTest is BasicTest {
14394 bytes31 (0 ), // reserved
14495 bytes32 (keccak256 ("new verifier " ))
14596 );
146- assertNotEq (newClientState.zkdcapVerifierInfos[0 ], clientState.zkdcap_verifier_infos[0 ]);
147- assertNotEq (newClientState.allowedQuoteStatuses.length , clientState.allowed_quote_statuses.length );
97+ {
98+ (bytes memory bz ,) = lc.getClientState (clientId);
99+ IbcLightclientsLcpV1ClientState.Data memory clientState = LCPProtoMarshaler.unmarshalClientState (bz);
100+ assertNotEq (newClientState.zkdcapVerifierInfos[0 ], clientState.zkdcap_verifier_infos[0 ]);
101+ assertNotEq (newClientState.allowedQuoteStatuses.length , clientState.allowed_quote_statuses.length );
102+ }
148103
149104 TokiLCPClientZKDCAP.NewConsensusState memory newConsensusState;
150105 newConsensusState.height = Height.Data (0 , 2 );
@@ -157,7 +112,7 @@ contract TokiLCPClientTest is BasicTest {
157112 address (this ), false , ZKDCAPTestHelper.dummyIntelRootCACert (), address (new NopRiscZeroVerifier ()), 2
158113 );
159114 Upgrades.upgradeProxy (
160- proxy ,
115+ address (lc) ,
161116 "TokiLCPClientZKDCAP.sol " ,
162117 abi.encodeCall (TokiLCPClientZKDCAP.upgrade, (newClientState, newConsensusState)),
163118 opts2
@@ -184,6 +139,121 @@ contract TokiLCPClientTest is BasicTest {
184139 }
185140 }
186141
142+ function testContractUpgradeWithEmptyConsensusState () public {
143+ if (! vm.envOr ("TEST_UPGRADEABLE " , false )) {
144+ return ;
145+ }
146+ string memory clientId = "lcp-zkdcap " ;
147+ LCPClientZKDCAPOwnableUpgradeable lc = contractUpgradeCommon (clientId);
148+
149+ TokiLCPClientZKDCAP.NewClientState memory newClientState;
150+ newClientState.clientId = clientId;
151+ newClientState.mrenclave = abi.encodePacked (keccak256 ("new mrenclave " ));
152+ newClientState.keyExpiration = 60 * 60 ;
153+ newClientState.allowedQuoteStatuses = new string [](1 );
154+ newClientState.allowedQuoteStatuses[0 ] = DCAPValidator.TCB_STATUS_SW_HARDENING_NEEDED_STRING;
155+ newClientState.allowedAdvisoryIds = new string [](1 );
156+ newClientState.allowedAdvisoryIds[0 ] = "INTEL-SA-0002 " ;
157+ newClientState.zkdcapVerifierInfos = new bytes [](1 );
158+ newClientState.zkdcapVerifierInfos[0 ] = abi.encodePacked (
159+ bytes1 (uint8 (1 )), // zkvmType
160+ bytes31 (0 ), // reserved
161+ bytes32 (keccak256 ("new verifier " ))
162+ );
163+
164+ {
165+ (bytes memory bz ,) = lc.getClientState (clientId);
166+ IbcLightclientsLcpV1ClientState.Data memory clientState = LCPProtoMarshaler.unmarshalClientState (bz);
167+ assertNotEq (newClientState.zkdcapVerifierInfos[0 ], clientState.zkdcap_verifier_infos[0 ]);
168+ assertNotEq (newClientState.allowedQuoteStatuses.length , clientState.allowed_quote_statuses.length );
169+ }
170+
171+ TokiLCPClientZKDCAP.NewConsensusState memory newConsensusState;
172+ // NOTE: The new consensus state is empty
173+ newConsensusState.height = Height.Data (0 , 0 );
174+
175+ Options memory opts2;
176+ opts2.referenceContract = "LCPClientZKDCAPOwnableUpgradeable.sol " ;
177+ opts2.constructorData = abi.encode (
178+ address (this ), false , ZKDCAPTestHelper.dummyIntelRootCACert (), address (new NopRiscZeroVerifier ()), 2
179+ );
180+ Upgrades.upgradeProxy (
181+ address (lc),
182+ "TokiLCPClientZKDCAP.sol " ,
183+ abi.encodeCall (TokiLCPClientZKDCAP.upgrade, (newClientState, newConsensusState)),
184+ opts2
185+ );
186+
187+ {
188+ (bytes memory bz ,) = lc.getClientState (clientId);
189+ IbcLightclientsLcpV1ClientState.Data memory clientState = LCPProtoMarshaler.unmarshalClientState (bz);
190+ assertEq (clientState.latest_height.revision_number, 0 );
191+ assertEq (clientState.latest_height.revision_height, 1 );
192+ assertEq (clientState.mrenclave, newClientState.mrenclave);
193+ assertEq (clientState.key_expiration, newClientState.keyExpiration);
194+ assertEq (clientState.allowed_quote_statuses.length , 1 );
195+ assertEq (clientState.allowed_quote_statuses[0 ], newClientState.allowedQuoteStatuses[0 ]);
196+ assertEq (clientState.allowed_advisory_ids.length , 1 );
197+ assertEq (clientState.allowed_advisory_ids[0 ], newClientState.allowedAdvisoryIds[0 ]);
198+ assertEq (clientState.zkdcap_verifier_infos[0 ], newClientState.zkdcapVerifierInfos[0 ]);
199+ }
200+ }
201+
202+ function contractUpgradeCommon (string memory clientId ) internal returns (LCPClientZKDCAPOwnableUpgradeable) {
203+ Options memory opts;
204+ opts.constructorData = abi.encode (
205+ address (this ), false , ZKDCAPTestHelper.dummyIntelRootCACert (), address (new NopRiscZeroVerifier ())
206+ );
207+ LCPClientZKDCAPOwnableUpgradeable lc = LCPClientZKDCAPOwnableUpgradeable (
208+ Upgrades.deployUUPSProxy (
209+ "LCPClientZKDCAPOwnableUpgradeable.sol " ,
210+ abi.encodePacked (LCPClientZKDCAPOwnableUpgradeable.initialize.selector ),
211+ opts
212+ )
213+ );
214+ IbcLightclientsLcpV1ClientState.Data memory clientState = defaultClientState ();
215+ clientState.allowed_quote_statuses = new string [](2 );
216+ clientState.allowed_quote_statuses[0 ] = DCAPValidator.TCB_STATUS_CONFIGURATION_NEEDED_STRING;
217+ clientState.allowed_quote_statuses[1 ] = DCAPValidator.TCB_STATUS_OUT_OF_DATE_STRING;
218+ clientState.allowed_advisory_ids = new string [](2 );
219+ clientState.allowed_advisory_ids[0 ] = "INTEL-SA-0001 " ;
220+ clientState.allowed_advisory_ids[1 ] = "INTEL-SA-0003 " ;
221+ lc.initializeClient (
222+ clientId, LCPProtoMarshaler.marshal (clientState), LCPProtoMarshaler.marshal (defaultConsensusState ())
223+ );
224+ DCAPValidator.Output memory output = ZKDCAPTestHelper.qvOutput ();
225+ output.advisoryIDs = clientState.allowed_advisory_ids;
226+ Vm.Wallet memory ek0 = vm.createWallet ("ek0 " );
227+ output.enclaveKey = ek0.addr;
228+ // warp to the time of `output.validityNotBefore`
229+ vm.warp (output.validityNotBefore);
230+ lc.zkDCAPRegisterEnclaveKey (clientId, registerEnclaveKeyMessage (output));
231+ {
232+ LCPCommitment.UpdateStateProxyMessage memory updateStateMessage;
233+ updateStateMessage.prevHeight = Height.Data (0 , 0 );
234+ updateStateMessage.prevStateId = bytes32 (0 );
235+ updateStateMessage.postHeight = Height.Data (0 , 1 );
236+ updateStateMessage.postStateId = keccak256 ("state-1 " );
237+ updateStateMessage.timestamp = 1 ;
238+ LCPCommitment.ValidationContext memory vc;
239+ updateStateMessage.context = abi.encode (vc);
240+ updateStateMessage.emittedStates = new LCPCommitment.EmittedState [](1 );
241+
242+ LCPCommitment.HeaderedProxyMessage memory headeredMessage;
243+ headeredMessage.header = LCPCommitment.LCP_MESSAGE_HEADER_UPDATE_STATE;
244+ headeredMessage.message = abi.encode (updateStateMessage);
245+
246+ IbcLightclientsLcpV1UpdateClientMessage.Data memory message;
247+ message.proxy_message = abi.encode (headeredMessage);
248+
249+ (uint8 v , bytes32 r , bytes32 s ) = vm.sign (ek0, keccak256 (message.proxy_message));
250+ message.signatures = new bytes [](1 );
251+ message.signatures[0 ] = abi.encodePacked (r, s, v);
252+ lc.updateClient (clientId, message);
253+ }
254+ return lc;
255+ }
256+
187257 function testRecoveredLCPClientUpgradeable () public {
188258 string memory clientId = "lcp-zkdcap " ;
189259 TestTokiLCPClientZKDCAP lc = new TestTokiLCPClientZKDCAP (
0 commit comments