Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 51 additions & 53 deletions .github/workflows/book.yml
Original file line number Diff line number Diff line change
@@ -1,58 +1,56 @@
name: book

on:
push:
branches: [main]
pull_request:
branches: [main]
paths:
- "book/**"
merge_group:
push:
branches: [main]
paths:
- "book/**"
merge_group:

jobs:
build:
name: Build Docusaurus
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 18

- name: Install dependencies
run: cd book && yarn install --frozen-lockfile
- name: Build website
run: |
cd book
yarn build-api
mv ../target/doc ./static/api
mv ./static/api/static.files/* ./static/api
rmdir ./static/api/static.files
yarn build-book

- name: Upload Build Artifact
uses: actions/upload-pages-artifact@v3
with:
path: book/build

deploy:
name: Deploy to GitHub Pages
needs: build

# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
permissions:
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source

# Deploy to the github-pages environment
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
build:
name: Build Docusaurus
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 18

- name: Install dependencies
run: cd book && yarn install --frozen-lockfile
- name: Build website
run: |
cd book
yarn build-api
mv ../target/doc ./static/api
mv ./static/api/static.files/* ./static/api
rmdir ./static/api/static.files
yarn build-book

- name: Upload Build Artifact
uses: actions/upload-pages-artifact@v3
with:
path: book/build

deploy:
name: Deploy to GitHub Pages
needs: build

# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
permissions:
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source

# Deploy to the github-pages environment
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
18 changes: 8 additions & 10 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
image=ubuntu22-full-x64,
spot=false,
"run-id=${{ github.run_id }}",
]
]
strategy:
matrix:
example:
Expand All @@ -39,12 +39,12 @@ jobs:

- name: "Install sp1up"
run: |
curl -L https://sp1.succinct.xyz | bash
echo "$HOME/.sp1/bin" >> $GITHUB_PATH
curl -L https://sp1.succinct.xyz | bash
echo "$HOME/.sp1/bin" >> $GITHUB_PATH

- name: "Install SP1 toolchain"
run: |
sp1up
sp1up

- name: "Set up RPC env"
run: |
Expand All @@ -54,19 +54,19 @@ jobs:
echo "OPTIMISM_RPC_URL=${{secrets.OPTIMISM_RPC_URL}}" >> $GITHUB_ENV

- name: Run ${{ matrix.example }}
uses: actions-rs/cargo@v1
uses: actions-rs/cargo@v1
with:
command: run
args:
--release --bin ${{ matrix.example }} --ignore-rust-version
args: --release --bin ${{ matrix.example }} --ignore-rust-version
env:
RUSTFLAGS: -Copt-level=3 -Coverflow-checks=y -Cdebuginfo=0 -C target-cpu=native
RUST_BACKTRACE: full
RUST_LOG: info

test-e2e:
name: E2E tests
runs-on: ["runs-on", "runner=32cpu-linux-x64", "run-id=${{ github.run_id }}"]
runs-on:
["runs-on", "runner=32cpu-linux-x64", "run-id=${{ github.run_id }}"]
env:
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
steps:
Expand All @@ -93,8 +93,6 @@ jobs:

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Run Forge build
run: |
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "contracts/lib/forge-std"]
path = contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "contracts/lib/sp1-helios"]
path = contracts/lib/sp1-helios
url = https://github.com/succinctlabs/sp1-helios
12 changes: 7 additions & 5 deletions book/docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ You can add the `--prove` argument to generate a proof.

:::warning

Running with `--prove` will generate a plonk proof. This requires significant computational resources, so we recommend using the [SP1 Prover network](https://docs.succinct.xyz/docs/network/developers/intro).
Running with `--prove` will generate a plonk proof. This requires significant computational resources, so we recommend using the [SP1 Prover network].

:::

Expand All @@ -40,20 +40,20 @@ RUST_LOG=info cargo run --bin uniswap-onchain-verify --release
By default, the `blockhash()` opcode is used, allowing to verify up to 256 blocks old, but the following arguments can be added to demonstrate the various features abaliable:

* If you provides a Beacon RPC endpoint with the `--beacon-sepolia-rpc-url` argument, the proof will be verified on chain with the beacon root using [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788), up to 8191 blocks old (~27h).
* The window can even be extended up to the Cancun hardfork by chaining beacon roots using the `--reference-block` argument.
* The window can even be extended up to the Cancun hardfork by chaining beacon roots using the `--reference-block` argument.

:::

:::warning

This example will generate a plonk proof. This requires significant computational resources, so we recommend using the [SP1 Prover network](https://docs.succinct.xyz/docs/network/developers/intro).
This example will generate a plonk proof. This requires significant computational resources, so we recommend using the [SP1 Prover network].

:::


## Multiplexer

The Multiplexer Oracle example demonstrates fetching exchange rates for multiple collateral tokens from an on-chain oracle contract and generating zero-knowledge proofs of the retrieved data.
The Multiplexer Oracle example demonstrates fetching exchange rates for multiple collateral tokens from an on-chain oracle contract and generating zero-knowledge proofs of the retrieved data.

:::tip

Expand Down Expand Up @@ -105,4 +105,6 @@ This example can be ran with the following command:
RUST_LOG=info cargo run --bin events --release
```

:::
:::

[SP1 Prover network]: https://docs.succinct.xyz/docs/protocol/spn/architecture
40 changes: 34 additions & 6 deletions book/docs/proof-verification.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,25 @@ SP1 Contract call retrieve the state for contract calls at a specific block (cal

The anchor consists of an identifier that identifies the block and a hash that enables its verification. The method used to generate the anchor have a direct impact of the window between the execution block and the block on which the verify transaction is contained, as you can see in the table below:

| Method | Anchor Identifier | Anchor Hash | On-chain validation | Validation window |
|-------------------------------------|-------------------|-------------|---------------------|-------------------|
| [Block hash](#using-block-hash) | Block number | Block hash | ✅ | 256 blocks |
| [Beacon root](#using-beacon-root) | Timestamp | Beacon root | ✅ | 8191 blocks |
| [Beacon root (chained)](#chaining) | Timestamp | Beacon root | ✅ | Up to Cancun |
| [Consensus](#using-consensus) | Slot | Beacon root | ❌ | N/A |
| Method | Anchor Identifier | Anchor Hash | On-chain validation | Validation window |
|-------------------------|-------------------|-------------|-----------------------|-------------------|
| [Block hash] | Block number | Block hash | ✅ | 256 blocks |
| [Beacon root] | Timestamp | Beacon root | ✅ | 8191 blocks |
| [Beacon root (chained)] | Timestamp | Beacon root | ✅ | Up to Cancun |
| [Consensus] | Slot | Beacon root | ✅ (using SP1 Helios) | Up to Atlair |

[Beacon root]: #using-beacon-root
[Block hash]: #using-block-hash
[Beacon root (chained)]: #chaining
[Consensus]: #using-consensus
[with SP1 Helios]: #on-chain-validation-using-sp1-helios

## Using block hash

This method uses the `blockhash` opcode to commit to a block hash. This gives 256 blocks (approximately 50 minutes) to create the proof and confirm that the validating transaction is included in a block.

The [ContractCall] library `verify()` function can by used to validate the contract call proof public values on-chain.

## Using beacon root

This approach enables verification through the [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) beacon roots contract. By using this technique, the onchain proof validation window is extended to 8191 blocks (approximately 27 hours). The method requires a beacon API endpoint connection and can be activated by invoking [`EvmSketchBuilder::cl_rpc_url()`]:
Expand All @@ -33,6 +41,8 @@ let sketch = EvmSketch::builder()
.await?;
```

In the same way as with the block hash method, the [ContractCall] library `verify()` function can by used to validate the contract call proof public values on-chain.

### Chaining

The EIP-4788 anchor mechanism can be used to query view call state from blocks beyond the 8191 block limit by separating the anchor into two components: an execution block and a reference block. While the reference block acts as the anchor and must remain within the ~27 hour onchain validation timeframe, the execution block can extend significantly further into the past—up to the Cancun hardfork (March 13, 2024 on Mainnet).
Expand Down Expand Up @@ -77,7 +87,25 @@ let sketch = EvmSketch::builder()
.await?;
```

More specifically, it is possible to leverage [SP1 Helios], which consists of the following components:

* The SP1 Helios program. An SP1 program that verifies the consensus of a source chain in the execution environment of a destination chain using the [helios] library.
* An `SP1Helios` contract. Contains the logic for verifying SP1 Helios proofs, storing the latest data from the Ethereum beacon chain, including the headers, execution state roots and sync committees.
* The operator. A Rust script that fetches the latest data from a deployed SP1Helios contract and an Ethereum beacon chain, determines the block to request, requests for/generates a proof, and relays the proof to the SP1Helios contract.

You can have a look at the [SP1 Helios book] to learn how to deploy it. Then, you can use the [ContractCall] library `verifyWithSp1Helios()` function to validate the contract call proof public values. It will uses the `SP1Helios` contract to verify the anchor is valid.

:::tip

As hinted above, the consensus method can be used to validate the public values of proofs generated on another chain. You just need to deploy the `SP1Helios` contract on the destination chain, and configure the operator to fetch the data from the chain where the contract executions occured.

:::

[`Anchor`]: pathname:///api/sp1_cc_client_executor/enum.Anchor.html
[`EvmSketchBuilder::cl_rpc_url()`]: pathname:///api/sp1_cc_host_executor/struct.EvmSketchBuilder.html#method.cl_rpc_url
[`EvmSketchBuilder::at_reference_block()`]: pathname:///api/sp1_cc_host_executor/struct.EvmSketchBuilder.html#method.at_reference_block
[`EvmSketchBuilder::consensus()`]: pathname:///api/sp1_cc_host_executor/struct.EvmSketchBuilder.html#method.consensus
[SP1 Helios]: https://github.com/succinctlabs/sp1-helios
[SP1 Helios book]: https://succinctlabs.github.io/sp1-helios/deployment.html
[helios]: https://github.com/a16z/helios
[ContractCall]: https://github.com/succinctlabs/sp1-contract-call/tree/main/contracts/src/ContractCall.sol
14 changes: 14 additions & 0 deletions contracts/foundry.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"../examples/uniswap/contracts/lib/forge-std": {
"rev": "b8f065fda83b8cd94a6b2fec8fcd911dc3b444fd"
},
"../examples/uniswap/contracts/lib/sp1-contracts": {
"rev": "a6ca9452af7d6175adcef28b634fcae8662ded03"
},
"lib/forge-std": {
"rev": "b8f065fda83b8cd94a6b2fec8fcd911dc3b444fd"
},
"lib/sp1-helios": {
"rev": "33d243728fe9ec4850e7b4fa1c2e373b7c8a61c6"
}
}
1 change: 1 addition & 0 deletions contracts/lib/sp1-helios
Submodule sp1-helios added at 3ad778
2 changes: 2 additions & 0 deletions contracts/remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@sp1-helios/=lib/sp1-helios/contracts/src/
@sp1-contracts/=lib/sp1-helios/contracts/lib/sp1-contracts/contracts/src/
14 changes: 14 additions & 0 deletions contracts/src/ContractCall.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {SP1Helios} from "@sp1-helios/SP1Helios.sol";

/// @notice The inputs used to verify a contract call.
struct ContractPublicValues {
uint256 id;
Expand Down Expand Up @@ -47,6 +49,18 @@ library ContractCall {
revert AnchorTypeNotSupported(publicValues.anchorType);
}

/// @notice Verify contract call public values, using a [`SP1Helios`] contract.
/// @dev Panics if the [`AnchorType`] is not `Slot`.
function verifyWithSp1Helios(ContractPublicValues memory publicValues, address sp1Helios) internal view {
if (publicValues.anchorType != AnchorType.Slot) {
revert AnchorTypeNotSupported(publicValues.anchorType);
}

if (publicValues.anchorHash != SP1Helios(sp1Helios).headers(publicValues.id)) {
revert AnchorMismatch();
}
}

/// @notice Verify if the provided block hash matches the one of the given block number.
function verifyBlockAnchor(uint256 blockNumber, bytes32 blockHash) internal view {
if (blockNumber >= block.number || block.number - blockNumber > 256) {
Expand Down
2 changes: 1 addition & 1 deletion examples/uniswap/contracts/lib/forge-std
Submodule forge-std updated 57 files
+1 −0 .github/CODEOWNERS
+6 −0 .github/dependabot.yml
+114 −100 .github/workflows/ci.yml
+6 −1 .github/workflows/sync.yml
+193 −0 CONTRIBUTING.md
+20 −4 README.md
+12 −0 RELEASE_CHECKLIST.md
+10 −4 foundry.toml
+1 −1 package.json
+12 −1 scripts/vm.py
+22 −9 src/Base.sol
+60 −0 src/Config.sol
+477 −0 src/LibVariable.sol
+1 −0 src/Script.sol
+142 −47 src/StdAssertions.sol
+36 −3 src/StdChains.sol
+17 −5 src/StdCheats.sol
+612 −0 src/StdConfig.sol
+30 −0 src/StdConstants.sol
+104 −0 src/StdJson.sol
+4 −0 src/StdMath.sol
+2 −2 src/StdStorage.sol
+104 −0 src/StdToml.sol
+0 −18 src/StdUtils.sol
+1 −0 src/Test.sol
+674 −40 src/Vm.sol
+471 −463 src/console.sol
+1 −1 src/interfaces/IERC1155.sol
+3 −3 src/interfaces/IERC4626.sol
+72 −0 src/interfaces/IERC6909.sol
+1 −1 src/interfaces/IERC721.sol
+150 −0 src/interfaces/IERC7540.sol
+241 −0 src/interfaces/IERC7575.sol
+0 −234 src/mocks/MockERC20.sol
+0 −231 src/mocks/MockERC721.sol
+44 −0 test/CommonBase.t.sol
+352 −0 test/Config.t.sol
+434 −0 test/LibVariable.t.sol
+1 −5 test/StdAssertions.t.sol
+21 −20 test/StdChains.t.sol
+55 −34 test/StdCheats.t.sol
+38 −0 test/StdConstants.t.sol
+12 −12 test/StdError.t.sol
+1 −1 test/StdJson.t.sol
+6 −16 test/StdMath.t.sol
+25 −8 test/StdStorage.t.sol
+1 −1 test/StdStyle.t.sol
+1 −1 test/StdToml.t.sol
+12 −12 test/StdUtils.t.sol
+9 −6 test/Vm.t.sol
+1 −1 test/compilation/CompilationScript.sol
+1 −1 test/compilation/CompilationScriptBase.sol
+1 −1 test/compilation/CompilationTest.sol
+1 −1 test/compilation/CompilationTestBase.sol
+81 −0 test/fixtures/config.toml
+0 −441 test/mocks/MockERC20.t.sol
+0 −721 test/mocks/MockERC721.t.sol
5 changes: 3 additions & 2 deletions examples/uniswap/contracts/remappings.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
@sp1-contracts/=./lib/sp1-contracts/contracts/src/
@sp1-contract-call/=../../../contracts/src/
@sp1-contracts/=lib/sp1-contracts/contracts/src/
@sp1-contract-call/=../../../contracts/src/
@sp1-helios/=../../../contracts/lib/sp1-helios/contracts/src/
Loading