dao-governance-framework/forum-network/src/classes/availability.js

72 lines
2.1 KiB
JavaScript
Raw Normal View History

2023-01-02 13:14:32 -06:00
import { Action } from './action.js';
2022-12-31 16:08:42 -06:00
import { Actor } from './actor.js';
import { CryptoUtil } from './crypto.js';
2022-12-31 16:08:42 -06:00
2023-01-01 21:09:02 -06:00
class Worker {
constructor(reputationPublicKey, tokenId, stakeAmount, duration) {
this.reputationPublicKey = reputationPublicKey;
2023-01-18 01:07:10 -06:00
this.tokenId = tokenId;
this.stakeAmount = stakeAmount;
this.duration = duration;
2023-01-18 01:07:10 -06:00
this.available = true;
this.assignedRequestId = null;
2023-01-01 21:09:02 -06:00
}
}
2022-12-31 16:08:42 -06:00
/**
* Purpose: Enable staking reputation to enter the pool of workers
*/
2023-01-01 21:09:02 -06:00
export class Availability extends Actor {
constructor(bench, name, scene) {
super(name, scene);
this.bench = bench;
2023-01-02 13:14:32 -06:00
this.actions = {
assignWork: new Action('assign work', scene),
};
2023-01-01 21:09:02 -06:00
this.workers = new Map();
2023-01-01 21:09:02 -06:00
}
register(reputationPublicKey, { stakeAmount, tokenId, duration }) {
// TODO: Should be signed by token owner
this.bench.reputation.lock(tokenId, stakeAmount, duration);
const workerId = CryptoUtil.randomUUID();
this.workers.set(workerId, new Worker(reputationPublicKey, tokenId, stakeAmount, duration));
return workerId;
}
2023-01-05 01:19:14 -06:00
2023-01-01 21:09:02 -06:00
get availableWorkers() {
return Array.from(this.workers.values()).filter(({ available }) => !!available);
}
async assignWork(requestId) {
const totalAmountStaked = this.availableWorkers
.reduce((total, { stakeAmount }) => total += stakeAmount, 0);
// Imagine all these amounts layed end-to-end along a number line.
// To weight choice by amount staked, pick a stake by choosing a number at random
// from within that line segment.
const randomChoice = Math.random() * totalAmountStaked;
let index = 0;
let acc = 0;
for (const { stakeAmount } of this.workers.values()) {
acc += stakeAmount;
if (acc >= randomChoice) {
break;
}
index += 1;
}
2023-01-01 21:09:02 -06:00
const worker = this.availableWorkers[index];
worker.available = false;
worker.assignedRequestId = requestId;
2023-01-02 13:14:32 -06:00
// TODO: Notify assignee
2023-01-05 01:19:14 -06:00
return worker;
2023-01-02 13:14:32 -06:00
}
async getAssignedWork(workerId) {
const worker = this.workers.get(workerId);
2023-01-02 13:14:32 -06:00
return worker.assignedRequestId;
2023-01-01 21:09:02 -06:00
}
}