A decentralized peer-to-peer (P2P) file storage system written in Go. This system allows nodes (peers) to connect, share, and retrieve files from each other over a TCP network. Files are encrypted and stored using content-addressable storage (CAS) with automatic peer discovery and file replication.
- Decentralized Storage: Files are distributed across multiple peers in the network
- Content-Addressable Storage (CAS): Files are stored based on their content hash
- Encryption: Files are encrypted using AES encryption
- Peer Discovery: Automatic connection to bootstrap nodes
- File Operations: Store, retrieve, and delete files across the network
- SQLite Database: Metadata tracking for files and peers
- Command-Line Interface: Easy-to-use CLI with Cobra
- Go 1.24.5 or higher: Download Go
- Git: For cloning the repository (optional)
git clone <repository-url>
cd P2PStorageThe project uses Go modules. Dependencies will be automatically downloaded when you build:
go mod downloadYou can build the project using either method:
Using Make:
make buildThis will create a binary at bin/p2p.
Using Go directly:
go build -o bin/p2pThe CLI tool provides several commands for managing your P2P storage node. All commands support a persistent --db flag to specify the SQLite database path (defaults to p2p.db).
--db <path>: Specify the SQLite database path (default:p2p.db)
Start a P2P storage node that listens for connections and can serve files to other peers.
./bin/p2p serve [flags]Flags:
--listen <address>: Listen address (default::3000)--bootstrap <nodes>: Bootstrap nodes to connect to (comma-separated or repeated flag)
Examples:
# Start a node on default port 3000
./bin/p2p serve
# Start a node on a custom port
./bin/p2p serve --listen :4000
# Start a node and connect to bootstrap nodes
./bin/p2p serve --listen :4000 --bootstrap :3000 --bootstrap :5000
# Use a custom database
./bin/p2p serve --db mynode.dbStore a file locally and broadcast it to all connected peers.
./bin/p2p store <key> <file> [flags]Arguments:
key: The key/name to store the file underfile: Path to the file to store
Flags:
--listen <address>: Listen address (default::3000)--bootstrap <nodes>: Bootstrap nodes to connect to
Examples:
# Store a file
./bin/p2p store myfile.txt /path/to/file.txt
# Store a file and connect to bootstrap nodes
./bin/p2p store document.pdf ./doc.pdf --bootstrap :3000
# Store with custom listen address
./bin/p2p store image.jpg ./photo.jpg --listen :4000 --bootstrap :3000Fetch a file from the network (local storage or peers).
./bin/p2p get <key> [flags]Arguments:
key: The key/name of the file to retrieve
Flags:
--listen <address>: Listen address (default::3000)--bootstrap <nodes>: Bootstrap nodes to connect to--out <path>: Output file path (if not specified, outputs to stdout)
Examples:
# Get a file and output to stdout
./bin/p2p get myfile.txt
# Get a file and save to a specific location
./bin/p2p get myfile.txt --out ./downloaded.txt
# Get a file from the network
./bin/p2p get document.pdf --bootstrap :3000 --out ./doc.pdfDelete a file from local storage.
./bin/p2p delete <key> [flags]Arguments:
key: The key/name of the file to delete
Flags:
--listen <address>: Listen address (default::3000)--bootstrap <nodes>: Bootstrap nodes to connect to
Examples:
# Delete a file
./bin/p2p delete myfile.txt
# Delete a file with custom database
./bin/p2p delete document.pdf --db mynode.dbList all known files in the database.
./bin/p2p files list [flags]Output Format:
ID Name Size LocalPath
Examples:
# List all files
./bin/p2p files list
# List files with custom database
./bin/p2p files list --db mynode.dbRun a local 3-node demo to test the P2P storage system.
./bin/p2p demoThis command:
- Starts three nodes on ports
:3000,:4000, and:5000 - Connects them to form a network
- Stores a test file
- Deletes the file
- Retrieves the file from the network
- Displays the file content
Example:
./bin/p2p demoTerminal 1 - Start Bootstrap Node:
./bin/p2p serve --listen :3000Terminal 2 - Start Second Node:
./bin/p2p serve --listen :4000 --bootstrap :3000Terminal 3 - Start Third Node:
./bin/p2p serve --listen :5000 --bootstrap :3000 --bootstrap :4000On Node 1 (port 3000):
./bin/p2p serve --listen :3000On Node 2 (port 4000):
# Start the node
./bin/p2p serve --listen :4000 --bootstrap :3000
# In another terminal, store a file
./bin/p2p store myfile.txt ./example.txt --listen :4000 --bootstrap :3000On Node 3 (port 5000):
# Start the node
./bin/p2p serve --listen :5000 --bootstrap :3000
# Retrieve the file stored by Node 2
./bin/p2p get myfile.txt --listen :5000 --bootstrap :3000 --out ./retrieved.txtP2PStorage/
├── main.go # Entry point
├── cmd.go # CLI commands definition
├── cmd_helpers.go # Helper functions for commands
├── server.go # FileServer implementation
├── storage.go # Storage layer with CAS
├── crypto.go # Encryption utilities
├── db/
│ ├── db.go # Database connection
│ └── repo.go # Database operations
└── p2p/
├── transport.go # Transport interface
├── tcp_transport.go # TCP transport implementation
├── message.go # Message definitions
├── encoding.go # Message encoding/decoding
└── handshake.go # Connection handshake
# Run all tests
go test ./...
# Run tests with verbose output
make test# Build the binary
make build
# Or use Go directly
go build -o bin/p2pThe system uses SQLite to store:
- File metadata (ID, name, size, local path)
- Peer information (address, status, last seen)
- Encryption keys
By default, the database is stored as p2p.db in the current directory. You can specify a custom path using the --db flag.
Files are stored using Content-Addressable Storage (CAS) in a directory structure based on the file key hash. The default storage root is <listen_address>_network (e.g., :3000_network).
Files are encrypted using AES encryption before storage.
If you get an error about a port being in use, choose a different port:
./bin/p2p serve --listen :4000Make sure bootstrap nodes are running before connecting to them. Start bootstrap nodes first, then connect other nodes to them.
If you encounter database errors, try deleting the database file and letting it recreate:
rm p2p.db
./bin/p2p serve[Add your license here]
[Add contribution guidelines here]