When propagating value, apply leaching before donations
This commit is contained in:
parent
5fc5bbe0b5
commit
a48d14905c
|
@ -0,0 +1,37 @@
|
|||
The communication protocol(s) among network nodes
|
||||
Each communication protocol among network nodes
|
||||
has its own purpose
|
||||
has its own assumptions, expectations, requirements, constraints
|
||||
|
||||
I think it makes sense to identify the constraints for our protocols.
|
||||
|
||||
We need the general public to be able to reliably
|
||||
|
||||
- Query information about the reputation WDAG
|
||||
- Submit requests and fees for work
|
||||
- Obtain the products of the work submitted by forum experts
|
||||
|
||||
Suppose we want only the requestor to be able to access a given work product.
|
||||
(Why might we want this?)
|
||||
Then the (soft) protocol for reviewing the work product would consist of
|
||||
validating a signature by the requestor, attesting to their acceptance of the work product.
|
||||
|
||||
Alternatively access could be permitted to some group, such as reputation holders (a.k.a. experts).
|
||||
|
||||
Otherwise, for maximum utility, we would want to make the work products available indefinitely, as valuable artifacts.
|
||||
Value here can be equated to the expected fees that the work products will help attract, which can in turn be equated to
|
||||
reputation awarded to authors and reviewers of the work products.
|
||||
|
||||
Thus, the work of making the artifacts available must be funded.
|
||||
|
||||
The work of participating in a gossip / forum node consensus protocol and validating forum chain blocks must also be funded.
|
||||
|
||||
Suppose we have a storage contract.
|
||||
|
||||
- There can be a market for specific pledges of storage.
|
||||
- buy: (amount, duration, price)
|
||||
- sell: (amount, duration, price)
|
||||
- Governance: Management of storage price
|
||||
- may negotiate via loose -> tight binding traversal forum post sequence
|
||||
- reputation in accordance with majority opinions on price parameters
|
||||
- Verification of storage must occur by (randomly) querying the storage nodes and validating their responses.
|
|
@ -0,0 +1,19 @@
|
|||
This system is meant to represent a body of experts receiving fees to perform work.
|
||||
Experts register their availability to receive work via the availability contract.
|
||||
Request and associated fees are sumbitted via the business contract.
|
||||
Evidence of the work performed is submitted as a post to the forum.
|
||||
A successful validation pool ratifies the post.
|
||||
Reputation is minted and distributed.
|
||||
Fees are distributed.
|
||||
|
||||
What if we want the work to be block production for a blockchain?
|
||||
Then to perform this work, an expert will need to participate in a communications network
|
||||
such that they can confidently arrive at a majority view of each block.
|
||||
Or else must at least be able to attest that a proposed block is valid,
|
||||
meaning that it
|
||||
|
||||
- does not conflict with what the node believes to be the majority view
|
||||
- includes what the node believes must be included according to the majority view
|
||||
note that with this scheme there be muliple possible valid proposed blocks.
|
||||
|
||||
---
|
|
@ -144,8 +144,7 @@ export class Forum extends ReputationHolder {
|
|||
}) {
|
||||
const postVertex = edge.to;
|
||||
const post = postVertex?.data;
|
||||
const balanceFromInbound = this.posts.getEdgeWeight(BALANCE, edge.from, edge.to) ?? 0;
|
||||
this.actions.propagateValue.log(edge.from.data, post, `(${increment}) balance (${balanceFromInbound})`);
|
||||
this.actions.propagateValue.log(edge.from.data, post, `(${increment})`);
|
||||
|
||||
if (!!params.referenceChainLimit && depth > params.referenceChainLimit) {
|
||||
this.actions.propagateValue.log(
|
||||
|
@ -164,37 +163,47 @@ export class Forum extends ReputationHolder {
|
|||
depth,
|
||||
value: post.value,
|
||||
increment,
|
||||
balanceFromInbound,
|
||||
initialNegative,
|
||||
});
|
||||
|
||||
let totalOutboundAmount = 0;
|
||||
|
||||
for (const citationEdge of postVertex.getEdges(CITATION, true)) {
|
||||
const { weight } = citationEdge;
|
||||
let outboundAmount = weight * increment;
|
||||
const balanceToOutbound = this.posts.getEdgeWeight(BALANCE, citationEdge.from, citationEdge.to) ?? 0;
|
||||
// We need to ensure that we propagate no more reputation than we leached
|
||||
if (initialNegative) {
|
||||
outboundAmount = outboundAmount < 0
|
||||
? Math.max(outboundAmount, -balanceToOutbound)
|
||||
: Math.min(outboundAmount, -balanceToOutbound);
|
||||
const propagate = async (positive) => {
|
||||
let totalOutboundAmount = 0;
|
||||
const citationEdges = postVertex.getEdges(CITATION, true)
|
||||
.filter(({ weight }) => (positive ? weight > 0 : weight < 0));
|
||||
for (const citationEdge of citationEdges) {
|
||||
const { weight } = citationEdge;
|
||||
let outboundAmount = weight * increment;
|
||||
const balanceToOutbound = this.posts.getEdgeWeight(BALANCE, citationEdge.from, citationEdge.to) ?? 0;
|
||||
// We need to ensure that we at most undo the prior effects of this post
|
||||
if (initialNegative) {
|
||||
outboundAmount = outboundAmount < 0
|
||||
? Math.max(outboundAmount, -balanceToOutbound)
|
||||
: Math.min(outboundAmount, -balanceToOutbound);
|
||||
}
|
||||
if (Math.abs(outboundAmount) > EPSILON) {
|
||||
const refundFromOutbound = await this.propagateValue(citationEdge, {
|
||||
rewardsAccumulator,
|
||||
increment: outboundAmount,
|
||||
depth: depth + 1,
|
||||
initialNegative: initialNegative || (depth === 0 && outboundAmount < 0),
|
||||
});
|
||||
outboundAmount -= refundFromOutbound;
|
||||
this.posts.setEdgeWeight(BALANCE, citationEdge.from, citationEdge.to, balanceToOutbound + outboundAmount);
|
||||
totalOutboundAmount += outboundAmount;
|
||||
}
|
||||
}
|
||||
if (Math.abs(outboundAmount) > EPSILON) {
|
||||
const refundFromOutbound = await this.propagateValue(citationEdge, {
|
||||
rewardsAccumulator,
|
||||
increment: outboundAmount,
|
||||
depth: depth + 1,
|
||||
initialNegative: initialNegative || (depth === 0 && outboundAmount < 0),
|
||||
});
|
||||
outboundAmount -= refundFromOutbound;
|
||||
this.posts.setEdgeWeight(BALANCE, citationEdge.from, citationEdge.to, balanceToOutbound + outboundAmount);
|
||||
totalOutboundAmount += outboundAmount;
|
||||
}
|
||||
}
|
||||
return totalOutboundAmount;
|
||||
};
|
||||
|
||||
increment -= totalOutboundAmount * params.leachingValue;
|
||||
// First, leach value via negative citations
|
||||
const totalLeachingAmount = await propagate(false);
|
||||
increment -= totalLeachingAmount * params.leachingValue;
|
||||
|
||||
// Now propagate value via positive citations
|
||||
const totalDonationAmount = await propagate(true);
|
||||
increment -= totalDonationAmount * params.leachingValue;
|
||||
|
||||
// Apply the remaining increment to the present post
|
||||
const rawNewValue = post.value + increment;
|
||||
const newValue = Math.max(0, rawNewValue);
|
||||
const appliedIncrement = newValue - post.value;
|
||||
|
|
|
@ -28,8 +28,8 @@ describe('Forum', () => {
|
|||
{ postId: posts[1], weight: 1 },
|
||||
]);
|
||||
forum.getPost(posts[0]).value.should.equal(0);
|
||||
forum.getPost(posts[1]).value.should.equal(20);
|
||||
forum.getPost(posts[2]).value.should.equal(10);
|
||||
forum.getPost(posts[1]).value.should.equal(30);
|
||||
forum.getPost(posts[2]).value.should.equal(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -44,8 +44,8 @@ describe('Forum', () => {
|
|||
{ postId: posts[2], weight: 1 },
|
||||
]);
|
||||
forum.getPost(posts[0]).value.should.equal(0);
|
||||
forum.getPost(posts[1]).value.should.equal(20);
|
||||
forum.getPost(posts[2]).value.should.equal(10);
|
||||
forum.getPost(posts[1]).value.should.equal(30);
|
||||
forum.getPost(posts[2]).value.should.equal(0);
|
||||
forum.getPost(posts[3]).value.should.equal(0);
|
||||
});
|
||||
|
||||
|
@ -55,8 +55,8 @@ describe('Forum', () => {
|
|||
]);
|
||||
console.log('test5', { posts });
|
||||
forum.getPost(posts[0]).value.should.equal(0);
|
||||
forum.getPost(posts[1]).value.should.equal(30);
|
||||
forum.getPost(posts[2]).value.should.equal(10);
|
||||
forum.getPost(posts[1]).value.should.equal(40);
|
||||
forum.getPost(posts[2]).value.should.equal(0);
|
||||
forum.getPost(posts[3]).value.should.equal(0);
|
||||
forum.getPost(posts[4]).value.should.equal(0);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue