This project validates telemetry, runs ML inference using the supplied scaler contract, updates trust, assigns shards, and exposes a Flask API. The repo already contains a real state_scaler.pkl, and the platform is intentionally aligned to that exact 12-feature order.
The saved scaler is a scikit-learn StandardScaler with 12 required features. The repository does not currently include a production classifier pickle, so the code loads the best available model artifact and fails clearly if no classifier is available instead of silently inventing a model.
- HTTP telemetry ingestion and MQTT consumer support
- Feature validation and replay protection
- Trust scoring state
- Shard and validator logic
- Local ledger block creation
- Docker-ready deployment
- Simulator for normal and attack traffic
- Render deployment template with Sepolia testnet variables
- Python 3.11+
pip install -r requirements.txt- Optional: Docker
- Optional: PostgreSQL
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txtcopy .env.example .envRelevant environment values include the database URL, MQTT host, model paths, secret key, and trust thresholds.
The exact feature order is:
FEATURES = [
"posx", "posy", "posz",
"spdx", "spdy", "spdz",
"aclx", "acly", "aclz",
"hedx", "hedy", "hedz",
]Inference uses:
X = np.array([[features[name] for name in FEATURES]], dtype=np.float32)
X_scaled = scaler.transform(X)python app.pycurl http://127.0.0.1:5000/api/healthExample request:
curl -X POST http://127.0.0.1:5000/api/predict -H "Content-Type: application/json" -d "{\"vehicle_id\":\"veh_sim_1\",\"message_id\":\"msg-001\",\"sequence\":1,\"timestamp\":1788534955.68,\"features\":{\"posx\":12.3,\"posy\":-4.2,\"posz\":0,\"spdx\":0.5,\"spdy\":0.2,\"spdz\":0,\"aclx\":0,\"acly\":0,\"aclz\":0,\"hedx\":0,\"hedy\":0,\"hedz\":0}}"python simulator/run.py --vehicles 10 --interval 0.1 --attack-rate 0.10docker compose up --buildThe repository includes render.yaml for a free Render web service. The service
can be deployed without external credentials: it uses SQLite by default and
keeps Ethereum disabled until Sepolia values are supplied. Render supplies the
public PORT value at runtime.
SQLite on a free web service is temporary storage and may reset after restarts.
Add a hosted PostgreSQL DATABASE_URL later when persistent cloud storage is
needed.
For a free blockchain test environment, use Ethereum Sepolia. Deploy
contracts/TrustRegistry.sol to Sepolia, then configure:
ETH_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/<provider-key>
ETH_CHAIN_ID=11155111
ETH_ACCOUNT=0x<testnet-account>
ETH_PRIVATE_KEY=<testnet-private-key>
ETH_CONTRACT_ADDRESS=0x<deployed-contract>
Use test ETH only. Never place a mainnet private key in Render, .env, or the
repository. The service accepts ETH_CONTRACT_ADDRESS and the legacy
TRUST_CONTRACT_ADDRESS name.
Neon or another hosted PostgreSQL provider can optionally supply DATABASE_URL.
The local Docker stack continues to use Postgres and Mosquitto; a hosted MQTT
broker is needed if the cloud deployment must receive MQTT traffic, because
localhost and the Docker mqtt hostname are not reachable from Render.
pytest -q tests/test_inference.py tests/test_trust.pyCanonical topic:
iov/{vehicle_id}/telemetry
The target cloud architecture is:
Vehicle -> AWS IoT Core -> ECS Fargate -> Flask API -> RDS PostgreSQL
- Missing scaler: ensure
models/state_scaler.pklexists. - Model missing: add the classifier artifact to
models/classifier.pklor updateMODEL_PATH. - MQTT problems: confirm the broker is running and
MQTT_HOSTis correct. predict_statefailing: inspect the model artifact type and ensure it exposes a supported inference interface.
- Keep secrets outside source code.
- Validate message timestamps and replay IDs.
- Treat
NormalandTrustedas separate concepts. - Keep blockchain logging outside the synchronous telemetry critical path.
The repository contains the scaler but not a real classifier pickle. The platform is explicitly built to detect this and report it rather than fabricating a model interface.