feat: add blockchain RPC blocks-range endpoint and marketplace bid listing

Blockchain Node:
- Replace /blocks (pagination) with /blocks-range (height range query)
- Add start/end height parameters with 1000-block max range validation
- Return blocks in ascending height order instead of descending
- Update metrics names (rpc_get_blocks_range_*)
- Remove total count from response (return start/end/count instead)

Coordinator API:
- Add effective_url property to DatabaseConfig (SQLite/PostgreSQL defaults
This commit is contained in:
oib
2026-02-16 22:54:08 +01:00
parent fdc3012780
commit 31d3d70836
20 changed files with 3330 additions and 80 deletions

View File

@@ -40,6 +40,66 @@ Internet → aitbc.bubuit.net (HTTPS :443)
## Incus Host (localhost)
### Services (Host)
| Service | Port | Process | Python Version | Purpose | Status |
|---------|------|---------|----------------|---------|--------|
| Mock Coordinator | 8090 | python3 | 3.11+ | Development/testing API endpoint | systemd: aitbc-mock-coordinator.service |
| Blockchain Node | N/A | python3 | 3.11+ | Local blockchain node | systemd: aitbc-blockchain-node.service |
| Blockchain RPC API | 9080 | python3 | 3.11+ | RPC API for blockchain | systemd: aitbc-blockchain-rpc.service |
| GPU Miner Client | N/A | python3 | 3.11+ | GPU mining client | systemd: aitbc-gpu-miner.service |
| Local Development Tools | Varies | python3 | 3.11+ | CLI tools, scripts, testing | Manual/venv |
### Systemd Services (Host)
All services are configured as systemd units but currently inactive:
```bash
# Service files location: /etc/systemd/system/
aitbc-blockchain-node.service # Blockchain node main process
aitbc-blockchain-rpc.service # RPC API on port 9080
aitbc-gpu-miner.service # GPU mining client
aitbc-mock-coordinator.service # Mock coordinator on port 8090
```
**Service Details:**
- **Working Directory**: `/home/oib/windsurf/aitbc/apps/blockchain-node`
- **Python Environment**: `/home/oib/windsurf/aitbc/apps/blockchain-node/.venv/bin/python`
- **User**: oib
- **Restart Policy**: always (with 5s delay)
**Verification Commands:**
```bash
# Check service status
sc-status aitbc-blockchain-node.service aitbc-blockchain-rpc.service aitbc-gpu-miner.service aitbc-mock-coordinator.service
# Start services
sudo systemctl start aitbc-mock-coordinator.service
sudo systemctl start aitbc-blockchain-node.service
# Check logs
journalctl -u aitbc-mock-coordinator --no-pager -n 20
```
### Python Environment (Host)
Development and testing services on localhost use **Python 3.11+**:
```bash
# Localhost development workspace
/home/oib/windsurf/aitbc/ # Local development
├── .venv/ # Primary Python environment
├── cli/ # CLI tools (12 command groups)
├── scripts/ # Development scripts
└── tests/ # Pytest suites
```
**Verification Commands:**
```bash
python3 --version # Should show Python 3.11+
ls -la /home/oib/windsurf/aitbc/.venv/bin/python # Check venv
```
### Nginx Reverse Proxy
The host runs a simple reverse proxy that forwards all traffic to the container. SSL is terminated here via Let's Encrypt.
@@ -80,14 +140,32 @@ ssh aitbc-cascade # Direct SSH to container
### Services
| Service | Port | Process | Public URL |
|---------|------|---------|------------|
| Nginx (web) | 80 | nginx | https://aitbc.bubuit.net/ |
| Coordinator API | 8000 | python (uvicorn) | /api/ → /v1/ |
| Blockchain Node RPC | 8081 | python3 | /rpc/ |
| Wallet Daemon | 8002 | python | /wallet/ |
| Trade Exchange | 3002 | python (server.py) | /Exchange |
| Exchange API | 8085 | python | /api/trades/*, /api/orders/* |
| Service | Port | Process | Python Version | Public URL |
|---------|------|---------|----------------|------------|
| Nginx (web) | 80 | nginx | N/A | https://aitbc.bubuit.net/ |
| Coordinator API | 8000 | python (uvicorn) | 3.11+ | /api/ → /v1/ |
| Blockchain Node RPC | 8081 | python3 | 3.11+ | /rpc/ |
| Wallet Daemon | 8002 | python | 3.11+ | /wallet/ |
| Trade Exchange | 3002 | python (server.py) | 3.11+ | /Exchange |
| Exchange API | 8085 | python | 3.11+ | /api/trades/*, /api/orders/* |
### Python Environment Details
All Python services in the AITBC container run on **Python 3.11+** with isolated virtual environments:
```bash
# Container: aitbc (10.1.223.93)
/opt/coordinator-api/.venv/ # Coordinator API (uvicorn, FastAPI)
/opt/blockchain-node/.venv/ # Blockchain Node 1 (aitbc_chain)
/opt/blockchain-node-2/.venv/ # Blockchain Node 2 (aitbc_chain)
/opt/exchange/.venv/ # Exchange API (Flask/specific framework)
```
**Verification Commands:**
```bash
ssh aitbc-cascade "python3 --version" # Should show Python 3.11+
ssh aitbc-cascade "ls -la /opt/*/.venv/bin/python" # Check venv symlinks
```
### Nginx Routes (container)

View File

@@ -0,0 +1,104 @@
# Mock Coordinator Services Removal - RESOLVED
**Date:** February 16, 2026
**Status:** Resolved
**Severity:** Low
## Issue Description
Mock coordinator services were running on both localhost and AITBC server environments, creating potential confusion between development and production deployments. This could lead to testing against mock data instead of real production APIs.
## Affected Components
- **Localhost**: `aitbc-mock-coordinator.service`
- **AITBC Server**: `aitbc-coordinator.service` (mock version)
- **Production**: `aitbc-coordinator-api.service` (desired service)
## Root Cause Analysis
Historical development setup included mock coordinator services for testing purposes. These were never properly cleaned up when moving to production deployment, leading to:
- Multiple coordinator services running simultaneously
- Potential routing to mock endpoints instead of production
- Confusion about which service was handling requests
## Solution Implemented
### 1. Localhost Cleanup
```bash
# Stop and disable mock service
sudo systemctl stop aitbc-mock-coordinator.service
sudo systemctl disable aitbc-mock-coordinator.service
# Remove service file
sudo rm /etc/systemd/system/aitbc-mock-coordinator.service
sudo systemctl daemon-reload
```
### 2. AITBC Server Cleanup
```bash
# Stop and disable mock service
ssh aitbc-cascade "systemctl stop aitbc-coordinator.service"
ssh aitbc-cascade "systemctl disable aitbc-coordinator.service"
# Remove service file
ssh aitbc-cascade "rm /etc/systemd/system/aitbc-coordinator.service"
ssh aitbc-cascade "systemctl daemon-reload"
```
### 3. Production Service Verification
Confirmed production services running correctly:
- **Localhost**: `aitbc-coordinator-api.service` active on port 8000
- **AITBC Server**: `aitbc-coordinator-api.service` active in container
### 4. Database Configuration Fix
Fixed database configuration issue that was preventing localhost production service from starting:
- Added missing `effective_url` property to `DatabaseConfig` class
- Fixed module path in systemd service file
- Installed missing dependency (`python-json-logger`)
## Verification
Tested both production services:
```bash
# Localhost health check
curl -s http://localhost:8000/v1/health
# Response: {"status": "ok", "env": "dev"} ✅
# AITBC Server health check
curl -s https://aitbc.bubuit.net/api/health
# Response: {"status": "ok", "env": "dev"} ✅
```
## Service Configuration Differences
### Before Cleanup
- **Localhost**: Mock service + broken production service
- **AITBC Server**: Mock service + working production service
### After Cleanup
- **Localhost**: Working production service only
- **AITBC Server**: Working production service only
## Impact
- **Clarity**: Clear separation between development and production environments
- **Reliability**: Production requests no longer risk hitting mock endpoints
- **Maintenance**: Reduced service footprint and complexity
- **Performance**: Eliminated redundant services
## Lessons Learned
1. **Service Hygiene**: Always clean up mock/test services before production deployment
2. **Documentation**: Keep accurate inventory of running services
3. **Configuration**: Ensure production services have correct paths and dependencies
4. **Verification**: Test both environments after configuration changes
## Current Service Status
### Localhost Services
-`aitbc-coordinator-api.service` - Production API (active)
-`aitbc-mock-coordinator.service` - Mock API (removed)
### AITBC Server Services
-`aitbc-coordinator-api.service` - Production API (active)
-`aitbc-coordinator.service` - Mock API (removed)
## Related Documentation
- [Infrastructure Documentation](/docs/infrastructure.md)
- [Service Management Guidelines](/docs/operations/service-management.md)
- [Development vs Production Environments](/docs/development/environments.md)

View File

@@ -0,0 +1,92 @@
# Web Vitals 422 Error - RESOLVED
**Date:** February 16, 2026
**Status:** Resolved
**Severity:** Medium
## Issue Description
The `/api/web-vitals` endpoint was returning 422 Unprocessable Content errors when receiving performance metrics from the frontend. This prevented the collection of important web performance data.
## Affected Components
- **Backend**: `/apps/coordinator-api/src/app/routers/web_vitals.py` - API schema
- **Frontend**: `/website/assets/js/web-vitals.js` - Metrics collection script
- **Endpoint**: `/api/web-vitals` - POST endpoint for performance metrics
## Root Cause Analysis
The `WebVitalsEntry` Pydantic model in the backend only included three fields:
- `name` (required)
- `startTime` (optional)
- `duration` (optional)
However, the browser's Web Vitals library was sending additional fields for certain metrics:
- `value` - For CLS (Cumulative Layout Shift) metrics
- `hadRecentInput` - For CLS metrics to distinguish user-initiated shifts
When these extra fields were included in the JSON payload, Pydantic validation failed with a 422 error.
## Solution Implemented
### 1. Schema Enhancement
Updated the `WebVitalsEntry` model to include the missing optional fields:
```python
class WebVitalsEntry(BaseModel):
name: str
startTime: Optional[float] = None
duration: Optional[float] = None
value: Optional[float] = None # Added
hadRecentInput: Optional[bool] = None # Added
```
### 2. Defensive Processing
Added filtering logic to handle any unexpected fields that might be sent in the future:
```python
# Filter entries to only include supported fields
filtered_entries = []
for entry in metric.entries:
filtered_entry = {
"name": entry.name,
"startTime": entry.startTime,
"duration": entry.duration,
"value": entry.value,
"hadRecentInput": entry.hadRecentInput
}
# Remove None values
filtered_entry = {k: v for k, v in filtered_entry.items() if v is not None}
filtered_entries.append(filtered_entry)
```
### 3. Deployment
- Deployed changes to both localhost and AITBC server
- Restarted coordinator-api service on both systems
- Verified functionality with test requests
## Verification
Tested the fix with various Web Vitals payloads:
```bash
# Test with CLS metric (includes extra fields)
curl -X POST https://aitbc.bubuit.net/api/web-vitals \
-H "Content-Type: application/json" \
-d '{"name":"CLS","value":0.1,"id":"cls","delta":0.05,"entries":[{"name":"layout-shift","startTime":100,"duration":0,"value":0.1,"hadRecentInput":false}],"url":"https://aitbc.bubuit.net/","timestamp":"2026-02-16T20:00:00Z"}'
# Result: 200 OK ✅
```
## Impact
- **Before**: Web Vitals metrics collection was failing completely
- **After**: All Web Vitals metrics are now successfully collected and logged
- **Performance**: No performance impact on the API endpoint
- **Compatibility**: Backward compatible with existing frontend code
## Lessons Learned
1. **Schema Mismatch**: Always ensure backend schemas match frontend payloads exactly
2. **Optional Fields**: Web APIs often evolve with additional optional fields
3. **Defensive Programming**: Filter unknown fields to prevent future validation errors
4. **Testing**: Test with real frontend payloads, not just ideal ones
## Related Documentation
- [Web Vitals Documentation](https://web.dev/vitals/)
- [Pydantic Validation](https://pydantic-docs.helpmanual.io/)
- [FastAPI Error Handling](https://fastapi.tiangolo.com/tutorial/handling-errors/)