Skip to content

[Release] FWSS v1.4.0 Mainnet Upgrade (includes Calibnet) #588

Description

@github-actions

Note

This is part of the "202608 FOC Release": #597

Overview

Field Value
Stack Version v1.4.0
Upgrade Type Breaking Change
Release-prep PR(s) #598
Technical Owner @Kubuxu
Go/No-Go Status No-Go — Calibnet FWSS announcement payload prepared; Safe execution waits for coordinated PDP Calibration rollout

Start here: Work through the Release Checklist from Phase 1. Expand the supporting sections below only when you need their context or evidence tables.

Release tracking and rollout records — tags, versions, deployment snapshots, schedule, and transaction evidence

Release Tracking

The filecoin-services GitHub release version is the stack version. It may differ from an individual contract VERSION() when the stack changes without an FWSS code change.

Item Value
Frozen deploy commit 4cbbea4a4f7da51ad674a1d9d122c6e677acfbec
Release branch release-v1.4.0 at 4cbbea4a4f7da51ad674a1d9d122c6e677acfbec
Phase 1 dry-runs Calibnet and Mainnet, both successful at 4cbbea4a4f7da51ad674a1d9d122c6e677acfbec; technical-owner dispositions approved
Phase 2 candidate deployments Frozen-tag preflights: Calibnet, Mainnet. Live candidate deployments and metadata verification: Calibnet, Mainnet.
GitHub pre-release FWSS v1.4.0
Release status Pre-release until Mainnet proxy switch is verified
deployments.json PR(s) TBD
Synapse SDK PR Phase 1 automation run 32501226593 generated the v1.4.0 ABI/types but failed its integration build before opening a PR because Synapse still references the removed piece-metadata getters. Phase 1 automation exception recorded; required downstream work remains tracked in FilOzone/synapse-sdk#917, assigned to @hugomrdias.

Field ownership for duplicated rollout data:

Data Source of truth Mirror/update
Operator status, owner decisions, exceptions, and in-progress tx/check evidence This release issue: Release Tracking and Run Log Mirror externally useful rollout status to the GitHub Release page
Live contract state Chain state read from the FWSS proxy, implementation slot, and View contract Record observed values in the Run Log and use them for go/no-go
Consumer-facing release status, addresses, epochs, and tx links GitHub Release page Populate from the Run Log as rollout facts become final
Repo deployment snapshot service_contracts/deployments.json on main Update by follow-up PR(s) only after the relevant proxy and View switches are live

Component Versions

Component Version Changed? Notes
Stack (filecoin-services) v1.4.0 Yes Git tag / GitHub Release
FilecoinWarmStorageService 1.4.0 Yes Breaking implementation upgrade; VERSION() bump in #598
PDPVerifier 3.5.0 Yes Independent PDP rollout tracked in FilOzone/pdp#304; integration baseline updated in #596

Upgrade Schedule

Network Requested delay Actual AFTER_EPOCH Status
Calibnet 2880 epochs (~24h) TBD Pending
Mainnet TBD TBD Pending

Set the requested delay before proposing the Safe transaction. Fill in the actual AFTER_EPOCH from nextUpgrade() after the announcement executes. The observed value is the source of truth for the execute step and external communications.

Run Log

The Run Log is this release issue's operator journal for rollout facts discovered during execution: deployed addresses, transaction links, validation outputs, exceptions, and owner decisions.

Keep this table current as values become known.

Network New FWSS implementation StateView / setView tx Announce tx Actual afterEpoch Execute tx Post-upgrade checks
Calibnet 0xF5436B44354735588B20CA18F7D3e95a14FAcA10 Candidate View 0x1B68d64f01bAa42014B9774605867BF4eDC0320f; setView pending TBD TBD TBD Candidate deployment and verification complete; proxy unchanged
Mainnet 0xa874C7333c8e1689C33155AD7bEE980926086e21 Candidate View 0xcf184Ab1FD8D1a563054d30Aa1fFb08136998172; setView pending TBD TBD TBD Candidate deployment and verification complete; proxy unchanged

Candidate Deployment Evidence

All candidates were deployed from frozen tag v1.4.0. The deployment workflows' ephemeral metadata passed verify-deployments.sh; no repository deployments.json update is published until the proxy and View switches are live. Direct calls return VERSION() = 1.4.0 on both FWSS candidates, and each StateView's service() points to the expected existing FWSS proxy.

Network Component Address Creation transaction Source verification
Calibnet SignatureVerificationLib 0xa3c88DD6510f88747742482f0963Bb5aE670b022 0xb191…8358 Sourcify exact match; Blockscout verified
Calibnet Rails 0xee2407847A4ccDdBB7eA6F188F19e998F0c92C2a 0x1f19…e51e Sourcify exact match; Blockscout verified
Calibnet FilecoinWarmStorageService 0xF5436B44354735588B20CA18F7D3e95a14FAcA10 0x1ddd…7912 Sourcify exact match; Blockscout verified
Calibnet FilecoinWarmStorageServiceStateView 0x1B68d64f01bAa42014B9774605867BF4eDC0320f 0x2bbd…b8c2 Sourcify exact match; Blockscout verified
Mainnet SignatureVerificationLib 0x63904443e46cc9F3db35CB4Fe16c76E7ffCA453e 0x9a7e…c3ae Sourcify exact match; Blockscout verified
Mainnet Rails 0x54aC29E68B3C7C5F7F315CeF1a85ECA848B88a9b 0x9cbe…5998 Sourcify exact match; Blockscout verified
Mainnet FilecoinWarmStorageService 0xa874C7333c8e1689C33155AD7bEE980926086e21 0x1d9e…af75 Sourcify exact match; Blockscout verified
Mainnet FilecoinWarmStorageServiceStateView 0xcf184Ab1FD8D1a563054d30Aa1fFb08136998172 0xc42d…70e9 Sourcify exact match; Blockscout verified

FilFox verification was attempted for all eight candidates and returned Unknown verification error; Sourcify and Blockscout verification succeeded. ABI publishing decision: the v1.4.0 tag already publishes the updated FWSS and StateView ABIs; the linked libraries expose no separate consumer ABI, so no additional ABI artifact is required.

Prepared StateView Owner Actions

Generated with CALLDATA_ONLY=true; not staged or executed. Execute each only after the corresponding FWSS proxy upgrade unless the technical owner changes the approved ordering.

Network Target Value Calldata
Calibnet 0x02925630df557F957f70E112bA06e50965417CA0 0 0x7f6330a10000000000000000000000001b68d64f01baa42014b9774605867bf4edc0320f
Mainnet 0x8408502033C418E1bbC97cE9ac48E5528F371A9f 0 0x7f6330a1000000000000000000000000cf184ab1fd8d1a563054d30aa1ffb08136998172
Scope and validation plan — cross-repo impact, dependencies, rollback, and pre-live evidence

Scope

  • In scope: FilecoinWarmStorageService implementation upgrade behind the existing FWSS proxy, plus the metadata-selected SignatureVerificationLib, Rails, and FilecoinWarmStorageServiceStateView companion deployments.
  • Out of scope: ServiceProviderRegistry, PDPVerifier deployment or proxy upgrade, FilecoinPay, and SessionKeyRegistry. PDPVerifier v3.5.0 is staged and upgraded independently through FilOzone/pdp#304 while the FWSS release preserves the existing PDP proxy address.

StateView scope exception

The technical owner approved including the metadata-selected FilecoinWarmStorageServiceStateView deployment on both networks. Each new View is verified with the other candidates and switched through a separate Safe setViewContract transaction after the corresponding FWSS proxy upgrade.

Cross-Repo Impact

Check every pre-seeded row and list each required cross-repo change or release. Use None only after the technical owner confirms there is no required change for that repository.

Repository Required change, PR, issue, or release Required before Mainnet? Owner/Status
FilOzone/synapse-sdk #928 required pricing update and future insufficient-balance warning; #917 removal of piece-metadata getters Yes Open; #928 unassigned, #917 assigned to @hugomrdias
FilOzone/pdp v3.5.0 rollout #304 Yes Rollout in progress
filecoin-project/curio #1440 PiecesAddedV2; #1422 removal processing Yes Open; #1440 assigned to @snadrus, #1422 assigned to @ZenGround0 and @LexLuthr
FilOzone/filecoin-cloud Phase 5 generated deployment-address update No Pending final deployment state
filecoin-project/filecoin-pin #668 remove piece-metadata reads No Open; tracked follow-up

Dependency Targets and Compatibility

Populate this table while reviewing the Phase 1 deployment inventory. The dry-run supplies the observed addresses and pinned deployment-metadata comparison; the technical owner records the compatibility disposition for every changed pinned component before approving the inventory.

Dependency Target version/address Calibnet observed Mainnet observed Verification/status
PDPVerifier v3.5.0 via existing proxies: Calibnet 0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C; Mainnet 0xBADd0B92C1c71d02E7d520f64c0876538fa2557F Proxy live at v3.4.0; recorded implementation 0xd60b90f6D3C42B26a246E141ec701a20Dde2fA61 Proxy live at v3.4.0; recorded implementation 0xb41A97FEDD2D9497C639A643ec75E56CbCeDe8BA Pinned/preserved candidate drift approved as compatible. The v3.5.0 proxy upgrades are staged independently and concurrently through FilOzone/pdp#304; this FWSS stack run must not deploy PDPVerifier. Perform each frozen-tag FWSS preflight and candidate deployment before that network's PDP proxy switch, or update the release candidate metadata and rerun both plans before freezing if PDP switches first.
FilecoinPay Preserve current live contract 0x09a0fDc2723fAd1A7b8e3e00eE5DF73841df55a0 0x23b1e018F08BB982348b15a86ee926eEBf7F4DAa Pinned/preserved candidate initcode drift approved as compatible. FilecoinPay remains out of scope and no FilecoinPay deployment is planned. Evidence: unchanged dependency commit since v1.3.1, matching live FWSS dependency getters, and passing foc-devnet/integration tests.
ServiceProviderRegistry Preserve current live proxy 0x839e5c9988e4e9977d40708d0094103c0839Ac9D 0xf55dDbf63F1b55c3F1D4FA7e339a68AB7b64A5eB Implementation metadata is up to date on both networks; existing proxies are preserved.
SessionKeyRegistry Preserve current live address 0x518411c2062E119Aaf7A8B12A2eDf9a939347655 0x74FD50525A958aF5d484601E252271f9625231aB Existing addresses are preserved on both networks.

Phase 1 Deployment Inventory

Both plans completed successfully from the release candidate without loading a deployer key or broadcasting transactions.

Component Calibnet plan Mainnet plan Technical-owner disposition
SessionKeyRegistry Using existing Using existing Preserve; out of scope
FilecoinPay Pinned/preserved; candidate initcode drift Pinned/preserved; candidate initcode drift Preserve; candidate drift approved as compatible
PDPVerifier implementation Pinned/preserved; candidate initcode drift Pinned/preserved; candidate initcode drift Preserve in this stack; compatibility approved; upgrade independently and concurrently through PDP rollout #304
PDPVerifier proxy Using existing Using existing Preserve address; coordinate ordering with the independent PDP proxy switch
ServiceProviderRegistry implementation Up to date Up to date Preserve; out of scope
ServiceProviderRegistry proxy Using existing Using existing Preserve
SignatureVerificationLib Would deploy Would deploy Expected companion deployment for v1.4.0
Rails Would deploy Would deploy Expected companion deployment for v1.4.0 pricing changes
FilecoinWarmStorageService implementation Would deploy Would deploy Expected v1.4.0 deployment
FilecoinWarmStorageService proxy Using existing Using existing Preserve
FilecoinWarmStorageServiceStateView Would deploy; separate Safe setViewContract required Would deploy; separate Safe setViewContract required Include in v1.4.0 scope; deploy and verify, then switch after the corresponding FWSS proxy upgrade
Endorsements ProviderIdSet Using existing Using existing Preserve

Initializer counters observed:

Network PDP current/next SPR current/next FWSS current/next
Calibnet 3 / 4 3 / 4 9 / 10
Mainnet 3 / 4 3 / 4 5 / 6

Rollback Plan

State whether rollback is safe before any live announce transaction. Link the approved rollback procedure or script when available.

Field Value
Rollback status Unsafe after v1.4 state-changing use
Previous FWSS implementation Calibnet 0x51bc9fb1e20280d57460a0a69a7077a9682aa164; Mainnet 0x3583e9fc40243924c6f8ebe3d17e5364bb6a01a9 (live ERC-1967 implementation slots checked before rollout)
Rollback procedure/script Not applicable after v1.4 state-changing use; mitigation is a reviewed forward fix. A rollback before any v1.4 state-changing transaction is only a narrow emergency option and requires a fresh state review.
Decision notes v1.4 adds authorizer-controlled state and changes payment rates and lifecycle-reserve behavior. Rolling back after those paths are used can restore older authorization semantics or apply older pricing logic to state touched under v1.4.

Pre-Live Validation

Record validation that proves the planned upgrade works against the full contract, Curio, and Synapse state before live rollout.

