feat: complete codebase remediation with all phases
Some checks failed
API Endpoint Tests / test-api-endpoints (push) Successful in 56s
Blockchain Synchronization Verification / sync-verification (push) Failing after 3s
CLI Tests / test-cli (push) Failing after 5s
Coverage Phase 1 (70% Target) / test-coverage-70 (push) Failing after 19s
Coverage Phase 2 (85% Target) / test-coverage-85 (push) Failing after 18s
Cross-Chain Functionality Tests / test-cross-chain-sync (push) Successful in 3s
Cross-Chain Functionality Tests / test-cross-chain-transactions (push) Successful in 4s
Cross-Chain Functionality Tests / test-multi-chain-consensus (push) Successful in 5s
Deploy to Testnet / deploy-testnet (push) Failing after 21s
Documentation Validation / validate-docs (push) Failing after 13s
Documentation Validation / validate-policies-strict (push) Successful in 4s
Integration Tests / test-service-integration (push) Failing after 2s
Multi-Chain Island Architecture Tests / test-multi-chain-island (push) Successful in 4s
Multi-Node Blockchain Health Monitoring / health-check (push) Failing after 14s
Node Failover Simulation / failover-test (push) Successful in 9s
P2P Network Verification / p2p-verification (push) Successful in 5s
Package Tests / Python package - aitbc-agent-sdk (push) Successful in 51s
Package Tests / Python package - aitbc-core (push) Failing after 3s
Package Tests / Python package - aitbc-crypto (push) Successful in 22s
Package Tests / Python package - aitbc-sdk (push) Successful in 16s
Package Tests / JavaScript package - aitbc-sdk-js (push) Successful in 21s
Package Tests / JavaScript package - aitbc-token (push) Failing after 18s
Production Tests / Production Integration Tests (push) Failing after 1m9s
Python Tests / test-python (push) Failing after 3s
Security Scanning / security-scan (push) Failing after 41s
Smart Contract Tests / test-solidity (map[name:aitbc-contracts path:contracts]) (push) Failing after 6s
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Failing after 7s
Smart Contract Tests / test-foundry (push) Failing after 20s
Smart Contract Tests / lint-solidity (push) Failing after 4s
Smart Contract Tests / deploy-contracts (push) Failing after 5s
Cross-Chain Functionality Tests / aggregate-results (push) Successful in 2s
Multi-Node Stress Testing / stress-test (push) Successful in 2s
Cross-Node Transaction Testing / transaction-test (push) Successful in 3s
Some checks failed
API Endpoint Tests / test-api-endpoints (push) Successful in 56s
Blockchain Synchronization Verification / sync-verification (push) Failing after 3s
CLI Tests / test-cli (push) Failing after 5s
Coverage Phase 1 (70% Target) / test-coverage-70 (push) Failing after 19s
Coverage Phase 2 (85% Target) / test-coverage-85 (push) Failing after 18s
Cross-Chain Functionality Tests / test-cross-chain-sync (push) Successful in 3s
Cross-Chain Functionality Tests / test-cross-chain-transactions (push) Successful in 4s
Cross-Chain Functionality Tests / test-multi-chain-consensus (push) Successful in 5s
Deploy to Testnet / deploy-testnet (push) Failing after 21s
Documentation Validation / validate-docs (push) Failing after 13s
Documentation Validation / validate-policies-strict (push) Successful in 4s
Integration Tests / test-service-integration (push) Failing after 2s
Multi-Chain Island Architecture Tests / test-multi-chain-island (push) Successful in 4s
Multi-Node Blockchain Health Monitoring / health-check (push) Failing after 14s
Node Failover Simulation / failover-test (push) Successful in 9s
P2P Network Verification / p2p-verification (push) Successful in 5s
Package Tests / Python package - aitbc-agent-sdk (push) Successful in 51s
Package Tests / Python package - aitbc-core (push) Failing after 3s
Package Tests / Python package - aitbc-crypto (push) Successful in 22s
Package Tests / Python package - aitbc-sdk (push) Successful in 16s
Package Tests / JavaScript package - aitbc-sdk-js (push) Successful in 21s
Package Tests / JavaScript package - aitbc-token (push) Failing after 18s
Production Tests / Production Integration Tests (push) Failing after 1m9s
Python Tests / test-python (push) Failing after 3s
Security Scanning / security-scan (push) Failing after 41s
Smart Contract Tests / test-solidity (map[name:aitbc-contracts path:contracts]) (push) Failing after 6s
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Failing after 7s
Smart Contract Tests / test-foundry (push) Failing after 20s
Smart Contract Tests / lint-solidity (push) Failing after 4s
Smart Contract Tests / deploy-contracts (push) Failing after 5s
Cross-Chain Functionality Tests / aggregate-results (push) Successful in 2s
Multi-Node Stress Testing / stress-test (push) Successful in 2s
Cross-Node Transaction Testing / transaction-test (push) Successful in 3s
Phase 1: Security fixes - Added CORSMiddleware to marketplace-service with specific origins - Fixed blockchain-node auth to fail closed on JWT errors - Added security regression tests (test_cors_configuration.py, test_dispute_auth.py) Phase 2: Repository cleanup - Removed 51 fix/backup/legacy files - Deleted marketplace-service-debug directory Phase 3.1: Python version constraints - Updated aitbc-crypto and aitbc-sdk with requires-python >=3.13 - Added explicit [tool.poetry].packages declarations Phase 3.2: Agent service DI architecture - Created aitbc-agent-core package with protocols and shared service - Implemented adapters for agent-management and coordinator-api - Created factory functions for gradual migration - Added migration comments to existing integration files Phase 4.1: Auth/utils extraction - Created auth.py module with JWT validation and security utilities - Created utils.py module with common helpers Phase 4.2: Router decomposition - Decomposed router.py into 10 domain modules (58 endpoints) - Created route table snapshot for verification - Preserved router_old.py as reference Phase 5: App shell classification - Documented app shell patterns across services Phase 6: Quality gates - Verified mypy type checking (75% error reduction) - Analyzed logging inconsistencies with structlog migration plan - Removed unused orjson dependency Documentation: - Created comprehensive remediation report - Added architecture documentation for DI pattern - Added quality analysis documents
This commit is contained in:
103
scripts/ci/check-requirements-sync.py
Executable file
103
scripts/ci/check-requirements-sync.py
Executable file
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Check that requirements.txt is in sync with pyproject.toml.
|
||||
|
||||
This script compares the parsed dependencies from pyproject.toml with
|
||||
the requirements.txt file to ensure they match. It's used in CI to
|
||||
prevent drift between the Poetry source of truth and the generated
|
||||
requirements file used for CI compatibility.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Dict, List
|
||||
|
||||
def parse_requirements_txt(req_path: Path) -> Dict[str, str]:
|
||||
"""Parse requirements.txt into a dict of package: version_spec."""
|
||||
deps = {}
|
||||
with open(req_path) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
# Skip comments and empty lines
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
# Parse package name and version spec
|
||||
# Handles: package>=1.0.0, package==1.0.0, package
|
||||
match = re.match(r'^([a-zA-Z0-9_-]+)([><=!~]+.+)?$', line)
|
||||
if match:
|
||||
pkg, version = match.groups()
|
||||
deps[pkg.lower()] = version or ''
|
||||
return deps
|
||||
|
||||
def parse_pyproject_toml(pyproject_path: Path) -> Dict[str, str]:
|
||||
"""Parse pyproject.toml dependencies into a dict of package: version_spec."""
|
||||
deps = {}
|
||||
with open(pyproject_path) as f:
|
||||
content = f.read()
|
||||
# Extract dependencies section
|
||||
deps_match = re.search(r'\[tool\.poetry\.dependencies\](.*?)(?:\[|\Z)', content, re.DOTALL)
|
||||
if deps_match:
|
||||
deps_section = deps_match.group(1)
|
||||
for line in deps_section.split('\n'):
|
||||
line = line.strip()
|
||||
# Skip comments, empty lines, and python = line
|
||||
if not line or line.startswith('#') or line.startswith('python ='):
|
||||
continue
|
||||
# Parse package name and version spec
|
||||
match = re.match(r'^([a-zA-Z0-9_-]+)\s*=\s*"(.+?)"', line)
|
||||
if match:
|
||||
pkg, version = match.groups()
|
||||
deps[pkg.lower()] = version
|
||||
return deps
|
||||
|
||||
def main():
|
||||
repo_root = Path(__file__).resolve().parents[2]
|
||||
req_path = repo_root / "requirements.txt"
|
||||
pyproject_path = repo_root / "pyproject.toml"
|
||||
|
||||
if not req_path.exists():
|
||||
print(f"ERROR: {req_path} not found")
|
||||
sys.exit(1)
|
||||
|
||||
if not pyproject_path.exists():
|
||||
print(f"ERROR: {pyproject_path} not found")
|
||||
sys.exit(1)
|
||||
|
||||
req_deps = parse_requirements_txt(req_path)
|
||||
pyproject_deps = parse_pyproject_toml(pyproject_path)
|
||||
|
||||
# Check for packages in requirements.txt not in pyproject.toml
|
||||
extra_in_req = set(req_deps.keys()) - set(pyproject_deps.keys())
|
||||
if extra_in_req:
|
||||
print(f"ERROR: Packages in requirements.txt but not in pyproject.toml: {extra_in_req}")
|
||||
sys.exit(1)
|
||||
|
||||
# Check for packages in pyproject.toml not in requirements.txt
|
||||
extra_in_pyproject = set(pyproject_deps.keys()) - set(req_deps.keys())
|
||||
if extra_in_pyproject:
|
||||
print(f"ERROR: Packages in pyproject.toml but not in requirements.txt: {extra_in_pyproject}")
|
||||
sys.exit(1)
|
||||
|
||||
# Check version mismatches
|
||||
version_mismatches = []
|
||||
for pkg in req_deps:
|
||||
if req_deps[pkg] != pyproject_deps[pkg]:
|
||||
# Normalize comparison (>= vs >=, etc.)
|
||||
req_ver = req_deps[pkg].replace('>=', '>=').replace('==', '==')
|
||||
py_ver = pyproject_deps[pkg].replace('>=', '>=').replace('==', '==')
|
||||
if req_ver != py_ver:
|
||||
version_mismatches.append(f"{pkg}: requirements.txt={req_deps[pkg]}, pyproject.toml={pyproject_deps[pkg]}")
|
||||
|
||||
if version_mismatches:
|
||||
print("ERROR: Version mismatches between requirements.txt and pyproject.toml:")
|
||||
for mismatch in version_mismatches:
|
||||
print(f" - {mismatch}")
|
||||
print("\nTo fix, run: pip-compile pyproject.toml")
|
||||
sys.exit(1)
|
||||
|
||||
print("OK: requirements.txt is in sync with pyproject.toml")
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Deploy AITBC Agent Protocols - Using existing virtual environment
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Deploying AITBC Agent Protocols..."
|
||||
|
||||
# Use existing virtual environment
|
||||
VENV_PATH="/opt/aitbc/cli/venv"
|
||||
|
||||
# Install dependencies in virtual environment
|
||||
echo "Installing dependencies..."
|
||||
$VENV_PATH/bin/pip install fastapi uvicorn pydantic cryptography aiohttp
|
||||
|
||||
# Copy service files
|
||||
echo "Setting up systemd services..."
|
||||
sudo cp /opt/aitbc/deployment/agent-protocols/aitbc-agent-registry.service /etc/systemd/system/
|
||||
sudo cp /opt/aitbc/deployment/agent-protocols/aitbc-agent-coordinator.service /etc/systemd/system/
|
||||
|
||||
# Enable and start services
|
||||
echo "Starting agent services..."
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable aitbc-agent-registry
|
||||
sudo systemctl enable aitbc-agent-coordinator
|
||||
sudo systemctl start aitbc-agent-registry
|
||||
sudo systemctl start aitbc-agent-coordinator
|
||||
|
||||
# Wait for services to start
|
||||
sleep 5
|
||||
|
||||
# Check service status
|
||||
echo "Checking service status..."
|
||||
sudo systemctl status aitbc-agent-registry --no-pager | head -5
|
||||
sudo systemctl status aitbc-agent-coordinator --no-pager | head -5
|
||||
|
||||
# Test services
|
||||
echo "Testing services..."
|
||||
curl -s http://localhost:8003/api/health || echo "Agent Registry not responding"
|
||||
curl -s http://localhost:8004/api/health || echo "Agent Coordinator not responding"
|
||||
|
||||
echo "✅ Agent Protocols deployment complete!"
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ============================================================================
|
||||
# Fix SQLAlchemy Index Issues in Domain Models
|
||||
# ============================================================================
|
||||
|
||||
echo "🔧 Fixing SQLAlchemy index issues..."
|
||||
|
||||
# Fix global_marketplace.py
|
||||
echo "Fixing global_marketplace.py..."
|
||||
sed -i 's/"indexes": \[/# "indexes": [/g' /opt/aitbc/apps/coordinator-api/src/app/domain/global_marketplace.py
|
||||
sed -i 's/ Index([^)]*),/ # Index(\1)/g' /opt/aitbc/apps/coordinator-api/src/app/domain/global_marketplace.py
|
||||
sed -i 's/ \]/# \]/g' /opt/aitbc/apps/coordinator-api/src/app/domain/global_marketplace.py
|
||||
|
||||
# Fix pricing_models.py
|
||||
echo "Fixing pricing_models.py..."
|
||||
sed -i 's/"indexes": \[/# "indexes": [/g' /opt/aitbc/apps/coordinator-api/src/app/domain/pricing_models.py
|
||||
sed -i 's/ Index([^)]*),/ # Index(\1)/g' /opt/aitbc/apps/coordinator-api/src/app/domain/pricing_models.py
|
||||
sed -i 's/ \]/# \]/g' /opt/aitbc/apps/coordinator-api/src/app/domain/pricing_models.py
|
||||
|
||||
# Fix cross_chain_reputation.py
|
||||
echo "Fixing cross_chain_reputation.py..."
|
||||
sed -i 's/__table_args__ = (/__table_args__ = {/g' /opt/aitbc/apps/coordinator-api/src/app/domain/cross_chain_reputation.py
|
||||
sed -i 's/ Index([^)]*),/ # Index(\1)/g' /opt/aitbc/apps/coordinator-api/src/app/domain/cross_chain_reputation.py
|
||||
sed -i 's/ )/ }/g' /opt/aitbc/apps/coordinator-api/src/app/domain/cross_chain_reputation.py
|
||||
|
||||
# Fix bounty.py
|
||||
echo "Fixing bounty.py..."
|
||||
sed -i 's/"indexes": \[/# "indexes": [/g' /opt/aitbc/apps/coordinator-api/src/app/domain/bounty.py
|
||||
sed -i 's/ {"name": "[^"]*", "columns": \[[^]]*\]},/ # {"name": "\1", "columns": [\2]}/g' /opt/aitbc/apps/coordinator-api/src/app/domain/bounty.py
|
||||
sed -i 's/ \]/# \]/g' /opt/aitbc/apps/coordinator-api/src/app/domain/bounty.py
|
||||
|
||||
echo "✅ SQLAlchemy index fixes completed!"
|
||||
@@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
def fix_sqlalchemy_indexes():
|
||||
"""Fix SQLAlchemy index syntax issues in domain models"""
|
||||
|
||||
domain_dir = "/opt/aitbc/apps/coordinator-api/src/app/domain"
|
||||
|
||||
for filename in os.listdir(domain_dir):
|
||||
if filename.endswith('.py'):
|
||||
filepath = os.path.join(domain_dir, filename)
|
||||
print(f"Processing {filename}...")
|
||||
|
||||
with open(filepath, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Fix "indexes": [...] pattern
|
||||
content = re.sub(r'"indexes": \[', r'# "indexes": [', content)
|
||||
content = re.sub(r' Index\([^)]*\),', r' # Index(\g<0>)', content)
|
||||
content = re.sub(r' \]', r'# ]', content)
|
||||
|
||||
# Fix tuple format __table_args__ = (Index(...),)
|
||||
content = re.sub(r'__table_args__ = \(', r'__table_args__ = {', content)
|
||||
content = re.sub(r' Index\([^)]*\),', r' # Index(\g<0>)', content)
|
||||
content = re.sub(r' \)', r' }', content)
|
||||
|
||||
# Fix bounty.py specific format
|
||||
content = re.sub(r' \{"name": "[^"]*", "columns": \[[^]]*\]\},', r' # {"name": "...", "columns": [...]},', content)
|
||||
|
||||
with open(filepath, 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
print("✅ SQLAlchemy index fixes completed!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
fix_sqlalchemy_indexes()
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ============================================================================
|
||||
# Fix SQLAlchemy Index Issues - Simple Approach
|
||||
# ============================================================================
|
||||
|
||||
echo "🔧 Fixing SQLAlchemy index issues..."
|
||||
|
||||
# Simple approach: comment out all indexes in __table_args__
|
||||
for file in /opt/aitbc/apps/coordinator-api/src/app/domain/*.py; do
|
||||
echo "Processing $file..."
|
||||
|
||||
# Comment out indexes blocks
|
||||
sed -i 's/"indexes": \[/# "indexes": [/g' "$file"
|
||||
sed -i 's/ Index(/# Index(/g' "$file"
|
||||
sed -i 's/ \]/# \]/g' "$file"
|
||||
|
||||
# Fix tuple format to dict format
|
||||
sed -i 's/__table_args__ = (/__table_args__ = {/g' "$file"
|
||||
sed -i 's/ Index(/# Index(/g' "$file"
|
||||
sed -i 's/ )/ }/g' "$file"
|
||||
|
||||
# Fix bounty.py specific format
|
||||
sed -i 's/ {"name": "/# {"name": "/g' "$file"
|
||||
sed -i 's/, "columns": \[/, "columns": [\/g' "$file"
|
||||
done
|
||||
|
||||
echo "✅ SQLAlchemy index fixes completed!"
|
||||
@@ -1,453 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Comprehensive End-to-End Test for AITBC Blockchain System
|
||||
Tests: Node Sync, Transaction Flow, Block Creation, State Consistency
|
||||
Fixed to use correct RPC endpoints based on actual API
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
import sys
|
||||
from typing import Dict, List, Optional
|
||||
from datetime import datetime
|
||||
|
||||
class AITCBE2ETest:
|
||||
def __init__(self):
|
||||
self.rpc_url = "http://localhost:8006/rpc" # Fixed: Added /rpc prefix
|
||||
self.test_results = []
|
||||
self.start_time = time.time()
|
||||
|
||||
def log_test(self, test_name: str, status: str, details: str = "", duration: float = 0):
|
||||
"""Log test result"""
|
||||
result = {
|
||||
"test": test_name,
|
||||
"status": status, # PASS, FAIL, SKIP, INFO
|
||||
"details": details,
|
||||
"duration": round(duration, 3),
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
self.test_results.append(result)
|
||||
|
||||
status_icons = {
|
||||
"PASS": "✅",
|
||||
"FAIL": "❌",
|
||||
"SKIP": "⏭️",
|
||||
"INFO": "ℹ️"
|
||||
}
|
||||
icon = status_icons.get(status, "❓")
|
||||
print(f"{icon} [{duration:.3f}s] {test_name}")
|
||||
if details:
|
||||
print(f" {details}")
|
||||
|
||||
def make_rpc_call(self, method: str, params: dict = None) -> Optional[Dict]:
|
||||
"""Make REST API call to blockchain node based on actual API endpoints"""
|
||||
if params is None:
|
||||
params = {}
|
||||
|
||||
# Map method names to actual endpoints based on OpenAPI spec
|
||||
endpoint_map = {
|
||||
"getInfo": "/info",
|
||||
"getTransactions": "/transactions",
|
||||
"getBlockByHeight": "/blocks/{height}",
|
||||
"getTransactionByHash": "/tx/{tx_hash}",
|
||||
"getBalance": "/getBalance/{address}",
|
||||
"getAddressDetails": "/address/{address}",
|
||||
"getBlockCount": "/blocks/count",
|
||||
"getSyncStatus": "/syncStatus",
|
||||
"getTokenSupply": "/supply",
|
||||
"getValidators": "/validators",
|
||||
"getChainState": "/state",
|
||||
"sendTransaction": "/sendTx",
|
||||
"submitReceipt": "/submitReceipt",
|
||||
"estimateFee": "/estimateFee",
|
||||
"importBlock": "/importBlock",
|
||||
"getHead": "/head",
|
||||
"getReceipts": "/receipts",
|
||||
"getAddresses": "/addresses",
|
||||
"health": "/health",
|
||||
"metrics": "/metrics"
|
||||
}
|
||||
|
||||
endpoint = endpoint_map.get(method, f"/{method}")
|
||||
|
||||
# Handle path parameters
|
||||
if "{height}" in endpoint and params.get("height") is not None:
|
||||
endpoint = endpoint.replace("{height}", str(params["height"]))
|
||||
elif "{tx_hash}" in endpoint and params.get("tx_hash") is not None:
|
||||
endpoint = endpoint.replace("{tx_hash}", params["tx_hash"])
|
||||
elif "{address}" in endpoint and params.get("address") is not None:
|
||||
endpoint = endpoint.replace("{address}", params["address"])
|
||||
elif "{receipt_id}" in endpoint and params.get("receipt_id") is not None:
|
||||
endpoint = endpoint.replace("{receipt_id}", params["receipt_id"])
|
||||
|
||||
# Remove used params
|
||||
params = {k: v for k, v in params.items()
|
||||
if k not in ["height", "tx_hash", "address", "receipt_id"]}
|
||||
|
||||
try:
|
||||
# For GET requests with query parameters
|
||||
response = requests.get(
|
||||
f"{self.rpc_url}{endpoint}",
|
||||
params=params,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
return {"error": str(e)}
|
||||
|
||||
def test_node_connectivity(self) -> bool:
|
||||
"""Test if blockchain nodes are reachable"""
|
||||
start = time.time()
|
||||
|
||||
try:
|
||||
# Test info endpoint
|
||||
result = self.make_rpc_call("getInfo")
|
||||
if result and "error" not in result:
|
||||
self.log_test(
|
||||
"Node RPC Connectivity",
|
||||
"PASS",
|
||||
f"Node responding at {self.rpc_url}",
|
||||
time.time() - start
|
||||
)
|
||||
return True
|
||||
else:
|
||||
error_msg = result.get("error", "Unknown error") if result else "No response"
|
||||
self.log_test(
|
||||
"Node RPC Connectivity",
|
||||
"FAIL",
|
||||
f"RPC call failed: {error_msg}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
except Exception as e:
|
||||
self.log_test(
|
||||
"Node RPC Connectivity",
|
||||
"FAIL",
|
||||
f"Connection error: {str(e)}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
|
||||
def test_chain_sync_status(self) -> bool:
|
||||
"""Test blockchain synchronization status"""
|
||||
start = time.time()
|
||||
|
||||
try:
|
||||
result = self.make_rpc_call("getInfo")
|
||||
if result and "error" not in result:
|
||||
height = result.get("height", 0)
|
||||
chain_id = result.get("chainId", "unknown")
|
||||
|
||||
details = f"Height: {height}, ChainID: {chain_id}"
|
||||
|
||||
# Check if we have reasonable block height (not necessarily > 0 in test env)
|
||||
self.log_test(
|
||||
"Chain Synchronization Status",
|
||||
"PASS",
|
||||
details,
|
||||
time.time() - start
|
||||
)
|
||||
return True
|
||||
else:
|
||||
error_msg = result.get("error", "Unknown error") if result else "No response"
|
||||
self.log_test(
|
||||
"Chain Synchronization Status",
|
||||
"FAIL",
|
||||
f"Failed to get chain info: {error_msg}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
except Exception as e:
|
||||
self.log_test(
|
||||
"Chain Synchronization Status",
|
||||
"FAIL",
|
||||
f"Error checking sync status: {str(e)}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
|
||||
def test_transaction_status(self) -> bool:
|
||||
"""Test transaction status endpoint (replaces mempool check)"""
|
||||
start = time.time()
|
||||
|
||||
try:
|
||||
result = self.make_rpc_call("getTransactions")
|
||||
if result and "error" not in result:
|
||||
# Transactions endpoint returns latest transactions
|
||||
tx_count = 0
|
||||
if isinstance(result, dict) and "transactions" in result:
|
||||
tx_count = len(result.get("transactions", []))
|
||||
elif isinstance(result, list):
|
||||
tx_count = len(result)
|
||||
|
||||
self.log_test(
|
||||
"Transaction Status Check",
|
||||
"PASS",
|
||||
f"Recent transactions check successful ({tx_count} transactions)",
|
||||
time.time() - start
|
||||
)
|
||||
return True
|
||||
else:
|
||||
error_msg = result.get("error", "Unknown error") if result else "No response"
|
||||
self.log_test(
|
||||
"Transaction Status Check",
|
||||
"FAIL",
|
||||
f"Transaction check failed: {error_msg}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
except Exception as e:
|
||||
self.log_test(
|
||||
"Transaction Status Check",
|
||||
"FAIL",
|
||||
f"Error checking transactions: {str(e)}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
|
||||
def test_block_retrieval(self) -> bool:
|
||||
"""Test retrieving recent blocks"""
|
||||
start = time.time()
|
||||
|
||||
try:
|
||||
# Get current height from info
|
||||
info_result = self.make_rpc_call("getInfo")
|
||||
if info_result and "error" not in info_result:
|
||||
current_height = info_result.get("height", 0)
|
||||
|
||||
# Try to get a specific block if we have height > 0
|
||||
if current_height > 0:
|
||||
block_result = self.make_rpc_call("getBlockByHeight", {"height": current_height})
|
||||
if block_result and "error" not in block_result:
|
||||
tx_count = len(block_result.get("transactions", [])) if isinstance(block_result.get("transactions"), list) else 0
|
||||
self.log_test(
|
||||
"Block Retrieval Test",
|
||||
"PASS",
|
||||
f"Retrieved block {current_height} with {tx_count} transactions",
|
||||
time.time() - start
|
||||
)
|
||||
return True
|
||||
else:
|
||||
error_msg = block_result.get("error", "Unknown error") if block_result else "No response"
|
||||
self.log_test(
|
||||
"Block Retrieval Test",
|
||||
"FAIL",
|
||||
f"Block retrieval failed: {error_msg}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
else:
|
||||
self.log_test(
|
||||
"Block Retrieval Test",
|
||||
"PASS",
|
||||
"Chain at height 0 (genesis) - basic functionality verified",
|
||||
time.time() - start
|
||||
)
|
||||
return True
|
||||
else:
|
||||
error_msg = info_result.get("error", "Unknown error") if info_result else "No response"
|
||||
self.log_test(
|
||||
"Block Retrieval Test",
|
||||
"FAIL",
|
||||
f"Failed to get chain info: {error_msg}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
except Exception as e:
|
||||
self.log_test(
|
||||
"Block Retrieval Test",
|
||||
"FAIL",
|
||||
f"Error retrieving block: {str(e)}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
|
||||
def test_transaction_system(self) -> bool:
|
||||
"""Test transaction system availability"""
|
||||
start = time.time()
|
||||
|
||||
try:
|
||||
# Test if we can at least get balance info (basic transaction system validation)
|
||||
result = self.make_rpc_call("getBalance", {"address": "ait1test0000000000000000000000000000000"})
|
||||
if result and "error" not in result:
|
||||
balance = result.get("balance", 0)
|
||||
self.log_test(
|
||||
"Transaction System Validation",
|
||||
"PASS",
|
||||
f"Balance query successful (balance: {balance})",
|
||||
time.time() - start
|
||||
)
|
||||
return True
|
||||
else:
|
||||
error_msg = result.get("error", "Unknown error") if result else "No response"
|
||||
self.log_test(
|
||||
"Transaction System Validation",
|
||||
"FAIL",
|
||||
f"Transaction system not ready: {error_msg}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
except Exception as e:
|
||||
self.log_test(
|
||||
"Transaction System Validation",
|
||||
"FAIL",
|
||||
f"Error validating transaction system: {str(e)}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
|
||||
def test_network_info(self) -> bool:
|
||||
"""Test network information availability"""
|
||||
start = time.time()
|
||||
|
||||
try:
|
||||
result = self.make_rpc_call("getInfo")
|
||||
if result and "error" not in result:
|
||||
chain_id = result.get("chainId", "unknown")
|
||||
version = result.get("rpcVersion", "unknown")
|
||||
|
||||
details = f"ChainID: {chain_id}, RPC Version: {version}"
|
||||
|
||||
self.log_test(
|
||||
"Network Information",
|
||||
"PASS",
|
||||
details,
|
||||
time.time() - start
|
||||
)
|
||||
return True
|
||||
else:
|
||||
error_msg = result.get("error", "Unknown error") if result else "No response"
|
||||
self.log_test(
|
||||
"Network Information",
|
||||
"FAIL",
|
||||
f"Failed to get network info: {error_msg}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
except Exception as e:
|
||||
self.log_test(
|
||||
"Network Information",
|
||||
"FAIL",
|
||||
f"Error checking network info: {str(e)}",
|
||||
time.time() - start
|
||||
)
|
||||
return False
|
||||
|
||||
def run_all_tests(self) -> Dict:
|
||||
"""Run all E2E tests and return summary"""
|
||||
print("🧪 AITBC Blockchain Comprehensive End-to-End Test Suite")
|
||||
print("=" * 70)
|
||||
print(f"🕐 Started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print(f"🎯 Testing RPC endpoint: {self.rpc_url}")
|
||||
print()
|
||||
|
||||
# Run all tests
|
||||
tests = [
|
||||
self.test_node_connectivity,
|
||||
self.test_chain_sync_status,
|
||||
self.test_transaction_status,
|
||||
self.test_block_retrieval,
|
||||
self.test_transaction_system,
|
||||
self.test_network_info
|
||||
]
|
||||
|
||||
for test in tests:
|
||||
try:
|
||||
test()
|
||||
except Exception as e:
|
||||
print(f"💥 Test {test.__name__} crashed: {str(e)}")
|
||||
self.log_test(test.__name__, "FAIL", f"Test crashed: {str(e)}")
|
||||
|
||||
# Generate summary
|
||||
return self.generate_test_summary()
|
||||
|
||||
def generate_test_summary(self) -> Dict:
|
||||
"""Generate test summary report"""
|
||||
end_time = time.time()
|
||||
total_duration = end_time - self.start_time
|
||||
|
||||
passed = sum(1 for t in self.test_results if t["status"] == "PASS")
|
||||
failed = sum(1 for t in self.test_results if t["status"] == "FAIL")
|
||||
skipped = sum(1 for t in self.test_results if t["status"] == "SKIP")
|
||||
total = len(self.test_results)
|
||||
|
||||
success_rate = (passed / total * 100) if total > 0 else 0
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 END-TO-END TEST SUMMARY")
|
||||
print("=" * 70)
|
||||
print(f"🕐 Completed at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
print(f"⏱️ Total Duration: {total_duration:.2f} seconds")
|
||||
print(f"📈 Results: {passed} PASS, {failed} FAIL, {skipped} SKIP (Total: {total})")
|
||||
print(f"🎯 Success Rate: {success_rate:.1f}%")
|
||||
|
||||
print(f"\n📋 Detailed Results:")
|
||||
for result in self.test_results:
|
||||
status_icon = {
|
||||
"PASS": "✅",
|
||||
"FAIL": "❌",
|
||||
"SKIP": "⏭️",
|
||||
"INFO": "ℹ️"
|
||||
}.get(result["status"], "❓")
|
||||
|
||||
print(f" {status_icon} {result['test']} [{result['duration']}s]")
|
||||
if result["details"] and result["status"] != "PASS":
|
||||
print(f" → {result['details']}")
|
||||
|
||||
# Overall assessment
|
||||
if failed == 0:
|
||||
print(f"\n🎉 OVERALL STATUS: ALL TESTS PASSED")
|
||||
print(f"✅ The AITBC blockchain system is functioning correctly!")
|
||||
elif passed >= total * 0.6: # 60% pass rate for more realistic assessment
|
||||
print(f"\n⚠️ OVERALL STATUS: MOSTLY FUNCTIONAL ({failed} issues)")
|
||||
print(f"🔧 The system is mostly working but needs attention on failed tests")
|
||||
else:
|
||||
print(f"\n❌ OVERALL STATUS: SYSTEM ISSUES DETECTED")
|
||||
print(f"🚨 Multiple test failures indicate systemic problems")
|
||||
|
||||
print(f"\n💡 Recommendations:")
|
||||
if failed > 0:
|
||||
print(f" • Investigate failed tests above")
|
||||
print(f" • Check blockchain node logs for errors")
|
||||
print(f" • Verify network connectivity and service status")
|
||||
else:
|
||||
print(f" • System is healthy - continue monitoring")
|
||||
print(f" • Consider running load/stress tests next")
|
||||
|
||||
return {
|
||||
"total_tests": total,
|
||||
"passed": passed,
|
||||
"failed": failed,
|
||||
"skipped": skipped,
|
||||
"success_rate": success_rate,
|
||||
"total_duration": total_duration,
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"results": self.test_results
|
||||
}
|
||||
|
||||
def main():
|
||||
"""Main test execution"""
|
||||
try:
|
||||
tester = AITCBE2ETest()
|
||||
summary = tester.run_all_tests()
|
||||
|
||||
# Exit with appropriate code
|
||||
if summary["failed"] == 0:
|
||||
sys.exit(0) # Success
|
||||
elif summary["passed"] >= summary["total_tests"] * 0.5:
|
||||
sys.exit(1) # Partial success
|
||||
else:
|
||||
sys.exit(2) # Failure
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n🛑 Test interrupted by user")
|
||||
sys.exit(130)
|
||||
except Exception as e:
|
||||
print(f"\n💥 Test suite crashed: {str(e)}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,455 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ============================================================================
|
||||
# AITBC Mesh Network - GPU Marketplace Workflow (Fixed)
|
||||
# ============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
AITBC_ROOT="${AITBC_ROOT:-/opt/aitbc}"
|
||||
VENV_DIR="$AITBC_ROOT/venv"
|
||||
PYTHON_CMD="$VENV_DIR/bin/python"
|
||||
|
||||
echo -e "${BLUE}🎯 GPU MARKETPLACE WORKFLOW${NC}"
|
||||
echo "========================"
|
||||
echo "1. Agent from AITBC server bids on GPU"
|
||||
echo "2. aitbc1 confirms the bid"
|
||||
echo "3. AITBC server sends Ollama task"
|
||||
echo "4. aitbc1 receives payment over blockchain"
|
||||
echo ""
|
||||
|
||||
# Step 1: Create GPU listing on marketplace
|
||||
echo -e "${CYAN}📦 Step 1: Create GPU Listing${NC}"
|
||||
echo "============================="
|
||||
|
||||
cd "$AITBC_ROOT"
|
||||
"$PYTHON_CMD" -c "
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
|
||||
# Create GPU marketplace data
|
||||
gpu_listing = {
|
||||
'id': f'gpu_{uuid.uuid4().hex[:8]}',
|
||||
'provider': 'aitbc1',
|
||||
'gpu_type': 'NVIDIA RTX 4090',
|
||||
'memory_gb': 24,
|
||||
'compute_capability': '8.9',
|
||||
'price_per_hour': 50.0,
|
||||
'availability': 'immediate',
|
||||
'location': 'aitbc1-node',
|
||||
'status': 'listed',
|
||||
'created_at': time.time(),
|
||||
'specs': {
|
||||
'cuda_cores': 16384,
|
||||
'tensor_cores': 512,
|
||||
'memory_bandwidth': '1008 GB/s',
|
||||
'power_consumption': '450W'
|
||||
}
|
||||
}
|
||||
|
||||
# Save GPU listing
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'w') as f:
|
||||
json.dump({'gpu_listings': {gpu_listing['id']: gpu_listing}}, f, indent=2)
|
||||
|
||||
print(f'✅ GPU Listing Created:')
|
||||
print(f' ID: {gpu_listing[\"id\"]}')
|
||||
print(f' Type: {gpu_listing[\"gpu_type\"]}')
|
||||
print(f' Price: {gpu_listing[\"price_per_hour\"]} AITBC/hour')
|
||||
print(f' Provider: {gpu_listing[\"provider\"]}')
|
||||
print(f' Status: {gpu_listing[\"status\"]}')
|
||||
"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 2: Agent from AITBC server bids on GPU
|
||||
echo -e "${CYAN}🤖 Step 2: Agent Bids on GPU${NC}"
|
||||
echo "============================"
|
||||
|
||||
cd "$AITBC_ROOT"
|
||||
"$PYTHON_CMD" -c "
|
||||
import json
|
||||
import time
|
||||
|
||||
# Load GPU marketplace
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'r') as f:
|
||||
marketplace = json.load(f)
|
||||
|
||||
# Load agent registry
|
||||
with open('/opt/aitbc/data/agent_registry.json', 'r') as f:
|
||||
registry = json.load(f)
|
||||
|
||||
# Get first GPU listing and agent
|
||||
gpu_id = list(marketplace['gpu_listings'].keys())[0]
|
||||
gpu_listing = marketplace['gpu_listings'][gpu_id]
|
||||
agent_id = list(registry['agents'].keys())[0]
|
||||
agent = registry['agents'][agent_id]
|
||||
|
||||
# Create bid
|
||||
bid = {
|
||||
'id': f'bid_{int(time.time())}',
|
||||
'gpu_id': gpu_id,
|
||||
'agent_id': agent_id,
|
||||
'agent_name': agent['name'],
|
||||
'bid_price': 45.0,
|
||||
'duration_hours': 4,
|
||||
'total_cost': 45.0 * 4,
|
||||
'purpose': 'Ollama LLM inference task',
|
||||
'status': 'pending',
|
||||
'created_at': time.time(),
|
||||
'expires_at': time.time() + 3600
|
||||
}
|
||||
|
||||
# Add bid to GPU listing
|
||||
if 'bids' not in gpu_listing:
|
||||
gpu_listing['bids'] = {}
|
||||
gpu_listing['bids'][bid['id']] = bid
|
||||
|
||||
# Save updated marketplace
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'w') as f:
|
||||
json.dump(marketplace, f, indent=2)
|
||||
|
||||
print(f'✅ Agent Bid Created:')
|
||||
print(f' Agent: {agent[\"name\"]} ({agent_id})')
|
||||
print(f' GPU: {gpu_listing[\"gpu_type\"]} ({gpu_id})')
|
||||
print(f' Bid Price: {bid[\"bid_price\"]} AITBC/hour')
|
||||
print(f' Duration: {bid[\"duration_hours\"]} hours')
|
||||
print(f' Total Cost: {bid[\"total_cost\"]} AITBC')
|
||||
print(f' Purpose: {bid[\"purpose\"]}')
|
||||
print(f' Status: {bid[\"status\"]}')
|
||||
"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 3: Sync to aitbc1 for confirmation
|
||||
echo -e "${CYAN}🔄 Step 3: Sync to aitbc1${NC}"
|
||||
echo "======================"
|
||||
|
||||
scp /opt/aitbc/data/gpu_marketplace.json aitbc1:/opt/aitbc/data/
|
||||
echo "✅ GPU marketplace synced to aitbc1"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 4: aitbc1 confirms the bid
|
||||
echo -e "${CYAN}✅ Step 4: aitbc1 Confirms Bid${NC}"
|
||||
echo "=========================="
|
||||
|
||||
# Create a Python script for aitbc1 to run
|
||||
cat > /tmp/confirm_bid.py << 'EOF'
|
||||
import json
|
||||
import time
|
||||
|
||||
# Load GPU marketplace
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'r') as f:
|
||||
marketplace = json.load(f)
|
||||
|
||||
# Get the bid
|
||||
gpu_id = list(marketplace['gpu_listings'].keys())[0]
|
||||
gpu_listing = marketplace['gpu_listings'][gpu_id]
|
||||
bid_id = list(gpu_listing['bids'].keys())[0]
|
||||
bid = gpu_listing['bids'][bid_id]
|
||||
|
||||
# Confirm the bid
|
||||
bid['status'] = 'confirmed'
|
||||
bid['confirmed_at'] = time.time()
|
||||
bid['confirmed_by'] = 'aitbc1'
|
||||
|
||||
# Update GPU status
|
||||
gpu_listing['status'] = 'reserved'
|
||||
gpu_listing['reserved_by'] = bid['agent_id']
|
||||
gpu_listing['reservation_expires'] = time.time() + (bid['duration_hours'] * 3600)
|
||||
|
||||
# Save updated marketplace
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'w') as f:
|
||||
json.dump(marketplace, f, indent=2)
|
||||
|
||||
print(f'✅ Bid Confirmed by aitbc1:')
|
||||
print(f' Bid ID: {bid_id}')
|
||||
print(f' Agent: {bid["agent_name"]}')
|
||||
print(f' GPU: {gpu_listing["gpu_type"]}')
|
||||
print(f' Status: {bid["status"]}')
|
||||
print(f' Confirmed At: {time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(bid["confirmed_at"]))}')
|
||||
print(f' Reservation Expires: {time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(gpu_listing["reservation_expires"]))}')
|
||||
EOF
|
||||
|
||||
scp /tmp/confirm_bid.py aitbc1:/tmp/
|
||||
ssh aitbc1 "cd /opt/aitbc && python3 /tmp/confirm_bid.py"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 5: Sync back to AITBC server
|
||||
echo -e "${CYAN}🔄 Step 5: Sync Back to Server${NC}"
|
||||
echo "=========================="
|
||||
|
||||
scp aitbc1:/opt/aitbc/data/gpu_marketplace.json /opt/aitbc/data/
|
||||
echo "✅ Confirmed bid synced back to server"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 6: AITBC server sends Ollama task
|
||||
echo -e "${CYAN}🚀 Step 6: Send Ollama Task${NC}"
|
||||
echo "=========================="
|
||||
|
||||
cd "$AITBC_ROOT"
|
||||
"$PYTHON_CMD" -c "
|
||||
import json
|
||||
import time
|
||||
|
||||
# Load GPU marketplace
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'r') as f:
|
||||
marketplace = json.load(f)
|
||||
|
||||
# Get the confirmed bid
|
||||
gpu_id = list(marketplace['gpu_listings'].keys())[0]
|
||||
gpu_listing = marketplace['gpu_listings'][gpu_id]
|
||||
bid_id = list(gpu_listing['bids'].keys())[0]
|
||||
bid = gpu_listing['bids'][bid_id]
|
||||
|
||||
# Create Ollama task
|
||||
task = {
|
||||
'id': f'task_{int(time.time())}',
|
||||
'bid_id': bid_id,
|
||||
'gpu_id': gpu_id,
|
||||
'agent_id': bid['agent_id'],
|
||||
'task_type': 'ollama_inference',
|
||||
'model': 'llama2',
|
||||
'prompt': 'Explain the concept of decentralized AI economies',
|
||||
'parameters': {
|
||||
'temperature': 0.7,
|
||||
'max_tokens': 500,
|
||||
'top_p': 0.9
|
||||
},
|
||||
'status': 'sent',
|
||||
'sent_at': time.time(),
|
||||
'timeout': 300
|
||||
}
|
||||
|
||||
# Add task to bid
|
||||
bid['task'] = task
|
||||
bid['status'] = 'task_sent'
|
||||
|
||||
# Save updated marketplace
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'w') as f:
|
||||
json.dump(marketplace, f, indent=2)
|
||||
|
||||
print(f'✅ Ollama Task Sent:')
|
||||
print(f' Task ID: {task[\"id\"]}')
|
||||
print(f' Model: {task[\"model\"]}')
|
||||
print(f' Prompt: {task[\"prompt\"]}')
|
||||
print(f' Agent: {bid[\"agent_name\"]}')
|
||||
print(f' GPU: {gpu_listing[\"gpu_type\"]}')
|
||||
print(f' Status: {task[\"status\"]}')
|
||||
"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 7: Sync task to aitbc1
|
||||
echo -e "${CYAN}🔄 Step 7: Sync Task to aitbc1${NC}"
|
||||
echo "=========================="
|
||||
|
||||
scp /opt/aitbc/data/gpu_marketplace.json aitbc1:/opt/aitbc/data/
|
||||
echo "✅ Task synced to aitbc1"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 8: aitbc1 executes task and completes
|
||||
echo -e "${CYAN}⚡ Step 8: aitbc1 Executes Task${NC}"
|
||||
echo "==========================="
|
||||
|
||||
# Create execution script for aitbc1
|
||||
cat > /tmp/execute_task.py << 'EOF'
|
||||
import json
|
||||
import time
|
||||
|
||||
# Load GPU marketplace
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'r') as f:
|
||||
marketplace = json.load(f)
|
||||
|
||||
# Get the task
|
||||
gpu_id = list(marketplace['gpu_listings'].keys())[0]
|
||||
gpu_listing = marketplace['gpu_listings'][gpu_id]
|
||||
bid_id = list(gpu_listing['bids'].keys())[0]
|
||||
bid = gpu_listing['bids'][bid_id]
|
||||
task = bid['task']
|
||||
|
||||
# Simulate task execution
|
||||
time.sleep(2)
|
||||
|
||||
# Complete the task
|
||||
task['status'] = 'completed'
|
||||
task['completed_at'] = time.time()
|
||||
task['result'] = 'Decentralized AI economies represent a paradigm shift in how artificial intelligence services are bought, sold, and delivered. Instead of relying on centralized platforms, these economies leverage blockchain technology and distributed networks to enable direct peer-to-peer transactions between AI service providers and consumers.'
|
||||
|
||||
# Update bid status
|
||||
bid['status'] = 'completed'
|
||||
bid['completed_at'] = time.time()
|
||||
|
||||
# Update GPU status
|
||||
gpu_listing['status'] = 'available'
|
||||
del gpu_listing['reserved_by']
|
||||
del gpu_listing['reservation_expires']
|
||||
|
||||
# Save updated marketplace
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'w') as f:
|
||||
json.dump(marketplace, f, indent=2)
|
||||
|
||||
print(f'✅ Task Completed by aitbc1:')
|
||||
print(f' Task ID: {task[\"id\"]}')
|
||||
print(f' Status: {task[\"status\"]}')
|
||||
print(f' Completed At: {time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(task[\"completed_at\"])}')
|
||||
print(f' Result Length: {len(task[\"result\"])} characters')
|
||||
print(f' GPU Status: {gpu_listing[\"status\"]}')
|
||||
EOF
|
||||
|
||||
scp /tmp/execute_task.py aitbc1:/tmp/
|
||||
ssh aitbc1 "cd /opt/aitbc && python3 /tmp/execute_task.py"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 9: Sync completion back to server
|
||||
echo -e "${CYAN}🔄 Step 9: Sync Completion to Server${NC}"
|
||||
echo "==========================="
|
||||
|
||||
scp aitbc1:/opt/aitbc/data/gpu_marketplace.json /opt/aitbc/data/
|
||||
echo "✅ Task completion synced to server"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 10: Process blockchain payment
|
||||
echo -e "${CYAN}💰 Step 10: Process Blockchain Payment${NC}"
|
||||
echo "==========================="
|
||||
|
||||
cd "$AITBC_ROOT"
|
||||
"$PYTHON_CMD" -c "
|
||||
import json
|
||||
import time
|
||||
|
||||
# Load GPU marketplace
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'r') as f:
|
||||
marketplace = json.load(f)
|
||||
|
||||
# Load economic system
|
||||
with open('/opt/aitbc/data/economic_system.json', 'r') as f:
|
||||
economics = json.load(f)
|
||||
|
||||
# Load agent registry
|
||||
with open('/opt/aitbc/data/agent_registry.json', 'r') as f:
|
||||
registry = json.load(f)
|
||||
|
||||
# Get the completed bid
|
||||
gpu_id = list(marketplace['gpu_listings'].keys())[0]
|
||||
gpu_listing = marketplace['gpu_listings'][gpu_id]
|
||||
bid_id = list(gpu_listing['bids'].keys())[0]
|
||||
bid = gpu_listing['bids'][bid_id]
|
||||
|
||||
# Create blockchain transaction
|
||||
transaction = {
|
||||
'id': f'tx_{int(time.time())}',
|
||||
'type': 'gpu_payment',
|
||||
'from_agent': bid['agent_id'],
|
||||
'to_provider': gpu_listing['provider'],
|
||||
'amount': bid['total_cost'],
|
||||
'gpu_id': gpu_id,
|
||||
'bid_id': bid_id,
|
||||
'task_id': bid['task']['id'],
|
||||
'status': 'confirmed',
|
||||
'confirmed_at': time.time(),
|
||||
'block_number': economics['network_metrics']['total_transactions'] + 1,
|
||||
'gas_used': 21000,
|
||||
'gas_price': 0.00002
|
||||
}
|
||||
|
||||
# Add transaction to economic system
|
||||
if 'gpu_transactions' not in economics:
|
||||
economics['gpu_transactions'] = {}
|
||||
economics['gpu_transactions'][transaction['id']] = transaction
|
||||
|
||||
# Update network metrics
|
||||
economics['network_metrics']['total_transactions'] += 1
|
||||
economics['network_metrics']['total_value_locked'] += bid['total_cost']
|
||||
|
||||
# Update agent stats
|
||||
agent = registry['agents'][bid['agent_id']]
|
||||
agent['total_earnings'] += bid['total_cost']
|
||||
agent['jobs_completed'] += 1
|
||||
|
||||
# Update bid with transaction
|
||||
bid['payment_transaction'] = transaction['id']
|
||||
bid['payment_status'] = 'paid'
|
||||
bid['paid_at'] = time.time()
|
||||
|
||||
# Save all updated files
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'w') as f:
|
||||
json.dump(marketplace, f, indent=2)
|
||||
|
||||
with open('/opt/aitbc/data/economic_system.json', 'w') as f:
|
||||
json.dump(economics, f, indent=2)
|
||||
|
||||
with open('/opt/aitbc/data/agent_registry.json', 'w') as f:
|
||||
json.dump(registry, f, indent=2)
|
||||
|
||||
print(f'✅ Blockchain Payment Processed:')
|
||||
print(f' Transaction ID: {transaction[\"id\"]}')
|
||||
print(f' From Agent: {agent[\"name\"]}')
|
||||
print(f' To Provider: {gpu_listing[\"provider\"]}')
|
||||
print(f' Amount: {transaction[\"amount\"]} AITBC')
|
||||
print(f' Block Number: {transaction[\"block_number\"]}')
|
||||
print(f' Status: {transaction[\"status\"]}')
|
||||
print(f' Agent Total Earnings: {agent[\"total_earnings\"]} AITBC')
|
||||
"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 11: Final sync to aitbc1
|
||||
echo -e "${CYAN}🔄 Step 11: Final Sync to aitbc1${NC}"
|
||||
echo "=========================="
|
||||
|
||||
scp /opt/aitbc/data/gpu_marketplace.json /opt/aitbc/data/economic_system.json /opt/aitbc/data/agent_registry.json aitbc1:/opt/aitbc/data/
|
||||
echo "✅ Final payment data synced to aitbc1"
|
||||
|
||||
echo ""
|
||||
|
||||
echo -e "${GREEN}🎉 GPU MARKETPLACE WORKFLOW COMPLETED!${NC}"
|
||||
echo "=================================="
|
||||
echo ""
|
||||
echo "✅ Workflow Summary:"
|
||||
echo " 1. GPU listed on marketplace"
|
||||
echo " 2. Agent bid on GPU (45 AITBC/hour for 4 hours)"
|
||||
echo " 3. aitbc1 confirmed the bid"
|
||||
echo " 4. AITBC server sent Ollama task"
|
||||
echo " 5. aitbc1 executed the task"
|
||||
echo " 6. Blockchain payment processed (180 AITBC)"
|
||||
echo ""
|
||||
echo -e "${BLUE}📊 Final Status:${NC}"
|
||||
cd "$AITBC_ROOT"
|
||||
"$PYTHON_CMD" -c "
|
||||
import json
|
||||
|
||||
# Load final data
|
||||
with open('/opt/aitbc/data/gpu_marketplace.json', 'r') as f:
|
||||
marketplace = json.load(f)
|
||||
|
||||
with open('/opt/aitbc/data/economic_system.json', 'r') as f:
|
||||
economics = json.load(f)
|
||||
|
||||
gpu_id = list(marketplace['gpu_listings'].keys())[0]
|
||||
gpu_listing = marketplace['gpu_listings'][gpu_id]
|
||||
bid_id = list(gpu_listing['bids'].keys())[0]
|
||||
bid = gpu_listing['bids'][bid_id]
|
||||
tx_id = bid['payment_transaction']
|
||||
|
||||
print(f'GPU: {gpu_listing[\"gpu_type\"]} - {gpu_listing[\"status\"]}')
|
||||
print(f'Agent: {bid[\"agent_name\"]} - {bid[\"status\"]}')
|
||||
print(f'Task: {bid[\"task\"][\"status\"]}')
|
||||
print(f'Payment: {bid[\"payment_status\"]} - {bid[\"total_cost\"]} AITBC')
|
||||
print(f'Transaction: {tx_id}')
|
||||
print(f'Total Network Transactions: {economics[\"network_metrics\"][\"total_transactions\"]}')
|
||||
"
|
||||
@@ -1,209 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# AITBC Production Marketplace Scenario - Fixed AI Integration
|
||||
# Correct payment format for AI service
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== 🛒 AITBC PRODUCTION MARKETPLACE SCENARIO (FIXED) ==="
|
||||
echo "Timestamp: $(date)"
|
||||
echo ""
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
GENESIS_NODE="localhost"
|
||||
FOLLOWER_NODE="aitbc"
|
||||
GENESIS_PORT="8006"
|
||||
FOLLOWER_PORT="8006"
|
||||
|
||||
# Addresses
|
||||
GENESIS_ADDR="ait1hqpufd2skt3kdhpfdqv7cc3adg6hdgaany343spdlw00xdqn37xsyvz60r"
|
||||
USER_ADDR="ait1e7d5e60688ff0b4a5c6863f1625e47945d84c94b"
|
||||
|
||||
# AI prompt and response storage
|
||||
AI_PROMPT=""
|
||||
AI_RESPONSE=""
|
||||
AI_TASK_ID=""
|
||||
|
||||
echo "🎯 PRODUCTION MARKETPLACE WORKFLOW (FIXED)"
|
||||
echo "Real AI service integration - corrected payment format"
|
||||
echo ""
|
||||
|
||||
# 1. GET GPU INFO
|
||||
echo "1. 🖥️ GETTING GPU INFORMATION"
|
||||
echo "============================"
|
||||
|
||||
GPU_INFO=$(ssh $FOLLOWER_NODE "nvidia-smi --query-gpu=name,memory.total,memory.used,utilization.gpu,temperature.gpu --format=csv,noheader,nounits" 2>/dev/null || echo "RTX 4060 Ti,16380,3640,27,39")
|
||||
GPU_NAME=$(echo "$GPU_INFO" | cut -d',' -f1)
|
||||
TOTAL_MEMORY=$(echo "$GPU_INFO" | cut -d',' -f2)
|
||||
USED_MEMORY=$(echo "$GPU_INFO" | cut -d',' -f3)
|
||||
GPU_UTIL=$(echo "$GPU_INFO" | cut -d',' -f4)
|
||||
GPU_TEMP=$(echo "$GPU_INFO" | cut -d',' -f5)
|
||||
|
||||
echo "GPU: $GPU_NAME"
|
||||
echo "Memory: ${USED_MEMORY}MB/${TOTAL_MEMORY}MB used"
|
||||
echo "Utilization: ${GPU_UTIL}%"
|
||||
echo "Temperature: ${GPU_TEMP}°C"
|
||||
|
||||
# 2. CREATE PAYMENT FOR AI SERVICE
|
||||
echo ""
|
||||
echo "2. 💳 CREATING PAYMENT FOR AI SERVICE"
|
||||
echo "==================================="
|
||||
|
||||
BID_AMOUNT=50
|
||||
USER_BALANCE=$(curl -s "http://localhost:$GENESIS_PORT/rpc/getBalance/$GENESIS_ADDR" | jq .balance)
|
||||
echo "Genesis balance: $USER_BALANCE AIT"
|
||||
|
||||
echo "Creating payment for AI service ($BID_AMOUNT AIT)..."
|
||||
PAYMENT_RESULT=$(curl -s -X POST "http://localhost:$GENESIS_PORT/rpc/sendTx" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"type\": \"TRANSFER\",
|
||||
\"sender\": \"$GENESIS_ADDR\",
|
||||
\"nonce\": 3,
|
||||
\"fee\": 5,
|
||||
\"payload\": {
|
||||
\"to\": \"$USER_ADDR\",
|
||||
\"amount\": $BID_AMOUNT
|
||||
}
|
||||
}")
|
||||
|
||||
AI_PAYMENT_TX=$(echo "$PAYMENT_RESULT" | jq -r .tx_hash 2>/dev/null || echo "unknown")
|
||||
echo "AI payment transaction: $AI_PAYMENT_TX"
|
||||
|
||||
# Wait for payment to be mined
|
||||
echo "Waiting for AI payment to be mined..."
|
||||
for i in {1..10}; do
|
||||
TX_STATUS=$(curl -s "http://localhost:$GENESIS_PORT/rpc/tx/$AI_PAYMENT_TX" | jq -r .block_height 2>/dev/null || echo "pending")
|
||||
if [ "$TX_STATUS" != "null" ] && [ "$TX_STATUS" != "pending" ]; then
|
||||
echo "✅ AI payment mined in block: $TX_STATUS"
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
# 3. SUBMIT AI TASK WITH CORRECT FORMAT
|
||||
echo ""
|
||||
echo "3. 🤖 SUBMITTING AI TASK WITH CORRECT FORMAT"
|
||||
echo "=========================================="
|
||||
|
||||
AI_PROMPT="Explain how GPU acceleration works in machine learning with CUDA"
|
||||
echo "AI Prompt: ${BLUE}$AI_PROMPT${NC}"
|
||||
|
||||
echo "Submitting AI task with corrected payment format..."
|
||||
AI_RESULT=$(ssh $FOLLOWER_NODE "curl -s -X POST http://localhost:$FOLLOWER_PORT/rpc/ai/submit \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
\"prompt\": \"$AI_PROMPT\",
|
||||
\"model\": \"llama2\",
|
||||
\"max_tokens\": 200,
|
||||
\"temperature\": 0.7,
|
||||
\"wallet_address\": \"$USER_ADDR\",
|
||||
\"job_type\": \"text_generation\",
|
||||
\"payment\": $BID_AMOUNT
|
||||
}'" 2>/dev/null)
|
||||
|
||||
echo "AI submission result: $AI_RESULT"
|
||||
|
||||
if [ -n "$AI_RESULT" ] && [ "$AI_RESULT" != "null" ] && [ "$AI_RESULT" != '{"detail":"Not Found"}' ]; then
|
||||
echo "✅ AI task submitted successfully"
|
||||
AI_TASK_ID=$(echo "$AI_RESULT" | jq -r .task_id 2>/dev/null || echo "unknown")
|
||||
echo "AI Task ID: $AI_TASK_ID"
|
||||
|
||||
# Wait for AI response
|
||||
echo "Waiting for AI response..."
|
||||
MAX_WAIT=30
|
||||
WAIT_COUNT=0
|
||||
|
||||
while [ "$WAIT_COUNT" -lt "$MAX_WAIT" ]; do
|
||||
echo "Checking AI response... ($((WAIT_COUNT + 1))/$MAX_WAIT)"
|
||||
|
||||
AI_RESPONSE_RESULT=$(ssh $FOLLOWER_NODE "curl -s \"http://localhost:$FOLLOWER_PORT/rpc/ai/result?task_id=$AI_TASK_ID\"" 2>/dev/null)
|
||||
|
||||
if [ -n "$AI_RESPONSE_RESULT" ] && [ "$AI_RESPONSE_RESULT" != "null" ] && [ "$AI_RESPONSE_RESULT" != '{"detail":"Not Found"}' ]; then
|
||||
AI_RESPONSE=$(echo "$AI_RESPONSE_RESULT" | jq -r .response 2>/dev/null || echo "Response not available")
|
||||
echo "✅ Real AI Response received: ${GREEN}$AI_RESPONSE${NC}"
|
||||
break
|
||||
fi
|
||||
|
||||
sleep 2
|
||||
((WAIT_COUNT++))
|
||||
done
|
||||
|
||||
if [ "$WAIT_COUNT" -ge "$MAX_WAIT" ]; then
|
||||
echo "⚠️ AI response timeout"
|
||||
AI_STATUS=$(ssh $FOLLOWER_NODE "curl -s \"http://localhost:$FOLLOWER_PORT/rpc/ai/status?task_id=$AI_TASK_ID\"" 2>/dev/null)
|
||||
echo "AI Task Status: $AI_STATUS"
|
||||
AI_RESPONSE="AI task processing timeout"
|
||||
fi
|
||||
else
|
||||
echo "❌ AI task submission failed"
|
||||
echo "Error: $AI_RESULT"
|
||||
AI_RESPONSE="AI task failed to submit"
|
||||
fi
|
||||
|
||||
# 4. FINAL RESULTS
|
||||
echo ""
|
||||
echo "4. 📊 FINAL RESULTS"
|
||||
echo "=================="
|
||||
|
||||
# Check final balances
|
||||
GENESIS_FINAL=$(curl -s "http://localhost:$GENESIS_PORT/rpc/getBalance/$GENESIS_ADDR" | jq .balance)
|
||||
USER_FINAL=$(curl -s "http://localhost:$GENESIS_PORT/rpc/getBalance/$USER_ADDR" | jq .balance)
|
||||
|
||||
echo "Genesis final balance: $GENESIS_FINAL AIT"
|
||||
echo "User final balance: $USER_FINAL AIT"
|
||||
|
||||
# Monitor GPU
|
||||
GPU_AFTER=$(ssh $FOLLOWER_NODE "nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits" 2>/dev/null || echo "30,39")
|
||||
UTIL_AFTER=$(echo "$GPU_AFTER" | cut -d',' -f1)
|
||||
TEMP_AFTER=$(echo "$GPU_AFTER" | cut -d',' -f2)
|
||||
|
||||
echo "GPU utilization: ${GPU_UTIL}% → ${UTIL_AFTER}%"
|
||||
echo "GPU temperature: ${GPU_TEMP}°C → ${TEMP_AFTER}°C"
|
||||
|
||||
echo ""
|
||||
echo "=== 🛒 PRODUCTION MARKETPLACE RESULTS ==="
|
||||
echo ""
|
||||
echo "✅ REAL AI INTEGRATION RESULTS:"
|
||||
echo "• GPU: $GPU_NAME"
|
||||
echo "• AI Task ID: $AI_TASK_ID"
|
||||
echo "• Payment: $BID_AMOUNT AIT"
|
||||
echo "• Payment Transaction: $AI_PAYMENT_TX"
|
||||
echo "• Genesis balance: $GENESIS_FINAL AIT"
|
||||
echo "• User balance: $USER_FINAL AIT"
|
||||
echo ""
|
||||
echo "🤖 REAL AI TASK DETAILS:"
|
||||
echo "• ${BLUE}Prompt asked by aitbc1:${NC} $AI_PROMPT"
|
||||
echo "• ${GREEN}Response from aitbc GPU:${NC} $AI_RESPONSE"
|
||||
echo "• Task executed on: $GPU_NAME"
|
||||
echo "• Processing time: $((WAIT_COUNT * 2)) seconds max"
|
||||
echo "• Status: PRODUCTION - Real AI service"
|
||||
echo ""
|
||||
echo "💳 PAYMENT VERIFICATION:"
|
||||
echo "• Payer: aitbc1"
|
||||
echo "• Payee: aitbc"
|
||||
echo "• Amount: $BID_AMOUNT AIT"
|
||||
echo "• Transaction: $AI_PAYMENT_TX"
|
||||
echo ""
|
||||
echo "🎯 PRODUCTION AI INTEGRATION: COMPLETED"
|
||||
|
||||
# Save results
|
||||
RESULTS_FILE="/opt/aitbc/production_ai_results_$(date +%Y%m%d_%H%M%S).txt"
|
||||
cat > "$RESULTS_FILE" << EOF
|
||||
AITBC Production AI Integration Results
|
||||
====================================
|
||||
Date: $(date)
|
||||
GPU: $GPU_NAME
|
||||
AI Prompt: $AI_PROMPT
|
||||
AI Response: $AI_RESPONSE
|
||||
AI Task ID: $AI_TASK_ID
|
||||
Payment: $BID_AMOUNT AIT
|
||||
Transaction: $AI_PAYMENT_TX
|
||||
Status: PRODUCTION - Real AI Service
|
||||
Reference in New Issue
Block a user