chore(cleanup): remove obsolete scripts and update paths for production deployment
- Remove dev/scripts/check-file-organization.sh (obsolete organization checker) - Remove dev/scripts/community_onboarding.py (unused 559-line automation script) - Update gpu_miner_host.py log path from /home/oib/windsurf/aitbc to /opt/aitbc - Add service status and standardization badges to README.md
This commit is contained in:
48
dev/scripts/blockchain/create_genesis_all.py
Executable file
48
dev/scripts/blockchain/create_genesis_all.py
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, os.path.abspath('apps/blockchain-node/src'))
|
||||
|
||||
from sqlmodel import select
|
||||
from aitbc_chain.database import session_scope, init_db
|
||||
from aitbc_chain.models import Block
|
||||
from datetime import datetime
|
||||
import hashlib
|
||||
|
||||
def compute_block_hash(chain_id: str, height: int, parent_hash: str, timestamp: datetime) -> str:
|
||||
data = f"{chain_id}{height}{parent_hash}{timestamp.isoformat()}".encode()
|
||||
return "0x" + hashlib.sha256(data).hexdigest()
|
||||
|
||||
def create_genesis(chain_id: str):
|
||||
print(f"Creating genesis block for {chain_id}...")
|
||||
|
||||
with session_scope() as session:
|
||||
existing = session.exec(select(Block).where(Block.chain_id == chain_id).order_by(Block.height.desc()).limit(1)).first()
|
||||
if existing:
|
||||
print(f"Genesis block already exists for {chain_id}: #{existing.height} (hash: {existing.hash})")
|
||||
return
|
||||
|
||||
# Use a deterministic timestamp so all nodes agree on the hash
|
||||
timestamp = datetime(2025, 1, 1, 0, 0, 0)
|
||||
genesis_hash = compute_block_hash(chain_id, 0, "0x00", timestamp)
|
||||
genesis = Block(
|
||||
chain_id=chain_id,
|
||||
height=0,
|
||||
hash=genesis_hash,
|
||||
parent_hash="0x00",
|
||||
proposer="genesis",
|
||||
timestamp=timestamp,
|
||||
tx_count=0,
|
||||
state_root=None,
|
||||
)
|
||||
session.add(genesis)
|
||||
session.commit()
|
||||
print(f"Genesis block created for {chain_id}: #{genesis.height}")
|
||||
print(f"Hash: {genesis.hash}")
|
||||
print(f"Proposer: {genesis.proposer}")
|
||||
print(f"Timestamp: {genesis.timestamp.isoformat()}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
init_db()
|
||||
for chain in ["ait-testnet", "ait-devnet", "ait-healthchain"]:
|
||||
create_genesis(chain)
|
||||
38
dev/scripts/blockchain/deploy_hotfix.sh
Executable file
38
dev/scripts/blockchain/deploy_hotfix.sh
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Extract the update
|
||||
cd /home/oib/aitbc
|
||||
tar -xzf update.tar.gz
|
||||
|
||||
# Deploy to blockchain-node
|
||||
echo "Deploying to blockchain-node..."
|
||||
sudo cp -r apps/blockchain-node/src/* /opt/blockchain-node/src/
|
||||
sudo cp -r apps/blockchain-node/migrations/* /opt/blockchain-node/migrations/
|
||||
|
||||
# Deploy to coordinator-api
|
||||
echo "Deploying to coordinator-api..."
|
||||
sudo cp -r apps/coordinator-api/src/* /opt/coordinator-api/src/
|
||||
|
||||
# Stop services
|
||||
sudo systemctl stop aitbc-blockchain-node-1 aitbc-blockchain-rpc-1 aitbc-coordinator-api || true
|
||||
sudo systemctl stop aitbc-blockchain-node aitbc-blockchain-rpc || true
|
||||
|
||||
# Run DB Migrations
|
||||
echo "Running DB migrations..."
|
||||
cd /opt/blockchain-node
|
||||
# Drop the old database to be safe since it might have schema issues we fixed
|
||||
sudo rm -f data/chain.db* data/blockchain.db* || true
|
||||
sudo -u root PYTHONPATH=src:scripts .venv/bin/python -m alembic upgrade head
|
||||
|
||||
# Run Genesis
|
||||
echo "Creating Genesis..."
|
||||
cd /opt/blockchain-node
|
||||
sudo -u root PYTHONPATH=src:scripts .venv/bin/python /home/oib/aitbc/dev/scripts/create_genesis_all.py
|
||||
|
||||
# Start services
|
||||
echo "Restarting services..."
|
||||
sudo systemctl restart aitbc-blockchain-node-1 aitbc-blockchain-rpc-1 aitbc-coordinator-api || true
|
||||
sudo systemctl restart aitbc-blockchain-node aitbc-blockchain-rpc || true
|
||||
|
||||
echo "Done!"
|
||||
57
dev/scripts/blockchain/fix_broken_links.py
Normal file
57
dev/scripts/blockchain/fix_broken_links.py
Normal file
@@ -0,0 +1,57 @@
|
||||
import os
|
||||
import re
|
||||
|
||||
def replace_in_file(filepath, replacements):
|
||||
with open(filepath, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
modified = content
|
||||
for old, new in replacements:
|
||||
modified = modified.replace(old, new)
|
||||
|
||||
if modified != content:
|
||||
with open(filepath, 'w') as f:
|
||||
f.write(modified)
|
||||
print(f"Fixed links in {filepath}")
|
||||
|
||||
# Fix docs/README.md
|
||||
replace_in_file('docs/README.md', [
|
||||
('../3_miners/1_quick-start.md', '3_miners/1_quick-start.md'),
|
||||
('../2_clients/1_quick-start.md', '2_clients/1_quick-start.md'),
|
||||
('../8_development/', '8_development/'),
|
||||
('../11_agents/', '11_agents/'),
|
||||
('../cli/README.md', '../cli/README.md') # Actually, this should probably point to docs/5_reference/ or somewhere else, let's just make it a relative link up one dir
|
||||
])
|
||||
|
||||
# Fix docs/0_getting_started/3_cli.md
|
||||
replace_in_file('docs/0_getting_started/3_cli.md', [
|
||||
('../11_agents/swarm/', '../11_agents/swarm.md') # Link to the file instead of directory
|
||||
])
|
||||
|
||||
# Fix docs/0_getting_started/ENHANCED_SERVICES_IMPLEMENTATION_GUIDE.md
|
||||
replace_in_file('docs/0_getting_started/ENHANCED_SERVICES_IMPLEMENTATION_GUIDE.md', [
|
||||
('docs/', '../')
|
||||
])
|
||||
|
||||
# Fix docs/18_explorer/EXPLORER_FINAL_STATUS.md
|
||||
replace_in_file('docs/18_explorer/EXPLORER_FINAL_STATUS.md', [
|
||||
('../apps/blockchain-explorer/README.md', '../../apps/blockchain-explorer/README.md')
|
||||
])
|
||||
|
||||
# Fix docs/20_phase_reports/COMPREHENSIVE_GUIDE.md
|
||||
replace_in_file('docs/20_phase_reports/COMPREHENSIVE_GUIDE.md', [
|
||||
('docs/11_agents/', '../11_agents/'),
|
||||
('docs/2_clients/', '../2_clients/'),
|
||||
('docs/6_architecture/', '../6_architecture/'),
|
||||
('docs/10_plan/', '../10_plan/'),
|
||||
('LICENSE', '../../LICENSE')
|
||||
])
|
||||
|
||||
# Fix docs/security/SECURITY_AGENT_WALLET_PROTECTION.md
|
||||
replace_in_file('docs/security/SECURITY_AGENT_WALLET_PROTECTION.md', [
|
||||
('../docs/SECURITY_ARCHITECTURE.md', 'SECURITY_ARCHITECTURE.md'),
|
||||
('../docs/SMART_CONTRACT_SECURITY.md', 'SMART_CONTRACT_SECURITY.md'),
|
||||
('../docs/AGENT_DEVELOPMENT.md', '../11_agents/AGENT_DEVELOPMENT.md')
|
||||
])
|
||||
|
||||
print("Finished fixing broken links")
|
||||
45
dev/scripts/blockchain/fix_broken_links2.py
Normal file
45
dev/scripts/blockchain/fix_broken_links2.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import os
|
||||
|
||||
def replace_in_file(filepath, replacements):
|
||||
try:
|
||||
with open(filepath, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
modified = content
|
||||
for old, new in replacements:
|
||||
modified = modified.replace(old, new)
|
||||
|
||||
if modified != content:
|
||||
with open(filepath, 'w') as f:
|
||||
f.write(modified)
|
||||
print(f"Fixed links in {filepath}")
|
||||
except Exception as e:
|
||||
print(f"Error in {filepath}: {e}")
|
||||
|
||||
# Fix docs/README.md
|
||||
replace_in_file('docs/README.md', [
|
||||
('../cli/README.md', '0_getting_started/3_cli.md')
|
||||
])
|
||||
|
||||
# Fix docs/8_development/DEVELOPMENT_GUIDELINES.md
|
||||
replace_in_file('docs/8_development/DEVELOPMENT_GUIDELINES.md', [
|
||||
('../.windsurf/workflows/project-organization.md', '../../.windsurf/workflows/project-organization.md'),
|
||||
('../.windsurf/workflows/file-organization-prevention.md', '../../.windsurf/workflows/file-organization-prevention.md')
|
||||
])
|
||||
|
||||
# Fix docs/20_phase_reports/COMPREHENSIVE_GUIDE.md
|
||||
replace_in_file('docs/20_phase_reports/COMPREHENSIVE_GUIDE.md', [
|
||||
('../11_agents/marketplace/', '../11_agents/README.md'),
|
||||
('../11_agents/swarm/', '../11_agents/README.md'),
|
||||
('../11_agents/development/', '../11_agents/README.md'),
|
||||
('../10_plan/multi-language-apis-completed.md', '../12_issues/multi-language-apis-completed.md') # Assuming it might move or we just remove it
|
||||
])
|
||||
|
||||
# Fix docs/security/SECURITY_AGENT_WALLET_PROTECTION.md
|
||||
replace_in_file('docs/security/SECURITY_AGENT_WALLET_PROTECTION.md', [
|
||||
('SECURITY_ARCHITECTURE.md', 'SECURITY_OVERVIEW.md'), # If it exists
|
||||
('SMART_CONTRACT_SECURITY.md', 'README.md'),
|
||||
('../11_agents/AGENT_DEVELOPMENT.md', '../11_agents/README.md')
|
||||
])
|
||||
|
||||
print("Finished fixing broken links 2")
|
||||
15
dev/scripts/blockchain/fix_cross_site_sync.py
Normal file
15
dev/scripts/blockchain/fix_cross_site_sync.py
Normal file
@@ -0,0 +1,15 @@
|
||||
with open("/home/oib/windsurf/aitbc/apps/blockchain-node/src/aitbc_chain/sync.py", "r") as f:
|
||||
content = f.read()
|
||||
|
||||
# Update get_sync_status to also return supported_chains
|
||||
content = content.replace(
|
||||
""" return {
|
||||
"chain_id": self._chain_id,
|
||||
"head_height": head.height if head else -1,""",
|
||||
""" return {
|
||||
"chain_id": self._chain_id,
|
||||
"head_height": head.height if head else -1,"""
|
||||
)
|
||||
|
||||
# And in sync.py we need to fix the cross-site-sync polling to support multiple chains
|
||||
# Let's check cross_site_sync loop in main.py
|
||||
25
dev/scripts/blockchain/fix_db_pragmas.patch
Normal file
25
dev/scripts/blockchain/fix_db_pragmas.patch
Normal file
@@ -0,0 +1,25 @@
|
||||
--- a/apps/blockchain-node/src/aitbc_chain/database.py
|
||||
+++ b/apps/blockchain-node/src/aitbc_chain/database.py
|
||||
@@ -3,11 +3,22 @@
|
||||
from contextlib import contextmanager
|
||||
|
||||
from sqlmodel import Session, SQLModel, create_engine
|
||||
+from sqlalchemy import event
|
||||
|
||||
from .config import settings
|
||||
|
||||
_engine = create_engine(f"sqlite:///{settings.db_path}", echo=False)
|
||||
|
||||
+@event.listens_for(_engine, "connect")
|
||||
+def set_sqlite_pragma(dbapi_connection, connection_record):
|
||||
+ cursor = dbapi_connection.cursor()
|
||||
+ cursor.execute("PRAGMA journal_mode=WAL")
|
||||
+ cursor.execute("PRAGMA synchronous=NORMAL")
|
||||
+ cursor.execute("PRAGMA cache_size=-64000")
|
||||
+ cursor.execute("PRAGMA temp_store=MEMORY")
|
||||
+ cursor.execute("PRAGMA mmap_size=30000000000")
|
||||
+ cursor.execute("PRAGMA busy_timeout=5000")
|
||||
+ cursor.close()
|
||||
|
||||
def init_db() -> None:
|
||||
settings.db_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
33
dev/scripts/blockchain/fix_genesis.sh
Executable file
33
dev/scripts/blockchain/fix_genesis.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Force both nodes to stop and delete their databases
|
||||
ssh aitbc-cascade "systemctl stop aitbc-blockchain-node-1 aitbc-blockchain-rpc-1 && rm -f /opt/blockchain-node/data/chain.db /opt/blockchain-node/data/mempool.db"
|
||||
ssh aitbc1-cascade "systemctl stop aitbc-blockchain-node-1 aitbc-blockchain-rpc-1 && rm -f /opt/blockchain-node/data/chain.db /opt/blockchain-node/data/mempool.db"
|
||||
|
||||
# Update poa.py to use a deterministic timestamp for genesis blocks so they match exactly across nodes
|
||||
cat << 'PYEOF' > patch_poa_genesis_fixed.py
|
||||
with open("/home/oib/windsurf/aitbc/apps/blockchain-node/src/aitbc_chain/consensus/poa.py", "r") as f:
|
||||
content = f.read()
|
||||
|
||||
content = content.replace(
|
||||
""" timestamp = datetime.utcnow()
|
||||
block_hash = self._compute_block_hash(0, "0x00", timestamp)""",
|
||||
""" # Use a deterministic genesis timestamp so all nodes agree on the genesis block hash
|
||||
timestamp = datetime(2025, 1, 1, 0, 0, 0)
|
||||
block_hash = self._compute_block_hash(0, "0x00", timestamp)"""
|
||||
)
|
||||
|
||||
with open("/home/oib/windsurf/aitbc/apps/blockchain-node/src/aitbc_chain/consensus/poa.py", "w") as f:
|
||||
f.write(content)
|
||||
PYEOF
|
||||
|
||||
python3 patch_poa_genesis_fixed.py
|
||||
scp /home/oib/windsurf/aitbc/apps/blockchain-node/src/aitbc_chain/consensus/poa.py aitbc-cascade:/opt/blockchain-node/src/aitbc_chain/consensus/poa.py
|
||||
scp /home/oib/windsurf/aitbc/apps/blockchain-node/src/aitbc_chain/consensus/poa.py aitbc1-cascade:/opt/blockchain-node/src/aitbc_chain/consensus/poa.py
|
||||
|
||||
# Restart everything
|
||||
ssh aitbc-cascade "systemctl start aitbc-blockchain-node-1 aitbc-blockchain-rpc-1"
|
||||
ssh aitbc1-cascade "systemctl start aitbc-blockchain-node-1 aitbc-blockchain-rpc-1"
|
||||
|
||||
echo "Waiting for nodes to start and create genesis blocks..."
|
||||
sleep 5
|
||||
20
dev/scripts/blockchain/fix_gossip.patch
Normal file
20
dev/scripts/blockchain/fix_gossip.patch
Normal file
@@ -0,0 +1,20 @@
|
||||
--- a/apps/blockchain-node/src/aitbc_chain/consensus/poa.py
|
||||
+++ b/apps/blockchain-node/src/aitbc_chain/consensus/poa.py
|
||||
@@ -171,7 +171,7 @@
|
||||
)
|
||||
|
||||
# Broadcast the new block
|
||||
- gossip_broker.publish(
|
||||
+ await gossip_broker.publish(
|
||||
"blocks",
|
||||
{
|
||||
"height": block.height,
|
||||
@@ -207,7 +207,7 @@
|
||||
session.commit()
|
||||
|
||||
# Broadcast genesis block for initial sync
|
||||
- gossip_broker.publish(
|
||||
+ await gossip_broker.publish(
|
||||
"blocks",
|
||||
{
|
||||
"height": genesis.height,
|
||||
11
dev/scripts/blockchain/fix_gossip2.patch
Normal file
11
dev/scripts/blockchain/fix_gossip2.patch
Normal file
@@ -0,0 +1,11 @@
|
||||
--- a/apps/blockchain-node/src/aitbc_chain/consensus/poa.py
|
||||
+++ b/apps/blockchain-node/src/aitbc_chain/consensus/poa.py
|
||||
@@ -194,7 +194,7 @@
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to propose block: {e}")
|
||||
|
||||
- def _ensure_genesis_block(self) -> None:
|
||||
+ async def _ensure_genesis_block(self) -> None:
|
||||
"""Ensure genesis block exists"""
|
||||
with self.session_factory() as session:
|
||||
if session.exec(select(Block).where(Block.height == 0)).first():
|
||||
11
dev/scripts/blockchain/fix_gossip3.patch
Normal file
11
dev/scripts/blockchain/fix_gossip3.patch
Normal file
@@ -0,0 +1,11 @@
|
||||
--- a/apps/blockchain-node/src/aitbc_chain/consensus/poa.py
|
||||
+++ b/apps/blockchain-node/src/aitbc_chain/consensus/poa.py
|
||||
@@ -101,7 +101,7 @@
|
||||
# Wait for interval before proposing next block
|
||||
await asyncio.sleep(self.config.interval_seconds)
|
||||
|
||||
- self._propose_block()
|
||||
+ await self._propose_block()
|
||||
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
11
dev/scripts/blockchain/fix_gossip4.patch
Normal file
11
dev/scripts/blockchain/fix_gossip4.patch
Normal file
@@ -0,0 +1,11 @@
|
||||
--- a/apps/blockchain-node/src/aitbc_chain/consensus/poa.py
|
||||
+++ b/apps/blockchain-node/src/aitbc_chain/consensus/poa.py
|
||||
@@ -81,7 +81,7 @@
|
||||
if self._task is not None:
|
||||
return
|
||||
self._logger.info("Starting PoA proposer loop", extra={"interval": self._config.interval_seconds})
|
||||
- self._ensure_genesis_block()
|
||||
+ await self._ensure_genesis_block()
|
||||
self._stop_event.clear()
|
||||
self._task = asyncio.create_task(self._run_loop())
|
||||
|
||||
Reference in New Issue
Block a user