Operator guide · calibration testnet

Test Lantern with Curio PDP

Run the stock Curio-PDP storage provider with Lantern as its only chain node, prove data on the Filecoin calibration network, and tell us where it hurt.

What you are testing

One chain node, and it is Lantern

Curio-PDP needs a Lotus-compatible chain API. The upstream Docker stack ships Forest for that, which needs a chain snapshot and tens of GB of disk. In this test the unmodified filecoin/curio-pdp:calibnet image talks only to Lantern: no Lotus, no Forest, no RPC bridge. Lantern anchors to the head with a multi-operator quorum, follows it over libp2p, and verifies every block, state read and FEVM eth_call locally. Curio signs its own messages; Lantern publishes them and holds no keys.

Build
~85 s
clean machine, from source
Init
~15 s
3-operator quorum
First proof
~2 h
after the data set exists
Network
calibration
testnet only
What you need

Before you begin

Machine

A Linux host, x86_64 or arm64, for the Curio-PDP stack (the walkthrough uses systemd and the docker0 bridge). Building Lantern and running the client script also work on macOS.

Docker

Docker Engine with Compose v2.24.4 or newer, plus git and curl. Node.js 20+ on any machine for the client test.

Resources

A few GB of RAM for the whole stack and about 20 GB of fast disk. Piece storage needs at least 100 GiB free (registration declares it); it may be HDD.

Public HTTPS

A hostname for the PDP API: a domain you control, or a domain on a free Cloudflare account for a Cloudflare Tunnel (works behind NAT).

Test tokens

About 10 tFIL across two wallets (at least about 6 tFIL for the PDP wallet, the rest for client gas) plus test USDFC for the client. Faucets: the official list or faucet.reiers.io.

Time

Plan for about half a day. Most of it is waiting: the first proof lands about one proving period (about 2 h on calibration) after your data set is created.

The path

Twelve steps, clean machine to proofs

