-
Notifications
You must be signed in to change notification settings - Fork 17
feat: handle rail termination callback from payments contract #87
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
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 |
|---|---|---|
|
|
@@ -30,6 +30,7 @@ contract PandoraService is PDPListener, IValidator, Initializable, UUPSUpgradeab | |
| event DataSetRailCreated(uint256 indexed dataSetId, uint256 railId, address payer, address payee, bool withCDN); | ||
| event RailRateUpdated(uint256 indexed dataSetId, uint256 railId, uint256 newRate); | ||
| event PieceMetadataAdded(uint256 indexed dataSetId, uint256 pieceId, string metadata); | ||
| event RailTerminatedInService(uint256 indexed railId, address indexed terminator, uint256 endEpoch); | ||
|
|
||
| // Constants | ||
| uint256 public constant NO_CHALLENGE_SCHEDULED = 0; | ||
|
|
@@ -118,6 +119,15 @@ contract PandoraService is PDPListener, IValidator, Initializable, UUPSUpgradeab | |
| // Track when proving was first activated for each data set | ||
| mapping(uint256 => uint256) public provingActivationEpoch; | ||
|
|
||
| // Rail termination tracking | ||
| struct RailTerminationStatus { | ||
| bool isTerminated; | ||
| uint256 endEpoch; | ||
| } | ||
|
|
||
| // Mapping from rail ID to termination status | ||
| mapping(uint256 => RailTerminationStatus) public railTerminationStatus; | ||
|
|
||
| // ========== Storage Provider Registry State ========== | ||
|
|
||
| uint256 public nextServiceProviderId = 1; | ||
|
|
@@ -495,6 +505,9 @@ contract PandoraService is PDPListener, IValidator, Initializable, UUPSUpgradeab | |
| DataSetInfo storage info = dataSetInfo[dataSetId]; | ||
| require(info.railId != 0, "Data set not registered with payment system"); | ||
|
|
||
| // Check if the rail is terminated | ||
| require(!railTerminationStatus[info.railId].isTerminated, "Cannot add pieces: rail is terminated"); | ||
|
|
||
| // Get the payer address for this data set | ||
| address payer = info.payer; | ||
| require(extraData.length > 0, "Extra data required for adding pieces"); | ||
|
|
@@ -532,6 +545,13 @@ contract PandoraService is PDPListener, IValidator, Initializable, UUPSUpgradeab | |
| "Data set not registered with payment system" | ||
| ); | ||
|
|
||
| // Check if rail is terminated and beyond end epoch | ||
| RailTerminationStatus memory termStatus = railTerminationStatus[info.railId]; | ||
| require( | ||
| !termStatus.isTerminated || block.number <= termStatus.endEpoch, | ||
| "Operation rejected: rail terminated and beyond end epoch" | ||
| ); | ||
|
|
||
| // Get the payer address for this data set | ||
| address payer = info.payer; | ||
|
|
||
|
|
@@ -561,6 +581,16 @@ contract PandoraService is PDPListener, IValidator, Initializable, UUPSUpgradeab | |
| uint256, /*seed*/ | ||
| uint256 challengeCount | ||
| ) external onlyPDPVerifier { | ||
| // Check if rail is terminated and beyond end epoch | ||
| DataSetInfo storage info = dataSetInfo[dataSetId]; | ||
| if (info.railId != 0) { | ||
| RailTerminationStatus memory termStatus = railTerminationStatus[info.railId]; | ||
| require( | ||
| !termStatus.isTerminated || block.number <= termStatus.endEpoch, | ||
| "Operation rejected: rail terminated and beyond end epoch" | ||
| ); | ||
| } | ||
|
|
||
| if (provenThisPeriod[dataSetId]) { | ||
| revert("Only one proof of possession allowed per proving period. Open a new proving period."); | ||
| } | ||
|
|
@@ -594,6 +624,16 @@ contract PandoraService is PDPListener, IValidator, Initializable, UUPSUpgradeab | |
| external | ||
| onlyPDPVerifier | ||
| { | ||
| // Check if rail is terminated and beyond end epoch | ||
| DataSetInfo storage info = dataSetInfo[dataSetId]; | ||
| if (info.railId != 0) { | ||
| RailTerminationStatus memory termStatus = railTerminationStatus[info.railId]; | ||
| require( | ||
| !termStatus.isTerminated || block.number <= termStatus.endEpoch, | ||
| "Operation rejected: rail terminated and beyond end epoch" | ||
|
Collaborator
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. Since these errors really mean -- "this entire dataset is unrecoverable" it should probably be a little more descriptive in this direction. For example "Operation rejected: rail terminated and finalized -- proof set must be removed to make progress"
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. I think we can remove the prefix |
||
| ); | ||
| } | ||
|
|
||
| // initialize state for new data set | ||
| if (provingDeadlines[dataSetId] == NO_PROVING_DEADLINE) { | ||
| uint256 firstDeadline = block.number + getMaxProvingPeriod(); | ||
|
|
@@ -1356,4 +1396,39 @@ contract PandoraService is PDPListener, IValidator, Initializable, UUPSUpgradeab | |
| note: "" | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * @notice Called when a payment rail is terminated in the Payments contract | ||
| * @dev Implements the IValidator interface function | ||
| * @param railId ID of the payment rail being terminated | ||
| * @param terminator Address that initiated the termination | ||
| * @param endEpoch The final epoch up to which the rail can be settled | ||
|
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. I might not understand settling fully, but does this mean funds will be locked inside the rail if I didn't settle them before |
||
| */ | ||
| function railTerminated(uint256 railId, address terminator, uint256 endEpoch) external override { | ||
| // Only payments contract can call this | ||
| require(msg.sender == paymentsContractAddress, "Only payments contract can terminate rails"); | ||
|
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. since only the one payments contract can do this, shall we drop the
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 The
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. If that is the case then the error message in the |
||
|
|
||
| // Verify rail exists in our mapping | ||
| uint256 dataSetId = railToDataSet[railId]; | ||
| require(dataSetId != 0, "Rail not associated with any data set"); | ||
|
|
||
| // Update termination status | ||
| railTerminationStatus[railId] = RailTerminationStatus({ | ||
|
Collaborator
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. nit: you could make this is a simple |
||
| isTerminated: true, | ||
| endEpoch: endEpoch | ||
| }); | ||
|
|
||
| emit RailTerminatedInService(railId, terminator, endEpoch); | ||
| } | ||
|
|
||
| /** | ||
| * @notice Check if a rail is terminated and get its end epoch | ||
| * @param railId The ID of the rail to check | ||
| * @return isTerminated Whether the rail is terminated | ||
| * @return endEpoch The end epoch for the terminated rail (0 if not terminated) | ||
| */ | ||
| function isRailTerminated(uint256 railId) external view returns (bool isTerminated, uint256 endEpoch) { | ||
| RailTerminationStatus memory status = railTerminationStatus[railId]; | ||
| return (status.isTerminated, status.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.
can we refactor this into a method like
requireActivePaymentRail(railId)orrequireUnterminatedPaymentRail(railId)? It is being used without differences in 3 placesThere 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.
I can add termination logic for the FilCDN rails when we have decided on this matter