Additional cleanup in preparation for forum test
This commit is contained in:
parent
07b992e572
commit
8980885881
|
@ -40,7 +40,7 @@ Should availability registration encumber reputation?
|
||||||
|
|
||||||
- Is a particular availability stake amount required?
|
- 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.
|
Seems like a soft protocol thing.
|
||||||
A given DAO can have a formula for deciding appropriate amounts.
|
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?
|
Does the following make sense?
|
||||||
We will link the forum to the bench
|
We will link the forum to the bench
|
||||||
An author of a forum post /_ ? is always? can be? _/ a reputation holder.
|
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`.
|
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.
|
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;
|
For now let's try thinking of them as experts no matter what;
|
||||||
|
|
|
@ -57,6 +57,9 @@ export class Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
setValue(label, value) {
|
setValue(label, value) {
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
value = value.toFixed(2);
|
||||||
|
}
|
||||||
let displayValue = this.values.get(label);
|
let displayValue = this.values.get(label);
|
||||||
if (!displayValue) {
|
if (!displayValue) {
|
||||||
displayValue = this.scene.addDisplayValue(`${this.name} ${label}`);
|
displayValue = this.scene.addDisplayValue(`${this.name} ${label}`);
|
||||||
|
|
|
@ -55,23 +55,19 @@ export class Bench extends Actor {
|
||||||
.reduce((acc, cur) => (acc += cur), 0);
|
.reduce((acc, cur) => (acc += cur), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
initiateValidationPool(
|
initiateValidationPool({
|
||||||
authorId,
|
postId,
|
||||||
{
|
fee,
|
||||||
postId,
|
duration,
|
||||||
fee,
|
tokenLossRatio,
|
||||||
duration,
|
contentiousDebate,
|
||||||
tokenLossRatio,
|
signingPublicKey,
|
||||||
contentiousDebate,
|
authorStake,
|
||||||
signingPublicKey,
|
anonymous,
|
||||||
authorStake,
|
}) {
|
||||||
anonymous,
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
const validationPoolNumber = this.validationPools.size + 1;
|
const validationPoolNumber = this.validationPools.size + 1;
|
||||||
const validationPool = new ValidationPool(
|
const validationPool = new ValidationPool(
|
||||||
this,
|
this,
|
||||||
authorId,
|
|
||||||
{
|
{
|
||||||
postId,
|
postId,
|
||||||
fee,
|
fee,
|
||||||
|
|
|
@ -61,7 +61,7 @@ export class Business extends Actor {
|
||||||
// Validation pool supports secret ballots but we aren't using that here, since we want
|
// Validation pool supports secret ballots but we aren't using that here, since we want
|
||||||
// the post to be attributable to the reputation holder.
|
// the post to be attributable to the reputation holder.
|
||||||
this.actions.initiateValidationPool.log(this, this.bench);
|
this.actions.initiateValidationPool.log(this, this.bench);
|
||||||
const pool = await this.bench.initiateValidationPool(reputationPublicKey, {
|
const pool = await this.bench.initiateValidationPool({
|
||||||
postId: post.id,
|
postId: post.id,
|
||||||
fee: request.fee,
|
fee: request.fee,
|
||||||
duration,
|
duration,
|
||||||
|
|
|
@ -44,20 +44,28 @@ export class Expert extends Actor {
|
||||||
return forum.addPost(this.reputationPublicKey, postContent);
|
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();
|
// For now, directly call bench.initiateValidationPool();
|
||||||
const signingKey = await CryptoUtil.generateAsymmetricKey();
|
if (poolOptions.anonymous) {
|
||||||
const signingPublicKey = await CryptoUtil.exportKey(signingKey.publicKey);
|
const signingKey = await CryptoUtil.generateAsymmetricKey();
|
||||||
|
poolOptions.signingPublicKey = await CryptoUtil.exportKey(signingKey.publicKey);
|
||||||
|
} else {
|
||||||
|
poolOptions.signingPublicKey = this.reputationPublicKey;
|
||||||
|
}
|
||||||
this.actions.initiateValidationPool.log(
|
this.actions.initiateValidationPool.log(
|
||||||
this,
|
this,
|
||||||
bench,
|
bench,
|
||||||
`(fee: ${options.fee})`,
|
`(fee: ${poolOptions.fee})`,
|
||||||
);
|
);
|
||||||
const pool = bench.initiateValidationPool(this.reputationPublicKey, {
|
const pool = bench.initiateValidationPool(poolOptions);
|
||||||
...options,
|
this.validationPools.set(pool.id, poolOptions);
|
||||||
signingPublicKey,
|
|
||||||
});
|
|
||||||
this.validationPools.set(pool.id, { signingPublicKey });
|
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ export class Scene {
|
||||||
darkMode: true,
|
darkMode: true,
|
||||||
primaryColor: '#2a5b6c',
|
primaryColor: '#2a5b6c',
|
||||||
primaryTextColor: '#b6b6b6',
|
primaryTextColor: '#b6b6b6',
|
||||||
fontFamily: 'monospace',
|
|
||||||
noteBkgColor: '#516f77',
|
noteBkgColor: '#516f77',
|
||||||
noteTextColor: '#cecece',
|
noteTextColor: '#cecece',
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,7 +16,6 @@ const ValidationPoolStates = Object.freeze({
|
||||||
export class ValidationPool extends Actor {
|
export class ValidationPool extends Actor {
|
||||||
constructor(
|
constructor(
|
||||||
bench,
|
bench,
|
||||||
authorId,
|
|
||||||
{
|
{
|
||||||
postId,
|
postId,
|
||||||
signingPublicKey,
|
signingPublicKey,
|
||||||
|
@ -61,7 +60,8 @@ export class ValidationPool extends Actor {
|
||||||
this.bench = bench;
|
this.bench = bench;
|
||||||
this.id = CryptoUtil.randomUUID();
|
this.id = CryptoUtil.randomUUID();
|
||||||
this.dateStart = new Date();
|
this.dateStart = new Date();
|
||||||
this.authorId = authorId;
|
this.authorSigningPublicKey = signingPublicKey;
|
||||||
|
this.anonymous = anonymous;
|
||||||
this.fee = fee;
|
this.fee = fee;
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
this.tokenLossRatio = tokenLossRatio;
|
this.tokenLossRatio = tokenLossRatio;
|
||||||
|
@ -201,10 +201,17 @@ export class ValidationPool extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
distributeTokens(result) {
|
distributeTokens(result) {
|
||||||
|
let authorReputationPublicKey;
|
||||||
|
if (this.anonymous) {
|
||||||
|
const author = this.voters.get(this.authorSigningPublicKey);
|
||||||
|
authorReputationPublicKey = author.reputationPublicKey;
|
||||||
|
} else {
|
||||||
|
authorReputationPublicKey = this.authorSigningPublicKey;
|
||||||
|
}
|
||||||
// Reward the author
|
// Reward the author
|
||||||
// TODO: If the vote fails, distribute tokens.author among winning voters
|
// TODO: If the vote fails, distribute tokens.author among winning voters
|
||||||
if (result === true) {
|
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
|
// Reward the vote winners, in proportion to their stakes
|
||||||
const tokensForWinners = this.tokens.against;
|
const tokensForWinners = this.tokens.against;
|
||||||
const winningVotes = this.listVotes(result);
|
const winningVotes = this.listVotes(result);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
body {
|
body {
|
||||||
background-color: #1b3d49;
|
background-color: #09343f;
|
||||||
background-color: #114754;
|
|
||||||
color: #b6b6b6;
|
color: #b6b6b6;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 8pt;
|
font-size: 8pt;
|
||||||
|
|
|
@ -26,17 +26,17 @@
|
||||||
"sequenceDiagram"
|
"sequenceDiagram"
|
||||||
));
|
));
|
||||||
|
|
||||||
const members = (window.members = []);
|
const experts = (window.experts = []);
|
||||||
const newExpert = async () => {
|
const newExpert = async () => {
|
||||||
const index = members.length;
|
const index = experts.length;
|
||||||
const name = `Expert${index + 1}`;
|
const name = `Expert${index + 1}`;
|
||||||
const member = await new Expert(name, scene).initialize();
|
const expert = await new Expert(name, scene).initialize();
|
||||||
members.push(member);
|
experts.push(expert);
|
||||||
return member;
|
return expert;
|
||||||
};
|
};
|
||||||
|
|
||||||
const member1 = await newExpert();
|
const expert1 = await newExpert();
|
||||||
const member2 = await newExpert();
|
const expert2 = await newExpert();
|
||||||
await newExpert();
|
await newExpert();
|
||||||
const bench = (window.bench = new Bench("Bench", scene));
|
const bench = (window.bench = new Bench("Bench", scene));
|
||||||
const forum = (window.forum = new Forum(bench, "Forum", scene));
|
const forum = (window.forum = new Forum(bench, "Forum", scene));
|
||||||
|
@ -55,10 +55,10 @@
|
||||||
const requestor = new Public("Public", scene);
|
const requestor = new Public("Public", scene);
|
||||||
|
|
||||||
const updateDisplayValues = async () => {
|
const updateDisplayValues = async () => {
|
||||||
for (const member of members) {
|
for (const expert of experts) {
|
||||||
member.setValue(
|
expert.setValue(
|
||||||
"rep",
|
"rep",
|
||||||
bench.reputations.getTokens(member.reputationPublicKey)
|
bench.reputations.getTokens(expert.reputationPublicKey)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
bench.setValue("total rep", bench.getTotalReputation());
|
bench.setValue("total rep", bench.getTotalReputation());
|
||||||
|
@ -73,10 +73,10 @@
|
||||||
const getActiveWorker = async () => {
|
const getActiveWorker = async () => {
|
||||||
let worker;
|
let worker;
|
||||||
let request;
|
let request;
|
||||||
for (const member of members) {
|
for (const expert of experts) {
|
||||||
request = await member.getAssignedWork(availability, business);
|
request = await expert.getAssignedWork(availability, business);
|
||||||
if (request) {
|
if (request) {
|
||||||
worker = member;
|
worker = expert;
|
||||||
worker.actions.getAssignedWork.log(worker, availability);
|
worker.actions.getAssignedWork.log(worker, availability);
|
||||||
worker.activate();
|
worker.activate();
|
||||||
break;
|
break;
|
||||||
|
@ -86,9 +86,9 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const voteForWorkEvidence = async (worker, pool) => {
|
const voteForWorkEvidence = async (worker, pool) => {
|
||||||
for (const member of members) {
|
for (const expert of experts) {
|
||||||
if (member !== worker) {
|
if (expert !== worker) {
|
||||||
await member.castVote(pool, {
|
await expert.castVote(pool, {
|
||||||
position: true,
|
position: true,
|
||||||
stake: 1,
|
stake: 1,
|
||||||
anonymous: false,
|
anonymous: false,
|
||||||
|
@ -100,8 +100,8 @@
|
||||||
await updateDisplayValuesAndDelay();
|
await updateDisplayValuesAndDelay();
|
||||||
|
|
||||||
// Populate availability pool
|
// Populate availability pool
|
||||||
await member1.registerAvailability(availability, 1);
|
await expert1.registerAvailability(availability, 1);
|
||||||
await member2.registerAvailability(availability, 1);
|
await expert2.registerAvailability(availability, 1);
|
||||||
await updateDisplayValuesAndDelay();
|
await updateDisplayValuesAndDelay();
|
||||||
|
|
||||||
// Submit work request
|
// Submit work request
|
||||||
|
|
|
@ -27,33 +27,26 @@
|
||||||
"sequenceDiagram"
|
"sequenceDiagram"
|
||||||
));
|
));
|
||||||
|
|
||||||
const members = (window.members = []);
|
const experts = (window.experts = []);
|
||||||
const newExpert = async () => {
|
const newExpert = async () => {
|
||||||
const index = members.length;
|
const index = experts.length;
|
||||||
const name = `Expert${index + 1}`;
|
const name = `Expert${index + 1}`;
|
||||||
const member = await new Expert(name, scene).initialize();
|
const expert = await new Expert(name, scene).initialize();
|
||||||
members.push(member);
|
experts.push(expert);
|
||||||
return member;
|
return expert;
|
||||||
};
|
};
|
||||||
|
|
||||||
const posts = (window.posts = []);
|
const expert1 = await newExpert();
|
||||||
const newPost = async (author, content, citations) => {
|
const expert2 = await newExpert();
|
||||||
const postContent = new PostContent({ hello: "there" });
|
|
||||||
const postId = await member1.submitPost(forum, postContent1);
|
|
||||||
return postId;
|
|
||||||
};
|
|
||||||
|
|
||||||
const member1 = await newExpert();
|
|
||||||
const member2 = await newExpert();
|
|
||||||
await newExpert();
|
await newExpert();
|
||||||
const bench = (window.bench = new Bench("Bench", scene));
|
const bench = (window.bench = new Bench("Bench", scene));
|
||||||
const forum = (window.forum = new Forum(bench, "Forum", scene));
|
const forum = (window.forum = new Forum(bench, "Forum", scene));
|
||||||
|
|
||||||
const updateDisplayValues = async () => {
|
const updateDisplayValues = async () => {
|
||||||
for (const member of members) {
|
for (const expert of experts) {
|
||||||
member.setValue(
|
expert.setValue(
|
||||||
"rep",
|
"rep",
|
||||||
bench.reputations.getTokens(member.reputationPublicKey)
|
bench.reputations.getTokens(expert.reputationPublicKey)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
bench.setValue("total rep", bench.getTotalReputation());
|
bench.setValue("total rep", bench.getTotalReputation());
|
||||||
|
@ -67,15 +60,39 @@
|
||||||
|
|
||||||
await updateDisplayValuesAndDelay();
|
await updateDisplayValuesAndDelay();
|
||||||
|
|
||||||
const postId1 = await member1.submitPost(
|
const { postId: postId1, pool: pool1 } = await expert1.submitPostWithFee(
|
||||||
|
bench,
|
||||||
forum,
|
forum,
|
||||||
new PostContent({ hello: "there" })
|
new PostContent({ hello: "there" }),
|
||||||
|
{
|
||||||
|
fee: 10,
|
||||||
|
duration: 1000,
|
||||||
|
tokenLossRatio: 1,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
await updateDisplayValuesAndDelay();
|
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,
|
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 updateDisplayValuesAndDelay();
|
||||||
|
|
||||||
|
await expert1.castVote(pool2, { position: true, stake: 1, anonymous: false });
|
||||||
|
await updateDisplayValuesAndDelay();
|
||||||
|
|
||||||
|
await pool2.evaluateWinningConditions();
|
||||||
|
await updateDisplayValuesAndDelay();
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -19,24 +19,24 @@
|
||||||
const scene = (window.scene = new Scene("Validation Pool test", rootBox).log(
|
const scene = (window.scene = new Scene("Validation Pool test", rootBox).log(
|
||||||
"sequenceDiagram"
|
"sequenceDiagram"
|
||||||
));
|
));
|
||||||
const member1 = (window.member1 = await new Expert(
|
const expert1 = (window.expert1 = await new Expert(
|
||||||
"Expert1",
|
"Expert1",
|
||||||
scene
|
scene
|
||||||
).initialize());
|
).initialize());
|
||||||
const member2 = (window.member2 = await new Expert(
|
const expert2 = (window.expert2 = await new Expert(
|
||||||
"Expert2",
|
"Expert2",
|
||||||
scene
|
scene
|
||||||
).initialize());
|
).initialize());
|
||||||
const bench = (window.bench = new Bench("Bench", scene));
|
const bench = (window.bench = new Bench("Bench", scene));
|
||||||
|
|
||||||
const updateDisplayValues = async () => {
|
const updateDisplayValues = async () => {
|
||||||
member1.setValue(
|
expert1.setValue(
|
||||||
"rep",
|
"rep",
|
||||||
bench.reputations.getTokens(member1.reputationPublicKey)
|
bench.reputations.getTokens(expert1.reputationPublicKey)
|
||||||
);
|
);
|
||||||
member2.setValue(
|
expert2.setValue(
|
||||||
"rep",
|
"rep",
|
||||||
bench.reputations.getTokens(member2.reputationPublicKey)
|
bench.reputations.getTokens(expert2.reputationPublicKey)
|
||||||
);
|
);
|
||||||
bench.setValue("total rep", bench.getTotalReputation());
|
bench.setValue("total rep", bench.getTotalReputation());
|
||||||
// With params.lockingTimeExponent = 0 and params.activeVoterThreshold = null,
|
// With params.lockingTimeExponent = 0 and params.activeVoterThreshold = null,
|
||||||
|
@ -50,14 +50,14 @@
|
||||||
updateDisplayValues();
|
updateDisplayValues();
|
||||||
await delay(1000);
|
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,
|
fee: 7,
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
tokenLossRatio: 1,
|
tokenLossRatio: 1,
|
||||||
});
|
});
|
||||||
await member1.revealIdentity(pool);
|
await expert1.revealIdentity(pool);
|
||||||
// Attempting to evaluate winning conditions before the duration has expired
|
// Attempting to evaluate winning conditions before the duration has expired
|
||||||
// should result in an exception
|
// should result in an exception
|
||||||
try {
|
try {
|
||||||
|
@ -78,14 +78,14 @@
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Failure example: second member can not self-approve
|
// Failure example: second expert can not self-approve
|
||||||
try {
|
try {
|
||||||
const pool = await member2.initiateValidationPool(bench, {
|
const pool = await expert2.initiateValidationPool(bench, {
|
||||||
fee: 1,
|
fee: 1,
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
tokenLossRatio: 1,
|
tokenLossRatio: 1,
|
||||||
});
|
});
|
||||||
await member2.revealIdentity(pool);
|
await expert2.revealIdentity(pool);
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
await pool.evaluateWinningConditions(); // Quorum not met!
|
await pool.evaluateWinningConditions(); // Quorum not met!
|
||||||
await updateDisplayValues();
|
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,
|
fee: 1,
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
tokenLossRatio: 1,
|
tokenLossRatio: 1,
|
||||||
});
|
});
|
||||||
await member1.castVote(pool, { position: true, stake: 4, lockingTime: 0 });
|
await expert1.castVote(pool, { position: true, stake: 4, lockingTime: 0 });
|
||||||
await member1.revealIdentity(pool);
|
await expert1.revealIdentity(pool);
|
||||||
await member2.revealIdentity(pool);
|
await expert2.revealIdentity(pool);
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
await pool.evaluateWinningConditions(); // Vote passes
|
await pool.evaluateWinningConditions(); // Vote passes
|
||||||
await updateDisplayValues();
|
await updateDisplayValues();
|
||||||
|
|
Loading…
Reference in New Issue