Skip to content

PDPVerifier upgrade from v3.3.0 to v3.4.0 #271

@rjan90

Description

@rjan90

Summary

Track the successive rollout of PDPVerifier from the v3.3.0 release baseline to v3.4.0, with Calibration first and Mainnet second.

v3.3.0 is already published and did not include a PDPVerifier deployment; per the v3.3.0 release notes, the live Mainnet and Calibration proxies remain on the v3.2.0 deployments until this rollout lands.

Previously blocked by: FilOzone/pdp#269, which is now closed.

This issue is the full operational checklist for the rollout and release closeout.

Rollout Status

Network Announced Executable on or after Executed Notes
Calibration Replacement announced 3752744 Executed Proxy is on v3.4.0; read-only smoke tests passed.
Mainnet Replacement announced 6053410 Executed Proxy is on v3.4.0; read-only smoke tests passed.

Operational Notes

  • Use this single issue to track the full rollout across both networks.
  • v3.3.0 did not deploy PDPVerifier; live proxies may still report v3.2.0 until this v3.4.0 rollout is executed.
  • Record major steps as issue comments as you go rather than editing every detail into the top post.
  • The live proxy already supports planned upgrades, first use tools/announce-planned-upgrade.sh, wait until the announced epoch, then use tools/upgrade.sh.
  • Do not deploy until all bytecode-affecting PRs are merged to main.
  • Tag the exact deployed commit first if you want the git tag to match the on-chain bytecode exactly.
  • If changelog-only updates happen after deploy, commit them after tagging.
  • The current tools/deploy-calibnet.sh and tools/deploy-mainnet.sh also deploy a fresh proxy. For upgrades, the safest path is still:
    • deploy the implementation manually with forge create
    • generate SAFE calldata with tools/upgrade.sh
  • tools/upgrade.sh prints the SAFE contract's on-chain nonce. The Safe UI may queue the transaction at a higher nonce if there are already pending transactions. That does not change the contract calldata.

Suggested PR titles:

  • Changelog draft: docs(changelog): draft v3.4.0 release notes
  • Changelog finalization: docs(changelog): finalize v3.4.0 release notes
  • Issue-template update: docs: update PDPVerifier upgrade issue template

Suggested release tag:

  • v3.4.0

Network Constants

  • Mainnet proxy: 0xBADd0B92C1c71d02E7d520f64c0876538fa2557F
  • Calibration proxy: 0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C
  • SAFE owner: 0x3569b2600877a9F42d9Ebdd205386F3F3788F3E5
  • Mainnet RPC: https://api.node.glif.io/rpc/v1
  • Calibration RPC: https://api.calibration.node.glif.io/rpc/v1

Release Preparation

1. Freeze the Deploy Commit

  • Final deploy commit on main confirmed: 1370f49f9af958e4e3a1396377035685d55ffdba
git checkout main
git pull --ff-only origin main
git rev-parse HEAD

