Update Python version requirements and fix compatibility issues
- Bump minimum Python version from 3.11 to 3.13 across all apps - Add Python 3.11-3.13 test matrix to CLI workflow - Document Python 3.11+ requirement in .env.example - Fix Starlette Broadcast removal with in-process fallback implementation - Add _InProcessBroadcast class for tests when Starlette Broadcast is unavailable - Refactor API key validators to read live settings instead of cached values - Update database models with explicit
This commit is contained in:
127
apps/zk-circuits/compile_cached.py
Executable file
127
apps/zk-circuits/compile_cached.py
Executable file
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Cached ZK Circuit Compiler
|
||||
|
||||
Uses the ZK cache system to speed up iterative circuit development.
|
||||
Only recompiles when source files have changed.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
from zk_cache import ZKCircuitCache
|
||||
|
||||
def compile_circuit_cached(circuit_file: str, output_dir: str = None, use_cache: bool = True) -> dict:
|
||||
"""
|
||||
Compile a ZK circuit with caching support
|
||||
|
||||
Args:
|
||||
circuit_file: Path to the .circom circuit file
|
||||
output_dir: Output directory for compiled artifacts (auto-generated if None)
|
||||
use_cache: Whether to use caching
|
||||
|
||||
Returns:
|
||||
Dict with compilation results
|
||||
"""
|
||||
circuit_path = Path(circuit_file)
|
||||
if not circuit_path.exists():
|
||||
raise FileNotFoundError(f"Circuit file not found: {circuit_file}")
|
||||
|
||||
# Auto-generate output directory if not specified
|
||||
if output_dir is None:
|
||||
circuit_name = circuit_path.stem
|
||||
output_dir = f"build/{circuit_name}"
|
||||
|
||||
output_path = Path(output_dir)
|
||||
|
||||
cache = ZKCircuitCache()
|
||||
result = {
|
||||
'cached': False,
|
||||
'compilation_time': 0.0,
|
||||
'cache_hit': False,
|
||||
'circuit_file': str(circuit_path),
|
||||
'output_dir': str(output_path)
|
||||
}
|
||||
|
||||
# Check cache first
|
||||
if use_cache:
|
||||
cached_result = cache.get_cached_artifacts(circuit_path, output_path)
|
||||
if cached_result:
|
||||
print(f"✅ Cache hit for {circuit_file} - skipping compilation")
|
||||
result['cache_hit'] = True
|
||||
result['compilation_time'] = cached_result.get('compilation_time', 0.0)
|
||||
return result
|
||||
|
||||
print(f"🔧 Compiling {circuit_file}...")
|
||||
|
||||
# Create output directory
|
||||
output_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Build circom command
|
||||
cmd = [
|
||||
"circom", str(circuit_path),
|
||||
"--r1cs", "--wasm", "--sym", "--c",
|
||||
"-o", str(output_path)
|
||||
]
|
||||
|
||||
# Execute compilation
|
||||
start_time = time.time()
|
||||
try:
|
||||
subprocess.run(cmd, check=True, capture_output=True, text=True)
|
||||
compilation_time = time.time() - start_time
|
||||
|
||||
# Cache successful compilation
|
||||
if use_cache:
|
||||
cache.cache_artifacts(circuit_path, output_path, compilation_time)
|
||||
|
||||
result['cached'] = True
|
||||
result['compilation_time'] = compilation_time
|
||||
print(f"✅ Compiled successfully in {compilation_time:.3f}s")
|
||||
return result
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"❌ Compilation failed: {e}")
|
||||
result['error'] = str(e)
|
||||
result['cached'] = False
|
||||
|
||||
return result
|
||||
|
||||
def main():
|
||||
"""CLI interface for cached circuit compilation"""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Cached ZK Circuit Compiler')
|
||||
parser.add_argument('circuit_file', help='Path to the .circom circuit file')
|
||||
parser.add_argument('--output-dir', '-o', help='Output directory for compiled artifacts')
|
||||
parser.add_argument('--no-cache', action='store_true', help='Disable caching')
|
||||
parser.add_argument('--stats', action='store_true', help='Show cache statistics')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.stats:
|
||||
cache = ZKCircuitCache()
|
||||
stats = cache.get_cache_stats()
|
||||
print(f"Cache Statistics:")
|
||||
print(f" Entries: {stats['entries']}")
|
||||
print(f" Total Size: {stats['total_size_mb']:.2f} MB")
|
||||
print(f" Cache Directory: {stats['cache_dir']}")
|
||||
return
|
||||
|
||||
# Compile circuit
|
||||
result = compile_circuit_cached(
|
||||
args.circuit_file,
|
||||
args.output_dir,
|
||||
not args.no_cache
|
||||
)
|
||||
|
||||
if result.get('cached') or result.get('cache_hit'):
|
||||
if result.get('cache_hit'):
|
||||
print("🎯 Used cached compilation")
|
||||
else:
|
||||
print(f"✅ Compiled successfully in {result['compilation_time']:.3f}s")
|
||||
else:
|
||||
print("❌ Compilation failed")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user