From 367faedebaff18b84fbe2fd96faf91a9686e7e0c Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 8 Oct 2025 16:35:30 +0200 Subject: [PATCH 01/12] Website/doc: rename documentation guidelines into ref code in doc --- ...guidelines.md => referencing-code-in-documentation.md} | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) rename website/docs/developers/{documentation-guidelines.md => referencing-code-in-documentation.md} (96%) diff --git a/website/docs/developers/documentation-guidelines.md b/website/docs/developers/referencing-code-in-documentation.md similarity index 96% rename from website/docs/developers/documentation-guidelines.md rename to website/docs/developers/referencing-code-in-documentation.md index e6d74a625..e525c55a1 100644 --- a/website/docs/developers/documentation-guidelines.md +++ b/website/docs/developers/referencing-code-in-documentation.md @@ -1,11 +1,11 @@ --- sidebar_position: 10 -title: Documentation Guidelines +title: Referencing code in documentation description: Best practices for writing and maintaining documentation -slug: /developers/documentation-guidelines +slug: /developers/referencing-code-in-documentation --- -# Documentation Guidelines +# Referencing code in documentation This guide explains how to write and maintain documentation for the Mina Rust project, including how to reference code from the codebase. Referencing code @@ -13,8 +13,6 @@ from codebases can be useful to check compatibility between implementations. For instance, we can have pages where the Rust code is compared to the OCaml code to discuss the differences or similarities. -## Referencing Code in Documentation - To keep documentation synchronized with the actual codebase, we use the [`docusaurus-theme-github-codeblock`](https://github.com/christian-bromann/docusaurus-theme-github-codeblock) plugin that automatically fetches code from GitHub. From ce570472ac8c68c1e3218086b394d04da36d6d01 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 8 Oct 2025 16:36:15 +0200 Subject: [PATCH 02/12] CLAUDE: add instructions to check OCaml refs --- CLAUDE.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 0b59440f8..f8644f217 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -162,6 +162,40 @@ The website is available at http://localhost:3000 when running locally. The website supports versioning and will be automatically deployed when commits are made to `develop` or when tags are created. +### OCaml Reference Tracking + +The Rust codebase maintains references to the corresponding OCaml implementation +to track correspondence and detect when updates are needed. + +**Comment format:** + +```rust +/// OCaml reference: src/lib/mina_base/transaction_status.ml L:9-113 +/// Commit: 55582d249cdb225f722dbbb3b1420ce7570d501f +/// Last verified: 2025-10-08 +pub enum TransactionFailure { + // ... +} +``` + +**Validation:** + +```bash +# Check all OCaml references +./.github/scripts/check-ocaml-refs.sh + +# Update stale commit hashes +./.github/scripts/check-ocaml-refs.sh --update + +# Check against specific branch +./.github/scripts/check-ocaml-refs.sh --branch develop +``` + +The validation script verifies that referenced OCaml files exist, line ranges +are valid, code at the referenced commit matches the current branch, and tracks +commit staleness. A GitHub Actions workflow runs weekly to automatically update +references and create PRs. + ## Additional Resources - `docs/handover/` - Comprehensive architecture documentation From cb63e46d648f82e8dda4cf515e041248e8f2cef1 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 8 Oct 2025 16:51:39 +0200 Subject: [PATCH 03/12] transaction_logic: add new format for checking OCaml references The script will also fail for now. The update script will be tested in a PR. --- ledger/src/scan_state/transaction_logic/mod.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ledger/src/scan_state/transaction_logic/mod.rs b/ledger/src/scan_state/transaction_logic/mod.rs index 7d486d3ca..95f9fff7c 100644 --- a/ledger/src/scan_state/transaction_logic/mod.rs +++ b/ledger/src/scan_state/transaction_logic/mod.rs @@ -60,7 +60,9 @@ pub use transaction_union_payload::{ ExistingOrNew, Tag, TimingValidation, TransactionUnion, TransactionUnionPayload, }; -/// +/// OCaml reference: src/lib/mina_base/transaction_status.ml L:9-51 +/// Commit: 2ee6e004ba8c6a0541056076aab22ea162f7eb3a +/// Last verified: 2025-10-08 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] pub enum TransactionFailure { Predicate, @@ -176,7 +178,9 @@ impl Display for TransactionFailure { } } -/// +/// OCaml reference: src/lib/mina_base/transaction_status.ml L:452-454 +/// Commit: 2ee6e004ba8c6a0541056076aab22ea162f7eb3a +/// Last verified: 2025-10-08 #[derive(SerdeYojsonEnum, Debug, Clone, PartialEq, Eq)] pub enum TransactionStatus { Applied, @@ -192,7 +196,9 @@ impl TransactionStatus { } } -/// +/// OCaml reference: src/lib/mina_base/with_status.ml L:6-10 +/// Commit: 2ee6e004ba8c6a0541056076aab22ea162f7eb3a +/// Last verified: 2025-10-08 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)] pub struct WithStatus { pub data: T, From e23c575c75034cb55b30b2367c6339d15eb67013 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 8 Oct 2025 16:52:24 +0200 Subject: [PATCH 04/12] Website: add documentation to reference OCaml code --- .../developers/ocaml-reference-tracking.md | 135 ++++++++++++++++++ website/sidebars.ts | 3 +- 2 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 website/docs/developers/ocaml-reference-tracking.md diff --git a/website/docs/developers/ocaml-reference-tracking.md b/website/docs/developers/ocaml-reference-tracking.md new file mode 100644 index 000000000..8fd9612d6 --- /dev/null +++ b/website/docs/developers/ocaml-reference-tracking.md @@ -0,0 +1,135 @@ +--- +sidebar_position: 11 +title: OCaml reference tracking +description: + System for tracking correspondence between Rust and OCaml implementations +slug: /developers/ocaml-reference-tracking +--- + +# OCaml reference tracking + +This document describes the system for tracking correspondence between Rust code +in this repository and the original OCaml implementation in the +[Mina Protocol repository](https://github.com/MinaProtocol/mina). + +## Overview + +As mina-rust is a reimplementation of the Mina OCaml client, we maintain inline +comments that reference the corresponding OCaml code. This helps developers: + +1. Understand the original implementation context +2. Verify that the Rust implementation matches the OCaml behavior +3. Track changes in the OCaml codebase that may require updates in Rust + +## Comment format + +OCaml references are added as doc comments directly above the Rust type or +function: + +```rust +/// OCaml reference: src/lib/mina_base/transaction_status.ml L:9-113 +/// Commit: 55582d249cdb225f722dbbb3b1420ce7570d501f +/// Last verified: 2025-10-08 +pub enum TransactionFailure { + // ... +} +``` + +### Format specification + +- **Line 1**: `/// OCaml reference: L:-` + - ``: Path to the OCaml file relative to the Mina repository root + - `L:-`: Line range in the OCaml file (optional but recommended) +- **Line 2**: `/// Commit: ` + - Full commit hash from the Mina repository +- **Line 3**: `/// Last verified: ` + - Date when the reference was last verified to be accurate + +## Validation script + +The `.github/scripts/check-ocaml-refs.sh` script validates all OCaml references: + +```bash +# Validate against compatible branch (default) +./.github/scripts/check-ocaml-refs.sh + +# Validate against a specific branch +./.github/scripts/check-ocaml-refs.sh --branch develop + +# Validate against a specific repository +./.github/scripts/check-ocaml-refs.sh --repo https://github.com/MinaProtocol/mina.git --branch develop + +# Automatically update stale commit hashes +./.github/scripts/check-ocaml-refs.sh --update +``` + +### What the script checks + +1. **File existence**: Verifies the OCaml file exists at the specified path +2. **Line ranges**: Validates that line ranges don't exceed the file length +3. **Code consistency**: Verifies that the code at the referenced commit matches + the code on the current branch (ensures the reference is still accurate) +4. **Commit staleness**: Checks if the commit hash matches the current HEAD + +### Exit codes + +- `0`: All references are valid or only stale commits (warning) +- `1`: Invalid references found (missing files or invalid line ranges) + +## Automated verification + +A GitHub Actions workflow runs weekly to: + +1. Validate all OCaml references against the latest `compatible` branch +2. Automatically update stale commit hashes and verification dates +3. Create a pull request with the updates + +The workflow can also be triggered manually via the Actions tab. + +## Adding new references + +When implementing new features from the OCaml codebase: + +1. Add the OCaml reference comment above your Rust type/function +2. Use the current commit hash from the Mina repository +3. Set the verification date to today +4. Include line ranges to make it easy to find the exact code + +Example: + +```rust +/// OCaml reference: src/lib/mina_base/fee_transfer.ml L:19-45 +/// Commit: 55582d249cdb225f722dbbb3b1420ce7570d501f +/// Last verified: 2025-10-08 +#[derive(Debug, Clone, PartialEq)] +pub struct SingleFeeTransfer { + pub receiver_pk: CompressedPubKey, + pub fee: Fee, + pub fee_token: TokenId, +} +``` + +## Finding the correct line range + +To find the line range for an OCaml reference: + +1. Navigate to the file in the Mina repository +2. Find the relevant type or function definition +3. Note the starting and ending line numbers +4. Use format `L:-` + +For single-line references, use the same number: `L:42-42` + +## Best practices + +1. **Be specific**: Include line ranges to point to exact definitions +2. **Verify regularly**: Run the validation script before committing +3. **Update when needed**: If you update Rust code based on OCaml changes, + update the commit hash and date +4. **Document differences**: If the Rust implementation intentionally differs, + add a note explaining why + +## Example references + +See `ledger/src/scan_state/transaction_logic/mod.rs` for examples of properly +formatted OCaml references. diff --git a/website/sidebars.ts b/website/sidebars.ts index 962b0621d..2b2411cd4 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -137,7 +137,8 @@ const sidebars: SidebarsConfig = { type: 'category', label: 'Documentation', items: [ - 'developers/documentation-guidelines', + 'developers/referencing-code-in-documentation', + 'developers/ocaml-reference-tracking', ], }, { From e229f4959b5f6fdc7e92ada5595eb82b294befe1 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 8 Oct 2025 16:54:19 +0200 Subject: [PATCH 05/12] ocaml-ref-check: add script and CI --- .github/scripts/check-ocaml-refs.sh | 241 ++++++++++++++++++++++++ .github/workflows/check-ocaml-refs.yaml | 125 ++++++++++++ 2 files changed, 366 insertions(+) create mode 100755 .github/scripts/check-ocaml-refs.sh create mode 100644 .github/workflows/check-ocaml-refs.yaml diff --git a/.github/scripts/check-ocaml-refs.sh b/.github/scripts/check-ocaml-refs.sh new file mode 100755 index 000000000..e6167c248 --- /dev/null +++ b/.github/scripts/check-ocaml-refs.sh @@ -0,0 +1,241 @@ +#!/usr/bin/env bash +# Script to validate OCaml reference comments in Rust code +# Usage: ./.github/scripts/check-ocaml-refs.sh [--repo REPO_URL] [--branch BRANCH] [--update] + +set -euo pipefail + +# Default configuration +OCAML_REPO="${OCAML_REPO:-https://github.com/MinaProtocol/mina.git}" +OCAML_BRANCH="${OCAML_BRANCH:-compatible}" +UPDATE_MODE="${UPDATE_MODE:-false}" +RUST_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + --repo) + OCAML_REPO="$2" + shift 2 + ;; + --branch) + OCAML_BRANCH="$2" + shift 2 + ;; + --update) + UPDATE_MODE="true" + shift + ;; + *) + echo "Unknown option: $1" + echo "Usage: ./.github/scripts/check-ocaml-refs.sh [--repo REPO_URL] [--branch BRANCH] [--update]" + exit 1 + ;; + esac +done + +echo "Checking OCaml references against ${OCAML_REPO} (branch: ${OCAML_BRANCH})" + +# Create temporary directory +TEMP_DIR=$(mktemp -d) +trap 'rm -rf "$TEMP_DIR"' EXIT + +# Extract GitHub owner and repo from URL (e.g., https://github.com/MinaProtocol/mina.git) +GITHUB_URL_PATTERN="https://github.com/([^/]+)/(.+)" +if [[ "$OCAML_REPO" =~ $GITHUB_URL_PATTERN ]]; then + GITHUB_OWNER="${BASH_REMATCH[1]}" + GITHUB_REPO="${BASH_REMATCH[2]%.git}" # Remove .git suffix if present +else + echo "Error: Repository URL must be a GitHub URL" + exit 1 +fi + +# Get current commit hash for the branch using GitHub API +echo "Fetching current commit from ${OCAML_BRANCH}..." +CURRENT_COMMIT=$(curl -s "https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/commits/${OCAML_BRANCH}" | grep -o '"sha": "[^"]*"' | head -1 | cut -d'"' -f4) + +if [ -z "$CURRENT_COMMIT" ]; then + echo "Error: Could not fetch current commit for branch ${OCAML_BRANCH}" + exit 1 +fi + +echo "Current OCaml commit: ${CURRENT_COMMIT}" + +# Find all Rust files with OCaml references +cd "${RUST_ROOT}" +RUST_FILES=$(rg -l "^/// OCaml reference:" --type rust || true) + +if [ -z "$RUST_FILES" ]; then + echo "No OCaml references found in Rust code" + exit 0 +fi + +# Use temporary files to accumulate results +RESULTS_FILE="${TEMP_DIR}/results.txt" +touch "$RESULTS_FILE" + +echo "" +echo "Validating references..." +echo "========================" + +# Process each file +echo "$RUST_FILES" | while IFS= read -r rust_file; do + # Extract OCaml reference comments from the file + awk ' + /^\/\/\/ OCaml reference:/ { + ref = $0 + getline + if ($0 ~ /^\/\/\/ Commit:/) { + commit = $0 + getline + if ($0 ~ /^\/\/\/ Last verified:/) { + verified = $0 + print ref + print commit + print verified + print "---" + } + } + } + ' "$rust_file" | while IFS= read -r line; do + if [[ "$line" == "/// OCaml reference:"* ]]; then + # Extract file path and line range + # Format: src/lib/mina_base/transaction_status.ml L:9-113 + FULL_REF="${line#/// OCaml reference: }" + OCAML_PATH="${FULL_REF%% L:*}" + LINE_RANGE=$(echo "$FULL_REF" | grep -o 'L:[0-9-]*' | sed 's/L://' || echo "") + + # Read next two lines + read -r commit_line + read -r _verified_line + read -r _separator + + COMMIT="${commit_line#/// Commit: }" + # LAST_VERIFIED could be extracted from _verified_line if needed for future validation + + # Fetch the OCaml file from the current branch + CURRENT_FILE="${TEMP_DIR}/current_${rust_file//\//_}_${OCAML_PATH//\//_}" + CURRENT_URL="https://raw.githubusercontent.com/${GITHUB_OWNER}/${GITHUB_REPO}/${OCAML_BRANCH}/${OCAML_PATH}" + + if ! curl -sf "$CURRENT_URL" -o "$CURRENT_FILE"; then + echo "INVALID|${rust_file}|${OCAML_PATH}|FILE_NOT_FOUND" >> "$RESULTS_FILE" + echo "❌ INVALID: ${rust_file}" + echo " OCaml file not found: ${OCAML_PATH}" + else + # Validate line range if specified + RANGE_VALID=true + if [ -n "$LINE_RANGE" ]; then + FILE_LINES=$(wc -l < "$CURRENT_FILE") + # START_LINE is not currently used but could be useful for validation + # START_LINE=$(echo "$LINE_RANGE" | cut -d'-' -f1) + END_LINE=$(echo "$LINE_RANGE" | cut -d'-' -f2) + + if [ "$END_LINE" -gt "$FILE_LINES" ]; then + echo "INVALID|${rust_file}|${OCAML_PATH}|LINE_RANGE_EXCEEDED|L:${LINE_RANGE}|${FILE_LINES}" >> "$RESULTS_FILE" + echo "❌ INVALID: ${rust_file}" + echo " Line range L:${LINE_RANGE} exceeds file length (${FILE_LINES} lines): ${OCAML_PATH}" + RANGE_VALID=false + fi + fi + + if [ "$RANGE_VALID" = "true" ]; then + # Verify that the code at the referenced commit matches the current branch + CODE_MATCHES=true + if [ -n "$LINE_RANGE" ]; then + START_LINE=$(echo "$LINE_RANGE" | cut -d'-' -f1) + END_LINE=$(echo "$LINE_RANGE" | cut -d'-' -f2) + + # Fetch the file from the referenced commit + COMMIT_FILE="${TEMP_DIR}/commit_${rust_file//\//_}_${OCAML_PATH//\//_}" + COMMIT_URL="https://raw.githubusercontent.com/${GITHUB_OWNER}/${GITHUB_REPO}/${COMMIT}/${OCAML_PATH}" + + if ! curl -sf "$COMMIT_URL" -o "$COMMIT_FILE"; then + echo "INVALID|${rust_file}|${OCAML_PATH}|COMMIT_NOT_FOUND|${COMMIT}" >> "$RESULTS_FILE" + echo "❌ INVALID: ${rust_file}" + echo " Referenced commit does not exist: ${COMMIT}" + CODE_MATCHES=false + else + # Extract the specific line ranges from both files and compare + CURRENT_LINES=$(sed -n "${START_LINE},${END_LINE}p" "$CURRENT_FILE") + COMMIT_LINES=$(sed -n "${START_LINE},${END_LINE}p" "$COMMIT_FILE") + + if [ "$CURRENT_LINES" != "$COMMIT_LINES" ]; then + echo "INVALID|${rust_file}|${OCAML_PATH}|CODE_MISMATCH|${COMMIT}" >> "$RESULTS_FILE" + echo "❌ INVALID: ${rust_file}" + echo " Code at L:${LINE_RANGE} differs between commit ${COMMIT} and current branch" + echo " Referenced: https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}/blob/${COMMIT}/${OCAML_PATH}#L${START_LINE}-L${END_LINE}" + echo " Current: https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}/blob/${OCAML_BRANCH}/${OCAML_PATH}#L${START_LINE}-L${END_LINE}" + CODE_MATCHES=false + fi + fi + fi + + if [ "$CODE_MATCHES" = "true" ]; then + # Check if commit is stale + if [ "$COMMIT" != "$CURRENT_COMMIT" ]; then + echo "STALE|${rust_file}|${OCAML_PATH}|${COMMIT}|${LINE_RANGE}" >> "$RESULTS_FILE" + echo "✓ VALID: ${rust_file} -> ${OCAML_PATH} L:${LINE_RANGE}" + echo " ⚠ STALE COMMIT: ${COMMIT} (current: ${CURRENT_COMMIT})" + else + echo "VALID|${rust_file}|${OCAML_PATH}|${LINE_RANGE}" >> "$RESULTS_FILE" + echo "✓ VALID: ${rust_file} -> ${OCAML_PATH} L:${LINE_RANGE}" + fi + fi + fi + fi + fi + done +done + +# Count results +TOTAL_REFS=$(wc -l < "$RESULTS_FILE") +VALID_REFS=$(grep -c "^VALID|" "$RESULTS_FILE" || true) +INVALID_REFS=$(grep -c "^INVALID|" "$RESULTS_FILE" || true) +STALE_COMMITS=$(grep -c "^STALE|" "$RESULTS_FILE" || true) + +echo "" +echo "Summary" +echo "=======" +echo "Total references found: ${TOTAL_REFS}" +echo "Valid references: $((VALID_REFS + STALE_COMMITS))" +echo "Invalid references: ${INVALID_REFS}" +echo "Stale commits: ${STALE_COMMITS}" + +if [ "$UPDATE_MODE" = "true" ] && [ "${STALE_COMMITS}" -gt 0 ]; then + echo "" + echo "Updating stale commit hashes and verification dates..." + + CURRENT_DATE=$(date +%Y-%m-%d) + + # Update each file with stale commits + grep "^STALE|" "$RESULTS_FILE" | while IFS='|' read -r _status rust_file ocaml_path _old_commit _line_range; do + echo "Updating ${rust_file}..." + + # Find and replace the old commit with the new one + sed -i.bak \ + -e "/^\/\/\/ OCaml reference: ${ocaml_path//\//\\/}/,/^\/\/\/ Last verified:/ { + s/^\/\/\/ Commit: .*/\/\/\/ Commit: ${CURRENT_COMMIT}/ + s/^\/\/\/ Last verified: .*/\/\/\/ Last verified: ${CURRENT_DATE}/ + }" \ + "${RUST_ROOT}/${rust_file}" + rm -f "${RUST_ROOT}/${rust_file}.bak" + done + + echo "Updated ${STALE_COMMITS} reference(s)" +fi + +# Exit with error if there are invalid references +if [ "${INVALID_REFS}" -gt 0 ]; then + echo "" + echo "❌ Validation failed: ${INVALID_REFS} invalid reference(s) found" + exit 1 +fi + +if [ "${STALE_COMMITS}" -gt 0 ] && [ "$UPDATE_MODE" = "false" ]; then + echo "" + echo "⚠ Warning: ${STALE_COMMITS} reference(s) have stale commits" + echo "Run with --update to update them automatically" + exit 0 +fi + +echo "" +echo "✓ All OCaml references are valid!" diff --git a/.github/workflows/check-ocaml-refs.yaml b/.github/workflows/check-ocaml-refs.yaml new file mode 100644 index 000000000..ad2a4dcf7 --- /dev/null +++ b/.github/workflows/check-ocaml-refs.yaml @@ -0,0 +1,125 @@ +# Check OCaml References +# +# This workflow validates OCaml reference comments in the Rust codebase +# and automatically updates stale commit hashes. +# +# Run locally with: +# gh act schedule -W .github/workflows/check-ocaml-refs.yaml +# gh act workflow_dispatch -W .github/workflows/check-ocaml-refs.yaml +# gh act workflow_dispatch -W .github/workflows/check-ocaml-refs.yaml --input branch=develop + +name: Check OCaml References + +on: + schedule: + # Run every Monday at 9:00 AM UTC + - cron: '0 9 * * 1' + workflow_dispatch: + inputs: + repo: + description: 'OCaml repository URL' + required: false + default: 'https://github.com/MinaProtocol/mina.git' + branch: + description: 'OCaml repository branch' + required: false + default: 'compatible' + +permissions: + contents: write + pull-requests: write + +jobs: + check-refs: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Install ripgrep + run: sudo apt-get update && sudo apt-get install -y ripgrep + + - name: Run OCaml reference validation + id: check + env: + OCAML_REPO: ${{ github.event.inputs.repo || 'https://github.com/MinaProtocol/mina.git' }} + OCAML_BRANCH: ${{ github.event.inputs.branch || 'compatible' }} + run: | + set +e + ./.github/scripts/check-ocaml-refs.sh \ + --repo "$OCAML_REPO" \ + --branch "$OCAML_BRANCH" + exit_code=$? + if [ $exit_code -ne 0 ]; then + echo "has_issues=true" >> $GITHUB_OUTPUT + exit 0 + fi + + - name: Update references if stale + if: steps.check.outputs.has_issues != 'true' + env: + OCAML_REPO: ${{ github.event.inputs.repo || 'https://github.com/MinaProtocol/mina.git' }} + OCAML_BRANCH: ${{ github.event.inputs.branch || 'compatible' }} + run: | + ./.github/scripts/check-ocaml-refs.sh \ + --repo "$OCAML_REPO" \ + --branch "$OCAML_BRANCH" \ + --update + + - name: Check for changes + id: changes + run: | + if git diff --quiet; then + echo "has_changes=false" >> $GITHUB_OUTPUT + else + echo "has_changes=true" >> $GITHUB_OUTPUT + fi + + - name: Create Pull Request + if: steps.changes.outputs.has_changes == 'true' + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: | + Update OCaml reference verification dates + + Automated update of OCaml reference commit hashes and verification + dates based on latest compatible branch. + branch: update-ocaml-refs-${{ github.run_number }} + delete-branch: true + title: 'Update OCaml reference verification dates' + body: | + ## Automated OCaml Reference Update + + This PR updates the OCaml reference comments in the Rust codebase to + reflect the latest commit from the OCaml repository. + + ### Changes + - Updated commit hashes to match latest OCaml compatible branch + - Updated verification dates to today + + ### Validation + All OCaml file references have been validated to ensure they still + exist at the specified paths. + + **Repository**: ${{ github.event.inputs.repo || 'https://github.com/MinaProtocol/mina.git' }} + **Branch**: ${{ github.event.inputs.branch || 'compatible' }} + + This PR was automatically generated by the `check-ocaml-refs` + workflow. + labels: | + automation + documentation + + - name: Post summary + if: always() + run: | + echo "## OCaml Reference Validation Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + if [ "${{ steps.check.outputs.has_issues }}" == "true" ]; then + echo "❌ Validation failed - some OCaml references are invalid" >> $GITHUB_STEP_SUMMARY + elif [ "${{ steps.changes.outputs.has_changes }}" == "true" ]; then + echo "✓ Validation passed - created PR to update stale references" >> $GITHUB_STEP_SUMMARY + else + echo "✓ All references are up to date" >> $GITHUB_STEP_SUMMARY + fi From f57e0fb0ccdb51fb6f58795e2cf0f9c63327c9a9 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 9 Oct 2025 17:27:26 +0200 Subject: [PATCH 06/12] GH workflow: add step to post a comment on PR when failed --- .github/workflows/check-ocaml-refs.yaml | 66 +++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check-ocaml-refs.yaml b/.github/workflows/check-ocaml-refs.yaml index ad2a4dcf7..6a3fad764 100644 --- a/.github/workflows/check-ocaml-refs.yaml +++ b/.github/workflows/check-ocaml-refs.yaml @@ -11,6 +11,10 @@ name: Check OCaml References on: + pull_request: + branches: + - develop + - main schedule: # Run every Monday at 9:00 AM UTC - cron: '0 9 * * 1' @@ -46,17 +50,68 @@ jobs: OCAML_BRANCH: ${{ github.event.inputs.branch || 'compatible' }} run: | set +e + # Capture output to file ./.github/scripts/check-ocaml-refs.sh \ --repo "$OCAML_REPO" \ - --branch "$OCAML_BRANCH" + --branch "$OCAML_BRANCH" 2>&1 | tee validation_output.txt exit_code=$? if [ $exit_code -ne 0 ]; then echo "has_issues=true" >> $GITHUB_OUTPUT - exit 0 + else + echo "has_issues=false" >> $GITHUB_OUTPUT fi + # Store output for PR comment + echo "output_file=validation_output.txt" >> $GITHUB_OUTPUT + exit 0 + + - name: Prepare PR comment + if: github.event_name == 'pull_request' + id: prepare-comment + env: + HAS_ISSUES: ${{ steps.check.outputs.has_issues }} + OCAML_REPO: ${{ github.event.inputs.repo || 'https://github.com/MinaProtocol/mina.git' }} + OCAML_BRANCH: ${{ github.event.inputs.branch || 'compatible' }} + run: | + # Determine status message + if [ "$HAS_ISSUES" = "true" ]; then + STATUS_MSG="❌ Validation failed" + else + STATUS_MSG="✓ Validation passed" + fi + + # Create comment body + cat > comment.md < + Click to see full validation output + + \`\`\` + COMMENT_EOF + + # Append validation output + cat validation_output.txt >> comment.md + + # Close the code block and details + cat >> comment.md <<'COMMENT_EOF' + ``` + + + COMMENT_EOF + + - name: Post PR comment with validation results + if: github.event_name == 'pull_request' + uses: peter-evans/create-or-update-comment@v4 + with: + issue-number: ${{ github.event.pull_request.number }} + body-path: comment.md - name: Update references if stale - if: steps.check.outputs.has_issues != 'true' + if: steps.check.outputs.has_issues != 'true' && github.event_name != 'pull_request' env: OCAML_REPO: ${{ github.event.inputs.repo || 'https://github.com/MinaProtocol/mina.git' }} OCAML_BRANCH: ${{ github.event.inputs.branch || 'compatible' }} @@ -67,6 +122,7 @@ jobs: --update - name: Check for changes + if: github.event_name != 'pull_request' id: changes run: | if git diff --quiet; then @@ -76,7 +132,7 @@ jobs: fi - name: Create Pull Request - if: steps.changes.outputs.has_changes == 'true' + if: steps.changes.outputs.has_changes == 'true' && github.event_name != 'pull_request' uses: peter-evans/create-pull-request@v6 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -118,6 +174,8 @@ jobs: echo "" >> $GITHUB_STEP_SUMMARY if [ "${{ steps.check.outputs.has_issues }}" == "true" ]; then echo "❌ Validation failed - some OCaml references are invalid" >> $GITHUB_STEP_SUMMARY + elif [ "${{ github.event_name }}" == "pull_request" ]; then + echo "✓ Validation completed - results posted as PR comment" >> $GITHUB_STEP_SUMMARY elif [ "${{ steps.changes.outputs.has_changes }}" == "true" ]; then echo "✓ Validation passed - created PR to update stale references" >> $GITHUB_STEP_SUMMARY else From 7278624b02f0fa07fa2bf13cbef8fd964dc424a5 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Fri, 10 Oct 2025 11:13:48 +0200 Subject: [PATCH 07/12] Ledger: update OCaml references in mod.rs --- .../src/scan_state/transaction_logic/mod.rs | 98 ++++++++++++++----- 1 file changed, 72 insertions(+), 26 deletions(-) diff --git a/ledger/src/scan_state/transaction_logic/mod.rs b/ledger/src/scan_state/transaction_logic/mod.rs index 95f9fff7c..3b844f4a0 100644 --- a/ledger/src/scan_state/transaction_logic/mod.rs +++ b/ledger/src/scan_state/transaction_logic/mod.rs @@ -61,7 +61,7 @@ pub use transaction_union_payload::{ }; /// OCaml reference: src/lib/mina_base/transaction_status.ml L:9-51 -/// Commit: 2ee6e004ba8c6a0541056076aab22ea162f7eb3a +/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 /// Last verified: 2025-10-08 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] pub enum TransactionFailure { @@ -179,7 +179,7 @@ impl Display for TransactionFailure { } /// OCaml reference: src/lib/mina_base/transaction_status.ml L:452-454 -/// Commit: 2ee6e004ba8c6a0541056076aab22ea162f7eb3a +/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 /// Last verified: 2025-10-08 #[derive(SerdeYojsonEnum, Debug, Clone, PartialEq, Eq)] pub enum TransactionStatus { @@ -197,7 +197,7 @@ impl TransactionStatus { } /// OCaml reference: src/lib/mina_base/with_status.ml L:6-10 -/// Commit: 2ee6e004ba8c6a0541056076aab22ea162f7eb3a +/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 /// Last verified: 2025-10-08 #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)] pub struct WithStatus { @@ -265,7 +265,9 @@ where } } -/// +/// OCaml reference: src/lib/mina_base/fee_transfer.ml L:76-80 +/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 +/// Last verified: 2025-10-10 #[derive(Debug, Clone, PartialEq)] pub struct SingleFeeTransfer { pub receiver_pk: CompressedPubKey, @@ -290,7 +292,9 @@ impl SingleFeeTransfer { } } -/// +/// OCaml reference: src/lib/mina_base/fee_transfer.ml L:68-69 +/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 +/// Last verified: 2025-10-10 #[derive(Debug, Clone, PartialEq)] pub struct FeeTransfer(pub(super) OneOrTwo); @@ -318,7 +322,9 @@ impl FeeTransfer { }) } - /// + /// OCaml reference: src/lib/mina_base/fee_transfer.ml L:110-114 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn fee_excess(&self) -> Result { let one_or_two = self.0.map(|SingleFeeTransfer { fee, fee_token, .. }| { (fee_token.clone(), Signed::::of_unsigned(*fee).negate()) @@ -326,7 +332,9 @@ impl FeeTransfer { FeeExcess::of_one_or_two(one_or_two) } - /// + /// OCaml reference: src/lib/mina_base/fee_transfer.ml L:85-97 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn of_singles(singles: OneOrTwo) -> Result { match singles { OneOrTwo::One(a) => Ok(Self(OneOrTwo::One(a))), @@ -365,7 +373,9 @@ impl CoinbaseFeeTransfer { } } -/// +/// OCaml reference: src/lib/mina_base/coinbase.ml L:17-21 +/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 +/// Last verified: 2025-10-10 #[derive(Debug, Clone, PartialEq)] pub struct Coinbase { pub receiver: CompressedPubKey, @@ -407,7 +417,9 @@ impl Coinbase { } } - /// + /// OCaml reference: src/lib/mina_base/coinbase.ml L:92-100 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 fn expected_supply_increase(&self) -> Result { let Self { amount, @@ -429,12 +441,16 @@ impl Coinbase { self.expected_supply_increase().map(|_| FeeExcess::empty()) } - /// + /// OCaml reference: src/lib/mina_base/coinbase.ml L:39-39 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn receiver(&self) -> AccountId { AccountId::new(self.receiver.clone(), TokenId::default()) } - /// + /// OCaml reference: src/lib/mina_base/coinbase.ml L:51-65 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn account_access_statuses( &self, status: &TransactionStatus, @@ -455,7 +471,9 @@ impl Coinbase { ids } - /// + /// OCaml reference: src/lib/mina_base/coinbase.ml L:67-69 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn accounts_referenced(&self) -> Vec { self.account_access_statuses(&TransactionStatus::Applied) .into_iter() @@ -558,7 +576,9 @@ impl Memo { self.0.as_slice() } - /// + /// OCaml reference: src/lib/mina_base/signed_command_memo.ml L:156-156 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn dummy() -> Self { // TODO Self([0; 34]) @@ -585,7 +605,9 @@ impl Memo { Self(s.into_bytes().try_into().unwrap()) } - /// + /// OCaml reference: src/lib/mina_base/signed_command_memo.ml L:117-120 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 fn create_by_digesting_string_exn(s: &str) -> Self { if s.len() > Self::MAX_DIGESTIBLE_STRING_LENGTH { panic!("Too_long_digestible_string"); @@ -606,7 +628,9 @@ impl Memo { Self(memo) } - /// + /// OCaml reference: src/lib/mina_base/signed_command_memo.ml L:205-207 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn gen() -> Self { use rand::distributions::{Alphanumeric, DistString}; let random_string = Alphanumeric.sample_string(&mut rand::thread_rng(), 50); @@ -667,7 +691,9 @@ impl binprot::BinProtRead for UserCommand { } impl UserCommand { - /// + /// OCaml reference: src/lib/mina_base/user_command.ml L:239 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn account_access_statuses( &self, status: &TransactionStatus, @@ -678,7 +704,9 @@ impl UserCommand { } } - /// + /// OCaml reference: src/lib/mina_base/user_command.ml L:306-307 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn accounts_referenced(&self) -> Vec { self.account_access_statuses(&TransactionStatus::Applied) .into_iter() @@ -714,7 +742,9 @@ impl UserCommand { self.applicable_at_nonce().succ() } - /// + /// OCaml reference: src/lib/mina_base/user_command.ml L:283-287 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn fee(&self) -> Fee { match self { UserCommand::SignedCommand(cmd) => cmd.fee(), @@ -748,7 +778,9 @@ impl UserCommand { } } - /// + /// OCaml reference: src/lib/mina_base/user_command.ml L:388-401 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn to_valid_unsafe(self) -> valid::UserCommand { match self { UserCommand::SignedCommand(cmd) => valid::UserCommand::SignedCommand(cmd), @@ -760,7 +792,9 @@ impl UserCommand { } } - /// + /// OCaml reference: src/lib/mina_base/user_command.ml L:220-226 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn to_verifiable( &self, status: &TransactionStatus, @@ -983,7 +1017,9 @@ impl Transaction { } } - /// + /// OCaml reference: src/lib/transaction/transaction.ml L:98-110 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn public_keys(&self) -> Vec { use Transaction::*; use UserCommand::*; @@ -998,7 +1034,9 @@ impl Transaction { } } - /// + /// OCaml reference: src/lib/transaction/transaction.ml L:112-124 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn account_access_statuses( &self, status: &TransactionStatus, @@ -1017,7 +1055,9 @@ impl Transaction { } } - /// + /// OCaml reference: src/lib/transaction/transaction.ml L:126-128 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 pub fn accounts_referenced(&self) -> Vec { self.account_access_statuses(&TransactionStatus::Applied) .into_iter() @@ -1094,11 +1134,15 @@ pub mod for_tests { } } - /// + /// OCaml reference: src/lib/transaction_logic/mina_transaction_logic.ml L:2285-2285 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 #[derive(Debug)] pub struct InitLedger(pub Vec<(Keypair, u64)>); - /// + /// OCaml reference: src/lib/transaction_logic/mina_transaction_logic.ml L:2351-2356 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 #[derive(Debug)] pub struct TransactionSpec { pub fee: Fee, @@ -1107,7 +1151,9 @@ pub mod for_tests { pub amount: Amount, } - /// + /// OCaml reference: src/lib/transaction_logic/mina_transaction_logic.ml L:2407 + /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 + /// Last verified: 2025-10-10 #[derive(Debug)] pub struct TestSpec { pub init_ledger: InitLedger, From 640689e44e097a5a4bd2e7d58fcdac2af4bb3900 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Fri, 10 Oct 2025 11:16:42 +0200 Subject: [PATCH 08/12] CHANGELOG: add description for patch 1525 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f49da0820..5b70b904f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1493](https://github.com/o1-labs/mina-rust/pull/1509)) - **Ledger/ZkAppCommand**: show how to build a ZkAppCommand from scratch, with dummy values ([#1514](https://github.com/o1-labs/mina-rust/pull/1514)) +- **CI/Documentation**: add a script to check the references to the OCaml code + ([#1525](https://github.com/o1-labs/mina-rust/pull/1525)). ### Changed @@ -62,6 +64,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1515](https://github.com/o1-labs/mina-rust/pull/1515)) - **CI/tests**: run the step `build-wasm` for each push and PR to `develop` ([#1497](https://github.com/o1-labs/mina-rust/pull/1497)) +- **ledger/scan_state/transaction_logic**: update OCaml references in `mod.rs` + ([#1525](https://github.com/o1-labs/mina-rust/pull/1525)) ## v0.17.0 From c43d71ad9fcbfd9a6ce51bb6ddbb59263e6b9d06 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Fri, 10 Oct 2025 11:18:07 +0200 Subject: [PATCH 09/12] GH/scripts: update links to doc guidelines --- .github/scripts/verify-code-references.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/verify-code-references.sh b/.github/scripts/verify-code-references.sh index 92fcbe3be..8b86d20f0 100755 --- a/.github/scripts/verify-code-references.sh +++ b/.github/scripts/verify-code-references.sh @@ -221,7 +221,7 @@ Please follow this workflow: 2. Create a follow-up PR with the documentation updates that reference the merged code 3. The verification will pass once the code is available on \`develop\` -See the [documentation guidelines](https://o1-labs.github.io/mina-rust/developers/documentation-guidelines) for more information about the two-PR workflow. +See the [documentation guidelines](https://o1-labs.github.io/mina-rust/docs/developers/documentation-guidelines) for more information about the two-PR workflow. EOF echo "" echo "PR comment written to: ${COMMENT_FILE}" From 9c541fa42b571aae56e3ec0ad9c1e07a82b3ea0e Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Fri, 10 Oct 2025 11:22:59 +0200 Subject: [PATCH 10/12] CI/check-ocaml-refs: update the existing commits instead of creating --- .github/workflows/check-ocaml-refs.yaml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-ocaml-refs.yaml b/.github/workflows/check-ocaml-refs.yaml index 6a3fad764..dbc43d314 100644 --- a/.github/workflows/check-ocaml-refs.yaml +++ b/.github/workflows/check-ocaml-refs.yaml @@ -79,8 +79,9 @@ jobs: STATUS_MSG="✓ Validation passed" fi - # Create comment body + # Create comment body with hidden identifier cat > comment.md < ## OCaml Reference Validation Results **Repository**: ${OCAML_REPO} @@ -103,12 +104,23 @@ jobs: COMMENT_EOF + - name: Find existing OCaml validation comment + if: github.event_name == 'pull_request' + uses: peter-evans/find-comment@v3 + id: find-comment + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: '' + - name: Post PR comment with validation results if: github.event_name == 'pull_request' uses: peter-evans/create-or-update-comment@v4 with: + comment-id: ${{ steps.find-comment.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }} body-path: comment.md + edit-mode: replace - name: Update references if stale if: steps.check.outputs.has_issues != 'true' && github.event_name != 'pull_request' From 6549693cf026959e661c0d4e3ae85c8c22cf7e93 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Fri, 10 Oct 2025 11:29:17 +0200 Subject: [PATCH 11/12] CI/GH actions: update find-comments version to v4 --- .github/workflows/check-ocaml-refs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-ocaml-refs.yaml b/.github/workflows/check-ocaml-refs.yaml index dbc43d314..47df74483 100644 --- a/.github/workflows/check-ocaml-refs.yaml +++ b/.github/workflows/check-ocaml-refs.yaml @@ -106,7 +106,7 @@ jobs: - name: Find existing OCaml validation comment if: github.event_name == 'pull_request' - uses: peter-evans/find-comment@v3 + uses: peter-evans/find-comment@v4 id: find-comment with: issue-number: ${{ github.event.pull_request.number }} From f3ab3e72bdcdfb4597ec72ff9047ebe9a524a9d7 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Fri, 10 Oct 2025 11:30:03 +0200 Subject: [PATCH 12/12] CI/GH actions: update create-or-update-comment to v5 --- .github/workflows/check-ocaml-refs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-ocaml-refs.yaml b/.github/workflows/check-ocaml-refs.yaml index 47df74483..12184e24c 100644 --- a/.github/workflows/check-ocaml-refs.yaml +++ b/.github/workflows/check-ocaml-refs.yaml @@ -115,7 +115,7 @@ jobs: - name: Post PR comment with validation results if: github.event_name == 'pull_request' - uses: peter-evans/create-or-update-comment@v4 + uses: peter-evans/create-or-update-comment@v5 with: comment-id: ${{ steps.find-comment.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }}