Skip to content

Conversation

@enitrat
Copy link
Contributor

@enitrat enitrat commented Dec 10, 2025

Summary

This PR optimizes public decryption by removing a redundant storage write in the Decryption contract, saving approximately 20,000 gas per public decryption request.

Changes

Storage Optimization

  • Renamed decryptionDone to userDecryptionDone: The mapping is now scoped to only user/delegated user decryption, where it's actually needed
  • Removed redundant SSTORE in publicDecryptionResponse(): Public decryption consensus is now tracked solely through decryptionConsensusDigest, eliminating an unnecessary storage write

Gas Impact

  • Savings: ~20,000 gas per public decryption request (1 cold SSTORE removed)
  • No additional cost: The check now uses decryptionConsensusDigest which is already read/written in the same function

Compatibility

  • External interfaces: No changes - isDecryptionDone() works identically for both types
  • kms-connector compatibility: Verified that the off-chain component calls isDecryptionDone() which maintains the same behavior, not the internal mapping

Close https://github.com/zama-ai/fhevm-internal/issues/751

…for public decryption

Optimize public decryption by removing redundant storage write.

Changes:
- Renamed decryptionDone to userDecryptionDone (only used for user decryption)
- Modified publicDecryptionResponse() to check decryptionConsensusDigest instead of decryptionDone
- Removed redundant SSTORE in publicDecryptionResponse() (~20k gas savings per request)
- Updated isDecryptionDone() with type-aware logic based on decryption ID range
- Public decryption now checks if decryptionConsensusDigest is set
- User decryption continues using userDecryptionDone mapping

Close zama-ai/fhevm-internal#751
@enitrat enitrat requested a review from a team as a code owner December 10, 2025 11:31
@cla-bot cla-bot bot added the cla-signed label Dec 10, 2025
@mergify
Copy link

mergify bot commented Dec 10, 2025

🧪 CI Insights

Here's what we observed from your CI run for 5846288.

🟢 All jobs passed!

But CI Insights is watching 👀

Copy link
Contributor

@ClementWalter ClementWalter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@enitrat enitrat requested review from a team and jatZama December 10, 2025 17:05
/// @notice Whether a (public, user, delegated user) decryption is done
mapping(uint256 decryptionId => bool decryptionDone) decryptionDone;
/// @notice Whether a (user, delegated user) decryption is done
mapping(uint256 decryptionId => bool userDecryptionDone) userDecryptionDone;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that, unfortunately, we can't rename state variables, but deprecate them and add the new ones at the end of the storage struct. This is because of upgrade conflicts between storage layouts. Also, we must bump the contract and the reinitializer versions in order to properly upgrade the contract once the change is introduced.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah ok cool thanks for raising that!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we must bump the contract and the reinitializer versions in order to properly upgrade the contract once the change is introduced.

what does this mean?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means:

  1. Bump internal contract version here
  2. And also bump the reinitializer version here

The second one is relevant for upgrading the contract, so the reinitializerVX method can be called with the correct versioning. For example, on testnet we have deployed now v0.10.x with reinitializer version 4, so when we need to upgrade to v0.11.x we should have this reinitializer version incremented to 5 in order to properly call the reinitializerV4() method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants