Track MEV multi-chain rollout validation and cutover
This commit is contained in:
@@ -18,7 +18,7 @@ source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
||||
|
||||
PROXMOX_HOST="${PROXMOX_HOST:-${PROXMOX_HOST_R630_04:-192.168.11.14}}"
|
||||
VMID="${MEV_CONTROL_BACKEND_VMID:-2421}"
|
||||
IP_CT="${MEV_CONTROL_BACKEND_IP:-192.168.11.219}"
|
||||
IP_CT="${MEV_CONTROL_BACKEND_IP:-192.168.11.223}"
|
||||
HOSTNAME_CT="${MEV_CONTROL_BACKEND_HOSTNAME:-mev-control-backend}"
|
||||
TEMPLATE_CT="${TEMPLATE:-local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst}"
|
||||
STORAGE="${STORAGE:-local-lvm}"
|
||||
@@ -71,4 +71,3 @@ ssh $SSH_OPTS "root@${PROXMOX_HOST}" "pct exec ${VMID} -- bash -lc \"set -euo pi
|
||||
echo ""
|
||||
echo "✅ Backend CT ${VMID} ready at ${IP_CT}"
|
||||
echo " Next: deploy the MEV stack inside the CT and point CT 2410 /api to http://${IP_CT}:9090"
|
||||
|
||||
|
||||
@@ -137,6 +137,19 @@ def run_cast_call(address: str, signature: str, rpc_url: str) -> str | None:
|
||||
return result.stdout.strip() or None
|
||||
|
||||
|
||||
def run_cast_wallet_address(private_key: str) -> str | None:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["cast", "wallet", "address", "--private-key", private_key],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
except Exception: # noqa: BLE001
|
||||
return None
|
||||
return result.stdout.strip() or None
|
||||
|
||||
|
||||
config = tomllib.loads(config_path.read_text())
|
||||
env_values = parse_env_file(env_path)
|
||||
chain_key = str(chain_id)
|
||||
@@ -152,6 +165,7 @@ def add_row(name: str, source: str, value: str, status: str) -> None:
|
||||
|
||||
|
||||
signer_key = os.environ.get("MEV_EXECUTOR_PRIVATE_KEY") or env_values.get("MEV_EXECUTOR_PRIVATE_KEY", "")
|
||||
signer_address = run_cast_wallet_address(signer_key) if signer_key else None
|
||||
if signer_key:
|
||||
add_row("MEV_EXECUTOR_PRIVATE_KEY", str(env_path), "(present, masked)", "ok")
|
||||
else:
|
||||
|
||||
177
scripts/verify/run-mev-roadmap-validation.sh
Executable file
177
scripts/verify/run-mev-roadmap-validation.sh
Executable file
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
MEV_ROOT="$ROOT/MEV_Bot/mev-platform"
|
||||
CHAIN_ID="${CHAIN_ID:-}"
|
||||
BASE_URL="${MEV_BASE_URL:-https://mev.defi-oracle.io}"
|
||||
API_KEY="${MEV_API_KEY:-${API_KEY:-}}"
|
||||
RUN_LIVE=0
|
||||
LIVE_PER_CHAIN=0
|
||||
|
||||
rpc_jsonrpc() {
|
||||
local rpc_url="$1"
|
||||
local body="$2"
|
||||
local attempts="${3:-4}"
|
||||
local delay=1
|
||||
local tmp_body tmp_code
|
||||
tmp_body="$(mktemp)"
|
||||
tmp_code="$(mktemp)"
|
||||
for ((i=1; i<=attempts; i++)); do
|
||||
if curl -sS -o "$tmp_body" -w '%{http_code}' -H 'content-type: application/json' -d "$body" "$rpc_url" >"$tmp_code"; then
|
||||
code="$(cat "$tmp_code")"
|
||||
if [[ "$code" == "200" ]]; then
|
||||
cat "$tmp_body"
|
||||
rm -f "$tmp_body" "$tmp_code"
|
||||
return 0
|
||||
fi
|
||||
if [[ "$code" != "429" ]]; then
|
||||
cat "$tmp_body" >&2 || true
|
||||
rm -f "$tmp_body" "$tmp_code"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
sleep "$delay"
|
||||
delay=$((delay * 2))
|
||||
done
|
||||
cat "$tmp_body" >&2 || true
|
||||
rm -f "$tmp_body" "$tmp_code"
|
||||
return 1
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--chain-id)
|
||||
CHAIN_ID="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--base-url)
|
||||
BASE_URL="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--api-key)
|
||||
API_KEY="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--live)
|
||||
RUN_LIVE=1
|
||||
shift
|
||||
;;
|
||||
--live-per-chain)
|
||||
RUN_LIVE=1
|
||||
LIVE_PER_CHAIN=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown arg: $1" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "[1/4] Rust validation"
|
||||
(
|
||||
cd "$MEV_ROOT"
|
||||
cargo test -p mev-shared
|
||||
cargo check -p mev-state-ingestion -p mev-liquidity-graph -p mev-opportunity-search -p mev-simulation -p mev-bundle-builder -p mev-admin-api
|
||||
)
|
||||
|
||||
echo "[2/4] Contract validation"
|
||||
(
|
||||
cd "$MEV_ROOT/contracts"
|
||||
forge test
|
||||
)
|
||||
|
||||
echo "[3/4] GUI validation"
|
||||
(
|
||||
cd "$MEV_ROOT/gui"
|
||||
npm run build
|
||||
)
|
||||
|
||||
echo "[4/4] Config inventory checks"
|
||||
python3 - "$MEV_ROOT/config.toml" "$CHAIN_ID" <<'PY'
|
||||
import sys, tomllib
|
||||
path = sys.argv[1]
|
||||
requested = sys.argv[2].strip()
|
||||
with open(path, "rb") as fh:
|
||||
data = tomllib.load(fh)
|
||||
chains = data.get("chains", {})
|
||||
required = {"1", "8453", "138"}
|
||||
missing = sorted(required - set(chains.keys()))
|
||||
if missing:
|
||||
raise SystemExit(f"Missing required chains in config.toml: {', '.join(missing)}")
|
||||
targets = [requested] if requested else sorted(required)
|
||||
for cid in targets:
|
||||
chain = chains.get(cid)
|
||||
if not chain:
|
||||
raise SystemExit(f"Chain {cid} missing from config.toml")
|
||||
if "rpc_url" not in chain:
|
||||
raise SystemExit(f"Chain {cid} missing rpc_url")
|
||||
if "multicall" not in chain:
|
||||
raise SystemExit(f"Chain {cid} missing multicall")
|
||||
venues = chain.get("venues", [])
|
||||
if cid == "138" and not venues:
|
||||
raise SystemExit("Chain 138 requires DODO venue examples or inventory")
|
||||
print("Config inventory checks passed")
|
||||
PY
|
||||
|
||||
if [[ "$RUN_LIVE" -eq 1 ]]; then
|
||||
echo "[live] API smoke"
|
||||
auth_header=()
|
||||
if [[ -n "$API_KEY" ]]; then
|
||||
auth_header=(-H "X-API-Key: $API_KEY")
|
||||
fi
|
||||
curl -fsS "${auth_header[@]}" "$BASE_URL/api/health" >/dev/null
|
||||
curl -fsS "${auth_header[@]}" "$BASE_URL/api/infra" >/dev/null
|
||||
curl -fsS "${auth_header[@]}" "$BASE_URL/api/stats/freshness" >/dev/null
|
||||
curl -fsS "${auth_header[@]}" "$BASE_URL/api/stats/venue-coverage" >/dev/null
|
||||
echo "Live API smoke passed"
|
||||
fi
|
||||
|
||||
if [[ "$LIVE_PER_CHAIN" -eq 1 ]]; then
|
||||
echo "[live] Per-chain deployment validation"
|
||||
python3 - "$MEV_ROOT/config.toml" <<'PY' > /tmp/mev_roadmap_live_targets.json
|
||||
import json, sys, tomllib
|
||||
with open(sys.argv[1], "rb") as fh:
|
||||
data = tomllib.load(fh)
|
||||
chains = data.get("chains", {})
|
||||
targets = {}
|
||||
for cid in ("1", "8453", "138"):
|
||||
chain = chains[cid]
|
||||
targets[cid] = {
|
||||
"rpc_url": chain.get("rpc_url", ""),
|
||||
"ws_url": chain.get("ws_url", ""),
|
||||
"multicall": chain.get("multicall", ""),
|
||||
}
|
||||
print(json.dumps(targets))
|
||||
PY
|
||||
for cid in 1 8453 138; do
|
||||
rpc_url="$(python3 -c 'import json; import sys; data=json.load(open("/tmp/mev_roadmap_live_targets.json")); print(data[sys.argv[1]]["rpc_url"])' "$cid")"
|
||||
ws_url="$(python3 -c 'import json; import sys; data=json.load(open("/tmp/mev_roadmap_live_targets.json")); print(data[sys.argv[1]]["ws_url"])' "$cid")"
|
||||
multicall="$(python3 -c 'import json; import sys; data=json.load(open("/tmp/mev_roadmap_live_targets.json")); print(data[sys.argv[1]]["multicall"])' "$cid")"
|
||||
override_var="MEV_LIVE_RPC_URL_${cid}"
|
||||
override_rpc="${!override_var:-}"
|
||||
if [[ -n "$override_rpc" ]]; then
|
||||
rpc_url="$override_rpc"
|
||||
fi
|
||||
echo " - chain $cid"
|
||||
[[ -n "$rpc_url" ]] || { echo "missing rpc_url for chain $cid" >&2; exit 1; }
|
||||
[[ -n "$multicall" ]] || { echo "missing multicall for chain $cid" >&2; exit 1; }
|
||||
chain_hex="$(rpc_jsonrpc "$rpc_url" '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}' | python3 -c 'import json,sys; print(json.load(sys.stdin)["result"])')"
|
||||
block_hex="$(rpc_jsonrpc "$rpc_url" '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' | python3 -c 'import json,sys; print(json.load(sys.stdin)["result"])')"
|
||||
[[ "$chain_hex" == "0x$(printf '%x' "$cid")" ]] || { echo "chainId mismatch for chain $cid: $chain_hex" >&2; exit 1; }
|
||||
[[ "$block_hex" != "0x0" ]] || { echo "block height invalid for chain $cid" >&2; exit 1; }
|
||||
if [[ -n "$ws_url" ]]; then
|
||||
echo " ws_url configured"
|
||||
else
|
||||
echo " ws_url missing" >&2
|
||||
exit 1
|
||||
fi
|
||||
curl -fsS "${auth_header[@]}" "$BASE_URL/api/stats/freshness" | python3 -c 'import json,sys; rows=json.load(sys.stdin); cid=int(sys.argv[1]); assert any(int(r["chain_id"])==cid for r in rows)' "$cid" >/dev/null
|
||||
curl -fsS "${auth_header[@]}" "$BASE_URL/api/stats/venue-coverage" | python3 -c 'import json,sys; rows=json.load(sys.stdin); cid=int(sys.argv[1]); assert any(int(r["chain_id"])==cid for r in rows)' "$cid" >/dev/null
|
||||
done
|
||||
rm -f /tmp/mev_roadmap_live_targets.json
|
||||
echo "Per-chain live validation passed"
|
||||
fi
|
||||
|
||||
echo "MEV roadmap validation completed successfully"
|
||||
Reference in New Issue
Block a user