8607459222bf1cef89da9aa4b043cd453ccecc78 #4282
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Checks | |
# On Rust, GitHub Actions, and caching | |
# =========== | |
# Here's a list of things to keep in mind if you find yourself maintaining this | |
# CI: | |
# | |
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key | |
# | |
# - Always install and select the desired Rust toolchain *before* running | |
# `Swatinem/rust-cache`. This is because the active Rust toolchain is used as | |
# a cache key. | |
# - You can use `rustup show` to install and select the right Rust toolchain if | |
# you have a `rust-toolchain.toml` file: | |
# https://github.com/rust-lang/rustup/issues/1397. | |
# - When caching Rust compilation artifacts, keep in mind that different `cargo` | |
# commands will use different profiles | |
# (https://doc.rust-lang.org/cargo/reference/profiles.html). Learn what you | |
# can reuse between one job and another and don't assume two commands will | |
# just share caches without conflicts. | |
# - Be extremely aware of cache thrashing a.k.a. churning. GitHub Actions' cache | |
# allows for 10GiB of data which is easily exceeded if not careful. | |
# Sometimes it's better not to cache than cache excessively. | |
# Disabling cache writes for non-default branches altogether if cache churning | |
# is unacceptably high is supposed to help with this. | |
# - Learn cache invalidation rules of `Swatinem/rust-cache` before making | |
# changes, e.g. what happens when `rustc --version` changes or `Cargo.lock` | |
# changes (or is missing). | |
# - The jobs dependency tree is the way it is to accommodate for sharing caches, | |
# not necessarily because it makes logical sense to run one job after the | |
# other. This is due to the fact that we can't share caches between jobs that | |
# run in parallel. | |
# - `sccache` is a good alternative to `Swatinem/rust-cache`, but it behaves | |
# poorly with GHA and often incurs into cache requests rate limits. We should | |
# probably explore `sccache` with a different backend. | |
# - If a job makes good use of extra cores, consider give it a bigger machine. | |
# GHA larger runners increase in cost linearly with the number of cores | |
# (https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions), | |
# so you're not wasting money unless several cores are sitting idle for long. | |
on: | |
workflow_dispatch: | |
inputs: | |
custom_name: | |
description: 'Custom run name (optional)' | |
required: false | |
type: string | |
merge_group: | |
types: ["checks_requested"] | |
push: | |
branches: ["nightly", "devnet-freeze", "release-v*"] | |
pull_request: | |
branches: ["nightly", "devnet-freeze", "release-v*"] | |
types: [opened, synchronize, reopened, ready_for_review] | |
run-name: ${{ inputs.custom_name || github.event.pull_request.title || github.sha }} | |
env: | |
CARGO_TERM_COLOR: always | |
RUSTFLAGS: -D warnings | |
FOUNDRY_PROFILE: ci | |
# Automatically cancels a job if a new commit if pushed to the same PR, branch, or tag. | |
# Source: <https://stackoverflow.com/a/72408109/5148606> | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
# Except in `nightly` and `stable` branches! Any cancelled job will cause the | |
# CI run to fail, and we want to keep a clean history for major branches. | |
cancel-in-progress: ${{ (github.ref != 'refs/heads/nightly') && (github.ref != 'refs/heads/devnet-freeze') && (github.ref != 'refs/heads/main') }} | |
jobs: | |
build: | |
name: build | |
runs-on: ubicloud-standard-30 | |
timeout-minutes: 60 | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: rui314/setup-mold@v1 | |
- name: Install Protoc | |
uses: arduino/setup-protoc@v2 | |
with: | |
version: "23.2" | |
repo-token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Toolchain | |
uses: dtolnay/rust-toolchain@nightly | |
- name: Rust Cache | |
uses: Swatinem/rust-cache@v2 | |
- name: Install cargo-risczero | |
uses: taiki-e/install-action@v2 | |
with: | |
tool: [email protected] | |
- name: Install risc0-zkvm toolchain | |
run: cargo risczero install --version r0.1.79.0 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Build citrea | |
run: make build-release | |
env: | |
REPR_GUEST_BUILD: 1 | |
- name: Upload artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: citrea-build | |
path: | | |
target/release/citrea | |
target/release/**/methods.rs | |
retention-days: 1 | |
check: | |
name: check | |
runs-on: ubicloud-standard-16 | |
timeout-minutes: 60 | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: rui314/setup-mold@v1 | |
- name: Install Protoc | |
uses: arduino/setup-protoc@v2 | |
with: | |
version: "23.2" | |
repo-token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Toolchain | |
uses: dtolnay/rust-toolchain@nightly | |
with: | |
components: rustfmt, clippy | |
- name: Rust Cache | |
uses: Swatinem/rust-cache@v2 | |
- name: Install cargo-risczero | |
uses: taiki-e/install-action@v2 | |
with: | |
tool: [email protected] | |
- name: Install risc0-zkvm toolchain | |
run: cargo risczero install --version r0.1.79.0-2 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Check TOML | |
uses: dprint/[email protected] | |
- name: Run lint | |
run: | | |
if ! make lint ; then | |
echo "Linting or formatting errors detected, please run 'make lint-fix' to fix it"; | |
exit 1 | |
fi | |
env: | |
SKIP_GUEST_BUILD: 1 | |
udeps: | |
name: udeps | |
runs-on: ubicloud-standard-8 | |
timeout-minutes: 60 | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: rui314/setup-mold@v1 | |
- name: Install Protoc | |
uses: arduino/setup-protoc@v2 | |
with: | |
version: "23.2" | |
repo-token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Toolchain | |
uses: actions-rs/toolchain@v1 | |
with: | |
toolchain: nightly-2024-07-27 | |
override: true | |
- name: Rust Cache | |
uses: Swatinem/rust-cache@v2 | |
- name: Install cargo-risczero | |
uses: taiki-e/install-action@v2 | |
with: | |
tool: [email protected] | |
- name: Install risc0-zkvm toolchain | |
run: cargo risczero install --version r0.1.79.0-2 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Run cargo-udeps | |
env: | |
RUSTFLAGS: -A warnings | |
SKIP_GUEST_BUILD: 1 | |
uses: aig787/cargo-udeps-action@v1 | |
with: | |
version: "latest" | |
args: "--workspace --all-features --all-targets" | |
deny: | |
runs-on: ubuntu-latest | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Run cargo-deny | |
uses: EmbarkStudios/cargo-deny-action@v1 | |
with: | |
command: check | |
coverage: | |
runs-on: ubicloud-standard-16 | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dtolnay/[email protected] | |
with: | |
components: llvm-tools-preview | |
- name: Rust Cache | |
uses: Swatinem/rust-cache@v2 | |
- uses: taiki-e/install-action@nextest | |
- uses: taiki-e/install-action@cargo-llvm-cov | |
- name: Install cargo-risczero | |
uses: taiki-e/install-action@v2 | |
with: | |
tool: [email protected] | |
- name: Install risc0-zkvm toolchain | |
run: cargo risczero install --version r0.1.79.0-2 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Cache ethereum-tests | |
uses: actions/cache@v3 | |
with: | |
key: "eth-tests-1c23e3c" | |
path: crates/evm/ethereum-tests | |
- name: Run coverage | |
run: make coverage | |
env: | |
RUST_BACKTRACE: 1 | |
TEST_BITCOIN_DOCKER: 1 | |
SHORT_PREFIX: 1 | |
CITREA_E2E_TEST_BINARY: ${{ github.workspace }}/target/debug/citrea | |
- name: Upload coverage | |
uses: codecov/codecov-action@v4 | |
with: | |
fail_ci_if_error: true # optional (default = false) | |
files: ./lcov.info | |
token: ${{ secrets.CODECOV_TOKEN }} | |
uniswap: | |
runs-on: ubicloud-standard-16 | |
needs: build | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/setup-node@v4 | |
with: | |
node-version: 18 | |
- name: Download artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: citrea-build | |
path: target/release | |
- name: Make citrea executable | |
run: chmod +x target/release/citrea | |
- name: Install node dependencies | |
working-directory: ./bin/citrea/tests/evm/uniswap | |
run: npm install | |
- name: Run uniswap tests | |
run: | | |
RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/sequencer_rollup_config.toml --sequencer resources/configs/mock/sequencer_config.toml --genesis-paths resources/genesis/mock/ & | |
sleep 2 | |
RUST_LOG=off ./target/release/citrea --rollup-config-path resources/configs/mock/rollup_config.toml --genesis-paths resources/genesis/mock/ & | |
sleep 2 | |
cd ./bin/citrea/tests/evm/uniswap | |
npx hardhat run --network citrea scripts/01_deploy.js | |
npx hardhat run --network citrea scripts/02_swap.js | |
seqnHeight=$(curl -s 0.0.0.0:12345/ -H "Content-Type: application/json" --data '{"method":"eth_getBlockByNumber","params":["latest"],"id":1,"jsonrpc":"2.0"}' | jq -e .result.number) || (echo "Couldn't get sequencer block"; exit 1) | |
nodeHeight=$(curl -s 0.0.0.0:12346/ -H "Content-Type: application/json" --data '{"method":"eth_getBlockByNumber","params":["latest"],"id":1,"jsonrpc":"2.0"}' | jq -e .result.number) || (echo "Couldn't get full node block"; exit 1) | |
echo seqnHeight: $seqnHeight | |
echo nodeHeight: $nodeHeight | |
sleep 10 | |
seqnRoot=$(curl -s 0.0.0.0:12345/ -H "Content-Type: application/json" --data '{"method":"eth_getBlockByNumber","params":['${seqnHeight}'],"id":1,"jsonrpc":"2.0"}' | jq -e .result.stateRoot) || (echo "Couldn't get sequencer state root"; exit 1) | |
nodeRoot=$(curl -s 0.0.0.0:12346/ -H "Content-Type: application/json" --data '{"method":"eth_getBlockByNumber","params":['${seqnHeight}'],"id":1,"jsonrpc":"2.0"}' | jq -e .result.stateRoot) || (echo "Couldn't get full node state root"; exit 1) | |
echo seqnRoot: $seqnRoot | |
echo nodeRoot: $nodeRoot | |
if [ "$seqnRoot" != "$nodeRoot" ]; then | |
echo "State root mismatch"; | |
exit 1 | |
fi | |
web3_py: | |
runs-on: ubicloud-standard-16 | |
needs: build | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/setup-python@v4 | |
- uses: dcarbone/install-jq-action@v2 | |
- name: Download artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: citrea-build | |
path: target/release | |
- name: Make citrea executable | |
run: chmod +x target/release/citrea | |
- name: Install dependencies | |
working-directory: ./bin/citrea/tests/evm/web3_py | |
run: pip install -r requirements.txt | |
- name: Run web3.py tests | |
run: | | |
RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/sequencer_rollup_config.toml --sequencer resources/configs/mock/sequencer_config.toml --genesis-paths resources/genesis/mock/ & | |
sleep 2 | |
RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/rollup_config.toml --genesis-paths resources/genesis/mock/ & | |
sleep 2 | |
cd ./bin/citrea/tests/evm/web3_py | |
python test.py | |
ethers_js: | |
runs-on: ubicloud-standard-16 | |
needs: build | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/setup-node@v4 | |
with: | |
node-version: 18 | |
- name: Download artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: citrea-build | |
path: target/release | |
- name: Make citrea executable | |
run: chmod +x target/release/citrea | |
- name: Install node dependencies | |
working-directory: ./bin/citrea/tests/evm/ethers_js | |
run: npm install | |
- name: Run ethers_js tests | |
run: | | |
RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/sequencer_rollup_config.toml --sequencer resources/configs/mock/sequencer_config.toml --genesis-paths resources/genesis/mock/ & | |
sleep 2 | |
RUST_LOG=off ./target/release/citrea --da-layer mock --rollup-config-path resources/configs/mock/rollup_config.toml --genesis-paths resources/genesis/mock/ & | |
sleep 2 | |
cd ./bin/citrea/tests/evm/ethers_js | |
npm install | |
npx mocha test.js | |
cd ../../../../.. | |
check_no_std: | |
runs-on: ubicloud-standard-4 | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install Rust Bare Metal | |
uses: actions-rs/toolchain@v1 | |
with: | |
toolchain: 1.79.0 | |
target: thumbv6m-none-eabi | |
override: true | |
- name: Install Rust WASM | |
uses: actions-rs/toolchain@v1 | |
with: | |
toolchain: 1.79.0 | |
target: wasm32-unknown-unknown | |
override: true | |
- name: cargo install cargo-hack | |
uses: taiki-e/install-action@cargo-hack | |
- uses: Swatinem/rust-cache@v2 | |
with: | |
save-if: ${{ github.ref == 'refs/heads/nightly' }} | |
- name: Run check | |
run: make check-no-std | |
nextest: | |
name: nextest | |
runs-on: ubicloud-standard-16 | |
timeout-minutes: 60 | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: rui314/setup-mold@v1 | |
- name: Install Protoc | |
uses: arduino/setup-protoc@v2 | |
with: | |
version: "23.2" | |
repo-token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Toolchain | |
uses: dtolnay/[email protected] | |
- name: Rust Cache | |
uses: Swatinem/rust-cache@v2 | |
- name: Install cargo-risczero | |
uses: taiki-e/install-action@v2 | |
with: | |
tool: [email protected] | |
- name: Install risc0-zkvm toolchain | |
run: cargo risczero install --version r0.1.79.0-2 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# `cargo-nextest` is much faster than standard `cargo test`. | |
- uses: taiki-e/install-action@nextest | |
- name: Cache ethereum-tests | |
uses: actions/cache@v3 | |
with: | |
key: "eth-tests-1c23e3c" | |
path: crates/evm/ethereum-tests | |
- name: Run nextest | |
run: make test | |
env: | |
RUST_BACKTRACE: 1 | |
BONSAI_API_URL: ${{ secrets.BONSAI_API_URL }} # TODO: remove this once we don't use the client on tests | |
BONSAI_API_KEY: ${{ secrets.BONSAI_API_KEY }} # TODO: remove this once we don't use the client on tests | |
TEST_BITCOIN_DOCKER: 1 | |
SHORT_PREFIX: 1 | |
CITREA_E2E_TEST_BINARY: ${{ github.workspace }}/target/debug/citrea | |
system-contracts: | |
strategy: | |
fail-fast: true | |
name: Foundry project | |
runs-on: ubicloud-standard-2 | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
submodules: recursive | |
- name: Install Foundry | |
uses: foundry-rs/foundry-toolchain@v1 | |
with: | |
version: nightly | |
- name: Run Forge build | |
run: | | |
cd crates/evm/src/evm/system_contracts | |
forge --version | |
forge build --sizes | |
id: build | |
- name: Run Forge tests | |
run: | | |
cd crates/evm/src/evm/system_contracts | |
forge test -vvv | |
id: test | |
check_genesis_files: | |
strategy: | |
fail-fast: true | |
name: Check Genesis Files | |
runs-on: ubicloud-standard-2 | |
if: github.event.pull_request.draft == false | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
submodules: recursive | |
- name: Install Foundry | |
uses: foundry-rs/foundry-toolchain@v1 | |
with: | |
# https://github.com/foundry-rs/foundry/releases/tag/nightly-25f24e677a6a32a62512ad4f561995589ac2c7dc | |
# This is the latest version known to work for us | |
version: nightly-25f24e677a6a32a62512ad4f561995589ac2c7dc | |
- name: Set up Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: "3.x" | |
- name: Run check_genesis.sh | |
run: ./.github/scripts/check_genesis.sh | |
shell: bash | |
validate_and_check_DA_ID: | |
runs-on: ubicloud-standard-2 | |
needs: build | |
env: | |
EXPECTED_BITCOIN_DA_ID: ${{ vars.EXPECTED_BITCOIN_DA_ID }} | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
steps: | |
- name: Validate EXPECTED_BITCOIN_DA_ID format | |
run: | | |
echo "Raw EXPECTED_BITCOIN_DA_ID value:" | |
echo "$EXPECTED_BITCOIN_DA_ID" | |
echo "Length of EXPECTED_BITCOIN_DA_ID: ${#EXPECTED_BITCOIN_DA_ID}" | |
if [ -z "${EXPECTED_BITCOIN_DA_ID// }" ]; then | |
echo "Error: EXPECTED_BITCOIN_DA_ID is not set, empty, or contains only spaces" | |
exit 1 | |
fi | |
# Remove any trailing newline or carriage return | |
EXPECTED_BITCOIN_DA_ID=$(echo "$EXPECTED_BITCOIN_DA_ID" | tr -d '\n\r') | |
# Count commas and spaces | |
comma_count=$(echo "$EXPECTED_BITCOIN_DA_ID" | tr -cd ',' | wc -c) | |
space_count=$(echo "$EXPECTED_BITCOIN_DA_ID" | tr -cd ' ' | wc -c) | |
echo "Number of commas: $comma_count" | |
echo "Number of spaces: $space_count" | |
# Split the string into an array and trim each element | |
IFS=', ' read -ra raw_numbers <<< "$EXPECTED_BITCOIN_DA_ID" | |
numbers=() | |
for num in "${raw_numbers[@]}"; do | |
trimmed_num=$(echo "$num" | tr -d '[:space:]') # Remove all whitespace | |
numbers+=("$trimmed_num") | |
done | |
echo "Number of elements after splitting and trimming: ${#numbers[@]}" | |
# Check if there are exactly 8 numbers | |
if [ ${#numbers[@]} -ne 8 ]; then | |
echo "Error: EXPECTED_BITCOIN_DA_ID should contain exactly 8 numbers" | |
echo "Actual number of elements: ${#numbers[@]}" | |
exit 1 | |
fi | |
# Check if all numbers are valid u32 | |
for i in "${!numbers[@]}"; do | |
num=${numbers[$i]} | |
echo "Checking number $((i+1)): '$num'" | |
echo "Hex representation: $(echo -n "$num" | xxd -p)" | |
if ! [[ $num =~ ^[0-9]+$ ]]; then | |
echo "Error: '$num' is not composed of digits only" | |
exit 1 | |
fi | |
if [ $num -gt 4294967295 ]; then | |
echo "Error: '$num' is greater than 4294967295" | |
exit 1 | |
fi | |
done | |
# Reconstruct the trimmed DA_ID | |
trimmed_da_id=$(IFS=', '; echo "${numbers[*]}") | |
# Final check | |
if [ $comma_count -eq 7 ] && [ $space_count -eq 7 ] && [ ${#numbers[@]} -eq 8 ]; then | |
echo "EXPECTED_BITCOIN_DA_ID is valid:" | |
echo "- Contains 7 commas" | |
echo "- Contains 7 spaces" | |
echo "- Contains 8 valid u32 numbers" | |
echo "Original value: $EXPECTED_BITCOIN_DA_ID" | |
echo "Trimmed value: $trimmed_da_id" | |
else | |
echo "Error: EXPECTED_BITCOIN_DA_ID format is incorrect" | |
echo "- Comma count: $comma_count (should be 7)" | |
echo "- Space count: $space_count (should be 7)" | |
echo "- Number count: ${#numbers[@]} (should be 8)" | |
exit 1 | |
fi | |
- name: Download artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: citrea-build | |
path: target/release | |
- name: Check BITCOIN_DA_ID | |
id: check-id | |
run: | | |
RESULT=$(grep -R "BITCOIN_DA_ID" target/ || echo "Grep failed") | |
EXPECTED_BITCOIN_DA_ID=$(echo "${{ env.EXPECTED_BITCOIN_DA_ID }}" | tr -d '\n\r') | |
if echo "$RESULT" | grep -q "$EXPECTED_BITCOIN_DA_ID"; then | |
echo "Check passed successfully." | |
echo "Expected: BITCOIN_DA_ID ${{ env.EXPECTED_BITCOIN_DA_ID }} " | |
echo "Actual: $RESULT" | |
else | |
echo "Check failed. Expected: BITCOIN_DA_ID ${{ env.EXPECTED_BITCOIN_DA_ID }} " | |
echo "Actual: $RESULT" | |
exit 1 | |
fi |