Compare commits

..

5 Commits

Author SHA1 Message Date
anonpenguin
889735f8d0
Merge pull request #42 from DeBrosOfficial/nightly
Peer ID Fixes and Identity v0.51.0
2025-09-26 09:38:59 +03:00
anonpenguin23
2eb4db3ddb
Update CHANGELOG.md 2025-09-26 07:56:05 +03:00
anonpenguin
587cb3dc11
Merge pull request #41 from DeBrosOfficial/peer-id-identity
Peer id identity fixes
2025-09-26 07:55:16 +03:00
anonpenguin23
b6db781ce2
- Added identity/main.go to generate identity and peer id
- Added encryption module identity.go for reusable identity create, save etc funtions
- Updated make file to support identity/main.go
- Updated node/node.go on loadOrCreateIdentity to use encryption.identity
- Updated cli/main.go to remove fallbacks for identity
- Updated install-debros-network.sh script to use new ./cmd/identity and fixed port order on print
- Updated makefile and changelog
2025-09-26 07:53:20 +03:00
anonpenguin23
5d951daaf8
Updated changelog 2025-09-23 07:50:09 +03:00
7 changed files with 173 additions and 138 deletions

View File

@ -16,6 +16,39 @@ The format is based on [Keep a Changelog][keepachangelog] and adheres to [Semant
### Fixed
## [0.51.0] - 2025-09-26
### Added
- Added identity/main.go to generate identity and peer id
- Added encryption module identity.go for reusable identity create, save etc funtions
### Changed
- Updated make file to support identity/main.go
- Updated node/node.go on loadOrCreateIdentity to use encryption.identity
- Updated cli/main.go to remove fallbacks for identity
- Updated install-debros-network.sh script to use new ./cmd/identity and fixed port order on print
### Deprecated
### Removed
### Fixed
## [0.50.1] - 2025-09-23
### Added
### Changed
### Deprecated
### Removed
### Fixed
- Fixed wrong URL /v1/db to /v1/rqlite
### Security

View File

@ -21,7 +21,7 @@ test-e2e:
.PHONY: build clean test run-node run-node2 run-node3 run-example deps tidy fmt vet lint clear-ports
VERSION := 0.50.1-beta
VERSION := 0.51.0-beta
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' -X 'main.date=$(DATE)'
@ -30,6 +30,7 @@ LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' -X 'main.date
build: deps
@echo "Building network executables (version=$(VERSION))..."
@mkdir -p bin
go build -ldflags "$(LDFLAGS)" -o bin/identity ./cmd/identity
go build -ldflags "$(LDFLAGS)" -o bin/node ./cmd/node
go build -ldflags "$(LDFLAGS)" -o bin/network-cli cmd/cli/main.go
# Inject gateway build metadata via pkg path variables

View File

@ -2,7 +2,6 @@ package main
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"log"
@ -363,50 +362,6 @@ func handlePeerID() {
}
}
// Fallback: try to extract from local identity files
identityPaths := []string{
"/opt/debros/data/node/identity.key",
"/opt/debros/data/bootstrap/identity.key",
"/opt/debros/keys/node/identity.key",
"./data/node/identity.key",
"./data/bootstrap/identity.key",
}
for _, path := range identityPaths {
if peerID := extractPeerIDFromFile(path); peerID != "" {
if format == "json" {
printJSON(map[string]string{"peer_id": peerID, "source": "local_identity"})
} else {
fmt.Printf("🆔 Peer ID: %s\n", peerID)
fmt.Printf("📂 Source: %s\n", path)
}
return
}
}
// Check peer.info files as last resort
peerInfoPaths := []string{
"/opt/debros/data/node/peer.info",
"/opt/debros/data/bootstrap/peer.info",
"./data/node/peer.info",
"./data/bootstrap/peer.info",
}
for _, path := range peerInfoPaths {
if data, err := os.ReadFile(path); err == nil {
multiaddr := strings.TrimSpace(string(data))
if peerID := extractPeerIDFromMultiaddr(multiaddr); peerID != "" {
if format == "json" {
printJSON(map[string]string{"peer_id": peerID, "source": "peer_info"})
} else {
fmt.Printf("🆔 Peer ID: %s\n", peerID)
fmt.Printf("📂 Source: %s\n", path)
}
return
}
}
}
fmt.Fprintf(os.Stderr, "❌ Could not find peer ID. Make sure the node is running or identity files exist.\n")
os.Exit(1)
}
@ -470,20 +425,6 @@ func discoverBootstrapPeer() string {
return "" // Return empty string if no peer info found
}
func tryDecodeBase64(s string) string {
// Only try to decode if it looks like base64 (no spaces, reasonable length)
if len(s) > 0 && len(s)%4 == 0 && !strings.ContainsAny(s, " \n\r\t") {
if decoded, err := base64.StdEncoding.DecodeString(s); err == nil {
// Check if decoded result looks like readable text
decodedStr := string(decoded)
if isPrintableText(decodedStr) {
return decodedStr
}
}
}
return s
}
func isPrintableText(s string) bool {
printableCount := 0
for _, r := range s {

45
cmd/identity/main.go Normal file
View File

@ -0,0 +1,45 @@
package main
import (
"flag"
"fmt"
"os"
"github.com/DeBrosOfficial/network/pkg/encryption"
)
func main() {
var outputPath string
var displayOnly bool
flag.StringVar(&outputPath, "output", "", "Output path for identity key")
flag.BoolVar(&displayOnly, "display-only", false, "Only display identity info, don't save")
flag.Parse()
// Generate identity using shared package
info, err := encryption.GenerateIdentity()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to generate identity: %v\n", err)
os.Exit(1)
}
// If display only, just show the info
if displayOnly {
fmt.Printf("Node Identity: %s\n", info.PeerID.String())
return
}
// Save to file using shared package
if outputPath == "" {
fmt.Fprintln(os.Stderr, "Output path is required")
os.Exit(1)
}
if err := encryption.SaveIdentity(info, outputPath); err != nil {
fmt.Fprintf(os.Stderr, "Failed to save identity: %v\n", err)
os.Exit(1)
}
fmt.Printf("Generated Node Identity: %s\n", info.PeerID.String())
fmt.Printf("Identity saved to: %s\n", outputPath)
}

View File

@ -0,0 +1,71 @@
package encryption
import (
"crypto/rand"
"os"
"path/filepath"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
)
type IdentityInfo struct {
PrivateKey crypto.PrivKey
PublicKey crypto.PubKey
PeerID peer.ID
}
func GenerateIdentity() (*IdentityInfo, error) {
priv, pub, err := crypto.GenerateKeyPairWithReader(crypto.Ed25519, 2048, rand.Reader)
if err != nil {
return nil, err
}
peerID, err := peer.IDFromPublicKey(pub)
if err != nil {
return nil, err
}
return &IdentityInfo{
PrivateKey: priv,
PublicKey: pub,
PeerID: peerID,
}, nil
}
func SaveIdentity(identity *IdentityInfo, path string) error {
data, err := crypto.MarshalPrivateKey(identity.PrivateKey)
if err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
return err
}
return os.WriteFile(path, data, 0600)
}
func LoadIdentity(path string) (*IdentityInfo, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
priv, err := crypto.UnmarshalPrivateKey(data)
if err != nil {
return nil, err
}
pub := priv.GetPublic()
peerID, err := peer.IDFromPublicKey(pub)
if err != nil {
return nil, err
}
return &IdentityInfo{
PrivateKey: priv,
PublicKey: pub,
PeerID: peerID,
}, nil
}

