| description | This guide walks you through setting up a PDP-enabled Filecoin Storage Provider using Lotus, YugabyteDB, and Curio |
|---|
{% hint style="info" %} For a PDP-only node without PoRep/sealing (skiff), see the Curio-PDP runbook and Skiff binary. {% endhint %}
{% hint style="danger" %} ALPHA FEATURE - UNDER DEVELOPMENT
This documentation covers the PDP (Proof of Data Possession) feature, which is currently in alpha and under active development. This tool is intended for testing and experimental use only.
For production use and submitting real deals with live PDP Storage Providers, please use the Synapse SDK. {% endhint %}
{% hint style="warning" %} Note: This guide is written specifically for Ubuntu 22.04. If you are using a different Linux distribution, refer to the relevant documentation for package installation and compatibility. {% endhint %}
Before starting, make sure you have a user with sudo privileges. This section prepares your system for the PDP stack.
- RAM: 32 GiB+
- CPU: 8 Core+
- Storage:
- 1 TiB Fast storage (NVMe/SSD)
- 10 TiB Long-term storage (HDD)
- GPU: Not required
- Connectivity: Public HTTPS endpoint (domain)
sudo apt update && sudo apt upgrade -y && sudo apt install -y \
mesa-opencl-icd ocl-icd-opencl-dev gcc git jq pkg-config curl clang \
build-essential hwloc libhwloc-dev libarchive-dev wget ntp python-is-python3 aria2Curio’s minimum Go version is set in the Curio repo at go.mod.
Example (current repo min is 1.26.2):
sudo rm -rf /usr/local/go
wget https://go.dev/dl/go1.26.2.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.26.2.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
go version{% hint style="success" %}
You should see something like: go version go1.26.2 linux/amd64
{% endhint %}
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh{% hint style="info" %} When prompted, choose the option 1) Proceed with standard installation (default — just press Enter). {% endhint %}
source $HOME/.cargo/env
rustc --version{% hint style="success" %}
You should see something like: rustc 1.86.0 (05f9846f8 2025-03-31)
{% endhint %}
sudo tee /etc/sudoers.d/dev-paths <<EOF
Defaults secure_path="/usr/local/go/bin:$HOME/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
EOFPDP requires database schema migrations.
How to confirm PDP schema exists:
- Connect to YSQL and verify expected tables exist in the
curioschema.
ysqlsh -h "$CURIO_DB_HOST" -p "${CURIO_DB_PORT:-5433}" -U "$CURIO_DB_USER" -d "${CURIO_DB_NAME:-yugabyte}" -c "\dn+ curio"Migration reference:
- The PDP schema is added via Curio’s HarmonyDB migrations (for example:
harmony/harmonydb/sql/20240930-pdp.sql).
If you upgraded Curio binaries but PDP still fails:
- check Curio logs on startup for schema upgrade output
- confirm you are connected to the correct DB (
CURIO_DB_NAMEdefaultyugabyte) and schema (curio)
PDP commonly confuses operators because multiple HTTP-exposed services may exist in a Curio deployment.
Recommended patterns:
- One public domain (e.g.
curio.example.com) - One HTTP server handles multiple routes
- Reverse proxy optional (see HTTP server docs)
pdp.example.comandmarket.example.com- Useful when you want different auth/proxying/caching policies
Checklist:
- Decide whether Curio terminates TLS or a reverse proxy does.
- Ensure inbound 80/443 is reachable for Let’s Encrypt (if used).
See:
documentation/en/curio-market/curio-http-server.md
Common causes:
- firewall blocks inbound traffic
- wrong domain/port
- TLS delegation mismatch
What to do:
- test from an external host
- confirm DNS and ports 80/443 (or your proxy) are correct
- include full logs + command used
🧠 Lotus is your gateway to the Filecoin network. It syncs the chain, manages wallets, and is required for Curio to interact with your node.
Clone and check out Lotus:
git clone https://github.com/filecoin-project/lotus.git
cd lotus
git checkout $(curl -s https://api.github.com/repos/filecoin-project/lotus/releases/latest | jq -r .tag_name)Build and Install for Mainnet
make clean && make lotus
sudo make install-daemon
lotus --versionBuild and Install for Calibration
make clean && make GOFLAGS="-tags=calibnet" lotus
sudo make install-daemon
lotus --version{% hint style="success" %}
You should see something like: lotus version 1.32.2+calibnet+git.ff88d8269
{% endhint %}
Download the Snapshot
Mainnet:
aria2c -x5 -o snapshot.car.zst https://forest-archive.chainsafe.dev/latest/mainnet/Calibration:
aria2c -x5 -o snapshot.car.zst https://forest-archive.chainsafe.dev/latest/calibnet/Import and Start the Daemon
lotus daemon --import-snapshot snapshot.car.zst --remove-existing-chain --halt-after-import
nohup lotus daemon > ~/lotus.log 2>&1 &{% hint style="info" %}
If you encounter errors related to EnableEthRPC or EnableIndexer, run the following command and restart Lotus
{% endhint %}
sed -i 's/^\( *\)#*EnableEthRPC = .*/\1EnableEthRPC = true/; s/^\( *\)#*EnableIndexer = .*/\1EnableIndexer = true/' ~/.lotus/config.tomlMonitor Sync Progress
lotus sync waitTo monitor continuously:
lotus sync wait --watchMonitor Logs
tail -f ~/lotus.log🧠 Curio uses YugabyteDB to store metadata about deals, sealing operations, and PDP submissions.
{% hint style="warning" %}
Before starting Yugabyte, you must increase the default ulimit values to ensure system limits do not interfere with the database.
{% endhint %}
To do this:
Add these lines to /etc/security/limits.conf:
echo "$(whoami) soft nofile 1048576" | sudo tee -a /etc/security/limits.conf
echo "$(whoami) hard nofile 1048576" | sudo tee -a /etc/security/limits.confThis ensures the increased limits are automatically applied to future sessions.
ulimit -n 1048576Verify:
ulimit -n{% hint style="success" %}
This should output 1048576.
{% endhint %}
wget https://software.yugabyte.com/releases/2.25.1.0/yugabyte-2.25.1.0-b381-linux-x86_64.tar.gz
tar xvfz yugabyte-2.25.1.0-b381-linux-x86_64.tar.gz
cd yugabyte-2.25.1.0
./bin/post_install.sh./bin/yugabyted start \
--advertise_address 127.0.0.1 \
--master_flags rpc_bind_addresses=127.0.0.1 \
--tserver_flags rpc_bind_addresses=127.0.0.1{% hint style="warning" %} If you encounter locale-related errors when starting Yugabyte for the first time, run: {% endhint %}
sudo locale-gen en_US.UTF-8{% hint style="success" %}
Visit http://127.0.0.1:15433 to confirm successful installation. This is the YugabyteDB web UI — it should display the dashboard if the service is running correctly and all nodes are healthy.
{% endhint %}
{% hint style="info" %} You can also check your Yugabyte cluster details directly in the CLI with: {% endhint %}
./bin/yugabyted status🧠 Curio is the core PDP client that coordinates sealing, interacts with Lotus and submits PDP proofs.
Before you proceed with the installation, you should increase the UDP buffer size:
sudo sysctl -w net.core.rmem_max=2097152
sudo sysctl -w net.core.rmem_default=2097152To make this change persistent across reboots:
echo 'net.core.rmem_max=2097152' | sudo tee -a /etc/sysctl.conf
echo 'net.core.rmem_default=2097152' | sudo tee -a /etc/sysctl.confClone the repository and switch to the PDP branch:
git clone https://github.com/filecoin-project/curio.git
cd curio
git checkout pdpM3d{% hint style="info" %} Curio is compiled for a specific Filecoin network at build time. Choose the appropriate build command below. {% endhint %}
Mainnet
make clean buildCalibration
make clean calibnet{% hint style="info" %} This step will take a few minutes to complete. {% endhint %}
Run the following to install the compiled binary:
sudo make installThis will place curio in /usr/local/bin
Verify the installation:
curio --versionExpected example output:
curio version 1.24.4+calibnet+git_f954c0a_2025-04-06T15:46:32-04:00Curio provides a utility to help you set up a new miner interactively. Run the following command:
curio guided-setupUse the arrow keys to navigate the guided setup menu and select "Setup non-Storage Provider cluster".
If you used the default installation steps from this guide, the following values should work:
- Host:
127.0.0.1 - Port:
5433 - Username:
yugabyte - Password:
yugabyte - Database:
yugabyte
You can verify these settings by running the following command from the Yugabyte directory:
./bin/yugabyted statusAfter selecting "Continue to connect and update schema", Curio will automatically create the required tables and schema in the database.
You'll be asked whether to share anonymised or signed telemetry with the Curio team to help improve the software.
Select your preference and continue.
At the final step of the guided setup, you'll be prompted to choose where to save your database configuration file.
Use the arrow keys to select a location. A common default is:
/home/your-username/curio.envOnce selected, setup will complete, and the miner configuration will be stored.
To explore the Curio interface visually, start the GUI layer:
curio run --layers=guiThen, open your browser and go to:
http://127.0.0.1:4701This will launch the Curio web GUI locally.
🧠 This section enables FWSS Proof of Data Possession (PDP) on your SP node using Curio. These steps guide you through running a standalone PDP service using Curio and pdptool.
| Cover image | ||
|---|---|---|
| PDP Support Channels | Filecoin.svg.png | https://filecoinproject.slack.com/archives/C0717TGU7V2 |
With Curio running with the GUI layer:
curio run --layers=guiRun the following commands in your Curio CLI to attach storage paths:
curio cli storage attach --init --seal /fast-storage/path
curio cli storage attach --init --store /long-term-storage/path{% hint style="info" %} Your fast-storage path should point to high-performance storage media such as NVMe or SSD.
To keep PDP payloads off sealed-sector disks, attach a dedicated piece to denytypes on storage configuration files. See Separate PDP / parked pieces from sealed storage.
{% endhint %}
Browse to the Configurations page of the Curio GUI.
Create a new layer named pdp and enable the following under Subsystems:
{% hint style="info" %} You may find it helpful to search for the setting names in your browser. {% endhint %}
- ✅
EnableParkPiece - ✅
EnablePDP - ✅
EnableCommP - ✅
EnableMoveStorage
In the HTTP section:
- ✅ Enable:
true - 🌐 DomainName:
your domain (e.g., pdp.mydomain.com) - 📡 ListenAddress:
0.0.0.0:443
{% hint style="info" %} Tip: You must point your domain's A record to your server's public IP address for Let's Encrypt to issue a certificate. {% endhint %}
{% hint style="warning" %} There are several ways to obtain private keys for Ethereum addresses. In this guide, we will use a new delegated FIL wallet address. {% endhint %}
Create a new delegated wallet:
lotus wallet new delegated# Example output:
t410fuo4dghaeiqzokiqnxruzdr6e3cjktnxprrc56bi{% hint style="info" %} You can display your Lotus wallets at any time by running: {% endhint %}
lotus wallet listExport & convert your new delegated wallet address private key:
lotus wallet export <your-delegated-wallet-address> | xxd -r -p | jq -r '.PrivateKey' | base64 -d | xxd -p -c 32# Example output:
d4c2e3f9a716bb0e47fa91b2cf4a29870be3c5982fd6eafed71e8ac3f9c0b127Browse to the PDP page of the Curio GUI and in the Owner Address section:
- Select Import Key
- Copy the previously generated private wallet key into the Private Key (Hex) field.
- Select Import Key
{% hint style="success" %} Your 0x wallet address - the delegated Ethereum address derived from your Filecoin delegated wallet private key - will be added to the Owner Address section of the Curio PDP page. {% endhint %}
Make sure to send a small amount of FIL or tFIL (testnet FIL) to your 0x wallet - we recommend 8 FIL for Mainnet & 5 tFIL for Calibration to ensure uninterrupted PDP operation during initial setup and testing. Calibration test FIL faucet information.
{% hint style="warning" %} Important: Secure your private key material. Don't expose or store it in plain text without protection. {% endhint %}
Restart Curio with both layers:
curio run --layers=gui,pdp{% hint style="info" %}
If you encounter errors related to EnableEthRPC or EnableIndexer, run the following command and restart Lotus
{% endhint %}
sed -i 's/^\( *\)#*EnableEthRPC = .*/\1EnableEthRPC = true/; s/^\( *\)#*EnableIndexer = .*/\1EnableIndexer = true/' ~/.lotus/config.toml{% hint style="info" %} If you encounter errors binding to port 443 when starting Curio with the pdp configuration layer, run: {% endhint %}
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/curioTest the PDP service:
{% hint style="info" %}
If pdptool is not installed, clone and build Curio:
{% endhint %}
git clone https://github.com/filecoin-project/curio.git
cd curio/cmd/pdptool
go build ../pdptool ping --service-url https://your-domain.com --service-name public{% hint style="info" %}
Always use public for the --service-name flag
{% endhint %}
{% hint style="success" %} Expected output: {% endhint %}
Ping successful: Service is reachable and JWT token is valid.You've successfully launched a PDP-enabled Filecoin Storage Provider stack. Your system is now:
- ✅ Syncing with the Filecoin network via Lotus
- ✅ Recording deal and sector metadata in YugabyteDB
- ✅ Operating Curio to manage sealing and coordination
- ✅ Enabled Proof of Data Possession (PDP)
- ✅ Connected to your PDP-enabled storage provider
- ✔️ Register your FWSS node
- 🔗 Explore FWSS & PDP tools & resources at https://www.filecoin.services
- 💬 Join the community - Filecoin Slack - #fil-pdp