dao-governance-framework/forum-network/public/classes/forum.js

87 lines
2.4 KiB
JavaScript

import { Actor } from './actor.js';
import { Graph, Vertex } from './graph.js';
import params from './params.js';
class Post extends Vertex {
constructor(forum, id, authorId, citations) {
super();
this.forum = forum;
this.id = id;
this.authorId = authorId;
this.citations = citations;
this.value = 0;
}
onValidate({ tokensMinted }) {
this.value = params.initialPostValueFunction({ tokensMinted });
this.forum.distributeReputation(this, this.value);
}
}
/**
* Purpose: Maintain a directed, acyclic, weighted graph of posts referencing other posts
*/
export class Forum extends Actor {
constructor(bench, name, scene) {
super(name, scene);
this.bench = bench;
this.posts = new Graph();
}
async addPost({
authorId, postId, citations = [], poolParams,
}) {
const post = new Post(this, postId, authorId);
this.posts.addVertex(postId, post);
for (const { postId: citedPostId, weight } of citations) {
this.posts.addEdge('citation', postId, citedPostId, { weight });
}
// this.applyReputationEffects(post);
// initiateValidationPool(authorId, {postId, fee, duration, tokenLossRatio, contentiousDebate, signingPublicKey}) {
const pool = await this.bench.initiateValidationPool(authorId, {
...poolParams,
postId,
});
return pool;
}
getPost(postId) {
return this.posts.getVertexData(postId);
}
getPosts() {
return this.posts.getVertices();
}
distributeReputation(post, amount, depth = 0) {
console.log('distributeReputation', { post, amount, depth });
// Add the given value to the current post
post.value += amount;
// Distribute a fraction of the added value among cited posts
const distributeAmongCitations = amount * params.citationFraction;
// Here we allow an arbitrary scale for the amount of the citations.
// We normalize by dividing each by the total.
const totalWeight = post.citations
?.map(({ weight }) => weight)
.reduce((acc, cur) => (acc += cur), 0);
for (const {
to: citedPostId,
data: { weight },
} of post.getEdges('citation', true)) {
const citedPost = this.getPost(citedPostId);
if (!citedPost) {
throw new Error(
`Post ${post.postId} cites unknown post ${citedPostId}`,
);
}
this.distributeReputation(
citedPost,
(weight / totalWeight) * distributeAmongCitations,
depth + 1,
);
}
}
}