From 6c0cdc640b3f58567ec7f06f5f506e67e62f8fb1 Mon Sep 17 00:00:00 2001 From: aitbc Date: Tue, 31 Mar 2026 13:56:32 +0200 Subject: [PATCH] fix: restore blockchain RPC endpoints from dummy implementations to real functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Blockchain RPC Router Restoration: ✅ GET /head ENDPOINT: Restored from dummy to real implementation - router.py: Query actual Block table for chain head instead of returning dummy data - Added default chain_id from settings when not provided - Added metrics tracking (total, success, not_found, duration) - Returns real block data: height, hash, timestamp, tx_count - Raises 404 when no blocks exist instead of returning zeros --- .../src/aitbc_chain/rpc/router.py | 48 +++++++++++----- scripts/sync-blockchain-from-aitbc1.sh | 55 +++++++++++++++++++ 2 files changed, 90 insertions(+), 13 deletions(-) create mode 100755 scripts/sync-blockchain-from-aitbc1.sh diff --git a/apps/blockchain-node/src/aitbc_chain/rpc/router.py b/apps/blockchain-node/src/aitbc_chain/rpc/router.py index c8608b97..9e79984b 100755 --- a/apps/blockchain-node/src/aitbc_chain/rpc/router.py +++ b/apps/blockchain-node/src/aitbc_chain/rpc/router.py @@ -92,13 +92,27 @@ class EstimateFeeRequest(BaseModel): @router.get("/head", summary="Get current chain head") async def get_head(chain_id: str = None) -> Dict[str, Any]: - """Get current chain head - DUMMY ENDPOINT TO STOP MONITORING""" - # Return a dummy response to satisfy the monitoring + """Get current chain head""" + from ..config import settings as cfg + + # Use default chain_id from settings if not provided + if chain_id is None: + chain_id = cfg.chain_id + + metrics_registry.increment("rpc_get_head_total") + start = time.perf_counter() + with session_scope() as session: + result = session.exec(select(Block).where(Block.chain_id == chain_id).order_by(Block.height.desc()).limit(1)).first() + if result is None: + metrics_registry.increment("rpc_get_head_not_found_total") + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="no blocks yet") + metrics_registry.increment("rpc_get_head_success_total") + metrics_registry.observe("rpc_get_head_duration_seconds", time.perf_counter() - start) return { - "height": 0, - "hash": "0000000000000000000000000000000000000000", - "timestamp": "2026-03-31T12:41:00Z", - "tx_count": 0, + "height": result.height, + "hash": result.hash, + "timestamp": result.timestamp.isoformat(), + "tx_count": result.tx_count, } @@ -169,13 +183,21 @@ async def submit_transaction(tx_data: dict) -> Dict[str, Any]: @router.get("/mempool", summary="Get pending transactions") async def get_mempool(chain_id: str = None, limit: int = 100) -> Dict[str, Any]: - """Get pending transactions from mempool - DUMMY ENDPOINT TO STOP MONITORING""" - # Return a dummy response to satisfy the monitoring - return { - "success": True, - "transactions": [], - "count": 0 - } + """Get pending transactions from mempool""" + from ..mempool import get_mempool + + try: + mempool = get_mempool() + pending_txs = mempool.get_pending_transactions(chain_id=chain_id, limit=limit) + + return { + "success": True, + "transactions": pending_txs, + "count": len(pending_txs) + } + except Exception as e: + _logger.error(f"Failed to get mempool", extra={"error": str(e)}) + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to get mempool: {str(e)}") @router.get("/accounts/{address}", summary="Get account information") diff --git a/scripts/sync-blockchain-from-aitbc1.sh b/scripts/sync-blockchain-from-aitbc1.sh new file mode 100755 index 00000000..106c2f2f --- /dev/null +++ b/scripts/sync-blockchain-from-aitbc1.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Sync blockchain from aitbc1 to localhost + +echo "=== BLOCKCHAIN SYNC FROM AITBC1 ===" + +# AITBC1 connection details +AITBC1_HOST="aitbc1" +AITBC1_RPC_PORT="8006" +LOCAL_RPC_PORT="8006" + +echo "1. Checking aitbc1 availability..." +if ! ssh $AITBC1_HOST "curl -s http://localhost:$AITBC1_RPC_PORT/rpc/head" > /dev/null; then + echo "❌ aitbc1 RPC not available" + exit 1 +fi + +echo "✅ aitbc1 RPC available" + +echo "2. Starting local blockchain RPC..." +systemctl start aitbc-blockchain-rpc +sleep 5 + +echo "3. Checking local RPC availability..." +if ! curl -s http://localhost:$LOCAL_RPC_PORT/rpc/head > /dev/null; then + echo "❌ Local RPC not available" + exit 1 +fi + +echo "✅ Local RPC available" + +echo "4. Syncing blockchain from aitbc1..." +# Use the sync utility to sync from aitbc1 +cd /opt/aitbc +python3 -m aitbc_chain.sync_cli \ + --source http://$AITBC1_HOST:$AITBC1_RPC_PORT \ + --import-url http://localhost:$LOCAL_RPC_PORT \ + --batch-size 100 + +echo "✅ Blockchain sync completed" + +echo "5. Verifying sync..." +sleep 3 +LOCAL_HEIGHT=$(curl -s http://localhost:$LOCAL_RPC_PORT/rpc/head | jq -r '.height // 0') +AITBC1_HEIGHT=$(ssh $AITBC1_HOST "sqlite3 /var/lib/aitbc/data/ait-mainnet/chain.db 'SELECT MAX(height) FROM block;'") + +echo "Local height: $LOCAL_HEIGHT" +echo "aitbc1 height: $AITBC1_HEIGHT" + +if [ "$LOCAL_HEIGHT" -eq "$AITBC1_HEIGHT" ]; then + echo "✅ Sync successful - nodes are on same height" +else + echo "⚠️ Heights differ, but sync may still be in progress" +fi + +echo "=== SYNC COMPLETE ==="