Validation Evidence/status
foc-devnet post-upgrade state validation Passed: FilOzone/foc-devnet#180. With upgraded pricing, the pre-funded sim-user wallets did not contain enough USDFC for the second copy. Increasing their USDFC balance allowed the run to complete successfully; this was a test-fixture funding issue, not an FWSS upgrade failure. FilOzone/synapse-sdk#928 was independently required for the pricing change and will add a future insufficient-balance warning.
Pricing validation Passed locally: forge test --match-contract PriceListTest completed with 132 passed, 0 failed. The getPriceList() round-trip tests cover rates, operation fees, lockups, and token wiring. Intended v1.4.0 values are 2.5 USDFC/TiB/month, 0.12 USDFC/data set/month, create 0.025, add 0.008 + 0.003/piece, schedule removal 0.007, terminate 0.006, lifecycle reserve 0.50, and replenish threshold 0.025 USDFC.
Synapse SDK integration build Phase 1 early signal failed as expected in workflow run 32501226593: regenerated v1.4.0 types remove getPieceMetadata and getAllPieceMetadata, while Synapse mocks, helpers, and tests still reference them. The workflow stops before pushing a branch or opening a PR. Automation exception recorded with owner @hugomrdias via FilOzone/synapse-sdk#917; the integration fix and passing build remain required before Mainnet.
Operator reference — network constants, operating rules, notice guidance, and required post-upgrade evidence

Network Constants

Network Chain ID RPC URL FWSS Proxy Safe Owner
Calibnet 314159 https://api.calibration.node.glif.io/rpc/v1 0x02925630df557F957f70E112bA06e50965417CA0 0x6386622B4915B027900d65560b0ab84F8a1ff2AA
Mainnet 314 https://api.node.glif.io/rpc/v1 0x8408502033C418E1bbC97cE9ac48E5528F371A9f 0x6386622B4915B027900d65560b0ab84F8a1ff2AA

Operating Rules

  • Use the release issue as the rollout source of truth. Keep the schedule, Run Log, tx links, and post-upgrade evidence current.
  • Create the stack tag and GitHub Release before any live proxy switch. Mark the GitHub Release as a pre-release until Mainnet is complete and verified.
  • Keep the GitHub pre-release page updated as the external rollout tracker for consumers; keep this issue updated as the operator runbook.
  • Keep CHANGELOG focused on what changed. Put mutable deployment status, addresses, epochs, and transaction links on the GitHub Release page.
  • Tag semantics: The vX.Y.Z tag is immutable and points to the frozen deploy commit used for contract deployment and bytecode verification. Post-deploy rollout facts such as live addresses, epochs, tx links, and deployments.json follow-up PRs are not folded back into the tag. They live on main, the release issue Run Log, and the GitHub Release page. Do not create a second "final release" tag.
  • Where to find what: Use the vX.Y.Z tag for the source that produced the deployed bytecode. Use on-chain reads from the FWSS proxy for live state, including the implementation slot and address getters such as viewContractAddress(), pdpVerifierAddress(), paymentsContractAddress(), serviceProviderRegistry(), sessionKeyRegistry(), usdfcTokenAddress(), and filBeamBeneficiaryAddress(). Use the GitHub Release rollout table for the historical record of what was live for this release.
  • service_contracts/deployments.json on a release branch or vX.Y.Z tag is the copy that existed at branch-cut/tag time and may be stale after Calibnet/Mainnet proxy or View switches. Do not use it as live state. Update deployments.json on main through the follow-up PR flow, but treat chain state and linked execute transactions as the live verification source.
  • The technical owner owns the written upgrade plan, dependency target verification, and final go/no-go decision.
  • Before any live announce transaction, fill in the Technical Owner, Cross-Repo Impact, Dependency Targets and Compatibility, Rollback Plan, and foc-devnet validation status.
  • Generate owner-action calldata with CALLDATA_ONLY=true and submit it through Safe Transaction Builder.
  • In Safe Transaction Builder, use the script output exactly: target is the printed FWSS proxy, value is 0, and data is the printed calldata.
  • Do not announce Mainnet until Calibnet execution, on-chain checks, explorer checks, smoke/E2E checks, and filecoin-pin Data Set creation validation are complete.
  • Do not announce Mainnet until required cross-repo changes are merged/released or explicitly waived by the technical owner.
  • service_contracts/deployments.json reflects what is live behind proxies and View contracts. Update it only after the relevant proxy switch and, if applicable, View switch are complete, normally through follow-up PR(s) to main, and record PR links in Release Tracking.
  • The requested delay starts when the Safe announcement executes. After execution, verify both fields returned by nextUpgrade() and record its exact afterEpoch as the source of truth.
  • A later announcement replaces the pending plan. Record the replacement transaction and explicitly mark it as superseding the previous announcement.

Notice Guidance

Upgrade Type Minimum Notice Recommended
Routine 2880 epochs (~24h) 1-2 days
Breaking change 20160 epochs (~1 week) 1-2 weeks

Calibnet can use a shorter window for rehearsal and validation, but use enough time for signers to coordinate. Select a positive operational delay; the contract's one-epoch floor is an emergency safety bound, not the routine notice policy.

export UPGRADE_DELAY_EPOCHS=2880 # use 240+ for Calibnet rehearsal, 20160 for breaking changes
echo "Requested upgrade delay: $UPGRADE_DELAY_EPOCHS epochs"

Post-Upgrade Evidence Required

For each network, record evidence that:

  • FWSS proxy implementation slot equals the new implementation address.
  • VERSION() returns the expected FWSS contract version without the leading v.
  • nextUpgrade() is cleared.
  • Blockscout shows the proxy and transaction as expected.
  • A smoke/E2E test passes. The v1.2.0 rollout used the Synapse SDK storage E2E example.
  • A filecoin-pin add flow succeeds after the upgrade with unique Data Set metadata, forcing creation of a new Data Set on the target network. Record the command output, metadata, Data Set ID, tx/link, SP, and timestamp in the Run Log.
Release notes and integrator action — summary of changes and any required downstream action

Changes

  • Added optional per-data-set programmable authorization through IDataSetAuthorizer.
  • Moved newly added piece metadata off-chain; integrations must consume PieceAdded events or an indexer.
  • Recalibrated proving, add-pieces, removal, termination, and lifecycle-reserve pricing for FIP-0115 gas conditions.
  • Allowed compact empty piece-metadata arrays in addPieces.
  • Increased FWSS extraData limits for programmable ACL payloads.
  • Updated the PDPVerifier integration baseline and published ABI for v3.5.0.

Action Required for Integrators

  • Stop calling the removed piece-metadata state-view getters. Index PieceAdded events where piece metadata is required.
  • Account for the new operation fees and lifecycle-reserve target. Existing data sets adopt the new proving rate on their next rate-touching operation and may require additional FilecoinPay funds.
  • Integrations using programmable data-set authorizers must support the expanded authorization payloads and authorizer-only mutation rules.

Release Checklist

