diff --git a/contracts/StorageContract.sol b/contracts/StorageContract.sol index fef4ee4..dc0b755 100644 --- a/contracts/StorageContract.sol +++ b/contracts/StorageContract.sol @@ -6,6 +6,7 @@ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; contract StorageContract { uint public immutable duration; // contract duration in seconds uint public immutable size; // storage size in bytes + bytes32 public immutable contentHash; // hash of data that is to be stored uint public immutable price; // price in coins address public immutable host; // host that provides storage uint public immutable proofPeriod; // average time between proofs (in blocks) @@ -14,6 +15,7 @@ contract StorageContract { constructor(uint _duration, uint _size, + bytes32 _contentHash, uint _price, uint _proofPeriod, uint _proofTimeout, @@ -21,7 +23,13 @@ contract StorageContract { bytes memory requestSignature, bytes memory bidSignature) { - bytes32 requestHash = hashRequest(_duration, _size, _proofPeriod, _proofTimeout); + bytes32 requestHash = hashRequest( + _duration, + _size, + _contentHash, + _proofPeriod, + _proofTimeout + ); bytes32 bidHash = hashBid(requestHash, _price); checkSignature(requestSignature, requestHash, msg.sender); checkSignature(bidSignature, bidHash, _host); @@ -29,6 +37,7 @@ contract StorageContract { duration = _duration; size = _size; price = _price; + contentHash = _contentHash; host = _host; proofPeriod = _proofPeriod; proofTimeout = _proofTimeout; @@ -36,7 +45,13 @@ contract StorageContract { } // Creates hash for a storage request that can be used to check its signature. - function hashRequest(uint _duration, uint _size, uint _proofPeriod, uint _proofTimeout) + function hashRequest( + uint _duration, + uint _size, + bytes32 _hash, + uint _proofPeriod, + uint _proofTimeout + ) internal pure returns (bytes32) { @@ -44,6 +59,7 @@ contract StorageContract { "[dagger.request.v1]", _duration, _size, + _hash, _proofPeriod, _proofTimeout )); diff --git a/test/StorageContract.test.js b/test/StorageContract.test.js index aff1179..511672c 100644 --- a/test/StorageContract.test.js +++ b/test/StorageContract.test.js @@ -6,6 +6,7 @@ describe("Storage Contract", function () { const duration = 31 * 24 * 60 * 60 // 31 days const size = 1 * 1024 * 1024 * 1024 // 1 Gigabyte + const contentHash = ethers.utils.sha256("0xdeadbeef") // hash of content const proofPeriod = 8 // 8 blocks ≈ 2 minutes const proofTimeout = 4 // 4 blocks ≈ 1 minute const price = 42 @@ -18,7 +19,13 @@ describe("Storage Contract", function () { beforeEach(async function () { [client, host] = await ethers.getSigners() StorageContract = await ethers.getContractFactory("StorageContract") - requestHash = hashRequest(duration, size, proofPeriod, proofTimeout) + requestHash = hashRequest( + duration, + size, + contentHash, + proofPeriod, + proofTimeout + ) bidHash = hashBid(requestHash, price) }) @@ -28,6 +35,7 @@ describe("Storage Contract", function () { contract = await StorageContract.deploy( duration, size, + contentHash, price, proofPeriod, proofTimeout, @@ -45,6 +53,10 @@ describe("Storage Contract", function () { expect(await contract.size()).to.equal(size) }) + it("contains the hash of the data that is to be stored", async function () { + expect(await contract.contentHash()).to.equal(contentHash) + }) + it("has a price", async function () { expect(await contract.price()).to.equal(price) }) @@ -63,11 +75,18 @@ describe("Storage Contract", function () { }) it("cannot be created when client signature is invalid", async function () { - let invalidHash = hashRequest(duration + 1, size, proofPeriod, proofTimeout) + let invalidHash = hashRequest( + duration + 1, + size, + contentHash, + proofPeriod, + proofTimeout + ) let invalidSignature = await sign(client, invalidHash) await expect(StorageContract.deploy( duration, size, + contentHash, price, proofPeriod, proofTimeout, @@ -82,6 +101,7 @@ describe("Storage Contract", function () { await expect(StorageContract.deploy( duration, size, + contentHash, price, proofPeriod, proofTimeout, @@ -93,11 +113,18 @@ describe("Storage Contract", function () { it("cannot be created when proof timeout is too large", async function () { let invalidTimeout = 129 // max proof timeout is 128 blocks - requestHash = hashRequest(duration, size, proofPeriod, invalidTimeout) + requestHash = hashRequest( + duration, + size, + contentHash, + proofPeriod, + invalidTimeout + ) bidHash = hashBid(requestHash, price) await expect(StorageContract.deploy( duration, size, + contentHash, price, proofPeriod, invalidTimeout, @@ -127,6 +154,7 @@ describe("Storage Contract", function () { contract = await StorageContract.deploy( duration, size, + contentHash, price, proofPeriod, proofTimeout, @@ -161,7 +189,6 @@ describe("Storage Contract", function () { }) }) -// TDOO: add root hash of data // TODO: payment on constructor // TODO: contract start and timeout // TODO: missed proofs diff --git a/test/marketplace.js b/test/marketplace.js index 5a2e078..2aad7cc 100644 --- a/test/marketplace.js +++ b/test/marketplace.js @@ -1,9 +1,9 @@ const { ethers } = require("hardhat") -function hashRequest(duration, size, proofPeriod, proofTimeout) { +function hashRequest(duration, size, hash, proofPeriod, proofTimeout) { return ethers.utils.solidityKeccak256( - ["string", "uint", "uint", "uint", "uint"], - ["[dagger.request.v1]", duration, size, proofPeriod, proofTimeout] + ["string", "uint", "uint", "bytes32", "uint", "uint"], + ["[dagger.request.v1]", duration, size, hash, proofPeriod, proofTimeout] ) }