View File

@ -2,7 +2,6 @@ package node
import (
"context"
"crypto/rand"
"fmt"
mathrand "math/rand"
"os"
@ -23,6 +22,7 @@ import (
"go.uber.org/zap"
"github.com/DeBrosOfficial/network/pkg/config"
"github.com/DeBrosOfficial/network/pkg/encryption"
"github.com/DeBrosOfficial/network/pkg/logging"
"github.com/DeBrosOfficial/network/pkg/pubsub"
database "github.com/DeBrosOfficial/network/pkg/rqlite"
@ -374,65 +374,41 @@ func (n *Node) startLibP2P() error {
return nil
}
// loadOrCreateIdentity loads an existing identity or creates a new one
// loadOrCreateIdentity loads an existing identity or creates a new one
func (n *Node) loadOrCreateIdentity() (crypto.PrivKey, error) {
identityFile := filepath.Join(n.config.Node.DataDir, "identity.key")
// Try to load existing identity
// Try to load existing identity using the shared package
if _, err := os.Stat(identityFile); err == nil {
data, err := os.ReadFile(identityFile)
info, err := encryption.LoadIdentity(identityFile)
if err != nil {
return nil, fmt.Errorf("failed to read identity file: %w", err)
}
priv, err := crypto.UnmarshalPrivateKey(data)
if err != nil {
n.logger.Warn("Failed to unmarshal existing identity, creating new one", zap.Error(err))
} else {
// Extract peer ID from private key for logging
peerID, err := peer.IDFromPrivateKey(priv)
if err != nil {
n.logger.ComponentInfo(logging.ComponentNode, "Loaded existing identity",
zap.String("file", identityFile),
zap.String("peer_id", "unable_to_extract"))
n.logger.Warn("Failed to load existing identity, creating new one", zap.Error(err))
} else {
n.logger.ComponentInfo(logging.ComponentNode, "Loaded existing identity",
zap.String("file", identityFile),
zap.String("peer_id", peerID.String()))
}
return priv, nil
zap.String("peer_id", info.PeerID.String()))
return info.PrivateKey, nil
}
}
// Create new identity
// Create new identity using shared package
n.logger.Info("Creating new identity", zap.String("file", identityFile))
priv, _, err := crypto.GenerateKeyPairWithReader(crypto.Ed25519, 2048, rand.Reader)
info, err := encryption.GenerateIdentity()
if err != nil {
return nil, fmt.Errorf("failed to generate key pair: %w", err)
return nil, fmt.Errorf("failed to generate identity: %w", err)
}
// Extract peer ID from private key for logging
peerID, err := peer.IDFromPrivateKey(priv)
if err != nil {
n.logger.Info("Identity created",
zap.String("peer_id", "unable_to_extract"))
} else {
n.logger.Info("Identity created",
zap.String("peer_id", peerID.String()))
}
// Save identity
data, err := crypto.MarshalPrivateKey(priv)
if err != nil {
return nil, fmt.Errorf("failed to marshal private key: %w", err)
}
if err := os.WriteFile(identityFile, data, 0600); err != nil {
// Save identity using shared package
if err := encryption.SaveIdentity(info, identityFile); err != nil {
return nil, fmt.Errorf("failed to save identity: %w", err)
}
n.logger.Info("Identity saved", zap.String("file", identityFile))
return priv, nil
n.logger.Info("Identity saved",
zap.String("file", identityFile),
zap.String("peer_id", info.PeerID.String()))
return info.PrivateKey, nil
}
// GetPeerID returns the peer ID of this node

View File

@ -335,40 +335,8 @@ generate_identity() {
fi
log "Generating node identity..."
cd "$INSTALL_DIR/src"
cat > /tmp/generate_identity_custom.go << 'EOF'
package main
import (
"crypto/rand"
"flag"
"fmt"
"os"
"path/filepath"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
)
func main() {
var outputPath string
flag.StringVar(&outputPath, "output", "", "Output path for identity key")
flag.Parse()
if outputPath == "" {
fmt.Println("Usage: go run generate_identity_custom.go -output <path>")
os.Exit(1)
}
priv, pub, err := crypto.GenerateKeyPairWithReader(crypto.Ed25519, 2048, rand.Reader)
if err != nil { panic(err) }
peerID, err := peer.IDFromPublicKey(pub)
if err != nil { panic(err) }
data, err := crypto.MarshalPrivateKey(priv)
if err != nil { panic(err) }
if err := os.MkdirAll(filepath.Dir(outputPath), 0700); err != nil { panic(err) }
if err := os.WriteFile(outputPath, data, 0600); err != nil { panic(err) }
fmt.Printf("Generated Peer ID: %s\n", peerID.String())
fmt.Printf("Identity saved to: %s\n", outputPath)
}
EOF
export PATH=$PATH:/usr/local/go/bin
sudo -u debros env "PATH=$PATH:/usr/local/go/bin" "GOMOD=$(pwd)" go run /tmp/generate_identity_custom.go -output "$identity_file"
rm /tmp/generate_identity_custom.go
sudo -u debros env "PATH=$PATH:/usr/local/go/bin" go run ./cmd/identity -output "$identity_file"
success "Node identity generated"
}
@ -560,10 +528,10 @@ main() {
log "${GREEN}Installation Directory:${NOCOLOR} ${CYAN}$INSTALL_DIR${NOCOLOR}"
log "${GREEN}Configuration:${NOCOLOR} ${CYAN}$INSTALL_DIR/configs/node.yaml${NOCOLOR}"
log "${GREEN}Logs:${NOCOLOR} ${CYAN}$INSTALL_DIR/logs/node.log${NOCOLOR}"
log "${GREEN}Node Port:${NOCOLOR} ${CYAN}$NODE_PORT${NOCOLOR}"
log "${GREEN}LibP2P Port:${NOCOLOR} ${CYAN}$NODE_PORT${NOCOLOR}"
log "${GREEN}RQLite Port:${NOCOLOR} ${CYAN}$RQLITE_PORT${NOCOLOR}"
log "${GREEN}Raft Port:${NOCOLOR} ${CYAN}$RAFT_PORT${NOCOLOR}"
log "${GREEN}Gateway Port:${NOCOLOR} ${CYAN}$GATEWAY_PORT${NOCOLOR}"
log "${GREEN}Raft Port:${NOCOLOR} ${CYAN}$RAFT_PORT${NOCOLOR}"
log "${BLUE}==================================================${NOCOLOR}"
log "${GREEN}Management Commands:${NOCOLOR}"
log "${CYAN} - sudo systemctl status debros-node${NOCOLOR} (Check status)"