diff --git a/README.md b/README.md index 35bc0c86..c43df154 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ We are currently experimenting with various proof systems and have handwritten g ### Install Dependencies -We use `just` as a task runner. Once installed, you can install the rest of the dependencies with: +We use [`just`](https://github.com/casey/just?tab=readme-ov-file#packages) as a task runner. Once installed, you can install the rest of the dependencies with: ```bash just install-deps diff --git a/ci/Dockerfile.bridge b/ci/Dockerfile.bridge index c7c1cbfb..60944d81 100644 --- a/ci/Dockerfile.bridge +++ b/ci/Dockerfile.bridge @@ -3,7 +3,7 @@ # A dockerfile for the celestia bridge node in DA layer # Based on: # https://github.com/celestiaorg/celestia-node/blob/main/Dockerfile -FROM docker.io/alpine:3.19.1 +FROM docker.io/alpine:3.21.0 ENV CELESTIA_HOME=/root diff --git a/ci/Dockerfile.lightnode b/ci/Dockerfile.lightnode index dac4537d..2f299c08 100644 --- a/ci/Dockerfile.lightnode +++ b/ci/Dockerfile.lightnode @@ -3,7 +3,7 @@ # A dockerfile for the celestia bridge node in DA layer # Based on: # https://github.com/celestiaorg/celestia-node/blob/main/Dockerfile -FROM docker.io/alpine:3.19.1 +FROM docker.io/alpine:3.21.0 ENV CELESTIA_HOME=/root diff --git a/ci/Dockerfile.validator b/ci/Dockerfile.validator index 68c5b8f2..b704c54e 100644 --- a/ci/Dockerfile.validator +++ b/ci/Dockerfile.validator @@ -3,7 +3,7 @@ # A dockerfile for the celestia validator in consensus layer # Based on: # https://github.com/celestiaorg/celestia-app/blob/main/Dockerfile -FROM docker.io/alpine:3.19.1 +FROM docker.io/alpine:3.21.0 ENV CELESTIA_HOME=/root diff --git a/ci/docker-compose.yml b/ci/docker-compose.yml index 6535ede6..be2599fd 100644 --- a/ci/docker-compose.yml +++ b/ci/docker-compose.yml @@ -23,7 +23,11 @@ services: # provide an id for the bridge node (default: 0) # each node should have a next natural number starting from 0 - NODE_ID=0 + # setting SKIP_AUTH to true disables the use of JWT for authentication - SKIP_AUTH=true + # this must match the service name in the docker-compose.yml file + # used for the trusted peers string for the light node + - CONTAINER_NAME=bridge-0 ports: - 26658:26658 volumes: @@ -42,6 +46,9 @@ services: - NODE_ID=1 # setting SKIP_AUTH to true disables the use of JWT for authentication - SKIP_AUTH=true + # this must match the service name in the docker-compose.yml file + # used for the trusted peers string for the light node + - CONTAINER_NAME=bridge-1 ports: - 36658:26658 volumes: @@ -55,34 +62,20 @@ services: context: . dockerfile: Dockerfile.lightnode environment: - # provide an id for the bridge node (default: 0) + # provide an id for the light node (default: 0) # each node should have a next natural number starting from 0 - NODE_ID=0 + # setting SKIP_AUTH to true disables the use of JWT for authentication - SKIP_AUTH=true + # depending on the number of bridge nodes, provide the count + # is used for the trusted peers string for the light node + - BRIDGE_COUNT=2 ports: - 46658:26658 volumes: - credentials:/credentials - genesis:/genesis - # Uncomment for another bridge node - # remember to adjust services.validator.command - # bridge-1: - # image: bridge - # platform: "linux/amd64" - # build: - # context: . - # dockerfile: Dockerfile.bridge - # environment: - # # provide an id for the bridge node (default: 0) - # # each node should have a next natural number starting from 0 - # - NODE_ID=1 - # ports: - # - 36658:26658 - # volumes: - # - credentials:/credentials - # - genesis:/genesis - volumes: # local volume where node's credentials can persist credentials: diff --git a/ci/run-bridge.sh b/ci/run-bridge.sh index ba4e2830..471e2ac7 100755 --- a/ci/run-bridge.sh +++ b/ci/run-bridge.sh @@ -6,6 +6,7 @@ set -euo pipefail # Name for this node or `bridge-0` if not provided NODE_ID="${NODE_ID:-0}" SKIP_AUTH="${SKIP_AUTH:-false}" +CONTAINER_NAME="${CONTAINER_NAME:-bridge-$NODE_ID}" NODE_NAME="bridge-$NODE_ID" # a private local network P2P_NETWORK="private" @@ -19,6 +20,7 @@ NODE_JWT_FILE="$CREDENTIALS_DIR/$NODE_NAME.jwt" # directory where validator will write the genesis hash GENESIS_DIR="/genesis" GENESIS_HASH_FILE="$GENESIS_DIR/genesis_hash" +TRUSTED_PEERS_FILE="$GENESIS_DIR/trusted_peers" # Wait for the validator to set up and provision us via shared dir wait_for_provision() { @@ -53,6 +55,44 @@ write_jwt_token() { celestia bridge auth admin --p2p.network "$P2P_NETWORK" > "$NODE_JWT_FILE" } +append_trusted_peers() { + peer_id="" + start_time=$(date +%s) + timeout=30 + + while [[ -z "$peer_id" ]]; do + peer_id=$(celestia p2p info | jq -r '.result.id' || echo "") + if [[ -z "$peer_id" ]]; then + echo "Node is not running yet. Retrying..." + sleep 1 + fi + + current_time=$(date +%s) + elapsed=$((current_time - start_time)) + if [[ $elapsed -ge $timeout ]]; then + echo "Failed to retrieve Peer ID after $timeout seconds. Exiting." + exit 1 + fi + done + + #multiaddr: /dns/$CONTAINER_NAME/tcp/$RPC_PORT/p2p/$peer_id + multiaddr="/dns/$CONTAINER_NAME/tcp/2121/p2p/$peer_id" + echo "Appending trusted peer: $multiaddr" + + # Read existing peers into a variable + existing_peers="" + if [[ -s "$TRUSTED_PEERS_FILE" ]]; then + existing_peers=$(cat "$TRUSTED_PEERS_FILE") + fi + + # Append the new multiaddr to the existing peers + if [[ -n "$existing_peers" ]]; then + echo "$existing_peers,$multiaddr" > "$TRUSTED_PEERS_FILE" + else + echo "$multiaddr" > "$TRUSTED_PEERS_FILE" + fi +} + main() { # Initialize the bridge node celestia bridge init --p2p.network "$P2P_NETWORK" @@ -64,6 +104,8 @@ main() { add_trusted_genesis # Update the JWT token write_jwt_token + # Append the peer multiaddr to the trusted peers (run in background, as the node needs to be running) + append_trusted_peers & # give validator some time to set up sleep 4 # Start the bridge node diff --git a/ci/run-lightnode.sh b/ci/run-lightnode.sh index 7cecacf1..655cd698 100755 --- a/ci/run-lightnode.sh +++ b/ci/run-lightnode.sh @@ -6,6 +6,7 @@ set -euo pipefail # Name for this node or `light-0` if not provided NODE_ID="${NODE_ID:-0}" SKIP_AUTH="${SKIP_AUTH:-false}" +BRIDGE_COUNT="${BRIDGE_COUNT}" NODE_NAME="light-$NODE_ID" # a private local network P2P_NETWORK="private" @@ -19,6 +20,7 @@ NODE_JWT_FILE="$CREDENTIALS_DIR/$NODE_NAME.jwt" # directory where validator will write the genesis hash GENESIS_DIR="/genesis" GENESIS_HASH_FILE="$GENESIS_DIR/genesis_hash" +TRUSTED_PEERS_FILE="$GENESIS_DIR/trusted_peers" # Wait for the validator to set up and provision us via shared dir wait_for_provision() { @@ -26,8 +28,35 @@ wait_for_provision() { while [[ ! ( -e "$GENESIS_HASH_FILE" && -e "$NODE_KEY_FILE" ) ]]; do sleep 0.1 done - echo "Validator is ready" + + echo "Waiting for $BRIDGE_COUNT bridge nodes to start" + start_time=$(date +%s) + timeout=30 + + while true; do + if [[ -e "$TRUSTED_PEERS_FILE" ]]; then + trusted_peers="$(cat "$TRUSTED_PEERS_FILE")" + comma_count=$(echo "$trusted_peers" | grep -o "," | wc -l) + if [[ $comma_count -eq $((BRIDGE_COUNT - 1)) ]]; then + echo "$BRIDGE_COUNT bridge nodes are ready" + break + else + echo "Trusted peers file does not contain the expected number of commas. Retrying..." + fi + else + echo "Trusted peers file does not exist yet. Retrying..." + fi + + current_time=$(date +%s) + elapsed=$((current_time - start_time)) + if [[ $elapsed -ge $timeout ]]; then + echo "Timeout reached. Exiting." + exit 1 + fi + + sleep 1 + done } # Import the test account key shared by the validator @@ -43,11 +72,19 @@ add_trusted_genesis() { # Read the hash of the genesis block genesis_hash="$(cat "$GENESIS_HASH_FILE")" + trusted_peers="$(cat "$TRUSTED_PEERS_FILE")" # and make it trusted in the node's config echo "Trusting a genesis: $genesis_hash" sed -i'.bak' "s/TrustedHash = .*/TrustedHash = $genesis_hash/" "$CONFIG_DIR/config.toml" } +add_trusted_peers() { + local trusted_peers="$(cat "$TRUSTED_PEERS_FILE")" + local formatted_peers=$(echo "$trusted_peers" | sed 's/\([^,]*\)/"\1"/g') + echo "Trusting peers: $formatted_peers" + sed -i'.bak' "s|TrustedPeers = .*|TrustedPeers = [$formatted_peers]|" "$CONFIG_DIR/config.toml" +} + write_jwt_token() { echo "Saving jwt token to $NODE_JWT_FILE" celestia light auth admin --p2p.network "$P2P_NETWORK" > "$NODE_JWT_FILE" @@ -62,6 +99,8 @@ main() { import_shared_key # Trust the private blockchain add_trusted_genesis + # Trust the bridge nodes + add_trusted_peers # Update the JWT token write_jwt_token # give validator some time to set up diff --git a/crates/tests/src/lib.rs b/crates/tests/src/lib.rs index 555e7bc0..81aeb5e6 100644 --- a/crates/tests/src/lib.rs +++ b/crates/tests/src/lib.rs @@ -34,11 +34,11 @@ async fn test_light_client_prover_talking() -> Result<()> { pretty_env_logger::init(); let bridge_cfg = CelestiaConfig { - connection_string: "ws://0.0.0.0:36658".to_string(), + connection_string: "ws://localhost:36658".to_string(), ..CelestiaConfig::default() }; let lc_cfg = CelestiaConfig { - connection_string: "ws://0.0.0.0:26658".to_string(), + connection_string: "ws://localhost:46658".to_string(), ..CelestiaConfig::default() }; diff --git a/elf/riscv32im-succinct-zkvm-elf b/elf/riscv32im-succinct-zkvm-elf index c3d1060a..ccb2b931 100755 Binary files a/elf/riscv32im-succinct-zkvm-elf and b/elf/riscv32im-succinct-zkvm-elf differ diff --git a/justfile b/justfile index 322cc7ce..6d5dfdc8 100644 --- a/justfile +++ b/justfile @@ -8,6 +8,9 @@ celestia-up: echo "Cleaning up any existing Docker resources..." docker-compose -f {{DOCKER_COMPOSE_FILE}} down -v --remove-orphans + echo "Building Docker images..." + docker-compose -f {{DOCKER_COMPOSE_FILE}} build + echo "Spinning up a fresh Docker Compose stack..." docker-compose -f {{DOCKER_COMPOSE_FILE}} up -d --force-recreate --renew-anon-volumes @@ -65,7 +68,9 @@ integration-test: just celestia-up echo "Running integration tests..." - cargo test -p prism-tests --lib --release --features mock_prover + if ! cargo test -p prism-tests --lib --release --features mock_prover; then + echo "Integration tests failed." + fi just celestia-down @@ -86,10 +91,19 @@ unit-test: cargo test --lib --release --features "mock_prover" -- --skip test_light_client_prover_talking coverage: - @echo "Generating coverage report..." - cargo llvm-cov nextest --html --output-dir coverage_report --lib --features "mock_prover" --release --workspace --exclude prism-cli --exclude-from-report prism-sp1 --ignore-filename-regex sp1 - @echo "Coverage report generated in 'coverage_report' directory" + #!/usr/bin/env bash + set -euo pipefail + just celestia-up + + echo "Generating coverage report..." + if ! cargo llvm-cov nextest --html --output-dir coverage_report --lib --features "mock_prover" --release --workspace --exclude prism-cli --exclude-from-report prism-sp1 --ignore-filename-regex sp1; then + echo "Coverage report generation failed." + else + echo "Coverage report generated in 'coverage_report' directory" + fi + + just celestia-down install-deps: #!/usr/bin/env bash @@ -139,13 +153,11 @@ install-deps: echo "Protobuf is already installed."; \ fi - if ! command -v cargo prove > /dev/null; then \ echo "Installing SP1..." curl -L https://sp1.succinct.xyz | bash; \ source ~/.bashrc || source ~/.bash_profile || source ~/.zshrc; \ - echo "Running sp1up to install SP1 toolchain..." sp1up @@ -159,4 +171,13 @@ install-deps: echo "SP1 is already installed."; \ fi + for tool in cargo-udeps cargo-llvm-cov cargo-nextest; do \ + if ! command -v $tool > /dev/null; then \ + echo "Installing $tool..."; \ + cargo install $tool; \ + else \ + echo "$tool is already installed."; \ + fi; \ + done + echo "All dependencies installed successfully!"