Show author reputations on sequence diagram

This commit is contained in:
Ladd Hoffman 2023-04-16 08:21:09 -05:00
parent 77643acf6f
commit 5b0b87d2d3
8 changed files with 34 additions and 30 deletions

View File

@ -4,8 +4,8 @@ import { CryptoUtil } from '../util/crypto.js';
import { ReputationHolder } from '../reputation/reputation-holder.js'; import { ReputationHolder } from '../reputation/reputation-holder.js';
export class Expert extends ReputationHolder { export class Expert extends ReputationHolder {
constructor(dao, name, scene) { constructor(dao, name, scene, options) {
super(name, scene); super(name, scene, options);
this.dao = dao; this.dao = dao;
this.actions = { this.actions = {
submitPostViaNetwork: new Action('submit post via network', scene), submitPostViaNetwork: new Action('submit post via network', scene),

View File

@ -13,8 +13,8 @@ import { Actor } from '../display/actor.js';
* - Reputation: Keep track of reputation accrued to each expert * - Reputation: Keep track of reputation accrued to each expert
*/ */
export class DAO extends Actor { export class DAO extends Actor {
constructor(name, scene) { constructor(name, scene, options) {
super(name, scene); super(name, scene, options);
/* Contracts */ /* Contracts */
this.forum = new Forum(this, 'Forum', scene); this.forum = new Forum(this, 'Forum', scene);
@ -38,7 +38,7 @@ export class DAO extends Actor {
return Array.from(this.experts.values()).filter((voter) => { return Array.from(this.experts.values()).filter((voter) => {
const hasVoted = !!voter.dateLastVote; const hasVoted = !!voter.dateLastVote;
const withinThreshold = !params.activeVoterThreshold const withinThreshold = !params.activeVoterThreshold
|| new Date() - voter.dateLastVote >= params.activeVoterThreshold; || new Date() - voter.dateLastVote >= params.activeVoterThreshold;
return hasVoted && withinThreshold; return hasVoted && withinThreshold;
}); });
} }

View File

@ -69,8 +69,9 @@ class Post extends Actor {
} }
} }
class Author { class Author extends Actor {
constructor(forum, publicKey) { constructor(forum, publicKey) {
super(publicKey, forum.scene);
this.forum = forum; this.forum = forum;
this.publicKey = publicKey; this.publicKey = publicKey;
this.name = publicKey; this.name = publicKey;
@ -158,6 +159,7 @@ export class Forum extends ReputationHolder {
const addAuthorToGraph = (publicKey, weight, authorTokenId) => { const addAuthorToGraph = (publicKey, weight, authorTokenId) => {
const author = new Author(this, publicKey); const author = new Author(this, publicKey);
author.setDisplayValue('reputation', () => author.getReputation());
const authorVertex = this.graph.getVertex(publicKey) const authorVertex = this.graph.getVertex(publicKey)
?? this.graph.addVertex(VertexTypes.AUTHOR, publicKey, author, author.getLabel()); ?? this.graph.addVertex(VertexTypes.AUTHOR, publicKey, author, author.getLabel());
const authorEdge = this.graph.addEdge( const authorEdge = this.graph.addEdge(
@ -217,6 +219,7 @@ export class Forum extends ReputationHolder {
const { tokenId: authorTokenId } = authorEdge.data; const { tokenId: authorTokenId } = authorEdge.data;
this.dao.reputation.transfer(this.id, author.publicKey, authorTokenId); this.dao.reputation.transfer(this.id, author.publicKey, authorTokenId);
authorVertex.setDisplayLabel(author.getLabel()); authorVertex.setDisplayLabel(author.getLabel());
await author.computeDisplayValues();
} }
} }
@ -338,6 +341,17 @@ export class Forum extends ReputationHolder {
const appliedIncrement = newValue - post.value; const appliedIncrement = newValue - post.value;
const refundToInbound = increment - appliedIncrement; const refundToInbound = increment - appliedIncrement;
// Apply reputation effects to post authors, not to the post directly
for (const authorEdge of postVertex.getEdges(EdgeTypes.AUTHOR, true)) {
const { weight, data: { tokenId }, to: { data: author } } = authorEdge;
const authorIncrement = weight * appliedIncrement;
rewardsAccumulator.set(tokenId, authorIncrement);
this.actions.propagate.log(post, author, `(${authorIncrement})`);
}
// Increment the value of the post
await post.setValue(newValue);
console.log('propagateValue end', { console.log('propagateValue end', {
depth, depth,
increment, increment,
@ -347,16 +361,6 @@ export class Forum extends ReputationHolder {
refundToInbound, refundToInbound,
}); });
// Apply reputation effects to post authors, not to the post directly
for (const authorEdge of postVertex.getEdges(EdgeTypes.AUTHOR, true)) {
const { weight, data: { tokenId } } = authorEdge;
const authorIncrement = weight * appliedIncrement;
rewardsAccumulator.set(tokenId, authorIncrement);
}
// Increment the value of the post
await post.setValue(newValue);
return refundToInbound; return refundToInbound;
} }
} }

View File

@ -1,7 +1,7 @@
import { displayNumber } from '../../util.js'; import { displayNumber } from '../../util.js';
export class Actor { export class Actor {
constructor(name, scene) { constructor(name, scene, { announce = false } = {}) {
if (!scene) throw new Error('An actor without a scene!'); if (!scene) throw new Error('An actor without a scene!');
this.name = name; this.name = name;
this.scene = scene; this.scene = scene;
@ -11,7 +11,7 @@ export class Actor {
this.values = new Map(); this.values = new Map();
this.valueFunctions = new Map(); this.valueFunctions = new Map();
this.active = 0; this.active = 0;
scene?.registerActor(this); scene?.registerActor(this, announce);
} }
activate() { activate() {

View File

@ -86,9 +86,11 @@ export class Scene {
return this; return this;
} }
registerActor(actor) { registerActor(actor, announce) {
this.actors.add(actor); this.actors.add(actor);
// this.sequence?.log(`participant ${actor.name}`); if (announce) {
this.sequence?.log(`participant ${actor.name}`);
}
} }
findActor(fn) { findActor(fn) {

View File

@ -2,8 +2,8 @@ import { randomID } from '../../util.js';
import { Actor } from '../display/actor.js'; import { Actor } from '../display/actor.js';
export class ReputationHolder extends Actor { export class ReputationHolder extends Actor {
constructor(name, scene) { constructor(name, scene, options) {
super(name, scene); super(name, scene, options);
this.reputationPublicKey = `${name}_${randomID()}`; this.reputationPublicKey = `${name}_${randomID()}`;
} }
} }

View File

@ -55,10 +55,10 @@ export class ForumTest {
return postId; return postId;
} }
async newExpert() { async newExpert(options) {
const index = this.experts.length; const index = this.experts.length;
const name = `Expert${index + 1}`; const name = `Expert${index + 1}`;
const expert = await new Expert(this.dao, name, this.scene).initialize(); const expert = await new Expert(this.dao, name, this.scene, options).initialize();
this.experts.push(expert); this.experts.push(expert);
// await expert.addComputedValue('rep', () => this.dao.reputation.valueOwnedBy(expert.reputationPublicKey)); // await expert.addComputedValue('rep', () => this.dao.reputation.valueOwnedBy(expert.reputationPublicKey));
return expert; return expert;
@ -81,15 +81,13 @@ export class ForumTest {
scene.addDisplayValue('q4. leachingValue').set(params.leachingValue); scene.addDisplayValue('q4. leachingValue').set(params.leachingValue);
scene.addDisplayValue(' '); scene.addDisplayValue(' ');
this.dao = new DAO('DAO', scene); this.dao = new DAO('DAO', scene, { announce: true });
this.forum = this.dao.forum; this.forum = this.dao.forum;
this.experts = []; this.experts = [];
this.posts = []; this.posts = [];
await this.newExpert(); await this.newExpert({ announce: true });
await this.dao.addComputedValue('total value', () => this.dao.reputation.getTotal()); await this.dao.addComputedValue('total value', () => this.dao.reputation.getTotal());
// await this.dao.addComputedValue('total reputation', () => this.dao.forum.getTotalValue());
this.dao.computeDisplayValues();
} }
} }

View File

@ -20,8 +20,8 @@ describe('Forum', function tests() {
experts = forumTest.experts; experts = forumTest.experts;
posts = forumTest.posts; posts = forumTest.posts;
await forumTest.newExpert(); await forumTest.newExpert({ announce: true });
await forumTest.newExpert(); await forumTest.newExpert({ announce: true });
}); });
it('Post1', async () => { it('Post1', async () => {