A skimmable summary with the key commands. The canonical, detailed walkthrough is RUN-PDP.md on GitHub, with every step linked below. Replace placeholders in angle brackets; pdp.example.com stands for your public hostname.

  1. 01

    Install Docker Engine and Compose v2.24.4 or newer

    The Lantern overlay uses the Compose !override tag, so distribution packages are often too old. Note your docker0 address: the commands below use Docker's default bridge address 172.17.0.1, replace it if yours differs.

    curl -fsSL https://get.docker.com | sudo sh
    sudo usermod -aG docker "$USER"      # then log out and back in
    docker version
    docker compose version               # must print v2.24.4 or newer
    ip -4 addr show docker0              # note the inet address, typically 172.17.0.1
  2. 02

    Get Lantern v1.10.1-rc1 and verify it

    Download the release binary and check it against the published manifest (Linux x86_64 shown, lantern-linux-arm64 also exists):

    Option A: download
    TAG=v1.10.1-rc1                              # or a newer release
    curl -fsSLO "https://github.com/Reiers/lantern/releases/download/$TAG/lantern-linux-amd64"
    curl -fsSLO "https://github.com/Reiers/lantern/releases/download/$TAG/lantern-linux-amd64.sha256"
    sha256sum -c lantern-linux-amd64.sha256       # lantern-linux-amd64: OK
    mkdir -p "$HOME/.local/bin"
    install -m 0755 lantern-linux-amd64 "$HOME/.local/bin/lantern"
    export PATH="$HOME/.local/bin:$PATH"           # add to ~/.bashrc if needed

    Or build from source with Go 1.26.4 (about 85 s on a clean machine, no C compiler, no Rust):

    Option B: build
    git clone https://github.com/Reiers/lantern.git
    cd lantern
    TAG=v1.10.1-rc1                              # or a newer release
    git checkout "$TAG"
    CGO_ENABLED=0 go build -trimpath -ldflags "-s -w -X main.versionTag=$TAG" -o lantern ./cmd/lantern

    Releases from v1.10.1 on are byte-reproducible. To check that the published bytes come from the tagged source, rebuild them in the pinned container (needs Docker, no local Go):

    ./scripts/repro-build.sh "$TAG" linux/amd64          # or linux/arm64, darwin/arm64; omit for all
    lantern version          # lantern v1.10.1 (<commit>) Lantern+mainnet, or newer

    Lantern+mainnet is only the compiled-in default. Every command takes --network calibration at run time.

  3. 03

    Initialise Lantern for calibration

    init writes a trust anchor only when at least 3 distinct operators agree on the current finalized head, and any conflicting answer fails it. node-type pdp selects the PDP tier (persistent 3 GiB block cache plus a one-day transaction index). Keep LANTERN_HOME identical for every command and for the service.

    export LANTERN_HOME="$HOME/.lantern"
    export LANTERN_PASS=''          # explicit empty: no keystore passphrase (Lantern holds no keys here)
    
    lantern init --network calibration --no-wallet
    lantern node-type pdp --network calibration
  4. 04

    Run the daemon on the Docker bridge

    Curio runs in a container, so Lantern binds the host's docker0 address: reachable from local containers, not routed from your LAN or the internet. --allow-remote-rpc is an acknowledgement, not an open door: write, sign and admin methods still need the token. Never use --listen 0.0.0.0:1234 on a host with a public interface.

    lantern service install --network calibration --listen 172.17.0.1:1234 -- --allow-remote-rpc --metrics 127.0.0.1:9092
    sudo loginctl enable-linger "$USER"
    curl -s http://172.17.0.1:1234/healthz            # ok
    lantern info --network calibration

    lantern info prints the FULLNODE_API_INFO value Curio needs. Filecoin.StateNetworkVersion must return 29: anything lower means a build that predates the NV29 upgrade. Treat the token like a password.

  5. 05

    Start stock Curio-PDP against Lantern

    Use the upstream filecoin-project/curio stack unchanged, plus one overlay file from the Lantern repo that removes Forest.

    git clone --depth 1 https://github.com/filecoin-project/curio.git
    cd curio/docker/skiff
    cp /path/to/lantern/deploy/curio-pdp/docker-compose.lantern.yaml .
    cp .env .env.upstream
    cp /path/to/lantern/deploy/curio-pdp/env.lantern.example .env

    The three .env lines that matter. Set the domain before the first start, and use an IP literal after /ip4/:

    .env
    SKIFF_IMAGE=filecoin/curio-pdp:calibnet
    SKIFF_HTTP_DOMAIN=pdp.example.com
    FULLNODE_API_INFO=<token from lantern info>:/ip4/172.17.0.1/tcp/1234/http

    Start Yugabyte and Curio-PDP only, naming both services every time (otherwise Compose also starts Forest). First start runs database migrations for a few minutes.

    C="docker compose -f docker-compose.yaml -f docker-compose.calibnet.yaml -f docker-compose.lantern.yaml"
    $C pull yugabyte skiff
    $C up -d --no-build yugabyte skiff
    $C ps
    $C logs -f skiff
  6. 06

    Open the admin GUI over an SSH tunnel

    The GUI listens on 127.0.0.1:4701 and has no login, so never publish port 4701. The Chain page should show your Lantern with Reachability and Sync Status ok. The PDP Guide page is your checklist for steps 7 to 10.

    ssh -fN -L 4701:127.0.0.1:4701 <user>@<host>
  7. 07

    Attach storage

    Create a piece directory, then attach /data/pdp-pieces under Storage in the GUI. The PDP Guide checks for at least 100 GiB free.

    docker exec skiff mkdir -p /data/pdp-pieces
  8. 08

    Create and fund the PDP wallet

    In Wallets (or the PDP Guide) click Create. Curio shows the private key once: save it before closing the dialog. Fund the 0x address with at least about 6 tFIL (5 FIL registry fee plus gas) from a calibration faucet: the official faucet list or faucet.reiers.io (tFIL and USDFC, run by the Lantern maintainer).

  9. 09

    Expose the PDP API over public HTTPS

    Clients and FWSS need https://pdp.example.com. Behind NAT, a free Cloudflare Tunnel works (the PDP Guide can start the connector for you); with your own domain, terminate TLS in front of port 80 or let Curio fetch a Let's Encrypt certificate. Open only 80 and 443, never 4701 or 1234.

    curl -i https://pdp.example.com/pdp/ping

    503 PDP wallet not configured before step 8 is expected (the path from the internet works). 200 once the wallet exists.

  10. 10

    Register with FWSS

    Open PDP (tools section), then Register Provider in the Filecoin Service Registry section. Description: at most 128 characters. Capacity: at least 100 GiB. The registry charges a 5 FIL fee. Curio signs, Lantern publishes from its local message pool. Note your provider ID once the transaction lands.

  11. 11

    Create a test data set as a client

    Use a separate client wallet (never the PDP key) funded with tFIL and USDFC, and Node.js 20+ on any machine. The script uploads a 4 MiB random piece and waits for your provider to create the data set through Lantern; expect a data set ID within roughly 5 to 10 minutes.

    cd deploy/curio-pdp
    npm install
    CLIENT_PRIVATE_KEY=0x<client key> PROVIDER_ID=<your provider id> node upload-test.mjs
  12. 12

    Watch proofs land

    A calibration proving period is 240 epochs, about 2 hours. The first proof lands about one period after the data set is created, then once per period. last proven epoch above 0 means a proof landed.

    node upload-test.mjs status <dataSetId>
    # read through your own Lantern instead of Glif:
    RPC_URL=http://172.17.0.1:1234/rpc/v1 node upload-test.mjs status <dataSetId>
