Switch node startup to YAML config files

Update Makefile, README, and .gitignore to use configs/ Add YAML config
loading to node main.go Add gopkg.in/yaml.v3 dependency Remove unused
IsBootstrap field from NodeConfig
This commit is contained in:
anonpenguin 2025-08-14 15:49:07 +03:00
parent a6129d3fc2
commit 271d7bbafb
7 changed files with 153 additions and 38 deletions

2
.gitignore vendored
View File

@ -71,3 +71,5 @@ data/*
data/bootstrap/rqlite/
.env.*
configs/

View File

@ -30,22 +30,20 @@ test:
# Run bootstrap node (auto-selects identity and data dir)
run-node:
@echo "Starting bootstrap node..."
go run ./cmd/node --data ./data/bootstrap --p2p-port $${P2P:-4001} --rqlite-http-port $${HTTP:-5001} --rqlite-raft-port $${RAFT:-7001} --adv-addr $${ADV_ADDR:-127.0.0.1} --disable-anonrc
@echo "Starting bootstrap node with config..."
go run ./cmd/node --config configs/bootstrap.yaml
# Run second node (regular) - requires join address of bootstrap node
# Usage: make run-node2 JOINADDR=/ip4/127.0.0.1/tcp/5001 HTTP=5002 RAFT=7002 P2P=4002
run-node2:
@echo "Starting regular node2..."
@if [ -z "$(JOINADDR)" ]; then echo "ERROR: Provide join address: make run-node2 JOINADDR=/ip4/127.0.0.1/tcp/5001 [HTTP=5002 RAFT=7002 P2P=4002]"; exit 1; fi
go run ./cmd/node --id node2 --data ./data/node2 --p2p-port $${P2P:-4002} --rqlite-http-port $${HTTP:-5002} --rqlite-raft-port $${RAFT:-7002} --rqlite-join-address $(JOINADDR)
@echo "Starting regular node2 with config..."
go run ./cmd/node --config configs/node.yaml
# Run third node (regular) - requires join address of bootstrap node
# Usage: make run-node3 JOINADDR=/ip4/127.0.0.1/tcp/5001 HTTP=5003 RAFT=7003 P2P=4003
run-node3:
@echo "Starting regular node3..."
@if [ -z "$(JOINADDR)" ]; then echo "ERROR: Provide join address: make run-node3 JOINADDR=/ip4/127.0.0.1/tcp/5001 [HTTP=5003 RAFT=7003 P2P=4003]"; exit 1; fi
go run ./cmd/node --id node3 --data ./data/node3 --p2p-port $${P2P:-4003} --rqlite-http-port $${HTTP:-5003} --rqlite-raft-port $${RAFT:-7003} --rqlite-join-address $(JOINADDR)
@echo "Starting regular node3 with config..."
go run ./cmd/node --config configs/node.yaml
# Run basic usage example
run-example:
@ -150,9 +148,9 @@ test-consensus: build
# Start development cluster (requires multiple terminals)
dev-cluster:
@echo "To start a development cluster, run these commands in separate terminals:"
@echo "1. make run-node # Start bootstrap node"
@echo "2. make run-node2 JOINADDR=/ip4/127.0.0.1/tcp/5001 HTTP=5002 RAFT=7002 P2P=4002"
@echo "3. make run-node3 JOINADDR=/ip4/127.0.0.1/tcp/5001 HTTP=5003 RAFT=7003 P2P=4003"
@echo "1. make run-node # Start bootstrap node (uses configs/bootstrap.yaml)"
@echo "2. make run-node2 # Start second node (uses configs/node.yaml)"
@echo "3. make run-node3 # Start third node (uses configs/node.yaml)"
@echo "4. make run-example # Test basic functionality"
@echo "5. make cli-health # Check network health"
@echo "6. make cli-peers # List peers"

View File

@ -109,13 +109,15 @@ make build
```bash
make run-node
# Or manually:
go run ./cmd/node -data ./data/bootstrap -p2p-port 4001 -rqlite-http-port 5001 -rqlite-raft-port 7001
go run ./cmd/node --config configs/bootstrap.yaml
```
### 4. Start Additional Nodes
```bash
go run ./cmd/node -id node2 -data ./data/node2 -rqlite-http-port 5002 -rqlite-raft-port 7002 -p2p-port 4002 --disable-anonrc
make run-node2
# Or manually:
go run ./cmd/node --config configs/node.yaml
```
### 5. Test with CLI
@ -174,23 +176,87 @@ sudo journalctl -u debros-node.service -f
## Configuration
### YAML Config Example (`/opt/debros/configs/node.yaml`)
### Example Configuration Files
#### `configs/bootstrap.yaml`
```yaml
node:
data_dir: "/opt/debros/data/node"
key_file: "/opt/debros/keys/node/identity.key"
id: ""
listen_addresses:
- "/ip4/0.0.0.0/tcp/4001"
solana_wallet: "YOUR_WALLET_ADDRESS"
data_dir: "./data/bootstrap"
max_connections: 100
disable_anonrc: true
database:
data_dir: "./data/db"
replication_factor: 3
shard_count: 16
max_database_size: 1073741824
backup_interval: 24h
rqlite_port: 5001
rqlite_raft_port: 7001
rqlite_join_address: "" # Bootstrap node does not join
discovery:
bootstrap_peers: []
discovery_interval: 15s
bootstrap_port: 4001
http_adv_address: "127.0.0.1"
raft_adv_address: ""
security:
enable_tls: false
private_key_file: ""
certificate_file: ""
auth_enabled: false
logging:
level: "info"
file: "/opt/debros/logs/node.log"
format: "console"
output_file: ""
```
#### `configs/node.yaml`
```yaml
node:
id: "node2"
listen_addresses:
- "/ip4/0.0.0.0/tcp/4002"
data_dir: "./data/node2"
max_connections: 50
disable_anonrc: true
database:
data_dir: "./data/db"
replication_factor: 3
shard_count: 16
max_database_size: 1073741824
backup_interval: 24h
rqlite_port: 5002
rqlite_raft_port: 7002
rqlite_join_address: "http://127.0.0.1:5001"
discovery:
bootstrap_peers:
- "/ip4/127.0.0.1/tcp/4001/p2p/<YOUR_BOOTSTRAP_PEER_ID>"
discovery_interval: 15s
bootstrap_port: 4002
http_adv_address: "127.0.0.1"
raft_adv_address: ""
security:
enable_tls: false
private_key_file: ""
certificate_file: ""
auth_enabled: false
logging:
level: "info"
format: "console"
output_file: ""
```
### Flags & Environment Variables

View File

@ -1,19 +1,19 @@
# DeBros Network: A Peer-to-Peer Decentralized Database Ecosystem
# DeBros Network: A Peer-to-Peer Decentralized Development Ecosystem
**DeBros**
info@debros.io
https://debros.io
August 2, 2025
August 14, 2025
## Abstract
We propose a decentralized ecosystem, the DeBros Network, enabling peer-to-peer application deployment and operation across a global network of nodes, free from centralized control. Built with Go and LibP2P for robust networking, RQLite for distributed consensus, and integrated with the Solana blockchain for identity and governance, the network provides a resilient, privacy-first platform for decentralized applications. Participation is governed by NFT ownership and token staking, with demonstrated applications like Anchat showcasing real-world messaging capabilities. The architecture eliminates single points of failure while maintaining developer simplicity and end-user accessibility.
We propose a decentralized development ecosystem, the DeBros Network, enabling peer-to-peer application deployment and operation across a global network of nodes, free from centralized control. Built LibP2P for robust networking, RQLite for distributed consensus, and integrated with the blochains like Etherium or Solana for identity and governance, the network provides a resilient, privacy-first platform for decentralized development. Participation is governed by NFT ownership and token staking, with demonstrated applications like Anchat showcasing real-world messaging capabilities. The architecture eliminates single points of failure while maintaining developer simplicity and end-user accessibility.
## 1. Introduction
Centralized systems dominate modern technology, imposing control over data, access, and development through single points of failure and intermediaries. These structures compromise privacy, resilience, innovation, and freedom, while existing decentralized solutions often lack the simplicity or scalability needed for widespread adoption.
The DeBros Network resolves these issues by establishing a peer-to-peer platform where nodes form a decentralized backbone for applications. Built on Go's performance and LibP2P's proven networking stack, it empowers a global community of developers and users to collaborate as equals, delivering scalable, privacy-first solutions without centralized oversight.
The DeBros Network resolves these issues by establishing a peer-to-peer platform where nodes form a decentralized backbone for applications. Built on LibP2P's proven networking stack and Rqlite as a database, it empowers a global community of developers and users to collaborate as equals, delivering scalable, privacy-first solutions without centralized oversight.
## 2. Problem Statement

View File

@ -4,6 +4,7 @@ import (
"context"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"os/signal"
@ -15,6 +16,7 @@ import (
"git.debros.io/DeBros/network/pkg/logging"
"git.debros.io/DeBros/network/pkg/node"
"go.uber.org/zap"
"gopkg.in/yaml.v3"
)
func setup_logger(component logging.Component) (logger *logging.ColoredLogger) {
@ -28,9 +30,10 @@ func setup_logger(component logging.Component) (logger *logging.ColoredLogger) {
return logger
}
func parse_and_return_network_flags() (dataDir, nodeID *string, p2pPort, rqlHTTP, rqlRaft *int, disableAnon *bool, rqlJoinAddr *string, advAddr *string, help *bool) {
func parse_and_return_network_flags() (configPath *string, dataDir, nodeID *string, p2pPort, rqlHTTP, rqlRaft *int, disableAnon *bool, rqlJoinAddr *string, advAddr *string, help *bool) {
logger := setup_logger(logging.ComponentNode)
configPath = flag.String("config", "", "Path to config YAML file (overrides defaults)")
dataDir = flag.String("data", "", "Data directory (auto-detected if not provided)")
nodeID = flag.String("id", "", "Node identifier (for running multiple local nodes)")
p2pPort = flag.Int("p2p-port", 4001, "LibP2P listen port")
@ -38,15 +41,63 @@ func parse_and_return_network_flags() (dataDir, nodeID *string, p2pPort, rqlHTTP
rqlRaft = flag.Int("rqlite-raft-port", 7001, "RQLite Raft port")
disableAnon = flag.Bool("disable-anonrc", false, "Disable Anyone proxy routing (defaults to enabled on 127.0.0.1:9050)")
rqlJoinAddr = flag.String("rqlite-join-address", "", "RQLite address to join (e.g., /ip4/)")
advAddr = flag.String("adv-addr", "127.0.0.1", "Default Addvertise address for rqlite and rafts")
advAddr = flag.String("adv-addr", "127.0.0.1", "Default Advertise address for rqlite and rafts")
help = flag.Bool("help", false, "Show help")
flag.Parse()
logger.Info("Successfully parsed all flags and arguments.")
if *configPath != "" {
cfg, err := LoadConfigFromYAML(*configPath)
if err != nil {
logger.Error("Failed to load config from YAML", zap.Error(err))
os.Exit(1)
}
logger.ComponentInfo(logging.ComponentNode, "Configuration loaded from YAML file", zap.String("path", *configPath))
// Instead of returning flag values, return config values
// For ListenAddresses, extract port from multiaddr string if possible, else use default
var p2pPortVal int
if len(cfg.Node.ListenAddresses) > 0 {
// Try to parse port from multiaddr string
var port int
_, err := fmt.Sscanf(cfg.Node.ListenAddresses[0], "/ip4/0.0.0.0/tcp/%d", &port)
if err == nil {
p2pPortVal = port
} else {
p2pPortVal = 4001
}
} else {
p2pPortVal = 4001
}
return configPath,
&cfg.Node.DataDir,
&cfg.Node.ID,
&p2pPortVal,
&cfg.Database.RQLitePort,
&cfg.Database.RQLiteRaftPort,
&cfg.Node.DisableAnonRC,
&cfg.Database.RQLiteJoinAddress,
&cfg.Discovery.HttpAdvAddress,
help
}
return
}
// LoadConfigFromYAML loads a config from a YAML file
func LoadConfigFromYAML(path string) (*config.Config, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read config file: %w", err)
}
var cfg config.Config
if err := yaml.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("failed to unmarshal YAML: %w", err)
}
return &cfg, nil
}
func disable_anon_proxy(disableAnon *bool) bool {
anyoneproxy.SetDisabled(*disableAnon)
logger := setup_logger(logging.ComponentAnyone)
@ -152,7 +203,7 @@ func load_args_into_config(cfg *config.Config, p2pPort, rqlHTTP, rqlRaft *int, r
func main() {
logger := setup_logger(logging.ComponentNode)
dataDir, nodeID, p2pPort, rqlHTTP, rqlRaft, disableAnon, rqlJoinAddr, advAddr, help := parse_and_return_network_flags()
_, dataDir, nodeID, p2pPort, rqlHTTP, rqlRaft, disableAnon, rqlJoinAddr, advAddr, help := parse_and_return_network_flags()
disable_anon_proxy(disableAnon)
check_if_should_open_help(help)

1
go.mod
View File

@ -11,6 +11,7 @@ require (
github.com/rqlite/gorqlite v0.0.0-20250609141355-ac86a4a1c9a8
go.uber.org/zap v1.27.0
golang.org/x/net v0.42.0
gopkg.in/yaml.v3 v3.0.1
)
require (

View File

@ -22,9 +22,7 @@ type NodeConfig struct {
ListenAddresses []string `yaml:"listen_addresses"` // LibP2P listen addresses
DataDir string `yaml:"data_dir"` // Data directory
MaxConnections int `yaml:"max_connections"` // Maximum peer connections
// Bootstrap configuration (only for bootstrap nodes)
IsBootstrap bool `yaml:"is_bootstrap"`
DisableAnonRC bool `yaml:"disable_anon_rc"` // Disable Anyone proxy/SOCKS5
}
// DatabaseConfig contains database-related configuration
@ -97,7 +95,6 @@ func DefaultConfig() *Config {
},
DataDir: "./data",
MaxConnections: 50,
IsBootstrap: false,
},
Database: DatabaseConfig{
DataDir: "./data/db",