Skip to content

Commit

Permalink
Another approach to getWaitForNSubmissionsPromise/getMiningCycleCompl…
Browse files Browse the repository at this point in the history
…etePromise
  • Loading branch information
area committed May 8, 2024
1 parent 16df261 commit 04ed490
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 69 deletions.
99 changes: 52 additions & 47 deletions helpers/test-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ const {

const IColony = artifacts.require("IColony");
const IMetaColony = artifacts.require("IMetaColony");
const IColonyNetwork = artifacts.require("IColonyNetwork");
const ITokenLocking = artifacts.require("ITokenLocking");
const Token = artifacts.require("Token");
const IReputationMiningCycle = artifacts.require("IReputationMiningCycle");
Expand Down Expand Up @@ -1129,69 +1128,75 @@ exports.getColonyNetworkEditable = async function getColonyNetworkEditable(colon
return colonyNetworkEditable;
};

exports.getWaitForNSubmissionsPromise = async function getWaitForNSubmissionsPromise(repCycleEthers, rootHash, nLeaves, jrh, n) {
const listenerCount = repCycleEthers.listenerCount("ReputationRootHashSubmitted");
exports.getWaitForNSubmissionsPromise = function getWaitForNSubmissionsPromise(repCycleEthers, fromBlock, rootHash, nLeaves, jrh, n) {
if (!repCycleEthers || !fromBlock) {
throw new Error("repCycleEthers and fromBlock must be defined when calling getWaitForNSubmissionsPromise");
}

const p = new Promise(function (resolve, reject) {
repCycleEthers.on("ReputationRootHashSubmitted", async (_miner, _hash, _nLeaves, _jrh, _entryIndex, event) => {
let nSubmissions;
// We want to see when our hash hits N submissions
// If we've passed in our hash, we check how many submissions that hash has
// If not, we're waiting for N submissions from any hash
if (rootHash) {
nSubmissions = await repCycleEthers.getNSubmissionsForHash(rootHash, nLeaves, jrh);
} else {
nSubmissions = await repCycleEthers.getNSubmissionsForHash(_hash, _nLeaves, _jrh);
}
if (nSubmissions.toNumber() >= n) {
event.removeListener();
resolve();
return new Promise(function (resolve, reject) {
const intervalId = setInterval(async () => {
const filter = repCycleEthers.filters.ReputationRootHashSubmitted();
const events = await repCycleEthers.queryFilter(filter, fromBlock);
// console.log(events)
if (events.length > 0) {
if (rootHash) {
const nSubmissions = await repCycleEthers.getNSubmissionsForHash(rootHash, nLeaves, jrh);
if (nSubmissions.toNumber() >= n) {
clearInterval(intervalId);
resolve();
}
} else {
// Check all events
await Promise.all(
events.map(async (event) => {
const nSubmissions = await repCycleEthers.getNSubmissionsForHash(event.args._newHash, event.args._nLeaves, event.args._jrh);
if (nSubmissions.toNumber() >= n) {
clearInterval(intervalId);
resolve();
}
}),
);
}
}
});
}, 1000);

// After 60s, we throw a timeout error
// After 60s, throw a timeout error
setTimeout(() => {
clearInterval(intervalId);
reject(new Error("Timeout while waiting for 12 hash submissions"));
}, 60 * 1000);
});

// Only return the promise once the handler has been set up
while (listenerCount === repCycleEthers.listenerCount("ReputationRootHashSubmitted")) {
await exports.sleep(1000);
}

return p;
};

exports.getMiningCycleCompletePromise = async function getMiningCycleCompletePromise(colonyNetworkEthers, oldHash, expectedHash) {
const listenerCount = colonyNetworkEthers.listenerCount("ReputationMiningCycleComplete");
exports.getMiningCycleCompletePromise = function getMiningCycleCompletePromise(colonyNetworkEthers, fromBlock, oldHash, expectedHash) {
if (!colonyNetworkEthers || !fromBlock) {
throw new Error("colonyNetworkEthers and fromBlock must be defined when calling getMiningCycleCompletePromise");
}

const p = new Promise(function (resolve, reject) {
colonyNetworkEthers.on("ReputationMiningCycleComplete", async (_hash, _nLeaves, event) => {
const colonyNetwork = await IColonyNetwork.at(colonyNetworkEthers.address);
const newHash = await colonyNetwork.getReputationRootHash();
if (oldHash) {
expect(newHash).to.not.equal(oldHash, "The old and new hashes are the same");
}
if (expectedHash) {
expect(newHash).to.equal(expectedHash, "The network root hash doesn't match the one submitted");
return new Promise(function (resolve, reject) {
const intervalId = setInterval(async () => {
const filter = colonyNetworkEthers.filters.ReputationMiningCycleComplete();
const events = await colonyNetworkEthers.queryFilter(filter, fromBlock);
if (events.length > 0) {
const event = events[events.length - 1];
const newHash = event.args[0];
if (oldHash) {
expect(newHash).to.not.equal(oldHash, "The old and new hashes are the same");
}
if (expectedHash) {
expect(newHash).to.equal(expectedHash, "The network root hash doesn't match the one submitted");
}
clearInterval(intervalId);
resolve();
}
event.removeListener();
resolve();
});
}, 1000);

// After 30s, we throw a timeout error
setTimeout(() => {
clearInterval(intervalId);
reject(new Error("ERROR: timeout while waiting for confirming hash"));
}, 30 * 1000);
});

// Only return the promise once the handler has been set up
while (listenerCount === colonyNetworkEthers.listenerCount("ReputationMiningCycleComplete")) {
await exports.sleep(1000);
}

return p;
};

exports.encodeTxData = async function encodeTxData(colony, functionName, args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,18 @@ hre.__SOLIDITY_COVERAGE_RUNNING
const oldHash = await colonyNetwork.getReputationRootHash();

const repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, rootHash, nLeaves, jrh, 12);
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, rootHash, nLeaves, jrh, 12);

// Forward through most of the cycle duration and wait for the client to submit all 12 allowed entries
await forwardTime(MINING_CYCLE_DURATION * 0.9, this);
await receive12Submissions;

const miningCycleComplete = getMiningCycleCompletePromise(reputationMinerClient._miner.colonyNetwork, oldHash, rootHash);
const miningCycleComplete = getMiningCycleCompletePromise(
reputationMinerClient._miner.colonyNetwork,
(await currentBlock()).number,
oldHash,
rootHash,
);

// Forward time to the end of the mining cycle and since we are the only miner, check the client confirmed our hash correctly
await forwardTime(MINING_CYCLE_DURATION * 0.1 + CHALLENGE_RESPONSE_WINDOW_DURATION + 1, this);
Expand Down Expand Up @@ -161,13 +166,18 @@ hre.__SOLIDITY_COVERAGE_RUNNING
const oldHash = await colonyNetwork.getReputationRootHash();

const repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, rootHash, nLeaves, jrh, 12);
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, rootHash, nLeaves, jrh, 12);

// Forward through most of the cycle duration and wait for the client to submit all 12 allowed entries
await forwardTime(MINING_CYCLE_DURATION * 0.9, this);
await receive12Submissions;

const miningCycleComplete = getMiningCycleCompletePromise(reputationMinerClient._miner.colonyNetwork, oldHash, rootHash);
const miningCycleComplete = getMiningCycleCompletePromise(
reputationMinerClient._miner.colonyNetwork,
(await currentBlock()).number,
oldHash,
rootHash,
);

let oracleCheckInterval;

Expand Down Expand Up @@ -216,7 +226,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING
const oldHash = await colonyNetwork.getReputationRootHash();

const repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();
const receive2Submissions = getWaitForNSubmissionsPromise(repCycleEthers, rootHash, nLeaves, jrh, 2);
const receive2Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, rootHash, nLeaves, jrh, 2);

// Forward through half of the cycle duration and wait for the client to submit some entries
await forwardTime(MINING_CYCLE_DURATION / 2, this);
Expand All @@ -233,12 +243,17 @@ hre.__SOLIDITY_COVERAGE_RUNNING
processingDelay: 1,
});
await reputationMinerClient2.initialise(colonyNetwork.address, startingBlockNumber);
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, rootHash, nLeaves, jrh, 12);
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, rootHash, nLeaves, jrh, 12);

await mineBlock();
await receive12Submissions;

const miningCycleComplete = getMiningCycleCompletePromise(reputationMinerClient._miner.colonyNetwork, oldHash, rootHash);
const miningCycleComplete = getMiningCycleCompletePromise(
reputationMinerClient._miner.colonyNetwork,
(await currentBlock()).number,
oldHash,
rootHash,
);

// Forward time to the end of the mining cycle and since we are the only miner, check the client confirmed our hash correctly
await forwardTime(MINING_CYCLE_DURATION * 0.6 + MINING_CYCLE_DURATION, this);
Expand All @@ -253,7 +268,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING
const jrh = await reputationMinerClient._miner.justificationTree.getRootHash();

const repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, rootHash, nLeaves, jrh, 12);
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, rootHash, nLeaves, jrh, 12);