What success looks like

From registration to steady proving

  1. 01 · Registration

    The PDP page shows your provider ID; the registration transaction has status 1.

  2. 02 · Data set creation

    After the client upload, Curio sends the create transaction through Lantern and logs Successfully processed data set create. The data set appears under DataSets.

  3. 03 · PDPv0_InitPP

    Runs once for the new data set and sends a nextProvingPeriod transaction (status 1).

  4. 04 · PDPv0_Prove

    Runs in every challenge window (every 240 epochs on calibration) and sends a provePossession transaction, followed by PDPv0_ProvPeriod scheduling the next period. The script's status mode shows the last proven epoch advancing.

  5. 05 · No manual intervention

    In the maintainers' 24 hour run, two data sets went through 13 consecutive proving windows each, every transaction landed with status 1, and the Lantern daemon never restarted.

Once registered, third-party clients may pick your provider on their own; that is normal. Full details: RUN-PDP.md 13.

Top gotchas

The errors we hit, so you do not

/ip4/ needs an IP literal

/ip4/host.docker.internal/... (as in the upstream .env) makes Curio exit with unknown url scheme '' in a loop. Use your docker0 IP, for example <token>:/ip4/172.17.0.1/tcp/1234/http.

Set SKIFF_HTTP_DOMAIN before the first start

It is seeded into the database once. If you started with localhost, edit HTTP.DomainName in Configuration (base layer) and restart skiff; changing .env later has no effect.

The daemon refuses to start without a trust anchor

no trust anchor at .../bootstrap-anchor.json means init never completed for this network and LANTERN_HOME. Run lantern init --network calibration --no-wallet (or lantern repair --network calibration) with the same LANTERN_HOME as the service.

Every command needs --network calibration

A command without it means mainnet: the daemon syncs mainnet or lantern info says "not initialised". Add the flag everywhere, including the service.

Compose older than v2.24.4, or unnamed services

Old Compose rejects the overlay's !override tag. Always run $C up -d --no-build yugabyte skiff; a bare up -d also starts Forest and downloads a snapshot.

Client create reverts on Filecoin Pay lockup

insufficient funds to cover lockup after function execution: each data set locks funds and the client already owns others. Deposit more, for example EXTRA_DEPOSIT_USDFC=5, and run the script again.

Provider description is limited to 128 characters

Longer descriptions fail with description is too long, max 128 characters allowed. Nothing is sent and no fee is charged: shorten it and submit again.

More symptoms and fixes: RUN-PDP.md troubleshooting. Seeing no contract code at given address? Your Lantern predates NV29: upgrade to v1.10.1-rc1 or later.

Report your run

Tell us how it went

A full run that worked end to end is as valuable as a bug report. Every friction point, however small, makes the guide better for the next operator.

What to include

  • Hardware: CPU and threads, RAM, disk, VM or bare metal
  • OS: distribution, version and kernel
  • Lantern version (lantern version) and how you got it: built, downloaded or installer
  • Build time, if you built from source
  • Time to first proof, from data set creation
  • Pass or fail for each step you reached
  • Every friction point, with the exact command and output

Never paste API tokens, private keys or the contents of secrets/. Redact them.

Credit where it is due

Testers are credited in the verification report if they want to be. Say so in your report and tell us the name or handle to use.

Questions, or prefer email? [email protected]