Refactor
This commit is contained in:
parent
92da97fede
commit
ea087451ff
|
@ -10,7 +10,7 @@ export class Expert extends Actor {
|
||||||
submitPostViaNetwork: new Action('submit post via network', scene),
|
submitPostViaNetwork: new Action('submit post via network', scene),
|
||||||
submitPost: new Action('submit post', scene),
|
submitPost: new Action('submit post', scene),
|
||||||
initiateValidationPool: new Action('initiate validation pool', scene),
|
initiateValidationPool: new Action('initiate validation pool', scene),
|
||||||
castVote: new Action('cast vote', scene),
|
stake: new Action('stake on post', scene),
|
||||||
revealIdentity: new Action('reveal identity', scene),
|
revealIdentity: new Action('reveal identity', scene),
|
||||||
registerAvailability: new Action('register availability', scene),
|
registerAvailability: new Action('register availability', scene),
|
||||||
getAssignedWork: new Action('get assigned work', scene),
|
getAssignedWork: new Action('get assigned work', scene),
|
||||||
|
@ -67,8 +67,8 @@ export class Expert extends Actor {
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
async castVote(validationPool, {
|
async stake(validationPool, {
|
||||||
position, stake, lockingTime, anonymous = true,
|
position, amount, lockingTime, anonymous = false,
|
||||||
}) {
|
}) {
|
||||||
let signingPublicKey;
|
let signingPublicKey;
|
||||||
if (anonymous) {
|
if (anonymous) {
|
||||||
|
@ -78,15 +78,15 @@ export class Expert extends Actor {
|
||||||
} else {
|
} else {
|
||||||
signingPublicKey = this.reputationPublicKey;
|
signingPublicKey = this.reputationPublicKey;
|
||||||
}
|
}
|
||||||
// TODO: encrypt vote
|
// TODO: encrypt stake
|
||||||
// TODO: sign message
|
// TODO: sign message
|
||||||
await this.actions.castVote.log(
|
await this.actions.stake.log(
|
||||||
this,
|
this,
|
||||||
validationPool,
|
validationPool,
|
||||||
`(${position ? 'for' : 'against'}, stake: ${stake}, anonymous: ${anonymous})`,
|
`(${position ? 'for' : 'against'}, stake: ${amount}, anonymous: ${anonymous})`,
|
||||||
);
|
);
|
||||||
return validationPool.castVote(signingPublicKey, {
|
return validationPool.stake(signingPublicKey, {
|
||||||
position, stake, lockingTime, anonymous,
|
position, amount, lockingTime, anonymous,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,15 +85,16 @@ export class Forum extends Actor {
|
||||||
post.setStatus('Validated');
|
post.setStatus('Validated');
|
||||||
|
|
||||||
// Compute rewards
|
// Compute rewards
|
||||||
const rewards = new Map();
|
const rewardsAccumulator = new Map();
|
||||||
await this.propagateValue(rewards, pool, post, initialValue);
|
await this.propagateValue(rewardsAccumulator, pool, post, initialValue);
|
||||||
|
|
||||||
// Apply computed rewards
|
// Apply computed rewards
|
||||||
for (const [id, value] of rewards) {
|
for (const [id, value] of rewardsAccumulator) {
|
||||||
bench.reputations.addTokens(id, value);
|
bench.reputations.addTokens(id, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async propagateValue(rewards, fromActor, post, increment, depth = 0) {
|
async propagateValue(rewardsAccumulator, fromActor, post, increment, depth = 0) {
|
||||||
if (params.referenceChainLimit >= 0 && depth > params.referenceChainLimit) {
|
if (params.referenceChainLimit >= 0 && depth > params.referenceChainLimit) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -101,29 +102,44 @@ export class Forum extends Actor {
|
||||||
this.actions.propagateValue.log(fromActor, post, `(${increment})`);
|
this.actions.propagateValue.log(fromActor, post, `(${increment})`);
|
||||||
|
|
||||||
// Recursively distribute reputation to citations, according to weights
|
// Recursively distribute reputation to citations, according to weights
|
||||||
let downstreamRefund = 0;
|
let totalOutboundAmount = 0;
|
||||||
|
let refundFromOutbound = 0;
|
||||||
for (const { postId: citedPostId, weight } of post.citations) {
|
for (const { postId: citedPostId, weight } of post.citations) {
|
||||||
const citedPost = this.getPost(citedPostId);
|
const citedPost = this.getPost(citedPostId);
|
||||||
downstreamRefund += await this.propagateValue(rewards, post, citedPost, weight * increment, depth + 1);
|
const outboundAmount = weight * increment;
|
||||||
|
totalOutboundAmount += outboundAmount;
|
||||||
|
refundFromOutbound += await this.propagateValue(rewardsAccumulator, post, citedPost, outboundAmount, depth + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply leaching value
|
// Apply leaching value
|
||||||
const adjustedIncrement = increment * (1 - params.leachingValue * post.totalCitationWeight) + downstreamRefund;
|
const incrementAfterLeaching = increment - (totalOutboundAmount - refundFromOutbound) * params.leachingValue;
|
||||||
|
// const adjustedIncrement = increment - outboundReferencesTotal + refundFromOutbound;
|
||||||
|
|
||||||
// Prevent value from decreasing below zero
|
// Prevent value from decreasing below zero
|
||||||
const rawNewValue = post.value + adjustedIncrement;
|
const rawNewValue = post.value + incrementAfterLeaching;
|
||||||
const newValue = Math.max(0, rawNewValue);
|
const newValue = Math.max(0, rawNewValue);
|
||||||
const upstreamRefund = rawNewValue < 0 ? rawNewValue : 0;
|
// 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 appliedIncrement = newValue - post.value;
|
||||||
|
|
||||||
|
// Award reputation to post author
|
||||||
|
console.log(`reward for post author ${post.authorPublicKey}`, {
|
||||||
|
increment,
|
||||||
|
totalOutboundAmount,
|
||||||
|
refundFromOutbound,
|
||||||
|
incrementAfterLeaching,
|
||||||
|
rawNewValue,
|
||||||
|
newValue,
|
||||||
|
appliedIncrement,
|
||||||
|
refundToInbound,
|
||||||
|
});
|
||||||
|
|
||||||
|
rewardsAccumulator.set(post.authorPublicKey, appliedIncrement);
|
||||||
|
|
||||||
// Increment the value of the post
|
// Increment the value of the post
|
||||||
await this.setPostValue(post, newValue);
|
await this.setPostValue(post, newValue);
|
||||||
|
|
||||||
// Award reputation to post author
|
return refundToInbound;
|
||||||
console.log(`reward for post author ${post.authorPublicKey}`, appliedIncrement);
|
|
||||||
|
|
||||||
rewards.set(post.authorPublicKey, appliedIncrement);
|
|
||||||
|
|
||||||
return upstreamRefund;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ export class PostMessage extends Message {
|
||||||
contentToJSON() {
|
contentToJSON() {
|
||||||
return {
|
return {
|
||||||
post: this.content.post.toJSON(),
|
post: this.content.post.toJSON(),
|
||||||
stake: this.content.stake,
|
stakeAmount: this.content.stake,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import params from '../params.js';
|
||||||
|
|
||||||
|
export class Stake {
|
||||||
|
constructor(position, amount, lockingTime) {
|
||||||
|
this.position = position;
|
||||||
|
this.amount = amount;
|
||||||
|
this.lockingTime = lockingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStakeValue() {
|
||||||
|
return this.amount * this.lockingTime ** params.lockingTimeExponent;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import { CryptoUtil } from './crypto.js';
|
import { CryptoUtil } from './crypto.js';
|
||||||
import { Vote } from './vote.js';
|
import { Stake } from './stake.js';
|
||||||
import { Voter } from './voter.js';
|
import { Voter } from './voter.js';
|
||||||
import { Actor } from './actor.js';
|
import { Actor } from './actor.js';
|
||||||
import params from '../params.js';
|
import params from '../params.js';
|
||||||
|
@ -58,7 +58,7 @@ export class ValidationPool extends Actor {
|
||||||
this.postId = postId;
|
this.postId = postId;
|
||||||
this.state = ValidationPoolStates.OPEN;
|
this.state = ValidationPoolStates.OPEN;
|
||||||
this.setStatus('Open');
|
this.setStatus('Open');
|
||||||
this.votes = new Map();
|
this.stakes = new Map();
|
||||||
this.voters = new Map();
|
this.voters = new Map();
|
||||||
this.id = CryptoUtil.randomUUID();
|
this.id = CryptoUtil.randomUUID();
|
||||||
this.dateStart = new Date();
|
this.dateStart = new Date();
|
||||||
|
@ -71,26 +71,20 @@ export class ValidationPool extends Actor {
|
||||||
this.tokensMinted = fee * params.mintingRatio();
|
this.tokensMinted = fee * params.mintingRatio();
|
||||||
// Tokens minted "for" the post go toward stake of author voting for their own post.
|
// Tokens minted "for" the post go toward stake of author voting for their own post.
|
||||||
// Also, author can provide additional stakes, e.g. availability stakes for work evidence post.
|
// Also, author can provide additional stakes, e.g. availability stakes for work evidence post.
|
||||||
this.castVote(signingPublicKey, {
|
this.stake(signingPublicKey, {
|
||||||
position: true,
|
position: true,
|
||||||
stake: this.tokensMinted * params.stakeForAuthor + authorStake,
|
amount: this.tokensMinted * params.stakeForAuthor + authorStake,
|
||||||
anonymous,
|
anonymous,
|
||||||
});
|
});
|
||||||
this.castVote(undefined, {
|
this.stake(this.id, {
|
||||||
position: false,
|
position: false,
|
||||||
stake: this.tokensMinted * (1 - params.stakeForAuthor),
|
amount: this.tokensMinted * (1 - params.stakeForAuthor),
|
||||||
isSystemVote: true,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async castVote(signingPublicKey, {
|
async stake(signingPublicKey, {
|
||||||
position, stake, lockingTime = 0, anonymous = true, isSystemVote = false,
|
position, amount, lockingTime = 0, anonymous = false,
|
||||||
}) {
|
}) {
|
||||||
if (isSystemVote) {
|
|
||||||
signingPublicKey = CryptoUtil.randomUUID();
|
|
||||||
anonymous = false;
|
|
||||||
}
|
|
||||||
const vote = new Vote(position, stake, lockingTime, isSystemVote);
|
|
||||||
if (this.state === ValidationPoolStates.CLOSED) {
|
if (this.state === ValidationPoolStates.CLOSED) {
|
||||||
throw new Error(`Validation pool ${this.id} is closed`);
|
throw new Error(`Validation pool ${this.id} is closed`);
|
||||||
}
|
}
|
||||||
|
@ -99,23 +93,17 @@ export class ValidationPool extends Actor {
|
||||||
`Validation pool ${this.id} has expired, no new votes may be cast`,
|
`Validation pool ${this.id} has expired, no new votes may be cast`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.votes.set(signingPublicKey, vote);
|
const stake = new Stake(position, amount, lockingTime);
|
||||||
|
this.stakes.set(signingPublicKey, stake);
|
||||||
|
console.log('new stake', stake);
|
||||||
if (!anonymous) {
|
if (!anonymous) {
|
||||||
await this.revealIdentity(signingPublicKey, signingPublicKey);
|
await this.revealIdentity(signingPublicKey, signingPublicKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listVotes(filter) {
|
|
||||||
return new Map(
|
|
||||||
Array.from(this.votes).filter(
|
|
||||||
([_, vote]) => filter(vote),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async revealIdentity(signingPublicKey, reputationPublicKey) {
|
async revealIdentity(signingPublicKey, reputationPublicKey) {
|
||||||
if (!this.votes.get(signingPublicKey)) {
|
if (!this.stakes.get(signingPublicKey)) {
|
||||||
throw new Error('Must vote before revealing identity');
|
throw new Error('Must stake before revealing identity');
|
||||||
}
|
}
|
||||||
const voter = this.bench.voters.get(reputationPublicKey)
|
const voter = this.bench.voters.get(reputationPublicKey)
|
||||||
?? new Voter(reputationPublicKey);
|
?? new Voter(reputationPublicKey);
|
||||||
|
@ -153,7 +141,7 @@ export class ValidationPool extends Actor {
|
||||||
for (const [
|
for (const [
|
||||||
signingPublicKey,
|
signingPublicKey,
|
||||||
{ stake, lockingTime },
|
{ stake, lockingTime },
|
||||||
] of this.votes) {
|
] of this.stakes) {
|
||||||
const voter = this.voters.get(signingPublicKey);
|
const voter = this.voters.get(signingPublicKey);
|
||||||
this.bench.reputations.lockTokens(
|
this.bench.reputations.lockTokens(
|
||||||
voter.reputationPublicKey,
|
voter.reputationPublicKey,
|
||||||
|
@ -164,6 +152,42 @@ export class ValidationPool extends Actor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} outcome: null --> all entries. Otherwise filters to position === outcome.
|
||||||
|
* @param {object} getStakeEntries options
|
||||||
|
* @param {boolean} options.excludeSystem: Whether to exclude votes cast during pool initialization
|
||||||
|
* @returns [signingPublicKey, stake][]
|
||||||
|
*/
|
||||||
|
getStakeEntries(outcome, options = {}) {
|
||||||
|
const { excludeSystem = false } = options;
|
||||||
|
const entries = Array.from(this.stakes.entries());
|
||||||
|
// console.log('entries', entries);
|
||||||
|
return entries
|
||||||
|
.filter(([signingPublicKey, __]) => !excludeSystem || signingPublicKey !== this.id)
|
||||||
|
.filter(([__, { position }]) => outcome === null || position === outcome);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} outcome: null --> all entries. Otherwise filters to position === outcome.
|
||||||
|
* @param {object} getStakeEntries options
|
||||||
|
* @returns number
|
||||||
|
*/
|
||||||
|
getTotalStakedOnPost(outcome, options) {
|
||||||
|
return this.getStakeEntries(outcome, options)
|
||||||
|
.map(([__, stake]) => stake.getStakeValue())
|
||||||
|
.reduce((acc, cur) => (acc += cur), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} outcome: null --> all entries. Otherwise filters to position === outcome.
|
||||||
|
* @param {object} getStakeEntries options
|
||||||
|
* @returns number
|
||||||
|
*/
|
||||||
|
getTotalValueOfStakesForOutcome(outcome, options) {
|
||||||
|
return this.getStakeEntries(outcome, options)
|
||||||
|
.reduce((total, [__, { amount }]) => (total += amount), 0);
|
||||||
|
}
|
||||||
|
|
||||||
async evaluateWinningConditions() {
|
async evaluateWinningConditions() {
|
||||||
if (this.state === ValidationPoolStates.RESOLVED) {
|
if (this.state === ValidationPoolStates.RESOLVED) {
|
||||||
throw new Error('Validation pool has already been resolved!');
|
throw new Error('Validation pool has already been resolved!');
|
||||||
|
@ -172,22 +196,15 @@ export class ValidationPool extends Actor {
|
||||||
if (elapsed < this.duration) {
|
if (elapsed < this.duration) {
|
||||||
throw new Error(`Validation pool duration has not yet elapsed! ${this.duration - elapsed} ms remaining.`);
|
throw new Error(`Validation pool duration has not yet elapsed! ${this.duration - elapsed} ms remaining.`);
|
||||||
}
|
}
|
||||||
if (this.voters.size < this.votes.size) {
|
if (this.voters.size < this.stakes.size) {
|
||||||
throw new Error('Not all voters have revealed their reputation public keys!');
|
throw new Error('Not all voters have revealed their reputation public keys!');
|
||||||
}
|
}
|
||||||
// Now we can evaluate winning conditions
|
// Now we can evaluate winning conditions
|
||||||
this.state = ValidationPoolStates.CLOSED;
|
this.state = ValidationPoolStates.CLOSED;
|
||||||
this.setStatus('Closed');
|
this.setStatus('Closed');
|
||||||
|
|
||||||
const getVoteValue = ({ stake, lockingTime }) => stake * lockingTime ** params.lockingTimeExponent;
|
const upvoteValue = this.getTotalValueOfStakesForOutcome(true);
|
||||||
const getTotalValue = (votePosition) => Array.from(this.listVotes(
|
const downvoteValue = this.getTotalValueOfStakesForOutcome(false);
|
||||||
({ position }) => position === votePosition,
|
|
||||||
).values())
|
|
||||||
.map(getVoteValue)
|
|
||||||
.reduce((acc, cur) => (acc += cur), 0);
|
|
||||||
|
|
||||||
const upvoteValue = getTotalValue(true);
|
|
||||||
const downvoteValue = getTotalValue(false);
|
|
||||||
const activeAvailableReputation = this.bench.getTotalActiveAvailableReputation();
|
const activeAvailableReputation = this.bench.getTotalActiveAvailableReputation();
|
||||||
const votePasses = upvoteValue >= params.winningRatio * downvoteValue;
|
const votePasses = upvoteValue >= params.winningRatio * downvoteValue;
|
||||||
const quorumMet = upvoteValue + downvoteValue >= params.quorum * activeAvailableReputation;
|
const quorumMet = upvoteValue + downvoteValue >= params.quorum * activeAvailableReputation;
|
||||||
|
@ -202,7 +219,7 @@ export class ValidationPool extends Actor {
|
||||||
this.setStatus(`Resolved - ${votePasses ? 'Won' : 'Lost'}`);
|
this.setStatus(`Resolved - ${votePasses ? 'Won' : 'Lost'}`);
|
||||||
this.scene.sequence.log(`note over ${this.name} : ${votePasses ? 'Win' : 'Lose'}`);
|
this.scene.sequence.log(`note over ${this.name} : ${votePasses ? 'Win' : 'Lose'}`);
|
||||||
this.applyTokenLocking();
|
this.applyTokenLocking();
|
||||||
await this.distributeReputation(result);
|
await this.distributeReputation({ votePasses });
|
||||||
// TODO: distribute fees
|
// TODO: distribute fees
|
||||||
} else {
|
} else {
|
||||||
this.setStatus('Resolved - Quorum not met');
|
this.setStatus('Resolved - Quorum not met');
|
||||||
|
@ -215,38 +232,40 @@ export class ValidationPool extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
async distributeReputation({ votePasses }) {
|
async distributeReputation({ votePasses }) {
|
||||||
|
// For now we assume a tightly binding pool, where all staked reputation is lost
|
||||||
// TODO: Take tokenLossRatio into account
|
// TODO: Take tokenLossRatio into account
|
||||||
const getTotalStaked = (votePosition, excludeSystem = false) => Array.from(this.listVotes(
|
// TODO: revoke staked reputation from losing voters
|
||||||
({ position, isSystemVote }) => position === votePosition && (!excludeSystem || !isSystemVote),
|
|
||||||
).values())
|
|
||||||
.map(({ stake }) => stake)
|
|
||||||
.reduce((acc, cur) => (acc += cur), 0);
|
|
||||||
const tokensForWinners = getTotalStaked(!votePasses);
|
|
||||||
const winningVotes = this.listVotes(({ position, isSystemVote }) => position === votePasses && !isSystemVote);
|
|
||||||
|
|
||||||
// Compute rewards for the winning voters, in proportion to their stakes
|
// In a tightly binding validation pool, losing voter stakes are transferred to winning voters.
|
||||||
|
const tokensForWinners = this.getTotalStakedOnPost(!votePasses);
|
||||||
|
const winningVotes = this.getStakeEntries(votePasses, { excludeSystem: true });
|
||||||
|
const totalValueOfStakesForWin = this.getTotalValueOfStakesForOutcome(votePasses);
|
||||||
|
|
||||||
|
// Compute rewards for the winning voters, in proportion to the value of their stakes.
|
||||||
const rewards = new Map();
|
const rewards = new Map();
|
||||||
for (const [signingPublicKey, { stake }] of winningVotes) {
|
for (const [signingPublicKey, stake] of winningVotes) {
|
||||||
const { reputationPublicKey } = this.voters.get(signingPublicKey);
|
const { reputationPublicKey } = this.voters.get(signingPublicKey);
|
||||||
const reward = (tokensForWinners * stake) / getTotalStaked(votePasses);
|
const value = stake.getStakeValue();
|
||||||
|
const reward = tokensForWinners * (value / totalValueOfStakesForWin);
|
||||||
rewards.set(reputationPublicKey, reward);
|
rewards.set(reputationPublicKey, reward);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('rewards for stakes', rewards);
|
||||||
|
|
||||||
const authorReputationPublicKey = this.voters.get(this.authorSigningPublicKey).reputationPublicKey;
|
const authorReputationPublicKey = this.voters.get(this.authorSigningPublicKey).reputationPublicKey;
|
||||||
|
|
||||||
// Distribute awards to voters other than the author
|
// Distribute awards to voters other than the author
|
||||||
for (const [id, value] of rewards) {
|
for (const [reputationPublicKey, amount] of rewards) {
|
||||||
if (id !== authorReputationPublicKey) {
|
if (reputationPublicKey !== authorReputationPublicKey) {
|
||||||
this.bench.reputations.addTokens(id, value);
|
this.bench.reputations.addTokens(reputationPublicKey, amount);
|
||||||
console.log(`reward for winning voter ${id}:`, value);
|
console.log(`reward for stake by ${reputationPublicKey}:`, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: revoke staked reputation from losing voters
|
|
||||||
|
|
||||||
if (votePasses) {
|
if (votePasses) {
|
||||||
// Distribute awards to author via the forum
|
// Distribute awards to author via the forum
|
||||||
const tokensForAuthor = this.tokensMinted * params.stakeForAuthor + rewards.get(authorReputationPublicKey);
|
const tokensForAuthor = this.tokensMinted * params.stakeForAuthor + rewards.get(authorReputationPublicKey);
|
||||||
|
console.log('sending reward for author stake to forum', { tokensForAuthor });
|
||||||
|
|
||||||
if (votePasses && !!this.forum) {
|
if (votePasses && !!this.forum) {
|
||||||
// Recurse through forum to determine reputation effects
|
// Recurse through forum to determine reputation effects
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
export class Vote {
|
|
||||||
constructor(position, stake, lockingTime, isSystemVote = false) {
|
|
||||||
this.position = position;
|
|
||||||
this.stake = stake;
|
|
||||||
this.lockingTime = lockingTime;
|
|
||||||
this.isSystemVote = isSystemVote;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,10 +5,10 @@ export class Voter {
|
||||||
this.dateLastVote = null;
|
this.dateLastVote = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
addVoteRecord(vote) {
|
addVoteRecord(stake) {
|
||||||
this.voteHistory.push(vote);
|
this.voteHistory.push(stake);
|
||||||
if (!this.dateLastVote || vote.dateStart > this.dateLastVote) {
|
if (!this.dateLastVote || stake.dateStart > this.dateLastVote) {
|
||||||
this.dateLastVote = vote.dateStart;
|
this.dateLastVote = stake.dateStart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,9 +87,9 @@
|
||||||
const voteForWorkEvidence = async (worker, pool) => {
|
const voteForWorkEvidence = async (worker, pool) => {
|
||||||
for (const expert of experts) {
|
for (const expert of experts) {
|
||||||
if (expert !== worker) {
|
if (expert !== worker) {
|
||||||
await expert.castVote(pool, {
|
await expert.stake(pool, {
|
||||||
position: true,
|
position: true,
|
||||||
stake: 1,
|
amount: 1,
|
||||||
anonymous: false,
|
anonymous: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@
|
||||||
worker.deactivate();
|
worker.deactivate();
|
||||||
await updateDisplayValuesAndDelay();
|
await updateDisplayValuesAndDelay();
|
||||||
|
|
||||||
// Vote on work evidence
|
// Stake on work evidence
|
||||||
await voteForWorkEvidence(worker, pool);
|
await voteForWorkEvidence(worker, pool);
|
||||||
await updateDisplayValuesAndDelay();
|
await updateDisplayValuesAndDelay();
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
);
|
);
|
||||||
await updateDisplayValuesAndDelay(1000);
|
await updateDisplayValuesAndDelay(1000);
|
||||||
|
|
||||||
// await expert2.castVote(pool1, { position: true, stake: 1, anonymous: false });
|
// await expert2.stake(pool1, { position: true, amount 1, anonymous: false });
|
||||||
// await updateDisplayValuesAndDelay();
|
// await updateDisplayValuesAndDelay();
|
||||||
|
|
||||||
await pool1.evaluateWinningConditions();
|
await pool1.evaluateWinningConditions();
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
);
|
);
|
||||||
await updateDisplayValuesAndDelay(1000);
|
await updateDisplayValuesAndDelay(1000);
|
||||||
|
|
||||||
// await expert1.castVote(pool2, { position: true, stake: 1, anonymous: false });
|
// await expert1.stake(pool2, { position: true, amount 1, anonymous: false });
|
||||||
// await updateDisplayValuesAndDelay();
|
// await updateDisplayValuesAndDelay();
|
||||||
|
|
||||||
await pool2.evaluateWinningConditions();
|
await pool2.evaluateWinningConditions();
|
||||||
|
@ -131,7 +131,7 @@
|
||||||
);
|
);
|
||||||
await updateDisplayValuesAndDelay(1000);
|
await updateDisplayValuesAndDelay(1000);
|
||||||
|
|
||||||
// await expert1.castVote(pool3, { position: true, stake: 1, anonymous: false });
|
// await expert1.stake(pool3, { position: true, amount 1, anonymous: false });
|
||||||
// await updateDisplayValuesAndDelay();
|
// await updateDisplayValuesAndDelay();
|
||||||
|
|
||||||
await pool3.evaluateWinningConditions();
|
await pool3.evaluateWinningConditions();
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
await pool.evaluateWinningConditions(); // Vote passes
|
await pool.evaluateWinningConditions(); // Stake passes
|
||||||
await updateDisplayValues();
|
await updateDisplayValues();
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
}
|
}
|
||||||
|
@ -105,12 +105,18 @@
|
||||||
fee: 1,
|
fee: 1,
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
tokenLossRatio: 1,
|
tokenLossRatio: 1,
|
||||||
|
anonymous: true,
|
||||||
|
});
|
||||||
|
await expert1.stake(pool, {
|
||||||
|
position: true,
|
||||||
|
amount: 4,
|
||||||
|
lockingTime: 0,
|
||||||
|
anonymous: true,
|
||||||
});
|
});
|
||||||
await expert1.castVote(pool, { position: true, stake: 4, lockingTime: 0 });
|
|
||||||
await expert1.revealIdentity(pool);
|
await expert1.revealIdentity(pool);
|
||||||
await expert2.revealIdentity(pool);
|
await expert2.revealIdentity(pool);
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
await pool.evaluateWinningConditions(); // Vote passes
|
await pool.evaluateWinningConditions(); // Stake passes
|
||||||
await updateDisplayValues();
|
await updateDisplayValues();
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue