Files
mev-beta/scripts/staging-pipeline-local.sh
Krypto Kajun 850223a953 fix(multicall): resolve critical multicall parsing corruption issues
- Added comprehensive bounds checking to prevent buffer overruns in multicall parsing
- Implemented graduated validation system (Strict/Moderate/Permissive) to reduce false positives
- Added LRU caching system for address validation with 10-minute TTL
- Enhanced ABI decoder with missing Universal Router and Arbitrum-specific DEX signatures
- Fixed duplicate function declarations and import conflicts across multiple files
- Added error recovery mechanisms with multiple fallback strategies
- Updated tests to handle new validation behavior for suspicious addresses
- Fixed parser test expectations for improved validation system
- Applied gofmt formatting fixes to ensure code style compliance
- Fixed mutex copying issues in monitoring package by introducing MetricsSnapshot
- Resolved critical security vulnerabilities in heuristic address extraction
- Progress: Updated TODO audit from 10% to 35% complete

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 00:12:55 -05:00

180 lines
6.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
cd "$ROOT_DIR"
LOG_DIR="${LOCAL_STAGING_LOG_DIR:-$ROOT_DIR/reports/ci/local-staging}"
mkdir -p "$LOG_DIR"
export GOCACHE="${LOCAL_STAGING_GOCACHE:-$ROOT_DIR/.gocache}"
export GOMODCACHE="${LOCAL_STAGING_GOMODCACHE:-$ROOT_DIR/.gomodcache}"
mkdir -p "$GOCACHE" "$GOMODCACHE"
BRANCH="${LOCAL_STAGING_BRANCH:-$(git rev-parse --abbrev-ref HEAD)}"
GO_IMAGE="${LOCAL_STAGING_GO_IMAGE:-docker.io/library/golang:1.24}"
GOLANGCI_IMAGE="${LOCAL_STAGING_GOLANGCI_IMAGE:-docker.io/golangci/golangci-lint:v1.60.1}"
HELM_IMAGE="${LOCAL_STAGING_HELM_IMAGE:-docker.io/alpine/helm:3.15.2}"
KUBECTL_IMAGE="${LOCAL_STAGING_KUBECTL_IMAGE:-docker.io/bitnami/kubectl:1.30.1}"
IMAGE_NAME="${LOCAL_STAGING_IMAGE_NAME:-mev-bot}"
IMAGE_TAG="${LOCAL_STAGING_IMAGE_TAG:-staging-local}"
IMAGE_REF="${IMAGE_NAME}:${IMAGE_TAG}"
IMAGE_TAR="${LOCAL_STAGING_IMAGE_TAR:-$ROOT_DIR/${IMAGE_NAME}-${IMAGE_TAG}.tar}"
HELM_RELEASE="${LOCAL_STAGING_HELM_RELEASE:-mev-bot}"
HELM_NAMESPACE="${LOCAL_STAGING_HELM_NAMESPACE:-mev-bot-staging}"
HELM_CHART="${LOCAL_STAGING_HELM_CHART:-charts/mev-bot}"
HELM_DRY_RUN="${LOCAL_STAGING_HELM_DRY_RUN:-true}"
KUBECONFIG_PATH="${LOCAL_STAGING_KUBECONFIG:-$HOME/.kube/config}"
SKIP_DOCKER="${LOCAL_STAGING_SKIP_DOCKER:-false}"
SKIP_DEPLOY="${LOCAL_STAGING_SKIP_DEPLOY:-false}"
CONTAINER_RUNTIME="${LOCAL_STAGING_RUNTIME:-}"
if [[ -z "$CONTAINER_RUNTIME" ]]; then
if command -v podman >/dev/null 2>&1; then
CONTAINER_RUNTIME=podman
elif command -v docker >/dev/null 2>&1; then
CONTAINER_RUNTIME=docker
else
echo "ERROR: Neither podman nor docker is available. Install one or set LOCAL_STAGING_RUNTIME." >&2
exit 1
fi
fi
if ! command -v "$CONTAINER_RUNTIME" >/dev/null 2>&1; then
echo "ERROR: Container runtime '$CONTAINER_RUNTIME' not found in PATH" >&2
exit 1
fi
CONTAINER_CMD=("$CONTAINER_RUNTIME")
if [[ "$CONTAINER_RUNTIME" == "podman" ]]; then
CONTAINER_CMD+=("--remote")
fi
CONTAINER_USER="$(id -u):$(id -g)"
RUNTIME_ARGS=(-u "$CONTAINER_USER" -v "$ROOT_DIR":/work -w /work -v "$GOCACHE":/gocache -v "$GOMODCACHE":/gomodcache -e GOCACHE=/gocache -e GOMODCACHE=/gomodcache)
if [[ "$CONTAINER_RUNTIME" == "podman" ]]; then
RUNTIME_ARGS+=(--security-opt label=disable)
fi
run_step() {
local name="$1"
shift
local logfile="$LOG_DIR/${name}.log"
printf '[%s] Starting %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$name"
if "$@" |& tee "$logfile"; then
printf '[%s] Completed %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$name"
else
printf '[%s] Failed %s; see %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$name" "$logfile"
exit 1
fi
}
log() {
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"
}
require_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "ERROR: Required command '$1' not found" >&2
exit 1
fi
}
run_container_step() {
local step="$1"
local image="$2"
shift 2
local cmd="$*"
run_step "$step" "${CONTAINER_CMD[@]}" run --rm "${RUNTIME_ARGS[@]}" "$image" bash -lc "$cmd"
}
run_container_step_env() {
local step="$1"
local image="$2"
shift 2
local env_args=()
while [[ $# -gt 0 && "$1" == --env=* ]]; do
env_args+=("${1/--env=/}")
shift
done
local cmd="$*"
local run_args=("${RUNTIME_ARGS[@]}")
for env in "${env_args[@]}"; do
run_args+=(-e "$env")
done
run_step "$step" "${CONTAINER_CMD[@]}" run --rm "${run_args[@]}" "$image" bash -lc "$cmd"
}
require_cmd git
log "Running local staging pipeline for branch ${BRANCH} using ${CONTAINER_CMD[*]}"
log "Logs: $LOG_DIR"
HOST_GOROOT="${LOCAL_STAGING_GOROOT:-}"
if [[ -z "$HOST_GOROOT" ]] && command -v go >/dev/null 2>&1; then
HOST_GOROOT=$(go env GOROOT 2>/dev/null || true)
fi
if [[ -n "$HOST_GOROOT" && -d "$HOST_GOROOT" ]]; then
RUNTIME_ARGS+=(-v "$HOST_GOROOT":/goroot:ro -e GOROOT=/goroot)
GO_BIN_PATH="/goroot/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else
GO_BIN_PATH="/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
fi
run_container_step_env setup-dependencies "$GO_IMAGE" "export PATH=$GO_BIN_PATH; go mod download && go mod verify"
run_container_step_env lint "$GOLANGCI_IMAGE" --env=GOLANGCI_LINT_CACHE=/tmp/golangci-lint --env=PATH="$GO_BIN_PATH" "golangci-lint run --timeout=10m"
run_container_step_env unit-tests "$GO_IMAGE" "export PATH=$GO_BIN_PATH; go test -race -coverprofile=coverage.out ./..."
if [[ -f coverage.out ]]; then
mv coverage.out "$LOG_DIR/coverage.out"
fi
run_container_step_env math-audit "$GO_IMAGE" "export PATH=$GO_BIN_PATH; go run ./tools/math-audit --vectors default --report reports/math/latest"
run_container_step_env profit-simulation "$GO_IMAGE" "export PATH=$GO_BIN_PATH; ./scripts/run_profit_simulation.sh"
if [[ "$SKIP_DOCKER" != "true" ]]; then
run_step docker-build "${CONTAINER_CMD[@]}" build -t "$IMAGE_REF" .
run_step docker-save "${CONTAINER_CMD[@]}" save "$IMAGE_REF" -o "$IMAGE_TAR"
else
log "Skipping Docker/Podman build and save (LOCAL_STAGING_SKIP_DOCKER=true)"
fi
if [[ "$SKIP_DEPLOY" != "true" ]]; then
HELM_RUN_ARGS=("${RUNTIME_ARGS[@]}")
if [[ -f "$KUBECONFIG_PATH" ]]; then
HELM_RUN_ARGS+=(-v "$KUBECONFIG_PATH":/kubeconfig:ro -e KUBECONFIG=/kubeconfig)
elif [[ "$HELM_DRY_RUN" == "false" ]]; then
echo "ERROR: kubeconfig not found at $KUBECONFIG_PATH" >&2
exit 1
fi
HELM_CMD=(helm upgrade --install "$HELM_RELEASE" "$HELM_CHART" --set "image.tag=${IMAGE_TAG}" --namespace "$HELM_NAMESPACE")
if [[ "$HELM_DRY_RUN" != "false" ]]; then
HELM_CMD+=('--dry-run')
fi
run_step helm-upgrade "${CONTAINER_CMD[@]}" run --rm "${HELM_RUN_ARGS[@]}" "$HELM_IMAGE" bash -lc "${HELM_CMD[*]}"
if command -v kubectl >/dev/null 2>&1 && [[ "$HELM_DRY_RUN" == "false" ]]; then
run_step rollout-status kubectl rollout status "deploy/${HELM_RELEASE}" -n "$HELM_NAMESPACE" --timeout=120s
run_step rollout-logs kubectl logs "deploy/${HELM_RELEASE}" -n "$HELM_NAMESPACE" --tail=100
elif [[ "$HELM_DRY_RUN" == "false" ]]; then
KUBE_RUN_ARGS=("${RUNTIME_ARGS[@]}")
if [[ -f "$KUBECONFIG_PATH" ]]; then
KUBE_RUN_ARGS+=(-v "$KUBECONFIG_PATH":/kubeconfig:ro -e KUBECONFIG=/kubeconfig)
fi
run_step rollout-status "${CONTAINER_CMD[@]}" run --rm "${KUBE_RUN_ARGS[@]}" "$KUBECTL_IMAGE" bash -lc "kubectl rollout status deploy/${HELM_RELEASE} -n ${HELM_NAMESPACE} --timeout=120s"
run_step rollout-logs "${CONTAINER_CMD[@]}" run --rm "${KUBE_RUN_ARGS[@]}" "$KUBECTL_IMAGE" bash -lc "kubectl logs deploy/${HELM_RELEASE} -n ${HELM_NAMESPACE} --tail=100"
else
log "Skipping rollout status/log tail (dry run or kube tooling unavailable)"
fi
else
log "Skipping deploy stage (LOCAL_STAGING_SKIP_DEPLOY=true)"
fi
log "Local staging pipeline completed"