@@ -37,6 +37,8 @@ interface PDPListener {
3737 ) external ;
3838}
3939
40+ uint256 constant NEW_DATA_SET_SENTINEL = 0 ;
41+
4042contract PDPVerifier is Initializable , UUPSUpgradeable , OwnableUpgradeable {
4143 // Constants
4244 address public constant BURN_ACTOR = 0xff00000000000000000000000000000000000063 ;
@@ -382,35 +384,6 @@ contract PDPVerifier is Initializable, UUPSUpgradeable, OwnableUpgradeable {
382384 }
383385 }
384386
385- // A data set is created empty, with no pieces. Creation yields a data set ID
386- // for referring to the data set later.
387- // Sender of create message is storage provider.
388- function createDataSet (address listenerAddr , bytes calldata extraData ) public payable returns (uint256 ) {
389- require (extraData.length <= EXTRA_DATA_MAX_SIZE, "Extra data too large " );
390- uint256 sybilFee = PDPFees.sybilFee ();
391- require (msg .value >= sybilFee, "sybil fee not met " );
392- burnFee (sybilFee);
393-
394- uint256 setId = nextDataSetId++ ;
395- dataSetLeafCount[setId] = 0 ;
396- nextChallengeEpoch[setId] = NO_CHALLENGE_SCHEDULED; // Initialized on first call to NextProvingPeriod
397- storageProvider[setId] = msg .sender ;
398- dataSetListener[setId] = listenerAddr;
399- dataSetLastProvenEpoch[setId] = NO_PROVEN_EPOCH;
400-
401- if (listenerAddr != address (0 )) {
402- PDPListener (listenerAddr).dataSetCreated (setId, msg .sender , extraData);
403- }
404- emit DataSetCreated (setId, msg .sender );
405-
406- // Return the at the end to avoid any possible re-entrency issues.
407- if (msg .value > sybilFee) {
408- (bool success ,) = msg .sender .call {value: msg .value - sybilFee}("" );
409- require (success, "Transfer failed. " );
410- }
411- return setId;
412- }
413-
414387 // Removes a data set. Must be called by the storage provider.
415388 function deleteDataSet (uint256 setId , bytes calldata extraData ) public {
416389 require (extraData.length <= EXTRA_DATA_MAX_SIZE, "Extra data too large " );
@@ -432,35 +405,81 @@ contract PDPVerifier is Initializable, UUPSUpgradeable, OwnableUpgradeable {
432405 emit DataSetDeleted (setId, deletedLeafCount);
433406 }
434407
435- // Appends new pieces to the collection managed by a data set.
436- // These pieces won't be challenged until the next proving period is
437- // started by calling nextProvingPeriod .
438- function addPieces (uint256 setId , Cids.Cid[] calldata pieceData , bytes calldata extraData )
408+ // Create Dataset and Add Pieces, When setId == NEW_DATA_SET_SENTINEL, this will create a new dataset with piece data provided
409+ // with the provided listenerAddr and expect extraData to be abi.encode(bytes createPayload, bytes addPayload).
410+ // When adding to an existing set, pass listenerAddr == address(0) and setId to the live dataset .
411+ function addPieces (uint256 setId , address listenerAddr , Cids.Cid[] calldata pieceData , bytes calldata extraData )
439412 public
413+ payable
440414 returns (uint256 )
441415 {
442- uint256 nPieces = pieceData.length ;
416+ if (setId == NEW_DATA_SET_SENTINEL) {
417+ (bytes memory createPayload , bytes memory addPayload ) = abi.decode (extraData, (bytes , bytes ));
418+
419+ require (createPayload.length <= EXTRA_DATA_MAX_SIZE, "Extra data too large " );
420+ uint256 sybilFee = PDPFees.sybilFee ();
421+ require (msg .value >= sybilFee, "sybil fee not met " );
422+ burnFee (sybilFee);
423+
424+ require (listenerAddr != address (0 ), "listener required for new dataset " );
425+ uint256 newSetId = nextDataSetId++ ;
426+ storageProvider[newSetId] = msg .sender ;
427+ dataSetListener[newSetId] = listenerAddr;
428+
429+ if (listenerAddr != address (0 )) {
430+ PDPListener (listenerAddr).dataSetCreated (newSetId, msg .sender , createPayload);
431+ }
432+ emit DataSetCreated (newSetId, msg .sender );
433+
434+ // Add pieces to the newly created data set (if any)
435+ if (pieceData.length > 0 ) {
436+ _addPiecesToDataSet (newSetId, pieceData, addPayload);
437+ }
438+
439+ // Return the at the end to avoid any possible re-entrency issues.
440+ if (msg .value > sybilFee) {
441+ (bool success ,) = msg .sender .call {value: msg .value - sybilFee}("" );
442+ require (success, "Transfer failed. " );
443+ }
444+
445+ return newSetId;
446+ } else {
447+ // Adding to an existing set; no fee should be sent and listenerAddr must be zero
448+ require (listenerAddr == address (0 ), "listener must be zero for existing dataset " );
449+ require (msg .value == 0 , "no fee on add to existing dataset " );
450+
451+ require (dataSetLive (setId), "Data set not live " );
452+ require (storageProvider[setId] == msg .sender , "Only the storage provider can add pieces " );
453+
454+ return _addPiecesToDataSet (setId, pieceData, extraData);
455+ }
456+ }
457+
458+ // Internal function to add pieces to a data set and handle events/listeners
459+ function _addPiecesToDataSet (uint256 setId , Cids.Cid[] calldata pieceData , bytes memory extraData )
460+ internal
461+ returns (uint256 firstAdded )
462+ {
443463 require (extraData.length <= EXTRA_DATA_MAX_SIZE, "Extra data too large " );
444- require ( dataSetLive (setId), " Data set not live " ) ;
464+ uint256 nPieces = pieceData. length ;
445465 require (nPieces > 0 , "Must add at least one piece " );
446- require (storageProvider[setId] == msg . sender , " Only the storage provider can add pieces " );
447- uint256 firstAdded = nextPieceId[setId];
448- uint256 [] memory pieceIds = new uint256 [](pieceData. length );
449- Cids.Cid[] memory pieceCidsAdded = new Cids.Cid [](pieceData. length );
466+
467+ firstAdded = nextPieceId[setId];
468+ uint256 [] memory pieceIds = new uint256 [](nPieces );
469+ Cids.Cid[] memory pieceCidsAdded = new Cids.Cid [](nPieces );
450470
451471 for (uint256 i = 0 ; i < nPieces; i++ ) {
452472 addOnePiece (setId, i, pieceData[i]);
453473 pieceIds[i] = firstAdded + i;
454474 pieceCidsAdded[i] = pieceData[i];
455475 }
476+
456477 emit PiecesAdded (setId, pieceIds, pieceCidsAdded);
457478
458479 address listenerAddr = dataSetListener[setId];
459480 if (listenerAddr != address (0 )) {
460481 PDPListener (listenerAddr).piecesAdded (setId, firstAdded, pieceData, extraData);
461482 }
462-
463- return firstAdded;
464483 }
465484
466485 error IndexedError (uint256 idx , string msg );
0 commit comments