Work through the phases in order. Do not announce Mainnet until the Calibnet execute transaction, on-chain checks, smoke/E2E test, and filecoin-pin Data Set creation validation are complete.

Phase 1: Issue, PR, Branch, and Checks

  • Create the release issue by running the Create Release Issue workflow from main. Do this before the remaining release-prep and branch steps so the generated issue tracks the complete process.
  • All intended FWSS contract changes are merged into main
  • Release-prep PR(s) opened for review (prefer one PR when practical) with changelog/release notes, a Deployment note linking to the GitHub Release page for rollout status, addresses, and transaction links, and any applicable version/submodule bump. For FWSS contract changes, include the FilecoinWarmStorageService VERSION() bump. For PDP-only stack releases, use the PDP/submodule bump PR and leave the FWSS VERSION() unchanged. Suggested title: chore: prep FWSS v1.4.0 release
  • Upgrade checks run:
cd service_contracts
forge test --match-contract FilecoinWarmStorageServiceUpgradeTest
forge inspect src/FilecoinWarmStorageService.sol:FilecoinWarmStorageService storageLayout --extra-output storageLayout
  • Release-prep PR(s) merged so main contains the final release notes and applicable version/submodule changes before creating the release branch
  • Create the release branch from main after the release-prep PR(s) land (recommended: release-v1.4.0), then record its name and commit in the existing release issue. Do not create a second release issue.
  • Name the technical owner, update the Overview, and confirm they own the written upgrade plan and go/no-go decision
  • Run and obtain technical-owner approval of the complete Phase 1 two-network deployment inventory:
    • From the release candidate, run the Deploy Contract workflow for both Calibnet and Mainnet with contract=Warm Storage stack and dry_run=true.
    • Populate Dependency Targets and Compatibility from the results and review every Would deploy, Up to date, Using existing, and Pinned/preserved result.
    • Add a pinned component with candidate drift; explicit review required to the rollout scope or explicitly approve it as compatible while preserved.
    • Stop, correct the release ref or deployment metadata, and rerun both plans for any unapproved difference.
  • Fill Cross-Repo Impact with required PRs, issues, releases, or None
  • Fill Rollback Plan, including whether rollback is safe and the approved procedure/script link when available
  • Run foc-devnet post-upgrade state validation, or record the technical owner's approved exception
  • Freeze the deploy commit and record it in Release Tracking
  • Create and push the stack tag from the frozen deploy commit before any live proxy switch:
git tag v1.4.0
git push origin v1.4.0
  • Create the GitHub Release from v1.4.0, mark it as a pre-release, and include component versions plus a FWSS rollout status table:
GitHub Release creation commands
export RELEASE_ISSUE_URL="https://github.com/FilOzone/filecoin-services/issues/588"

cat > /tmp/fwss-release-notes.md <<'EOF'
> Status: Pre-release. Calibnet and Mainnet rollout pending; tracked in [the release issue](RELEASE_ISSUE_URL).

## Summary
- FWSS v1.4.0 adds programmable data-set authorization, moves newly added piece metadata off-chain, recalibrates pricing and lifecycle reserves, supports compact empty piece metadata, and expands programmable ACL payload limits.

## Component Versions

