synor/scripts/profile.sh
Gulshan Yadav 48949ebb3f Initial commit: Synor blockchain monorepo
A complete blockchain implementation featuring:
- synord: Full node with GHOSTDAG consensus
- explorer-web: Modern React blockchain explorer with 3D DAG visualization
- CLI wallet and tools
- Smart contract SDK and example contracts (DEX, NFT, token)
- WASM crypto library for browser/mobile
2026-01-08 05:22:17 +05:30

349 lines
9.1 KiB
Bash
Executable file

#!/usr/bin/env bash
# Synor Profiling Script
# Generates flamegraphs and performance profiles for critical paths
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
PROFILE_DIR="$PROJECT_ROOT/target/profiles"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
# Check dependencies
check_deps() {
info "Checking profiling dependencies..."
# Check for cargo-flamegraph
if ! command -v cargo-flamegraph &> /dev/null; then
warn "cargo-flamegraph not found. Installing..."
cargo install flamegraph
fi
# Check for samply (alternative profiler)
if ! command -v samply &> /dev/null; then
warn "samply not found. Install with: cargo install samply"
fi
# macOS: check for dtrace access
if [[ "$OSTYPE" == "darwin"* ]]; then
if ! csrutil status 2>/dev/null | grep -q "disabled"; then
warn "On macOS, you may need to disable SIP for dtrace-based profiling"
warn "Alternative: use 'samply' which uses the Instruments profiler"
fi
fi
success "Dependencies checked"
}
# Build with profiling symbols
build_profile() {
info "Building with profiling profile..."
cd "$PROJECT_ROOT"
cargo build --profile profiling --workspace
success "Build complete"
}
# Profile kHeavyHash mining
profile_mining() {
info "Profiling kHeavyHash mining..."
mkdir -p "$PROFILE_DIR/mining"
cd "$PROJECT_ROOT"
# Run mining benchmark with flamegraph
if command -v cargo-flamegraph &> /dev/null; then
CARGO_PROFILE_BENCH_DEBUG=true cargo flamegraph \
--bench mining_bench \
-p synor-mining \
--output "$PROFILE_DIR/mining/flamegraph.svg" \
-- --bench "kheavyhash"
success "Mining flamegraph saved to $PROFILE_DIR/mining/flamegraph.svg"
else
# Fallback to regular benchmark with timing
cargo bench -p synor-mining --bench mining_bench -- --verbose
fi
}
# Profile GHOSTDAG consensus
profile_ghostdag() {
info "Profiling GHOSTDAG consensus..."
mkdir -p "$PROFILE_DIR/ghostdag"
cd "$PROJECT_ROOT"
if command -v cargo-flamegraph &> /dev/null; then
CARGO_PROFILE_BENCH_DEBUG=true cargo flamegraph \
--bench ghostdag_bench \
-p synor-dag \
--output "$PROFILE_DIR/ghostdag/flamegraph.svg" \
-- --bench
success "GHOSTDAG flamegraph saved to $PROFILE_DIR/ghostdag/flamegraph.svg"
else
cargo bench -p synor-dag --bench ghostdag_bench -- --verbose
fi
}
# Profile storage operations
profile_storage() {
info "Profiling storage operations..."
mkdir -p "$PROFILE_DIR/storage"
cd "$PROJECT_ROOT"
if command -v cargo-flamegraph &> /dev/null; then
CARGO_PROFILE_BENCH_DEBUG=true cargo flamegraph \
--bench storage_bench \
-p synor-storage \
--output "$PROFILE_DIR/storage/flamegraph.svg" \
-- --bench
success "Storage flamegraph saved to $PROFILE_DIR/storage/flamegraph.svg"
else
cargo bench -p synor-storage --bench storage_bench -- --verbose
fi
}
# Profile crypto operations
profile_crypto() {
info "Profiling crypto operations..."
mkdir -p "$PROFILE_DIR/crypto"
cd "$PROJECT_ROOT"
if command -v cargo-flamegraph &> /dev/null; then
CARGO_PROFILE_BENCH_DEBUG=true cargo flamegraph \
--bench crypto_bench \
-p synor-crypto \
--output "$PROFILE_DIR/crypto/flamegraph.svg" \
-- --bench
success "Crypto flamegraph saved to $PROFILE_DIR/crypto/flamegraph.svg"
else
cargo bench -p synor-crypto --bench crypto_bench -- --verbose
fi
}
# Profile consensus validation
profile_consensus() {
info "Profiling consensus validation..."
mkdir -p "$PROFILE_DIR/consensus"
cd "$PROJECT_ROOT"
if command -v cargo-flamegraph &> /dev/null; then
CARGO_PROFILE_BENCH_DEBUG=true cargo flamegraph \
--bench consensus_bench \
-p synor-consensus \
--output "$PROFILE_DIR/consensus/flamegraph.svg" \
-- --bench
success "Consensus flamegraph saved to $PROFILE_DIR/consensus/flamegraph.svg"
else
cargo bench -p synor-consensus --bench consensus_bench -- --verbose
fi
}
# Run all benchmarks and compare
run_all_benchmarks() {
info "Running all benchmarks..."
cd "$PROJECT_ROOT"
# Create baseline if it doesn't exist
if [[ ! -d "$PROFILE_DIR/baseline" ]]; then
info "Creating baseline benchmark results..."
cargo bench --workspace -- --save-baseline baseline
success "Baseline saved"
else
info "Comparing against baseline..."
cargo bench --workspace -- --baseline baseline
fi
}
# Profile with samply (macOS-friendly)
profile_with_samply() {
local target="$1"
if ! command -v samply &> /dev/null; then
error "samply not installed. Run: cargo install samply"
fi
info "Profiling $target with samply..."
mkdir -p "$PROFILE_DIR/samply"
cd "$PROJECT_ROOT"
case "$target" in
mining)
samply record -- cargo bench -p synor-mining --bench mining_bench
;;
ghostdag)
samply record -- cargo bench -p synor-dag --bench ghostdag_bench
;;
storage)
samply record -- cargo bench -p synor-storage --bench storage_bench
;;
crypto)
samply record -- cargo bench -p synor-crypto --bench crypto_bench
;;
consensus)
samply record -- cargo bench -p synor-consensus --bench consensus_bench
;;
*)
error "Unknown target: $target"
;;
esac
}
# Generate summary report
generate_report() {
info "Generating profiling report..."
local report="$PROFILE_DIR/PROFILING_REPORT.md"
cat > "$report" << 'EOF'
# Synor Profiling Report
Generated: $(date)
## Critical Paths Analyzed
### 1. kHeavyHash Mining
- Matrix initialization time
- Hash computation throughput
- Memory allocation patterns
### 2. GHOSTDAG Consensus
- Block ordering performance
- Blue score calculation
- Merge set computation
### 3. Storage Operations
- RocksDB read/write latency
- Batch operation efficiency
- Cache hit rates
### 4. Cryptography
- Ed25519 signing/verification
- Dilithium3 operations
- Hybrid signature performance
## Flamegraphs
See SVG files in subdirectories:
- `mining/flamegraph.svg`
- `ghostdag/flamegraph.svg`
- `storage/flamegraph.svg`
- `crypto/flamegraph.svg`
- `consensus/flamegraph.svg`
## Optimization Opportunities
1. **Hot paths** - Look for wide bars at the top of flamegraphs
2. **Allocation pressure** - Search for `alloc` or `malloc` patterns
3. **Lock contention** - Look for mutex/rwlock wait times
4. **Serialization overhead** - Check borsh/serde time
## Running Profiles
```bash
# Profile specific component
./scripts/profile.sh mining
./scripts/profile.sh ghostdag
./scripts/profile.sh storage
# Run all benchmarks with comparison
./scripts/profile.sh all
# Use samply on macOS
./scripts/profile.sh samply mining
```
EOF
success "Report generated at $report"
}
# Print usage
usage() {
cat << EOF
Usage: $0 <command> [options]
Commands:
check Check profiling dependencies
build Build with profiling symbols
mining Profile kHeavyHash mining
ghostdag Profile GHOSTDAG consensus
storage Profile storage operations
crypto Profile cryptographic operations
consensus Profile consensus validation
all Run all benchmarks
samply Profile with samply (macOS-friendly)
report Generate profiling report
Options:
-h, --help Show this help message
Examples:
$0 check # Check dependencies
$0 mining # Profile mining
$0 samply ghostdag # Profile GHOSTDAG with samply
$0 all # Run all benchmarks
EOF
}
# Main entry point
main() {
case "${1:-}" in
check)
check_deps
;;
build)
build_profile
;;
mining)
check_deps
profile_mining
;;
ghostdag)
check_deps
profile_ghostdag
;;
storage)
check_deps
profile_storage
;;
crypto)
check_deps
profile_crypto
;;
consensus)
check_deps
profile_consensus
;;
all)
check_deps
run_all_benchmarks
;;
samply)
profile_with_samply "${2:-}"
;;
report)
generate_report
;;
-h|--help|"")
usage
;;
*)
error "Unknown command: $1"
;;
esac
}
main "$@"