Add verification of resulting author reputations

This commit is contained in:
Ladd Hoffman 2023-04-16 18:30:44 -05:00
parent dad2d66fc8
commit b71649df97
7 changed files with 36 additions and 19 deletions

View File

@ -61,14 +61,9 @@ export class Expert extends ReputationHolder {
async initiateValidationPool(poolOptions) {
// For now, make direct call rather than network
poolOptions.reputationPublicKey = this.reputationPublicKey;
const pool = await this.dao.initiateValidationPool(poolOptions);
const pool = await this.dao.initiateValidationPool(this, poolOptions);
this.tokens.push(pool.tokenId);
this.validationPools.set(pool.id, poolOptions);
await this.actions.initiateValidationPool.log(
this,
pool,
`(fee: ${poolOptions.fee}, stake: ${poolOptions.authorStakeAmount ?? 0})`,
);
return pool;
}

View File

@ -77,7 +77,7 @@ export class Business extends Actor {
// Initiate a validation pool for this work evidence.
await this.actions.initiateValidationPool.log(this, this.dao);
const pool = await this.dao.initiateValidationPool({
const pool = await this.dao.initiateValidationPool(this, {
postId,
fee: request.fee,
duration,

View File

@ -55,10 +55,10 @@ export class DAO extends Actor {
.reduce((acc, cur) => (acc += cur), 0);
}
async initiateValidationPool(poolOptions, stakeOptions) {
async initiateValidationPool(fromActor, poolOptions, stakeOptions) {
const validationPoolNumber = this.validationPools.size + 1;
const name = `Pool${validationPoolNumber}`;
const pool = new ValidationPool(this, poolOptions, name, this.scene);
const pool = new ValidationPool(this, poolOptions, name, this.scene, fromActor);
this.validationPools.set(pool.id, pool);
if (stakeOptions) {

View File

@ -137,17 +137,17 @@ export class Forum extends ReputationHolder {
authorVertex,
weight,
{ tokenId: authorTokenId },
{
hide: author.options.hide,
},
{ hide: author.options.hide },
);
};
// In the case of multiple authors, mint additional (empty) tokens.
// If no authors are specified, treat the sender as the sole author.
// TODO: Verify that cumulative author weight == 1
if (!post.authors?.length) {
addAuthorToGraph(post.senderId, 1, tokenId);
} else {
// TODO: Verify that author list includes the sender
for (const { publicKey, weight } of post.authors) {
// If the sender is also listed among the authors, do not mint them an additional token.
if (publicKey === post.senderId) {
@ -158,8 +158,6 @@ export class Forum extends ReputationHolder {
}
}
// TODO: Verify that cumulative author weight === 1
const rewardsAccumulator = new Map();
// Compute reputation rewards
@ -181,11 +179,16 @@ export class Forum extends ReputationHolder {
} else {
this.dao.reputation.transferValueFrom(tokenId, authorTokenId, amount);
}
await author.computeDisplayValues();
authorVertex.setDisplayLabel(author.getLabel());
}
await author.computeDisplayValues();
authorVertex.setDisplayLabel(author.getLabel());
}
const senderVertex = this.graph.getVertex(post.senderId);
const { data: sender } = senderVertex;
await sender.computeDisplayValues();
senderVertex.setDisplayLabel(sender.getLabel());
// Transfer ownership of the minted tokens to the authors
for (const authorEdge of postVertex.getEdges(EdgeTypes.AUTHOR, true)) {
const authorVertex = authorEdge.to;

View File

@ -27,16 +27,21 @@ export class ValidationPool extends ReputationHolder {
},
name,
scene,
fromActor,
) {
super(name, scene);
this.id = this.reputationPublicKey;
this.actions = {
initiate: new Action('initiate validation pool', scene),
reward: new Action('reward', scene),
transfer: new Action('transfer', scene),
mint: new Action('mint', scene),
};
this.actions.initiate.log(fromActor, this, `(fee: ${fee})`);
this.activate();
// If contentiousDebate = true, we will follow the progression defined by getTokenLossRatio()
if (
!contentiousDebate
@ -90,8 +95,6 @@ export class ValidationPool extends ReputationHolder {
const voter = this.dao.experts.get(reputationPublicKey) ?? new Voter(reputationPublicKey);
voter.addVoteRecord(this);
this.dao.experts.set(reputationPublicKey, voter);
this.activate();
}
getTokenLossRatio() {

View File

@ -16,14 +16,16 @@ describe('Forum', function tests() {
let forum;
let experts;
let posts;
let dao;
before(async () => {
forum = forumTest.forum;
experts = forumTest.experts;
posts = forumTest.posts;
dao = forumTest.dao;
});
it('Post1', async () => {
it('Post1 has three authors and reputation is distributed among them', async () => {
const authors = [
{ author: experts[0], weight: 0.5 },
{ author: experts[1], weight: 0.25 },
@ -31,6 +33,10 @@ describe('Forum', function tests() {
];
await forumTest.addPost(authors, 10);
forum.getPost(posts[0]).value.should.equal(10);
dao.reputation.valueOwnedBy(experts[0].reputationPublicKey).should.equal(5);
dao.reputation.valueOwnedBy(experts[1].reputationPublicKey).should.equal(2.5);
dao.reputation.valueOwnedBy(experts[2].reputationPublicKey).should.equal(2.5);
});
});
});

View File

@ -16,11 +16,13 @@ describe('Forum', function tests() {
let forum;
let experts;
let posts;
let dao;
before(async () => {
forum = forumTest.forum;
experts = forumTest.experts;
posts = forumTest.posts;
dao = forumTest.dao;
});
it('Post1 with two authors', async () => {
@ -30,6 +32,10 @@ describe('Forum', function tests() {
];
await forumTest.addPost(authors, 10);
forum.getPost(posts[0]).value.should.equal(10);
dao.reputation.valueOwnedBy(experts[0].reputationPublicKey).should.equal(5);
dao.reputation.valueOwnedBy(experts[1].reputationPublicKey).should.equal(5);
dao.reputation.valueOwnedBy(experts[2].reputationPublicKey).should.equal(0);
});
it('Post2 with two authors, one shared with Post1', async () => {
@ -39,6 +45,10 @@ describe('Forum', function tests() {
];
await forumTest.addPost(authors, 10);
forum.getPost(posts[0]).value.should.equal(10);
dao.reputation.valueOwnedBy(experts[0].reputationPublicKey).should.equal(5);
dao.reputation.valueOwnedBy(experts[1].reputationPublicKey).should.equal(10);
dao.reputation.valueOwnedBy(experts[2].reputationPublicKey).should.equal(5);
});
});
});