Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

## [1.4.0] - FWSS Breaking Upgrade

This contract-stack release upgrades FilecoinWarmStorageService (FWSS) to v1.4.0 and updates the PDPVerifier integration baseline to v3.5.0.

| Component | Version | Upgrade classification |
|---|---|---|
| Stack (`filecoin-services`) | `v1.4.0` | Breaking |
| `FilecoinWarmStorageService` | `1.4.0` | Breaking implementation upgrade |
| `PDPVerifier` | `3.5.0` | Independent dependency upgrade |

### Deployment / Rollout Status

Rollout status, network-by-network implementation addresses, announcement and execution epochs, transaction links, and validation evidence are tracked on the [v1.4.0 GitHub Release](https://github.com/FilOzone/filecoin-services/releases/tag/v1.4.0). The FWSS proxy addresses remain unchanged.

### Breaking Changes

- Newly added piece metadata is no longer persisted in FWSS contract storage and must instead be indexed from `PieceAdded` events. The `getPieceMetadata` and `getAllPieceMetadata` helpers have been removed from `FilecoinWarmStorageServiceStateView`, the state library, and their published ABIs. Existing on-chain piece metadata remains eligible for cleanup when pieces are removed ([#577](https://github.com/FilOzone/filecoin-services/pull/577)).
Expand All @@ -22,6 +36,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

- Increased FWSS `extraData` limits to support programmable ACL payloads: data-set creation increased from 4 KiB to 5 KiB, while removal scheduling and service termination increased from 256 bytes to 1 KiB ([#560](https://github.com/FilOzone/filecoin-services/pull/560)).

- Updated the PDPVerifier dependency and published ABI for the v3.5.0 integration surface ([#596](https://github.com/FilOzone/filecoin-services/pull/596)).

### Upgrade Notes

- The new one-time operation fees apply immediately to existing and new data sets. Existing data sets adopt the new proving rate on their next rate-touching operation: `piecesAdded`, `nextProvingPeriod` when processing removals or pending fees, or termination. The next fee-charging operation may also raise the lifecycle-reserve lockup toward `0.50 USDFC`; underfunded payers can therefore receive `InsufficientLockupFunds` until their FilecoinPay balance is topped up ([#583](https://github.com/FilOzone/filecoin-services/pull/583)).
Expand Down Expand Up @@ -504,7 +520,8 @@ This release contains breaking changes that rename core concepts throughout the

The underlying functionality remains unchanged; this release only updates terminology for consistency.

[Unreleased]: https://github.com/FilOzone/filecoin-services/compare/v1.3.1...HEAD
[Unreleased]: https://github.com/FilOzone/filecoin-services/compare/v1.4.0...HEAD
[1.4.0]: https://github.com/FilOzone/filecoin-services/compare/v1.3.1...v1.4.0
[1.3.1]: https://github.com/FilOzone/filecoin-services/compare/v1.3.0...v1.3.1
[1.3.0]: https://github.com/FilOzone/filecoin-services/compare/v1.2.1...v1.3.0
[1.2.1]: https://github.com/FilOzone/filecoin-services/compare/v1.2.0...v1.2.1
Expand Down
2 changes: 1 addition & 1 deletion service_contracts/src/FilecoinWarmStorageService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ contract FilecoinWarmStorageService is
EIP712Upgradeable
{
// Version tracking
string public constant VERSION = "1.3.1";
string public constant VERSION = "1.4.0";
string private constant SERVICE_NAME = "Filecoin Warm Storage Service";
string private constant SERVICE_DESCRIPTION =
"Warm storage service for the Filecoin Onchain Cloud. Manages PDP-backed datasets, Filecoin Pay storage rails, lifecycle fees, and optional CDN payment rails.";
Expand Down
20 changes: 10 additions & 10 deletions service_contracts/test/FilecoinWarmStorageService.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1081,7 +1081,7 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
);
assertEq(address(pricing.tokenAddress), address(mockUSDFC), "Token address should match USDFC");
assertEq(pricing.epochsPerMonth, EPOCHS_PER_MONTH, "Epochs per month should be 86400");
assertEq(pricing.datasetFeePerMonth, DATASET_FEE_PER_MONTH, "Dataset fee should be 0.024 USDFC");
assertEq(pricing.datasetFeePerMonth, DATASET_FEE_PER_MONTH, "Dataset fee should be 0.12 USDFC");

// Verify the values are in expected range
assert(pricing.pricePerTiBPerMonthNoCDN < 10 ** 20); // Less than 10^20
Expand Down Expand Up @@ -1142,17 +1142,17 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
assert(rate100GiB > rate48GiB);
}

function testDatasetFee_ExactlyPoint024USDFC() public pure {
function testDatasetFee_ExactlyPoint12USDFC() public pure {
uint256 ratePerEpoch = calculateStorageSizeBasedRatePerEpoch(0);

assertEq(ratePerEpoch, DATASET_FEE_PER_EPOCH, "Dataset fee per epoch should be exact");
}

// Minimum Funds Validation Tests
function testInsufficientFunds_BelowMinimum() public {
// Setup: Client with insufficient funds (below 0.124 USDFC minimum = 0.024 dataset fee + 0.1 lifecycle reserve)
// Setup: Client with insufficient funds (below 0.62 USDFC minimum = 0.12 dataset fee + 0.50 lifecycle reserve)
address insufficientClient = makeAddr("insufficientClient");
uint256 insufficientAmount = 12e16; // 0.12 USDFC (below 0.124 minimum)
uint256 insufficientAmount = 12e16; // 0.12 USDFC (below 0.62 minimum)

// Transfer tokens from test contract to the test client
mockUSDFC.safeTransfer(insufficientClient, insufficientAmount);
Expand Down Expand Up @@ -1195,9 +1195,9 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
}

function testInsufficientFunds_ExactMinimum() public {
// Setup: Client with exactly the minimum funds (0.124 USDFC = 0.024 dataset fee + 0.1 lifecycle reserve)
// Setup: Client with exactly the minimum funds (0.62 USDFC = 0.12 dataset fee + 0.50 lifecycle reserve)
address exactClient = makeAddr("exactClient");
uint256 exactAmount = DATASET_FEE_PER_MONTH + LIFECYCLE_RESERVE_TARGET; // Exactly 0.124 USDFC
uint256 exactAmount = DATASET_FEE_PER_MONTH + LIFECYCLE_RESERVE_TARGET; // Exactly 0.62 USDFC

// Transfer tokens from test contract to the test client
mockUSDFC.safeTransfer(exactClient, exactAmount);
Expand Down Expand Up @@ -1236,9 +1236,9 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {
}

function testInsufficientFunds_JustAboveMinimum() public {
// Setup: Client with slightly more than minimum (0.125 USDFC)
// Setup: Client with slightly more than minimum (0.621 USDFC)
address aboveMinClient = makeAddr("aboveMinClient");
uint256 aboveMinAmount = DATASET_FEE_PER_MONTH + LIFECYCLE_RESERVE_TARGET + 1e15; // 0.125 USDFC (just above 0.124 minimum)
uint256 aboveMinAmount = DATASET_FEE_PER_MONTH + LIFECYCLE_RESERVE_TARGET + 1e15; // 0.621 USDFC

// Transfer tokens from test contract to the test client
mockUSDFC.safeTransfer(aboveMinClient, aboveMinAmount);
Expand Down Expand Up @@ -1283,7 +1283,7 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest {

// Setup: Client with minimal funds - just enough to create an empty dataset
address limitedClient = makeAddr("limitedClient");
uint256 limitedAmount = DATASET_FEE_PER_MONTH + LIFECYCLE_RESERVE_TARGET + 1e15; // 0.125 USDFC (just above 0.124 minimum)
uint256 limitedAmount = DATASET_FEE_PER_MONTH + LIFECYCLE_RESERVE_TARGET + 1e15; // 0.621 USDFC

mockUSDFC.safeTransfer(limitedClient, limitedAmount);

Expand Down Expand Up @@ -5863,7 +5863,7 @@ contract FilecoinWarmStorageServiceUpgradeTest is Test {
if (logs[i].topics[0] == expectedTopic) {
// Decode and verify the event data
(string memory version, address implementation) = abi.decode(logs[i].data, (string, address));
assertEq(version, "1.3.1", "Version should be 1.3.1");
assertEq(version, "1.4.0", "Version should be 1.4.0");
assertTrue(implementation != address(0), "Implementation address should not be zero");
foundEvent = true;
break;
Expand Down
Loading