diff --git a/CHANGELOG.md b/CHANGELOG.md index f2f1acb4..8bfc72c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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)). @@ -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)). @@ -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 diff --git a/service_contracts/src/FilecoinWarmStorageService.sol b/service_contracts/src/FilecoinWarmStorageService.sol index 28f130f3..fb63a3e7 100644 --- a/service_contracts/src/FilecoinWarmStorageService.sol +++ b/service_contracts/src/FilecoinWarmStorageService.sol @@ -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."; diff --git a/service_contracts/test/FilecoinWarmStorageService.t.sol b/service_contracts/test/FilecoinWarmStorageService.t.sol index c50844e2..5ed123d3 100644 --- a/service_contracts/test/FilecoinWarmStorageService.t.sol +++ b/service_contracts/test/FilecoinWarmStorageService.t.sol @@ -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 @@ -1142,7 +1142,7 @@ 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"); @@ -1150,9 +1150,9 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest { // 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); @@ -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); @@ -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); @@ -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); @@ -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;