Skip to content

Fix client activation when ELC updater is enabled#72

Draft
izquierdo-datachain wants to merge 12 commits into
mainfrom
activate-client-with-elc-updater
Draft

Fix client activation when ELC updater is enabled#72
izquierdo-datachain wants to merge 12 commits into
mainfrom
activate-client-with-elc-updater

Conversation

@izquierdo-datachain

Copy link
Copy Markdown
Contributor

Activating a client requires updating the EKI, which involves:

  • Registering the enclave key in the counterparty chain.
  • Confirming that the transaction to register the enclave key in the counterparty was finalized.

To confirm finality, the Relayer needs to query the counterparty using GetLatestFinalizedHeader(), then check if the transaction's block height is lower than the finalized height, or not.

If ELC updater is not in use, GetLatestFinalizedHeader() queries the origin prover directly. But if ELC updater is in use, it tries to get the latest record available from ELC updater.

The problem is that before this commit, ELC updater itself cannot insert any record because:

  • It needs to update the ELC before any record can be inserted.
  • To update the ELC, it needs to call SetupHeadersForUpdate() which queries the on-chain light client.
  • But the on-chain light client is not activated yet, so the state is zeroed-out.

So there's a chicken-and-egg problem: activation requires records, but records can't be produced until activation is done.

This commit fixes the issue by making ELC updater's call to SetupHeadersForUpdate() query the ELC in LCP instead of querying the on-chain light client when there are no records yet. This works because the ELC has non-zero state when the client creation step of the handshake is done, and it's the same thing that updateELC() does.

Activating a client requires updating the EKI, which involves:

* Registering the enclave key in the counterparty chain.
* Confirming that the transaction to register the enclave key in the counterparty was finalized.

To confirm finality, the Relayer needs to query the counterparty using GetLatestFinalizedHeader(),
then check if the transaction's block height is lower than the finalized height, or not.

If ELC updater is not in use, GetLatestFinalizedHeader() queries the origin prover directly. But if ELC updater is in use,
it tries to get the latest record available from ELC updater.

The problem is that before this commit, ELC updater itself cannot insert any record because:

* It needs to update the ELC before any record can be inserted.
* To update the ELC, it needs to call SetupHeadersForUpdate() which queries the on-chain light client.
* But the on-chain light client is not activated yet, so the state is zeroed-out.

So there's a chicken-and-egg problem: activation requires records, but records
can't be produced until activation is done.

This commit fixes the issue by making ELC updater's call to
SetupHeadersForUpdate() query the ELC in LCP instead of querying the on-chain
light client when there are no records yet. This works because the ELC has
non-zero state when the client creation step of the handshake is done, and it's
the same thing that updateELC() does.
@izquierdo-datachain izquierdo-datachain self-assigned this Apr 17, 2026
@izquierdo-datachain izquierdo-datachain force-pushed the activate-client-with-elc-updater branch from c5358d5 to 2e79492 Compare April 21, 2026 07:56
This reverts commit 7c9ef04.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant