import { Action } from './action.js'; import { Actor } from './actor.js'; import { CryptoUtil } from './crypto.js'; import { PostContent } from './post.js'; class Request { constructor(fee, content) { this.id = CryptoUtil.randomUUID(); this.fee = fee; this.content = content; } } /** * Purpose: Enable fee-driven work requests, to be completed by workers from the availability pool */ export class Business extends Actor { requests = new Map(); constructor(bench, forum, availability, name, scene) { super(name, scene); this.bench = bench; this.forum = forum; this.availability = availability; this.actions = { assignWork: new Action('assign work', scene), addPost: new Action('add post', scene), initiateValidationPool: new Action('initiate validation pool', scene), }; } /** * Fee should be held in escrow. * That means there should be specific conditions under which the fee will be refunded. * That means the submission should include some time value to indicate when it expires. * There could be separate thresholds to indicate the earliest that the job may be cancelled, * and the time at which the job will be automatically cancelled. */ async submitRequest(fee, content) { const request = new Request(fee, content); this.requests.set(request.id, request); this.actions.assignWork.log(this, this.availability); await this.availability.assignWork(request.id); return request.id; } async getRequest(requestId) { const request = this.requests.get(requestId); return request; } async submitWork(reputationPublicKey, requestId, workEvidence, { tokenLossRatio, duration }) { const request = this.requests.get(requestId); if (!request) { throw new Error(`Request not found! id: ${requestId}`); } // Create a post representing this submission. const post = new PostContent({ requestId, workEvidence, }); this.actions.addPost.log(this, this.forum); await this.forum.addPost(reputationPublicKey, post); // Initiate a validation pool for this work evidence. // Validation pool supports secret ballots but we aren't using that here, since we want // the post to be attributable to the reputation holder. this.actions.initiateValidationPool.log(this, this.bench); const pool = await this.bench.initiateValidationPool(reputationPublicKey, { postId: post.id, fee: request.fee, duration, tokenLossRatio, signingPublicKey: reputationPublicKey, anonymous: false, }); // When the validation pool concludes, // reputation should be awarded and fees should be distributed. return pool; } }