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: inclusion proof program #115

Merged
merged 5 commits into from
Jul 24, 2024
Merged

Conversation

tchataigner
Copy link
Member

@tchataigner tchataigner commented Jul 22, 2024

This PR creates a storage inclusion program for our Ethereum Light Client. It comes with a benchmark and tests.

Tests

The unit tests can be found under ethereum/light-client/src/proofs/inclusion.rs. A basic PR will trigger an execution test while the tests for SNARK and STARK proving are to be manually triggered because of computational costs.

Benchmark

The benchmark for this program can be found in ethereum/light-client/benches/inclusion.rs. This benchmark can either be on the STARK or SNARK proof based on an environment variable MODE=<STARK | SNARK>.

The current number for this inclusion proof is:

{
  // Time in milliseconds, 7~ minutes
  "proving_time": 441123,
  "verification_time": 2
}

The benchmark can be ran with:

MODE=SNARK SHARD_BATCH_SIZE=0 SHARD_SIZE=4194304 RUSTFLAGS="-C target-cpu=native -C opt-level=3" cargo +nightly-2024-05-31 bench --bench inclusion

Changelog

  • Implemented the inclusion program to execute the following:
    1. Check signature on the attested block in the latest finalized update
    2. Verify the EIP1186 proof on the state root hash of the block finalized by the update
  • Created a StorageInclusionProver that handles everything around this program: execute, STARK/SNARK proving and verifying
  • Implemented the secondary server to run the proving and verifying
  • Implemented request forwarding from the primary server to the secondary one
  • A bit of Rust documentation and MdBook documentation

Related issues

Closes #70

@tchataigner tchataigner force-pushed the feature/inclusion-proof-program branch from 09a05d9 to 0dc1ee6 Compare July 22, 2024 19:57
@tchataigner tchataigner marked this pull request as ready for review July 22, 2024 19:57
@tchataigner tchataigner force-pushed the feature/inclusion-proof-program branch 4 times, most recently from c816e56 to 2f4f6f4 Compare July 22, 2024 21:30
@tchataigner tchataigner force-pushed the feature/inclusion-proof-program branch from 2f4f6f4 to f33b126 Compare July 22, 2024 21:41
@storojs72 storojs72 self-requested a review July 23, 2024 07:54
storojs72
storojs72 previously approved these changes Jul 23, 2024
// Commit the two hashes
sphinx_zkvm::io::commit(&old_sync_committee_hash.hash());
// Commit the signer hash, the current and next sync committee hashes, and the block height
sphinx_zkvm::io::commit(update.attested_header().beacon().slot());
Copy link
Member

Choose a reason for hiding this comment

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

Is this: update.attested_header().beacon().slot() correspond to a block height?

Copy link
Member Author

@tchataigner tchataigner Jul 23, 2024

Choose a reason for hiding this comment

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

Yes, I have changed it to the finalized one now though

sphinx_zkvm::io::commit(&old_sync_committee_hash.hash());
// Commit the signer hash, the current and next sync committee hashes, and the block height
sphinx_zkvm::io::commit(update.attested_header().beacon().slot());
sphinx_zkvm::io::commit(&signer_sync_committee_hash.hash());
Copy link
Member

Choose a reason for hiding this comment

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

Is my understanding correct, that:

  • signer_sync_commitee_hash corresponds to H_29;
  • updated_sync_committee_hash corresponds to H_30;
  • next_sync_committee_hash corresponds to H_31;

according to the explanation from @huitseeker

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes!

wwared
wwared previously approved these changes Jul 23, 2024
Copy link
Member

@wwared wwared left a comment

Choose a reason for hiding this comment

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

Looks great! Main question is the last one about committing additional EIP1186 data in the inclusion program

ethereum/core/src/types/utils.rs Outdated Show resolved Hide resolved
ethereum/programs/inclusion/src/main.rs Show resolved Hide resolved
Comment on lines 75 to 80
sphinx_zkvm::io::commit(
eip1186_proof
.key_hash()
.expect("EIP1186Proof::key_hash: could not get key hash")
.as_ref(),
);
Copy link
Member

Choose a reason for hiding this comment

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

Should we commit additional data related to the EIP1186 proof? Specifically I'm thinking of the value correspondingly associated with the specific key/storage/slot/address.

Copy link
Member

Choose a reason for hiding this comment

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

+1. We do commit merkle tree key / value in aptos case.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've updated the program to have all the keys/values as outputs. I have removed what I had set previously to uniquely identify the proof, as it is redundant.

wwared
wwared previously approved these changes Jul 23, 2024
Copy link
Member

@huitseeker huitseeker left a comment

Choose a reason for hiding this comment

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

Overall looks good to me, I've left a few comments inline.

Comment on lines 185 to 189
for (i, element) in list.iter().enumerate() {
if i < list.len() - 1 {
element_offset += element.len();
bytes.extend_from_slice(&(element_offset as u32).to_le_bytes());
}
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I think you can avoid the enumerate.

    let mut element_offset = (list.len() * OFFSET_BYTE_LENGTH) as u32;

    for element in list {
        bytes.extend_from_slice(&element_offset.to_le_bytes());
        element_offset += element.len() as u32;
        serialized_elements.extend_from_slice(element);
    }

Copy link
Member Author

Choose a reason for hiding this comment

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

Makes sense!

Comment on lines 215 to 218
loop {
if cursor == first_offset {
break;
}
Copy link
Member

Choose a reason for hiding this comment

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

Could this be replaced by ?

    while cursor < first_offset {
    ...
    }

})?
.to_vec(),
);
} else if !bytes.is_empty() {
Copy link
Member

Choose a reason for hiding this comment

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

Could we negate this and front-load this condition?

    if bytes.len() <= OFFSET_BYTE_LENGTH {
        if bytes.is_empty() {
            return Ok(list_bytes);
        } else {
            return Err(TypesError::UnderLength {
                structure: "StorageProof".into(),
                minimum: OFFSET_BYTE_LENGTH,
                actual: bytes.len(),
            });
        }
    }

Copy link
Member Author

@tchataigner tchataigner Jul 23, 2024

Choose a reason for hiding this comment

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

Yes, and it should improve readability 😄

}

#[test]
#[ignore = "This test is too slow for CI"]
Copy link
Member

Choose a reason for hiding this comment

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

Could we open an issue to run this on a nightly basis? /cc @samuelburnham

Copy link
Member Author

Choose a reason for hiding this comment

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

Created #117

Copy link
Member

@wwared wwared left a comment

Choose a reason for hiding this comment

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

Looks great on my end

Copy link
Member

@storojs72 storojs72 left a comment

Choose a reason for hiding this comment

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

LGTM

@tchataigner tchataigner merged commit 968739a into dev Jul 24, 2024
6 checks passed
@tchataigner tchataigner deleted the feature/inclusion-proof-program branch July 24, 2024 07:42
tchataigner added a commit that referenced this pull request Jul 30, 2024
* feat: inclusion program

* refactor: output correct committee hash + finalized slot

* fix: fix tests after transition to finalized block height

* refactor: apply suggestion

Co-authored-by: wwared <[email protected]>

* refactor: address reviews

---------

Co-authored-by: wwared <[email protected]>
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.

State inclusion program
4 participants