2023-01-02 13:52:05 -06:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<head>
|
|
|
|
<title>Availability test</title>
|
|
|
|
<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';
|
2023-01-26 10:44:57 -06:00
|
|
|
import { PostContent } from '../classes/post-content.js';
|
2023-01-02 13:52:05 -06:00
|
|
|
|
|
|
|
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-02 13:52:05 -06:00
|
|
|
|
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();
|
2023-01-26 10:44:57 -06:00
|
|
|
scene.withFlowchart();
|
2023-01-02 13:52:05 -06:00
|
|
|
|
2023-01-04 15:18:29 -06:00
|
|
|
const experts = (window.experts = []);
|
2023-01-03 12:00:12 -06:00
|
|
|
const newExpert = async () => {
|
2023-01-04 15:18:29 -06:00
|
|
|
const index = experts.length;
|
2023-01-03 12:00:12 -06:00
|
|
|
const name = `Expert${index + 1}`;
|
2023-01-04 15:18:29 -06:00
|
|
|
const expert = await new Expert(name, scene).initialize();
|
|
|
|
experts.push(expert);
|
|
|
|
return expert;
|
2023-01-02 13:52:05 -06:00
|
|
|
};
|
|
|
|
|
2023-01-04 15:18:29 -06:00
|
|
|
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));
|
2023-01-26 10:44:57 -06:00
|
|
|
const availability = (window.availability = new Availability(
|
2023-01-02 13:52:05 -06:00
|
|
|
bench,
|
2023-01-18 01:07:10 -06:00
|
|
|
'Availability',
|
|
|
|
scene,
|
|
|
|
));
|
2023-01-02 13:52:05 -06:00
|
|
|
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);
|
2023-01-02 13:52:05 -06:00
|
|
|
|
|
|
|
const updateDisplayValues = async () => {
|
2023-01-04 15:18:29 -06:00
|
|
|
for (const expert of experts) {
|
2023-01-05 14:21:45 -06:00
|
|
|
await expert.setValue(
|
2023-01-18 01:07:10 -06:00
|
|
|
'rep',
|
|
|
|
bench.reputation.valueOwnedBy(expert.reputationPublicKey),
|
2023-01-03 01:26:55 -06:00
|
|
|
);
|
|
|
|
}
|
2023-01-18 01:07:10 -06:00
|
|
|
await bench.setValue('total rep', bench.reputation.getTotal());
|
2023-01-05 14:21:45 -06:00
|
|
|
await scene.sequence.render();
|
2023-01-02 13:52:05 -06:00
|
|
|
};
|
|
|
|
|
2023-01-26 10:44:57 -06:00
|
|
|
const updateDisplayValuesAndDelay = async (delayMs = DELAY_INTERVAL) => {
|
2023-01-02 13:52:05 -06:00
|
|
|
await updateDisplayValues();
|
2023-01-26 10:44:57 -06:00
|
|
|
await delay(delayMs);
|
2023-01-02 13:52:05 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
const getActiveWorker = async () => {
|
|
|
|
let worker;
|
|
|
|
let request;
|
2023-01-04 15:18:29 -06:00
|
|
|
for (const expert of experts) {
|
|
|
|
request = await expert.getAssignedWork(availability, business);
|
2023-01-02 13:52:05 -06:00
|
|
|
if (request) {
|
2023-01-04 15:18:29 -06:00
|
|
|
worker = expert;
|
2023-01-05 14:21:45 -06:00
|
|
|
await worker.actions.getAssignedWork.log(worker, availability);
|
2023-01-02 13:52:05 -06:00
|
|
|
worker.activate();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return { worker, request };
|
|
|
|
};
|
|
|
|
|
|
|
|
const voteForWorkEvidence = async (worker, pool) => {
|
2023-01-04 15:18:29 -06:00
|
|
|
for (const expert of experts) {
|
|
|
|
if (expert !== worker) {
|
2023-01-12 16:41:55 -06:00
|
|
|
await expert.stake(pool, {
|
2023-01-02 13:52:05 -06:00
|
|
|
position: true,
|
2023-01-12 16:41:55 -06:00
|
|
|
amount: 1,
|
2023-01-02 13:52:05 -06:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
await updateDisplayValuesAndDelay();
|
|
|
|
|
2023-01-26 10:44:57 -06:00
|
|
|
// 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();
|
|
|
|
|
2023-01-02 13:52:05 -06:00
|
|
|
// Populate availability pool
|
2023-01-26 10:44:57 -06:00
|
|
|
await expert1.registerAvailability(availability, 1, 10000);
|
|
|
|
await expert2.registerAvailability(availability, 1, 10000);
|
2023-01-02 13:52:05 -06:00
|
|
|
await updateDisplayValuesAndDelay();
|
|
|
|
|
|
|
|
// Submit work request
|
|
|
|
await requestor.submitRequest(
|
|
|
|
business,
|
|
|
|
{ fee: 100 },
|
2023-01-18 01:07:10 -06:00
|
|
|
{ please: 'do some work' },
|
|
|
|
);
|
2023-01-02 13:52:05 -06:00
|
|
|
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',
|
2023-01-02 13:52:05 -06:00
|
|
|
},
|
|
|
|
{
|
|
|
|
tokenLossRatio: 1,
|
|
|
|
duration: 1000,
|
2023-01-18 01:07:10 -06:00
|
|
|
},
|
|
|
|
);
|
2023-01-02 13:52:05 -06:00
|
|
|
worker.deactivate();
|
|
|
|
await updateDisplayValuesAndDelay();
|
|
|
|
|
2023-01-12 16:41:55 -06:00
|
|
|
// Stake on work evidence
|
2023-01-02 13:52:05 -06:00
|
|
|
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',
|
2023-01-02 13:52:05 -06:00
|
|
|
);
|
|
|
|
} else {
|
2023-01-18 01:07:10 -06:00
|
|
|
console.error('Unexpected error');
|
2023-01-02 13:52:05 -06:00
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|