152 lines
4.6 KiB
Bash
Executable file
152 lines
4.6 KiB
Bash
Executable file
#!/bin/bash
|
|
# backfill-proofs.sh - Generate/upgrade OpenTimestamp proofs for all commits
|
|
# Usage: backfill-proofs.sh [repository-path]
|
|
|
|
set -e
|
|
|
|
REPO_PATH="${1:-.}"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
cd "$REPO_PATH"
|
|
|
|
# Verify we're in a git repository
|
|
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
|
echo "Error: not a git repository" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Find the generate-proof.sh script
|
|
GENERATE_SCRIPT=""
|
|
|
|
# Check if generate-proof.sh is in the same directory as this script
|
|
if [ -f "$SCRIPT_DIR/generate-proof.sh" ]; then
|
|
GENERATE_SCRIPT="$SCRIPT_DIR/generate-proof.sh"
|
|
# Check in repository root
|
|
elif [ -f "generate-proof.sh" ]; then
|
|
GENERATE_SCRIPT="./generate-proof.sh"
|
|
# Check if skill is installed globally
|
|
elif [ -f "$HOME/.openclaw/workspace/skills/git-ots-hook/scripts/generate-proof.sh" ]; then
|
|
GENERATE_SCRIPT="$HOME/.openclaw/workspace/skills/git-ots-hook/scripts/generate-proof.sh"
|
|
else
|
|
echo "Error: generate-proof.sh not found" >&2
|
|
exit 1
|
|
fi
|
|
|
|
chmod +x "$GENERATE_SCRIPT"
|
|
|
|
# Ensure .ots directory exists
|
|
mkdir -p .ots
|
|
|
|
# Cache file for attestation status (avoids repeated ots info calls)
|
|
STATUS_CACHE=".ots/.attestation-cache"
|
|
if [ ! -f "$STATUS_CACHE" ]; then
|
|
echo "# Attestation status cache" > "$STATUS_CACHE"
|
|
echo "# Format: commit-hash:status:timestamp" >> "$STATUS_CACHE"
|
|
fi
|
|
|
|
# Function to check cached status
|
|
get_cached_status() {
|
|
local commit="$1"
|
|
local cache_line=$(grep "^$commit:" "$STATUS_CACHE" 2>/dev/null | tail -1)
|
|
if [ -n "$cache_line" ]; then
|
|
local status=$(echo "$cache_line" | cut -d: -f2)
|
|
local timestamp=$(echo "$cache_line" | cut -d: -f3)
|
|
local now=$(date +%s)
|
|
local age=$((now - timestamp))
|
|
# Cache valid for 1 hour (3600 seconds)
|
|
if [ "$age" -lt 3600 ]; then
|
|
echo "$status"
|
|
return 0
|
|
fi
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# Function to cache status
|
|
cache_status() {
|
|
local commit="$1"
|
|
local status="$2"
|
|
local now=$(date +%s)
|
|
echo "$commit:$status:$now" >> "$STATUS_CACHE"
|
|
}
|
|
|
|
echo "[ots-backfill] Scanning commit history..."
|
|
|
|
# Get all commit hashes (oldest to newest)
|
|
COMMITS=$(git rev-list --reverse HEAD)
|
|
TOTAL=$(echo "$COMMITS" | wc -l)
|
|
CURRENT=0
|
|
|
|
# Track if any proofs were updated
|
|
UPDATED=0
|
|
|
|
for COMMIT in $COMMITS; do
|
|
CURRENT=$((CURRENT + 1))
|
|
echo "[ots-backfill] Processing commit $CURRENT/$TOTAL: ${COMMIT:0:8}"
|
|
|
|
# Check if proof exists for this commit
|
|
PROOF_FILE=".ots/${COMMIT}.ots"
|
|
|
|
if [ -f "$PROOF_FILE" ]; then
|
|
# Check cached status first
|
|
CACHED_STATUS=$(get_cached_status "$COMMIT" || echo "")
|
|
|
|
if [ "$CACHED_STATUS" = "attested" ]; then
|
|
echo " ✓ Already attested (cached, skipping)"
|
|
continue
|
|
fi
|
|
|
|
# Check if already fully attested (only if not cached or cache expired)
|
|
PENDING_COUNT=$(ots info "$PROOF_FILE" 2>&1 | grep -c "PendingAttestation" || echo "0")
|
|
|
|
if [ "$PENDING_COUNT" -eq 0 ]; then
|
|
echo " ✓ Already attested"
|
|
cache_status "$COMMIT" "attested"
|
|
continue
|
|
fi
|
|
|
|
# Cache as pending
|
|
cache_status "$COMMIT" "pending"
|
|
|
|
# Try to upgrade existing proof (only contacts calendars if pending)
|
|
echo " Upgrading pending proof..."
|
|
if ots upgrade "$PROOF_FILE" 2>/dev/null; then
|
|
echo " ✓ Upgraded to attested"
|
|
cache_status "$COMMIT" "attested"
|
|
UPDATED=$((UPDATED + 1))
|
|
else
|
|
echo " - Still pending (no upgrade available yet)"
|
|
fi
|
|
else
|
|
# Generate new proof for this commit
|
|
echo " Generating new proof..."
|
|
"$GENERATE_SCRIPT" "$COMMIT" "$PROOF_FILE" >/dev/null 2>&1
|
|
echo " ✓ Generated proof"
|
|
cache_status "$COMMIT" "pending"
|
|
UPDATED=$((UPDATED + 1))
|
|
fi
|
|
done
|
|
|
|
# Create/update latest proof symlink
|
|
LATEST_COMMIT=$(git rev-parse HEAD)
|
|
if [ -f ".ots/${LATEST_COMMIT}.ots" ]; then
|
|
cp ".ots/${LATEST_COMMIT}.ots" ".ots/proof.ots"
|
|
echo "[ots-backfill] Updated .ots/proof.ots for latest commit"
|
|
fi
|
|
|
|
# Save previous commit chain info
|
|
echo "[ots-backfill] Saving commit chain..."
|
|
git rev-list HEAD | while read COMMIT; do
|
|
PREV=$(git rev-parse ${COMMIT}^1 2>/dev/null || echo "")
|
|
if [ -n "$PREV" ]; then
|
|
echo "$COMMIT:$PREV" >> ".ots/commit-chain.txt"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
echo "[ots-backfill] Complete! Processed $TOTAL commits, updated $UPDATED proofs"
|
|
echo ""
|
|
echo "Proofs stored in: .ots/"
|
|
echo " - Individual proofs: .ots/<commit-hash>.ots"
|
|
echo " - Latest proof: .ots/proof.ots"
|
|
echo " - Commit chain: .ots/commit-chain.txt"
|