dao-governance-framework/forum-network/src/tests/availability.test.html

191 lines
5.0 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<head>
<title>Availability test</title>
2023-01-26 11:15:25 -06:00
<link type="text/css" rel="stylesheet" href="../index.css" />
</head>
<body>
<div id="availability-test"></div>
</body>
<script type="module">
2023-01-18 01:07:10 -06:00
import { Box } from '../classes/box.js';
import { Scene } from '../classes/scene.js';
import { Expert } from '../classes/expert.js';
import { Bench } from '../classes/bench.js';
import { Business } from '../classes/business.js';
import { Availability } from '../classes/availability.js';
import { delay } from '../util.js';
import { Forum } from '../classes/forum.js';
import { Public } from '../classes/public.js';
import { PostContent } from '../classes/post-content.js';
const DELAY_INTERVAL = 500;
2023-01-18 01:07:10 -06:00
const rootElement = document.getElementById('availability-test');
const rootBox = new Box('rootBox', rootElement).flex();
2023-01-18 01:07:10 -06:00
const scene = (window.scene = new Scene('Availability test', rootBox));
2023-01-08 20:19:33 -06:00
scene.withSequenceDiagram();
scene.withFlowchart();
2023-01-27 21:20:13 -06:00
scene.withTable();
const experts = (window.experts = []);
2023-01-03 12:00:12 -06:00
const newExpert = async () => {
const index = experts.length;
2023-01-03 12:00:12 -06:00
const name = `Expert${index + 1}`;
const expert = await new Expert(name, scene).initialize();
experts.push(expert);
return expert;
};
const expert1 = await newExpert();
const expert2 = await newExpert();
2023-01-18 01:07:10 -06:00
const forum = (window.forum = new Forum('Forum', scene));
const bench = (window.bench = new Bench(forum, 'Bench', scene));
const availability = (window.availability = new Availability(
bench,
2023-01-18 01:07:10 -06:00
'Availability',
scene,
));
const business = (window.business = new Business(
bench,
forum,
availability,
2023-01-18 01:07:10 -06:00
'Business',
scene,
));
const requestor = new Public('Public', scene);
const updateDisplayValues = async () => {
for (const expert of experts) {
await expert.setValue(
2023-01-18 01:07:10 -06:00
'rep',
bench.reputation.valueOwnedBy(expert.reputationPublicKey),
);
}
2023-01-18 01:07:10 -06:00
await bench.setValue('total rep', bench.reputation.getTotal());
await scene.sequence.render();
};
const updateDisplayValuesAndDelay = async (delayMs = DELAY_INTERVAL) => {
await updateDisplayValues();
await delay(delayMs);
};
const getActiveWorker = async () => {
let worker;
let request;
for (const expert of experts) {
request = await expert.getAssignedWork(availability, business);
if (request) {
worker = expert;
await worker.actions.getAssignedWork.log(worker, availability);
worker.activate();
break;
}
}
return { worker, request };
};
const voteForWorkEvidence = async (worker, pool) => {
for (const expert of experts) {
if (expert !== worker) {
2023-01-12 16:41:55 -06:00
await expert.stake(pool, {
position: true,
2023-01-12 16:41:55 -06:00
amount: 1,
});
}
}
};
await updateDisplayValuesAndDelay();
// Experts gain initial reputation by submitting a post with fee
const { postId: postId1, pool: pool1 } = await expert1.submitPostWithFee(
bench,
forum,
new PostContent({ hello: 'there' }).setTitle('Post 1'),
{
fee: 10,
duration: 1000,
tokenLossRatio: 1,
},
);
await updateDisplayValuesAndDelay(1000);
await pool1.evaluateWinningConditions();
await updateDisplayValuesAndDelay();
const { pool: pool2 } = await expert2.submitPostWithFee(
bench,
forum,
new PostContent({ hello: 'to you as well' })
.setTitle('Post 2')
.addCitation(postId1, 0.5),
{
fee: 10,
duration: 1000,
tokenLossRatio: 1,
},
);
await updateDisplayValuesAndDelay(1000);
await pool2.evaluateWinningConditions();
await updateDisplayValuesAndDelay();
// Populate availability pool
await expert1.registerAvailability(availability, 1, 10000);
await expert2.registerAvailability(availability, 1, 10000);
await updateDisplayValuesAndDelay();
// Submit work request
await requestor.submitRequest(
business,
{ fee: 100 },
2023-01-18 01:07:10 -06:00
{ please: 'do some work' },
);
await updateDisplayValuesAndDelay();
// Receive work request
const { worker, request } = await getActiveWorker();
// Submit work evidence
const pool = await worker.submitWork(
business,
request.id,
{
2023-01-18 01:07:10 -06:00
here: 'is some evidence of work product',
},
{
tokenLossRatio: 1,
duration: 1000,
2023-01-18 01:07:10 -06:00
},
);
worker.deactivate();
await updateDisplayValuesAndDelay();
2023-01-12 16:41:55 -06:00
// Stake on work evidence
await voteForWorkEvidence(worker, pool);
await updateDisplayValuesAndDelay();
// Wait for validation pool duration to elapse
await delay(1000);
// Distribute reputation awards and fees
await pool.evaluateWinningConditions();
await updateDisplayValuesAndDelay();
// This should throw an exception since the pool is already resolved
try {
await pool.evaluateWinningConditions();
} catch (e) {
if (e.message.match(/Validation pool has already been resolved/)) {
console.log(
2023-01-18 01:07:10 -06:00
'Caught expected error: Validation pool has already been resolved',
);
} else {
2023-01-18 01:07:10 -06:00
console.error('Unexpected error');
throw e;
}
}
</script>