Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: sgx verifier #58

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft

feat: sgx verifier #58

wants to merge 8 commits into from

Conversation

zimpha
Copy link
Member

@zimpha zimpha commented Oct 29, 2024

No description provided.

@zimpha zimpha self-assigned this Oct 29, 2024
@zimpha zimpha requested a review from icemelon November 1, 2024 06:22
src/L1/rollup/IScrollChain.sol Outdated Show resolved Hide resolved
src/L1/rollup/IScrollChain.sol Outdated Show resolved Hide resolved
src/L1/rollup/ScrollChain.sol Outdated Show resolved Hide resolved
src/L1/rollup/ScrollChain.sol Show resolved Hide resolved
src/L1/rollup/ScrollChain.sol Outdated Show resolved Hide resolved
src/sgx-verifier/AttestationVerifier.sol Show resolved Hide resolved
src/sgx-verifier/AttestationVerifier.sol Show resolved Hide resolved
src/sgx-verifier/AttestationVerifier.sol Show resolved Hide resolved
src/sgx-verifier/SGXVerifier.sol Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

How will we deal with protocol upgrades (multiple batch versions)?

Will we deploy multiple instances of SGXVerifier with different attestationVerifier contracts? Or will they reuse the same attestationVerifier?

Copy link
Member Author

Choose a reason for hiding this comment

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

We will have a MultipleVersionRollupVerifier contract deployed only for SGXVerifier and the version managed in this contract. So each time we upgrade batch version, both MultipleVersionRollupVerifier for zkp and tee should be updated.

For different SGXVerifier, I believe we can share the same attestationVerifier.

Copy link
Contributor

Choose a reason for hiding this comment

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

For different SGXVerifier, I believe we can share the same attestationVerifier.

I'm not sure. Basically we'd need batchVersion ==> mrEnclave mapping implemented by MultipleVersionRollupVerifier. (In practice it's batchVersion ==> sgxVerifier ==> attestationVerifier.)

Copy link
Member Author

Choose a reason for hiding this comment

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

(In practice it's batchVersion ==> sgxVerifier ==> attestationVerifier.)

true, we can decide it later. It is only related to deployment.

Thegaram
Thegaram previously approved these changes Nov 5, 2024
src/L1/rollup/IScrollChain.sol Outdated Show resolved Hide resolved
// Pop finalized and non-skipped message from L1MessageQueue.
_finalizePoppedL1Messages(_totalL1MessagesPoppedOverall);

emit VerifyBatchWithTee(_batchIndex);
emit FinalizeBatch(_batchIndex, _batchHash, _postStateRoot, _withdrawRoot);
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a note to self (and to @colinlyguo): This will keep the semantics of FinalizeBatch as before, but indexers might still need to be updated if they want to decode the transaction calldata. (Maybe only relevant for commit, not finalize.)

Copy link
Member

Choose a reason for hiding this comment

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

chain-monitor (does not monitor batch finalize events, only monitors finalize deposit/withdraw events), bridge-history (withdraw proof), and l2geth-verifier (finalize batch verification) are compatible. I believe sync-from-DA feature is also compatible.

We can keep a close eye on monitoring these components after the upgrade as well.

Comment on lines 629 to 630
finalizedStateRoots[_batchIndex] = _postStateRoot;
withdrawRoots[_batchIndex] = _withdrawRoot;
Copy link
Contributor

Choose a reason for hiding this comment

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

These are not finalized at this point. Is there a risk that clients will incorrectly rely on unfinalized roots?

The question is: Should we prevent this programmatically / through renaming? Or should we just use documentation to communicate that clients must use lastFinalizedBatchIndex or isBatchFinalized before reading from finalizedStateRoots.

Copy link
Member Author

Choose a reason for hiding this comment

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

We can override the function of finalizedStateRoots and withdrawRoots, to make it return bytes(0) for all indices after lastFinalizedBatchIndex.

emit ResolveState(state.batchIndex, state.stateRoot, state.withdrawRoot);

// reset zkp verified batch index, zk prover need to reprove everything after this batch
lastZkpVerifiedBatchIndex = state.batchIndex;
Copy link
Contributor

Choose a reason for hiding this comment

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

@colinlyguo any thoughts what we'd need to add to be able to recover from this relatively painlessly? Maybe just listen to ResolveState events in rollup-relayer and update db accordingly? (Though in this case most likely we'll need to fix either zk or sgx prover.)

Copy link
Member

@colinlyguo colinlyguo Nov 6, 2024

Choose a reason for hiding this comment

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

Maybe just listen to ResolveState events in rollup-relayer and update db accordingly
agree.
Though in this case most likely we'll need to fix either zk or sgx prover.
Before ResolveState

  • if no need to fix zk prover or it has been fixed, then can rely on auto-recover of rollup-relayer.
  • if we just ResolveState first then fix zk prover, then add a flag to halt finalization.

point me out if missing any corner cases pls.

Copy link
Contributor

Choose a reason for hiding this comment

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

So with MockFinalize mode we'd still need to run an SGX prover?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, running a SGX prover is cheap. I think it is ok to run it in sepolia.

Copy link
Contributor

Choose a reason for hiding this comment

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

Since the verifier is set as address(0), does that mean that we just need someone to call finalizeBundleWithTeeProof (e.g. in rollup-relayer, when fake finalize mode is enabled), and the verifyBundleProof call will be a no-op?

Copy link
Member Author

Choose a reason for hiding this comment

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

seems that I forget to change the constructor. The verifier should not be set as address(0). I did change ScrollChainMockBlob since it is used in unit tests. I'm thinking we should also add unit tests for ScrollChainMockFinalize.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see two options two make ScrollChainMockFinalize useful:

  1. Use address(0) as verifier so that we bypass the whole verification step. Then, rollup-relayer can call finalizeBundleWithTeeProof when fake finalization is enabled.
  2. Keep the verifier, but somehow bypass verifyAttestation, so that we can run the "SGX" prover on normal hardware. (Setting up SGX hardware is too complex for a devnet.)

Copy link
Member Author

Choose a reason for hiding this comment

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

For option 2, we need test the feature in sepolia first before goes to mainnet. After test we can do anything we like, like bypass verifyAttestation or fake finalization on tee proof.

src/L1/rollup/ScrollChain.sol Outdated Show resolved Hide resolved
src/L1/rollup/ScrollChain.sol Outdated Show resolved Hide resolved
src/L1/rollup/ScrollChain.sol Outdated Show resolved Hide resolved
src/L1/rollup/ScrollChain.sol Outdated Show resolved Hide resolved
import {BytesUtils} from "./utils/BytesUtils.sol";

/// @dev This contract is modified from https://github.com/automata-network/scroll-prover/blob/demo/contracts/src/core/AttestationVerifier.sol
contract AttestationVerifier is Ownable, IAttestationVerifier {
Copy link
Member

Choose a reason for hiding this comment

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

any doc about this verifier?

src/sgx-verifier/AttestationVerifier.sol Outdated Show resolved Hide resolved
function initializeV2() external reinitializer(2) {
uint256 cachedIndex = lastZkpVerifiedBatchIndex;
lastTeeVerifiedBatchIndex = cachedIndex;
emit VerifyBatchWithTee(cachedIndex);
Copy link
Member

Choose a reason for hiding this comment

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

Would another event name to differentiate from real tee verify a better choice?

);

/// @notice Emitted when a batch is verified by tee proof
/// @dev Tee proof always comes after zk proof. If they match, the state root and withdraw root are the same.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// @dev Tee proof always comes after zk proof. If they match, the state root and withdraw root are the same.

/*************************
* Public View Functions *
*************************/

/// @return The latest finalized batch index.
/// @return The latest finalized batch index (both zkp and tee verified).
Copy link
Contributor

Choose a reason for hiding this comment

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

(both zkp and tee verified)

This is not always true, right?


/// @notice The timestamp to delay proof when we only has one proof type.
/// @dev This is enabled after Euclid upgrade.
uint256 public proofDelayTimestamp;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
uint256 public proofDelayTimestamp;
uint256 public emergencyFinalizationDelay;

The word "timestamp" is usually used for instants, not durations

/**********************
* Internal Functions *
**********************/

/// @dev Internal function to enable proof types.
/// @param mask The mask for new enabled proof types.
function _enableProofTypes(uint256 mask) internal {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should require that mask <= 3

@@ -172,6 +260,14 @@ contract ScrollChain is OwnableUpgradeable, PausableUpgradeable, IScrollChain {
_;
}

modifier whenFinalizeNotPaused(ProofType proofType) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also consider paused here (operator pause) as a 3rd case

/// @notice Update the bundle size
/// @param size The new bundle size.
/// @param batchIndex The start batch index for new bundle size.
function updateBundleSize(uint128 size, uint128 batchIndex) external onlyOwner {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a risk that we (accidentally) set a very large index, and then we have no way to change this?

);

// initialize the first element in the array
bundleSize.push(BundleSizeStruct(_bundleSize, uint128(cachedIndex)));
Copy link
Contributor

Choose a reason for hiding this comment

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

How will the upgrade happen? Basically right after executing the upgrade we'll need to reset all pending bundles in the rollup-relayer, right?

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.

3 participants