From 94200b59d4a6f2a1779405d2633219c4225d834f Mon Sep 17 00:00:00 2001 From: Ladd Hoffman Date: Sat, 28 Jan 2023 08:22:52 -0600 Subject: [PATCH] Fix negative citation propagation --- forum-network/src/classes/forum.js | 43 +++++++++++------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/forum-network/src/classes/forum.js b/forum-network/src/classes/forum.js index 213f201..e40a3d8 100644 --- a/forum-network/src/classes/forum.js +++ b/forum-network/src/classes/forum.js @@ -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); } }