Fix negative citation propagation

This commit is contained in:
Ladd Hoffman 2023-01-28 08:22:52 -06:00
parent d04b280645
commit 94200b59d4
1 changed files with 16 additions and 27 deletions

View File

@ -112,43 +112,32 @@ export class Forum extends ReputationHolder {
}
async propagateValue(rewardsAccumulator, fromActor, post, increment, depth = 0) {
if (params.referenceChainLimit >= 0 && depth > params.referenceChainLimit) {
return increment;
}
if (increment < 0 && depth > 1) {
return increment;
}
this.actions.propagateValue.log(fromActor, post, `(${increment})`);
// Recursively distribute reputation to citations, according to weights
let totalOutboundAmount = 0;
let refundFromOutbound = 0;
for (const { postId: citedPostId, weight } of post.citations) {
const citedPost = this.getPost(citedPostId);
const outboundAmount = weight * increment;
totalOutboundAmount += outboundAmount;
refundFromOutbound += await this.propagateValue(rewardsAccumulator, post, citedPost, outboundAmount, depth + 1);
if (params.referenceChainLimit >= 0 && depth <= params.referenceChainLimit) {
for (const { postId: citedPostId, weight } of post.citations) {
const citedPost = this.getPost(citedPostId);
let outboundAmount = weight * increment;
// If this is a negative citation, it must not bring the target below zero value.
if (outboundAmount < 0) {
const citedPostTotalCitationWeight = citedPost.citations.reduce((t, { weight: w }) => t += w, 0);
const citedPostCapacity = citedPost.value / (1 - citedPostTotalCitationWeight);
outboundAmount = Math.max(outboundAmount, -citedPostCapacity);
}
totalOutboundAmount += outboundAmount;
await this.propagateValue(rewardsAccumulator, post, citedPost, outboundAmount, depth + 1);
}
}
// Apply leaching value
const incrementAfterLeaching = increment - (totalOutboundAmount - refundFromOutbound) * params.leachingValue;
// Prevent value from decreasing below zero
const rawNewValue = post.value + incrementAfterLeaching;
const newValue = Math.max(0, rawNewValue);
// We "refund" the amount that could not be applied.
// Note that this will always be a negative quantity, because this situation only arises when increment is negative.
const refundToInbound = rawNewValue - newValue;
const appliedIncrement = newValue - post.value;
const incrementAfterLeaching = increment - totalOutboundAmount * params.leachingValue;
// Award reputation to post author
rewardsAccumulator.set(post.tokenId, appliedIncrement);
rewardsAccumulator.set(post.tokenId, incrementAfterLeaching);
// Increment the value of the post
await this.setPostValue(post, newValue);
return refundToInbound;
await this.setPostValue(post, post.value + incrementAfterLeaching);
}
}