-
Notifications
You must be signed in to change notification settings - Fork 17
feat: terminate all data set rails (storange and CDN) atomically #93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
91c8006
15648ae
9d9efda
5828b55
ce984db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -102,6 +102,7 @@ contract FilecoinWarmStorageService is | |
| string[] pieceMetadata; // Array of metadata for each piece | ||
| uint256 clientDataSetId; // ClientDataSetID | ||
| bool withCDN; // Whether the data set is registered for CDN add-on | ||
| uint256 paymentEndEpoch; // 0 if payment is not terminated | ||
| } | ||
|
|
||
| // Decode structure for data set creation extra data | ||
|
|
@@ -198,6 +199,7 @@ contract FilecoinWarmStorageService is | |
| /// @dev This fee is burned to prevent spam registrations | ||
| uint256 public constant SP_REGISTRATION_FEE = 1 ether; | ||
| // Modifier to ensure only the PDP verifier contract can call certain functions | ||
|
|
||
| modifier onlyPDPVerifier() { | ||
| require(msg.sender == pdpVerifierAddress, "Caller is not the PDP verifier"); | ||
| _; | ||
|
|
@@ -530,6 +532,7 @@ contract FilecoinWarmStorageService is | |
| IPDPTypes.PieceData[] memory pieceData, | ||
| bytes calldata extraData | ||
| ) external onlyPDPVerifier { | ||
| requirePaymentNotTerminated(dataSetId); | ||
| // Verify the data set exists in our mapping | ||
| DataSetInfo storage info = dataSetInfo[dataSetId]; | ||
| require(info.pdpRailId != 0, "Data set not registered with payment system"); | ||
|
|
@@ -558,6 +561,7 @@ contract FilecoinWarmStorageService is | |
| external | ||
| onlyPDPVerifier | ||
| { | ||
| requirePaymentNotBeyondEndEpoch(dataSetId); | ||
| // Verify the data set exists in our mapping | ||
| DataSetInfo storage info = dataSetInfo[dataSetId]; | ||
| require(info.pdpRailId != 0, "Data set not registered with payment system"); | ||
|
|
@@ -586,6 +590,7 @@ contract FilecoinWarmStorageService is | |
| uint256, /*seed*/ | ||
| uint256 challengeCount | ||
| ) external onlyPDPVerifier { | ||
| requirePaymentNotBeyondEndEpoch(dataSetId); | ||
| if (provenThisPeriod[dataSetId]) { | ||
| revert("Only one proof of possession allowed per proving period. Open a new proving period."); | ||
| } | ||
|
|
@@ -619,6 +624,7 @@ contract FilecoinWarmStorageService is | |
| external | ||
| onlyPDPVerifier | ||
| { | ||
| requirePaymentNotBeyondEndEpoch(dataSetId); | ||
| // initialize state for new data set | ||
| if (provingDeadlines[dataSetId] == NO_PROVING_DEADLINE) { | ||
| uint256 firstDeadline = block.number + getMaxProvingPeriod(); | ||
|
|
@@ -717,6 +723,44 @@ contract FilecoinWarmStorageService is | |
| emit DataSetStorageProviderChanged(dataSetId, oldStorageProvider, newStorageProvider); | ||
| } | ||
|
|
||
| function terminateDataSetPayment(uint256 dataSetId) external { | ||
| DataSetInfo storage info = dataSetInfo[dataSetId]; | ||
| require(info.pdpRailId != 0, "invalid dataset ID"); | ||
|
|
||
| // Check if already terminated | ||
| require(info.paymentEndEpoch == 0, "dataset payment already terminated"); | ||
|
|
||
| // Check authorization | ||
| require( | ||
| msg.sender == info.payer || msg.sender == info.payee, "Only payer or payee can terminate data set payment" | ||
| ); | ||
|
|
||
| Payments payments = Payments(paymentsContractAddress); | ||
|
|
||
| payments.terminateRail(info.pdpRailId); | ||
|
|
||
| if (info.withCDN) { | ||
| payments.terminateRail(info.cacheMissRailId); | ||
| payments.terminateRail(info.cdnRailId); | ||
| } | ||
| } | ||
|
|
||
| function requirePaymentNotTerminated(uint256 dataSetId) internal view { | ||
| DataSetInfo storage info = dataSetInfo[dataSetId]; | ||
| require(info.pdpRailId != 0, "invalid dataset ID"); | ||
| require(info.paymentEndEpoch == 0, "data set payment has already been terminated"); | ||
| } | ||
|
|
||
| function requirePaymentNotBeyondEndEpoch(uint256 dataSetId) internal view { | ||
| DataSetInfo storage info = dataSetInfo[dataSetId]; | ||
| if (info.paymentEndEpoch != 0) { | ||
| require( | ||
| block.number <= info.paymentEndEpoch, | ||
| "data set is beyond its payment end epoch: remove data set to make progress" | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| function updatePaymentRates(uint256 dataSetId, uint256 leafCount) internal { | ||
| // Revert if no payment rail is configured for this data set | ||
| require(dataSetInfo[dataSetId].pdpRailId != 0, "No PDP payment rail configured"); | ||
|
|
@@ -1173,10 +1217,10 @@ contract FilecoinWarmStorageService is | |
|
|
||
| // Check if registration is already pending | ||
| require(pendingProviders[msg.sender].registeredAt == 0, "Registration already pending"); | ||
|
|
||
| // Burn one-time fee to register | ||
| require(msg.value == SP_REGISTRATION_FEE, "Incorrect registration fee"); | ||
| (bool sent, ) = BURN_ADDRESS.call{value: msg.value}(""); | ||
| (bool sent,) = BURN_ADDRESS.call{value: msg.value}(""); | ||
| require(sent, "Burn failed"); | ||
|
|
||
| // Store pending registration | ||
|
|
@@ -1329,7 +1373,8 @@ contract FilecoinWarmStorageService is | |
| metadata: storageInfo.metadata, | ||
| pieceMetadata: storageInfo.pieceMetadata, | ||
| clientDataSetId: storageInfo.clientDataSetId, | ||
| withCDN: storageInfo.withCDN | ||
| withCDN: storageInfo.withCDN, | ||
| paymentEndEpoch: storageInfo.paymentEndEpoch | ||
| }); | ||
| } | ||
| return dataSets; | ||
|
|
@@ -1407,4 +1452,21 @@ contract FilecoinWarmStorageService is | |
| note: "" | ||
| }); | ||
| } | ||
|
|
||
| function railTerminated(uint256 railId, address terminator, uint256 endEpoch) external override { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For my understanding: After
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @juliangruber That is correct ! |
||
| require(msg.sender == paymentsContractAddress, "Caller is not the Payments contract"); | ||
|
|
||
| if (terminator != address(this)) { | ||
| revert( | ||
| "cannot terminate rail using Payments contract: call `terminateDataSetPayment` on the service contract" | ||
| ); | ||
| } | ||
|
|
||
| uint256 dataSetId = railToDataSet[railId]; | ||
| require(dataSetId != 0, "data set does not exist for given rail"); | ||
| DataSetInfo storage info = dataSetInfo[dataSetId]; | ||
| if (info.paymentEndEpoch == 0) { | ||
| info.paymentEndEpoch = endEpoch; | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: unrelated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a forge fmt