Post value propagation
This commit is contained in:
parent
8980885881
commit
cfa445471f
|
@ -8,8 +8,9 @@ import { Action } from './action.js';
|
||||||
* Purpose: Keep track of reputation holders
|
* Purpose: Keep track of reputation holders
|
||||||
*/
|
*/
|
||||||
export class Bench extends Actor {
|
export class Bench extends Actor {
|
||||||
constructor(name, scene) {
|
constructor(forum, name, scene) {
|
||||||
super(name, scene);
|
super(name, scene);
|
||||||
|
this.forum = forum;
|
||||||
this.validationPools = new Map();
|
this.validationPools = new Map();
|
||||||
this.voters = new Map();
|
this.voters = new Map();
|
||||||
this.reputations = new Reputations();
|
this.reputations = new Reputations();
|
||||||
|
@ -68,6 +69,7 @@ export class Bench extends Actor {
|
||||||
const validationPoolNumber = this.validationPools.size + 1;
|
const validationPoolNumber = this.validationPools.size + 1;
|
||||||
const validationPool = new ValidationPool(
|
const validationPool = new ValidationPool(
|
||||||
this,
|
this,
|
||||||
|
this.forum,
|
||||||
{
|
{
|
||||||
postId,
|
postId,
|
||||||
fee,
|
fee,
|
||||||
|
@ -78,7 +80,7 @@ export class Bench extends Actor {
|
||||||
authorStake,
|
authorStake,
|
||||||
anonymous,
|
anonymous,
|
||||||
},
|
},
|
||||||
`pool${validationPoolNumber}`,
|
`Pool${validationPoolNumber}`,
|
||||||
this.scene,
|
this.scene,
|
||||||
);
|
);
|
||||||
this.validationPools.set(validationPool.id, validationPool);
|
this.validationPools.set(validationPool.id, validationPool);
|
||||||
|
|
|
@ -25,7 +25,7 @@ export class Business extends Actor {
|
||||||
|
|
||||||
this.actions = {
|
this.actions = {
|
||||||
assignWork: new Action('assign work', scene),
|
assignWork: new Action('assign work', scene),
|
||||||
addPost: new Action('add post', scene),
|
submitPost: new Action('submit post', scene),
|
||||||
initiateValidationPool: new Action('initiate validation pool', scene),
|
initiateValidationPool: new Action('initiate validation pool', scene),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ export class Business extends Actor {
|
||||||
requestId,
|
requestId,
|
||||||
workEvidence,
|
workEvidence,
|
||||||
});
|
});
|
||||||
this.actions.addPost.log(this, this.forum);
|
this.actions.submitPost.log(this, this.forum);
|
||||||
await this.forum.addPost(reputationPublicKey, post);
|
await this.forum.addPost(reputationPublicKey, post);
|
||||||
|
|
||||||
// Initiate a validation pool for this work evidence.
|
// Initiate a validation pool for this work evidence.
|
||||||
|
|
|
@ -12,6 +12,16 @@ class Post extends Actor {
|
||||||
this.id = postContent.id ?? CryptoUtil.randomUUID();
|
this.id = postContent.id ?? CryptoUtil.randomUUID();
|
||||||
this.authorId = authorId;
|
this.authorId = authorId;
|
||||||
this.value = 0;
|
this.value = 0;
|
||||||
|
this.citations = postContent.citations;
|
||||||
|
}
|
||||||
|
|
||||||
|
setPostValue(value) {
|
||||||
|
this.setValue('value', value);
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPostValue() {
|
||||||
|
return this.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,9 +29,8 @@ class Post extends Actor {
|
||||||
* Purpose: Maintain a directed, acyclic, weighted graph of posts referencing other posts
|
* Purpose: Maintain a directed, acyclic, weighted graph of posts referencing other posts
|
||||||
*/
|
*/
|
||||||
export class Forum extends Actor {
|
export class Forum extends Actor {
|
||||||
constructor(bench, name, scene) {
|
constructor(name, scene) {
|
||||||
super(name, scene);
|
super(name, scene);
|
||||||
this.bench = bench;
|
|
||||||
this.posts = new Graph();
|
this.posts = new Graph();
|
||||||
this.actions = {
|
this.actions = {
|
||||||
addPost: new Action('add post', scene),
|
addPost: new Action('add post', scene),
|
||||||
|
@ -46,11 +55,6 @@ export class Forum extends Actor {
|
||||||
return this.posts.getVertices();
|
return this.posts.getVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
onValidate({ tokensMinted }) {
|
|
||||||
const initialValue = params.initialPostValueFunction({ tokensMinted });
|
|
||||||
this.distributeReputation(this, initialValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
distributeReputation(post, amount, depth = 0) {
|
distributeReputation(post, amount, depth = 0) {
|
||||||
console.log('distributeReputation', { post, amount, depth });
|
console.log('distributeReputation', { post, amount, depth });
|
||||||
// Add the given value to the current post
|
// Add the given value to the current post
|
||||||
|
|
|
@ -45,7 +45,6 @@ export class Graph {
|
||||||
throw new Error(`Vertex already exists with id: ${id}`);
|
throw new Error(`Vertex already exists with id: ${id}`);
|
||||||
}
|
}
|
||||||
const vertex = new Vertex(data);
|
const vertex = new Vertex(data);
|
||||||
console.log('addVertex', vertex);
|
|
||||||
this.vertices.set(id, vertex);
|
this.vertices.set(id, vertex);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +76,6 @@ export class Graph {
|
||||||
}
|
}
|
||||||
|
|
||||||
addEdge(label, from, to, data) {
|
addEdge(label, from, to, data) {
|
||||||
console.log('addEdge', { from, to });
|
|
||||||
if (this.getEdge(label, from, to)) {
|
if (this.getEdge(label, from, to)) {
|
||||||
throw new Error(`Edge ${label} from ${from} to ${to} already exists`);
|
throw new Error(`Edge ${label} from ${from} to ${to} already exists`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ const params = {
|
||||||
lockingTimeExponent: 0, // c11
|
lockingTimeExponent: 0, // c11
|
||||||
|
|
||||||
/* Forum parameters */
|
/* Forum parameters */
|
||||||
initialPostValueFunction: ({ tokensMinted }) => tokensMinted, // q1
|
initialPostValue: () => 1, // q1
|
||||||
citationFraction: 0.3, // q2
|
citationFraction: 0.3, // q2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ const ValidationPoolStates = Object.freeze({
|
||||||
export class ValidationPool extends Actor {
|
export class ValidationPool extends Actor {
|
||||||
constructor(
|
constructor(
|
||||||
bench,
|
bench,
|
||||||
|
forum,
|
||||||
{
|
{
|
||||||
postId,
|
postId,
|
||||||
signingPublicKey,
|
signingPublicKey,
|
||||||
|
@ -52,6 +53,7 @@ export class ValidationPool extends Actor {
|
||||||
}]; got ${duration}`,
|
}]; got ${duration}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
this.forum = forum;
|
||||||
this.postId = postId;
|
this.postId = postId;
|
||||||
this.state = ValidationPoolStates.OPEN;
|
this.state = ValidationPoolStates.OPEN;
|
||||||
this.setStatus('Open');
|
this.setStatus('Open');
|
||||||
|
@ -66,6 +68,7 @@ export class ValidationPool extends Actor {
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
this.tokenLossRatio = tokenLossRatio;
|
this.tokenLossRatio = tokenLossRatio;
|
||||||
this.contentiousDebate = contentiousDebate;
|
this.contentiousDebate = contentiousDebate;
|
||||||
|
this.tokensMinted = fee * params.mintingRatio;
|
||||||
this.tokens = {
|
this.tokens = {
|
||||||
for: fee * params.mintingRatio * params.stakeForWin,
|
for: fee * params.mintingRatio * params.stakeForWin,
|
||||||
against: fee * params.mintingRatio * (1 - params.stakeForWin),
|
against: fee * params.mintingRatio * (1 - params.stakeForWin),
|
||||||
|
@ -93,7 +96,6 @@ export class ValidationPool extends Actor {
|
||||||
}
|
}
|
||||||
this.votes.set(signingPublicKey, vote);
|
this.votes.set(signingPublicKey, vote);
|
||||||
if (!anonymous) {
|
if (!anonymous) {
|
||||||
console.log('castVote: revealing identity since this is not an anonymous vote');
|
|
||||||
await this.revealIdentity(signingPublicKey, signingPublicKey);
|
await this.revealIdentity(signingPublicKey, signingPublicKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,20 +202,33 @@ export class ValidationPool extends Actor {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
distributeTokens(result) {
|
propagateValue(nextPost, increment) {
|
||||||
let authorReputationPublicKey;
|
const postValue = nextPost.getPostValue();
|
||||||
if (this.anonymous) {
|
nextPost.setPostValue(postValue + increment);
|
||||||
const author = this.voters.get(this.authorSigningPublicKey);
|
for (const { postId: citedPostId, weight } of nextPost.citations) {
|
||||||
authorReputationPublicKey = author.reputationPublicKey;
|
console.log('citedPostId', citedPostId);
|
||||||
} else {
|
const citedPost = this.forum.getPost(citedPostId);
|
||||||
authorReputationPublicKey = this.authorSigningPublicKey;
|
this.propagateValue(citedPost, weight * increment);
|
||||||
}
|
}
|
||||||
// Reward the author
|
}
|
||||||
// TODO: If the vote fails, distribute tokens.author among winning voters
|
|
||||||
|
distributeTokens(result) {
|
||||||
|
const authorReputationPublicKey = this.anonymous
|
||||||
|
? this.voters.get(this.authorSigningPublicKey).reputationPublicKey
|
||||||
|
: this.authorSigningPublicKey;
|
||||||
|
|
||||||
|
// TODO: Take tokenLossRatio into account
|
||||||
|
|
||||||
if (result === true) {
|
if (result === true) {
|
||||||
this.bench.reputations.addTokens(authorReputationPublicKey, this.tokens.for);
|
// Take initialValue into account
|
||||||
|
const initialPostValue = params.initialPostValue() * this.tokensMinted;
|
||||||
|
const tokensForAuthor = initialPostValue * params.stakeForWin;
|
||||||
|
const tokensForWinners = initialPostValue * (1 - params.stakeForWin);
|
||||||
|
|
||||||
|
// Reward the author
|
||||||
|
this.bench.reputations.addTokens(authorReputationPublicKey, tokensForAuthor);
|
||||||
|
|
||||||
// Reward the vote winners, in proportion to their stakes
|
// Reward the vote winners, in proportion to their stakes
|
||||||
const tokensForWinners = this.tokens.against;
|
|
||||||
const winningVotes = this.listVotes(result);
|
const winningVotes = this.listVotes(result);
|
||||||
const totalStakes = Array.from(winningVotes.values())
|
const totalStakes = Array.from(winningVotes.values())
|
||||||
.map(({ stake }) => stake)
|
.map(({ stake }) => stake)
|
||||||
|
@ -226,6 +241,15 @@ export class ValidationPool extends Actor {
|
||||||
const reward = (tokensForWinners * stake) / totalStakes;
|
const reward = (tokensForWinners * stake) / totalStakes;
|
||||||
this.bench.reputations.addTokens(reputationPublicKey, reward);
|
this.bench.reputations.addTokens(reputationPublicKey, reward);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the forum post to set its (initial) value
|
||||||
|
const post = this.forum.getPost(this.postId);
|
||||||
|
|
||||||
|
// Recursively update values of referenced posts
|
||||||
|
this.propagateValue(post, initialPostValue);
|
||||||
|
} else {
|
||||||
|
// TODO: If the vote fails, distribute tokens.author among winning voters.
|
||||||
|
throw new Error("Vote did not pass -- we don't currently handle that!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,8 @@
|
||||||
const expert1 = await newExpert();
|
const expert1 = await newExpert();
|
||||||
const expert2 = await newExpert();
|
const expert2 = await newExpert();
|
||||||
await newExpert();
|
await newExpert();
|
||||||
const bench = (window.bench = new Bench("Bench", scene));
|
const forum = (window.forum = new Forum("Forum", scene));
|
||||||
const forum = (window.forum = new Forum(bench, "Forum", scene));
|
const bench = (window.bench = new Bench(forum, "Bench", scene));
|
||||||
const availability = (window.bench = new Availability(
|
const availability = (window.bench = new Availability(
|
||||||
bench,
|
bench,
|
||||||
"Availability",
|
"Availability",
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
const expert1 = await newExpert();
|
const expert1 = await newExpert();
|
||||||
const expert2 = await newExpert();
|
const expert2 = await newExpert();
|
||||||
await newExpert();
|
await newExpert();
|
||||||
const bench = (window.bench = new Bench("Bench", scene));
|
const forum = (window.forum = new Forum("Forum", scene));
|
||||||
const forum = (window.forum = new Forum(bench, "Forum", scene));
|
const bench = (window.bench = new Bench(forum, "Bench", scene));
|
||||||
|
|
||||||
const updateDisplayValues = async () => {
|
const updateDisplayValues = async () => {
|
||||||
for (const expert of experts) {
|
for (const expert of experts) {
|
||||||
|
|
Loading…
Reference in New Issue