chore: remove obsolete payment architecture and integration test documentation

- Remove AITBC_PAYMENT_ARCHITECTURE.md (dual-currency system documentation)
- Remove IMPLEMENTATION_COMPLETE_SUMMARY.md (integration test completion summary)
- Remove INTEGRATION_TEST_FIXES.md (test fixes documentation)
- Remove INTEGRATION_TEST_UPDATES.md (real features implementation notes)
- Remove PAYMENT_INTEGRATION_COMPLETE.md (wallet-coordinator integration docs)
- Remove WALLET_COORDINATOR_INTEGRATION.md (payment
This commit is contained in:
oib
2026-01-29 12:28:43 +01:00
parent 5c99c92ffb
commit ff4554b9dd
94 changed files with 7925 additions and 128 deletions

View File

@@ -0,0 +1,24 @@
#!/bin/bash
# Clean up failed deployment and prepare for redeployment
echo "🧹 Cleaning up failed deployment..."
echo "=================================="
# Stop any running services
echo "Stopping services..."
ssh ns3-root "systemctl stop blockchain-node blockchain-rpc nginx 2>/dev/null || true"
# Remove old directories
echo "Removing old directories..."
ssh ns3-root "rm -rf /opt/blockchain-node /opt/blockchain-node-src /opt/blockchain-explorer 2>/dev/null || true"
# Remove systemd services
echo "Removing systemd services..."
ssh ns3-root "systemctl disable blockchain-node blockchain-rpc blockchain-explorer 2>/dev/null || true"
ssh ns3-root "rm -f /etc/systemd/system/blockchain-node.service /etc/systemd/system/blockchain-rpc.service /etc/systemd/system/blockchain-explorer.service 2>/dev/null || true"
ssh ns3-root "systemctl daemon-reload"
echo "✅ Cleanup complete!"
echo ""
echo "You can now run: ./scripts/deploy/deploy-all-remote.sh"

View File

@@ -0,0 +1,56 @@
#!/bin/bash
# Deploy blockchain node and explorer by building directly on ns3
echo "🚀 AITBC Remote Deployment (Build on Server)"
echo "=========================================="
echo "This will build the blockchain node directly on ns3"
echo "to utilize the gigabit connection instead of uploading."
echo ""
# Copy deployment scripts to server
echo "Copying deployment scripts to ns3..."
scp scripts/deploy/deploy-blockchain-remote.sh ns3-root:/opt/
scp scripts/deploy/deploy-explorer-remote.sh ns3-root:/opt/
# Create directories on server first
echo "Creating directories on ns3..."
ssh ns3-root "mkdir -p /opt/blockchain-node-src /opt/blockchain-node"
# Copy blockchain source code to server (excluding data files)
echo "Copying blockchain source code to ns3..."
rsync -av --exclude='data/' --exclude='*.db' --exclude='__pycache__' --exclude='.venv' apps/blockchain-node/ ns3-root:/opt/blockchain-node-src/
# Execute blockchain deployment
echo ""
echo "Deploying blockchain node..."
ssh ns3-root "cd /opt && cp -r /opt/blockchain-node-src/* /opt/blockchain-node/ && cd /opt/blockchain-node && chmod +x ../deploy-blockchain-remote.sh && ../deploy-blockchain-remote.sh"
# Wait for blockchain to start
echo ""
echo "Waiting 10 seconds for blockchain node to start..."
sleep 10
# Execute explorer deployment on ns3
echo ""
echo "Deploying blockchain explorer..."
ssh ns3-root "cd /opt && ./deploy-explorer-remote.sh"
# Check services
echo ""
echo "Checking service status..."
ssh ns3-root "systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'"
echo ""
echo "✅ Deployment complete!"
echo ""
echo "Services:"
echo " - Blockchain Node RPC: http://localhost:8082"
echo " - Blockchain Explorer: http://localhost:3000"
echo ""
echo "External access:"
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
echo ""
echo "The blockchain node will start syncing automatically."
echo "The explorer connects to the local node and displays real-time data."

View File

@@ -0,0 +1,207 @@
#!/bin/bash
# Deploy blockchain node and explorer to incus container
set -e
echo "🚀 Deploying Blockchain Node and Explorer"
echo "========================================"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Copy blockchain node to container
print_status "Copying blockchain node to container..."
ssh ns3-root "rm -rf /opt/blockchain-node 2>/dev/null || true"
scp -r apps/blockchain-node ns3-root:/opt/
# Setup blockchain node in container
print_status "Setting up blockchain node..."
ssh ns3-root << 'EOF'
cd /opt/blockchain-node
# Create configuration
cat > .env << EOL
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=0.0.0.0
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=memory
EOL
# Create data directory
mkdir -p data/devnet
# Setup Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Generate genesis
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
python scripts/make_genesis.py --output data/devnet/genesis.json --force
EOF
# Create systemd service for blockchain node
print_status "Creating systemd service for blockchain node..."
ssh ns3-root << 'EOF'
cat > /etc/systemd/system/blockchain-node.service << EOL
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/blockchain-rpc.service << EOL
[Unit]
Description=AITBC Blockchain RPC API
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
systemctl daemon-reload
systemctl enable blockchain-node blockchain-rpc
EOF
# Start blockchain node
print_status "Starting blockchain node..."
ssh ns3-root "systemctl start blockchain-node blockchain-rpc"
# Wait for node to start
print_status "Waiting for blockchain node to start..."
sleep 5
# Check status
print_status "Checking blockchain node status..."
ssh ns3-root "systemctl status blockchain-node blockchain-rpc --no-pager | grep -E 'Active:|Main PID:'"
# Copy explorer to container
print_status "Copying blockchain explorer to container..."
ssh ns3-root "rm -rf /opt/blockchain-explorer 2>/dev/null || true"
scp -r apps/blockchain-explorer ns3-root:/opt/
# Setup explorer in container
print_status "Setting up blockchain explorer..."
ssh ns3-root << 'EOF'
cd /opt/blockchain-explorer
# Create Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
EOF
# Create systemd service for explorer
print_status "Creating systemd service for blockchain explorer..."
ssh ns3-root << 'EOF'
cat > /etc/systemd/system/blockchain-explorer.service << EOL
[Unit]
Description=AITBC Blockchain Explorer
After=blockchain-rpc.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-explorer
Environment=PATH=/opt/blockchain-explorer/.venv/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/opt/blockchain-explorer/.venv/bin/python3 main.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
systemctl daemon-reload
systemctl enable blockchain-explorer
EOF
# Start explorer
print_status "Starting blockchain explorer..."
ssh ns3-root "systemctl start blockchain-explorer"
# Wait for explorer to start
print_status "Waiting for explorer to start..."
sleep 3
# Setup port forwarding
print_status "Setting up port forwarding..."
ssh ns3-root << 'EOF'
# Clear existing NAT rules
iptables -t nat -F PREROUTING 2>/dev/null || true
iptables -t nat -F POSTROUTING 2>/dev/null || true
# Add port forwarding for blockchain RPC
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
# Add port forwarding for explorer
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
# Save rules
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v4
# Install iptables-persistent for persistence
apt-get update
apt-get install -y iptables-persistent
EOF
# Check all services
print_status "Checking all services..."
ssh ns3-root "systemctl status blockchain-node blockchain-rpc blockchain-explorer --no-pager | grep -E 'Active:|Main PID:'"
print_success "✅ Deployment complete!"
echo ""
echo "Services deployed:"
echo " - Blockchain Node RPC: http://192.168.100.10:8082"
echo " - Blockchain Explorer: http://192.168.100.10:3000"
echo ""
echo "External access:"
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
echo ""
echo "The explorer is connected to the local blockchain node and will display"
echo "real-time blockchain data including blocks and transactions."

View File

@@ -0,0 +1,94 @@
#!/bin/bash
# Deploy blockchain explorer to incus container
set -e
echo "🔍 Deploying Blockchain Explorer"
echo "================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Copy explorer to container
print_status "Copying blockchain explorer to container..."
ssh ns3-root "rm -rf /opt/blockchain-explorer 2>/dev/null || true"
scp -r apps/blockchain-explorer ns3-root:/opt/
# Setup explorer in container
print_status "Setting up blockchain explorer..."
ssh ns3-root << 'EOF'
cd /opt/blockchain-explorer
# Create Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
EOF
# Create systemd service for explorer
print_status "Creating systemd service for blockchain explorer..."
ssh ns3-root << 'EOF'
cat > /etc/systemd/system/blockchain-explorer.service << EOL
[Unit]
Description=AITBC Blockchain Explorer
After=blockchain-rpc.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-explorer
Environment=PATH=/opt/blockchain-explorer/.venv/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/opt/blockchain-explorer/.venv/bin/python3 main.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
systemctl daemon-reload
systemctl enable blockchain-explorer
EOF
# Start explorer
print_status "Starting blockchain explorer..."
ssh ns3-root "systemctl start blockchain-explorer"
# Wait for explorer to start
print_status "Waiting for explorer to start..."
sleep 3
# Setup port forwarding for explorer
print_status "Setting up port forwarding for explorer..."
ssh ns3-root << 'EOF'
# Add port forwarding for explorer
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
# Save rules
iptables-save > /etc/iptables/rules.v4
EOF
# Check status
print_status "Checking blockchain explorer status..."
ssh ns3-root "systemctl status blockchain-explorer --no-pager | grep -E 'Active:|Main PID:'"
print_success "✅ Blockchain explorer deployed!"
echo ""
echo "Explorer URL: http://192.168.100.10:3000"
echo "External URL: http://aitbc.keisanki.net:3000"
echo ""
echo "The explorer will automatically connect to the local blockchain node."
echo "You can view blocks, transactions, and chain statistics."

View File

@@ -0,0 +1,157 @@
#!/bin/bash
# Deploy blockchain node directly on ns3 server (build in place)
set -e
echo "🚀 Deploying Blockchain Node on ns3 (Build in Place)"
echo "====================================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Check if we're on the right server
print_status "Checking server..."
if [ "$(hostname)" != "ns3" ] && [ "$(hostname)" != "aitbc" ]; then
print_warning "This script should be run on ns3 server"
echo "Please run: ssh ns3-root"
echo "Then: cd /opt && ./deploy-blockchain-remote.sh"
exit 1
fi
# Install dependencies if needed
print_status "Installing dependencies..."
apt-get update
apt-get install -y python3 python3-venv python3-pip git curl
# Create directory
print_status "Creating blockchain node directory..."
mkdir -p /opt/blockchain-node
cd /opt/blockchain-node
# Check if source code exists
if [ ! -d "src" ]; then
print_status "Source code not found in /opt/blockchain-node, copying from /opt/blockchain-node-src..."
if [ -d "/opt/blockchain-node-src" ]; then
cp -r /opt/blockchain-node-src/* .
else
print_warning "Source code not found. Please ensure it was copied properly."
exit 1
fi
fi
# Setup Python environment
print_status "Setting up Python environment..."
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Create configuration with auto-sync
print_status "Creating configuration..."
cat > .env << EOL
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=0.0.0.0
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=memory
EOL
# Create fresh data directory
print_status "Creating fresh data directory..."
rm -rf data
mkdir -p data/devnet
# Generate fresh genesis
print_status "Generating fresh genesis block..."
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
python scripts/make_genesis.py --output data/devnet/genesis.json --force
# Create systemd service for blockchain node
print_status "Creating systemd services..."
cat > /etc/systemd/system/blockchain-node.service << EOL
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/blockchain-rpc.service << EOL
[Unit]
Description=AITBC Blockchain RPC API
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
# Enable and start services
print_status "Starting blockchain node..."
systemctl daemon-reload
systemctl enable blockchain-node blockchain-rpc
systemctl start blockchain-node blockchain-rpc
# Wait for services to start
print_status "Waiting for services to start..."
sleep 5
# Check status
print_status "Checking service status..."
systemctl status blockchain-node blockchain-rpc --no-pager | head -15
# Setup port forwarding if in container
if [ "$(hostname)" = "aitbc" ]; then
print_status "Setting up port forwarding..."
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
iptables-save > /etc/iptables/rules.v4
fi
print_success "✅ Blockchain node deployed!"
echo ""
if [ "$(hostname)" = "aitbc" ]; then
echo "Node RPC: http://192.168.100.10:8082"
echo "External RPC: http://aitbc.keisanki.net:8082"
else
echo "Node RPC: http://95.216.198.140:8082"
echo "External RPC: http://aitbc.keisanki.net:8082"
fi
echo ""
echo "The node will automatically sync on startup."

View File

@@ -0,0 +1,139 @@
#!/bin/bash
# Deploy blockchain node and explorer to incus container
set -e
echo "🚀 Deploying Blockchain Node and Explorer"
echo "========================================"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Copy blockchain node to container
print_status "Copying blockchain node to container..."
ssh ns3-root "rm -rf /opt/blockchain-node 2>/dev/null || true"
scp -r apps/blockchain-node ns3-root:/opt/
# Setup blockchain node in container
print_status "Setting up blockchain node..."
ssh ns3-root << 'EOF'
cd /opt/blockchain-node
# Create configuration
cat > .env << EOL
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=0.0.0.0
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=memory
EOL
# Create data directory
mkdir -p data/devnet
# Setup Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Generate genesis
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
python scripts/make_genesis.py --output data/devnet/genesis.json --force
EOF
# Create systemd service for blockchain node
print_status "Creating systemd service for blockchain node..."
ssh ns3-root << 'EOF'
cat > /etc/systemd/system/blockchain-node.service << EOL
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/blockchain-rpc.service << EOL
[Unit]
Description=AITBC Blockchain RPC API
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
systemctl daemon-reload
systemctl enable blockchain-node blockchain-rpc
EOF
# Start blockchain node
print_status "Starting blockchain node..."
ssh ns3-root "systemctl start blockchain-node blockchain-rpc"
# Wait for node to start
print_status "Waiting for blockchain node to start..."
sleep 5
# Check status
print_status "Checking blockchain node status..."
ssh ns3-root "systemctl status blockchain-node blockchain-rpc --no-pager | grep -E 'Active:|Main PID:'"
# Setup port forwarding
print_status "Setting up port forwarding..."
ssh ns3-root << 'EOF'
# Clear existing rules
iptables -t nat -F PREROUTING 2>/dev/null || true
iptables -t nat -F POSTROUTING 2>/dev/null || true
# Add port forwarding for blockchain RPC
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
# Save rules
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v4
EOF
print_success "✅ Blockchain node deployed!"
echo ""
echo "Node RPC: http://192.168.100.10:8082"
echo "External RPC: http://aitbc.keisanki.net:8082"
echo ""
echo "Next: Deploying blockchain explorer..."

316
scripts/deploy/deploy-direct.sh Executable file
View File

@@ -0,0 +1,316 @@
#!/bin/bash
# Deploy blockchain node and explorer directly on ns3
set -e
echo "🚀 AITBC Direct Deployment on ns3"
echo "================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Check if we're on ns3
if [ "$(hostname)" != "ns3" ] && [ "$(hostname)" != "aitbc" ]; then
print_warning "This script must be run on ns3 server"
echo "Run: ssh ns3-root"
echo "Then: cd /opt && ./deploy-direct.sh"
exit 1
fi
# Stop existing services
print_status "Stopping existing services..."
systemctl stop blockchain-node blockchain-rpc blockchain-explorer nginx 2>/dev/null || true
# Install dependencies
print_status "Installing dependencies..."
apt-get update
apt-get install -y python3 python3-venv python3-pip git curl nginx
# Deploy blockchain node
print_status "Deploying blockchain node..."
cd /opt
rm -rf blockchain-node
cp -r blockchain-node-src blockchain-node
cd blockchain-node
# Create configuration
print_status "Creating configuration..."
cat > .env << EOL
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=0.0.0.0
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=memory
EOL
# Create fresh data directory
rm -rf data
mkdir -p data/devnet
# Setup Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Generate genesis
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
python scripts/make_genesis.py --output data/devnet/genesis.json --force
# Create systemd services
print_status "Creating systemd services..."
cat > /etc/systemd/system/blockchain-node.service << EOL
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/blockchain-rpc.service << EOL
[Unit]
Description=AITBC Blockchain RPC API
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
# Start blockchain services
print_status "Starting blockchain services..."
systemctl daemon-reload
systemctl enable blockchain-node blockchain-rpc
systemctl start blockchain-node blockchain-rpc
# Deploy explorer
print_status "Deploying blockchain explorer..."
cd /opt
rm -rf blockchain-explorer
mkdir -p blockchain-explorer
cd blockchain-explorer
# Create HTML explorer
cat > index.html << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AITBC Blockchain Explorer</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/lucide@latest"></script>
</head>
<body class="bg-gray-50">
<header class="bg-blue-600 text-white shadow-lg">
<div class="container mx-auto px-4 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<i data-lucide="cube" class="w-8 h-8"></i>
<h1 class="text-2xl font-bold">AITBC Blockchain Explorer</h1>
</div>
<button onclick="refreshData()" class="bg-blue-500 hover:bg-blue-400 px-3 py-1 rounded flex items-center space-x-1">
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
<span>Refresh</span>
</button>
</div>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Current Height</p>
<p class="text-2xl font-bold" id="chain-height">-</p>
</div>
<i data-lucide="trending-up" class="w-10 h-10 text-green-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Latest Block</p>
<p class="text-lg font-mono" id="latest-hash">-</p>
</div>
<i data-lucide="hash" class="w-10 h-10 text-blue-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Node Status</p>
<p class="text-lg font-semibold" id="node-status">-</p>
</div>
<i data-lucide="activity" class="w-10 h-10 text-purple-500"></i>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b">
<h2 class="text-xl font-semibold flex items-center">
<i data-lucide="blocks" class="w-5 h-5 mr-2"></i>
Latest Blocks
</h2>
</div>
<div class="p-6">
<table class="w-full">
<thead>
<tr class="text-left text-gray-500 text-sm">
<th class="pb-3">Height</th>
<th class="pb-3">Hash</th>
<th class="pb-3">Timestamp</th>
<th class="pb-3">Transactions</th>
</tr>
</thead>
<tbody id="blocks-table">
<tr>
<td colspan="4" class="text-center py-8 text-gray-500">
Loading blocks...
</td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
<script>
lucide.createIcons();
const RPC_URL = 'http://localhost:8082';
async function refreshData() {
try {
const response = await fetch(`${RPC_URL}/rpc/head`);
const head = await response.json();
document.getElementById('chain-height').textContent = head.height || '-';
document.getElementById('latest-hash').textContent = head.hash ? head.hash.substring(0, 16) + '...' : '-';
document.getElementById('node-status').innerHTML = '<span class="text-green-500">Online</span>';
// Load last 10 blocks
const tbody = document.getElementById('blocks-table');
tbody.innerHTML = '';
for (let i = 0; i < 10 && head.height - i >= 0; i++) {
const blockResponse = await fetch(`${RPC_URL}/rpc/blocks/${head.height - i}`);
const block = await blockResponse.json();
const row = tbody.insertRow();
row.innerHTML = `
<td class="py-3 font-mono">${block.height}</td>
<td class="py-3 font-mono text-sm">${block.hash ? block.hash.substring(0, 16) + '...' : '-'}</td>
<td class="py-3 text-sm">${new Date(block.timestamp * 1000).toLocaleString()}</td>
<td class="py-3">${block.transactions ? block.transactions.length : 0}</td>
`;
}
} catch (error) {
console.error('Error:', error);
document.getElementById('node-status').innerHTML = '<span class="text-red-500">Error</span>';
}
}
refreshData();
setInterval(refreshData, 30000);
</script>
</body>
</html>
EOF
# Configure nginx
print_status "Configuring nginx..."
cat > /etc/nginx/sites-available/blockchain-explorer << EOL
server {
listen 3000;
server_name _;
root /opt/blockchain-explorer;
index index.html;
location / {
try_files \$uri \$uri/ =404;
}
}
EOL
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
nginx -t
systemctl reload nginx
# Setup port forwarding if in container
if [ "$(hostname)" = "aitbc" ]; then
print_status "Setting up port forwarding..."
iptables -t nat -F PREROUTING 2>/dev/null || true
iptables -t nat -F POSTROUTING 2>/dev/null || true
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
iptables-save > /etc/iptables/rules.v4
fi
# Wait for services to start
print_status "Waiting for services to start..."
sleep 5
# Check services
print_status "Checking service status..."
systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'
print_success "✅ Deployment complete!"
echo ""
echo "Services:"
if [ "$(hostname)" = "aitbc" ]; then
echo " - Blockchain Node RPC: http://192.168.100.10:8082"
echo " - Blockchain Explorer: http://192.168.100.10:3000"
echo ""
echo "External access:"
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
else
echo " - Blockchain Node RPC: http://localhost:8082"
echo " - Blockchain Explorer: http://localhost:3000"
echo ""
echo "External access:"
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"
fi

View File

@@ -0,0 +1,396 @@
#!/bin/bash
# Deploy blockchain explorer directly on ns3 server
set -e
echo "🔍 Deploying Blockchain Explorer on ns3"
echo "======================================"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Check if we're on the right server
if [ "$(hostname)" != "ns3" ] && [ "$(hostname)" != "aitbc" ]; then
print_warning "This script should be run on ns3 server"
exit 1
fi
# Create directory
print_status "Creating blockchain explorer directory..."
mkdir -p /opt/blockchain-explorer
cd /opt/blockchain-explorer
# Create a simple HTML-based explorer (no build needed)
print_status "Creating web-based explorer..."
cat > index.html << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AITBC Blockchain Explorer</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/lucide@latest"></script>
<style>
.fade-in { animation: fadeIn 0.3s ease-in; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
</style>
</head>
<body class="bg-gray-50">
<header class="bg-blue-600 text-white shadow-lg">
<div class="container mx-auto px-4 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<i data-lucide="cube" class="w-8 h-8"></i>
<h1 class="text-2xl font-bold">AITBC Blockchain Explorer</h1>
</div>
<div class="flex items-center space-x-4">
<span class="text-sm">Network: <span class="font-mono bg-blue-700 px-2 py-1 rounded">ait-devnet</span></span>
<button onclick="refreshData()" class="bg-blue-500 hover:bg-blue-400 px-3 py-1 rounded flex items-center space-x-1">
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
<span>Refresh</span>
</button>
</div>
</div>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<!-- Chain Stats -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Current Height</p>
<p class="text-2xl font-bold" id="chain-height">-</p>
</div>
<i data-lucide="trending-up" class="w-10 h-10 text-green-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Latest Block</p>
<p class="text-lg font-mono" id="latest-hash">-</p>
</div>
<i data-lucide="hash" class="w-10 h-10 text-blue-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Node Status</p>
<p class="text-lg font-semibold" id="node-status">-</p>
</div>
<i data-lucide="activity" class="w-10 h-10 text-purple-500"></i>
</div>
</div>
</div>
<!-- Search -->
<div class="bg-white rounded-lg shadow p-6 mb-8">
<div class="flex space-x-4">
<input type="text" id="search-input" placeholder="Search by block height, hash, or transaction hash"
class="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
<button onclick="search()" class="bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700">
Search
</button>
</div>
</div>
<!-- Latest Blocks -->
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b">
<h2 class="text-xl font-semibold flex items-center">
<i data-lucide="blocks" class="w-5 h-5 mr-2"></i>
Latest Blocks
</h2>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="w-full">
<thead>
<tr class="text-left text-gray-500 text-sm">
<th class="pb-3">Height</th>
<th class="pb-3">Hash</th>
<th class="pb-3">Timestamp</th>
<th class="pb-3">Transactions</th>
<th class="pb-3">Actions</th>
</tr>
</thead>
<tbody id="blocks-table">
<tr>
<td colspan="5" class="text-center py-8 text-gray-500">
Loading blocks...
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Block Details Modal -->
<div id="block-modal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50">
<div class="flex items-center justify-center min-h-screen p-4">
<div class="bg-white rounded-lg max-w-4xl w-full max-h-[90vh] overflow-y-auto">
<div class="p-6 border-b">
<div class="flex justify-between items-center">
<h2 class="text-2xl font-bold">Block Details</h2>
<button onclick="closeModal()" class="text-gray-500 hover:text-gray-700">
<i data-lucide="x" class="w-6 h-6"></i>
</button>
</div>
</div>
<div class="p-6" id="block-details">
<!-- Block details will be loaded here -->
</div>
</div>
</div>
</div>
</main>
<footer class="bg-gray-800 text-white mt-12">
<div class="container mx-auto px-4 py-6 text-center">
<p class="text-sm">AITBC Blockchain Explorer - Connected to node at http://localhost:8082</p>
</div>
</footer>
<script>
// Initialize lucide icons
lucide.createIcons();
// RPC URL - change based on environment
const RPC_URL = window.location.hostname === 'localhost' ?
'http://localhost:8082' :
'http://95.216.198.140:8082';
// Global state
let currentData = {};
// Load initial data
document.addEventListener('DOMContentLoaded', () => {
refreshData();
});
// Refresh all data
async function refreshData() {
try {
await Promise.all([
loadChainStats(),
loadLatestBlocks()
]);
} catch (error) {
console.error('Error refreshing data:', error);
document.getElementById('node-status').innerHTML = '<span class="text-red-500">Error</span>';
}
}
// Load chain statistics
async function loadChainStats() {
const response = await fetch(`${RPC_URL}/rpc/head`);
const data = await response.json();
document.getElementById('chain-height').textContent = data.height || '-';
document.getElementById('latest-hash').textContent = data.hash ? data.hash.substring(0, 16) + '...' : '-';
document.getElementById('node-status').innerHTML = '<span class="text-green-500">Online</span>';
currentData.head = data;
}
// Load latest blocks
async function loadLatestBlocks() {
const tbody = document.getElementById('blocks-table');
tbody.innerHTML = '<tr><td colspan="5" class="text-center py-8 text-gray-500">Loading blocks...</td></tr>';
const head = await fetch(`${RPC_URL}/rpc/head`).then(r => r.json());
const blocks = [];
// Load last 10 blocks
for (let i = 0; i < 10 && head.height - i >= 0; i++) {
const block = await fetch(`${RPC_URL}/rpc/blocks/${head.height - i}`).then(r => r.json());
blocks.push(block);
}
tbody.innerHTML = blocks.map(block => `
<tr class="border-t hover:bg-gray-50">
<td class="py-3 font-mono">${block.height}</td>
<td class="py-3 font-mono text-sm">${block.hash ? block.hash.substring(0, 16) + '...' : '-'}</td>
<td class="py-3 text-sm">${formatTimestamp(block.timestamp)}</td>
<td class="py-3">${block.transactions ? block.transactions.length : 0}</td>
<td class="py-3">
<button onclick="showBlockDetails(${block.height})" class="text-blue-600 hover:text-blue-800">
View Details
</button>
</td>
</tr>
`).join('');
}
// Show block details
async function showBlockDetails(height) {
const block = await fetch(`${RPC_URL}/rpc/blocks/${height}`).then(r => r.json());
const modal = document.getElementById('block-modal');
const details = document.getElementById('block-details');
details.innerHTML = `
<div class="space-y-6">
<div>
<h3 class="text-lg font-semibold mb-2">Block Header</h3>
<div class="bg-gray-50 rounded p-4 space-y-2">
<div class="flex justify-between">
<span class="text-gray-600">Height:</span>
<span class="font-mono">${block.height}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Hash:</span>
<span class="font-mono text-sm">${block.hash || '-'}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Parent Hash:</span>
<span class="font-mono text-sm">${block.parent_hash || '-'}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Timestamp:</span>
<span>${formatTimestamp(block.timestamp)}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Proposer:</span>
<span class="font-mono text-sm">${block.proposer || '-'}</span>
</div>
</div>
</div>
${block.transactions && block.transactions.length > 0 ? `
<div>
<h3 class="text-lg font-semibold mb-2">Transactions (${block.transactions.length})</h3>
<div class="space-y-2">
${block.transactions.map(tx => `
<div class="bg-gray-50 rounded p-4">
<div class="flex justify-between mb-2">
<span class="text-gray-600">Hash:</span>
<span class="font-mono text-sm">${tx.hash || '-'}</span>
</div>
<div class="flex justify-between mb-2">
<span class="text-gray-600">Type:</span>
<span>${tx.type || '-'}</span>
</div>
<div class="flex justify-between mb-2">
<span class="text-gray-600">From:</span>
<span class="font-mono text-sm">${tx.sender || '-'}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Fee:</span>
<span>${tx.fee || '0'}</span>
</div>
</div>
`).join('')}
</div>
</div>
` : '<p class="text-gray-500">No transactions in this block</p>'}
</div>
`;
modal.classList.remove('hidden');
}
// Close modal
function closeModal() {
document.getElementById('block-modal').classList.add('hidden');
}
// Search functionality
async function search() {
const query = document.getElementById('search-input').value.trim();
if (!query) return;
// Try block height first
if (/^\\d+$/.test(query)) {
showBlockDetails(parseInt(query));
return;
}
// TODO: Add transaction hash search
alert('Search by block height is currently supported');
}
// Format timestamp
function formatTimestamp(timestamp) {
if (!timestamp) return '-';
return new Date(timestamp * 1000).toLocaleString();
}
// Auto-refresh every 30 seconds
setInterval(refreshData, 30000);
</script>
</body>
</html>
EOF
# Install a simple web server
print_status "Installing web server..."
apt-get install -y nginx
# Configure nginx to serve the explorer
print_status "Configuring nginx..."
cat > /etc/nginx/sites-available/blockchain-explorer << EOL
server {
listen 3000;
server_name _;
root /opt/blockchain-explorer;
index index.html;
location / {
try_files \$uri \$uri/ =404;
}
# CORS headers for API access
location /rpc/ {
proxy_pass http://localhost:8082;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
}
EOL
# Enable the site
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
# Test and reload nginx
nginx -t
systemctl reload nginx
# Setup port forwarding if in container
if [ "$(hostname)" = "aitbc" ]; then
print_status "Setting up port forwarding..."
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
iptables-save > /etc/iptables/rules.v4
fi
print_status "Checking nginx status..."
systemctl status nginx --no-pager | head -10
print_success "✅ Blockchain explorer deployed!"
echo ""
echo "Explorer URL: http://localhost:3000"
if [ "$(hostname)" = "aitbc" ]; then
echo "External URL: http://aitbc.keisanki.net:3000"
else
echo "External URL: http://aitbc.keisanki.net:3000"
fi
echo ""
echo "The explorer is a static HTML site served by nginx."

View File

@@ -0,0 +1,121 @@
#!/bin/bash
# Deploy the first blockchain node
set -e
echo "🚀 Deploying First Blockchain Node"
echo "================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
NODE1_DIR="/opt/blockchain-node"
# Create configuration for first node
print_status "Creating configuration for first node..."
cat > $NODE1_DIR/.env << EOF
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=127.0.0.1
RPC_BIND_PORT=8080
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=node1_proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=http
GOSSIP_BROADCAST_URL=http://127.0.0.1:7071/gossip
EOF
# Create data directory
mkdir -p $NODE1_DIR/data/devnet
# Generate genesis file
print_status "Generating genesis file..."
cd $NODE1_DIR
export PYTHONPATH="${NODE1_DIR}/src:${NODE1_DIR}/scripts:${PYTHONPATH:-}"
python3 scripts/make_genesis.py --output data/devnet/genesis.json --force
# Create systemd service
print_status "Creating systemd service..."
sudo cat > /etc/systemd/system/blockchain-node.service << EOF
[Unit]
Description=AITBC Blockchain Node 1
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=$NODE1_DIR
Environment=PATH=$NODE1_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=$NODE1_DIR/src:$NODE1_DIR/scripts
ExecStart=$NODE1_DIR/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Create RPC API service
print_status "Creating RPC API service..."
sudo cat > /etc/systemd/system/blockchain-rpc.service << EOF
[Unit]
Description=AITBC Blockchain RPC API 1
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=$NODE1_DIR
Environment=PATH=$NODE1_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=$NODE1_DIR/src:$NODE1_DIR/scripts
ExecStart=$NODE1_DIR/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8080
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Setup Python environment if not exists
if [ ! -d "$NODE1_DIR/.venv" ]; then
print_status "Setting up Python environment..."
cd $NODE1_DIR
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
fi
# Enable and start services
print_status "Enabling and starting services..."
sudo systemctl daemon-reload
sudo systemctl enable blockchain-node blockchain-rpc
sudo systemctl start blockchain-node blockchain-rpc
# Check status
print_status "Checking service status..."
sudo systemctl status blockchain-node --no-pager -l
sudo systemctl status blockchain-rpc --no-pager -l
echo ""
print_status "✅ First blockchain node deployed!"
echo ""
echo "Node 1 RPC: http://127.0.0.1:8080"
echo "Node 2 RPC: http://127.0.0.1:8081"
echo ""
echo "To check logs:"
echo " Node 1: sudo journalctl -u blockchain-node -f"
echo " Node 2: sudo journalctl -u blockchain-node-2 -f"

View File

@@ -0,0 +1,306 @@
#!/bin/bash
# Deploy blockchain node and explorer inside the container
set -e
echo "🚀 Deploying Inside Container"
echo "============================"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Check if we're in the container
if [ ! -f /proc/1/environ ] || ! grep -q container=lxc /proc/1/environ 2>/dev/null; then
if [ "$(hostname)" != "aitbc" ]; then
print_warning "This script must be run inside the aitbc container"
exit 1
fi
fi
# Stop existing services
print_status "Stopping existing services..."
systemctl stop blockchain-node blockchain-rpc nginx 2>/dev/null || true
# Install dependencies
print_status "Installing dependencies..."
apt-get update
apt-get install -y python3 python3-venv python3-pip git curl nginx
# Deploy blockchain node
print_status "Deploying blockchain node..."
cd /opt
rm -rf blockchain-node
# The source is already in blockchain-node-src, copy it properly
cp -r blockchain-node-src blockchain-node
cd blockchain-node
# Check if pyproject.toml exists
if [ ! -f pyproject.toml ]; then
print_warning "pyproject.toml not found, looking for it..."
find . -name "pyproject.toml" -type f
# If it's in a subdirectory, move everything up
if [ -f blockchain-node-src/pyproject.toml ]; then
print_status "Moving files from nested directory..."
mv blockchain-node-src/* .
rmdir blockchain-node-src
fi
fi
# Create configuration
print_status "Creating configuration..."
cat > .env << EOL
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=0.0.0.0
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=memory
EOL
# Create fresh data directory
rm -rf data
mkdir -p data/devnet
# Setup Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Generate genesis
export PYTHONPATH="${PWD}/src:${PWD}/scripts:${PYTHONPATH:-}"
python scripts/make_genesis.py --output data/devnet/genesis.json --force
# Create systemd services
print_status "Creating systemd services..."
cat > /etc/systemd/system/blockchain-node.service << EOL
[Unit]
Description=AITBC Blockchain Node
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/blockchain-rpc.service << EOL
[Unit]
Description=AITBC Blockchain RPC API
After=blockchain-node.service
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOL
# Start blockchain services
print_status "Starting blockchain services..."
systemctl daemon-reload
systemctl enable blockchain-node blockchain-rpc
systemctl start blockchain-node blockchain-rpc
# Deploy explorer
print_status "Deploying blockchain explorer..."
cd /opt
rm -rf blockchain-explorer
mkdir -p blockchain-explorer
cd blockchain-explorer
# Create HTML explorer
cat > index.html << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AITBC Blockchain Explorer</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/lucide@latest"></script>
</head>
<body class="bg-gray-50">
<header class="bg-blue-600 text-white shadow-lg">
<div class="container mx-auto px-4 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-3">
<i data-lucide="cube" class="w-8 h-8"></i>
<h1 class="text-2xl font-bold">AITBC Blockchain Explorer</h1>
</div>
<button onclick="refreshData()" class="bg-blue-500 hover:bg-blue-400 px-3 py-1 rounded flex items-center space-x-1">
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
<span>Refresh</span>
</button>
</div>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Current Height</p>
<p class="text-2xl font-bold" id="chain-height">-</p>
</div>
<i data-lucide="trending-up" class="w-10 h-10 text-green-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Latest Block</p>
<p class="text-lg font-mono" id="latest-hash">-</p>
</div>
<i data-lucide="hash" class="w-10 h-10 text-blue-500"></i>
</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-500 text-sm">Node Status</p>
<p class="text-lg font-semibold" id="node-status">-</p>
</div>
<i data-lucide="activity" class="w-10 h-10 text-purple-500"></i>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b">
<h2 class="text-xl font-semibold flex items-center">
<i data-lucide="blocks" class="w-5 h-5 mr-2"></i>
Latest Blocks
</h2>
</div>
<div class="p-6">
<table class="w-full">
<thead>
<tr class="text-left text-gray-500 text-sm">
<th class="pb-3">Height</th>
<th class="pb-3">Hash</th>
<th class="pb-3">Timestamp</th>
<th class="pb-3">Transactions</th>
</tr>
</thead>
<tbody id="blocks-table">
<tr>
<td colspan="4" class="text-center py-8 text-gray-500">
Loading blocks...
</td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
<script>
lucide.createIcons();
const RPC_URL = 'http://localhost:8082';
async function refreshData() {
try {
const response = await fetch(`${RPC_URL}/rpc/head`);
const head = await response.json();
document.getElementById('chain-height').textContent = head.height || '-';
document.getElementById('latest-hash').textContent = head.hash ? head.hash.substring(0, 16) + '...' : '-';
document.getElementById('node-status').innerHTML = '<span class="text-green-500">Online</span>';
// Load last 10 blocks
const tbody = document.getElementById('blocks-table');
tbody.innerHTML = '';
for (let i = 0; i < 10 && head.height - i >= 0; i++) {
const blockResponse = await fetch(`${RPC_URL}/rpc/blocks/${head.height - i}`);
const block = await blockResponse.json();
const row = tbody.insertRow();
row.innerHTML = `
<td class="py-3 font-mono">${block.height}</td>
<td class="py-3 font-mono text-sm">${block.hash ? block.hash.substring(0, 16) + '...' : '-'}</td>
<td class="py-3 text-sm">${new Date(block.timestamp * 1000).toLocaleString()}</td>
<td class="py-3">${block.transactions ? block.transactions.length : 0}</td>
`;
}
} catch (error) {
console.error('Error:', error);
document.getElementById('node-status').innerHTML = '<span class="text-red-500">Error</span>';
}
}
refreshData();
setInterval(refreshData, 30000);
</script>
</body>
</html>
EOF
# Configure nginx
print_status "Configuring nginx..."
cat > /etc/nginx/sites-available/blockchain-explorer << EOL
server {
listen 3000;
server_name _;
root /opt/blockchain-explorer;
index index.html;
location / {
try_files \$uri \$uri/ =404;
}
}
EOL
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
nginx -t
systemctl reload nginx
# Wait for services to start
print_status "Waiting for services to start..."
sleep 5
# Check services
print_status "Checking service status..."
systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'
print_success "✅ Deployment complete in container!"
echo ""
echo "Services:"
echo " - Blockchain Node RPC: http://localhost:8082"
echo " - Blockchain Explorer: http://localhost:3000"
echo ""
echo "These are accessible from the host via port forwarding."

View File

@@ -0,0 +1,56 @@
#!/bin/bash
# Deploy Modern Blockchain Explorer
set -e
echo "🚀 Deploying Modern Blockchain Explorer"
echo "======================================"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Stop existing services
print_status "Stopping existing services..."
systemctl stop nginx 2>/dev/null || true
# Create directory
print_status "Creating explorer directory..."
rm -rf /opt/blockchain-explorer
mkdir -p /opt/blockchain-explorer/assets
# Copy files
print_status "Copying explorer files..."
cp -r /opt/blockchain-node-src/apps/blockchain-explorer/* /opt/blockchain-explorer/
# Update nginx configuration
print_status "Updating nginx configuration..."
cp /opt/blockchain-explorer/nginx.conf /etc/nginx/sites-available/blockchain-explorer
ln -sf /etc/nginx/sites-available/blockchain-explorer /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
# Test and start nginx
print_status "Starting nginx..."
nginx -t
systemctl start nginx
print_success "✅ Modern explorer deployed!"
echo ""
echo "Access URLs:"
echo " - Explorer: http://localhost:3000/"
echo " - API: http://localhost:3000/api/v1/"
echo ""
echo "Standardized API Endpoints:"
echo " - GET /api/v1/chain/head"
echo " - GET /api/v1/chain/blocks?limit=N"
echo " - GET /api/v1/chain/blocks/{height}"

View File

@@ -0,0 +1,160 @@
#!/bin/bash
# Deploy nginx reverse proxy for AITBC services
# This replaces firehol/iptables port forwarding with nginx reverse proxy
set -e
echo "🚀 Deploying Nginx Reverse Proxy for AITBC"
echo "=========================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if we're on the host server
if ! grep -q "ns3-root" ~/.ssh/config 2>/dev/null; then
print_error "ns3-root SSH configuration not found. Please add it to ~/.ssh/config"
exit 1
fi
# Install nginx on host if not already installed
print_status "Checking nginx installation on host..."
ssh ns3-root "which nginx > /dev/null || (apt-get update && apt-get install -y nginx)"
# Install certbot for SSL certificates
print_status "Checking certbot installation..."
ssh ns3-root "which certbot > /dev/null || (apt-get update && apt-get install -y certbot python3-certbot-nginx)"
# Copy nginx configuration
print_status "Copying nginx configuration..."
scp infra/nginx/nginx-aitbc-reverse-proxy.conf ns3-root:/tmp/aitbc-reverse-proxy.conf
# Backup existing nginx configuration
print_status "Backing up existing nginx configuration..."
ssh ns3-root "mkdir -p /etc/nginx/backup && cp -r /etc/nginx/sites-available/* /etc/nginx/backup/ 2>/dev/null || true"
# Install the new configuration
print_status "Installing nginx reverse proxy configuration..."
ssh ns3-root << 'EOF'
# Remove existing configurations
rm -f /etc/nginx/sites-enabled/default
rm -f /etc/nginx/sites-available/aitbc*
# Copy new configuration
cp /tmp/aitbc-reverse-proxy.conf /etc/nginx/sites-available/aitbc-reverse-proxy.conf
# Create symbolic link
ln -sf /etc/nginx/sites-available/aitbc-reverse-proxy.conf /etc/nginx/sites-enabled/
# Test nginx configuration
nginx -t
EOF
# Check if SSL certificate exists
print_status "Checking SSL certificate..."
if ! ssh ns3-root "test -f /etc/letsencrypt/live/aitbc.keisanki.net/fullchain.pem"; then
print_warning "SSL certificate not found. Obtaining Let's Encrypt certificate..."
# Obtain SSL certificate
ssh ns3-root << 'EOF'
# Stop nginx temporarily
systemctl stop nginx 2>/dev/null || true
# Obtain certificate
certbot certonly --standalone -d aitbc.keisanki.net -d api.aitbc.keisanki.net -d rpc.aitbc.keisanki.net --email admin@keisanki.net --agree-tos --non-interactive
# Start nginx
systemctl start nginx
EOF
if [ $? -ne 0 ]; then
print_error "Failed to obtain SSL certificate. Please run certbot manually:"
echo "certbot certonly --standalone -d aitbc.keisanki.net -d api.aitbc.keisanki.net -d rpc.aitbc.keisanki.net"
exit 1
fi
fi
# Restart nginx
print_status "Restarting nginx..."
ssh ns3-root "systemctl restart nginx && systemctl enable nginx"
# Remove old iptables rules (optional)
print_warning "Removing old iptables port forwarding rules (if they exist)..."
ssh ns3-root << 'EOF'
# Flush existing NAT rules for AITBC ports
iptables -t nat -D PREROUTING -p tcp --dport 8000 -j DNAT --to-destination 192.168.100.10:8000 2>/dev/null || true
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 8000 -j MASQUERADE 2>/dev/null || true
iptables -t nat -D PREROUTING -p tcp --dport 8081 -j DNAT --to-destination 192.168.100.10:8081 2>/dev/null || true
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 8081 -j MASQUERADE 2>/dev/null || true
iptables -t nat -D PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082 2>/dev/null || true
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE 2>/dev/null || true
iptables -t nat -D PREROUTING -p tcp --dport 9080 -j DNAT --to-destination 192.168.100.10:9080 2>/dev/null || true
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 9080 -j MASQUERADE 2>/dev/null || true
iptables -t nat -D PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000 2>/dev/null || true
iptables -t nat -D POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE 2>/dev/null || true
# Save iptables rules
iptables-save > /etc/iptables/rules.v4 2>/dev/null || true
EOF
# Wait for nginx to start
sleep 2
# Test the configuration
print_status "Testing reverse proxy configuration..."
echo ""
# Test main domain
if curl -s -o /dev/null -w "%{http_code}" https://aitbc.keisanki.net/health | grep -q "200"; then
print_status "✅ Main domain (aitbc.keisanki.net) - OK"
else
print_error "❌ Main domain (aitbc.keisanki.net) - FAILED"
fi
# Test API endpoint
if curl -s -o /dev/null -w "%{http_code}" https://aitbc.keisanki.net/api/health | grep -q "200"; then
print_status "✅ API endpoint - OK"
else
print_warning "⚠️ API endpoint - Not responding (service may not be running)"
fi
# Test RPC endpoint
if curl -s -o /dev/null -w "%{http_code}" https://aitbc.keisanki.net/rpc/head | grep -q "200"; then
print_status "✅ RPC endpoint - OK"
else
print_warning "⚠️ RPC endpoint - Not responding (blockchain node may not be running)"
fi
echo ""
print_status "🎉 Nginx reverse proxy deployment complete!"
echo ""
echo "Service URLs:"
echo " • Blockchain Explorer: https://aitbc.keisanki.net"
echo " • API: https://aitbc.keisanki.net/api/"
echo " • RPC: https://aitbc.keisanki.net/rpc/"
echo " • Exchange: https://aitbc.keisanki.net/exchange/"
echo ""
echo "Alternative URLs:"
echo " • API-only: https://api.aitbc.keisanki.net"
echo " • RPC-only: https://rpc.aitbc.keisanki.net"
echo ""
echo "Note: Make sure all services are running in the container:"
echo " • blockchain-explorer.service (port 3000)"
echo " • coordinator-api.service (port 8000)"
echo " • blockchain-rpc.service (port 8082)"
echo " • aitbc-exchange.service (port 9080)"

View File

@@ -0,0 +1,18 @@
#!/bin/bash
# Deploy blockchain node by building directly on ns3 server
echo "🚀 Remote Blockchain Deployment (Build on Server)"
echo "=============================================="
# Copy deployment script to server
echo "Copying deployment script to ns3..."
scp scripts/deploy/deploy-blockchain-remote.sh ns3-root:/opt/
# Execute deployment on server
echo "Executing deployment on ns3 (utilizing gigabit connection)..."
ssh ns3-root "cd /opt && chmod +x deploy-blockchain-remote.sh && ./deploy-blockchain-remote.sh"
echo ""
echo "Deployment complete!"
echo "The blockchain node was built directly on ns3 using its fast connection."

View File

@@ -0,0 +1,127 @@
#!/bin/bash
# Deploy a second blockchain node on the same server
set -e
echo "🚀 Deploying Second Blockchain Node"
echo "=================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Create directory for second node
print_status "Creating directory for second node..."
NODE2_DIR="/opt/blockchain-node-2"
sudo mkdir -p $NODE2_DIR
sudo chown $USER:$USER $NODE2_DIR
# Copy blockchain node code
print_status "Copying blockchain node code..."
cp -r /opt/blockchain-node/* $NODE2_DIR/
# Create configuration for second node
print_status "Creating configuration for second node..."
cat > $NODE2_DIR/.env << EOF
CHAIN_ID=ait-devnet
DB_PATH=./data/chain2.db
RPC_BIND_HOST=127.0.0.1
RPC_BIND_PORT=8081
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7071
PROPOSER_KEY=node2_proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=http
GOSSIP_BROADCAST_URL=http://127.0.0.1:7070/gossip
EOF
# Create data directory
mkdir -p $NODE2_DIR/data/devnet
# Generate genesis file (same as first node)
print_status "Generating genesis file..."
cd $NODE2_DIR
export PYTHONPATH="${NODE2_DIR}/src:${NODE2_DIR}/scripts:${PYTHONPATH:-}"
python3 scripts/make_genesis.py --output data/devnet/genesis.json --force
# Create systemd service
print_status "Creating systemd service..."
sudo cat > /etc/systemd/system/blockchain-node-2.service << EOF
[Unit]
Description=AITBC Blockchain Node 2
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=$NODE2_DIR
Environment=PATH=$NODE2_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=$NODE2_DIR/src:$NODE2_DIR/scripts
ExecStart=$NODE2_DIR/.venv/bin/python3 -m aitbc_chain.main
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Create RPC API service
print_status "Creating RPC API service..."
sudo cat > /etc/systemd/system/blockchain-rpc-2.service << EOF
[Unit]
Description=AITBC Blockchain RPC API 2
After=blockchain-node-2.service
[Service]
Type=exec
User=root
WorkingDirectory=$NODE2_DIR
Environment=PATH=$NODE2_DIR/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=$NODE2_DIR/src:$NODE2_DIR/scripts
ExecStart=$NODE2_DIR/.venv/bin/python3 -m uvicorn aitbc_chain.app:app --host 0.0.0.0 --port 8081
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Setup Python environment
print_status "Setting up Python environment..."
cd $NODE2_DIR
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
# Enable and start services
print_status "Enabling and starting services..."
sudo systemctl daemon-reload
sudo systemctl enable blockchain-node-2 blockchain-rpc-2
sudo systemctl start blockchain-node-2 blockchain-rpc-2
# Check status
print_status "Checking service status..."
sudo systemctl status blockchain-node-2 --no-pager -l
sudo systemctl status blockchain-rpc-2 --no-pager -l
echo ""
print_status "✅ Second blockchain node deployed!"
echo ""
echo "Node 1 RPC: http://127.0.0.1:8080"
echo "Node 2 RPC: http://127.0.0.1:8081"
echo ""
echo "To check logs:"
echo " Node 1: sudo journalctl -u blockchain-node -f"
echo " Node 2: sudo journalctl -u blockchain-node-2 -f"

View File

@@ -0,0 +1,84 @@
#!/bin/bash
# Deploy blockchain node inside incus container aitbc
set -e
echo "🚀 AITBC Deployment in Incus Container"
echo "======================================"
echo "This will deploy inside the aitbc container"
echo ""
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Check if we're on ns3 host
if [ "$(hostname)" != "ns3" ]; then
print_warning "This script must be run on ns3 host"
echo "Run: ssh ns3-root"
exit 1
fi
# Check if container exists
if ! incus list | grep -q "aitbc.*RUNNING"; then
print_warning "Container aitbc is not running"
exit 1
fi
# Copy source to container
print_status "Copying source code to container..."
incus exec aitbc -- rm -rf /opt/blockchain-node-src 2>/dev/null || true
incus exec aitbc -- mkdir -p /opt/blockchain-node-src
# Use the source already on the server
incus file push -r /opt/blockchain-node-src/. aitbc/opt/blockchain-node-src/
# Fix the nested directory issue - move everything up one level
incus exec aitbc -- sh -c 'if [ -d /opt/blockchain-node-src/blockchain-node-src ]; then mv /opt/blockchain-node-src/blockchain-node-src/* /opt/blockchain-node-src/ && rmdir /opt/blockchain-node-src/blockchain-node-src; fi'
# Copy deployment script to container
print_status "Copying deployment script to container..."
incus file push /opt/deploy-in-container.sh aitbc/opt/
# Execute deployment inside container
print_status "Deploying inside container..."
incus exec aitbc -- bash /opt/deploy-in-container.sh
# Setup port forwarding on host
print_status "Setting up port forwarding on host..."
iptables -t nat -F PREROUTING 2>/dev/null || true
iptables -t nat -F POSTROUTING 2>/dev/null || true
# Forward blockchain RPC
iptables -t nat -A PREROUTING -p tcp --dport 8082 -j DNAT --to-destination 192.168.100.10:8082
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 8082 -j MASQUERADE
# Forward explorer
iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 192.168.100.10:3000
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.10 --dport 3000 -j MASQUERADE
# Save rules
mkdir -p /etc/iptables
iptables-save > /etc/iptables/rules.v4
# Check services
print_status "Checking services in container..."
incus exec aitbc -- systemctl status blockchain-node blockchain-rpc nginx --no-pager | grep -E 'Active:|Main PID:'
print_success "✅ Deployment complete!"
echo ""
echo "Services in container aitbc:"
echo " - Blockchain Node RPC: http://192.168.100.10:8082"
echo " - Blockchain Explorer: http://192.168.100.10:3000"
echo ""
echo "External access via ns3:"
echo " - Blockchain Node RPC: http://aitbc.keisanki.net:8082"
echo " - Blockchain Explorer: http://aitbc.keisanki.net:3000"

View File

@@ -0,0 +1,113 @@
#!/bin/bash
# Setup gossip relay to connect blockchain nodes
set -e
echo "🌐 Setting up Gossip Relay for Blockchain Nodes"
echo "=============================================="
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Stop existing nodes
print_status "Stopping blockchain nodes..."
sudo systemctl stop blockchain-node blockchain-node-2 blockchain-rpc blockchain-rpc-2 2>/dev/null || true
# Update node configurations to use broadcast backend
print_status "Updating Node 1 configuration..."
sudo cat > /opt/blockchain-node/.env << EOF
CHAIN_ID=ait-devnet
DB_PATH=./data/chain.db
RPC_BIND_HOST=127.0.0.1
RPC_BIND_PORT=8082
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7070
PROPOSER_KEY=node1_proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=broadcast
GOSSIP_BROADCAST_URL=http://127.0.0.1:7070/gossip
EOF
print_status "Updating Node 2 configuration..."
sudo cat > /opt/blockchain-node-2/.env << EOF
CHAIN_ID=ait-devnet
DB_PATH=./data/chain2.db
RPC_BIND_HOST=127.0.0.1
RPC_BIND_PORT=8081
P2P_BIND_HOST=0.0.0.0
P2P_BIND_PORT=7071
PROPOSER_KEY=node2_proposer_key_$(date +%s)
MINT_PER_UNIT=1000
COORDINATOR_RATIO=0.05
GOSSIP_BACKEND=broadcast
GOSSIP_BROADCAST_URL=http://127.0.0.1:7070/gossip
EOF
# Create gossip relay service
print_status "Creating gossip relay service..."
sudo cat > /etc/systemd/system/blockchain-gossip-relay.service << EOF
[Unit]
Description=AITBC Blockchain Gossip Relay
After=network.target
[Service]
Type=exec
User=root
WorkingDirectory=/opt/blockchain-node
Environment=PATH=/opt/blockchain-node/.venv/bin:/usr/local/bin:/usr/bin:/bin
Environment=PYTHONPATH=/opt/blockchain-node/src:/opt/blockchain-node/scripts
ExecStart=/opt/blockchain-node/.venv/bin/python3 -m aitbc_chain.gossip.relay --port 7070 --host 0.0.0.0
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Enable and start gossip relay
print_status "Starting gossip relay..."
sudo systemctl daemon-reload
sudo systemctl enable blockchain-gossip-relay
sudo systemctl start blockchain-gossip-relay
# Wait for relay to start
sleep 2
# Check if relay is running
print_status "Checking gossip relay status..."
sudo systemctl status blockchain-gossip-relay --no-pager | head -10
# Restart blockchain nodes
print_status "Restarting blockchain nodes with shared gossip..."
sudo systemctl start blockchain-node blockchain-node-2 blockchain-rpc blockchain-rpc-2
# Wait for nodes to start
sleep 3
# Check status
print_status "Checking node status..."
sudo systemctl status blockchain-node blockchain-node-2 --no-pager | grep -E 'Active:|Main PID:'
echo ""
print_status "✅ Gossip relay setup complete!"
echo ""
echo "Nodes are now connected via shared gossip backend."
echo "They should sync blocks and transactions."
echo ""
echo "To verify connectivity:"
echo " 1. Run: python /opt/test_blockchain_simple.py"
echo " 2. Check if heights are converging"
echo ""
echo "Gossip relay logs: sudo journalctl -u blockchain-gossip-relay -f"

View File

@@ -0,0 +1,40 @@
#!/bin/bash
# Test if blockchain node and explorer are running
echo "🔍 Testing Blockchain Deployment"
echo "==============================="
# Test blockchain RPC
echo "Testing blockchain RPC..."
if curl -s http://aitbc.keisanki.net:8082/rpc/head > /dev/null; then
echo "✅ Blockchain RPC is accessible"
curl -s http://aitbc.keisanki.net:8082/rpc/head | jq '.height'
else
echo "❌ Blockchain RPC is not accessible"
fi
# Test explorer
echo ""
echo "Testing blockchain explorer..."
if curl -s http://aitbc.keisanki.net:3000 > /dev/null; then
echo "✅ Explorer is accessible"
else
echo "❌ Explorer is not accessible"
fi
# Check services on server
echo ""
echo "Checking service status on ns3..."
ssh ns3-root "systemctl is-active blockchain-node blockchain-rpc nginx" | while read service status; do
if [ "$status" = "active" ]; then
echo "$service is running"
else
echo "$service is not running"
fi
done
# Check logs if needed
echo ""
echo "Recent blockchain logs:"
ssh ns3-root "journalctl -u blockchain-node -n 5 --no-pager"