Skip to content
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

Deal status refactoring and code improvements #9

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,6 @@ lint/tmp/
gas-report.txt

contracts/test/fuzzing/crytic-export
temp
temp

yarn.lock
170 changes: 144 additions & 26 deletions contracts/DealStatus.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,39 @@ pragma solidity ^0.8.17;
// import "hardhat/console.sol";

import "./interfaces/IAggregatorOracle.sol";
import "./data-segment/Proof.sol";
import {Proof} from "./data-segment/Proof.sol";
import {MarketTypes} from "@zondax/filecoin-solidity/contracts/v0.8/types/MarketTypes.sol";
import {MarketAPI} from "@zondax/filecoin-solidity/contracts/v0.8/MarketAPI.sol";
import {CommonTypes} from "@zondax/filecoin-solidity/contracts/v0.8/types/CommonTypes.sol";

// Delta that implements the AggregatorOracle interface
contract DealStatus is IAggregatorOracle, Proof {
///////////////////
// State Variables
///////////////////

uint256 private transactionId;
mapping(uint256 => bytes) private txIdToCid;
mapping(bytes => Deal[]) private cidToDeals;

///////////////////
// Functions
///////////////////

//constructor
constructor() {
transactionId = 0;
}

// external functions

/**
* @notice Submits a new transaction with the given content identifier.
* @dev Increments the transaction ID, saves the content identifier, and emits a SubmitAggregatorRequest event.
* @param _cid The content identifier for the new transaction.
* @return The ID of the newly created transaction.
*/

function submit(bytes memory _cid) external returns (uint256) {
// Increment the transaction ID
transactionId++;
Expand All @@ -29,11 +50,21 @@ contract DealStatus is IAggregatorOracle, Proof {
return transactionId;
}

/**
* @notice Submits a new transaction with the given content identifier and RaaS parameters.
* @dev Increments the transaction ID, saves the content identifier, and emits a SubmitAggregatorRequestWithRaaS event.
* @param _cid The content identifier for the new transaction.
* @param _replication_target The number of replications of data needed.
* @param _repair_threshold The threshold to repair the deal if miner faults.
* @param _renew_threshold The threshold to renew the deal.
* @return The ID of the newly created transaction.
*/

function submitRaaS(
bytes memory _cid,
uint256 _replication_target,
uint256 _replication_target,
uint256 _repair_threshold,
uint256 _renew_threshold
uint256 _renew_threshold
) external returns (uint256) {
// Increment the transaction ID
transactionId++;
Expand All @@ -42,10 +73,27 @@ contract DealStatus is IAggregatorOracle, Proof {
txIdToCid[transactionId] = _cid;

// Emit the event
emit SubmitAggregatorRequestWithRaaS(transactionId, _cid, _replication_target, _repair_threshold, _renew_threshold);
emit SubmitAggregatorRequestWithRaaS(
transactionId,
_cid,
_replication_target,
_repair_threshold,
_renew_threshold
);
return transactionId;
}

/**
* @notice Completes a transaction with the given transaction ID, deal ID, miner ID, inclusion proof, and inclusion verifier data.
* @dev Emits a CompleteAggregatorRequest event.
* @param _id The ID of the transaction to complete.
* @param _dealId The ID of the deal to complete.
* @param _minerId The ID of the miner that completed the deal.
* @param _proof The inclusion proof for the transaction.
* @param _verifierData The inclusion verifier data for the transaction.
* @return The inclusion auxiliary data proof for the given file proof and verifier data.
*/

function complete(
uint256 _id,
uint64 _dealId,
Expand All @@ -61,7 +109,7 @@ contract DealStatus is IAggregatorOracle, Proof {
bytes memory cid = txIdToCid[_id];
for (uint256 i = 0; i < cidToDeals[cid].length; i++) {
if (cidToDeals[cid][i].dealId == _dealId) {
return this.computeExpectedAuxData(_proof, _verifierData);
return computeExpectedAuxData(_proof, _verifierData);
}
}

Expand All @@ -70,43 +118,48 @@ contract DealStatus is IAggregatorOracle, Proof {

// Perform validation logic
// return this.computeExpectedAuxDataWithDeal(_dealId, _proof, _verifierData);
return this.computeExpectedAuxData(_proof, _verifierData);
return computeExpectedAuxData(_proof, _verifierData);
}

// allDealIds should return all the deal ids created by the aggregator
function getAllDeals(bytes memory _cid) external view returns (Deal[] memory) {
return cidToDeals[_cid];
}
// View functions

function getAllCIDs() external view returns (bytes[] memory) {
bytes[] memory cids = new bytes[](transactionId);
for (uint256 i = 0; i < transactionId; i++) {
cids[i] = txIdToCid[i + 1];
}
return cids;
}
/**
* @notice Retrieves all active deals associated with a given content identifier.
* @dev Iterates through all deals associated with the content identifier, checks their activation and termination status, and removes any inactive deals from the returned array.
* @param _cid The content identifier for which to retrieve active deals.
* @return An array of Deal structs representing all active deals associated with the given content identifier.
*/

// getActiveDeals should return all the _cid's active dealIds
function getActiveDeals(bytes memory _cid) external returns (Deal[] memory) {
function getActiveDeals(bytes memory _cid) external view returns (Deal[] memory) {
// get all the deal ids for the cid
Deal[] memory activeDealIds;
activeDealIds = this.getAllDeals(_cid);

for (uint256 i = 0; i < activeDealIds.length; i++) {
uint64 dealID = activeDealIds[i].dealId;
// get the deal's expiration epoch
MarketTypes.GetDealActivationReturn memory dealActivationStatus = MarketAPI.getDealActivation(dealID);
(int64 activated, int64 terminated) = this.getDealActivationData(dealID);

if (dealActivationStatus.terminated > 0 || dealActivationStatus.activated == -1) {
if (terminated > 0 || activated == -1) {
delete activeDealIds[i];
}
}

return activeDealIds;
}

// getExpiringDeals should return all the deals' dealIds if they are expiring within `epochs`
function getExpiringDeals(bytes memory _cid, uint64 epochs) external returns (Deal[] memory) {
/**
* @notice Retrieves all expiring deals associated with a given content identifier.
* @dev Iterates through all deals associated with the content identifier, checks their expiration status, and removes any non-expiring deals from the returned array.
* @param _cid The content identifier for which to retrieve expiring deals.
* @param epochs The number of epochs before a deal's expiration to consider it expiring.
* @return An array of Deal structs representing all expiring deals associated with the given content identifier.
*/

function getExpiringDeals(
bytes memory _cid,
uint64 epochs
) external view returns (Deal[] memory) {
// the logic is similar to the above, but use this api call:
// https://github.com/Zondax/filecoin-solidity/blob/master/contracts/v0.8/MarketAPI.sol#LL110C9-L110C9
Deal[] memory expiringDealIds;
Expand All @@ -115,13 +168,78 @@ contract DealStatus is IAggregatorOracle, Proof {
for (uint256 i = 0; i < expiringDealIds.length; i++) {
uint64 dealId = expiringDealIds[i].dealId;
// get the deal's expiration epoch
MarketTypes.GetDealTermReturn memory dealTerm = MarketAPI.getDealTerm(dealId);

if (block.number < uint64(dealTerm.end) - epochs || block.number > uint64(dealTerm.end)) {
(int64 startEpoch, int64 duration) = this.getDealTermData(dealId);
if (
(block.number + epochs < uint64(startEpoch) + uint64(duration)) ||
(block.number > uint64(startEpoch) + uint64(duration))
) {
delete expiringDealIds[i];
}
}

return expiringDealIds;
}

//Getter Functions

/**
* @notice Retrieves the activation and termination data for a given deal.
* @dev Calls the MarketAPI to get the deal's activation status and then unwraps the activation and termination epochs.
* @param _dealId The ID of the deal for which to retrieve activation data.
* @return dealActivation The activation epoch of the deal or -1.
* @return dealTermination The termination epoch of the deal or -1.
*/

function getDealActivationData(
uint64 _dealId
) public view returns (int64 dealActivation, int64 dealTermination) {
MarketTypes.GetDealActivationReturn memory dealActivationStatus = MarketAPI
.getDealActivation(_dealId);
return (
CommonTypes.ChainEpoch.unwrap(dealActivationStatus.activated),
CommonTypes.ChainEpoch.unwrap(dealActivationStatus.terminated)
);
}

/**
* @notice Retrieves the start and end epochs for a given deal.
* @dev Calls the MarketAPI to get the deal's start and end epochs and then unwraps them.
* @param _dealId The ID of the deal for which to retrieve term data.
* @return startEpoch The start epoch of the deal.
* @return endEpoch The end epoch of the deal.
*/
function getDealTermData(
uint64 _dealId
) public view returns (int64 startEpoch, int64 endEpoch) {
MarketTypes.GetDealTermReturn memory dealTerm = MarketAPI.getDealTerm(_dealId);
return (
CommonTypes.ChainEpoch.unwrap(dealTerm.start),
CommonTypes.ChainEpoch.unwrap(dealTerm.end)
);
}

/**
* @notice Retrieves all deals associated with a given content identifier.
* @dev Returns the array of deals associated with the given content identifier.
* @param _cid The content identifier for which to retrieve deals.
* @return An array of Deal structs representing all deals associated with the given content identifier.
*/

function getAllDeals(bytes memory _cid) external view returns (Deal[] memory) {
return cidToDeals[_cid];
}

/**
* @notice Retrieves all content identifiers associated with the contract.
* @dev Returns the array of content identifiers associated with the aggregator.
* @return An array of bytes representing all content identifiers associated with the aggregator.
*/

function getAllCIDs() external view returns (bytes[] memory) {
bytes[] memory cids = new bytes[](transactionId);
for (uint256 i = 0; i < transactionId; i++) {
cids[i] = txIdToCid[i + 1];
}
return cids;
}
}
13 changes: 8 additions & 5 deletions contracts/data-segment/Cid.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import "./Const.sol";

library Cid {
// cidToPieceCommitment converts a CID to a piece commitment.
function cidToPieceCommitment(bytes memory _cb) public pure returns (bytes32) {
require(_cb.length == CID_COMMP_HEADER_LENGTH + MERKLE_TREE_NODE_SIZE, "wrong length of CID");
function cidToPieceCommitment(bytes memory _cb) internal pure returns (bytes32) {
require(
keccak256(abi.encodePacked(_cb[0], _cb[1], _cb[2], _cb[3], _cb[4], _cb[5], _cb[6]))
== keccak256(abi.encodePacked(CID_COMMP_HEADER)),
_cb.length == CID_COMMP_HEADER_LENGTH + MERKLE_TREE_NODE_SIZE,
"wrong length of CID"
);
require(
keccak256(abi.encodePacked(_cb[0], _cb[1], _cb[2], _cb[3], _cb[4], _cb[5], _cb[6])) ==
keccak256(abi.encodePacked(CID_COMMP_HEADER)),
"wrong content of CID header"
);
bytes32 res;
Expand All @@ -22,7 +25,7 @@ library Cid {
}

// pieceCommitmentToCid converts a piece commitment to a CID.
function pieceCommitmentToCid(bytes32 _commp) public pure returns (bytes memory) {
function pieceCommitmentToCid(bytes32 _commp) internal pure returns (bytes memory) {
bytes memory cb = abi.encodePacked(CID_COMMP_HEADER, _commp);
return cb;
}
Expand Down
Loading