Additional cleanup in preparation for forum test

This commit is contained in:
Ladd Hoffman 2023-01-04 15:18:29 -06:00
parent 07b992e572
commit 8980885881
11 changed files with 117 additions and 88 deletions

View File

@ -40,7 +40,7 @@ Should availability registration encumber reputation?
- Is a particular availability stake amount required?
Currently I support updating the staked amount.
Currently we support updating the staked amount.
Seems like a soft protocol thing.
A given DAO can have a formula for deciding appropriate amounts.
@ -59,7 +59,7 @@ The following was a code comment on `Business.submitRequest(fee, ...)`:
Does the following make sense?
We will link the forum to the bench
An author of a forum post /_ ? is always? can be? _/ a reputation holder.
This is what we call a member. Let's update that terminology to be `reputationHolder`.
This is what we call a expert. Let's update that terminology to be `reputationHolder`.
That's too long, though. Let's rename it to `expert`.
So we want to aim for the situation where the author of a forum post is an expert.
For now let's try thinking of them as experts no matter what;

View File

@ -57,6 +57,9 @@ export class Actor {
}
setValue(label, value) {
if (typeof value === 'number') {
value = value.toFixed(2);
}
let displayValue = this.values.get(label);
if (!displayValue) {
displayValue = this.scene.addDisplayValue(`${this.name} ${label}`);

View File

@ -55,23 +55,19 @@ export class Bench extends Actor {
.reduce((acc, cur) => (acc += cur), 0);
}
initiateValidationPool(
authorId,
{
postId,
fee,
duration,
tokenLossRatio,
contentiousDebate,
signingPublicKey,
authorStake,
anonymous,
},
) {
initiateValidationPool({
postId,
fee,
duration,
tokenLossRatio,
contentiousDebate,
signingPublicKey,
authorStake,
anonymous,
}) {
const validationPoolNumber = this.validationPools.size + 1;
const validationPool = new ValidationPool(
this,
authorId,
{
postId,
fee,

View File

@ -61,7 +61,7 @@ export class Business extends Actor {
// Validation pool supports secret ballots but we aren't using that here, since we want
// the post to be attributable to the reputation holder.
this.actions.initiateValidationPool.log(this, this.bench);
const pool = await this.bench.initiateValidationPool(reputationPublicKey, {
const pool = await this.bench.initiateValidationPool({
postId: post.id,
fee: request.fee,
duration,

View File

@ -44,20 +44,28 @@ export class Expert extends Actor {
return forum.addPost(this.reputationPublicKey, postContent);
}
async initiateValidationPool(bench, options) {
async submitPostWithFee(bench, forum, postContent, poolOptions) {
this.actions.submitPost.log(this, forum);
const postId = await forum.addPost(this.reputationPublicKey, postContent);
const pool = await this.initiateValidationPool(bench, { ...poolOptions, postId, anonymous: false });
return { postId, pool };
}
async initiateValidationPool(bench, poolOptions) {
// For now, directly call bench.initiateValidationPool();
const signingKey = await CryptoUtil.generateAsymmetricKey();
const signingPublicKey = await CryptoUtil.exportKey(signingKey.publicKey);
if (poolOptions.anonymous) {
const signingKey = await CryptoUtil.generateAsymmetricKey();
poolOptions.signingPublicKey = await CryptoUtil.exportKey(signingKey.publicKey);
} else {
poolOptions.signingPublicKey = this.reputationPublicKey;
}
this.actions.initiateValidationPool.log(
this,
bench,
`(fee: ${options.fee})`,
`(fee: ${poolOptions.fee})`,
);
const pool = bench.initiateValidationPool(this.reputationPublicKey, {
...options,
signingPublicKey,
});
this.validationPools.set(pool.id, { signingPublicKey });
const pool = bench.initiateValidationPool(poolOptions);
this.validationPools.set(pool.id, poolOptions);
return pool;
}

View File

@ -28,7 +28,6 @@ export class Scene {
darkMode: true,
primaryColor: '#2a5b6c',
primaryTextColor: '#b6b6b6',
fontFamily: 'monospace',
noteBkgColor: '#516f77',
noteTextColor: '#cecece',
},

View File

@ -16,7 +16,6 @@ const ValidationPoolStates = Object.freeze({
export class ValidationPool extends Actor {
constructor(
bench,
authorId,
{
postId,
signingPublicKey,
@ -61,7 +60,8 @@ export class ValidationPool extends Actor {
this.bench = bench;
this.id = CryptoUtil.randomUUID();
this.dateStart = new Date();
this.authorId = authorId;
this.authorSigningPublicKey = signingPublicKey;
this.anonymous = anonymous;
this.fee = fee;
this.duration = duration;
this.tokenLossRatio = tokenLossRatio;
@ -201,10 +201,17 @@ export class ValidationPool extends Actor {
}
distributeTokens(result) {
let authorReputationPublicKey;
if (this.anonymous) {
const author = this.voters.get(this.authorSigningPublicKey);
authorReputationPublicKey = author.reputationPublicKey;
} else {
authorReputationPublicKey = this.authorSigningPublicKey;
}
// Reward the author
// TODO: If the vote fails, distribute tokens.author among winning voters
if (result === true) {
this.bench.reputations.addTokens(this.authorId, this.tokens.for);
this.bench.reputations.addTokens(authorReputationPublicKey, this.tokens.for);
// Reward the vote winners, in proportion to their stakes
const tokensForWinners = this.tokens.against;
const winningVotes = this.listVotes(result);

View File

@ -1,6 +1,5 @@
body {
background-color: #1b3d49;
background-color: #114754;
background-color: #09343f;
color: #b6b6b6;
font-family: monospace;
font-size: 8pt;

View File

@ -26,17 +26,17 @@
"sequenceDiagram"
));
const members = (window.members = []);
const experts = (window.experts = []);
const newExpert = async () => {
const index = members.length;
const index = experts.length;
const name = `Expert${index + 1}`;
const member = await new Expert(name, scene).initialize();
members.push(member);
return member;
const expert = await new Expert(name, scene).initialize();
experts.push(expert);
return expert;
};
const member1 = await newExpert();
const member2 = await newExpert();
const expert1 = await newExpert();
const expert2 = await newExpert();
await newExpert();
const bench = (window.bench = new Bench("Bench", scene));
const forum = (window.forum = new Forum(bench, "Forum", scene));
@ -55,10 +55,10 @@
const requestor = new Public("Public", scene);
const updateDisplayValues = async () => {
for (const member of members) {
member.setValue(
for (const expert of experts) {
expert.setValue(
"rep",
bench.reputations.getTokens(member.reputationPublicKey)
bench.reputations.getTokens(expert.reputationPublicKey)
);
}
bench.setValue("total rep", bench.getTotalReputation());
@ -73,10 +73,10 @@
const getActiveWorker = async () => {
let worker;
let request;
for (const member of members) {
request = await member.getAssignedWork(availability, business);
for (const expert of experts) {
request = await expert.getAssignedWork(availability, business);
if (request) {
worker = member;
worker = expert;
worker.actions.getAssignedWork.log(worker, availability);
worker.activate();
break;
@ -86,9 +86,9 @@
};
const voteForWorkEvidence = async (worker, pool) => {
for (const member of members) {
if (member !== worker) {
await member.castVote(pool, {
for (const expert of experts) {
if (expert !== worker) {
await expert.castVote(pool, {
position: true,
stake: 1,
anonymous: false,
@ -100,8 +100,8 @@
await updateDisplayValuesAndDelay();
// Populate availability pool
await member1.registerAvailability(availability, 1);
await member2.registerAvailability(availability, 1);
await expert1.registerAvailability(availability, 1);
await expert2.registerAvailability(availability, 1);
await updateDisplayValuesAndDelay();
// Submit work request

View File

@ -27,33 +27,26 @@
"sequenceDiagram"
));
const members = (window.members = []);
const experts = (window.experts = []);
const newExpert = async () => {
const index = members.length;
const index = experts.length;
const name = `Expert${index + 1}`;
const member = await new Expert(name, scene).initialize();
members.push(member);
return member;
const expert = await new Expert(name, scene).initialize();
experts.push(expert);
return expert;
};
const posts = (window.posts = []);
const newPost = async (author, content, citations) => {
const postContent = new PostContent({ hello: "there" });
const postId = await member1.submitPost(forum, postContent1);
return postId;
};
const member1 = await newExpert();
const member2 = await newExpert();
const expert1 = await newExpert();
const expert2 = await newExpert();
await newExpert();
const bench = (window.bench = new Bench("Bench", scene));
const forum = (window.forum = new Forum(bench, "Forum", scene));
const updateDisplayValues = async () => {
for (const member of members) {
member.setValue(
for (const expert of experts) {
expert.setValue(
"rep",
bench.reputations.getTokens(member.reputationPublicKey)
bench.reputations.getTokens(expert.reputationPublicKey)
);
}
bench.setValue("total rep", bench.getTotalReputation());
@ -67,15 +60,39 @@
await updateDisplayValuesAndDelay();
const postId1 = await member1.submitPost(
const { postId: postId1, pool: pool1 } = await expert1.submitPostWithFee(
bench,
forum,
new PostContent({ hello: "there" })
new PostContent({ hello: "there" }),
{
fee: 10,
duration: 1000,
tokenLossRatio: 1,
}
);
await updateDisplayValuesAndDelay();
const postId2 = await member1.submitPost(
await expert2.castVote(pool1, { position: true, stake: 1, anonymous: false });
await updateDisplayValuesAndDelay();
await pool1.evaluateWinningConditions();
await updateDisplayValuesAndDelay();
const { pool: pool2 } = await expert2.submitPostWithFee(
bench,
forum,
new PostContent({ hello: "to you as well" }).addCitation(postId1, 0.5)
new PostContent({ hello: "to you as well" }).addCitation(postId1, 0.5),
{
fee: 10,
duration: 1000,
tokenLossRatio: 1,
}
);
await updateDisplayValuesAndDelay();
await expert1.castVote(pool2, { position: true, stake: 1, anonymous: false });
await updateDisplayValuesAndDelay();
await pool2.evaluateWinningConditions();
await updateDisplayValuesAndDelay();
</script>

View File

@ -19,24 +19,24 @@
const scene = (window.scene = new Scene("Validation Pool test", rootBox).log(
"sequenceDiagram"
));
const member1 = (window.member1 = await new Expert(
const expert1 = (window.expert1 = await new Expert(
"Expert1",
scene
).initialize());
const member2 = (window.member2 = await new Expert(
const expert2 = (window.expert2 = await new Expert(
"Expert2",
scene
).initialize());
const bench = (window.bench = new Bench("Bench", scene));
const updateDisplayValues = async () => {
member1.setValue(
expert1.setValue(
"rep",
bench.reputations.getTokens(member1.reputationPublicKey)
bench.reputations.getTokens(expert1.reputationPublicKey)
);
member2.setValue(
expert2.setValue(
"rep",
bench.reputations.getTokens(member2.reputationPublicKey)
bench.reputations.getTokens(expert2.reputationPublicKey)
);
bench.setValue("total rep", bench.getTotalReputation());
// With params.lockingTimeExponent = 0 and params.activeVoterThreshold = null,
@ -50,14 +50,14 @@
updateDisplayValues();
await delay(1000);
// First member can self-approve
// First expert can self-approve
{
const pool = await member1.initiateValidationPool(bench, {
const pool = await expert1.initiateValidationPool(bench, {
fee: 7,
duration: 1000,
tokenLossRatio: 1,
});
await member1.revealIdentity(pool);
await expert1.revealIdentity(pool);
// Attempting to evaluate winning conditions before the duration has expired
// should result in an exception
try {
@ -78,14 +78,14 @@
await delay(1000);
}
// Failure example: second member can not self-approve
// Failure example: second expert can not self-approve
try {
const pool = await member2.initiateValidationPool(bench, {
const pool = await expert2.initiateValidationPool(bench, {
fee: 1,
duration: 1000,
tokenLossRatio: 1,
});
await member2.revealIdentity(pool);
await expert2.revealIdentity(pool);
await delay(1000);
await pool.evaluateWinningConditions(); // Quorum not met!
await updateDisplayValues();
@ -99,16 +99,16 @@
}
}
// Second member must be approved by first member
// Second expert must be approved by first expert
{
const pool = await member2.initiateValidationPool(bench, {
const pool = await expert2.initiateValidationPool(bench, {
fee: 1,
duration: 1000,
tokenLossRatio: 1,
});
await member1.castVote(pool, { position: true, stake: 4, lockingTime: 0 });
await member1.revealIdentity(pool);
await member2.revealIdentity(pool);
await expert1.castVote(pool, { position: true, stake: 4, lockingTime: 0 });
await expert1.revealIdentity(pool);
await expert2.revealIdentity(pool);
await delay(1000);
await pool.evaluateWinningConditions(); // Vote passes
await updateDisplayValues();