All checks were successful
Documentation Validation / validate-docs (push) Successful in 13s
- Comprehensive workflow for setting up two-node AITBC blockchain - aitbc1 as genesis authority, aitbc as follower node - Includes wallet creation, genesis setup, and cross-node transactions - Uses standardized directory structure with /var/lib/aitbc and /etc/aitbc - Step-by-step commands for Redis gossip sync and RPC configuration
270 lines
8.0 KiB
Markdown
270 lines
8.0 KiB
Markdown
---
|
|
description: Multi-node blockchain deployment and setup workflow
|
|
---
|
|
|
|
# Multi-Node Blockchain Deployment Workflow
|
|
|
|
This workflow sets up a two-node AITBC blockchain network (aitbc1 as genesis authority, aitbc as follower node), creates wallets, and demonstrates cross-node transactions.
|
|
|
|
## Prerequisites
|
|
|
|
- SSH access to both nodes (aitbc1 and aitbc)
|
|
- Both nodes have the AITBC repository cloned
|
|
- Redis available for cross-node gossip
|
|
- Python venv at `/opt/aitbc/venv`
|
|
|
|
## Directory Structure
|
|
|
|
- `/opt/aitbc/venv` - Central Python virtual environment
|
|
- `/opt/aitbc/requirements.txt` - Python dependencies
|
|
- `/var/lib/aitbc/data` - Blockchain database files
|
|
- `/var/lib/aitbc/keystore` - Wallet credentials
|
|
- `/etc/aitbc/` - Configuration files
|
|
- `/var/log/aitbc/` - Service logs
|
|
|
|
## Steps
|
|
|
|
### 1. Prepare aitbc1 (Genesis Authority Node)
|
|
|
|
```bash
|
|
# SSH to aitbc1
|
|
ssh aitbc1
|
|
|
|
# Pull latest code
|
|
cd /opt/aitbc
|
|
git pull origin main
|
|
|
|
# Install/update dependencies
|
|
/opt/aitbc/venv/bin/pip install -r requirements.txt
|
|
|
|
# Create required directories
|
|
mkdir -p /var/lib/aitbc/data /var/lib/aitbc/keystore /etc/aitbc /var/log/aitbc
|
|
|
|
# Set up environment configuration
|
|
cat > /etc/aitbc/blockchain.env << 'EOF'
|
|
# Blockchain Node Configuration (aitbc1 - genesis authority)
|
|
chain_id=ait-mainnet
|
|
supported_chains=ait-mainnet
|
|
rpc_bind_host=0.0.0.0
|
|
rpc_bind_port=8006
|
|
p2p_bind_host=0.0.0.0
|
|
p2p_bind_port=7070
|
|
proposer_id=aitbc1genesis
|
|
enable_block_production=true
|
|
block_time_seconds=10
|
|
keystore_path=/var/lib/aitbc/keystore
|
|
keystore_password_file=/var/lib/aitbc/keystore/.password
|
|
gossip_backend=broadcast
|
|
gossip_broadcast_url=redis://localhost:6379
|
|
db_path=/var/lib/aitbc/data/ait-mainnet/chain.db
|
|
mint_per_unit=0
|
|
coordinator_ratio=0.05
|
|
EOF
|
|
|
|
# Create genesis block with wallets
|
|
cd /opt/aitbc/apps/blockchain-node
|
|
/opt/aitbc/venv/bin/python scripts/setup_production.py \
|
|
--base-dir /opt/aitbc/apps/blockchain-node \
|
|
--chain-id ait-mainnet \
|
|
--total-supply 1000000000
|
|
|
|
# Copy genesis and allocations to standard location
|
|
mkdir -p /var/lib/aitbc/data/ait-mainnet
|
|
cp data/ait-mainnet/genesis.json /var/lib/aitbc/data/ait-mainnet/
|
|
cp data/ait-mainnet/allocations.json /var/lib/aitbc/data/ait-mainnet/
|
|
cp keystore/* /var/lib/aitbc/keystore/
|
|
|
|
# Update systemd services to use new paths
|
|
sed -i 's|EnvironmentFile=/opt/aitbc/.env|EnvironmentFile=/etc/aitbc/blockchain.env|g' /opt/aitbc/systemd/aitbc-blockchain-*.service
|
|
sed -i 's|WorkingDirectory=/opt/aitbc/apps/blockchain-node|WorkingDirectory=/opt/aitbc/apps/blockchain-node|g' /opt/aitbc/systemd/aitbc-blockchain-*.service
|
|
sed -i 's|ExecStart=/opt/aitbc/venv/bin/python|ExecStart=/opt/aitbc/venv/bin/python|g' /opt/aitbc/systemd/aitbc-blockchain-*.service
|
|
|
|
# Enable and start blockchain services
|
|
systemctl daemon-reload
|
|
systemctl enable aitbc-blockchain-node aitbc-blockchain-rpc
|
|
systemctl start aitbc-blockchain-node aitbc-blockchain-rpc
|
|
|
|
# Monitor startup
|
|
journalctl -f -u aitbc-blockchain-node -u aitbc-blockchain-rpc
|
|
```
|
|
|
|
### 2. Verify aitbc1 Genesis State
|
|
|
|
```bash
|
|
# Check blockchain state
|
|
curl -s http://localhost:8006/rpc/head | jq .
|
|
curl -s http://localhost:8006/rpc/info | jq .
|
|
curl -s http://localhost:8006/rpc/supply | jq .
|
|
|
|
# Check genesis wallet balance
|
|
GENESIS_ADDR=$(cat /var/lib/aitbc/keystore/aitbc1genesis.json | jq -r '.address')
|
|
curl -s "http://localhost:8006/rpc/getBalance/$GENESIS_ADDR" | jq .
|
|
```
|
|
|
|
### 3. Prepare aitbc (Follower Node)
|
|
|
|
```bash
|
|
# SSH to aitbc
|
|
ssh aitbc
|
|
|
|
# Pull latest code
|
|
cd /opt/aitbc
|
|
git pull origin main
|
|
|
|
# Install/update dependencies
|
|
/opt/aitbc/venv/bin/pip install -r requirements.txt
|
|
|
|
# Create required directories
|
|
mkdir -p /var/lib/aitbc/data /var/lib/aitbc/keystore /etc/aitbc /var/log/aitbc
|
|
|
|
# Set up follower configuration
|
|
cat > /etc/aitbc/blockchain.env << 'EOF'
|
|
# Blockchain Node Configuration (aitbc - follower node)
|
|
chain_id=ait-mainnet
|
|
supported_chains=ait-mainnet
|
|
rpc_bind_host=0.0.0.0
|
|
rpc_bind_port=8006
|
|
p2p_bind_host=0.0.0.0
|
|
p2p_bind_port=7070
|
|
proposer_id=follower-node-aitbc
|
|
enable_block_production=false
|
|
block_time_seconds=10
|
|
keystore_path=/var/lib/aitbc/keystore
|
|
keystore_password_file=/var/lib/aitbc/keystore/.password
|
|
gossip_backend=broadcast
|
|
gossip_broadcast_url=redis://10.1.223.40:6379
|
|
db_path=/var/lib/aitbc/data/ait-mainnet/chain.db
|
|
mint_per_unit=0
|
|
coordinator_ratio=0.05
|
|
EOF
|
|
|
|
# Copy genesis from aitbc1
|
|
scp aitbc1:/var/lib/aitbc/data/ait-mainnet/genesis.json /var/lib/aitbc/data/ait-mainnet/
|
|
scp aitbc1:/var/lib/aitbc/data/ait-mainnet/allocations.json /var/lib/aitbc/data/ait-mainnet/
|
|
|
|
# Update systemd services
|
|
sed -i 's|EnvironmentFile=/opt/aitbc/.env|EnvironmentFile=/etc/aitbc/blockchain.env|g' /opt/aitbc/systemd/aitbc-blockchain-*.service
|
|
|
|
# Stop any existing services and clear old data
|
|
systemctl stop aitbc-blockchain-* 2>/dev/null || true
|
|
rm -f /var/lib/aitbc/data/ait-mainnet/chain.db*
|
|
|
|
# Start follower services
|
|
systemctl daemon-reload
|
|
systemctl enable aitbc-blockchain-node aitbc-blockchain-rpc
|
|
systemctl start aitbc-blockchain-node aitbc-blockchain-rpc
|
|
|
|
# Monitor sync
|
|
journalctl -f -u aitbc-blockchain-node -u aitbc-blockchain-rpc
|
|
```
|
|
|
|
### 4. Watch Blockchain Sync
|
|
|
|
```bash
|
|
# On aitbc, monitor sync progress
|
|
watch -n 2 'curl -s http://localhost:8006/rpc/head | jq .height'
|
|
|
|
# Compare with aitbc1
|
|
ssh aitbc1 'curl -s http://localhost:8006/rpc/head | jq .height'
|
|
```
|
|
|
|
### 5. Create Wallet on aitbc
|
|
|
|
```bash
|
|
# On aitbc, create a new wallet
|
|
cd /opt/aitbc/apps/blockchain-node
|
|
/opt/aitbc/venv/bin/python scripts/keystore.py \
|
|
--name aitbc-user \
|
|
--create \
|
|
--password $(cat /var/lib/aitbc/keystore/.password)
|
|
|
|
# Note the new wallet address
|
|
WALLET_ADDR=$(cat /var/lib/aitbc/keystore/aitbc-user.json | jq -r '.address')
|
|
echo "New wallet: $WALLET_ADDR"
|
|
```
|
|
|
|
### 6. Send 1000 AIT from Genesis to aitbc Wallet
|
|
|
|
```bash
|
|
# On aitbc1, create and sign transaction
|
|
cd /opt/aitbc/apps/blockchain-node
|
|
|
|
# Get genesis wallet private key
|
|
PASSWORD=$(cat /var/lib/aitbc/keystore/.password)
|
|
GENESIS_KEY=$(/opt/aitbc/venv/bin/python -c "
|
|
import json, sys
|
|
from cryptography.hazmat.primitives.asymmetric import ed25519
|
|
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
|
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|
from cryptography.hazmat.primitives import hashes
|
|
import base64
|
|
|
|
with open('/var/lib/aitbc/keystore/aitbc1genesis.json') as f:
|
|
ks = json.load(f)
|
|
|
|
# Decrypt private key
|
|
crypto = ks['crypto']
|
|
salt = bytes.fromhex(crypto['kdfparams']['salt'])
|
|
kdf = PBKDF2HMAC(hashes.SHA256(), 32, salt, crypto['kdfparams']['c'])
|
|
key = kdf.derive('$PASSWORD'.encode())
|
|
aesgcm = AESGCM(key)
|
|
nonce = bytes.fromhex(crypto['cipherparams']['nonce'])
|
|
priv = aesgcm.decrypt(nonce, bytes.fromhex(crypto['ciphertext']), None)
|
|
print(priv.hex())
|
|
")
|
|
|
|
# Create transaction to send 1000 AIT
|
|
TX_JSON=$(cat << EOF
|
|
{
|
|
"sender": "$(cat /var/lib/aitbc/keystore/aitbc1genesis.json | jq -r '.address')",
|
|
"recipient": "$WALLET_ADDR",
|
|
"value": 1000,
|
|
"fee": 10,
|
|
"nonce": 0,
|
|
"type": "transfer",
|
|
"payload": {}
|
|
}
|
|
EOF
|
|
)
|
|
|
|
# Submit transaction via RPC
|
|
curl -X POST http://localhost:8006/sendTx \
|
|
-H "Content-Type: application/json" \
|
|
-d "$TX_JSON"
|
|
|
|
# Wait for transaction to be mined
|
|
sleep 15
|
|
|
|
# Verify balance on aitbc
|
|
curl -s "http://localhost:8006/rpc/getBalance/$WALLET_ADDR" | jq .
|
|
```
|
|
|
|
### 7. Final Verification
|
|
|
|
```bash
|
|
# Check both nodes are in sync
|
|
echo "=== aitbc1 height ==="
|
|
ssh aitbc1 'curl -s http://localhost:8006/rpc/head | jq .height'
|
|
|
|
echo "=== aitbc height ==="
|
|
curl -s http://localhost:8006/rpc/head | jq .height
|
|
|
|
echo "=== aitbc wallet balance ==="
|
|
curl -s "http://localhost:8006/rpc/getBalance/$WALLET_ADDR" | jq .
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
- **Services won't start**: Check `/var/log/aitbc/` for service logs
|
|
- **Sync issues**: Verify Redis connectivity between nodes
|
|
- **Transaction failures**: Check wallet nonce and balance
|
|
- **Permission errors**: Ensure `/var/lib/aitbc/` is owned by root with proper permissions
|
|
|
|
## Notes
|
|
|
|
- Only one `.env` file is used at `/etc/aitbc/blockchain.env`
|
|
- All services use the central venv at `/opt/aitbc/venv`
|
|
- Database files are stored in `/var/lib/aitbc/data`
|
|
- Wallet credentials are in `/var/lib/aitbc/keystore`
|
|
- Service logs go to `/var/log/aitbc/` via journald
|