// Make a submission from the second client and then await the remaining 11 submissions from the first client
await goodClient.loadState(oldHash);
Expand All @@ -264,7 +279,12 @@ hre.__SOLIDITY_COVERAGE_RUNNING
await checkSuccessEthers(goodClient.submitRootHash());
await receive12Submissions;

const miningCycleComplete = getMiningCycleCompletePromise(reputationMinerClient._miner.colonyNetwork, oldHash, rootHash);
const miningCycleComplete = getMiningCycleCompletePromise(
reputationMinerClient._miner.colonyNetwork,
(await currentBlock()).number,
oldHash,
rootHash,
);

// Forward time to the end of the mining cycle and since we are the only miner, check the client confirmed our hash correctly
await forwardTime(MINING_CYCLE_DURATION / 2 + CHALLENGE_RESPONSE_WINDOW_DURATION + 1, this);
Expand All @@ -288,7 +308,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING
const completionAddresses = [];
while (!differentAddresses) {
const repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, null, null, null, 12);
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, null, null, null, 12);

// Forward time and wait for the client to submit all 12 allowed entries
await forwardTime(MINING_CYCLE_DURATION / 2, this);
Expand Down Expand Up @@ -357,7 +377,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING
let firstSubmissionBlockNumber = latestBlock.number;

let repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();
let receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, null, null, null, 12);
let receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, null, null, null, 12);

await forwardTime(MINING_CYCLE_DURATION / 2, this);
const oldHash = await colonyNetwork.getReputationRootHash();
Expand Down Expand Up @@ -427,7 +447,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING

// So we've now seen a miner lose a race - let's check they can go through a cycle correctly.
repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();
receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, null, null, null, 12);
receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, null, null, null, 12);

latestBlock = await currentBlock();
firstSubmissionBlockNumber = latestBlock.number;
Expand Down Expand Up @@ -483,7 +503,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING

const repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();

const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, rootHash, nLeaves, jrh, 12);
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, rootHash, nLeaves, jrh, 12);

// Forward through most of the cycle duration
await forwardTime(MINING_CYCLE_DURATION / 2, this);
Expand Down Expand Up @@ -684,7 +704,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING
expect(adapter.outputs[0]).to.equal("Successfully resumed pre-submission", "The client didn't resume pre-submission");
await reputationMinerClient2.close();

const receive2Submissions = getWaitForNSubmissionsPromise(repCycleEthers, rootHash, nLeaves, jrh, 2);
const receive2Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, rootHash, nLeaves, jrh, 2);

// Forward through half of the cycle duration and wait for the client to submit some entries
await forwardTime(MINING_CYCLE_DURATION / 2, this);
Expand Down Expand Up @@ -728,7 +748,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING

const repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();

const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, rootHash, nLeaves, jrh, 12);
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, rootHash, nLeaves, jrh, 12);

// Forward through most of the cycle duration
await forwardTime(MINING_CYCLE_DURATION / 2, this);
Expand Down Expand Up @@ -828,7 +848,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING

const repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();

const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, rootHash, nLeaves, jrh, 12);
const receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, rootHash, nLeaves, jrh, 12);
const openingTimestamp = await repCycleEthers.getReputationMiningWindowOpenTimestamp();

// Forward through most of the cycle duration
Expand Down Expand Up @@ -900,7 +920,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING

// Add a listener to process log for when a new cycle starts, which won't happen yet because the submission window is still open

const newCycleStart = getMiningCycleCompletePromise(reputationMinerClient._miner.colonyNetwork);
const newCycleStart = getMiningCycleCompletePromise(reputationMinerClient._miner.colonyNetwork, (await currentBlock()).number);

await forwardTime(CHALLENGE_RESPONSE_WINDOW_DURATION + 1, this);

Expand All @@ -920,7 +940,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING
// Advance through a reputation cycle
let rootHash = await reputationMinerClient._miner.getRootHash();

let receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, null, null, null, 12);
let receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, null, null, null, 12);

const delayedReputationMinerClient = new ReputationMinerClient({
loader,
Expand All @@ -947,7 +967,12 @@ hre.__SOLIDITY_COVERAGE_RUNNING

let oldHash = await colonyNetwork.getReputationRootHash();

let miningCycleComplete = getMiningCycleCompletePromise(reputationMinerClient._miner.colonyNetwork, oldHash, rootHash);
let miningCycleComplete = getMiningCycleCompletePromise(
reputationMinerClient._miner.colonyNetwork,
(await currentBlock()).number,
oldHash,
rootHash,
);

// Forward time to the end of the mining cycle and since we are the only miner, check the client confirmed our hash correctly
await forwardTimeTo(openingTimestamp + MINING_CYCLE_DURATION + CHALLENGE_RESPONSE_WINDOW_DURATION, this);
Expand All @@ -957,14 +982,19 @@ hre.__SOLIDITY_COVERAGE_RUNNING
repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();
openingTimestamp = parseInt(await repCycleEthers.getReputationMiningWindowOpenTimestamp(), 10);

receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, null, null, null, 12);
receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, null, null, null, 12);

await forwardTimeTo(openingTimestamp + MINING_CYCLE_DURATION * 0.9, this);
await receive12Submissions;

rootHash = await reputationMinerClient._miner.getRootHash();
oldHash = await colonyNetwork.getReputationRootHash();
miningCycleComplete = getMiningCycleCompletePromise(reputationMinerClient._miner.colonyNetwork, oldHash, rootHash);
miningCycleComplete = getMiningCycleCompletePromise(
reputationMinerClient._miner.colonyNetwork,
(await currentBlock()).number,
oldHash,
rootHash,
);

await forwardTimeTo(openingTimestamp + MINING_CYCLE_DURATION + CHALLENGE_RESPONSE_WINDOW_DURATION, this);
await miningCycleComplete;
Expand All @@ -979,7 +1009,7 @@ hre.__SOLIDITY_COVERAGE_RUNNING
repCycleEthers = await reputationMinerClient._miner.getActiveRepCycle();
openingTimestamp = parseInt(await repCycleEthers.getReputationMiningWindowOpenTimestamp(), 10);

receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, null, null, null, 12);
receive12Submissions = getWaitForNSubmissionsPromise(repCycleEthers, (await currentBlock()).number, null, null, null, 12);

await forwardTimeTo(openingTimestamp + MINING_CYCLE_DURATION * 0.9, this);
await receive12Submissions;
Expand Down

0 comments on commit 04ed490

Please sign in to comment.