| Component | Version | Notes |
|---|---|---|
| Stack (`filecoin-services`) | `v1.4.0` | Git tag / GitHub Release |
| `FilecoinWarmStorageService` | `1.4.0` | Breaking implementation upgrade |
| `PDPVerifier` | `3.5.0` | Independent rollout tracked in [FilOzone/pdp#304](https://github.com/FilOzone/pdp/issues/304) |

## Rollout Status

| Network | FWSS Proxy | FWSS Implementation | StateView | Announce tx | Actual `afterEpoch` | Execute tx | Status |
|---|---|---|---|---|---:|---|---|
| Calibnet | `0x02925630df557F957f70E112bA06e50965417CA0` | `TBD` | `TBD` | `TBD` | `TBD` | `TBD` | Pending |
| Mainnet | `0x8408502033C418E1bbC97cE9ac48E5528F371A9f` | `TBD` | `TBD` | `TBD` | `TBD` | `TBD` | Pending |

## Action Required For Integrators
- Stop calling removed piece-metadata getters and index `PieceAdded` events where metadata is required.
- Account for the new operation fees and lifecycle-reserve target; existing data sets may need additional FilecoinPay funds on their next rate-touching operation.
- Support programmable data-set authorizers and the expanded authorization payloads where used.
EOF

perl -0pi -e 's|RELEASE_ISSUE_URL|$ENV{RELEASE_ISSUE_URL}|g' /tmp/fwss-release-notes.md

gh release create v1.4.0 \
  --verify-tag \
  --prerelease \
  --title "FWSS v1.4.0" \
  --notes-file /tmp/fwss-release-notes.md
  • Confirm the Update Synapse SDK workflow opened or updated the expected Synapse SDK PR and that its integration build passes against the intended contract ABI/types and deployment-address state, or record an exception/owner in Release Tracking. This Phase 1 check is the early ABI/type signal; run the workflow again in Phase 5 after final deployment-address state exists.
  • Release issue Overview and Release Tracking updated with PR links, release link, summary, and action required

Phase 2: Deploy Contracts

Deploy both networks before any announce/execute.

  • Immediately before each live deployment, rerun the metadata-aware dry-run from the frozen release tag and confirm it exactly matches the Phase 1 approved inventory, including every pinned-drift disposition. Stop and return to scope review if it differs; do not change pins ad hoc during rollout.
  • Run the Deploy Contract workflow once per network from the same frozen tag with contract=Warm Storage stack and dry_run=false. The metadata-aware stack run deploys every approved changed, unpinned component in nonce order; do not select components manually or run separate FWSS/SPR deployment paths.
  • Run service_contracts/tools/verify-deployments.sh --chain <CHAIN> for each target network after deployment metadata is available. Resolve or explicitly waive any bytecode/metadata mismatch before live announce.
  • If linked libraries or StateView are newly deployed, record their addresses, verification status, and ABI-publishing decision in the Run Log.
Deployment metadata checks
cd service_contracts

ETH_RPC_URL="https://api.calibration.node.glif.io/rpc/v1" \
  ./tools/verify-deployments.sh --chain 314159

ETH_RPC_URL="https://api.node.glif.io/rpc/v1" \
  ./tools/verify-deployments.sh --chain 314

Use the deploy dry-run output to distinguish contracts that are Pinned/preserved, Up to date, or Would deploy. Pinned/preserved is a policy decision, not proof that candidate code is unchanged: the output reports whether the candidate matches recorded deployment metadata or requires explicit drift review. Record the approved deploy set and every preserve disposition before any live announce transaction.

Dry-run marks as needing deployment Operator action
SignatureVerificationLib, Rails, or FilecoinWarmStorageService The approved contract=Warm Storage stack live run deploys each changed, unpinned component automatically and records its address
ServiceProviderRegistry Only unpin in the reviewed release-prep PR when the release explicitly includes it; add an exception section to this issue, then let the approved contract=Warm Storage stack run deploy it
PDPVerifier, FilecoinPay, ProviderIdSet, or FilecoinWarmStorageServiceStateView If candidate metadata matches, keep pinned unless the release explicitly includes it. If candidate drift is reported, either expand the reviewed scope and unpin in the release ref or record the technical owner's compatibility approval for preserving the deployed version
SessionKeyRegistry Only deploy if explicitly included; use the dedicated contract=SessionKeyRegistry workflow option and add an exception section to this issue

Calibnet Warm Storage Stack

  • Complete the frozen-tag Calibnet drift check above, then rerun the same workflow inputs with dry_run=false
  • Capture CALI_NEW_IMPL, plus CALI_NEW_SPR_IMPL, new library addresses, and CALI_NEW_VIEW when those components are in the approved inventory, and add them to the Run Log
  • Verify every newly deployed contract on Sourcify and Blockscout
  • Attempt FilFox verification and record result

Mainnet Warm Storage Stack

  • Complete the frozen-tag Mainnet drift check above, then rerun the same workflow inputs with dry_run=false
  • Capture MAIN_NEW_IMPL, plus MAIN_NEW_SPR_IMPL, new library addresses, and MAIN_NEW_VIEW when those components are in the approved inventory, and add them to the Run Log
  • Verify every newly deployed contract on Sourcify and Blockscout
  • Attempt FilFox verification and record result
  • Add both FWSS implementation addresses and every companion SPR, library, or StateView candidate address to the GitHub pre-release rollout status. Do not update service_contracts/deployments.json until proxy slots are live.

Verification command pattern:

cd service_contracts

# Calibnet: use CALI_NEW_* values; Mainnet: use MAIN_NEW_* values.
export CHAIN=314159
export FWSS_IMPL="$CALI_NEW_IMPL"
export SPR_IMPL="${CALI_NEW_SPR_IMPL:-}"
export RAILS_IMPL="${CALI_NEW_RAILS:-}"

source tools/verify-contracts.sh

verify_candidate() {
  local address="$1"
  local artifact="$2"
  [ -z "$address" ] && return 0
  verify_sourcify "$address" "$artifact"
  verify_blockscout "$address" "$artifact"
  verify_filfox "$address" "$artifact"
}

verify_candidate "$FWSS_IMPL" "src/FilecoinWarmStorageService.sol:FilecoinWarmStorageService"
verify_candidate "$SPR_IMPL" "src/ServiceProviderRegistry.sol:ServiceProviderRegistry"
verify_candidate "$RAILS_IMPL" "src/lib/Rails.sol:Rails"

Repeat for every address in the approved live inventory, including a new StateView or other library when present. Supply explorer-specific constructor/library arguments when required, and record any verification failure or waiver in the Run Log.

Optional StateView Switch

  • If the stack deploy inventory includes a new FilecoinWarmStorageServiceStateView, confirm it was deployed by the approved live stack run; do not run a second StateView deployment
  • Capture CALI_NEW_VIEW and/or MAIN_NEW_VIEW, record the deployed StateView address and verification status in the Run Log, and add the StateView address to the GitHub pre-release rollout table
  • Generate setViewContract(address) calldata for each affected network and stage it in Safe UI. Execute the staged setViewContract transaction after the corresponding FWSS proxy upgrade execute transaction unless the technical owner approves a different ordering.
    • Calldata generated and recorded above; Safe staging remains pending.
  • After each setViewContract transaction lands, record its tx link in the Run Log and verify viewContractAddress() equals the new StateView address
StateView setViewContract calldata and verification
# Calibnet
cd service_contracts/tools
export ETH_RPC_URL="https://api.calibration.node.glif.io/rpc/v1"
export FWSS_PROXY_ADDRESS="0x02925630df557F957f70E112bA06e50965417CA0"
export FWSS_VIEW_ADDRESS="$CALI_NEW_VIEW"

CALLDATA_ONLY=true ./warm-storage-set-view.sh

CURRENT_VIEW=$(cast call --rpc-url "$ETH_RPC_URL" \
  "$FWSS_PROXY_ADDRESS" \
  'viewContractAddress()(address)')
echo "viewContractAddress(): $CURRENT_VIEW (expected $FWSS_VIEW_ADDRESS)"

# Mainnet
export ETH_RPC_URL="https://api.node.glif.io/rpc/v1"
export FWSS_PROXY_ADDRESS="0x8408502033C418E1bbC97cE9ac48E5528F371A9f"
export FWSS_VIEW_ADDRESS="$MAIN_NEW_VIEW"

CALLDATA_ONLY=true ./warm-storage-set-view.sh

CURRENT_VIEW=$(cast call --rpc-url "$ETH_RPC_URL" \
  "$FWSS_PROXY_ADDRESS" \
  'viewContractAddress()(address)')
echo "viewContractAddress(): $CURRENT_VIEW (expected $FWSS_VIEW_ADDRESS)"

In Safe Transaction Builder, set target to the printed FWSS proxy, value to 0, and data to the printed calldata.

Phase 3: Calibnet Announce + Execute

Announce

  • If this release has a ServiceProviderRegistry exception, generate its Calibnet announcement with NEW_SERVICE_PROVIDER_REGISTRY_IMPLEMENTATION_ADDRESS="$CALI_NEW_SPR_IMPL" UPGRADE_DELAY_EPOCHS=<delay> CALLDATA_ONLY=true ./service-provider-registry-announce-upgrade.sh, execute it through the owner Safe, then verify and record the exact implementation and observed afterEpoch returned by nextUpgrade() before any execute transaction. Not applicable: no ServiceProviderRegistry exception.

  • Set the Calibnet requested delay and update the schedule table.

  • Generate announce calldata and submit/sign/execute in Safe UI:

    • Payload generated and fork-simulated; Safe staging/signing/execution remains pending.
    • Target: 0x02925630df557F957f70E112bA06e50965417CA0
    • Value: 0
    • Function: announceUpgradePlan(address,uint96)
    • Candidate: 0xF5436B44354735588B20CA18F7D3e95a14FAcA10
    • Requested delay: 2880
    • Calldata: 0x7df6b5c3000000000000000000000000f5436b44354735588b20ca18f7d3e95a14faca100000000000000000000000000000000000000000000000000000000000000b40
    • Validation note: the live Filecoin RPC rejects eth_call with the contract Safe as sender (SysErrSenderInvalid). The immutable v1.4.0 helper was therefore run unchanged against an Anvil fork of current Calibnet state, where its owner simulation passed before encoding this payload. Live owner, current View, and cleared nextUpgrade() were independently checked.
cd service_contracts/tools
export ETH_RPC_URL="https://api.calibration.node.glif.io/rpc/v1"
export FWSS_PROXY_ADDRESS="0x02925630df557F957f70E112bA06e50965417CA0"
export NEW_FWSS_IMPLEMENTATION_ADDRESS="$CALI_NEW_IMPL"

Configure the requested delay:

export UPGRADE_DELAY_EPOCHS=240 # use a longer window if desired

Generate the transaction:

CALLDATA_ONLY=true ./warm-storage-announce-upgrade.sh
  • In Safe Transaction Builder, set target to the printed FWSS proxy, value to 0, and data to the printed calldata
  • After the Safe transaction executes, verify and read back the pending plan:
export ANNOUNCE_TX_HASH="0x..." # Safe execution transaction hash

CURRENT_VIEW=$(cast call --rpc-url "$ETH_RPC_URL" \
  "$FWSS_PROXY_ADDRESS" \
  'viewContractAddress()(address)')

UPGRADE_PLAN=($(cast call --rpc-url "$ETH_RPC_URL" \
  "$CURRENT_VIEW" \
  'nextUpgrade()(address,uint96)'))

OBSERVED_IMPL=${UPGRADE_PLAN[0]}
OBSERVED_AFTER_EPOCH=${UPGRADE_PLAN[1]}
echo "Planned implementation: $OBSERVED_IMPL (expected $CALI_NEW_IMPL)"
echo "Actual afterEpoch: $OBSERVED_AFTER_EPOCH"

ANNOUNCE_EPOCH=$(cast receipt --rpc-url "$ETH_RPC_URL" "$ANNOUNCE_TX_HASH" blockNumber)
EFFECTIVE_DELAY_EPOCHS=$UPGRADE_DELAY_EPOCHS
[ "$EFFECTIVE_DELAY_EPOCHS" -eq 0 ] && EFFECTIVE_DELAY_EPOCHS=1
EXPECTED_AFTER_EPOCH=$((ANNOUNCE_EPOCH + EFFECTIVE_DELAY_EPOCHS))

if [ "$(printf '%s' "$OBSERVED_IMPL" | tr '[:upper:]' '[:lower:]')" != "$(printf '%s' "$CALI_NEW_IMPL" | tr '[:upper:]' '[:lower:]')" ]; then
  echo "ERROR: announced implementation mismatch"
  exit 1
fi
if [ "$OBSERVED_AFTER_EPOCH" -ne "$EXPECTED_AFTER_EPOCH" ]; then
  echo "ERROR: afterEpoch mismatch ($OBSERVED_AFTER_EPOCH != $EXPECTED_AFTER_EPOCH)"
  exit 1
fi
  • Record the Calibnet announce tx and observed afterEpoch in the schedule and Run Log
  • Update the GitHub pre-release Calibnet rollout status with the announce tx and observed afterEpoch
  • Create or update the public operational notice on status.filecoin.cloud for the Calibration network before execution. Identify the network and scheduled date/window, link the GitHub pre-release, and keep the maintenance window open through expected post-upgrade validation. Follow the Operational Event Communications Runbook.

Execute

  • Wait for the observed Calibnet afterEpoch
  • If this release has a ServiceProviderRegistry exception, generate its Calibnet execution with NEW_SERVICE_PROVIDER_REGISTRY_IMPLEMENTATION_ADDRESS="$CALI_NEW_SPR_IMPL" NEW_VERSION=<version> CALLDATA_ONLY=true ./service-provider-registry-execute-upgrade.sh, execute it in the approved transaction order, then verify and record its implementation slot, VERSION(), initializer counter, preserved registry state, and cleared nextUpgrade()
  • Generate execute calldata and submit/sign/execute in Safe UI:
cd service_contracts/tools
export ETH_RPC_URL="https://api.calibration.node.glif.io/rpc/v1"
export FWSS_PROXY_ADDRESS="0x02925630df557F957f70E112bA06e50965417CA0"
export NEW_WARM_STORAGE_IMPLEMENTATION_ADDRESS="$CALI_NEW_IMPL"

CALLDATA_ONLY=true ./warm-storage-execute-upgrade.sh
  • In Safe Transaction Builder, set target to the printed FWSS proxy, value to 0, and data to the printed calldata
  • Record Calibnet execute tx link in the Run Log
  • Verify implementation slot equals CALI_NEW_IMPL
  • Verify VERSION() returns the expected FWSS contract version
  • Verify viewContractAddress() equals CALI_NEW_VIEW if a StateView switch was expected, or the unchanged View address otherwise
  • Verify nextUpgrade() is cleared
export ETH_RPC_URL="https://api.calibration.node.glif.io/rpc/v1"
export FWSS_PROXY_ADDRESS="0x02925630df557F957f70E112bA06e50965417CA0"
export EXPECTED_FWSS_IMPLEMENTATION_ADDRESS="$CALI_NEW_IMPL"
export EXPECTED_FWSS_VERSION="1.4.0"
export EXPECTED_FWSS_VIEW_ADDRESS="${CALI_NEW_VIEW:-unchanged}"

CURRENT_VIEW=$(cast call --rpc-url "$ETH_RPC_URL" \
  "$FWSS_PROXY_ADDRESS" \
  'viewContractAddress()(address)')
if [ "$EXPECTED_FWSS_VIEW_ADDRESS" = "unchanged" ]; then
  EXPECTED_FWSS_VIEW_ADDRESS="$CURRENT_VIEW"
fi

IMPLEMENTATION_SLOT=$(cast rpc --rpc-url "$ETH_RPC_URL" \
  eth_getStorageAt \
  "$FWSS_PROXY_ADDRESS" \
  0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc \
  latest | tr -d '"' | sed 's/^0x000000000000000000000000/0x/')

ACTUAL_VERSION=$(cast call --rpc-url "$ETH_RPC_URL" \
  "$FWSS_PROXY_ADDRESS" \
  'VERSION()(string)' | tr -d '"')

NEXT_UPGRADE=$(cast call --rpc-url "$ETH_RPC_URL" \
  "$CURRENT_VIEW" \
  'nextUpgrade()(address,uint96)')

echo "Implementation slot: $IMPLEMENTATION_SLOT (expected $EXPECTED_FWSS_IMPLEMENTATION_ADDRESS)"
echo "VERSION(): $ACTUAL_VERSION (expected $EXPECTED_FWSS_VERSION)"
echo "viewContractAddress(): $CURRENT_VIEW (expected $EXPECTED_FWSS_VIEW_ADDRESS)"
echo "nextUpgrade(): $NEXT_UPGRADE (expected zero address and 0)"

if [ "$(printf '%s' "$CURRENT_VIEW" | tr '[:upper:]' '[:lower:]')" != "$(printf '%s' "$EXPECTED_FWSS_VIEW_ADDRESS" | tr '[:upper:]' '[:lower:]')" ]; then
  echo "ERROR: viewContractAddress() mismatch"
  exit 1
fi
  • Verify FWSS pricing output, such as getPriceList(), matches the intended release pricing and record the command/output in the Run Log
  • Run and record a Calibnet smoke/E2E test result
  • Validate Calibnet Data Set creation through filecoin-pin add with --network calibration and unique --data-set-metadata, then record the command output, metadata, Data Set ID, tx/link, SP, and timestamp in the Run Log
Calibnet filecoin-pin validation
RUN_ID="fwss-v1.4.0-calibnet-$(date -u +%Y%m%dT%H%M%SZ)"
printf "FWSS v1.4.0 Calibnet smoke %s\n" "$RUN_ID" > "/tmp/$RUN_ID.txt"

filecoin-pin add "/tmp/$RUN_ID.txt" \
  --network calibration \
  --data-set-metadata fwss_release=v1.4.0 \
  --data-set-metadata smoke_run="$RUN_ID"

The unique smoke_run metadata is required so this validates new Data Set creation rather than reusing an existing Data Set.

  • Verify the proxy on Blockscout
  • Update the GitHub pre-release Calibnet rollout status with execute tx, checks, and smoke/E2E evidence
  • If Calibnet deployment addresses should be published before Mainnet, open or update a Calibnet-only follow-up PR to main for service_contracts/deployments.json after the Calibnet proxy switch and, if applicable, View switch are live, then record the PR link in Release Tracking. Otherwise record that the deployments.json update will wait for Mainnet.
  • Technical owner confirms Calibnet results are good before announcing Mainnet

Phase 4: Mainnet Announce + Execute

Announce

  • Technical owner records Mainnet go/no-go after reviewing Calibnet evidence, rollback status, dependency targets, and cross-repo status

  • Confirm required cross-repo changes are merged/released or explicitly waived by the technical owner

  • Create or update the public operational notice on status.filecoin.cloud for Mainnet before or alongside stakeholder notification. Identify the network and scheduled date/window, link the GitHub pre-release, and keep the maintenance window open through expected post-upgrade validation. Follow the Operational Event Communications Runbook.

  • Notify stakeholders before announcing Mainnet, including FilB so they can propagate the upgrade notice

  • If this release has a ServiceProviderRegistry exception, generate its Mainnet announcement with NEW_SERVICE_PROVIDER_REGISTRY_IMPLEMENTATION_ADDRESS="$MAIN_NEW_SPR_IMPL" UPGRADE_DELAY_EPOCHS=<delay> CALLDATA_ONLY=true ./service-provider-registry-announce-upgrade.sh, execute it through the owner Safe, then verify and record the exact implementation and observed afterEpoch returned by nextUpgrade() before any execute transaction.

  • Set the Mainnet requested delay and update the schedule table.

  • Generate announce calldata and submit/sign/execute in Safe UI:

cd service_contracts/tools
export ETH_RPC_URL="https://api.node.glif.io/rpc/v1"
export FWSS_PROXY_ADDRESS="0x8408502033C418E1bbC97cE9ac48E5528F371A9f"
export NEW_FWSS_IMPLEMENTATION_ADDRESS="$MAIN_NEW_IMPL"

Configure the requested delay:

export UPGRADE_DELAY_EPOCHS=2880 # use 20160 for breaking changes

Generate the transaction:

CALLDATA_ONLY=true ./warm-storage-announce-upgrade.sh
  • In Safe Transaction Builder, set target to the printed FWSS proxy, value to 0, and data to the printed calldata
  • After the Safe transaction executes, verify and read back the pending plan:
export ANNOUNCE_TX_HASH="0x..." # Safe execution transaction hash

CURRENT_VIEW=$(cast call --rpc-url "$ETH_RPC_URL" \
  "$FWSS_PROXY_ADDRESS" \
  'viewContractAddress()(address)')

UPGRADE_PLAN=($(cast call --rpc-url "$ETH_RPC_URL" \
  "$CURRENT_VIEW" \
  'nextUpgrade()(address,uint96)'))

OBSERVED_IMPL=${UPGRADE_PLAN[0]}
OBSERVED_AFTER_EPOCH=${UPGRADE_PLAN[1]}
echo "Planned implementation: $OBSERVED_IMPL (expected $MAIN_NEW_IMPL)"
echo "Actual afterEpoch: $OBSERVED_AFTER_EPOCH"

ANNOUNCE_EPOCH=$(cast receipt --rpc-url "$ETH_RPC_URL" "$ANNOUNCE_TX_HASH" blockNumber)
EFFECTIVE_DELAY_EPOCHS=$UPGRADE_DELAY_EPOCHS
[ "$EFFECTIVE_DELAY_EPOCHS" -eq 0 ] && EFFECTIVE_DELAY_EPOCHS=1
EXPECTED_AFTER_EPOCH=$((ANNOUNCE_EPOCH + EFFECTIVE_DELAY_EPOCHS))

if [ "$(printf '%s' "$OBSERVED_IMPL" | tr '[:upper:]' '[:lower:]')" != "$(printf '%s' "$MAIN_NEW_IMPL" | tr '[:upper:]' '[:lower:]')" ]; then
  echo "ERROR: announced implementation mismatch"
  exit 1
fi
if [ "$OBSERVED_AFTER_EPOCH" -ne "$EXPECTED_AFTER_EPOCH" ]; then
  echo "ERROR: afterEpoch mismatch ($OBSERVED_AFTER_EPOCH != $EXPECTED_AFTER_EPOCH)"
  exit 1
fi
  • Record the Mainnet announce tx and observed afterEpoch in the schedule and Run Log
  • Update the GitHub pre-release Mainnet rollout status with the announce tx and observed afterEpoch

Execute

  • Wait for the observed Mainnet afterEpoch
  • If this release has a ServiceProviderRegistry exception, generate its Mainnet execution with NEW_SERVICE_PROVIDER_REGISTRY_IMPLEMENTATION_ADDRESS="$MAIN_NEW_SPR_IMPL" NEW_VERSION=<version> CALLDATA_ONLY=true ./service-provider-registry-execute-upgrade.sh, execute it in the approved transaction order, then verify and record its implementation slot, VERSION(), initializer counter, preserved registry state, and cleared nextUpgrade()
  • Generate execute calldata and submit/sign/execute in Safe UI:
cd service_contracts/tools
export ETH_RPC_URL="https://api.node.glif.io/rpc/v1"
export FWSS_PROXY_ADDRESS="0x8408502033C418E1bbC97cE9ac48E5528F371A9f"
export NEW_WARM_STORAGE_IMPLEMENTATION_ADDRESS="$MAIN_NEW_IMPL"

CALLDATA_ONLY=true ./warm-storage-execute-upgrade.sh
  • In Safe Transaction Builder, set target to the printed FWSS proxy, value to 0, and data to the printed calldata
  • Record Mainnet execute tx link in the Run Log
  • Verify implementation slot equals MAIN_NEW_IMPL
  • Verify VERSION() returns the expected FWSS contract version
  • Verify viewContractAddress() equals MAIN_NEW_VIEW if a StateView switch was expected, or the unchanged View address otherwise
  • Verify nextUpgrade() is cleared
export ETH_RPC_URL="https://api.node.glif.io/rpc/v1"
export FWSS_PROXY_ADDRESS="0x8408502033C418E1bbC97cE9ac48E5528F371A9f"
export EXPECTED_FWSS_IMPLEMENTATION_ADDRESS="$MAIN_NEW_IMPL"
export EXPECTED_FWSS_VERSION="1.4.0"
export EXPECTED_FWSS_VIEW_ADDRESS="${MAIN_NEW_VIEW:-unchanged}"

CURRENT_VIEW=$(cast call --rpc-url "$ETH_RPC_URL" \
  "$FWSS_PROXY_ADDRESS" \
  'viewContractAddress()(address)')
if [ "$EXPECTED_FWSS_VIEW_ADDRESS" = "unchanged" ]; then
  EXPECTED_FWSS_VIEW_ADDRESS="$CURRENT_VIEW"
fi

IMPLEMENTATION_SLOT=$(cast rpc --rpc-url "$ETH_RPC_URL" \
  eth_getStorageAt \
  "$FWSS_PROXY_ADDRESS" \
  0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc \
  latest | tr -d '"' | sed 's/^0x000000000000000000000000/0x/')

ACTUAL_VERSION=$(cast call --rpc-url "$ETH_RPC_URL" \
  "$FWSS_PROXY_ADDRESS" \
  'VERSION()(string)' | tr -d '"')

NEXT_UPGRADE=$(cast call --rpc-url "$ETH_RPC_URL" \
  "$CURRENT_VIEW" \
  'nextUpgrade()(address,uint96)')

echo "Implementation slot: $IMPLEMENTATION_SLOT (expected $EXPECTED_FWSS_IMPLEMENTATION_ADDRESS)"
echo "VERSION(): $ACTUAL_VERSION (expected $EXPECTED_FWSS_VERSION)"
echo "viewContractAddress(): $CURRENT_VIEW (expected $EXPECTED_FWSS_VIEW_ADDRESS)"
echo "nextUpgrade(): $NEXT_UPGRADE (expected zero address and 0)"

if [ "$(printf '%s' "$CURRENT_VIEW" | tr '[:upper:]' '[:lower:]')" != "$(printf '%s' "$EXPECTED_FWSS_VIEW_ADDRESS" | tr '[:upper:]' '[:lower:]')" ]; then
  echo "ERROR: viewContractAddress() mismatch"
  exit 1
fi
  • Verify FWSS pricing output, such as getPriceList(), matches the intended release pricing and record the command/output in the Run Log
  • Run and record a Mainnet smoke/E2E test result
  • Validate Mainnet Data Set creation through filecoin-pin add with --network mainnet and unique --data-set-metadata, then record the command output, metadata, Data Set ID, tx/link, SP, and timestamp in the Run Log
Mainnet filecoin-pin validation
RUN_ID="fwss-v1.4.0-mainnet-$(date -u +%Y%m%dT%H%M%SZ)"
printf "FWSS v1.4.0 Mainnet smoke %s\n" "$RUN_ID" > "/tmp/$RUN_ID.txt"

filecoin-pin add "/tmp/$RUN_ID.txt" \
  --network mainnet \
  --data-set-metadata fwss_release=v1.4.0 \
  --data-set-metadata smoke_run="$RUN_ID"

The unique smoke_run metadata is required so this validates new Data Set creation rather than reusing an existing Data Set.

  • Verify the proxy on Blockscout
  • Update the GitHub pre-release Mainnet rollout status with execute tx, checks, and smoke/E2E evidence

Phase 5: Promote Release and Close Out

  • Confirm live Calibnet and Mainnet FWSS implementation slots match the new implementation addresses
  • Resolve or complete every public operational notice after the corresponding rollout and post-upgrade validation succeed. Publish a final status update and record each notice link and final state in Release Tracking.
  • Confirm cross-repo follow-ups are complete or tracked with owners
  • Open or update follow-up PR(s) to main for service_contracts/deployments.json after the relevant Calibnet/Mainnet proxy switches and, if applicable, View switches are live. Include live implementation addresses, View addresses, deployment bytecode metadata, and pdp_version / fwss_version fields for each updated network.
  • Record the service_contracts/deployments.json PR link(s) in Release Tracking, then merge after checksum validation, bytecode metadata verification, and live-slot verification
  • Verify final service_contracts/deployments.json bytecode metadata matches the live deployed contracts after all proxy and View switches are complete
Deployment bytecode metadata verification commands
cd service_contracts

# Calibnet
CHAIN=314159 ETH_RPC_URL="https://api.calibration.node.glif.io/rpc/v1" \
  ./tools/verify-deployments.sh

# Mainnet
CHAIN=314 ETH_RPC_URL="https://api.node.glif.io/rpc/v1" \
  ./tools/verify-deployments.sh
  • Merge release-prep PR(s) if still open, keeping mutable rollout details on the GitHub Release page
  • Promote the GitHub Release from pre-release to latest after Mainnet proxy switch, checks, and release-page status are complete
  • Publish or update required ABIs after linked-library or interface changes: run make -C service_contracts update-abi for checked-in service_contracts/abi updates, confirm the Synapse SDK workflow regenerated downstream ABI/types, and record any explicit linked-library ABI publishing target or None required
ABI update commands
make -C service_contracts update-abi
git status --short service_contracts/abi
  • Run the Update Synapse SDK workflow manually with the release tag and the approved source ref/SHA after the intended deployment address state is available, or record an exception/owner in Release Tracking. This Phase 5 run is the final address-state update and should not be skipped because the Phase 1 ABI/type signal already ran.
  • Merge auto-generated PRs in filecoin-cloud
  • Confirm Synapse PR/release is merged or owned
  • Capture lessons learned from this rollout and update service_contracts/tools/UPGRADE-CHECKLIST.md if the process should change
  • Add release link to this issue
  • Close this issue

Resources

Wall time: 0.58 seconds

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions