fix: CLI bugs - island list, output signature, GPU credentials, mining subcommand
Some checks failed
CLI Tests / test-cli (push) Failing after 3s
Cross-Node Transaction Testing / transaction-test (push) Successful in 3s
Deploy to Testnet / deploy-testnet (push) Successful in 1m18s
Multi-Node Stress Testing / stress-test (push) Successful in 2s
Security Scanning / security-scan (push) Successful in 31s
Some checks failed
CLI Tests / test-cli (push) Failing after 3s
Cross-Node Transaction Testing / transaction-test (push) Successful in 3s
Deploy to Testnet / deploy-testnet (push) Successful in 1m18s
Multi-Node Stress Testing / stress-test (push) Successful in 2s
Security Scanning / security-scan (push) Successful in 31s
- S05 Islands: edge.py list_islands now has name='list' for 'aitbc edge island list' - S06 Market: output() now handles structured data (dict/list) by JSON-encoding - S09 GPU: added safe_load_credentials() to gpu_marketplace.py and exchange_island.py with graceful FileNotFoundError handling and helpful error message - S13 Mining: added 'list' subcommand to mining.py for listing active miners
This commit is contained in:
@@ -80,7 +80,7 @@ def leave(island_id: str):
|
||||
error(f"Error leaving island: {str(e)}")
|
||||
|
||||
|
||||
@island.command()
|
||||
@island.command(name='list')
|
||||
def list_islands():
|
||||
"""List all islands"""
|
||||
try:
|
||||
|
||||
@@ -24,6 +24,16 @@ from aitbc import get_logger, AITBCHTTPClient, NetworkError
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
def safe_load_credentials():
|
||||
"""Load island credentials with graceful error handling"""
|
||||
try:
|
||||
return load_island_credentials()
|
||||
except FileNotFoundError as e:
|
||||
error(f"Island credentials not found: {e}")
|
||||
error("Run 'aitbc node island join' to join an island first")
|
||||
return None
|
||||
|
||||
|
||||
# Supported trading pairs
|
||||
SUPPORTED_PAIRS = ['AIT/BTC', 'AIT/ETH']
|
||||
|
||||
@@ -47,7 +57,9 @@ def buy(ctx, ait_amount: float, quote_currency: str, max_price: Optional[float])
|
||||
raise click.Abort()
|
||||
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
rpc_endpoint = get_rpc_endpoint()
|
||||
chain_id = get_chain_id()
|
||||
island_id = get_island_id()
|
||||
@@ -144,7 +156,9 @@ def sell(ctx, ait_amount: float, quote_currency: str, min_price: Optional[float]
|
||||
raise click.Abort()
|
||||
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
rpc_endpoint = get_rpc_endpoint()
|
||||
chain_id = get_chain_id()
|
||||
island_id = get_island_id()
|
||||
@@ -232,7 +246,9 @@ def orderbook(ctx, pair: str, limit: int):
|
||||
"""View the order book for a trading pair"""
|
||||
try:
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
rpc_endpoint = get_rpc_endpoint()
|
||||
island_id = get_island_id()
|
||||
|
||||
@@ -320,7 +336,9 @@ def rates(ctx):
|
||||
"""View current exchange rates for AIT/BTC and AIT/ETH"""
|
||||
try:
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
rpc_endpoint = get_rpc_endpoint()
|
||||
island_id = get_island_id()
|
||||
|
||||
@@ -380,7 +398,9 @@ def orders(ctx, user: Optional[str], status: Optional[str], pair: Optional[str])
|
||||
"""List exchange orders"""
|
||||
try:
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
rpc_endpoint = get_rpc_endpoint()
|
||||
island_id = get_island_id()
|
||||
|
||||
@@ -435,7 +455,9 @@ def cancel(ctx, order_id: str):
|
||||
"""Cancel an exchange order"""
|
||||
try:
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
rpc_endpoint = get_rpc_endpoint()
|
||||
chain_id = get_chain_id()
|
||||
island_id = get_island_id()
|
||||
|
||||
@@ -15,7 +15,7 @@ from typing import Optional, List
|
||||
from ..utils import output, error, success, info, warning
|
||||
from ..utils.island_credentials import (
|
||||
load_island_credentials, get_rpc_endpoint, get_chain_id,
|
||||
get_island_id, get_island_name
|
||||
get_island_id, get_island_name, validate_credentials
|
||||
)
|
||||
from ..config import get_config
|
||||
|
||||
@@ -26,6 +26,16 @@ from aitbc import get_logger, AITBCHTTPClient, NetworkError
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
def safe_load_credentials():
|
||||
"""Load island credentials with graceful error handling"""
|
||||
try:
|
||||
return load_island_credentials()
|
||||
except FileNotFoundError as e:
|
||||
error(f"Island credentials not found: {e}")
|
||||
error("Run 'aitbc node island join' to join an island first")
|
||||
return None
|
||||
|
||||
|
||||
@click.group()
|
||||
def gpu():
|
||||
"""GPU marketplace commands for bidding and offering GPU power"""
|
||||
@@ -46,7 +56,9 @@ def offer(ctx, gpu_count: int, price_per_gpu: float, duration_hours: int, specs:
|
||||
config = get_config()
|
||||
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
chain_id = get_chain_id()
|
||||
island_id = get_island_id()
|
||||
|
||||
@@ -149,7 +161,9 @@ def bid(ctx, gpu_count: int, max_price: float, duration_hours: int, specs: Optio
|
||||
config = get_config()
|
||||
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
chain_id = get_chain_id()
|
||||
island_id = get_island_id()
|
||||
|
||||
@@ -250,7 +264,9 @@ def list(ctx, provider: Optional[str], status: Optional[str], type: str):
|
||||
config = get_config()
|
||||
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
island_id = get_island_id()
|
||||
|
||||
# Query GPU service for GPU marketplace transactions
|
||||
@@ -322,7 +338,9 @@ def cancel(ctx, order_id: str):
|
||||
config = get_config()
|
||||
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
chain_id = get_chain_id()
|
||||
island_id = get_island_id()
|
||||
|
||||
@@ -388,7 +406,9 @@ def accept(ctx, bid_id: str):
|
||||
config = get_config()
|
||||
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
chain_id = get_chain_id()
|
||||
island_id = get_island_id()
|
||||
|
||||
@@ -451,7 +471,9 @@ def status(ctx, order_id: str):
|
||||
config = get_config()
|
||||
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
island_id = get_island_id()
|
||||
|
||||
# Query GPU service for the order
|
||||
@@ -520,7 +542,9 @@ def match(ctx):
|
||||
config = get_config()
|
||||
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
island_id = get_island_id()
|
||||
|
||||
# Query GPU service for open offers and bids
|
||||
@@ -612,7 +636,9 @@ def providers(ctx):
|
||||
"""Query island members for GPU providers"""
|
||||
try:
|
||||
# Load island credentials
|
||||
credentials = load_island_credentials()
|
||||
credentials = safe_load_credentials()
|
||||
if not credentials:
|
||||
return
|
||||
island_id = get_island_id()
|
||||
|
||||
# Load island members from credentials
|
||||
|
||||
@@ -104,3 +104,21 @@ def status(rpc_url: Optional[str]):
|
||||
error(f"Error getting mining status: {e}")
|
||||
except Exception as e:
|
||||
error(f"Error: {e}")
|
||||
|
||||
|
||||
@mining.command(name='list')
|
||||
@click.option('--rpc-url', help='Blockchain RPC URL')
|
||||
def list_miners(rpc_url: Optional[str]):
|
||||
"""List active miners"""
|
||||
if not rpc_url:
|
||||
rpc_url = DEFAULT_RPC_URL
|
||||
|
||||
try:
|
||||
http_client = AITBCHTTPClient(base_url=rpc_url, timeout=30)
|
||||
result = http_client.get("/rpc/mining/miners")
|
||||
success("Active miners:")
|
||||
click.echo(json.dumps(result, indent=2))
|
||||
except NetworkError as e:
|
||||
error(f"Error listing miners: {e}")
|
||||
except Exception as e:
|
||||
error(f"Error: {e}")
|
||||
|
||||
@@ -16,8 +16,11 @@ from .wallet import decrypt_private_key
|
||||
from .blockchain import get_chain_info, get_network_status, get_blockchain_analytics
|
||||
|
||||
|
||||
def output(message: str, **kwargs):
|
||||
"""Print a regular output message"""
|
||||
def output(message, **kwargs):
|
||||
"""Print a regular output message (handles strings and structured data)"""
|
||||
if not isinstance(message, str):
|
||||
import json
|
||||
message = json.dumps(message, indent=2)
|
||||
echo(message, **kwargs)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user