diff --git a/backend/routes/backup.js b/backend/routes/backup.js index fb5eead..435ad91 100644 --- a/backend/routes/backup.js +++ b/backend/routes/backup.js @@ -1,6 +1,6 @@ const express = require('express'); const router = express.Router(); -const { fillArrayWithPinnedCIDs, copyToMFS, createCAR, addBackCAR, calculateCommP, listActiveBackups, startBackup } = require('../utils/backupUtils'); +const { fillArrayWithPinnedCIDs, copyToMFS, createCAR, addBackCAR, calculateCommP, listActiveBackups, startBackup, clearInProgressBackups } = require('../utils/backupUtils'); // This will start the backup process. Probably we will change it to POST instead of GET, and it would be good if we could give in some parameters, like PeerID router.get('/start', async (req, res) => { @@ -10,8 +10,8 @@ router.get('/start', async (req, res) => { await copyToMFS(ipfs, arrayOfCIDs, folderName); const { payloadCID, payloadSize } = await createCAR(ipfs, CID, folderName, globSource); await calculateCommP(folderName, payloadCID); - //await addBackCAR(ipfs, CID, folderName, globSource) - + //await addToFilecoin(); // we chained this to calculateCommP, because couldn't solve it other way + //await checkDealStatus(); // we chained this to addToFilecoin }); // This will backup a single folder, that it is pointed to @@ -19,7 +19,6 @@ router.get('/folder', async (req, res) => { const { ipfs, CID, globSource, folderName } = await startBackup(req.query.name, res); const { payloadCID, payloadSize } = await createCAR(ipfs, CID, folderName); await calculateCommP(folderName, payloadCID, CID); - //await addBackCAR(ipfs, CID, folderName, globSource); }); // Delete backup folders @@ -53,4 +52,16 @@ router.get('/show-inprogress', async (req, res) => { res.json(listActiveBackups(req.query.name)); }); +router.get('/clear-inprogress', (req, res) => { + try { + clearInProgressBackups(); + res.json({message: "InProgressBackups were cleared."}); + } catch (error) { + res.json({ + message: "There was an error while trying to clear the InProgressBackups object.", + error: error + }); + } +}) + module.exports = router; \ No newline at end of file diff --git a/backend/utils/backupUtils.js b/backend/utils/backupUtils.js index 59a3029..0d48d2c 100644 --- a/backend/utils/backupUtils.js +++ b/backend/utils/backupUtils.js @@ -161,7 +161,7 @@ async function calculateCommP(folderName, payloadCID, CID) { console.log("CommP: ", commPCid) console.log("Payload size: ", payloadSize); console.log("Piece Size: ", paddedPieceSize); - addToFilecoin(CID, folderName); + addToFilecoin(folderName); } catch (error) { console.error("There was an error while trying to calculate commP!", error); inProgressBackups[folderName].commPCalculationError = error; @@ -180,40 +180,23 @@ async function calculateCommP(folderName, payloadCID, CID) { return {commPCid, paddedPieceSize} } -async function addToFilecoin(not_used, folderName) { +async function addToFilecoin(folderName) { // Convert piece CID string to hex bytes const cid = inProgressBackups[folderName].commP; const cidHexRaw = new CID(cid).toString('base16').substring(1); const cidHex = "0x" + cidHexRaw; const contractAddr = process.env.DEAL_CONTRACT; - - const verified = false; - const skipIpniAnnounce = false; - const removeUnsealedCopy = false; - - const extraParamsV1 = [ - "http://45.91.171.156:3000/fetch?fileName=" + folderName + ".car", - inProgressBackups[folderName].payloadSize, - skipIpniAnnounce, - removeUnsealedCopy, - ] - - const startEpoch = 215000; - - const DealRequestStruct = [ - cidHex, - inProgressBackups[folderName].pieceSize, - verified, - inProgressBackups[folderName].payloadCID, - startEpoch, // arbitrary number, will need to fetch this later - (startEpoch+600000), // end - 0, // storage price per epoch - 0, // provider collateral - 0, // client collateral - 1, // extra params version - extraParamsV1, - ]; + const BackupRequestStruct = { + pieceCID: cidHex, + pieceSize: inProgressBackups[folderName].pieceSize, + label: inProgressBackups[folderName].payloadCID, + dealDuration: 600000, + maxPricePerEpoch: 0, // Max price per epoch + originalLocation: "http://45.91.171.156:3000/fetch?fileName=" + folderName + ".car", + carSize: inProgressBackups[folderName].payloadSize, + } + const networkId = network.defaultNetwork; console.log("Making deal proposal on network", networkId) @@ -221,13 +204,11 @@ async function addToFilecoin(not_used, folderName) { const DealClient = await ethers.getContractFactory("DealClient", wallet); // Contract Factory const dealClient = await DealClient.attach(contractAddr); // Contract instance - transaction = await dealClient.makeDealProposal(DealRequestStruct) // Transaction + transaction = await dealClient.startBackup(BackupRequestStruct) // Transaction transactionReceipt = await transaction.wait() const event = transactionReceipt.events[0].topics[1]; // Listen for DealProposalCreate event - //console.log("transactionReceipt: ", transactionReceipt); - //console.log("Events: ", transactionReceipt.events); - //console.log("Topics: ", transactionReceipt.events[0].topics); + inProgressBackups[folderName].dealRequestMade = true; console.log("Complete! Event Emitted. ProposalId is:", event); @@ -245,35 +226,31 @@ async function checkDealStatus(folderName) { const dealClient = await DealClient.attach(contractAddr); // Contract instance const max_try = 50; let try_count = 0; - let dealID = 0; + let deals = []; do { console.log("Attempt ", try_count); - const result = await dealClient.getDealId(commPasBytes); // Send transaction - dealID = result.toNumber(); - console.log("Deal ID: ", dealID); - if (dealID !== 0) { + deals = await dealClient.getDeals(commPasBytes); // Send transaction + //dealID = result.toNumber(); + console.log("Deals array: ", deals); + if (deals.length > 0) { inProgressBackups[folderName].dealPublished = true; break; } try_count++; await delay(1000*60*2); - } while (try_count < max_try && dealID === 0); + } while (try_count < max_try && deals.length === 0); - if (try_count === max_try && dealID === 0) { + if (try_count === max_try && deals.length === 0) { inProgressBackups[folderName].dealIdError = `Tried to get the DealID ${try_count} times without success. Most likely there was an error with making the deal.`; console.error(`Tried to get the DealID ${try_count} times without success. Most likely there was an error with making the deal.`); return; } console.log(`Backup finished successfully.`); - /*const refreshTransaction = dealClient.refreshValues(dealID); - console.log("Refresh transaction made. Hash: ", refreshTransaction.hash); + console.log("Deals: ", deals); + delete inProgressBackups[folderName]; - const isDealActivated = await dealClient.getDealVerificationStatus(dealID); - console.log("Is Deal Activated? ", isDealActivated); - const dealActive = await dealClient.getDealActivationStatus(dealID); - console.log("Deal Active: ", dealActive);*/ } catch (error) { inProgressBackups[folderName].dealIdError = error; console.error("There was an error while trying to get DealID", error); @@ -292,8 +269,15 @@ function listActiveBackups(name) { } } +function clearInProgressBackups() { + //inProgressBackups = Object.assign({}, {}); + for (let key in inProgressBackups) { + delete inProgressBackups[key]; + } +} + function delay(time) { return new Promise(resolve => setTimeout(resolve, time)); } -module.exports = { startBackup, fillArrayWithPinnedCIDs, copyToMFS, createCAR, addBackCAR, calculateCommP, addToFilecoin, listActiveBackups } \ No newline at end of file +module.exports = { startBackup, fillArrayWithPinnedCIDs, copyToMFS, createCAR, addBackCAR, calculateCommP, addToFilecoin, listActiveBackups, clearInProgressBackups } \ No newline at end of file diff --git a/commP b/commP new file mode 100644 index 0000000..e69de29 diff --git a/contracts/basic-deal-client/DealClient.sol b/contracts/basic-deal-client/DealClient.sol index a2a7d23..80dde5f 100644 --- a/contracts/basic-deal-client/DealClient.sol +++ b/contracts/basic-deal-client/DealClient.sol @@ -28,58 +28,33 @@ contract MockMarket { } } -struct ProposalIdSet { - bytes32 proposalId; - bool valid; -} -struct ProposalIdx { - uint256 idx; - bool valid; -} -struct ProviderSet { - bytes provider; - bool valid; -} -// User request for this contract to make a deal. This structure is modelled after Filecoin's Deal -// Proposal, but leaves out the provider, since any provider can pick up a deal broadcast by this -// contract. -struct DealRequest { - // To be cast to a CommonTypes.Cid - bytes piece_cid; - uint64 piece_size; - bool verified_deal; - // To be cast to a CommonTypes.FilAddress - // bytes client_addr; - // CommonTypes.FilAddress provider; - string label; - int64 start_epoch; - int64 end_epoch; - uint256 storage_price_per_epoch; - uint256 provider_collateral; - uint256 client_collateral; - uint64 extra_params_version; - ExtraParamsV1 extra_params; -} - -// Extra parameters associated with the deal request. These are off-protocol flags that -// the storage provider will need. -struct ExtraParamsV1 { - string location_ref; - uint64 car_size; - bool skip_ipni_announce; - bool remove_unsealed_copy; +// This is the object that is coming from the backup script, it will contain information that we need to create a Deal Request +struct BackupRequest { + bytes pieceCID; // Can be casted to CommonTypes.Cid | CommonTypes.Cid(pieceCID) + uint64 pieceSize; // Power of 2 + string label; // PayloadCID + int64 dealDuration; // Deal Duration in epoch + uint256 maxPricePerEpoch; // Max storage price per epoch + string originalLocation; // Original location, from where the data will be downloaded (location ref) + uint64 carSize; // alias Payload Size } - + // For every PieceCID, we will store this collection of data // It will be a value pair of a commP key struct BackupItem { uint16 totalDealCount; uint16 atLeast1MonthDealCount; uint16 targetRedundancy; - BackupItemDeal[] deals; + uint64 pieceSize; + string label; + int64 dealDuration; + uint256 maxPricePerEpoch; + string originalLocation; + uint64 carSize; + uint64 dealArrayId; } // A single deal about a BackupItem @@ -92,7 +67,16 @@ struct BackupItemDeal { bool isActivated; } -function serializeExtraParamsV1(ExtraParamsV1 memory params) pure returns (bytes memory) { +struct ExtraParamsV1 { + string location_ref; + uint64 car_size; + bool skip_ipni_announce; + bool remove_unsealed_copy; +} + +function serializeExtraParamsV1( + ExtraParamsV1 memory params +) pure returns (bytes memory) { CBOR.CBORBuffer memory buf = CBOR.create(64); buf.startFixedArray(4); buf.writeString(params.location_ref); @@ -110,92 +94,131 @@ contract DealClient { uint64 constant public DATACAP_RECEIVER_HOOK_METHOD_NUM = 3726118371; uint64 constant public MARKET_NOTIFY_DEAL_METHOD_NUM = 4186741094; - mapping(bytes32 => ProposalIdx) public dealProposals; // contract deal id -> deal index - mapping(bytes => ProposalIdSet) public pieceToProposal; // commP -> dealProposalID - mapping(bytes => ProviderSet) public pieceProviders; // commP -> provider - mapping(bytes => uint64) public pieceDeals; // commP -> deal ID + mapping(bytes32 => bytes) public dealProposals; // We will have this instead of dealProposals. uniqId -> commP mapping(bytes => BackupItem) public backupItems; // commP -> BackupItem - this is the one that we will keep on the long run + mapping(uint64 => BackupItemDeal[]) public dealArrays; // dealArrayId -> BackupItemDeal[] + uint64 dealArrayNonce = 0; // Will be used as identifier for dealArrays + uint16 defaultTargetRedundancy = 2; // Default target redundancy, that will be copied to every BackupItem, if other value not specified - DealRequest[] deals; - - // Temporary variables - this will become obsolate - MarketTypes.GetDealActivationReturn public tempActivationStatus; - bool public tempIsDealActivated; event ReceivedDataCap(string received); event DealProposalCreate(bytes32 indexed id, uint64 size, bool indexed verified, uint256 price); + event Log(string text); + event UniqId(bytes32 id); + address public owner; constructor() { owner = msg.sender; } - function makeDealProposal( - DealRequest calldata deal - ) public returns (bytes32) { - // TODO: length check on byte fields - require(msg.sender == owner); - uint256 index = deals.length; - deals.push(deal); + // Start the backup proccess, an entry should be created in 'backupItems' after this + // Another function will bring up the BackupItem to target redundancy if this does not succeed at first + function startBackup(BackupRequest calldata backupMeta) public returns (bool) { + emit Log("Backup started"); + require (msg.sender == owner); + + // Initialize new backup entry + backupItems[backupMeta.pieceCID] = BackupItem({ + totalDealCount: 0, + atLeast1MonthDealCount: 0, + targetRedundancy: defaultTargetRedundancy, + pieceSize: backupMeta.pieceSize, + label: backupMeta.label, + dealDuration: backupMeta.dealDuration, + maxPricePerEpoch: backupMeta.maxPricePerEpoch, + originalLocation: backupMeta.originalLocation, + carSize: backupMeta.carSize, + dealArrayId: dealArrayNonce + }); + // is the dealArray ready to be used ? seems like it is. + dealArrayNonce = dealArrayNonce + 1; + + uint64 index = backupItems[backupMeta.pieceCID].dealArrayId; + // We make as many deals, as target redundancy + for (uint16 i = 0; i < backupItems[backupMeta.pieceCID].targetRedundancy; i++) { + bytes32 uniqId = keccak256(abi.encodePacked(block.timestamp, msg.sender, backupMeta.pieceCID, i)); + emit UniqId(uniqId); + + dealProposals[uniqId] = backupMeta.pieceCID; // uniqID -> commP + // Writes the proposal metadata tothe event log + emit DealProposalCreate( + uniqId, + backupMeta.pieceSize, + false, // Not verified + 0 // Initially price is 0 + ); + } - // creates a unique ID for the deal proposal -- there are many ways to do this - bytes32 id = keccak256( - abi.encodePacked(block.timestamp, msg.sender, index) - ); - dealProposals[id] = ProposalIdx(index, true); + return true; + } - pieceToProposal[deal.piece_cid] = ProposalIdSet(id, true); + function getBackupItem(bytes memory commP) public view returns (BackupItem memory) { + return backupItems[commP]; + } - // writes the proposal metadata to the event log - emit DealProposalCreate( - id, - deal.piece_size, - deal.verified_deal, - deal.storage_price_per_epoch - ); + function getDeals(bytes memory commP) public view returns (BackupItemDeal[] memory) { + uint64 index = backupItems[commP].dealArrayId; + return dealArrays[index]; + } + + function refreshMetadataForBackupItem() public {} - return id; + function refreshMetadataForAll() public { + // will need an array for this, can not iterate 'backupItems' mapping } + function keepTargetRedundancy() public {} + // Returns a CBOR-encoded DealProposal. function getDealProposal(bytes32 proposalId) view public returns (bytes memory) { - // TODO make these array accesses safe. - DealRequest memory deal = getDealRequest(proposalId); - - MarketTypes.DealProposal memory ret; - ret.piece_cid = CommonTypes.Cid(deal.piece_cid); - ret.piece_size = deal.piece_size; - ret.verified_deal = deal.verified_deal; - ret.client = getDelegatedAddress(address(this)); - // Set a dummy provider. The provider that picks up this deal will need to set its own address. - ret.provider = FilAddresses.fromActorID(0); - ret.label = deal.label; - ret.start_epoch = deal.start_epoch; - ret.end_epoch = deal.end_epoch; - ret.storage_price_per_epoch = uintToBigInt(deal.storage_price_per_epoch); - ret.provider_collateral = uintToBigInt(deal.provider_collateral); - ret.client_collateral = uintToBigInt(deal.client_collateral); + bytes memory commP = dealProposals[proposalId]; // Get PieceCID based on uniqId + + int64 epochFromNow = 2000; // Deal will be activated this many epoch from now + int64 startEpoch = int64(int256(block.number)) + epochFromNow; + int64 endEpoch = startEpoch + backupItems[commP].dealDuration; + + MarketTypes.DealProposal memory ret; // Create DealProposal object + ret.piece_cid = CommonTypes.Cid(commP); // Piece CID + ret.piece_size = backupItems[commP].pieceSize; // Piece Size + ret.verified_deal = false; // Deal is not verified + ret.client = getDelegatedAddress(address(this)); // This will be the address of the contract + ret.provider = FilAddresses.fromActorID(0); // Set a dummy provider. The provider that picks up this deal will need to set its own address. + ret.label = backupItems[commP].label; // Payload CID + ret.start_epoch = startEpoch; // Start epoch + ret.end_epoch = endEpoch; // End epoch + ret.storage_price_per_epoch = uintToBigInt(0); // We need to solve this, we have max value instead of a concrete value + ret.provider_collateral = uintToBigInt(0); // Most likely this will be always 0 + ret.client_collateral = uintToBigInt(0); // Most likely this will be always 0 return serializeDealProposal(ret); } - function getDealId(bytes calldata commP) public view returns (uint64) { - return pieceDeals[commP]; + function getExtraParams(bytes32 proposalId) public view returns (bytes memory extra_params) { + bytes memory commP = dealProposals[proposalId]; // Get PieceCID based on uniqId + ExtraParamsV1 memory extraParams= ExtraParamsV1({ + location_ref: backupItems[commP].originalLocation, + car_size: backupItems[commP].carSize, + skip_ipni_announce: false, + remove_unsealed_copy: false + }); + return serializeExtraParamsV1(extraParams); } - function getDealVerificationStatus(uint64 dealId) public view returns (bool) { - return tempIsDealActivated; + // We needed this to test something, probably we will delete it later + function getCommpFromId(bytes32 proposalId) view public returns (bytes memory) { + bytes memory commP = dealProposals[proposalId]; // Get PieceCID based on uniqId + return commP; } - function getDealActivationStatus(uint64 dealId) public view returns (MarketTypes.GetDealActivationReturn memory) { - return tempActivationStatus; + function getDefaultTargetRedundancy() public view returns (uint16) { + return defaultTargetRedundancy; } - function refreshValues(uint64 dealId) public { - tempIsDealActivated = MarketAPI.getDealVerified(dealId); - tempActivationStatus = MarketAPI.getDealActivation(dealId); + function changeDefaultTargetRedundancy(uint16 newValue) public { + defaultTargetRedundancy = newValue; } // TODO fix in filecoin-solidity. They're using the wrong hex value. @@ -203,40 +226,42 @@ contract DealClient { return CommonTypes.FilAddress(abi.encodePacked(hex"040a", addr)); } - function getExtraParams( - bytes32 proposalId - ) public view returns (bytes memory extra_params) { - DealRequest memory deal = getDealRequest(proposalId); - return serializeExtraParamsV1(deal.extra_params); - } - - // helper function to get deal request based from id - function getDealRequest( - bytes32 proposalId - ) internal view returns (DealRequest memory) { - ProposalIdx memory pi = dealProposals[proposalId]; - require(pi.valid, "proposalId not available"); - - return deals[pi.idx]; - } function authenticateMessage(bytes memory params) view internal { AccountTypes.AuthenticateMessageParams memory amp = params.deserializeAuthenticateMessageParams(); MarketTypes.DealProposal memory proposal = deserializeDealProposal(amp.message); - require(pieceToProposal[proposal.piece_cid.data].valid, "piece cid must be added before authorizing"); - require(!pieceProviders[proposal.piece_cid.data].valid, "deal failed policy check: provider already claimed this cid"); + require(backupItems[proposal.piece_cid.data].targetRedundancy > 0, "CommP must exist in backupItems!"); // We could turn off the backup by setting redundancy to 0 + //require(!pieceProviders[proposal.piece_cid.data].valid, "deal failed policy check: provider already claimed this cid"); } function dealNotify(bytes memory params) internal { MarketDealNotifyParams memory mdnp = deserializeMarketDealNotifyParams(params); MarketTypes.DealProposal memory proposal = deserializeDealProposal(mdnp.dealProposal); - require(pieceToProposal[proposal.piece_cid.data].valid, "piece cid must be added before authorizing"); - require(!pieceProviders[proposal.piece_cid.data].valid, "deal failed policy check: provider already claimed this cid"); - - pieceProviders[proposal.piece_cid.data] = ProviderSet(proposal.provider.data, true); - pieceDeals[proposal.piece_cid.data] = mdnp.dealId; + require(backupItems[proposal.piece_cid.data].targetRedundancy > 0, "CommP must exist in backupItems!"); // We could turn off the backup by setting redundancy to 0 + bool providerAlreadyStoringThisData = false; + BackupItemDeal[] memory arr = dealArrays[backupItems[proposal.piece_cid.data].dealArrayId]; + for (uint i = 0; i < arr.length; i++) { + if (arr[i].dealId == mdnp.dealId) { // couldn't compare providerAddress + providerAlreadyStoringThisData = true; + break; + } + } + require(!providerAlreadyStoringThisData, "Provider is already storing this data"); // We don't want duplicates, has to be stored on different miner + + + dealArrays[backupItems[proposal.piece_cid.data].dealArrayId].push(BackupItemDeal({ + dealId: mdnp.dealId, + providerAddress: proposal.provider.data, + startEpoch: proposal.start_epoch, + endEpoch: proposal.end_epoch, + status: MarketTypes.GetDealActivationReturn({ + activated: -1, // Epoch at which the deal was activated, or -1. + terminated: -1 // Epoch at which the deal was terminated abnormally, or -1. + }), + isActivated: false + })); } // client - filecoin address byte format diff --git a/deploy/00_deploy.js b/deploy/00_deploy.js index 4671d9a..a95bb91 100644 --- a/deploy/00_deploy.js +++ b/deploy/00_deploy.js @@ -14,11 +14,11 @@ module.exports = async ({ deployments }) => { //deploy FilecoinMarketConsumer - const FilecoinMarketConsumer = await ethers.getContractFactory('FilecoinMarketConsumer', wallet); + /*const FilecoinMarketConsumer = await ethers.getContractFactory('FilecoinMarketConsumer', wallet); console.log('Deploying FilecoinMarketConsumer...'); const filecoinMarketConsumer = await FilecoinMarketConsumer.deploy(); await filecoinMarketConsumer.deployed() - console.log('FilecoinMarketConsumer deployed to:', filecoinMarketConsumer.address); + console.log('FilecoinMarketConsumer deployed to:', filecoinMarketConsumer.address);*/ //deploy DealClient const DealClient = await ethers.getContractFactory('DealClient', wallet); diff --git a/hardhat.config.js b/hardhat.config.js index 58987bc..7c6893c 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -1,13 +1,22 @@ require("@nomicfoundation/hardhat-toolbox") require("hardhat-deploy") require("hardhat-deploy-ethers") +//require("@nomicfoundation/hardhat-foundry" ) require("./tasks") require("dotenv").config() const PRIVATE_KEY = process.env.PRIVATE_KEY /** @type import('hardhat/config').HardhatUserConfig */ module.exports = { - solidity: "0.8.17", + solidity: { + version: "0.8.17", + settings: { + optimizer: { + enabled: true, + runs: 200 + } + } + }, defaultNetwork: "hyperspace", networks: { hyperspace: { @@ -22,4 +31,5 @@ module.exports = { cache: "./cache", artifacts: "./artifacts", }, + } diff --git a/tasks/deal-client/get-deal-id.js b/tasks/deal-client/get-backup-item.js similarity index 73% rename from tasks/deal-client/get-deal-id.js rename to tasks/deal-client/get-backup-item.js index d49744f..ff9ec1f 100644 --- a/tasks/deal-client/get-deal-id.js +++ b/tasks/deal-client/get-backup-item.js @@ -1,8 +1,8 @@ const CID = require('cids'); task( - "get-deal-id", - "Gets a DealID from PieceCID" + "get-backup-item", + "Get BackupItem, that does not include the DealArray (but includes the index of it)" ) .addParam("contract", "The address of the deal client solidity") .addParam("commP", "The PieceCID") @@ -11,12 +11,12 @@ task( const commP = taskArgs.commP; const commPasBytes = new CID(commP).bytes; const networkId = network.name; - console.log("Getting DealId on network", networkId) + console.log("Getting BackupItem on network", networkId) const wallet = new ethers.Wallet(network.config.accounts[0], ethers.provider); // Create a new wallet instance const DealClient = await ethers.getContractFactory("DealClient", wallet); // Create a DealClient contract factory const dealClient = await DealClient.attach(contractAddr); // Create a contract instance - let result = await dealClient.getDealId(commPasBytes); // Send transaction - console.log("The dealID is:", result); + let result = await dealClient.getBackupItem(commPasBytes); // Send transaction + console.log("The BackupItem is:", result); }) \ No newline at end of file diff --git a/tasks/deal-client/get-commp.js b/tasks/deal-client/get-commp.js new file mode 100644 index 0000000..cd03b73 --- /dev/null +++ b/tasks/deal-client/get-commp.js @@ -0,0 +1,22 @@ +const CID = require('cids'); + +task( + "get-commp", + "Get CommP from UniqID" + ) + .addParam("contract", "The address of the deal client solidity") + .addParam("uniqId", "The PieceCID, alias commP") + .setAction(async (taskArgs) => { + const contractAddr = taskArgs.contract; + const networkId = network.name; + console.log("Getting CommP from UniqID on network", networkId); + + const wallet = new ethers.Wallet(network.config.accounts[0], ethers.provider); + const DealClient = await ethers.getContractFactory("DealClient", wallet); + const dealClient = await DealClient.attach(contractAddr); + + //send a transaction to call makeDealProposal() method + //transaction = await dealClient.getDealProposal(proposalID) + let result = await dealClient.getCommpFromId(taskArgs.uniqId); + console.log("CommP:", result); + }) \ No newline at end of file diff --git a/tasks/deal-client/get-deal-proposal.js b/tasks/deal-client/get-deal-proposal.js index a7088ff..d515747 100644 --- a/tasks/deal-client/get-deal-proposal.js +++ b/tasks/deal-client/get-deal-proposal.js @@ -1,26 +1,22 @@ +const CID = require('cids'); + task( "get-deal-proposal", - "Gets a deal proposal from the proposal id" + "Get the Deal info the miner would fetch, from CommP. Will give back byte array." ) .addParam("contract", "The address of the deal client solidity") - .addParam("proposalId", "The proposal ID") + .addParam("uniqId", "The PieceCID, alias commP") .setAction(async (taskArgs) => { - const contractAddr = taskArgs.contract - const proposalID = taskArgs.proposalId - const networkId = network.name - console.log("Getting deal proposal on network", networkId) + const contractAddr = taskArgs.contract; + const networkId = network.name; + console.log("Getting bytes from UniqID on network", networkId); - //create a new wallet instance - const wallet = new ethers.Wallet(network.config.accounts[0], ethers.provider) - - //create a DealClient contract factory - const DealClient = await ethers.getContractFactory("DealClient", wallet) - //create a DealClient contract instance - //this is what you will call to interact with the deployed contract - const dealClient = await DealClient.attach(contractAddr) + const wallet = new ethers.Wallet(network.config.accounts[0], ethers.provider); + const DealClient = await ethers.getContractFactory("DealClient", wallet); + const dealClient = await DealClient.attach(contractAddr); //send a transaction to call makeDealProposal() method //transaction = await dealClient.getDealProposal(proposalID) - let result = await dealClient.getDealProposal(proposalID) - console.log("The deal proposal is:", result) + let result = await dealClient.getDealProposal(taskArgs.uniqId); + console.log("Bytes:", result); }) \ No newline at end of file diff --git a/tasks/deal-client/get-deals.js b/tasks/deal-client/get-deals.js new file mode 100644 index 0000000..7762d9b --- /dev/null +++ b/tasks/deal-client/get-deals.js @@ -0,0 +1,24 @@ +const CID = require('cids'); + +task( + "get-deals", + "Gets a deal proposal from the proposal id" + ) + .addParam("contract", "The address of the deal client solidity") + .addParam("commP", "The PieceCID, alias commP") + .setAction(async (taskArgs) => { + const contractAddr = taskArgs.contract; + const commP = taskArgs.commP; + const commPasBytes = new CID(commP).bytes; + const networkId = network.name; + console.log("Getting deal proposal on network", networkId); + + const wallet = new ethers.Wallet(network.config.accounts[0], ethers.provider); + const DealClient = await ethers.getContractFactory("DealClient", wallet); + const dealClient = await DealClient.attach(contractAddr); + + //send a transaction to call makeDealProposal() method + //transaction = await dealClient.getDealProposal(proposalID) + let result = await dealClient.getDeals(commPasBytes); + console.log("List of deals:", result); + }) \ No newline at end of file diff --git a/tasks/deal-client/make-deal-proposal.js b/tasks/deal-client/make-deal-proposal.js deleted file mode 100644 index 94da826..0000000 --- a/tasks/deal-client/make-deal-proposal.js +++ /dev/null @@ -1,76 +0,0 @@ -const CID = require('cids') - -task( - "make-deal-proposal", - "Makes a deal proposal via the client contract. This will ultimately emit an event that storage providers can listen too and choose to accept your deal." - ) - .addParam("contract", "The address of the deal client solidity") - .addParam("pieceCid", "The address of the DealRewarder contract") - .addParam("pieceSize", "The piece CID of the data you want to put up a bounty for") - .addParam("verifiedDeal", "Size of the data you are putting a bounty on") - .addParam("label", "The deal label (typically the raw cid)") - .addParam("startEpoch", "The epoch the deal will start") - .addParam("endEpoch", "The epoch the deal will end") - .addParam("storagePricePerEpoch", "The cost of the deal, in FIL, per epoch") - .addParam("providerCollateral", "The collateral, in FIL, to be put up by the storage provider") - .addParam("clientCollateral", "The collateral, in FIL, to be put up by the the client (which is you)") - .addParam("extraParamsVersion", "") - .addParam("locationRef", "Where the data you want to be stored is located") - .addParam("carSize", "The size of the .car file") - .addParam("skipIpniAnnounce", "") - .addParam("removeUnsealedCopy", "") - .setAction(async (taskArgs) => { - //store taskargs as useable variables - //convert piece CID string to hex bytes - const cid = taskArgs.pieceCid - const cidHexRaw = new CID(cid).toString('base16').substring(1) - const cidHex = "0x" + cidHexRaw - const contractAddr = taskArgs.contract - - const verified = (taskArgs.verifiedDeal === 'true') - const skipIpniAnnounce = (taskArgs.skipIpniAnnounce === 'true') - const removeUnsealedCopy = (taskArgs.removeUnsealedCopy === 'true') - - const extraParamsV1 = [ - taskArgs.locationRef, - taskArgs.carSize, - skipIpniAnnounce, - removeUnsealedCopy, - ] - - const DealRequestStruct = [ - cidHex, - taskArgs.pieceSize, - verified, - taskArgs.label, - taskArgs.startEpoch, - taskArgs.endEpoch, - taskArgs.storagePricePerEpoch, - taskArgs.providerCollateral, - taskArgs.clientCollateral, - taskArgs.extraParamsVersion, - extraParamsV1, - ] - const networkId = network.name - console.log("Making deal proposal on network", networkId) - - //create a new wallet instance - const wallet = new ethers.Wallet(network.config.accounts[0], ethers.provider) - - //create a DealClient contract factory - const DealClient = await ethers.getContractFactory("DealClient", wallet) - //create a DealClient contract instance - //this is what you will call to interact with the deployed contract - const dealClient = await DealClient.attach(contractAddr) - - //send a transaction to call makeDealProposal() method - transaction = await dealClient.makeDealProposal(DealRequestStruct) - transactionReceipt = await transaction.wait() - - //listen for DealProposalCreate event - const event = transactionReceipt.events[0].topics[0] - console.log("transactionReceipt: ", transactionReceipt); - console.log("Events: ", transactionReceipt.events); - console.log("Topics: ", transactionReceipt.events[0].topics); - console.log("Complete! Event Emitted. ProposalId is:", event) - }) \ No newline at end of file diff --git a/tasks/deal-client/start-backup.js b/tasks/deal-client/start-backup.js new file mode 100644 index 0000000..f3baeb2 --- /dev/null +++ b/tasks/deal-client/start-backup.js @@ -0,0 +1,55 @@ +const CID = require('cids') + +task( + "start-backup", + "Start the backup proccess, it will create a BackupItem in the contract, and later the contract can keep target redundancy based on that. It will try to make initial deals." + ) + .addParam("contract", "The address of the deal client solidity") + .addParam("pieceCid", "PiceCID, alias commP") + .addParam("pieceSize", "Size of PieceCID") + .addParam("label", "The deal label (typically the raw cid)") + .addParam("dealDuration", "Deal duration in epoch") + .addParam("maxPricePerEpoch", "The max cost of the deal, in FIL, per epoch") + .addParam("originalLocation", "Location ref, the original location of the data, later probably it will mirror it from existing provider") + .addParam("carSize", "The size of the .car file") + .setAction(async (taskArgs) => { + //store taskargs as useable variables + //convert piece CID string to hex bytes + const cid = taskArgs.pieceCid + const cidHexRaw = new CID(cid).toString('base16').substring(1) + const cidHex = "0x" + cidHexRaw + const contractAddr = taskArgs.contract + + const BackupRequestStruct = { + pieceCID: cidHex, + pieceSize: taskArgs.pieceSize, + label: taskArgs.label, + dealDuration: taskArgs.dealDuration, + maxPricePerEpoch: taskArgs.maxPricePerEpoch, + originalLocation: taskArgs.originalLocation, + carSize: taskArgs.carSize, + } + + const networkId = network.name + console.log("Making deal proposal on network", networkId) + + //create a new wallet instance + const wallet = new ethers.Wallet(network.config.accounts[0], ethers.provider) + + //create a DealClient contract factory + const DealClient = await ethers.getContractFactory("DealClient", wallet) + //create a DealClient contract instance + //this is what you will call to interact with the deployed contract + const dealClient = await DealClient.attach(contractAddr) + + //send a transaction to call makeDealProposal() method + transaction = await dealClient.startBackup(BackupRequestStruct) + transactionReceipt = await transaction.wait() + + //listen for DealProposalCreate event + const event = transactionReceipt.events[0].topics[0] + console.log("transactionReceipt: ", transactionReceipt); + console.log("Events: ", transactionReceipt.events); + console.log("Topics: ", transactionReceipt.events[0].topics); + console.log("Complete! Event Emitted. ProposalId is:", event) + }) \ No newline at end of file diff --git a/tasks/index.js b/tasks/index.js index 73f267a..f70b7bb 100644 --- a/tasks/index.js +++ b/tasks/index.js @@ -1,5 +1,7 @@ exports.getAddress = require("./get-address") exports.storeAll = require("./filecoin-market-consumer/store-all") -exports.makeDealProposal = require("./deal-client/make-deal-proposal") +exports.makeDealProposal = require("./deal-client/start-backup") +exports.getDealProposal = require("./deal-client/get-deals") +exports.getDealProposal = require("./deal-client/get-commp") exports.getDealProposal = require("./deal-client/get-deal-proposal") -exports.getDealId = require("./deal-client/get-deal-id") \ No newline at end of file +exports.getDealId = require("./deal-client/get-backup-item") \ No newline at end of file