From 69d7ccf4c7947ea0e3d30b0d5cb8a7f346ebea32 Mon Sep 17 00:00:00 2001 From: anonpenguin23 Date: Wed, 5 Nov 2025 10:52:40 +0200 Subject: [PATCH] feat: enhance IPFS and Cluster integration in setup - Added automatic setup for IPFS and IPFS Cluster during the network setup process. - Implemented initialization of IPFS repositories and Cluster configurations for each node. - Enhanced Makefile to support starting IPFS and Cluster daemons with improved logging. - Introduced a new documentation guide for IPFS Cluster setup, detailing configuration and verification steps. - Updated changelog to reflect the new features and improvements. --- .zed/debug.json | 4 +-- Makefile | 26 ++++++++++---------- README.md | 4 +-- cmd/node/main.go | 4 +-- docs/ipfs-cluster-setup.md | 2 +- e2e/gateway_e2e_test.go | 2 +- pkg/anyoneproxy/socks.go | 6 ++--- pkg/cli/config_commands.go | 10 ++++---- pkg/cli/setup.go | 10 ++++---- pkg/client/defaults_test.go | 6 ++--- pkg/config/validate_test.go | 20 +++++++-------- pkg/gateway/anon_proxy_handler.go | 2 +- pkg/gateway/anon_proxy_handler_test.go | 4 +-- pkg/gateway/gateway.go | 4 +-- pkg/gateway/storage_handlers_test.go | 18 ++++++++++---- pkg/ipfs/client_test.go | 34 +++++++++++++++----------- pkg/node/node.go | 2 +- pkg/node/node_test.go | 10 ++++---- 18 files changed, 91 insertions(+), 77 deletions(-) diff --git a/.zed/debug.json b/.zed/debug.json index 6418b00..4119f7a 100644 --- a/.zed/debug.json +++ b/.zed/debug.json @@ -11,7 +11,7 @@ "program": "./cmd/gateway", "env": { "GATEWAY_ADDR": ":6001", - "GATEWAY_BOOTSTRAP_PEERS": "/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWSHHwEY6cga3ng7tD1rzStAU58ogQXVMX3LZJ6Gqf6dee", + "GATEWAY_BOOTSTRAP_PEERS": "/ip4/localhost/tcp/4001/p2p/12D3KooWSHHwEY6cga3ng7tD1rzStAU58ogQXVMX3LZJ6Gqf6dee", "GATEWAY_NAMESPACE": "default", "GATEWAY_API_KEY": "ak_iGustrsFk9H8uXpwczCATe5U:default" } @@ -36,7 +36,7 @@ "program": "./cmd/gateway", "env": { "GATEWAY_ADDR": ":6001", - "GATEWAY_BOOTSTRAP_PEERS": "/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWSHHwEY6cga3ng7tD1rzStAU58ogQXVMX3LZJ6Gqf6dee", + "GATEWAY_BOOTSTRAP_PEERS": "/ip4/localhost/tcp/4001/p2p/12D3KooWSHHwEY6cga3ng7tD1rzStAU58ogQXVMX3LZJ6Gqf6dee", "GATEWAY_NAMESPACE": "default", "GATEWAY_API_KEY": "ak_iGustrsFk9H8uXpwczCATe5U:default" } diff --git a/Makefile b/Makefile index 712948d..355cce4 100644 --- a/Makefile +++ b/Makefile @@ -7,12 +7,12 @@ test: # Gateway-focused E2E tests assume gateway and nodes are already running # Configure via env: -# GATEWAY_BASE_URL (default http://127.0.0.1:6001) +# GATEWAY_BASE_URL (default http://localhost:6001) # GATEWAY_API_KEY (required for auth-protected routes) .PHONY: test-e2e test-e2e: @echo "Running gateway E2E tests (HTTP/WS only)..." - @echo "Base URL: $${GATEWAY_BASE_URL:-http://127.0.0.1:6001}" + @echo "Base URL: $${GATEWAY_BASE_URL:-http://localhost:6001}" @test -n "$$GATEWAY_API_KEY" || (echo "GATEWAY_API_KEY must be set" && exit 1) go test -v -tags e2e ./e2e @@ -57,7 +57,7 @@ run-node: go run ./cmd/node --config node.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 +# Usage: make run-node2 JOINADDR=/ip4/localhost/tcp/5001 HTTP=5002 RAFT=7002 P2P=4002 run-node2: @echo "Starting regular node (node.yaml)..." @echo "Config: ~/.debros/node.yaml" @@ -65,7 +65,7 @@ run-node2: go run ./cmd/node --config node2.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 +# Usage: make run-node3 JOINADDR=/ip4/localhost/tcp/5001 HTTP=5003 RAFT=7003 P2P=4003 run-node3: @echo "Starting regular node (node2.yaml)..." @echo "Config: ~/.debros/node2.yaml" @@ -122,9 +122,9 @@ dev: build echo " Initializing IPFS..."; \ mkdir -p $$HOME/.debros/bootstrap/ipfs; \ IPFS_PATH=$$HOME/.debros/bootstrap/ipfs/repo ipfs init --profile=server 2>&1 | grep -v "generating" | grep -v "peer identity" || true; \ - IPFS_PATH=$$HOME/.debros/bootstrap/ipfs/repo ipfs config --json Addresses.API '["/ip4/127.0.0.1/tcp/5001"]' 2>&1 | grep -v "generating" || true; \ - IPFS_PATH=$$HOME/.debros/bootstrap/ipfs/repo ipfs config --json Addresses.Gateway '["/ip4/127.0.0.1/tcp/8080"]' 2>&1 | grep -v "generating" || true; \ - IPFS_PATH=$$HOME/.debros/bootstrap/ipfs/repo ipfs config --json Addresses.Swarm '["/ip4/0.0.0.0/tcp/4001","/ip6/::/tcp/4001"]' 2>&1 | grep -v "generating" || true; \ + IPFS_PATH=$$HOME/.debros/bootstrap/ipfs/repo ipfs config --json Addresses.API '["/ip4/localhost/tcp/5001"]' 2>&1 | grep -v "generating" || true; \ + IPFS_PATH=$$HOME/.debros/bootstrap/ipfs/repo ipfs config --json Addresses.Gateway '["/ip4/localhost/tcp/8080"]' 2>&1 | grep -v "generating" || true; \ + IPFS_PATH=$$HOME/.debros/bootstrap/ipfs/repo ipfs config --json Addresses.Swarm '["/ip4/0.0.0.0/tcp/4101","/ip6/::/tcp/4101"]' 2>&1 | grep -v "generating" || true; \ fi; \ echo " Initializing IPFS Cluster..."; \ mkdir -p $$HOME/.debros/bootstrap/ipfs-cluster; \ @@ -135,9 +135,9 @@ dev: build echo " Initializing IPFS..."; \ mkdir -p $$HOME/.debros/node2/ipfs; \ IPFS_PATH=$$HOME/.debros/node2/ipfs/repo ipfs init --profile=server 2>&1 | grep -v "generating" | grep -v "peer identity" || true; \ - IPFS_PATH=$$HOME/.debros/node2/ipfs/repo ipfs config --json Addresses.API '["/ip4/127.0.0.1/tcp/5002"]' 2>&1 | grep -v "generating" || true; \ - IPFS_PATH=$$HOME/.debros/node2/ipfs/repo ipfs config --json Addresses.Gateway '["/ip4/127.0.0.1/tcp/8081"]' 2>&1 | grep -v "generating" || true; \ - IPFS_PATH=$$HOME/.debros/node2/ipfs/repo ipfs config --json Addresses.Swarm '["/ip4/0.0.0.0/tcp/4002","/ip6/::/tcp/4002"]' 2>&1 | grep -v "generating" || true; \ + IPFS_PATH=$$HOME/.debros/node2/ipfs/repo ipfs config --json Addresses.API '["/ip4/localhost/tcp/5002"]' 2>&1 | grep -v "generating" || true; \ + IPFS_PATH=$$HOME/.debros/node2/ipfs/repo ipfs config --json Addresses.Gateway '["/ip4/localhost/tcp/8081"]' 2>&1 | grep -v "generating" || true; \ + IPFS_PATH=$$HOME/.debros/node2/ipfs/repo ipfs config --json Addresses.Swarm '["/ip4/0.0.0.0/tcp/4102","/ip6/::/tcp/4102"]' 2>&1 | grep -v "generating" || true; \ fi; \ echo " Initializing IPFS Cluster..."; \ mkdir -p $$HOME/.debros/node2/ipfs-cluster; \ @@ -148,9 +148,9 @@ dev: build echo " Initializing IPFS..."; \ mkdir -p $$HOME/.debros/node3/ipfs; \ IPFS_PATH=$$HOME/.debros/node3/ipfs/repo ipfs init --profile=server 2>&1 | grep -v "generating" | grep -v "peer identity" || true; \ - IPFS_PATH=$$HOME/.debros/node3/ipfs/repo ipfs config --json Addresses.API '["/ip4/127.0.0.1/tcp/5003"]' 2>&1 | grep -v "generating" || true; \ - IPFS_PATH=$$HOME/.debros/node3/ipfs/repo ipfs config --json Addresses.Gateway '["/ip4/127.0.0.1/tcp/8082"]' 2>&1 | grep -v "generating" || true; \ - IPFS_PATH=$$HOME/.debros/node3/ipfs/repo ipfs config --json Addresses.Swarm '["/ip4/0.0.0.0/tcp/4003","/ip6/::/tcp/4003"]' 2>&1 | grep -v "generating" || true; \ + IPFS_PATH=$$HOME/.debros/node3/ipfs/repo ipfs config --json Addresses.API '["/ip4/localhost/tcp/5003"]' 2>&1 | grep -v "generating" || true; \ + IPFS_PATH=$$HOME/.debros/node3/ipfs/repo ipfs config --json Addresses.Gateway '["/ip4/localhost/tcp/8082"]' 2>&1 | grep -v "generating" || true; \ + IPFS_PATH=$$HOME/.debros/node3/ipfs/repo ipfs config --json Addresses.Swarm '["/ip4/0.0.0.0/tcp/4103","/ip6/::/tcp/4103"]' 2>&1 | grep -v "generating" || true; \ fi; \ echo " Initializing IPFS Cluster..."; \ mkdir -p $$HOME/.debros/node3/ipfs-cluster; \ diff --git a/README.md b/README.md index b325374..dd2e561 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ Use `make dev` for the complete stack or run binaries individually with `go run All runtime configuration lives in `~/.debros/`. - `bootstrap.yaml`: `type: bootstrap`, blank `database.rqlite_join_address` -- `node*.yaml`: `type: node`, set `database.rqlite_join_address` (e.g. `127.0.0.1:7001`) and include the bootstrap `discovery.bootstrap_peers` +- `node*.yaml`: `type: node`, set `database.rqlite_join_address` (e.g. `localhost:7001`) and include the bootstrap `discovery.bootstrap_peers` - `gateway.yaml`: configure `gateway.bootstrap_peers`, `gateway.namespace`, and optional auth flags Validation reminders: @@ -127,7 +127,7 @@ Environment overrides: ```bash export GATEWAY_ADDR="0.0.0.0:6001" export GATEWAY_NAMESPACE="my-app" -export GATEWAY_BOOTSTRAP_PEERS="/ip4/127.0.0.1/tcp/4001/p2p/" +export GATEWAY_BOOTSTRAP_PEERS="/ip4/localhost/tcp/4001/p2p/" export GATEWAY_REQUIRE_AUTH=true export GATEWAY_API_KEYS="key1:namespace1,key2:namespace2" ``` diff --git a/cmd/node/main.go b/cmd/node/main.go index 5d469b1..949ecd3 100644 --- a/cmd/node/main.go +++ b/cmd/node/main.go @@ -255,10 +255,10 @@ func main() { // Set default advertised addresses if empty if cfg.Discovery.HttpAdvAddress == "" { - cfg.Discovery.HttpAdvAddress = fmt.Sprintf("127.0.0.1:%d", cfg.Database.RQLitePort) + cfg.Discovery.HttpAdvAddress = fmt.Sprintf("localhost:%d", cfg.Database.RQLitePort) } if cfg.Discovery.RaftAdvAddress == "" { - cfg.Discovery.RaftAdvAddress = fmt.Sprintf("127.0.0.1:%d", cfg.Database.RQLiteRaftPort) + cfg.Discovery.RaftAdvAddress = fmt.Sprintf("localhost:%d", cfg.Database.RQLiteRaftPort) } // Validate configuration diff --git a/docs/ipfs-cluster-setup.md b/docs/ipfs-cluster-setup.md index fa70343..65e606f 100644 --- a/docs/ipfs-cluster-setup.md +++ b/docs/ipfs-cluster-setup.md @@ -122,7 +122,7 @@ If automatic setup didn't work, you can manually initialize: ```bash sudo -u debros ipfs init --profile=server --repo-dir=~/.debros/bootstrap/ipfs/repo -sudo -u debros ipfs config --json Addresses.API '["/ip4/127.0.0.1/tcp/5001"]' --repo-dir=~/.debros/bootstrap/ipfs/repo +sudo -u debros ipfs config --json Addresses.API '["/ip4/localhost/tcp/5001"]' --repo-dir=~/.debros/bootstrap/ipfs/repo ``` ### 2. Initialize Cluster diff --git a/e2e/gateway_e2e_test.go b/e2e/gateway_e2e_test.go index 8c6cb27..036d9b2 100644 --- a/e2e/gateway_e2e_test.go +++ b/e2e/gateway_e2e_test.go @@ -37,7 +37,7 @@ func requireAPIKey(t *testing.T) string { } func gatewayBaseURL() string { - return getEnv("GATEWAY_BASE_URL", "http://127.0.0.1:6001") + return getEnv("GATEWAY_BASE_URL", "http://localhost:6001") } func httpClient() *http.Client { diff --git a/pkg/anyoneproxy/socks.go b/pkg/anyoneproxy/socks.go index a4c4ce2..df4a2eb 100644 --- a/pkg/anyoneproxy/socks.go +++ b/pkg/anyoneproxy/socks.go @@ -19,7 +19,7 @@ var disabled bool func SetDisabled(v bool) { disabled = v } // Enabled reports whether Anyone proxy routing is active. -// Defaults to true, using SOCKS5 at 127.0.0.1:9050, unless explicitly disabled +// Defaults to true, using SOCKS5 at localhost:9050, unless explicitly disabled // via SetDisabled(true) or environment variable ANYONE_DISABLE=1. // ANYONE_SOCKS5 may override the proxy address. func Enabled() bool { @@ -31,7 +31,7 @@ func Enabled() bool { // socksAddr returns the SOCKS5 address to use for proxying (host:port). func socksAddr() string { - return "127.0.0.1:9050" + return "localhost:9050" } // socksContextDialer implements tcp.ContextDialer over a SOCKS5 proxy. @@ -57,7 +57,7 @@ func (d *socksContextDialer) DialContext(ctx context.Context, network, address s // DialerForAddr returns a tcp.DialerForAddr that routes through the Anyone SOCKS5 proxy. // It automatically BYPASSES the proxy for loopback, private, and link-local addresses -// to allow local/dev networking (e.g. 127.0.0.1, 10.0.0.0/8, 192.168.0.0/16, fc00::/7, fe80::/10). +// to allow local/dev networking (e.g. localhost, 10.0.0.0/8, 192.168.0.0/16, fc00::/7, fe80::/10). func DialerForAddr() tcp.DialerForAddr { return func(raddr ma.Multiaddr) (tcp.ContextDialer, error) { // Prefer direct dialing for local/private targets diff --git a/pkg/cli/config_commands.go b/pkg/cli/config_commands.go index 84f267e..208aac7 100644 --- a/pkg/cli/config_commands.go +++ b/pkg/cli/config_commands.go @@ -286,7 +286,7 @@ func initFullStack(force bool) { fmt.Printf("✅ Generated bootstrap identity: %s (Peer ID: %s)\n", bootstrapIdentityPath, bootstrapInfo.PeerID.String()) // Construct bootstrap multiaddr - bootstrapMultiaddr := fmt.Sprintf("/ip4/127.0.0.1/tcp/4001/p2p/%s", bootstrapInfo.PeerID.String()) + bootstrapMultiaddr := fmt.Sprintf("/ip4/localhost/tcp/4001/p2p/%s", bootstrapInfo.PeerID.String()) fmt.Printf(" Bootstrap multiaddr: %s\n", bootstrapMultiaddr) // Generate configs for all nodes... @@ -430,8 +430,8 @@ discovery: %s discovery_interval: "15s" bootstrap_port: %d - http_adv_address: "127.0.0.1:%d" - raft_adv_address: "127.0.0.1:%d" + http_adv_address: "localhost:%d" + raft_adv_address: "localhost:%d" node_namespace: "default" security: @@ -477,8 +477,8 @@ discovery: bootstrap_peers: [] discovery_interval: "15s" bootstrap_port: %d - http_adv_address: "127.0.0.1:%d" - raft_adv_address: "127.0.0.1:%d" + http_adv_address: "localhost:%d" + raft_adv_address: "localhost:%d" node_namespace: "default" security: diff --git a/pkg/cli/setup.go b/pkg/cli/setup.go index f9e8634..18dd3b5 100644 --- a/pkg/cli/setup.go +++ b/pkg/cli/setup.go @@ -1102,12 +1102,12 @@ func installOlric() { configPath := olricConfigDir + "/config.yaml" if _, err := os.Stat(configPath); os.IsNotExist(err) { configContent := `server: - bindAddr: "127.0.0.1" + bindAddr: "localhost" bindPort: 3320 memberlist: environment: local - bindAddr: "127.0.0.1" + bindAddr: "localhost" bindPort: 3322 ` @@ -1907,8 +1907,8 @@ func initializeIPFSForNode(nodeID, vpsIP string, isBootstrap bool) error { } // Configure IPFS API and Gateway addresses - exec.Command("sudo", "-u", "debros", "ipfs", "config", "--json", "Addresses.API", `["/ip4/127.0.0.1/tcp/5001"]`, "--repo-dir="+ipfsRepoPath).Run() - exec.Command("sudo", "-u", "debros", "ipfs", "config", "--json", "Addresses.Gateway", `["/ip4/127.0.0.1/tcp/8080"]`, "--repo-dir="+ipfsRepoPath).Run() + exec.Command("sudo", "-u", "debros", "ipfs", "config", "--json", "Addresses.API", `["/ip4/localhost/tcp/5001"]`, "--repo-dir="+ipfsRepoPath).Run() + exec.Command("sudo", "-u", "debros", "ipfs", "config", "--json", "Addresses.Gateway", `["/ip4/localhost/tcp/8080"]`, "--repo-dir="+ipfsRepoPath).Run() exec.Command("sudo", "-u", "debros", "ipfs", "config", "--json", "Addresses.Swarm", `["/ip4/0.0.0.0/tcp/4001","/ip6/::/tcp/4001"]`, "--repo-dir="+ipfsRepoPath).Run() fmt.Printf(" ✓ IPFS initialized\n") } @@ -2059,7 +2059,7 @@ func generateClusterServiceConfig(nodeID, vpsIP, secret string, isBootstrap bool }, IPFSConnector: ipfsConnectorConfig{ IPFSHTTP: ipfsHTTPConfig{ - NodeMultiaddress: "/ip4/127.0.0.1/tcp/5001", + NodeMultiaddress: "/ip4/localhost/tcp/5001", }, }, Datastore: datastoreConfig{ diff --git a/pkg/client/defaults_test.go b/pkg/client/defaults_test.go index eca0d4e..a686094 100644 --- a/pkg/client/defaults_test.go +++ b/pkg/client/defaults_test.go @@ -11,7 +11,7 @@ func TestDefaultBootstrapPeersNonEmpty(t *testing.T) { old := os.Getenv("DEBROS_BOOTSTRAP_PEERS") t.Cleanup(func() { os.Setenv("DEBROS_BOOTSTRAP_PEERS", old) }) // Set a valid bootstrap peer - validPeer := "/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWHbcFcrGPXKUrHcxvd8MXEeUzRYyvY8fQcpEBxncSUwhj" + validPeer := "/ip4/localhost/tcp/4001/p2p/12D3KooWHbcFcrGPXKUrHcxvd8MXEeUzRYyvY8fQcpEBxncSUwhj" _ = os.Setenv("DEBROS_BOOTSTRAP_PEERS", validPeer) peers := DefaultBootstrapPeers() if len(peers) == 0 { @@ -50,8 +50,8 @@ func TestNormalizeEndpoints(t *testing.T) { } func TestEndpointFromMultiaddr(t *testing.T) { - ma, _ := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/4001") - if ep := endpointFromMultiaddr(ma, 5001); ep != "http://127.0.0.1:5001" { + ma, _ := multiaddr.NewMultiaddr("/ip4/localhost/tcp/4001") + if ep := endpointFromMultiaddr(ma, 5001); ep != "http://localhost:5001" { t.Fatalf("unexpected endpoint: %s", ep) } } diff --git a/pkg/config/validate_test.go b/pkg/config/validate_test.go index 2122e6f..f351e9d 100644 --- a/pkg/config/validate_test.go +++ b/pkg/config/validate_test.go @@ -7,7 +7,7 @@ import ( // validConfigForType returns a valid config for the given node type func validConfigForType(nodeType string) *Config { - validPeer := "/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWHbcFcrGPXKUrHcxvd8MXEeUzRYyvY8fQcpEBxncSUwhj" + validPeer := "/ip4/localhost/tcp/4001/p2p/12D3KooWHbcFcrGPXKUrHcxvd8MXEeUzRYyvY8fQcpEBxncSUwhj" cfg := &Config{ Node: NodeConfig{ Type: nodeType, @@ -30,8 +30,8 @@ func validConfigForType(nodeType string) *Config { BootstrapPeers: []string{validPeer}, DiscoveryInterval: 15 * time.Second, BootstrapPort: 4001, - HttpAdvAddress: "127.0.0.1:5001", - RaftAdvAddress: "127.0.0.1:7001", + HttpAdvAddress: "localhost:5001", + RaftAdvAddress: "localhost:7001", NodeNamespace: "default", }, Logging: LoggingConfig{ @@ -205,7 +205,7 @@ func TestValidateRQLiteJoinAddress(t *testing.T) { } func TestValidateBootstrapPeers(t *testing.T) { - validPeer := "/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWHbcFcrGPXKUrHcxvd8MXEeUzRYyvY8fQcpEBxncSUwhj" + validPeer := "/ip4/localhost/tcp/4001/p2p/12D3KooWHbcFcrGPXKUrHcxvd8MXEeUzRYyvY8fQcpEBxncSUwhj" tests := []struct { name string nodeType string @@ -217,9 +217,9 @@ func TestValidateBootstrapPeers(t *testing.T) { {"bootstrap with peer", "bootstrap", []string{validPeer}, false}, {"bootstrap without peer", "bootstrap", []string{}, false}, {"invalid multiaddr", "node", []string{"invalid"}, true}, - {"missing p2p", "node", []string{"/ip4/127.0.0.1/tcp/4001"}, true}, + {"missing p2p", "node", []string{"/ip4/localhost/tcp/4001"}, true}, {"duplicate peer", "node", []string{validPeer, validPeer}, true}, - {"invalid port", "node", []string{"/ip4/127.0.0.1/tcp/99999/p2p/12D3KooWHbcFcrGPXKUrHcxvd8MXEeUzRYyvY8fQcpEBxncSUwhj"}, true}, + {"invalid port", "node", []string{"/ip4/localhost/tcp/99999/p2p/12D3KooWHbcFcrGPXKUrHcxvd8MXEeUzRYyvY8fQcpEBxncSUwhj"}, true}, } for _, tt := range tests { @@ -392,17 +392,17 @@ func TestValidateCompleteConfig(t *testing.T) { BackupInterval: 24 * time.Hour, RQLitePort: 5002, RQLiteRaftPort: 7002, - RQLiteJoinAddress: "127.0.0.1:7001", + RQLiteJoinAddress: "localhost:7001", MinClusterSize: 1, }, Discovery: DiscoveryConfig{ BootstrapPeers: []string{ - "/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWHbcFcrGPXKUrHcxvd8MXEeUzRYyvY8fQcpEBxncSUwhj", + "/ip4/localhost/tcp/4001/p2p/12D3KooWHbcFcrGPXKUrHcxvd8MXEeUzRYyvY8fQcpEBxncSUwhj", }, DiscoveryInterval: 15 * time.Second, BootstrapPort: 4001, - HttpAdvAddress: "127.0.0.1:5001", - RaftAdvAddress: "127.0.0.1:7001", + HttpAdvAddress: "localhost:5001", + RaftAdvAddress: "localhost:7001", NodeNamespace: "default", }, Security: SecurityConfig{ diff --git a/pkg/gateway/anon_proxy_handler.go b/pkg/gateway/anon_proxy_handler.go index e8aa925..7b0cd2d 100644 --- a/pkg/gateway/anon_proxy_handler.go +++ b/pkg/gateway/anon_proxy_handler.go @@ -234,7 +234,7 @@ func isPrivateOrLocalHost(host string) bool { } // Check for localhost variants - if host == "localhost" || host == "127.0.0.1" || host == "::1" { + if host == "localhost" || host == "localhost" || host == "::1" { return true } diff --git a/pkg/gateway/anon_proxy_handler_test.go b/pkg/gateway/anon_proxy_handler_test.go index 005e124..d72c2e5 100644 --- a/pkg/gateway/anon_proxy_handler_test.go +++ b/pkg/gateway/anon_proxy_handler_test.go @@ -92,7 +92,7 @@ func TestAnonProxyHandler_PrivateAddressBlocking(t *testing.T) { url string }{ {"localhost", "http://localhost/test"}, - {"127.0.0.1", "http://127.0.0.1/test"}, + {"localhost", "http://localhost/test"}, {"private 10.x", "http://10.0.0.1/test"}, {"private 192.168.x", "http://192.168.1.1/test"}, {"private 172.16.x", "http://172.16.0.1/test"}, @@ -166,7 +166,7 @@ func TestIsPrivateOrLocalHost(t *testing.T) { expected bool }{ {"localhost", true}, - {"127.0.0.1", true}, + {"localhost", true}, {"::1", true}, {"10.0.0.1", true}, {"192.168.1.1", true}, diff --git a/pkg/gateway/gateway.go b/pkg/gateway/gateway.go index d1d1545..e14a043 100644 --- a/pkg/gateway/gateway.go +++ b/pkg/gateway/gateway.go @@ -371,7 +371,7 @@ func discoverOlricServers(networkClient client.NetworkClient, logger *zap.Logger } // Skip localhost loopback addresses (we'll use localhost:3320 as fallback) - if ip == "127.0.0.1" || ip == "::1" || ip == "localhost" { + if ip == "localhost" || ip == "::1" || ip == "localhost" { continue } @@ -402,7 +402,7 @@ func discoverOlricServers(networkClient client.NetworkClient, logger *zap.Logger } // Skip localhost - if ip == "127.0.0.1" || ip == "::1" || ip == "localhost" { + if ip == "localhost" || ip == "::1" || ip == "localhost" { continue } diff --git a/pkg/gateway/storage_handlers_test.go b/pkg/gateway/storage_handlers_test.go index 30dd839..e539aec 100644 --- a/pkg/gateway/storage_handlers_test.go +++ b/pkg/gateway/storage_handlers_test.go @@ -18,11 +18,12 @@ import ( // mockIPFSClient is a mock implementation of ipfs.IPFSClient for testing type mockIPFSClient struct { - addFunc func(ctx context.Context, reader io.Reader, name string) (*ipfs.AddResponse, error) - pinFunc func(ctx context.Context, cid string, name string, replicationFactor int) (*ipfs.PinResponse, error) - pinStatusFunc func(ctx context.Context, cid string) (*ipfs.PinStatus, error) - getFunc func(ctx context.Context, cid string, ipfsAPIURL string) (io.ReadCloser, error) - unpinFunc func(ctx context.Context, cid string) error + addFunc func(ctx context.Context, reader io.Reader, name string) (*ipfs.AddResponse, error) + pinFunc func(ctx context.Context, cid string, name string, replicationFactor int) (*ipfs.PinResponse, error) + pinStatusFunc func(ctx context.Context, cid string) (*ipfs.PinStatus, error) + getFunc func(ctx context.Context, cid string, ipfsAPIURL string) (io.ReadCloser, error) + unpinFunc func(ctx context.Context, cid string) error + getPeerCountFunc func(ctx context.Context) (int, error) } func (m *mockIPFSClient) Add(ctx context.Context, reader io.Reader, name string) (*ipfs.AddResponse, error) { @@ -72,6 +73,13 @@ func (m *mockIPFSClient) Health(ctx context.Context) error { return nil } +func (m *mockIPFSClient) GetPeerCount(ctx context.Context) (int, error) { + if m.getPeerCountFunc != nil { + return m.getPeerCountFunc(ctx) + } + return 3, nil +} + func (m *mockIPFSClient) Close(ctx context.Context) error { return nil } diff --git a/pkg/ipfs/client_test.go b/pkg/ipfs/client_test.go index 344dad1..77445eb 100644 --- a/pkg/ipfs/client_test.go +++ b/pkg/ipfs/client_test.go @@ -6,6 +6,7 @@ import ( "io" "net/http" "net/http/httptest" + "strconv" "strings" "testing" "time" @@ -158,14 +159,19 @@ func TestClient_Pin(t *testing.T) { t.Errorf("Expected method POST, got %s", r.Method) } - var reqBody map[string]interface{} - if err := json.NewDecoder(r.Body).Decode(&reqBody); err != nil { - t.Errorf("Failed to decode request: %v", err) - return + if cid := strings.TrimPrefix(r.URL.Path, "/pins/"); cid != expectedCID { + t.Errorf("Expected CID %s in path, got %s", expectedCID, cid) } - if reqBody["cid"] != expectedCID { - t.Errorf("Expected CID %s, got %v", expectedCID, reqBody["cid"]) + query := r.URL.Query() + if got := query.Get("replication-min"); got != strconv.Itoa(expectedReplicationFactor) { + t.Errorf("Expected replication-min %d, got %s", expectedReplicationFactor, got) + } + if got := query.Get("replication-max"); got != strconv.Itoa(expectedReplicationFactor) { + t.Errorf("Expected replication-max %d, got %s", expectedReplicationFactor, got) + } + if got := query.Get("name"); got != expectedName { + t.Errorf("Expected name %s, got %s", expectedName, got) } response := PinResponse{ @@ -231,14 +237,14 @@ func TestClient_PinStatus(t *testing.T) { t.Errorf("Expected method GET, got %s", r.Method) } - response := PinStatus{ - Cid: expectedCID, - Name: "test-file", - Status: "pinned", - ReplicationMin: 3, - ReplicationMax: 3, - ReplicationFactor: 3, - Peers: []string{"peer1", "peer2", "peer3"}, + response := map[string]interface{}{ + "cid": expectedCID, + "name": "test-file", + "peer_map": map[string]interface{}{ + "peer1": map[string]interface{}{"status": "pinned"}, + "peer2": map[string]interface{}{"status": "pinned"}, + "peer3": map[string]interface{}{"status": "pinned"}, + }, } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) diff --git a/pkg/node/node.go b/pkg/node/node.go index af840e8..1687b73 100644 --- a/pkg/node/node.go +++ b/pkg/node/node.go @@ -321,7 +321,7 @@ func (n *Node) startLibP2P() error { // For localhost/development, disable NAT services // For production, these would be enabled isLocalhost := len(n.config.Node.ListenAddresses) > 0 && - (strings.Contains(n.config.Node.ListenAddresses[0], "127.0.0.1") || + (strings.Contains(n.config.Node.ListenAddresses[0], "localhost") || strings.Contains(n.config.Node.ListenAddresses[0], "localhost")) if isLocalhost { diff --git a/pkg/node/node_test.go b/pkg/node/node_test.go index 8ee0ab4..b07bb05 100644 --- a/pkg/node/node_test.go +++ b/pkg/node/node_test.go @@ -177,13 +177,13 @@ func TestHashBootstrapConnections(t *testing.T) { } // Create two hosts (A and B) listening on localhost TCP - hA, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0")) + hA, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/localhost/tcp/0")) if err != nil { t.Fatalf("libp2p.New (A): %v", err) } defer hA.Close() - hB, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0")) + hB, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/localhost/tcp/0")) if err != nil { t.Fatalf("libp2p.New (B): %v", err) } @@ -244,19 +244,19 @@ func TestHashBootstrapConnections(t *testing.T) { } // Create three hosts (A, B, C) listening on localhost TCP - hA, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0")) + hA, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/localhost/tcp/0")) if err != nil { t.Fatalf("libp2p.New (A): %v", err) } defer hA.Close() - hB, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0")) + hB, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/localhost/tcp/0")) if err != nil { t.Fatalf("libp2p.New (B): %v", err) } defer hB.Close() - hC, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0")) + hC, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/localhost/tcp/0")) if err != nil { t.Fatalf("libp2p.New (C): %v", err) }