mirror of
https://github.com/DeBrosOfficial/network.git
synced 2025-10-06 12:09:07 +00:00
refactor: standardize ports (LibP2P 4001, RQLite 5001/7001) and remove .env configuration
This commit is contained in:
parent
8d57fc8f98
commit
b744f7f513
14
.env.example
14
.env.example
@ -1,14 +0,0 @@
|
|||||||
# Example Environment Configuration for Development
|
|
||||||
# Copy this to .env and modify as needed
|
|
||||||
|
|
||||||
# Bootstrap peers for development (localhost)
|
|
||||||
BOOTSTRAP_PEERS=/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWN3AQHuxAzXfu98tiFYw7W3N2SyDwdxDRANXJp3ktVf8j
|
|
||||||
|
|
||||||
# Environment setting (development or production)
|
|
||||||
ENVIRONMENT=development
|
|
||||||
|
|
||||||
# Note: In production, set ENVIRONMENT=production and the bootstrap.go will automatically
|
|
||||||
# use the production bootstrap peers defined in constants/bootstrap.go
|
|
||||||
|
|
||||||
# For multiple bootstrap peers, separate with commas:
|
|
||||||
# BOOTSTRAP_PEERS=/ip4/127.0.0.1/tcp/4001/p2p/peer1,/ip4/127.0.0.1/tcp/4005/p2p/peer2
|
|
@ -350,14 +350,14 @@ database:
|
|||||||
node:
|
node:
|
||||||
data_dir: "./data/node"
|
data_dir: "./data/node"
|
||||||
listen_addresses:
|
listen_addresses:
|
||||||
- "/ip4/0.0.0.0/tcp/4002"
|
- "/ip4/0.0.0.0/tcp/4001"
|
||||||
discovery:
|
discovery:
|
||||||
bootstrap_peers:
|
bootstrap_peers:
|
||||||
- "/ip4/127.0.0.1/tcp/4001/p2p/{BOOTSTRAP_PEER_ID}"
|
- "/ip4/127.0.0.1/tcp/4001/p2p/{BOOTSTRAP_PEER_ID}"
|
||||||
discovery_interval: "10s"
|
discovery_interval: "10s"
|
||||||
database:
|
database:
|
||||||
rqlite_port: 5002
|
rqlite_port: 5001
|
||||||
rqlite_raft_port: 7002
|
rqlite_raft_port: 7001
|
||||||
rqlite_join_address: "http://localhost:5001"
|
rqlite_join_address: "http://localhost:5001"
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -452,7 +452,7 @@ for _, peer := range peers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect to specific peer
|
// Connect to specific peer
|
||||||
err := client.Network().ConnectToPeer(ctx, "/ip4/192.168.1.100/tcp/4002/p2p/{PEER_ID}")
|
err := client.Network().ConnectToPeer(ctx, "/ip4/192.168.1.100/tcp/4001/p2p/{PEER_ID}")
|
||||||
```
|
```
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
72
Makefile
72
Makefile
@ -23,40 +23,29 @@ test:
|
|||||||
@echo "Running tests..."
|
@echo "Running tests..."
|
||||||
go test -v ./...
|
go test -v ./...
|
||||||
|
|
||||||
# Run node (auto-detects if bootstrap or regular based on configuration)
|
# Run bootstrap node explicitly
|
||||||
run-node:
|
run-node:
|
||||||
@echo "Starting network node..."
|
@echo "Starting BOOTSTRAP node (role=bootstrap)..."
|
||||||
go run cmd/node/main.go -data ./data/node
|
go run cmd/node/main.go -role bootstrap -data ./data/bootstrap
|
||||||
|
|
||||||
# Run second node with different identity
|
# Run second node (regular) - requires BOOTSTRAP multiaddr
|
||||||
|
# Usage: make run-node2 BOOTSTRAP=/ip4/127.0.0.1/tcp/4001/p2p/<ID> HTTP=5002 RAFT=7002
|
||||||
run-node2:
|
run-node2:
|
||||||
@echo "Starting second network node..."
|
@echo "Starting REGULAR node2 (role=node)..."
|
||||||
go run cmd/node/main.go -id node2
|
@if [ -z "$(BOOTSTRAP)" ]; then echo "ERROR: Provide BOOTSTRAP multiaddr: make run-node2 BOOTSTRAP=/ip4/127.0.0.1/tcp/4001/p2p/<ID> [HTTP=5002 RAFT=7002]"; exit 1; fi
|
||||||
|
go run cmd/node/main.go -role node -id node2 -data ./data/node2 -bootstrap $(BOOTSTRAP) -rqlite-http-port ${HTTP-5002} -rqlite-raft-port ${RAFT-7002}
|
||||||
|
|
||||||
# Run third node with different identity
|
# Run third node (regular) - requires BOOTSTRAP multiaddr
|
||||||
|
# Usage: make run-node3 BOOTSTRAP=/ip4/127.0.0.1/tcp/4001/p2p/<ID> HTTP=5003 RAFT=7003
|
||||||
run-node3:
|
run-node3:
|
||||||
@echo "Starting third network node..."
|
@echo "Starting REGULAR node3 (role=node)..."
|
||||||
go run cmd/node/main.go -id node3
|
@if [ -z "$(BOOTSTRAP)" ]; then echo "ERROR: Provide BOOTSTRAP multiaddr: make run-node3 BOOTSTRAP=/ip4/127.0.0.1/tcp/4001/p2p/<ID> [HTTP=5003 RAFT=7003]"; exit 1; fi
|
||||||
|
go run cmd/node/main.go -role node -id node3 -data ./data/node3 -bootstrap $(BOOTSTRAP) -rqlite-http-port ${HTTP-5003} -rqlite-raft-port ${RAFT-7003}
|
||||||
|
|
||||||
# Show current bootstrap configuration
|
# Show how to run with flags
|
||||||
show-bootstrap:
|
show-bootstrap:
|
||||||
@echo "Current bootstrap configuration from .env:"
|
@echo "Provide bootstrap via flags, e.g.:"
|
||||||
@cat .env 2>/dev/null || echo "No .env file found - using defaults"
|
@echo " make run-node2 BOOTSTRAP=/ip4/127.0.0.1/tcp/4001/p2p/<PEER_ID> HTTP=5002 RAFT=7002"
|
||||||
|
|
||||||
# Run example
|
|
||||||
run-example:
|
|
||||||
@echo "Running basic usage example..."
|
|
||||||
go run examples/basic_usage.go
|
|
||||||
|
|
||||||
# Build Anchat
|
|
||||||
build-anchat:
|
|
||||||
@echo "Building Anchat..."
|
|
||||||
cd anchat && go build -o bin/anchat cmd/cli/main.go
|
|
||||||
|
|
||||||
# Run Anchat demo
|
|
||||||
run-anchat:
|
|
||||||
@echo "Starting Anchat demo..."
|
|
||||||
cd anchat && go run cmd/cli/main.go demo_user
|
|
||||||
|
|
||||||
# Run network CLI
|
# Run network CLI
|
||||||
run-cli:
|
run-cli:
|
||||||
@ -112,7 +101,6 @@ dev-setup: deps
|
|||||||
@echo "Setting up development environment..."
|
@echo "Setting up development environment..."
|
||||||
@mkdir -p data/bootstrap data/node data/node-node2 data/node-node3
|
@mkdir -p data/bootstrap data/node data/node-node2 data/node-node3
|
||||||
@mkdir -p data/test-bootstrap data/test-node1 data/test-node2
|
@mkdir -p data/test-bootstrap data/test-node1 data/test-node2
|
||||||
@mkdir -p anchat/bin
|
|
||||||
@echo "Development setup complete!"
|
@echo "Development setup complete!"
|
||||||
|
|
||||||
# Multi-node testing
|
# Multi-node testing
|
||||||
@ -142,35 +130,31 @@ test-consensus: build
|
|||||||
# Start development cluster (requires multiple terminals)
|
# Start development cluster (requires multiple terminals)
|
||||||
dev-cluster:
|
dev-cluster:
|
||||||
@echo "To start a development cluster, run these commands in separate terminals:"
|
@echo "To start a development cluster, run these commands in separate terminals:"
|
||||||
@echo "1. make run-node # Start first node (auto-detects as bootstrap in dev)"
|
@echo "1. make run-node # Start bootstrap node"
|
||||||
@echo "2. make run-node2 # Start second node with different identity"
|
@echo "2. make run-node2 BOOTSTRAP=/ip4/127.0.0.1/tcp/4001/p2p/<ID> HTTP=5002 RAFT=7002"
|
||||||
@echo "3. make run-node3 # Start third node with different identity"
|
@echo "3. make run-node3 BOOTSTRAP=/ip4/127.0.0.1/tcp/4001/p2p/<ID> HTTP=5003 RAFT=7003"
|
||||||
@echo "4. make run-example # Test basic functionality"
|
@echo "4. make run-example # Test basic functionality"
|
||||||
@echo "5. make run-anchat # Start messaging app"
|
@echo "5. make cli-health # Check network health"
|
||||||
@echo "6. make show-bootstrap # Check bootstrap configuration"
|
@echo "6. make cli-peers # List peers"
|
||||||
@echo "7. make cli-health # Check network health"
|
@echo "7. make cli-storage-test # Test storage"
|
||||||
@echo "8. make cli-peers # List peers"
|
@echo "8. make cli-pubsub-test # Test messaging"
|
||||||
@echo "9. make cli-storage-test # Test storage"
|
|
||||||
@echo "10. make cli-pubsub-test # Test messaging"
|
|
||||||
|
|
||||||
# Full development workflow
|
# Full development workflow
|
||||||
dev: clean build build-anchat test
|
dev: clean build test
|
||||||
@echo "Development workflow complete!"
|
@echo "Development workflow complete!"
|
||||||
|
|
||||||
# Help
|
# Help
|
||||||
help:
|
help:
|
||||||
@echo "Available targets:"
|
@echo "Available targets:"
|
||||||
@echo " build - Build all executables"
|
@echo " build - Build all executables"
|
||||||
@echo " build-anchat - Build Anchat application"
|
|
||||||
@echo " clean - Clean build artifacts"
|
@echo " clean - Clean build artifacts"
|
||||||
@echo " test - Run tests"
|
@echo " test - Run tests"
|
||||||
@echo " run-node - Start network node (auto-detects bootstrap vs regular)"
|
@echo " run-node - Start bootstrap node (role=bootstrap)"
|
||||||
@echo " run-node2 - Start second node with different identity"
|
@echo " run-node2 - Start second node (role=node). Provide BOOTSTRAP, optional HTTP/RAFT"
|
||||||
@echo " run-node3 - Start third node with different identity"
|
@echo " run-node3 - Start third node (role=node). Provide BOOTSTRAP, optional HTTP/RAFT"
|
||||||
@echo " run-example - Run usage example"
|
@echo " run-example - Run usage example"
|
||||||
@echo " run-anchat - Run Anchat demo"
|
|
||||||
@echo " run-cli - Run network CLI help"
|
@echo " run-cli - Run network CLI help"
|
||||||
@echo " show-bootstrap - Show current bootstrap configuration"
|
@echo " show-bootstrap - Show example bootstrap usage with flags"
|
||||||
@echo " cli-health - Check network health"
|
@echo " cli-health - Check network health"
|
||||||
@echo " cli-peers - List network peers"
|
@echo " cli-peers - List network peers"
|
||||||
@echo " cli-status - Get network status"
|
@echo " cli-status - Get network status"
|
||||||
|
293
README.md
293
README.md
@ -19,7 +19,6 @@ A distributed peer-to-peer network built with Go and LibP2P, providing decentral
|
|||||||
- [3. Build the Project](#3-build-the-project)
|
- [3. Build the Project](#3-build-the-project)
|
||||||
- [4. Start the Network](#4-start-the-network)
|
- [4. Start the Network](#4-start-the-network)
|
||||||
- [5. Test with CLI](#5-test-with-cli)
|
- [5. Test with CLI](#5-test-with-cli)
|
||||||
- [6. Test Anchat Messaging](#6-test-anchat-messaging)
|
|
||||||
- [Deployment](#deployment)
|
- [Deployment](#deployment)
|
||||||
- [Production Installation Script](#production-installation-script)
|
- [Production Installation Script](#production-installation-script)
|
||||||
- [One-Command Installation](#one-command-installation)
|
- [One-Command Installation](#one-command-installation)
|
||||||
@ -51,11 +50,6 @@ A distributed peer-to-peer network built with Go and LibP2P, providing decentral
|
|||||||
- [Environment Setup](#environment-setup)
|
- [Environment Setup](#environment-setup)
|
||||||
- [Configuration System](#configuration-system)
|
- [Configuration System](#configuration-system)
|
||||||
- [Client Library Usage](#client-library-usage)
|
- [Client Library Usage](#client-library-usage)
|
||||||
- [Anchat - Decentralized Messaging Application](#anchat---decentralized-messaging-application)
|
|
||||||
- [Features](#features-1)
|
|
||||||
- [Quick Start with Anchat](#quick-start-with-anchat)
|
|
||||||
- [Anchat Commands](#anchat-commands)
|
|
||||||
- [Anchat Configuration](#anchat-configuration)
|
|
||||||
- [Troubleshooting](#troubleshooting)
|
- [Troubleshooting](#troubleshooting)
|
||||||
- [Common Issues](#common-issues)
|
- [Common Issues](#common-issues)
|
||||||
- [Debug Commands](#debug-commands)
|
- [Debug Commands](#debug-commands)
|
||||||
@ -165,11 +159,8 @@ Ensure these ports are available or configure firewall rules accordingly.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repository
|
# Clone the repository
|
||||||
git clone https://git.debros.io/DeBros/network-cluster.git
|
git clone https://git.debros.io/DeBros/network.git
|
||||||
cd network-cluster
|
cd network
|
||||||
|
|
||||||
# Copy environment configuration
|
|
||||||
cp .env.example .env
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Generate Bootstrap Identity (Development Only)
|
### 2. Generate Bootstrap Identity (Development Only)
|
||||||
@ -180,35 +171,18 @@ For development, you need to generate a consistent bootstrap peer identity:
|
|||||||
# Generate bootstrap peer identity
|
# Generate bootstrap peer identity
|
||||||
go run scripts/generate-bootstrap-identity.go
|
go run scripts/generate-bootstrap-identity.go
|
||||||
|
|
||||||
# This will create data/bootstrap/identity.key and show the peer ID
|
# This will create data/bootstrap/identity.key and show the peer ID (and multiaddr)
|
||||||
# Copy the peer ID and update your .env files
|
# Save the printed peer ID to use with the -bootstrap flag
|
||||||
```
|
```
|
||||||
|
|
||||||
**Important:** After generating the bootstrap identity, update both `.env` files:
|
**Important:** After generating the bootstrap identity, copy the printed multiaddr
|
||||||
|
or peer ID for use with the `-bootstrap` flag when starting regular nodes.
|
||||||
```bash
|
|
||||||
# Update main .env file
|
|
||||||
nano .env
|
|
||||||
# Update BOOTSTRAP_PEERS with the generated peer ID
|
|
||||||
|
|
||||||
# Update Anchat .env file
|
|
||||||
nano anchat/.env
|
|
||||||
# Update BOOTSTRAP_PEERS with the same peer ID
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Build the Project
|
### 3. Build the Project
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build all network executables
|
# Build all network executables
|
||||||
make build
|
make build
|
||||||
|
|
||||||
# Build Anchat application
|
|
||||||
cd anchat
|
|
||||||
make build
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
# Or build everything at once
|
|
||||||
make build && make build-anchat
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Start the Network
|
### 4. Start the Network
|
||||||
@ -216,24 +190,33 @@ make build && make build-anchat
|
|||||||
**Terminal 1 - Bootstrap Node:**
|
**Terminal 1 - Bootstrap Node:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make run-node
|
# Start an explicit bootstrap node (LibP2P 4001, RQLite 5001/7001)
|
||||||
# This automatically detects and starts as bootstrap node on port 4001
|
go run cmd/node/main.go -role bootstrap -data ./data/bootstrap
|
||||||
# if the local machine matches bootstrap peer configuration
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Terminal 2 - Regular Node:**
|
**Terminal 2 - Regular Node:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make run-node
|
# Replace <BOOTSTRAP_PEER_ID> with the ID printed by the identity generator
|
||||||
# This automatically connects to bootstrap peers from .env
|
go run cmd/node/main.go \
|
||||||
# No need to specify bootstrap manually anymore!
|
-role node \
|
||||||
|
-id node2 \
|
||||||
|
-data ./data/node2 \
|
||||||
|
-bootstrap /ip4/127.0.0.1/tcp/4001/p2p/<BOOTSTRAP_PEER_ID> \
|
||||||
|
-rqlite-http-port 5002 \
|
||||||
|
-rqlite-raft-port 7002
|
||||||
```
|
```
|
||||||
|
|
||||||
**Terminal 3 - Another Node (optional):**
|
**Terminal 3 - Another Node (optional):**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# For additional nodes, use different data directory
|
go run cmd/node/main.go \
|
||||||
go run cmd/node/main.go -data ./data/node2
|
-role node \
|
||||||
|
-id node3 \
|
||||||
|
-data ./data/node3 \
|
||||||
|
-bootstrap /ip4/127.0.0.1/tcp/4001/p2p/<BOOTSTRAP_PEER_ID> \
|
||||||
|
-rqlite-http-port 5003 \
|
||||||
|
-rqlite-raft-port 7003
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. Test with CLI
|
### 5. Test with CLI
|
||||||
@ -253,18 +236,6 @@ make show-bootstrap
|
|||||||
./bin/cli peers
|
./bin/cli peers
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6. Test Anchat Messaging
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Terminal 1 - First user
|
|
||||||
cd anchat
|
|
||||||
./bin/anchat
|
|
||||||
|
|
||||||
# Terminal 2 - Second user
|
|
||||||
cd anchat
|
|
||||||
./bin/anchat
|
|
||||||
```
|
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
### Production Installation Script
|
### Production Installation Script
|
||||||
@ -430,7 +401,7 @@ sudo cp -r /opt/debros/keys /backup/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Check if ports are open
|
# Check if ports are open
|
||||||
sudo netstat -tuln | grep -E "(4001|4002|5001|5002|7001|7002)"
|
sudo netstat -tuln | grep -E "(4001|5001|7001)"
|
||||||
|
|
||||||
# Check service logs
|
# Check service logs
|
||||||
sudo journalctl -u debros-node.service --since "1 hour ago"
|
sudo journalctl -u debros-node.service --since "1 hour ago"
|
||||||
@ -448,81 +419,19 @@ ps aux | grep debros
|
|||||||
|
|
||||||
For more advanced configuration options and development setup, see the sections below.
|
For more advanced configuration options and development setup, see the sections below.
|
||||||
|
|
||||||
## Environment Configuration
|
## Configuration
|
||||||
|
|
||||||
### Bootstrap Peers Configuration
|
### Bootstrap and Ports (via flags)
|
||||||
|
|
||||||
The network uses `.env` files to configure bootstrap peers automatically. This eliminates the need to manually specify bootstrap peer addresses when starting nodes.
|
- **Bootstrap node**: `-role bootstrap`
|
||||||
|
- **Regular node**: `-role node -bootstrap <multiaddr>`
|
||||||
|
- **RQLite ports**: `-rqlite-http-port` (default 5001), `-rqlite-raft-port` (default 7001)
|
||||||
|
|
||||||
#### Setup for Development
|
Examples are shown in Quick Start above for local multi-node on a single machine.
|
||||||
|
|
||||||
1. **Copy example configuration:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cp .env.example .env
|
|
||||||
cp anchat/.env.example anchat/.env
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Generate bootstrap identity:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go run scripts/generate-bootstrap-identity.go
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Update .env files with the generated peer ID:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Main network .env
|
|
||||||
BOOTSTRAP_PEERS=/ip4/127.0.0.1/tcp/4001/p2p/YOUR_GENERATED_PEER_ID
|
|
||||||
|
|
||||||
# Anchat .env
|
|
||||||
BOOTSTRAP_PEERS=/ip4/127.0.0.1/tcp/4001/p2p/YOUR_GENERATED_PEER_ID
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Configuration Files
|
|
||||||
|
|
||||||
**Main Network (.env):**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Bootstrap Node Configuration for Development
|
|
||||||
BOOTSTRAP_PEERS=/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWN3AQHuxAzXfu98tiFYw7W3N2SyDwdxDRANXJp3ktVf8j
|
|
||||||
BOOTSTRAP_PORT=4001
|
|
||||||
ENVIRONMENT=development
|
|
||||||
```
|
|
||||||
|
|
||||||
**Anchat Application (anchat/.env):**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Anchat Bootstrap Configuration
|
|
||||||
BOOTSTRAP_PEERS=/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWN3AQHuxAzXfu98tiFYw7W3N2SyDwdxDRANXJp3ktVf8j
|
|
||||||
BOOTSTRAP_PORT=4001
|
|
||||||
ENVIRONMENT=development
|
|
||||||
ANCHAT_LOG_LEVEL=info
|
|
||||||
ANCHAT_DATABASE_NAME=anchattestingdb1
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Multiple Bootstrap Peers
|
|
||||||
|
|
||||||
For production or redundancy, you can specify multiple bootstrap peers:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
BOOTSTRAP_PEERS=/ip4/bootstrap1.example.com/tcp/4001/p2p/12D3KooWPeer1,/ip4/bootstrap2.example.com/tcp/4001/p2p/12D3KooWPeer2,/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWLocalPeer
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Checking Configuration
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# View current bootstrap configuration
|
|
||||||
make show-bootstrap
|
|
||||||
|
|
||||||
# Check which .env file is being used
|
|
||||||
cat .env
|
|
||||||
cat anchat/.env
|
|
||||||
```
|
|
||||||
|
|
||||||
## CLI Commands
|
## CLI Commands
|
||||||
|
|
||||||
The CLI and nodes now automatically load bootstrap peers from `.env` files - no manual configuration needed!
|
The CLI can still accept `--bootstrap <multiaddr>` to override discovery when needed.
|
||||||
|
|
||||||
### Network Operations
|
### Network Operations
|
||||||
|
|
||||||
@ -568,7 +477,7 @@ The CLI and nodes now automatically load bootstrap peers from `.env` files - no
|
|||||||
### Project Structure
|
### Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
network-cluster/
|
network/
|
||||||
├── cmd/
|
├── cmd/
|
||||||
│ ├── bootstrap/ # Bootstrap node
|
│ ├── bootstrap/ # Bootstrap node
|
||||||
│ ├── node/ # Regular network node
|
│ ├── node/ # Regular network node
|
||||||
@ -580,21 +489,9 @@ network-cluster/
|
|||||||
│ ├── storage/ # Storage service
|
│ ├── storage/ # Storage service
|
||||||
│ ├── constants/ # Bootstrap configuration
|
│ ├── constants/ # Bootstrap configuration
|
||||||
│ └── config/ # System configuration
|
│ └── config/ # System configuration
|
||||||
├── anchat/ # Anchat messaging application
|
├── scripts/ # Helper scripts (install, security, tests)
|
||||||
│ ├── cmd/cli/ # Anchat CLI
|
├── scripts/ # Helper scripts (install, security, tests)
|
||||||
│ ├── pkg/
|
|
||||||
│ │ ├── chat/ # Chat functionality
|
|
||||||
│ │ ├── crypto/ # Encryption
|
|
||||||
│ │ └── constants/ # Anchat bootstrap config
|
|
||||||
│ ├── .env # Anchat environment config
|
|
||||||
│ └── .env.example # Anchat config template
|
|
||||||
├── scripts/
|
|
||||||
│ └── generate-bootstrap-identity.go # Bootstrap ID generator
|
|
||||||
├── .env # Main environment config
|
|
||||||
├── .env.example # Main config template
|
|
||||||
├── bin/ # Built executables
|
├── bin/ # Built executables
|
||||||
├── data/ # Runtime data directories
|
|
||||||
└── Makefile # Build and run commands
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building and Testing
|
### Building and Testing
|
||||||
@ -603,11 +500,6 @@ network-cluster/
|
|||||||
# Build all network executables
|
# Build all network executables
|
||||||
make build
|
make build
|
||||||
|
|
||||||
# Build Anchat application
|
|
||||||
cd anchat && make build && cd ..
|
|
||||||
# or
|
|
||||||
make build-anchat
|
|
||||||
|
|
||||||
# Show current bootstrap configuration
|
# Show current bootstrap configuration
|
||||||
make show-bootstrap
|
make show-bootstrap
|
||||||
|
|
||||||
@ -631,19 +523,17 @@ make dev
|
|||||||
```bash
|
```bash
|
||||||
# Copy environment templates
|
# Copy environment templates
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
cp anchat/.env.example anchat/.env
|
|
||||||
|
|
||||||
# Generate consistent bootstrap identity
|
# Generate consistent bootstrap identity
|
||||||
go run scripts/generate-bootstrap-identity.go
|
go run scripts/generate-bootstrap-identity.go
|
||||||
|
|
||||||
# Update both .env files with the generated peer ID
|
# Update .env files with the generated peer ID
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Build Everything:**
|
2. **Build Everything:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make build # Build network components
|
make build # Build network components
|
||||||
make build-anchat # Build Anchat application
|
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Start Development Cluster:**
|
3. **Start Development Cluster:**
|
||||||
@ -658,9 +548,6 @@ make dev
|
|||||||
# Terminal 3: Test with CLI
|
# Terminal 3: Test with CLI
|
||||||
./bin/cli health
|
./bin/cli health
|
||||||
./bin/cli peers
|
./bin/cli peers
|
||||||
|
|
||||||
# Terminal 4 & 5: Test Anchat
|
|
||||||
cd anchat && ./bin/anchat
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Environment Setup
|
### Environment Setup
|
||||||
@ -689,7 +576,6 @@ make dev
|
|||||||
```bash
|
```bash
|
||||||
# Setup .env files
|
# Setup .env files
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
cp anchat/.env.example anchat/.env
|
|
||||||
|
|
||||||
# Generate bootstrap identity
|
# Generate bootstrap identity
|
||||||
go run scripts/generate-bootstrap-identity.go
|
go run scripts/generate-bootstrap-identity.go
|
||||||
@ -756,100 +642,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Anchat - Decentralized Messaging Application
|
|
||||||
|
|
||||||
Anchat is a demonstration application built on the network that provides decentralized, encrypted messaging capabilities.
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
- **Decentralized Messaging**: No central servers, messages flow through the P2P network
|
|
||||||
- **Wallet-based Authentication**: Connect using Solana wallet addresses
|
|
||||||
- **Encrypted Communications**: End-to-end encryption for private messages
|
|
||||||
- **Room-based Chat**: Create and join chat rooms
|
|
||||||
- **Network Auto-discovery**: Automatically finds and connects to other Anchat users
|
|
||||||
|
|
||||||
### Quick Start with Anchat
|
|
||||||
|
|
||||||
1. **Setup Environment:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ensure main network is configured
|
|
||||||
cp .env.example .env
|
|
||||||
cp anchat/.env.example anchat/.env
|
|
||||||
|
|
||||||
# Generate bootstrap identity and update .env files
|
|
||||||
go run scripts/generate-bootstrap-identity.go
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Build Anchat:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd anchat
|
|
||||||
make build
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Start Network Infrastructure:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Terminal 1: Bootstrap node (auto-detected)
|
|
||||||
make run-node
|
|
||||||
|
|
||||||
# Terminal 2: Regular node (optional but recommended)
|
|
||||||
make run-node
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Start Anchat Clients:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Terminal 3: First user
|
|
||||||
cd anchat
|
|
||||||
./bin/anchat
|
|
||||||
|
|
||||||
# Terminal 4: Second user
|
|
||||||
cd anchat
|
|
||||||
./bin/anchat
|
|
||||||
```
|
|
||||||
|
|
||||||
### Anchat Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Room management
|
|
||||||
/list # List available rooms
|
|
||||||
/join <room> # Join a room
|
|
||||||
/leave # Leave current room
|
|
||||||
/create <room> [desc] # Create a new room
|
|
||||||
|
|
||||||
# Messaging
|
|
||||||
<message> # Send message to current room
|
|
||||||
/msg <user> <message> # Send private message
|
|
||||||
/me <action> # Send action message
|
|
||||||
|
|
||||||
# User management
|
|
||||||
/users # List users in current room
|
|
||||||
/nick <username> # Change username
|
|
||||||
/who # Show your user info
|
|
||||||
|
|
||||||
# System
|
|
||||||
/help # Show all commands
|
|
||||||
/debug # Show debug information
|
|
||||||
/quit # Exit Anchat
|
|
||||||
```
|
|
||||||
|
|
||||||
### Anchat Configuration
|
|
||||||
|
|
||||||
Anchat uses its own bootstrap configuration in `anchat/.env`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Anchat-specific environment variables
|
|
||||||
BOOTSTRAP_PEERS=/ip4/127.0.0.1/tcp/4001/p2p/YOUR_BOOTSTRAP_PEER_ID
|
|
||||||
BOOTSTRAP_PORT=4001
|
|
||||||
ENVIRONMENT=development
|
|
||||||
ANCHAT_LOG_LEVEL=info
|
|
||||||
ANCHAT_DATABASE_NAME=anchattestingdb1
|
|
||||||
```
|
|
||||||
|
|
||||||
The Anchat application also includes hardcoded fallback bootstrap peers in `anchat/pkg/constants/bootstrap.go` for reliability.
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Common Issues
|
### Common Issues
|
||||||
@ -857,7 +649,7 @@ The Anchat application also includes hardcoded fallback bootstrap peers in `anch
|
|||||||
**Bootstrap peer not found / Peer ID mismatch:**
|
**Bootstrap peer not found / Peer ID mismatch:**
|
||||||
|
|
||||||
- Generate a new bootstrap identity: `go run scripts/generate-bootstrap-identity.go`
|
- Generate a new bootstrap identity: `go run scripts/generate-bootstrap-identity.go`
|
||||||
- Update both `.env` and `anchat/.env` with the new peer ID
|
- Update `.env` with the new peer ID
|
||||||
- Restart the bootstrap node: `make run-node`
|
- Restart the bootstrap node: `make run-node`
|
||||||
- Check configuration: `make show-bootstrap`
|
- Check configuration: `make show-bootstrap`
|
||||||
|
|
||||||
@ -875,26 +667,18 @@ The Anchat application also includes hardcoded fallback bootstrap peers in `anch
|
|||||||
- Verify RQLite is properly installed: `rqlited --version`
|
- Verify RQLite is properly installed: `rqlited --version`
|
||||||
- Check for port conflicts: `netstat -an | grep -E "(4001|5001|7001)"`
|
- Check for port conflicts: `netstat -an | grep -E "(4001|5001|7001)"`
|
||||||
|
|
||||||
**Anchat clients can't discover each other:**
|
|
||||||
|
|
||||||
- Ensure both clients use the same bootstrap peer ID in `anchat/.env`
|
|
||||||
- Verify the bootstrap node is running
|
|
||||||
- Check that both clients successfully connect to bootstrap
|
|
||||||
- Look for "peer id mismatch" errors in the logs
|
|
||||||
|
|
||||||
### Debug Commands
|
### Debug Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Check current configuration
|
# Check current configuration
|
||||||
make show-bootstrap
|
make show-bootstrap
|
||||||
cat .env
|
cat .env
|
||||||
cat anchat/.env
|
|
||||||
|
|
||||||
# Check running processes
|
# Check running processes
|
||||||
ps aux | grep -E "(bootstrap|node|rqlite)"
|
ps aux | grep -E "(bootstrap|node|rqlite)"
|
||||||
|
|
||||||
# Check port usage
|
# Check port usage
|
||||||
netstat -an | grep -E "(4001|4002|4003|5001|5002|5003|7001|7002|7003)"
|
netstat -an | grep -E "(4001|5001|7001)"
|
||||||
|
|
||||||
# Check bootstrap peer info
|
# Check bootstrap peer info
|
||||||
cat data/bootstrap/peer.info
|
cat data/bootstrap/peer.info
|
||||||
@ -927,7 +711,6 @@ go run -c 'package main; import "fmt"; import "network/pkg/constants"; func main
|
|||||||
|
|
||||||
# Verify .env file syntax
|
# Verify .env file syntax
|
||||||
grep -E "^[A-Z_]+=.*" .env
|
grep -E "^[A-Z_]+=.*" .env
|
||||||
grep -E "^[A-Z_]+=.*" anchat/.env
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Logs and Data
|
### Logs and Data
|
||||||
@ -937,7 +720,7 @@ grep -E "^[A-Z_]+=.*" anchat/.env
|
|||||||
- RQLite data: `./data/<node>/rqlite/`
|
- RQLite data: `./data/<node>/rqlite/`
|
||||||
- Peer info: `./data/<node>/peer.info`
|
- Peer info: `./data/<node>/peer.info`
|
||||||
- Bootstrap identity: `./data/bootstrap/identity.key`
|
- Bootstrap identity: `./data/bootstrap/identity.key`
|
||||||
- Environment config: `./.env`, `./anchat/.env`
|
- Environment config: `./.env`
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
48
clear-ports.sh
Executable file
48
clear-ports.sh
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# clear-ports.sh
|
||||||
|
# Safely terminate any processes listening on specified TCP ports.
|
||||||
|
# Usage:
|
||||||
|
# ./clear-ports.sh # clears 4001, 5001, 7001 by default
|
||||||
|
# ./clear-ports.sh 4001 5001 7001 # clears the specified ports
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Collect ports from args or use defaults
|
||||||
|
PORTS=("$@")
|
||||||
|
if [ ${#PORTS[@]} -eq 0 ]; then
|
||||||
|
PORTS=(4001 5001 7001)
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Gracefully terminating listeners on: ${PORTS[*]}"
|
||||||
|
for p in "${PORTS[@]}"; do
|
||||||
|
PIDS=$(lsof -t -n -P -iTCP:"$p" -sTCP:LISTEN 2>/dev/null || true)
|
||||||
|
if [ -n "$PIDS" ]; then
|
||||||
|
echo "Port $p -> PIDs: $PIDS (SIGTERM)"
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
kill -TERM $PIDS 2>/dev/null || true
|
||||||
|
else
|
||||||
|
echo "Port $p -> no listeners"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
echo "Force killing any remaining listeners..."
|
||||||
|
for p in "${PORTS[@]}"; do
|
||||||
|
PIDS=$(lsof -t -n -P -iTCP:"$p" -sTCP:LISTEN 2>/dev/null || true)
|
||||||
|
if [ -n "$PIDS" ]; then
|
||||||
|
echo "Port $p -> PIDs: $PIDS (SIGKILL)"
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
kill -9 $PIDS 2>/dev/null || true
|
||||||
|
else
|
||||||
|
echo "Port $p -> none remaining"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "\nVerification (should be empty):"
|
||||||
|
for p in "${PORTS[@]}"; do
|
||||||
|
echo "--- Port $p ---"
|
||||||
|
lsof -n -P -iTCP:"$p" -sTCP:LISTEN 2>/dev/null || true
|
||||||
|
echo
|
||||||
|
done
|
||||||
|
|
@ -10,10 +10,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
|
||||||
"git.debros.io/DeBros/network/pkg/client"
|
"git.debros.io/DeBros/network/pkg/client"
|
||||||
"git.debros.io/DeBros/network/pkg/constants"
|
"git.debros.io/DeBros/network/pkg/constants"
|
||||||
|
"github.com/libp2p/go-libp2p/core/crypto"
|
||||||
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -23,6 +23,9 @@ func main() {
|
|||||||
dataDir = flag.String("data", "", "Data directory (auto-detected if not provided)")
|
dataDir = flag.String("data", "", "Data directory (auto-detected if not provided)")
|
||||||
nodeID = flag.String("id", "", "Node identifier (for running multiple local nodes)")
|
nodeID = flag.String("id", "", "Node identifier (for running multiple local nodes)")
|
||||||
bootstrap = flag.String("bootstrap", "", "Bootstrap peer address (for manual override)")
|
bootstrap = flag.String("bootstrap", "", "Bootstrap peer address (for manual override)")
|
||||||
|
role = flag.String("role", "auto", "Node role: auto|bootstrap|node (auto detects based on config)")
|
||||||
|
rqlHTTP = flag.Int("rqlite-http-port", 5001, "RQLite HTTP API port")
|
||||||
|
rqlRaft = flag.Int("rqlite-raft-port", 7001, "RQLite Raft port")
|
||||||
help = flag.Bool("help", false, "Show help")
|
help = flag.Bool("help", false, "Show help")
|
||||||
)
|
)
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
@ -32,8 +35,17 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine node role
|
||||||
|
var isBootstrap bool
|
||||||
|
switch strings.ToLower(*role) {
|
||||||
|
case "bootstrap":
|
||||||
|
isBootstrap = true
|
||||||
|
case "node":
|
||||||
|
isBootstrap = false
|
||||||
|
default:
|
||||||
// Auto-detect if this is a bootstrap node based on configuration
|
// Auto-detect if this is a bootstrap node based on configuration
|
||||||
isBootstrap := isBootstrapNode()
|
isBootstrap = isBootstrapNode()
|
||||||
|
}
|
||||||
|
|
||||||
// Set default data directory if not provided
|
// Set default data directory if not provided
|
||||||
if *dataDir == "" {
|
if *dataDir == "" {
|
||||||
@ -48,8 +60,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LibP2P uses port 4000, RQLite uses 4001
|
// LibP2P uses port 4001, RQLite uses 5001 (HTTP) and 7001 (Raft)
|
||||||
port := 4000
|
port := 4001
|
||||||
|
|
||||||
// Create logger with appropriate component type
|
// Create logger with appropriate component type
|
||||||
var logger *logging.StandardLogger
|
var logger *logging.StandardLogger
|
||||||
@ -80,9 +92,9 @@ func main() {
|
|||||||
fmt.Sprintf("/ip4/0.0.0.0/udp/%d/quic", port),
|
fmt.Sprintf("/ip4/0.0.0.0/udp/%d/quic", port),
|
||||||
}
|
}
|
||||||
|
|
||||||
// All nodes use the same RQLite port (4001) to join the same cluster
|
// RQLite ports (overridable for local multi-node on one host)
|
||||||
cfg.Database.RQLitePort = 4001
|
cfg.Database.RQLitePort = *rqlHTTP
|
||||||
cfg.Database.RQLiteRaftPort = 4002
|
cfg.Database.RQLiteRaftPort = *rqlRaft
|
||||||
|
|
||||||
if isBootstrap {
|
if isBootstrap {
|
||||||
// Check if this is the primary bootstrap node (first in list) or secondary
|
// Check if this is the primary bootstrap node (first in list) or secondary
|
||||||
@ -102,7 +114,7 @@ func main() {
|
|||||||
if isSecondaryBootstrap {
|
if isSecondaryBootstrap {
|
||||||
// Secondary bootstrap nodes join the primary bootstrap
|
// Secondary bootstrap nodes join the primary bootstrap
|
||||||
primaryBootstrapHost := parseHostFromMultiaddr(bootstrapPeers[0])
|
primaryBootstrapHost := parseHostFromMultiaddr(bootstrapPeers[0])
|
||||||
cfg.Database.RQLiteJoinAddress = fmt.Sprintf("http://%s:4001", primaryBootstrapHost)
|
cfg.Database.RQLiteJoinAddress = fmt.Sprintf("http://%s:%d", primaryBootstrapHost, *rqlHTTP)
|
||||||
logger.Printf("Secondary bootstrap node - joining primary bootstrap at: %s", cfg.Database.RQLiteJoinAddress)
|
logger.Printf("Secondary bootstrap node - joining primary bootstrap at: %s", cfg.Database.RQLiteJoinAddress)
|
||||||
} else {
|
} else {
|
||||||
// Primary bootstrap node doesn't join anyone - it starts the cluster
|
// Primary bootstrap node doesn't join anyone - it starts the cluster
|
||||||
@ -118,11 +130,11 @@ func main() {
|
|||||||
// Extract IP from bootstrap peer for RQLite join
|
// Extract IP from bootstrap peer for RQLite join
|
||||||
bootstrapHost := parseHostFromMultiaddr(*bootstrap)
|
bootstrapHost := parseHostFromMultiaddr(*bootstrap)
|
||||||
if bootstrapHost != "" {
|
if bootstrapHost != "" {
|
||||||
rqliteJoinAddr = fmt.Sprintf("http://%s:4001", bootstrapHost)
|
rqliteJoinAddr = fmt.Sprintf("http://%s:%d", bootstrapHost, *rqlHTTP)
|
||||||
logger.Printf("Using extracted bootstrap host %s for RQLite join", bootstrapHost)
|
logger.Printf("Using extracted bootstrap host %s for RQLite join", bootstrapHost)
|
||||||
} else {
|
} else {
|
||||||
logger.Printf("Warning: Could not extract host from bootstrap peer %s, using localhost fallback", *bootstrap)
|
logger.Printf("Warning: Could not extract host from bootstrap peer %s, using localhost fallback", *bootstrap)
|
||||||
rqliteJoinAddr = "http://localhost:4001" // Use localhost fallback instead
|
rqliteJoinAddr = fmt.Sprintf("http://localhost:%d", *rqlHTTP) // Use localhost fallback instead
|
||||||
}
|
}
|
||||||
logger.Printf("Using command line bootstrap peer: %s", *bootstrap)
|
logger.Printf("Using command line bootstrap peer: %s", *bootstrap)
|
||||||
} else {
|
} else {
|
||||||
@ -133,18 +145,18 @@ func main() {
|
|||||||
// Use the first bootstrap peer for RQLite join
|
// Use the first bootstrap peer for RQLite join
|
||||||
bootstrapHost := parseHostFromMultiaddr(bootstrapPeers[0])
|
bootstrapHost := parseHostFromMultiaddr(bootstrapPeers[0])
|
||||||
if bootstrapHost != "" {
|
if bootstrapHost != "" {
|
||||||
rqliteJoinAddr = fmt.Sprintf("http://%s:4001", bootstrapHost)
|
rqliteJoinAddr = fmt.Sprintf("http://%s:5001", bootstrapHost)
|
||||||
logger.Printf("Using extracted bootstrap host %s for RQLite join", bootstrapHost)
|
logger.Printf("Using extracted bootstrap host %s for RQLite join", bootstrapHost)
|
||||||
} else {
|
} else {
|
||||||
logger.Printf("Warning: Could not extract host from bootstrap peer %s", bootstrapPeers[0])
|
logger.Printf("Warning: Could not extract host from bootstrap peer %s", bootstrapPeers[0])
|
||||||
// Try primary production server as fallback
|
// Try primary production server as fallback
|
||||||
rqliteJoinAddr = "http://localhost:4001"
|
rqliteJoinAddr = "http://localhost:5001"
|
||||||
}
|
}
|
||||||
logger.Printf("Using environment bootstrap peers: %v", bootstrapPeers)
|
logger.Printf("Using environment bootstrap peers: %v", bootstrapPeers)
|
||||||
} else {
|
} else {
|
||||||
logger.Printf("Warning: No bootstrap peers configured")
|
logger.Printf("Warning: No bootstrap peers configured")
|
||||||
// Default to localhost when no peers configured
|
// Default to localhost when no peers configured
|
||||||
rqliteJoinAddr = "http://localhost:4001"
|
rqliteJoinAddr = "http://localhost:5001"
|
||||||
logger.Printf("Using localhost fallback for RQLite join")
|
logger.Printf("Using localhost fallback for RQLite join")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ func (d *DatabaseClientImpl) connectToAvailableNode() (*gorqlite.Connection, err
|
|||||||
return nil, fmt.Errorf("failed to connect to any RQLite instance. Last error: %w", lastErr)
|
return nil, fmt.Errorf("failed to connect to any RQLite instance. Last error: %w", lastErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getRQLiteNodes returns a list of RQLite node URLs using the peer IPs/hostnames from bootstrap.go, always on port 4001
|
// getRQLiteNodes returns a list of RQLite node URLs using the peer IPs/hostnames from bootstrap.go, always on port 5001
|
||||||
func (d *DatabaseClientImpl) getRQLiteNodes() []string {
|
func (d *DatabaseClientImpl) getRQLiteNodes() []string {
|
||||||
// Use bootstrap peer addresses from constants
|
// Use bootstrap peer addresses from constants
|
||||||
// Import the constants package
|
// Import the constants package
|
||||||
@ -207,7 +207,7 @@ func (d *DatabaseClientImpl) getRQLiteNodes() []string {
|
|||||||
// Example multiaddr: /ip4/57.129.81.31/tcp/4001/p2p/12D3KooWQRK2duw5B5LXi8gA7HBBFiCsLvwyph2ZU9VBmvbE1Nei
|
// Example multiaddr: /ip4/57.129.81.31/tcp/4001/p2p/12D3KooWQRK2duw5B5LXi8gA7HBBFiCsLvwyph2ZU9VBmvbE1Nei
|
||||||
parts := strings.Split(addr, "/")
|
parts := strings.Split(addr, "/")
|
||||||
var host string
|
var host string
|
||||||
var port string = "4001" // always use 4001
|
var port string = "5001" // always use RQLite HTTP 5001
|
||||||
for i := 0; i < len(parts); i++ {
|
for i := 0; i < len(parts); i++ {
|
||||||
if parts[i] == "ip4" || parts[i] == "ip6" {
|
if parts[i] == "ip4" || parts[i] == "ip6" {
|
||||||
host = parts[i+1]
|
host = parts[i+1]
|
||||||
@ -215,15 +215,15 @@ func (d *DatabaseClientImpl) getRQLiteNodes() []string {
|
|||||||
if parts[i] == "dns" || parts[i] == "dns4" || parts[i] == "dns6" {
|
if parts[i] == "dns" || parts[i] == "dns4" || parts[i] == "dns6" {
|
||||||
host = parts[i+1]
|
host = parts[i+1]
|
||||||
}
|
}
|
||||||
// ignore tcp port in multiaddr, always use 4001
|
// ignore tcp port in multiaddr, always use 5001 for RQLite HTTP
|
||||||
}
|
}
|
||||||
if host != "" {
|
if host != "" {
|
||||||
nodes = append(nodes, "http://"+host+":"+port)
|
nodes = append(nodes, "http://"+host+":"+port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If no peers found, fallback to localhost:4001
|
// If no peers found, fallback to localhost:5001
|
||||||
if len(nodes) == 0 {
|
if len(nodes) == 0 {
|
||||||
nodes = append(nodes, "http://localhost:4001")
|
nodes = append(nodes, "http://localhost:5001")
|
||||||
}
|
}
|
||||||
return nodes
|
return nodes
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,6 @@ package constants
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/joho/godotenv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Bootstrap node configuration
|
// Bootstrap node configuration
|
||||||
@ -19,109 +14,8 @@ var (
|
|||||||
BootstrapAddresses []string
|
BootstrapAddresses []string
|
||||||
|
|
||||||
// BootstrapPort is the default port for bootstrap nodes (LibP2P)
|
// BootstrapPort is the default port for bootstrap nodes (LibP2P)
|
||||||
BootstrapPort int = 4000
|
BootstrapPort int = 4001
|
||||||
)
|
|
||||||
|
|
||||||
// Load environment variables and initialize bootstrap configuration
|
|
||||||
func init() {
|
|
||||||
loadEnvironmentConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadEnvironmentConfig loads bootstrap configuration from .env file
|
|
||||||
func loadEnvironmentConfig() {
|
|
||||||
// Try to load .env file from current directory and parent directories
|
|
||||||
envPaths := []string{
|
|
||||||
".env",
|
|
||||||
"../.env",
|
|
||||||
"../../.env", // For when running from anchat subdirectory
|
|
||||||
}
|
|
||||||
|
|
||||||
var envLoaded bool
|
|
||||||
for _, path := range envPaths {
|
|
||||||
if _, err := os.Stat(path); err == nil {
|
|
||||||
if err := godotenv.Load(path); err == nil {
|
|
||||||
envLoaded = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !envLoaded {
|
|
||||||
// Fallback to default values if no .env file found
|
|
||||||
setDefaultBootstrapConfig()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load bootstrap peers from environment
|
|
||||||
if peersEnv := os.Getenv("BOOTSTRAP_PEERS"); peersEnv != "" {
|
|
||||||
// Split by comma and trim whitespace
|
|
||||||
peerAddrs := strings.Split(peersEnv, ",")
|
|
||||||
BootstrapAddresses = make([]string, 0, len(peerAddrs))
|
|
||||||
BootstrapPeerIDs = make([]string, 0, len(peerAddrs))
|
|
||||||
|
|
||||||
for _, addr := range peerAddrs {
|
|
||||||
addr = strings.TrimSpace(addr)
|
|
||||||
if addr != "" {
|
|
||||||
BootstrapAddresses = append(BootstrapAddresses, addr)
|
|
||||||
|
|
||||||
// Extract peer ID from multiaddr
|
|
||||||
if peerID := extractPeerIDFromMultiaddr(addr); peerID != "" {
|
|
||||||
BootstrapPeerIDs = append(BootstrapPeerIDs, peerID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load bootstrap port from environment
|
|
||||||
if portEnv := os.Getenv("BOOTSTRAP_PORT"); portEnv != "" {
|
|
||||||
if port, err := strconv.Atoi(portEnv); err == nil && port > 0 {
|
|
||||||
BootstrapPort = port
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no environment config found, use defaults
|
|
||||||
if len(BootstrapAddresses) == 0 {
|
|
||||||
setDefaultBootstrapConfig()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// setDefaultBootstrapConfig sets default bootstrap configuration
|
|
||||||
func setDefaultBootstrapConfig() {
|
|
||||||
// Check if we're in production environment
|
|
||||||
if env := os.Getenv("ENVIRONMENT"); env == "production" {
|
|
||||||
// Production: only use live production peers
|
|
||||||
BootstrapPeerIDs = []string{
|
|
||||||
"12D3KooWNxt9bNvqftdqXg98JcUHreGxedWSZRUbyqXJ6CW7GaD4",
|
|
||||||
"12D3KooWGbdnA22bN24X2gyY1o9jozwTBq9wbfvwtJ7G4XQ9JgFm",
|
|
||||||
}
|
|
||||||
BootstrapAddresses = []string{
|
|
||||||
"/ip4/57.129.81.31/tcp/4000/p2p/12D3KooWNxt9bNvqftdqXg98JcUHreGxedWSZRUbyqXJ6CW7GaD4",
|
|
||||||
"/ip4/38.242.250.186/tcp/4000/p2p/12D3KooWGbdnA22bN24X2gyY1o9jozwTBq9wbfvwtJ7G4XQ9JgFm",
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Development: only use localhost bootstrap
|
|
||||||
BootstrapPeerIDs = []string{
|
|
||||||
"12D3KooWBQAr9Lj9Z3918wBT523tJaRiPN6zRywAtttvPrwcZfJb",
|
|
||||||
}
|
|
||||||
BootstrapAddresses = []string{
|
|
||||||
"/ip4/127.0.0.1/tcp/4000/p2p/12D3KooWBQAr9Lj9Z3918wBT523tJaRiPN6zRywAtttvPrwcZfJb",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BootstrapPort = 4000
|
|
||||||
}
|
|
||||||
|
|
||||||
// extractPeerIDFromMultiaddr extracts the peer ID from a multiaddr string
|
|
||||||
func extractPeerIDFromMultiaddr(multiaddr string) string {
|
|
||||||
// Look for /p2p/ followed by the peer ID
|
|
||||||
parts := strings.Split(multiaddr, "/p2p/")
|
|
||||||
if len(parts) >= 2 {
|
|
||||||
return parts[1]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constants for backward compatibility
|
|
||||||
var (
|
|
||||||
// Primary bootstrap peer ID (first in the list)
|
// Primary bootstrap peer ID (first in the list)
|
||||||
BootstrapPeerID string
|
BootstrapPeerID string
|
||||||
|
|
||||||
@ -129,6 +23,27 @@ var (
|
|||||||
BootstrapAddress string
|
BootstrapAddress string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Initialize bootstrap configuration (no .env loading; defaults only)
|
||||||
|
func init() {
|
||||||
|
setDefaultBootstrapConfig()
|
||||||
|
updateBackwardCompatibilityConstants()
|
||||||
|
}
|
||||||
|
|
||||||
|
// setDefaultBootstrapConfig sets default bootstrap configuration
|
||||||
|
func setDefaultBootstrapConfig() {
|
||||||
|
// Check if we're in production environment
|
||||||
|
BootstrapPeerIDs = []string{
|
||||||
|
"12D3KooWNxt9bNvqftdqXg98JcUHreGxedWSZRUbyqXJ6CW7GaD4",
|
||||||
|
"12D3KooWGbdnA22bN24X2gyY1o9jozwTBq9wbfvwtJ7G4XQ9JgFm",
|
||||||
|
}
|
||||||
|
BootstrapAddresses = []string{
|
||||||
|
"/ip4/57.129.81.31/tcp/4001/p2p/12D3KooWNxt9bNvqftdqXg98JcUHreGxedWSZRUbyqXJ6CW7GaD4",
|
||||||
|
"/ip4/38.242.250.186/tcp/4001/p2p/12D3KooWGbdnA22bN24X2gyY1o9jozwTBq9wbfvwtJ7G4XQ9JgFm",
|
||||||
|
}
|
||||||
|
|
||||||
|
BootstrapPort = 4001
|
||||||
|
}
|
||||||
|
|
||||||
// updateBackwardCompatibilityConstants updates the single constants for backward compatibility
|
// updateBackwardCompatibilityConstants updates the single constants for backward compatibility
|
||||||
func updateBackwardCompatibilityConstants() {
|
func updateBackwardCompatibilityConstants() {
|
||||||
if len(BootstrapPeerIDs) > 0 {
|
if len(BootstrapPeerIDs) > 0 {
|
||||||
@ -139,14 +54,6 @@ func updateBackwardCompatibilityConstants() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this after loading environment config
|
|
||||||
func init() {
|
|
||||||
// This runs after the first init() that calls loadEnvironmentConfig()
|
|
||||||
updateBackwardCompatibilityConstants()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions for working with bootstrap peers
|
|
||||||
|
|
||||||
// GetBootstrapPeers returns a copy of all bootstrap peer addresses
|
// GetBootstrapPeers returns a copy of all bootstrap peer addresses
|
||||||
func GetBootstrapPeers() []string {
|
func GetBootstrapPeers() []string {
|
||||||
if len(BootstrapAddresses) == 0 {
|
if len(BootstrapAddresses) == 0 {
|
||||||
@ -176,12 +83,6 @@ func AddBootstrapPeer(peerID, address string) {
|
|||||||
updateBackwardCompatibilityConstants()
|
updateBackwardCompatibilityConstants()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReloadEnvironmentConfig reloads the configuration from environment
|
|
||||||
func ReloadEnvironmentConfig() {
|
|
||||||
loadEnvironmentConfig()
|
|
||||||
updateBackwardCompatibilityConstants()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEnvironmentInfo returns information about the current configuration
|
// GetEnvironmentInfo returns information about the current configuration
|
||||||
func GetEnvironmentInfo() map[string]interface{} {
|
func GetEnvironmentInfo() map[string]interface{} {
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
@ -189,18 +90,5 @@ func GetEnvironmentInfo() map[string]interface{} {
|
|||||||
"bootstrap_peer_ids": GetBootstrapPeerIDs(),
|
"bootstrap_peer_ids": GetBootstrapPeerIDs(),
|
||||||
"bootstrap_port": BootstrapPort,
|
"bootstrap_port": BootstrapPort,
|
||||||
"environment": os.Getenv("ENVIRONMENT"),
|
"environment": os.Getenv("ENVIRONMENT"),
|
||||||
"config_loaded_from": getConfigSource(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getConfigSource returns where the configuration was loaded from
|
|
||||||
func getConfigSource() string {
|
|
||||||
envPaths := []string{".env", "../.env", "../../.env"}
|
|
||||||
for _, path := range envPaths {
|
|
||||||
if _, err := os.Stat(path); err == nil {
|
|
||||||
abs, _ := filepath.Abs(path)
|
|
||||||
return abs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "default values (no .env file found)"
|
|
||||||
}
|
|
||||||
|
@ -15,9 +15,9 @@ NOCOLOR='\033[0m'
|
|||||||
INSTALL_DIR="/opt/debros"
|
INSTALL_DIR="/opt/debros"
|
||||||
REPO_URL="https://git.debros.io/DeBros/network.git"
|
REPO_URL="https://git.debros.io/DeBros/network.git"
|
||||||
MIN_GO_VERSION="1.19"
|
MIN_GO_VERSION="1.19"
|
||||||
NODE_PORT="4000" # LibP2P port for peer-to-peer communication
|
NODE_PORT="4001" # LibP2P port for peer-to-peer communication
|
||||||
RQLITE_PORT="4001" # All nodes use same RQLite port to join same cluster
|
RQLITE_PORT="5001" # All nodes use same RQLite HTTP port to join same cluster
|
||||||
RAFT_PORT="4002" # All nodes use same Raft port
|
RAFT_PORT="7001" # All nodes use same Raft port
|
||||||
UPDATE_MODE=false
|
UPDATE_MODE=false
|
||||||
NON_INTERACTIVE=false
|
NON_INTERACTIVE=false
|
||||||
|
|
||||||
|
@ -69,14 +69,14 @@ sudo ufw default allow outgoing
|
|||||||
sudo ufw allow 22/tcp comment "SSH"
|
sudo ufw allow 22/tcp comment "SSH"
|
||||||
|
|
||||||
# LibP2P P2P networking (public, encrypted)
|
# LibP2P P2P networking (public, encrypted)
|
||||||
sudo ufw allow 4000/tcp comment "LibP2P P2P"
|
sudo ufw allow 4001/tcp comment "LibP2P P2P"
|
||||||
sudo ufw allow 4000/udp comment "LibP2P QUIC"
|
sudo ufw allow 4001/udp comment "LibP2P QUIC"
|
||||||
|
|
||||||
# RQLite ports (restrict to cluster IPs only)
|
# RQLite ports (restrict to cluster IPs only)
|
||||||
BOOTSTRAP_IPS=("57.129.81.31" "38.242.250.186")
|
BOOTSTRAP_IPS=("57.129.81.31" "38.242.250.186")
|
||||||
for ip in "${BOOTSTRAP_IPS[@]}"; do
|
for ip in "${BOOTSTRAP_IPS[@]}"; do
|
||||||
sudo ufw allow from "$ip" to any port 4001 comment "RQLite HTTP from $ip"
|
sudo ufw allow from "$ip" to any port 5001 comment "RQLite HTTP from $ip"
|
||||||
sudo ufw allow from "$ip" to any port 4002 comment "RQLite Raft from $ip"
|
sudo ufw allow from "$ip" to any port 7001 comment "RQLite Raft from $ip"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Enable firewall
|
# Enable firewall
|
||||||
@ -85,7 +85,7 @@ sudo ufw --force enable
|
|||||||
echo "🔧 Configuring RQLite cluster authentication..."
|
echo "🔧 Configuring RQLite cluster authentication..."
|
||||||
|
|
||||||
# Update RQLite join addresses with authentication
|
# Update RQLite join addresses with authentication
|
||||||
AUTHENTICATED_JOIN_ADDRESS="http://$CLUSTER_USER:$CLUSTER_PASS@57.129.81.31:4001"
|
AUTHENTICATED_JOIN_ADDRESS="http://$CLUSTER_USER:$CLUSTER_PASS@57.129.81.31:5001"
|
||||||
|
|
||||||
# Create environment file for authenticated connections
|
# Create environment file for authenticated connections
|
||||||
cat > "$CONFIG_DIR/rqlite-env" << EOF
|
cat > "$CONFIG_DIR/rqlite-env" << EOF
|
||||||
@ -106,9 +106,9 @@ cat > "$DEBROS_DIR/bin/rqlite-connect" << 'EOF'
|
|||||||
source /opt/debros/keys/rqlite-cluster-auth
|
source /opt/debros/keys/rqlite-cluster-auth
|
||||||
|
|
||||||
if [ "$1" = "cluster" ]; then
|
if [ "$1" = "cluster" ]; then
|
||||||
rqlite -H localhost -p 4001 -u "$RQLITE_CLUSTER_USER" -p "$RQLITE_CLUSTER_PASS"
|
rqlite -H localhost -p 5001 -u "$RQLITE_CLUSTER_USER" -p "$RQLITE_CLUSTER_PASS"
|
||||||
elif [ "$1" = "api" ]; then
|
elif [ "$1" = "api" ]; then
|
||||||
rqlite -H localhost -p 4001 -u "$RQLITE_API_USER" -p "$RQLITE_API_PASS"
|
rqlite -H localhost -p 5001 -u "$RQLITE_API_USER" -p "$RQLITE_API_PASS"
|
||||||
else
|
else
|
||||||
echo "Usage: $0 {cluster|api}"
|
echo "Usage: $0 {cluster|api}"
|
||||||
exit 1
|
exit 1
|
||||||
@ -124,8 +124,8 @@ echo "📋 Security Summary:"
|
|||||||
echo " - RQLite authentication enabled"
|
echo " - RQLite authentication enabled"
|
||||||
echo " - Firewall configured with IP restrictions"
|
echo " - Firewall configured with IP restrictions"
|
||||||
echo " - Cluster credentials generated and stored"
|
echo " - Cluster credentials generated and stored"
|
||||||
echo " - Port 4000: Public LibP2P (encrypted P2P)"
|
echo " - Port 4001: Public LibP2P (encrypted P2P)"
|
||||||
echo " - Port 4001/4002: RQLite cluster (IP-restricted)"
|
echo " - Port 5001/7001: RQLite cluster (IP-restricted)"
|
||||||
echo ""
|
echo ""
|
||||||
echo "🔐 Credentials stored in:"
|
echo "🔐 Credentials stored in:"
|
||||||
echo " - Users: $CONFIG_DIR/rqlite-users.json"
|
echo " - Users: $CONFIG_DIR/rqlite-users.json"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user