Current origin/main: 1370f49f9af958e4e3a1396377035685d55ffdba (merge of #275, with the bytecode-affecting #274 included). Use this exact commit for replacement implementation deployments.

  • Intended VERSION confirmed in src/PDPVerifier.sol: 3.4.0
    • If a version-only fix PR is needed: chore: correctly set version to v3.4.0
rg -n 'string public constant VERSION' src/PDPVerifier.sol

Current status: origin/main now has VERSION = "3.4.0" after #272, #274, and #275 merged.

2. Confirm Constructor Values

  • Calibration constructor values confirmed
    • initializerVersion = 3
    • challengeFinality = 10
  • Current Calibration proxy initializer counter read: 2
RPC_URL="https://api.calibration.node.glif.io/rpc/v1" \
./tools/get-initialized-counter.sh 0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C
  • Mainnet constructor values confirmed
    • initializerVersion = 3
    • challengeFinality = 150
  • Current Mainnet proxy initializer counter read: 2
RPC_URL="https://api.node.glif.io/rpc/v1" \
./tools/get-initialized-counter.sh 0xBADd0B92C1c71d02E7d520f64c0876538fa2557F

Both current proxy initializer counters returned 2; deploy the next implementation with initializerVersion = 3.

3. Confirm the Live Proxy Owner and Version

  • Current Calibration proxy owner confirmed: 0x3569b2600877a9F42d9Ebdd205386F3F3788F3E5
  • Current Calibration proxy version confirmed: 3.2.0
cast call --rpc-url https://api.calibration.node.glif.io/rpc/v1 \
  -f 0x0000000000000000000000000000000000000000 \
  0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C \
  "owner()(address)"

cast call --rpc-url https://api.calibration.node.glif.io/rpc/v1 \
  0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C \
  "VERSION()(string)"
  • Current Mainnet proxy owner confirmed: 0x3569b2600877a9F42d9Ebdd205386F3F3788F3E5
  • Current Mainnet proxy version confirmed: 3.2.0
cast call --rpc-url https://api.node.glif.io/rpc/v1 \
  -f 0x0000000000000000000000000000000000000000 \
  0xBADd0B92C1c71d02E7d520f64c0876538fa2557F \
  "owner()(address)"

cast call --rpc-url https://api.node.glif.io/rpc/v1 \
  0xBADd0B92C1c71d02E7d520f64c0876538fa2557F \
  "VERSION()(string)"

If the owner is a SAFE or other contract owner, use tools/upgrade.sh to generate calldata for the owner workflow rather than broadcasting directly.

Current planned-upgrade slots checked during preparation: both Calibration and Mainnet are empty.

4. Draft Release Notes

  • Draft CHANGELOG.md release notes before deployment
    • Merged draft adds ## [3.4.0] - TBD in #272.
    • Replacement implementation addresses and verification links are drafted in #276.
    • Release date and active-proxy wording remain TBD until rollout execution.
    • Draft includes expected integration impact, constructor values, and caller changes before Calibration starts.

Calibration Rollout

  • Deploy the replacement PDPVerifier implementation to Calibration
    • Deployer: 0x2127C3a31F54B81B5E9AD1e29C36c420d3D6ecC5
    • Implementation: 0xd60b90f6D3C42B26a246E141ec701a20Dde2fA61
    • Deployment transaction: 0x0a74c8e5bdc0821bf17fd2b48ff4439ad7515d1477220bfdadc24dfbb592b68c
    • Supersedes earlier deployed/announced candidate 0x7BdDF92aaBA8a578C3F494729BfAC5190d84acda from commit a0ba1b0722625a7746b504ab1decb4f9febca1f2
export RPC_URL="https://api.calibration.node.glif.io/rpc/v1"
export KEYSTORE="..."
export PASSWORD="..."

forge create \
  --rpc-url "$RPC_URL" \
  --keystore "$KEYSTORE" \
  --password "$PASSWORD" \
  --broadcast \
  --chain-id 314159 \
  src/PDPVerifier.sol:PDPVerifier \
  --constructor-args \
  3 \
  10
  • Sanity-check VERSION() and immutable values on the Calibration implementation
    • VERSION() = "3.4.0"
    • getChallengeFinality() = 10
cast call --rpc-url "$RPC_URL" <IMPL> "VERSION()(string)"
cast call --rpc-url "$RPC_URL" <IMPL> "getChallengeFinality()(uint256)"
CONSTRUCTOR_ARGS=$(cast abi-encode "constructor(uint64,uint256)" \
  3 \
  10 | sed 's/^0x//')

forge verify-contract \
  --chain 314159 \
  --rpc-url "$RPC_URL" \
  --watch \
  --constructor-args "$CONSTRUCTOR_ARGS" \
  <IMPL> \
  src/PDPVerifier.sol:PDPVerifier

forge verify-contract \
  --chain-id 314159 \
  --verifier blockscout \
  --verifier-url "https://filecoin-testnet.blockscout.com/api/" \
  --force \
  --skip-is-verified-check \
  --watch \
  --constructor-args "$CONSTRUCTOR_ARGS" \
  <IMPL> \
  src/PDPVerifier.sol:PDPVerifier

filfox-verifier forge \
  <IMPL> \
  src/PDPVerifier.sol:PDPVerifier \
  --chain 314159
  • Calibration replacement planned-upgrade announcement payload generated

    • Notice window: 2880 epochs (~1 day)
    • afterEpoch = 3752744
    • Earliest eligible time: 2026-05-27 19:05 UTC / 21:05 Oslo
    • Target: 0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C
    • Value: 0
    • Data: 0xbd003827000000000000000000000000d60b90f6d3c42b26a246e141ec701a20dde2fa610000000000000000000000000000000000000000000000000000000000394328
    • Safe owner nonce reported by helper: 12
    • If the Safe UI asks whether to use the implementation ABI for the proxy, use the implementation ABI, but keep the transaction target as the proxy.
  • Stage the Calibration replacement planned-upgrade SAFE transaction

  • Execute the Calibration replacement planned-upgrade SAFE transaction

  • Confirm nextUpgrade() matches 0xd60b90f6D3C42B26a246E141ec701a20Dde2fA61 and 3752744 before execution

  • Wait until the chain reaches afterEpoch = 3752744

  • Calibration SAFE upgrade transaction payload generated

    • If SAFE/contract-owner helper changes are needed first: tools: support SAFE-owned PDP upgrades
ETH_RPC_URL="$RPC_URL" \
SAFE_ADDRESS="0x3569b2600877a9F42d9Ebdd205386F3F3788F3E5" \
PDP_VERIFIER_PROXY_ADDRESS="0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C" \
NEW_PDP_VERIFIER_IMPLEMENTATION_ADDRESS="<IMPL>" \
./tools/upgrade.sh

For legacy one-step upgrades, this prints:

  • target
  • value
  • data

If building the transaction via the Safe UI ABI form:

  • method: upgradeToAndCall(address,bytes)
  • newImplementation: <IMPL>
  • data: 0x8fd3ab80

0x8fd3ab80 is the calldata for migrate().

cast rpc --rpc-url https://api.calibration.node.glif.io/rpc/v1 \
  eth_getStorageAt \
  0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C \
  0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc \
  latest | sed 's/"//g' | sed 's/0x000000000000000000000000/0x/'

cast call --rpc-url https://api.calibration.node.glif.io/rpc/v1 \
  0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C \
  "VERSION()(string)"
  • Run lightweight read-only smoke tests on Calibration

Find a recent live dataset with active pieces:

RPC_URL="https://api.calibration.node.glif.io/rpc/v1"
PROXY="0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C"
NEXT=$(cast call --rpc-url "$RPC_URL" "$PROXY" "getNextDataSetId()(uint256)" | awk '{print $1}')

for id in $(seq $((NEXT-1)) -1 $((NEXT-20))); do
  live=$(cast call --rpc-url "$RPC_URL" "$PROXY" "dataSetLive(uint256)(bool)" "$id" 2>/dev/null || true)
  if [ "$live" = "true" ]; then
    active=$(cast call --rpc-url "$RPC_URL" "$PROXY" "getActivePieceCount(uint256)(uint256)" "$id" 2>/dev/null | awk '{print $1}' || true)
    if [ "$active" != "0" ]; then
      echo "SET_ID=$id ACTIVE=$active"
      break
    fi
  fi
done

Then run:

SET_ID=<live_set_id>
CID=$(cast call --rpc-url "$RPC_URL" "$PROXY" "getPieceCid(uint256,uint256)((bytes))" "$SET_ID" 0 | tr -d '()')

cast call --rpc-url "$RPC_URL" "$PROXY" \
  "getActivePieces(uint256,uint256,uint256)((bytes)[],uint256[],bool)" \
  "$SET_ID" 0 10

cast call --rpc-url "$RPC_URL" "$PROXY" \
  "getActivePiecesByCursor(uint256,uint256,uint256)((bytes)[],uint256[],bool)" \
  "$SET_ID" 0 10

cast call --rpc-url "$RPC_URL" "$PROXY" \
  "findPieceIdsByCid(uint256,(bytes),uint256,uint256)(uint256[])" \
  "$SET_ID" "($CID)" 0 10

Check that:

  • the old and new pagination calls agree

  • findPieceIdsByCid() returns the expected piece ID(s)

  • Smoke-test result:

    • Live set found: SET_ID=14018, active pieces: 1
    • getActivePieces() and getActivePiecesByCursor() both returned piece ID [0], CID 0x0155912023e6720a12cb2974215d562b2169d4b68b7dedd8cfdeb152c644e4e988972a0ca21a6a01, hasMore=false
    • findPieceIdsByCid() returned [0]
  • Post Calibration completion/update communication

    • If release notes need to be drafted or refreshed first: docs(changelog): draft v3.4.0 release notes
  • Confirm no blocker remains for Mainnet rollout

Mainnet Rollout

  • Calibration rollout completed successfully
  • Draft and send initial upgrade communication
    • If release notes need to be drafted or refreshed first: docs(changelog): draft v3.4.0 release notes
  • Deploy the replacement PDPVerifier implementation to Mainnet
    • Deployer: 0x2127C3a31F54B81B5E9AD1e29C36c420d3D6ecC5
    • Implementation: 0xb41A97FEDD2D9497C639A643ec75E56CbCeDe8BA
    • Deployment transaction: 0xbac2cdc4e823d77dae34241ccb5181c394b2556a000baf5403dce7f13056f184
    • Supersedes earlier deployed/announced candidate 0xd28a11D0a93F68f49EE1977a3e882Ef530B7603C from commit a0ba1b0722625a7746b504ab1decb4f9febca1f2
export RPC_URL="https://api.node.glif.io/rpc/v1"
export KEYSTORE="..."
export PASSWORD="..."

forge create \
  --rpc-url "$RPC_URL" \
  --keystore "$KEYSTORE" \
  --password "$PASSWORD" \
  --broadcast \
  --chain-id 314 \
  src/PDPVerifier.sol:PDPVerifier \
  --constructor-args \
  3 \
  150
  • Sanity-check VERSION() and immutable values on the Mainnet implementation
    • VERSION() = "3.4.0"
    • getChallengeFinality() = 150
cast call --rpc-url "$RPC_URL" <IMPL> "VERSION()(string)"
cast call --rpc-url "$RPC_URL" <IMPL> "getChallengeFinality()(uint256)"
CONSTRUCTOR_ARGS=$(cast abi-encode "constructor(uint64,uint256)" \
  3 \
  150 | sed 's/^0x//')

forge verify-contract \
  --chain 314 \
  --rpc-url "$RPC_URL" \
  --watch \
  --constructor-args "$CONSTRUCTOR_ARGS" \
  <IMPL> \
  src/PDPVerifier.sol:PDPVerifier

forge verify-contract \
  --chain-id 314 \
  --verifier blockscout \
  --verifier-url "https://filecoin.blockscout.com/api/" \
  --force \
  --skip-is-verified-check \
  --watch \
  --constructor-args "$CONSTRUCTOR_ARGS" \
  <IMPL> \
  src/PDPVerifier.sol:PDPVerifier

filfox-verifier forge \
  <IMPL> \
  src/PDPVerifier.sol:PDPVerifier \
  --chain 314
  • Mainnet replacement planned-upgrade announcement payload generated

    • Notice window: 2880 epochs (~1 day)
    • afterEpoch = 6053410
    • Earliest eligible time: 2026-05-27 19:05 UTC / 21:05 Oslo
    • Target: 0xBADd0B92C1c71d02E7d520f64c0876538fa2557F
    • Value: 0
    • Data: 0xbd003827000000000000000000000000b41a97fedd2d9497c639a643ec75e56cbcede8ba00000000000000000000000000000000000000000000000000000000005c5e22
    • Safe owner nonce reported by helper: 8
    • If the Safe UI asks whether to use the implementation ABI for the proxy, use the implementation ABI, but keep the transaction target as the proxy.
  • Stage the Mainnet replacement planned-upgrade SAFE transaction

  • Execute the Mainnet replacement planned-upgrade SAFE transaction

  • Confirm nextUpgrade() matches 0xb41A97FEDD2D9497C639A643ec75E56CbCeDe8BA and 6053410 before execution

  • Wait until the chain reaches afterEpoch = 6053410

  • Mainnet SAFE upgrade transaction payload generated

    • If SAFE/contract-owner helper changes are needed first: tools: support SAFE-owned PDP upgrades
ETH_RPC_URL="$RPC_URL" \
SAFE_ADDRESS="0x3569b2600877a9F42d9Ebdd205386F3F3788F3E5" \
PDP_VERIFIER_PROXY_ADDRESS="0xBADd0B92C1c71d02E7d520f64c0876538fa2557F" \
NEW_PDP_VERIFIER_IMPLEMENTATION_ADDRESS="<IMPL>" \
./tools/upgrade.sh

If building the Safe transaction with ABI inputs:

  • method: upgradeToAndCall(address,bytes)

  • newImplementation: <IMPL>

  • data: 0x8fd3ab80

  • Mainnet implementation address, verification links, calldata, and rollout notes shared for independent review

  • Stage the Mainnet SAFE transaction

  • Collect SAFE signer approvals

  • Confirm the Mainnet execution date/time

  • Execute the Mainnet SAFE upgrade transaction: https://filecoin.blockscout.com/tx/0x07407b3becb1786e3b4217bfb5774d155d91d9688b0800fe5740689a72c4ed10

  • Verify the Mainnet proxy implementation slot: 0xb41a97fedd2d9497c639a643ec75e56cbcede8ba

  • Verify the Mainnet proxy is on v3.4.0

cast rpc --rpc-url https://api.node.glif.io/rpc/v1 \
  eth_getStorageAt \
  0xBADd0B92C1c71d02E7d520f64c0876538fa2557F \
  0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc \
  latest | sed 's/"//g' | sed 's/0x000000000000000000000000/0x/'

cast call --rpc-url https://api.node.glif.io/rpc/v1 \
  0xBADd0B92C1c71d02E7d520f64c0876538fa2557F \
  "VERSION()(string)"
  • Run lightweight read-only smoke tests on Mainnet
  • Smoke-test result:
    • Live set found: SET_ID=1205, active pieces: 1
    • getActivePieces() and getActivePiecesByCursor() both returned piece ID [0], CID 0x015591202580dd8d6918ec7f1c3cd60a5f809e41cc81d9caa5234236a0b81350bc40ee046c1d89e47a1a, hasMore=false
    • findPieceIdsByCid() returned [0]
  • Publish completion/update communication

Release Closeout

git tag -a v3.4.0 -m "v3.4.0"
git push origin v3.4.0
  • Update CHANGELOG.md release date, deployed addresses, verification links, deployment transactions, and deploy commit
  • Finalize release notes on main
    • Suggested PR title: docs(changelog): finalize v3.4.0 release notes
  • Prefer Blockscout links in the deployed-address section because they give a better verification view than Filfox.
  • Sync PDPVerifier source, ABI, and deployments in filecoin-services: chore: sync PDPVerifier v3.4.0 release filecoin-services#489
  • Create follow-up issue in fwss-subgraph: Audit PDPVerifier v3.4.0 downstream impact FIL-Builders/fwss-subgraph#4
  • Close this rollout issue
    • If the issue template needs improvement afterward: docs: update PDPVerifier upgrade issue template

Deployment / Verification Details

Fill these in as comments or update them here once known.

Calibration

Mainnet

Suggested Comment Cadence

Recommended issue comments to post as the rollout progresses:

  1. Deploy commit and Calibration constructor values
  2. Calibration implementation deployment output
  3. Calibration verification links and SAFE transaction review request
  4. Calibration execution transaction link and smoke-test results
  5. Mainnet implementation deployment output
  6. Mainnet verification links and SAFE transaction review request
  7. Scheduled Mainnet execution window
  8. Mainnet execution transaction link and post-upgrade verification
  9. Release-closeout links (CHANGELOG, tag, filecoin-services, fwss-subgraph)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

Status
🎉 Done
Status
🎉 Done

Relationships

None yet

Development

No branches or pull requests

Issue actions