diff --git a/.github/scripts/check-ocaml-refs.sh b/.github/scripts/check-ocaml-refs.sh index adc11d052a..9f0b330d54 100755 --- a/.github/scripts/check-ocaml-refs.sh +++ b/.github/scripts/check-ocaml-refs.sh @@ -1,6 +1,8 @@ #!/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] +# +# Supports hyperlink format: /// OCaml: set -euo pipefail @@ -62,7 +64,7 @@ echo "Current OCaml commit: ${CURRENT_COMMIT}" # Find all Rust files with OCaml references cd "${RUST_ROOT}" -RUST_FILES=$(git grep -l -E "^/// OCaml reference:" "*.rs" "**/*.rs" || true) +RUST_FILES=$(git grep -l -E "^/// OCaml: /dev/null || true) if [ -z "$RUST_FILES" ]; then echo "No OCaml references found in Rust code" @@ -79,106 +81,102 @@ 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 + # Process hyperlink format: /// OCaml: + grep -n "^/// OCaml: /dev/null | while IFS=: read -r line_num line_content; do + # Extract URL from angle brackets + URL=$(echo "$line_content" | sed -n 's/.*<\(https:\/\/github\.com\/MinaProtocol\/mina\/blob\/[^>]*\)>.*/\1/p') + + if [ -z "$URL" ]; then + echo "INVALID|${rust_file}|LINE:${line_num}|MALFORMED_URL" >> "$RESULTS_FILE" + echo "❌ INVALID: ${rust_file}:${line_num}" + echo " Malformed OCaml reference URL" + continue + fi + + # Parse URL: https://github.com/MinaProtocol/mina/blob/COMMIT/path#L1-L10 + # Pattern: blob/COMMIT/PATH with optional #L1-L10 + if [[ "$URL" =~ blob/([a-f0-9]+)/([^#]+)(#L([0-9]+)(-L([0-9]+))?)? ]]; then + COMMIT="${BASH_REMATCH[1]}" + OCAML_PATH="${BASH_REMATCH[2]}" + START_LINE="${BASH_REMATCH[4]}" + END_LINE="${BASH_REMATCH[6]}" + + # If only start line is specified, set end line to same + if [ -n "$START_LINE" ] && [ -z "$END_LINE" ]; then + END_LINE="$START_LINE" + fi + + LINE_RANGE="" + if [ -n "$START_LINE" ]; then + LINE_RANGE="${START_LINE}-${END_LINE}" + fi + else + echo "INVALID|${rust_file}|LINE:${line_num}|INVALID_URL_FORMAT" >> "$RESULTS_FILE" + echo "❌ INVALID: ${rust_file}:${line_num}" + echo " URL does not match expected format: $URL" + continue + fi + + # 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}:${line_num}" + 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") + + 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}:${line_num}" + 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}" + 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 + # 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}:${line_num}" + 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}:${line_num}" + 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 - 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 + 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 + if [ "$CODE_MATCHES" = "true" ]; then + # Check if commit is stale + if [ "$COMMIT" != "$CURRENT_COMMIT" ]; then + echo "STALE|${rust_file}|${line_num}|${OCAML_PATH}|${COMMIT}|${LINE_RANGE}" >> "$RESULTS_FILE" + echo "✓ VALID: ${rust_file}:${line_num} -> ${OCAML_PATH} L:${LINE_RANGE}" + echo " ⚠ STALE COMMIT: ${COMMIT} (current: ${CURRENT_COMMIT})" + else + echo "VALID|${rust_file}|${line_num}|${OCAML_PATH}|${LINE_RANGE}" >> "$RESULTS_FILE" + echo "✓ VALID: ${rust_file}:${line_num} -> ${OCAML_PATH} L:${LINE_RANGE}" fi fi fi @@ -202,22 +200,26 @@ 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" + echo "Updating stale commit hashes..." + + # Update hyperlink format + grep "^STALE|" "$RESULTS_FILE" | while IFS='|' read -r _status rust_file line_num ocaml_path old_commit line_range; do + echo "Updating ${rust_file}:${line_num}..." + + # Build new URL + NEW_URL="https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}/blob/${CURRENT_COMMIT}/${ocaml_path}" + if [ -n "$line_range" ] && [ "$line_range" != "" ]; then + START_LINE=$(echo "$line_range" | cut -d'-' -f1) + END_LINE=$(echo "$line_range" | cut -d'-' -f2) + NEW_URL="${NEW_URL}#L${START_LINE}-L${END_LINE}" + fi + + # Use sed to replace the URL at the specific line + # We need to escape special characters in the URL for sed + OLD_COMMIT_ESCAPED=$(echo "$old_commit" | sed 's/[\/&]/\\&/g') + CURRENT_COMMIT_ESCAPED=$(echo "$CURRENT_COMMIT" | sed 's/[\/&]/\\&/g') + + sed -i "${line_num}s/blob\/${OLD_COMMIT_ESCAPED}\//blob\/${CURRENT_COMMIT_ESCAPED}\//" "${RUST_ROOT}/${rust_file}" done echo "Updated ${STALE_COMMITS} reference(s)" diff --git a/CLAUDE.md b/CLAUDE.md index f8644f2176..87eb168369 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -170,9 +170,7 @@ 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 +/// OCaml: pub enum TransactionFailure { // ... } diff --git a/crates/core/src/block/prevalidate.rs b/crates/core/src/block/prevalidate.rs index edf9b19116..6087077c6d 100644 --- a/crates/core/src/block/prevalidate.rs +++ b/crates/core/src/block/prevalidate.rs @@ -112,8 +112,7 @@ pub fn prevalidate_block( validate_constants(block, genesis)?; // TODO(tizoc): check for InvalidDeltaBlockChainProof - // - // - + /// OCaml: + /// OCaml: Ok(()) } diff --git a/crates/core/src/constants.rs b/crates/core/src/constants.rs index 39d5bf12df..70b1c28cbd 100644 --- a/crates/core/src/constants.rs +++ b/crates/core/src/constants.rs @@ -87,7 +87,7 @@ pub struct ForkConstants { /// While most constraint constants are identical across networks, some parameters /// may differ between mainnet and testnets for development purposes. /// -/// Related OCaml implementation: +/// OCaml: /// Protocol specification: #[derive(Clone, Debug)] pub struct ConstraintConstants { diff --git a/crates/ledger/src/account/account.rs b/crates/ledger/src/account/account.rs index fb7ef54af0..a32b4d0df3 100644 --- a/crates/ledger/src/account/account.rs +++ b/crates/ledger/src/account/account.rs @@ -1270,9 +1270,7 @@ pub struct PermsConst { /// - Flexible permission policies for different operations /// - Zero-knowledge application state and verification /// -/// OCaml reference: src/lib/mina_base/account.ml L:201-224 -/// Commit: fc6be4c58091c761f827c858229c2edf9519e941 -/// Last verified: 2025-10-13 +/// OCaml: #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(into = "v2::MinaBaseAccountBinableArgStableV2")] #[serde(try_from = "v2::MinaBaseAccountBinableArgStableV2")] diff --git a/crates/ledger/src/scan_state/transaction_logic/for_tests.rs b/crates/ledger/src/scan_state/transaction_logic/for_tests.rs index e37c9f16cf..5250f6ea73 100644 --- a/crates/ledger/src/scan_state/transaction_logic/for_tests.rs +++ b/crates/ledger/src/scan_state/transaction_logic/for_tests.rs @@ -60,15 +60,11 @@ impl PartialOrd for HashableCompressedPubKey { } } -/// OCaml reference: src/lib/transaction_logic/mina_transaction_logic.ml L:2285-2285 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-10 +/// OCaml: #[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 +/// OCaml: #[derive(Debug)] pub struct TransactionSpec { pub fee: Fee, @@ -77,9 +73,7 @@ pub struct TransactionSpec { pub amount: Amount, } -/// OCaml reference: src/lib/transaction_logic/mina_transaction_logic.ml L:2407 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-10 +/// OCaml: #[derive(Debug)] pub struct TestSpec { pub init_ledger: InitLedger, diff --git a/crates/ledger/src/scan_state/transaction_logic/mod.rs b/crates/ledger/src/scan_state/transaction_logic/mod.rs index 14749c8687..3f171aa168 100644 --- a/crates/ledger/src/scan_state/transaction_logic/mod.rs +++ b/crates/ledger/src/scan_state/transaction_logic/mod.rs @@ -115,9 +115,7 @@ pub use transaction_union_payload::{ ExistingOrNew, Tag, TimingValidation, TransactionUnion, TransactionUnionPayload, }; -/// OCaml reference: src/lib/mina_base/transaction_status.ml L:9-51 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-08 +/// OCaml: #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)] pub enum TransactionFailure { Predicate, @@ -233,9 +231,7 @@ impl Display for TransactionFailure { } } -/// OCaml reference: src/lib/mina_base/transaction_status.ml L:452-454 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-08 +/// OCaml: #[derive(SerdeYojsonEnum, Debug, Clone, PartialEq, Eq)] pub enum TransactionStatus { Applied, @@ -251,9 +247,7 @@ impl TransactionStatus { } } -/// OCaml reference: src/lib/mina_base/with_status.ml L:6-10 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-08 +/// OCaml: #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)] pub struct WithStatus { pub data: T, @@ -323,9 +317,7 @@ where } } -/// OCaml reference: src/lib/mina_base/fee_transfer.ml L:76-80 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-10 +/// OCaml: #[derive(Debug, Clone, PartialEq)] pub struct SingleFeeTransfer { pub receiver_pk: CompressedPubKey, @@ -350,9 +342,7 @@ impl SingleFeeTransfer { } } -/// OCaml reference: src/lib/mina_base/fee_transfer.ml L:68-69 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-10 +/// OCaml: #[derive(Debug, Clone, PartialEq)] pub struct FeeTransfer(pub(super) OneOrTwo); @@ -380,9 +370,7 @@ impl FeeTransfer { }) } - /// OCaml reference: src/lib/mina_base/fee_transfer.ml L:110-114 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: 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()) @@ -390,9 +378,7 @@ 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 + /// OCaml: pub fn of_singles(singles: OneOrTwo) -> Result { match singles { OneOrTwo::One(a) => Ok(Self(OneOrTwo::One(a))), @@ -431,9 +417,7 @@ impl CoinbaseFeeTransfer { } } -/// OCaml reference: src/lib/mina_base/coinbase.ml L:17-21 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-10 +/// OCaml: #[derive(Debug, Clone, PartialEq)] pub struct Coinbase { pub receiver: CompressedPubKey, @@ -475,9 +459,7 @@ impl Coinbase { } } - /// OCaml reference: src/lib/mina_base/coinbase.ml L:92-100 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: fn expected_supply_increase(&self) -> Result { let Self { amount, @@ -499,16 +481,12 @@ 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 + /// OCaml: 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 + /// OCaml: pub fn account_access_statuses( &self, status: &TransactionStatus, @@ -529,9 +507,7 @@ impl Coinbase { ids } - /// OCaml reference: src/lib/mina_base/coinbase.ml L:67-69 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn accounts_referenced(&self) -> Vec { self.account_access_statuses(&TransactionStatus::Applied) .into_iter() @@ -634,9 +610,7 @@ 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 + /// OCaml: pub fn dummy() -> Self { // TODO Self([0; 34]) @@ -663,9 +637,7 @@ 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 + /// OCaml: fn create_by_digesting_string_exn(s: &str) -> Self { if s.len() > Self::MAX_DIGESTIBLE_STRING_LENGTH { panic!("Too_long_digestible_string"); @@ -686,9 +658,7 @@ impl Memo { Self(memo) } - /// OCaml reference: src/lib/mina_base/signed_command_memo.ml L:205-207 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn gen() -> Self { use rand::distributions::{Alphanumeric, DistString}; let random_string = Alphanumeric.sample_string(&mut rand::thread_rng(), 50); @@ -749,9 +719,7 @@ 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 + /// OCaml: pub fn account_access_statuses( &self, status: &TransactionStatus, @@ -762,9 +730,7 @@ impl UserCommand { } } - /// OCaml reference: src/lib/mina_base/user_command.ml L:306-307 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn accounts_referenced(&self) -> Vec { self.account_access_statuses(&TransactionStatus::Applied) .into_iter() @@ -800,9 +766,7 @@ 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 + /// OCaml: pub fn fee(&self) -> Fee { match self { UserCommand::SignedCommand(cmd) => cmd.fee(), @@ -836,9 +800,7 @@ impl UserCommand { } } - /// OCaml reference: src/lib/mina_base/user_command.ml L:388-401 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn to_valid_unsafe(self) -> valid::UserCommand { match self { UserCommand::SignedCommand(cmd) => valid::UserCommand::SignedCommand(cmd), @@ -850,9 +812,7 @@ impl UserCommand { } } - /// OCaml reference: src/lib/mina_base/user_command.ml L:220-226 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn to_verifiable( &self, status: &TransactionStatus, @@ -1086,9 +1046,7 @@ impl GenericTransaction for Transaction { /// types and implements conversion to/from the p2p wire format /// [`MinaTransactionTransactionStableV2`]. /// -/// OCaml reference: src/lib/transaction/transaction.ml L:8-11 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-10 +/// OCaml: #[derive(Clone, Debug, derive_more::From)] pub enum Transaction { /// User-initiated transaction: signed command or zkApp command @@ -1116,9 +1074,7 @@ impl Transaction { } } - /// OCaml reference: src/lib/transaction/transaction.ml L:98-110 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn public_keys(&self) -> Vec { use Transaction::*; use UserCommand::*; @@ -1133,9 +1089,7 @@ impl Transaction { } } - /// OCaml reference: src/lib/transaction/transaction.ml L:112-124 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn account_access_statuses( &self, status: &TransactionStatus, @@ -1154,9 +1108,7 @@ impl Transaction { } } - /// OCaml reference: src/lib/transaction/transaction.ml L:126-128 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn accounts_referenced(&self) -> Vec { self.account_access_statuses(&TransactionStatus::Applied) .into_iter() diff --git a/crates/ledger/src/scan_state/transaction_logic/signed_command.rs b/crates/ledger/src/scan_state/transaction_logic/signed_command.rs index 0f50aed511..75b2b0e127 100644 --- a/crates/ledger/src/scan_state/transaction_logic/signed_command.rs +++ b/crates/ledger/src/scan_state/transaction_logic/signed_command.rs @@ -14,9 +14,7 @@ use super::{zkapp_command::AccessedOrNot, Memo, TransactionStatus}; /// Common fields shared by all signed command payloads. /// -/// OCaml reference: src/lib/mina_base/signed_command_payload.ml L:34-48 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-10 +/// OCaml: #[derive(Debug, Clone, PartialEq)] pub struct Common { /// Fee paid to the block producer @@ -42,9 +40,7 @@ pub struct PaymentPayload { /// Stake delegation payload for delegating stake to another account. /// -/// OCaml reference: src/lib/mina_base/stake_delegation.ml L:11-13 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-10 +/// OCaml: #[derive(Debug, Clone, PartialEq, Eq)] pub enum StakeDelegationPayload { /// Delegate stake to a new delegate @@ -55,17 +51,13 @@ pub enum StakeDelegationPayload { } impl StakeDelegationPayload { - /// OCaml reference: src/lib/mina_base/stake_delegation.ml L:35-37 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn receiver(&self) -> AccountId { let Self::SetDelegate { new_delegate } = self; AccountId::new(new_delegate.clone(), TokenId::default()) } - /// OCaml reference: src/lib/mina_base/stake_delegation.ml L:33-33 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn receiver_pk(&self) -> &CompressedPubKey { let Self::SetDelegate { new_delegate } = self; new_delegate @@ -75,9 +67,7 @@ impl StakeDelegationPayload { /// The body of a signed command, which can be either a payment or stake /// delegation. /// -/// OCaml reference: src/lib/mina_base/signed_command_payload.ml L:179-181 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-10 +/// OCaml: #[derive(Debug, Clone, PartialEq, Eq)] pub enum Body { /// Transfer MINA tokens from fee payer to receiver @@ -88,9 +78,7 @@ pub enum Body { /// Signed command payload containing common fields and the transaction body. /// -/// OCaml reference: src/lib/mina_base/signed_command_payload.ml L:239-243 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-10 +/// OCaml: #[derive(Debug, Clone, PartialEq)] pub struct SignedCommandPayload { /// Common fields (fee, fee payer, nonce, valid_until, memo) @@ -121,9 +109,7 @@ impl SignedCommandPayload { } } -/// OCaml reference: src/lib/mina_base/signed_command_payload.ml L:352-362 -/// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 -/// Last verified: 2025-10-10 +/// OCaml: mod weight { use super::*; @@ -163,17 +149,13 @@ impl SignedCommand { self.payload.common.valid_until } - /// OCaml reference: src/lib/mina_base/signed_command_payload.ml L:292-292 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn fee_payer(&self) -> AccountId { let public_key = self.payload.common.fee_payer_pk.clone(); AccountId::new(public_key, TokenId::default()) } - /// OCaml reference: src/lib/mina_base/signed_command_payload.ml L:290-290 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn fee_payer_pk(&self) -> &CompressedPubKey { &self.payload.common.fee_payer_pk } @@ -187,9 +169,7 @@ impl SignedCommand { weight::of_body(body) } - /// OCaml reference: src/lib/mina_base/signed_command_payload.ml L:288-288 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn fee_token(&self) -> TokenId { TokenId::default() } @@ -198,9 +178,7 @@ impl SignedCommand { self.payload.common.fee } - /// OCaml reference: src/lib/mina_base/signed_command_payload.ml L:304-304 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn receiver(&self) -> AccountId { match &self.payload.body { Body::Payment(payload) => { @@ -210,9 +188,7 @@ impl SignedCommand { } } - /// OCaml reference: src/lib/mina_base/signed_command_payload.ml L:302-302 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn receiver_pk(&self) -> &CompressedPubKey { match &self.payload.body { Body::Payment(payload) => &payload.receiver_pk, @@ -235,9 +211,7 @@ impl SignedCommand { FeeExcess::of_single((self.fee_token(), Signed::::of_unsigned(self.fee()))) } - /// OCaml reference: src/lib/mina_base/signed_command_payload.ml L:320-338 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn account_access_statuses( &self, status: &TransactionStatus, @@ -260,16 +234,12 @@ impl SignedCommand { .collect() } - /// OCaml reference: src/lib/mina_base/signed_command.ml L:417-420 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn public_keys(&self) -> [&CompressedPubKey; 2] { [self.fee_payer_pk(), self.receiver_pk()] } - /// OCaml reference: src/lib/mina_base/signed_command.ml L:422-424 - /// Commit: 5da42ccd72e791f164d4d200cf1ce300262873b3 - /// Last verified: 2025-10-10 + /// OCaml: pub fn check_valid_keys(&self) -> bool { self.public_keys() .into_iter() diff --git a/crates/node/src/transition_frontier/sync/transition_frontier_sync_reducer.rs b/crates/node/src/transition_frontier/sync/transition_frontier_sync_reducer.rs index 3dbe51f0bd..e541c18b30 100644 --- a/crates/node/src/transition_frontier/sync/transition_frontier_sync_reducer.rs +++ b/crates/node/src/transition_frontier/sync/transition_frontier_sync_reducer.rs @@ -451,7 +451,7 @@ impl TransitionFrontierSyncState { // it is not possible to recover this info from the staging ledger reconstruction, // so the value will not always be correct for the root block. // The `false` value is used to be compatible with: - // + /// OCaml: let root_block_just_emitted_a_proof = false; if let Some(reconstructed_root_block) = root_block_updates_iter.next() { diff --git a/crates/p2p-messages/src/string.rs b/crates/p2p-messages/src/string.rs index 030a9a5a7c..4a3d30f9db 100644 --- a/crates/p2p-messages/src/string.rs +++ b/crates/p2p-messages/src/string.rs @@ -11,9 +11,9 @@ const CHUNK_SIZE: usize = 5_000; pub type ByteString = BoundedByteString; pub type CharString = BoundedCharString; -// +/// OCaml: pub const ZKAPP_URI_MAX_LENGTH: usize = 255; -// +/// OCaml: pub const TOKEN_SYMBOL_MAX_LENGTH: usize = 6; pub type ZkAppUri = BoundedCharString; diff --git a/website/docs/developers/ocaml-reference-tracking.md b/website/docs/developers/ocaml-reference-tracking.md index 6112752ec6..b73df2f42a 100644 --- a/website/docs/developers/ocaml-reference-tracking.md +++ b/website/docs/developers/ocaml-reference-tracking.md @@ -23,13 +23,11 @@ comments that reference the corresponding OCaml code. This helps developers: ## Comment format -OCaml references are added as doc comments directly above the Rust type or -function: +OCaml references are added as single-line doc comments directly above the Rust +type or function, using a clickable hyperlink format: ```rust -/// OCaml reference: src/lib/mina_base/transaction_status.ml L:9-113 -/// Commit: 55582d249cdb225f722dbbb3b1420ce7570d501f -/// Last verified: 2025-10-08 +/// OCaml: pub enum TransactionFailure { // ... } @@ -37,17 +35,30 @@ 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 +The format is: `/// OCaml: ` + +Where the URL follows this structure: + +``` +https://github.com/MinaProtocol/mina/blob//#L-L +``` + +- ``: Full commit hash from the Mina repository (40 characters) +- ``: Path to the OCaml file relative to the Mina repository root +- `#L-L`: Line range in the OCaml file (optional but recommended) + +**Benefits of this format**: + +- Single line is easier to read and maintain +- Clickable in IDEs and GitHub +- Commit hash embedded in URL preserves historical tracking +- Line range visible directly in URL fragment +- Works in markdown viewers and documentation ## Validation script -The `.github/scripts/check-ocaml-refs.sh` script validates all OCaml references: +The `.github/scripts/check-ocaml-refs.sh` script validates all OCaml references +in the hyperlink format. ```bash # Validate against compatible branch (default) @@ -91,16 +102,14 @@ The workflow can also be triggered manually via the Actions tab. 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 +2. Use the current commit hash from the Mina repository (full 40-character hash) +3. Include line ranges to make it easy to find the exact code +4. Use angle brackets around the URL for automatic linking Example: ```rust -/// OCaml reference: src/lib/mina_base/fee_transfer.ml L:19-45 -/// Commit: 55582d249cdb225f722dbbb3b1420ce7570d501f -/// Last verified: 2025-10-08 +/// OCaml: #[derive(Debug, Clone, PartialEq)] pub struct SingleFeeTransfer { pub receiver_pk: CompressedPubKey,