add genesis command to CLI
Some checks failed
Blockchain Synchronization Verification / sync-verification (push) Failing after 3s
CLI Tests / test-cli (push) Failing after 3s
Documentation Validation / validate-docs (push) Successful in 5s
Documentation Validation / validate-policies-strict (push) Successful in 3s
Integration Tests / test-service-integration (push) Successful in 1m10s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 2s
P2P Network Verification / p2p-verification (push) Successful in 1s
Python Tests / test-python (push) Failing after 10s
Security Scanning / security-scan (push) Successful in 1m10s

Imported genesis command module and registered it with the CLI command group.
This commit is contained in:
aitbc
2026-04-25 18:04:54 +02:00
parent 787ddcdae3
commit ca228163ea
5 changed files with 979 additions and 0 deletions

View File

@@ -0,0 +1,194 @@
"""Genesis block and wallet generation commands for AITBC CLI"""
import click
from typing import Optional
from ..utils import output, error, success
import subprocess
import sys
from pathlib import Path
@click.group()
def genesis():
"""Genesis block and wallet generation commands"""
pass
@genesis.command()
@click.option("--chain-id", default="ait-mainnet", help="Chain ID for genesis")
@click.option("--create-wallet", is_flag=True, help="Create genesis wallet with secure random key")
@click.option("--password", help="Wallet password (auto-generated if not provided)")
@click.option("--proposer", help="Proposer address (defaults to genesis wallet)")
@click.option("--force", is_flag=True, help="Force overwrite existing genesis")
@click.option("--register-service", is_flag=True, help="Register genesis wallet with wallet service")
@click.option("--service-url", default="http://localhost:8003", help="Wallet service URL")
@click.pass_context
def init(ctx, chain_id: str, create_wallet: bool, password: Optional[str], proposer: Optional[str],
force: bool, register_service: bool, service_url: str):
"""Initialize genesis block and wallet for a blockchain"""
script_path = Path("/opt/aitbc/apps/blockchain-node/scripts/unified_genesis.py")
if not script_path.exists():
error(f"Genesis generation script not found: {script_path}")
return
# Build command
cmd = [
sys.executable,
str(script_path),
"--chain-id", chain_id
]
if create_wallet:
cmd.append("--create-wallet")
if password:
cmd.extend(["--password", password])
if proposer:
cmd.extend(["--proposer", proposer])
if force:
cmd.append("--force")
if register_service:
cmd.append("--register-service")
cmd.extend(["--service-url", service_url])
try:
success(f"Running genesis generation for {chain_id}...")
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
output(result.stdout, ctx.obj.get("output_format", "table"))
success(f"Genesis generation completed successfully")
except subprocess.CalledProcessError as e:
error(f"Genesis generation failed: {e.stderr}")
return
@genesis.command()
@click.option("--chain-id", default="ait-mainnet", help="Chain ID to verify")
@click.pass_context
def verify(ctx, chain_id: str):
"""Verify genesis block and wallet configuration"""
import json
import sqlite3
# Check genesis config file
genesis_path = Path(f"/var/lib/aitbc/data/{chain_id}/genesis.json")
if not genesis_path.exists():
error(f"Genesis config not found: {genesis_path}")
return
try:
with open(genesis_path) as f:
genesis_data = json.load(f)
success(f"✓ Genesis config found: {genesis_path}")
output({
"chain_id": genesis_data.get("chain_id"),
"genesis_hash": genesis_data.get("block", {}).get("hash"),
"proposer": genesis_data.get("block", {}).get("proposer"),
"allocations_count": len(genesis_data.get("allocations", []))
}, ctx.obj.get("output_format", "table"))
except Exception as e:
error(f"Failed to read genesis config: {e}")
return
# Check database
db_path = Path("/var/lib/aitbc/data/chain.db")
if not db_path.exists():
error(f"Database not found: {db_path}")
return
try:
conn = sqlite3.connect(str(db_path))
cursor = conn.cursor()
# Check genesis block
cursor.execute("SELECT * FROM block WHERE height=0 AND chain_id=?", (chain_id,))
genesis_block = cursor.fetchone()
if genesis_block:
success(f"✓ Genesis block found in database")
output({
"height": genesis_block[1],
"hash": genesis_block[2],
"proposer": genesis_block[4]
}, ctx.obj.get("output_format", "table"))
else:
error(f"Genesis block not found in database for chain {chain_id}")
# Check genesis accounts
cursor.execute("SELECT COUNT(*) FROM account WHERE chain_id=?", (chain_id,))
account_count = cursor.fetchone()[0]
if account_count > 0:
success(f"✓ Found {account_count} accounts in database")
else:
error(f"No accounts found in database for chain {chain_id}")
conn.close()
except Exception as e:
error(f"Failed to verify database: {e}")
return
# Check genesis wallet
wallet_path = Path("/var/lib/aitbc/keystore/genesis.json")
if wallet_path.exists():
success(f"✓ Genesis wallet found: {wallet_path}")
try:
with open(wallet_path) as f:
wallet_data = json.load(f)
output({
"address": wallet_data.get("address"),
"public_key": wallet_data.get("public_key")[:16] + "..." if wallet_data.get("public_key") else None
}, ctx.obj.get("output_format", "table"))
except Exception as e:
error(f"Failed to read genesis wallet: {e}")
else:
error(f"Genesis wallet not found: {wallet_path}")
@genesis.command()
@click.option("--chain-id", default="ait-mainnet", help="Chain ID to show info for")
@click.pass_context
def info(ctx, chain_id: str):
"""Show genesis block information"""
import json
import sqlite3
genesis_path = Path(f"/var/lib/aitbc/data/{chain_id}/genesis.json")
if not genesis_path.exists():
error(f"Genesis config not found: {genesis_path}")
return
try:
with open(genesis_path) as f:
genesis_data = json.load(f)
block = genesis_data.get("block", {})
allocations = genesis_data.get("allocations", [])
output({
"chain_id": genesis_data.get("chain_id"),
"genesis_block": {
"height": block.get("height"),
"hash": block.get("hash"),
"parent_hash": block.get("parent_hash"),
"proposer": block.get("proposer"),
"timestamp": block.get("timestamp"),
"tx_count": block.get("tx_count")
},
"allocations": [
{
"address": alloc.get("address"),
"balance": alloc.get("balance"),
"nonce": alloc.get("nonce")
}
for alloc in allocations[:5] # Show first 5
],
"total_allocations": len(allocations)
}, ctx.obj.get("output_format", "table"))
except Exception as e:
error(f"Failed to read genesis info: {e}")

View File

@@ -11,6 +11,7 @@ from pathlib import Path
from aitbc_cli.commands.gpu_marketplace import gpu
from aitbc_cli.commands.exchange_island import exchange_island
from aitbc_cli.commands.wallet import wallet
from aitbc_cli.commands.genesis import genesis
# Force version to 0.2.2
__version__ = "0.2.2"
@@ -159,6 +160,7 @@ cli.add_command(version)
cli.add_command(gpu)
cli.add_command(exchange_island)
cli.add_command(wallet)
cli.add_command(genesis)
if __name__ == '__main__':
cli()