diff --git a/README.md b/README.md index ab0bb085..1043a782 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The Madara orchestrator is designed to be an additional service which runs in parallel to Madara and handles various critical jobs that ensure proper block processing, proof generation, data submission and state transitions. -> šŸ“ **Note**: These instructions are verified for Ubuntu systems. While most steps remain similar +> šŸ“ **Note**: These instructions are verified for Ubuntu systems with AMD64 architecture. While most steps remain similar > for macOS, some package names and installation commands may differ. ## Table of Contents @@ -129,15 +129,19 @@ The system uses dedicated queues for managing different job phases: - SNS for alerts - EventBridge for scheduling -> šŸšØ **Important Note**: Currently, Madara doesn't support the `get_storage_proof` endpoint. +> šŸšØ **Important Note**: SNOS requires the `get_storage_proof` RPC endpoint to function. +> Currently, this endpoint is not implemented in Madara. > -> Therefore, you need to run Pathfinder alongside Madara: +> šŸš§ Until madara implements the `get_storage_proof` endpoint, you need to run Pathfinder alongside Madara: > > - Madara will run in sequencer mode > - Pathfinder will sync with Madara > - The orchestrator will use Pathfinder's RPC URL for SNOS and state update fetching > -> This setup ensures proper functionality until the `get_storage_proof` endpoint is implemented in Madara. +> This setup is temporary until either: +> +> 1. SNOS is adapted to work without the `get_storage_proof` endpoint, or +> 2. The `get_storage_proof` endpoint is implemented in Madara ## šŸš€ Installation & Setup @@ -212,41 +216,89 @@ The system uses dedicated queues for managing different job phases: 4. **Setup Mock Proving Service** + šŸš§ This setup is for development purposes only: + ```bash - # Create a simple HTTP server that always returns 200 - # Example using Python - python3 -m http.server 8888 & + # Start the mock prover service using Docker + docker run -d -p 6000:6000 ocdbytes/mock-prover:latest # Set the mock prover URL in your .env - MADARA_ORCHESTRATOR_ATLANTIC_SERVICE_URL=http://localhost:8888 + MADARA_ORCHESTRATOR_SHARP_URL=http://localhost:6000 ``` -5. **Deploy Mock Verifier Contract** +5. **Run Pathfinder** (Choose one method) - You can deploy the mock verifier contract in two ways: + > šŸšØ **Important Note**: + > + > - Pathfinder requires a WebSocket Ethereum endpoint (`ethereum.url`). Since Anvil doesn't support WebSocket yet, + > you'll need to provide a different Ethereum endpoint (e.g., Alchemy, Infura). This is okay for local development + > as Pathfinder only uses this for block header verification. + > - Make sure `chain-id` matches your Madara chain ID (default: `MADARA_DEVNET`) + > - The `gateway-url` and `feeder-gateway-url` should point to your local Madara node (default: `http://localhost:8080`) - a. **Using Test Implementation** + a. **From Source** (Recommended for development) - - Reference the implementation in `e2e-tests/tests.rs` which contains `AnvilSetup` - - This handles the deployment of both the StarkNet core contract and verifier contract + ```bash + # Clone the repository + git clone https://github.com/eqlabs/pathfinder.git + cd pathfinder + + # Run pathfinder + cargo run --bin pathfinder -- \ + --network custom \ + --chain-id MADARA_DEVNET \ + --ethereum.url wss://eth-sepolia.g.alchemy.com/v2/xxx \ # Replace with your Ethereum endpoint + --gateway-url http://localhost:8080/gateway \ + --feeder-gateway-url http://localhost:8080/feeder_gateway \ + --storage.state-tries archive \ + --data-directory ~/Desktop/pathfinder_db/ \ + --http-rpc 127.0.0.1:9545 + ``` - ```rust - // From e2e-tests/tests.rs - let anvil_setup = AnvilSetup::new(); - let (starknet_core_contract_address, verifier_contract_address) = anvil_setup.deploy_contracts().await; + b. **Using Docker** + + ```bash + # Create data directory + mkdir -p ~/pathfinder_data + + # Run pathfinder container + docker run \ + --name pathfinder \ + --restart unless-stopped \ + -p 9545:9545 \ + --user "$(id -u):$(id -g)" \ + -e RUST_LOG=info \ + -v ~/pathfinder_data:/usr/share/pathfinder/data \ + eqlabs/pathfinder \ + --network custom \ + --chain-id MADARA_DEVNET \ + --ethereum.url wss://eth-sepolia.g.alchemy.com/v2/xxx \ # Replace with your Ethereum endpoint + --gateway-url http://localhost:8080/gateway \ + --feeder-gateway-url http://localhost:8080/feeder_gateway \ + --storage.state-tries archive ``` - b. **Manual Deployment** +6. **Deploy Mock Verifier Contract** - - Alternatively, you can deploy the mock verifier directly using Foundry - - The contract should implement the same interface as used in the tests - - Set the deployed address in your environment: + šŸš§ For development purposes, you can deploy the mock verifier contract using: ```bash - MADARA_ORCHESTRATOR_VERIFIER_ADDRESS= + ./scripts/dummy_contract_deployment.sh http://localhost:9944 0 ``` -Note: The mock services are intended for development and testing purposes only. + This script: + + - Takes the Madara endpoint and block number as parameters + - Automatically deploys both the verifier contract and core contract + - Sets up the necessary contract relationships + - The deployed contract addresses will be output to the console + + ```bash + MADARA_ORCHESTRATOR_L1_CORE_CONTRACT_ADDRESS= + MADARA_ORCHESTRATOR_VERIFIER_ADDRESS= + ``` + +šŸš§ Note: The mock services are intended for development and testing purposes only. In production, you'll need to use actual proving services and verifier contracts. ### Setup Mode @@ -267,7 +319,7 @@ Run mode executes the orchestrator's job processing workflow. Example command: ```bash RUST_LOG=info cargo run --release --bin orchestrator run \ - --atlantic \ + --sharp \ --aws \ --settle-on-ethereum \ --aws-s3 \ @@ -381,6 +433,8 @@ It requires a `Otel-collector` url to be able to send metrics/logs/traces. ### Local Environment Setup +šŸš§ This setup is for development purposes. For production deployment, please refer to our deployment documentation. + Before running tests, ensure you have: 1. **Required Services Running**: @@ -401,6 +455,8 @@ Before running tests, ensure you have: 1. **E2E Tests** šŸ”„ + šŸš§ Development test environment: + - End-to-end workflow testing - Tests orchestrator functionality on block 66645 of Starknet - Uses mocked proving endpoints diff --git a/scripts/artifacts/eth/MockGPSVerifier.sol b/scripts/artifacts/eth/MockGPSVerifier.sol new file mode 100644 index 00000000..a5ddb007 --- /dev/null +++ b/scripts/artifacts/eth/MockGPSVerifier.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract MockGPSVerifier { + // Returns true for any input fact hash + function isValid(bytes32) public pure returns (bool) { + return true; + } +} \ No newline at end of file diff --git a/scripts/dummy_contract_deployment.sh b/scripts/dummy_contract_deployment.sh new file mode 100755 index 00000000..2e3162f6 --- /dev/null +++ b/scripts/dummy_contract_deployment.sh @@ -0,0 +1,150 @@ +#!/bin/bash + +# Check if jq is installed +if ! command -v jq &> /dev/null; then + echo "Error: jq is required but not installed. Please install jq first." + exit 1 +fi + +# Check if curl is installed +if ! command -v curl &> /dev/null; then + echo "Error: curl is required but not installed. Please install curl first." + exit 1 +fi + +# Check if required arguments are provided +if [ -z "$1" ] || [ -z "$2" ]; then + echo "Usage: $0 " + echo "Example: $0 http://localhost:9944 66644" + exit 1 +fi + +# Read arguments +ABI_FILE='./e2e-tests/artifacts/contracts/Starknet.json' +RPC_URL=$1 +BLOCK_NUMBER=$2 + +# Default Anvil private key +PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" +ANVIL_URL="http://localhost:8545" + +echo -e "\nšŸ” Fetching state update for block $BLOCK_NUMBER..." + +# Fetch state update from RPC with correct params structure +STATE_UPDATE=$(curl -s -X POST -H "Content-Type: application/json" --data "{ + \"jsonrpc\":\"2.0\", + \"method\":\"starknet_getStateUpdate\", + \"params\": { + \"block_id\": { + \"block_number\": $BLOCK_NUMBER + } + }, + \"id\":1 +}" "$RPC_URL") + +# Extract global root and block hash from the response +GLOBAL_ROOT=$(echo "$STATE_UPDATE" | jq -r '.result.new_root') +BLOCK_HASH=$(echo "$STATE_UPDATE" | jq -r '.result.block_hash') + +if [ "$GLOBAL_ROOT" == "null" ] || [ "$BLOCK_HASH" == "null" ]; then + echo "Error: Failed to fetch state update data" + echo "Response: $STATE_UPDATE" + exit 1 +fi + +echo -e "\nšŸ“Š State Update Data:" +echo " Global Root: $GLOBAL_ROOT" +echo " Block Hash: $BLOCK_HASH" +echo "" + +# Deploy the verifier contract using forge create +echo -e "šŸš€ Deploying verifier contract...\n" +VERIFIER_RESULT=$(forge create \ + --rpc-url "$ANVIL_URL" \ + --private-key "$PRIVATE_KEY" \ + "scripts/artifacts/eth/MockGPSVerifier.sol:MockGPSVerifier" \ + 2>&1) + +if [ $? -ne 0 ]; then + echo "Error deploying verifier contract:" + echo "$VERIFIER_RESULT" + exit 1 +fi + +# Extract contract address from forge create output +VERIFIER_ADDRESS=$(echo "$VERIFIER_RESULT" | grep "Deployed to" | awk '{print $3}') +echo -e "šŸ“¦ Verifier deployed at: $VERIFIER_ADDRESS\n" + +# Now deploy the main Starknet contract +echo -e "šŸš€ Deploying Starknet contract...\n" + +# Extract bytecode from the JSON file +BYTECODE=$(jq -r '.bytecode.object' "$ABI_FILE" | sed 's/^0x//') + +if [ "$BYTECODE" == "null" ] || [ -z "$BYTECODE" ]; then + echo "Error: No bytecode found in the JSON file" + exit 1 +fi + +# Deploy the contract using cast +RESULT=$(cast send \ + --private-key "$PRIVATE_KEY" \ + --rpc-url "$ANVIL_URL" \ + --create "0x$BYTECODE" \ + 2>&1) + +# Check if deployment was successful +if [ $? -eq 0 ]; then + # Extract contract address from the result using grep and awk + CONTRACT_ADDRESS=$(echo "$RESULT" | grep "contractAddress" | awk '{print $2}') + + if [ -n "$CONTRACT_ADDRESS" ]; then + echo -e "šŸ“¦ Starknet contract deployed successfully at: $CONTRACT_ADDRESS\n" + + # sleep for 2 seconds + sleep 2 + + # Initialize the contract with the required data + echo -e "šŸ”§ Initializing contract...\n" + + # Create the initialization data + PROGRAM_HASH="853638403225561750106379562222782223909906501242604214771127703946595519856" + AGGREGATOR_PROGRAM_HASH="0" + CONFIG_HASH="1773546093672122186726825451867439478968296982619761985456743675021283370179" + + # Encode the initialization data + INIT_DATA=$(cast abi-encode "f(uint256,uint256,address,uint256,uint256,int256,uint256)" \ + $PROGRAM_HASH \ + $AGGREGATOR_PROGRAM_HASH \ + $VERIFIER_ADDRESS \ + $CONFIG_HASH \ + $GLOBAL_ROOT \ + $BLOCK_NUMBER \ + $BLOCK_HASH) + + # Call initializeContractState + INIT_RESULT=$(cast send \ + --private-key "$PRIVATE_KEY" \ + --rpc-url "$ANVIL_URL" \ + $CONTRACT_ADDRESS \ + "initializeContractState(bytes)" \ + $INIT_DATA) + + if [ $? -eq 0 ]; then + TX_HASH=$(echo "$INIT_RESULT" | grep "transactionHash" | awk '{print $2}') + echo -e "āœ… Contract initialized successfully!" + echo -e " Transaction: $TX_HASH\n" + else + echo -e "āŒ Error initializing contract\n" + echo "$INIT_RESULT" + exit 1 + fi + else + echo "āŒ Error: Could not extract contract address from output" + exit 1 + fi +else + echo "āŒ Error deploying contract:" + echo "$RESULT" + exit 1 +fi \ No newline at end of file