Use bid hash as contract id
Adds nonce to storage request to ensure uniqueness.
This commit is contained in:
parent
08cedae4bf
commit
c3e85c675a
|
@ -20,48 +20,48 @@ contract StorageContracts {
|
|||
}
|
||||
|
||||
uint numberOfContracts;
|
||||
mapping(uint => Contract) contracts;
|
||||
mapping(bytes32 => Contract) contracts;
|
||||
|
||||
function duration(uint contractId) public view returns (uint) {
|
||||
function duration(bytes32 contractId) public view returns (uint) {
|
||||
return contracts[contractId].duration;
|
||||
}
|
||||
|
||||
function size(uint contractId) public view returns (uint) {
|
||||
function size(bytes32 contractId) public view returns (uint) {
|
||||
return contracts[contractId].size;
|
||||
}
|
||||
|
||||
function contentHash(uint contractId) public view returns (bytes32) {
|
||||
function contentHash(bytes32 contractId) public view returns (bytes32) {
|
||||
return contracts[contractId].contentHash;
|
||||
}
|
||||
|
||||
function price(uint contractId) public view returns (uint) {
|
||||
function price(bytes32 contractId) public view returns (uint) {
|
||||
return contracts[contractId].price;
|
||||
}
|
||||
|
||||
function host(uint contractId) public view returns (address) {
|
||||
function host(bytes32 contractId) public view returns (address) {
|
||||
return contracts[contractId].host;
|
||||
}
|
||||
|
||||
function proofPeriod(uint contractId) public view returns (uint) {
|
||||
function proofPeriod(bytes32 contractId) public view returns (uint) {
|
||||
return contracts[contractId].proofPeriod;
|
||||
}
|
||||
|
||||
function proofTimeout(uint contractId) public view returns (uint) {
|
||||
function proofTimeout(bytes32 contractId) public view returns (uint) {
|
||||
return contracts[contractId].proofTimeout;
|
||||
}
|
||||
|
||||
function missingProofs(uint contractId) public view returns (uint) {
|
||||
function missingProofs(bytes32 contractId) public view returns (uint) {
|
||||
return contracts[contractId].missingProofs;
|
||||
}
|
||||
|
||||
function newContract(
|
||||
uint contractId,
|
||||
uint _duration,
|
||||
uint _size,
|
||||
bytes32 _contentHash,
|
||||
uint _price,
|
||||
uint _proofPeriod,
|
||||
uint _proofTimeout,
|
||||
bytes32 _nonce,
|
||||
uint _bidExpiry,
|
||||
address _host,
|
||||
bytes memory requestSignature,
|
||||
|
@ -74,13 +74,15 @@ contract StorageContracts {
|
|||
_size,
|
||||
_contentHash,
|
||||
_proofPeriod,
|
||||
_proofTimeout
|
||||
_proofTimeout,
|
||||
_nonce
|
||||
);
|
||||
bytes32 bidHash = hashBid(requestHash, _bidExpiry, _price);
|
||||
checkSignature(requestSignature, requestHash, msg.sender);
|
||||
checkSignature(bidSignature, bidHash, _host);
|
||||
checkProofTimeout(_proofTimeout);
|
||||
checkBidExpiry(_bidExpiry);
|
||||
bytes32 contractId = bidHash;
|
||||
checkId(contractId);
|
||||
Contract storage c = contracts[contractId];
|
||||
c.initialized = true;
|
||||
|
@ -100,7 +102,8 @@ contract StorageContracts {
|
|||
uint _size,
|
||||
bytes32 _hash,
|
||||
uint _proofPeriod,
|
||||
uint _proofTimeout
|
||||
uint _proofTimeout,
|
||||
bytes32 _nonce
|
||||
)
|
||||
internal pure
|
||||
returns (bytes32)
|
||||
|
@ -111,7 +114,8 @@ contract StorageContracts {
|
|||
_size,
|
||||
_hash,
|
||||
_proofPeriod,
|
||||
_proofTimeout
|
||||
_proofTimeout,
|
||||
_nonce
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -148,7 +152,7 @@ contract StorageContracts {
|
|||
require(expiry > block.timestamp, "Bid expired");
|
||||
}
|
||||
|
||||
function checkId(uint contractId) internal view {
|
||||
function checkId(bytes32 contractId) internal view {
|
||||
require(
|
||||
!contracts[contractId].initialized,
|
||||
"A contract with this id already exists"
|
||||
|
@ -160,7 +164,7 @@ contract StorageContracts {
|
|||
// timeout for it to be valid. Whether a proof is required is determined
|
||||
// randomly, but on average it is once every proof period.
|
||||
function isProofRequired(
|
||||
uint contractId,
|
||||
bytes32 contractId,
|
||||
uint blocknumber
|
||||
)
|
||||
public view
|
||||
|
@ -172,7 +176,7 @@ contract StorageContracts {
|
|||
}
|
||||
|
||||
function isProofTimedOut(
|
||||
uint contractId,
|
||||
bytes32 contractId,
|
||||
uint blocknumber
|
||||
)
|
||||
internal view
|
||||
|
@ -183,7 +187,7 @@ contract StorageContracts {
|
|||
}
|
||||
|
||||
function submitProof(
|
||||
uint contractId,
|
||||
bytes32 contractId,
|
||||
uint blocknumber,
|
||||
bool proof
|
||||
)
|
||||
|
@ -203,7 +207,7 @@ contract StorageContracts {
|
|||
c.proofReceived[blocknumber] = true;
|
||||
}
|
||||
|
||||
function markProofAsMissing(uint contractId, uint blocknumber) public {
|
||||
function markProofAsMissing(bytes32 contractId, uint blocknumber) public {
|
||||
Contract storage c = contracts[contractId];
|
||||
require(
|
||||
isProofTimedOut(contractId, blocknumber),
|
||||
|
|
|
@ -10,6 +10,7 @@ describe("Storage Contracts", function () {
|
|||
const proofPeriod = 8 // 8 blocks ≈ 2 minutes
|
||||
const proofTimeout = 4 // 4 blocks ≈ 1 minute
|
||||
const price = 42
|
||||
const nonce = ethers.utils.randomBytes(32)
|
||||
|
||||
var contracts
|
||||
var client, host
|
||||
|
@ -26,24 +27,25 @@ describe("Storage Contracts", function () {
|
|||
size,
|
||||
contentHash,
|
||||
proofPeriod,
|
||||
proofTimeout
|
||||
proofTimeout,
|
||||
nonce
|
||||
)
|
||||
bidExpiry = Math.round(Date.now() / 1000) + 60 * 60 // 1 hour from now
|
||||
bidHash = hashBid(requestHash, bidExpiry, price)
|
||||
id = Math.round(Math.random() * 99999999) // randomly chosen contract id
|
||||
id = bidHash
|
||||
})
|
||||
|
||||
describe("when properly instantiated", function () {
|
||||
|
||||
beforeEach(async function () {
|
||||
await contracts.newContract(
|
||||
id,
|
||||
duration,
|
||||
size,
|
||||
contentHash,
|
||||
price,
|
||||
proofPeriod,
|
||||
proofTimeout,
|
||||
nonce,
|
||||
bidExpiry,
|
||||
await host.getAddress(),
|
||||
await sign(client, requestHash),
|
||||
|
@ -82,26 +84,26 @@ describe("Storage Contracts", function () {
|
|||
|
||||
it("cannot be created when contract id already used", async function () {
|
||||
await contracts.newContract(
|
||||
id,
|
||||
duration,
|
||||
size,
|
||||
contentHash,
|
||||
price,
|
||||
proofPeriod,
|
||||
proofTimeout,
|
||||
nonce,
|
||||
bidExpiry,
|
||||
await host.getAddress(),
|
||||
await sign(client, requestHash),
|
||||
await sign(host, bidHash)
|
||||
)
|
||||
await expect(contracts.newContract(
|
||||
id,
|
||||
duration,
|
||||
size,
|
||||
contentHash,
|
||||
price,
|
||||
proofPeriod,
|
||||
proofTimeout,
|
||||
nonce,
|
||||
bidExpiry,
|
||||
await host.getAddress(),
|
||||
await sign(client, requestHash),
|
||||
|
@ -115,17 +117,18 @@ describe("Storage Contracts", function () {
|
|||
size,
|
||||
contentHash,
|
||||
proofPeriod,
|
||||
proofTimeout
|
||||
proofTimeout,
|
||||
nonce
|
||||
)
|
||||
let invalidSignature = await sign(client, invalidHash)
|
||||
await expect(contracts.newContract(
|
||||
id,
|
||||
duration,
|
||||
size,
|
||||
contentHash,
|
||||
price,
|
||||
proofPeriod,
|
||||
proofTimeout,
|
||||
nonce,
|
||||
bidExpiry,
|
||||
await host.getAddress(),
|
||||
invalidSignature,
|
||||
|
@ -137,13 +140,13 @@ describe("Storage Contracts", function () {
|
|||
let invalidBid = hashBid(requestHash, bidExpiry, price - 1)
|
||||
let invalidSignature = await sign(host, invalidBid)
|
||||
await expect(contracts.newContract(
|
||||
id,
|
||||
duration,
|
||||
size,
|
||||
contentHash,
|
||||
price,
|
||||
proofPeriod,
|
||||
proofTimeout,
|
||||
nonce,
|
||||
bidExpiry,
|
||||
await host.getAddress(),
|
||||
await sign(client, requestHash),
|
||||
|
@ -158,17 +161,18 @@ describe("Storage Contracts", function () {
|
|||
size,
|
||||
contentHash,
|
||||
proofPeriod,
|
||||
invalidTimeout
|
||||
invalidTimeout,
|
||||
nonce
|
||||
)
|
||||
bidHash = hashBid(requestHash, bidExpiry, price)
|
||||
await expect(contracts.newContract(
|
||||
id,
|
||||
duration,
|
||||
size,
|
||||
contentHash,
|
||||
price,
|
||||
proofPeriod,
|
||||
invalidTimeout,
|
||||
nonce,
|
||||
bidExpiry,
|
||||
await host.getAddress(),
|
||||
await sign(client, requestHash),
|
||||
|
@ -180,13 +184,13 @@ describe("Storage Contracts", function () {
|
|||
let expired = Math.round(Date.now() / 1000) - 60 // 1 minute ago
|
||||
let bidHash = hashBid(requestHash, expired, price)
|
||||
await expect(contracts.newContract(
|
||||
id,
|
||||
duration,
|
||||
size,
|
||||
contentHash,
|
||||
price,
|
||||
proofPeriod,
|
||||
proofTimeout,
|
||||
nonce,
|
||||
expired,
|
||||
await host.getAddress(),
|
||||
await sign(client, requestHash),
|
||||
|
@ -218,13 +222,13 @@ describe("Storage Contracts", function () {
|
|||
|
||||
beforeEach(async function () {
|
||||
await contracts.newContract(
|
||||
id,
|
||||
duration,
|
||||
size,
|
||||
contentHash,
|
||||
price,
|
||||
proofPeriod,
|
||||
proofTimeout,
|
||||
nonce,
|
||||
bidExpiry,
|
||||
await host.getAddress(),
|
||||
await sign(client, requestHash),
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
const { ethers } = require("hardhat")
|
||||
|
||||
function hashRequest(duration, size, hash, proofPeriod, proofTimeout) {
|
||||
function hashRequest(duration, size, hash, proofPeriod, proofTimeout, nonce) {
|
||||
const type = "[dagger.request.v1]"
|
||||
return ethers.utils.solidityKeccak256(
|
||||
["string", "uint", "uint", "bytes32", "uint", "uint"],
|
||||
["[dagger.request.v1]", duration, size, hash, proofPeriod, proofTimeout]
|
||||
["string", "uint", "uint", "bytes32", "uint", "uint", "bytes32"],
|
||||
[type, duration, size, hash, proofPeriod, proofTimeout, nonce]
|
||||
)
|
||||
}
|
||||
|
||||
function hashBid(requestHash, expiry, price) {
|
||||
const type = "[dagger.bid.v1]"
|
||||
return ethers.utils.solidityKeccak256(
|
||||
["string", "bytes32", "uint", "uint"],
|
||||
["[dagger.bid.v1]", requestHash, expiry, price]
|
||||
[type, requestHash, expiry, price]
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue