Cleanup isPassing (#2147)
This commit is contained in:
@@ -61,8 +61,6 @@ export interface DeriveReferendumVoteState {
|
||||
}
|
||||
|
||||
export interface DeriveReferendumVotes extends DeriveReferendumVoteState {
|
||||
changeAye: BN;
|
||||
changeNay: BN;
|
||||
isPassing: boolean;
|
||||
votes: DeriveReferendumVote[];
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { TypeRegistry } from '@polkadot/types';
|
||||
|
||||
import { approxChanges, calcPassing } from './util';
|
||||
|
||||
const ACTUAL = {
|
||||
sqrtElectorate: new BN('2949443240'),
|
||||
votedAye: new BN('358406690000000000'),
|
||||
votedNay: new BN('18942000000000000'),
|
||||
votedTotal: new BN('136099900000000000')
|
||||
};
|
||||
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('approxChanges', (): void => {
|
||||
it('approximates where the points are', (): void => {
|
||||
const threshold = registry.createType('VoteThreshold', 0);
|
||||
|
||||
console.time('approxChanges');
|
||||
|
||||
const { changeAye, changeNay, isPassing } = approxChanges(threshold, ACTUAL.sqrtElectorate, ACTUAL);
|
||||
|
||||
console.timeEnd('approxChanges');
|
||||
|
||||
console.error(isPassing, changeAye.toString().padStart(20).substr(0, 8), changeNay.toString().padStart(20).substr(0, 8));
|
||||
|
||||
expect(isPassing).toBe(true);
|
||||
expect(
|
||||
calcPassing(threshold, ACTUAL.sqrtElectorate, ACTUAL.votedAye.sub(changeAye), ACTUAL.votedNay, ACTUAL.votedTotal.sub(changeAye))
|
||||
).toBe(false);
|
||||
expect(
|
||||
calcPassing(threshold, ACTUAL.sqrtElectorate, ACTUAL.votedAye, ACTUAL.votedNay.add(changeNay), ACTUAL.votedTotal.add(changeNay))
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -14,12 +14,6 @@ import { bnSqrt } from '@polkadot/util';
|
||||
type PreimageInfo = [Bytes, AccountId, Balance, BlockNumber];
|
||||
type OldPreimage = ITuple<PreimageInfo>;
|
||||
|
||||
interface Approx {
|
||||
changeAye: BN;
|
||||
changeNay: BN;
|
||||
isPassing: boolean;
|
||||
}
|
||||
|
||||
interface ApproxState {
|
||||
votedAye: BN;
|
||||
votedNay: BN;
|
||||
@@ -65,7 +59,7 @@ export function compareRationals (n1: BN, d1: BN, n2: BN, d2: BN): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
export function calcPassing (threshold: VoteThreshold, sqrtElectorate: BN, votedAye: BN, votedNay: BN, votedTotal: BN): boolean {
|
||||
export function calcPassing (threshold: VoteThreshold, sqrtElectorate: BN, { votedAye, votedNay, votedTotal }: ApproxState): boolean {
|
||||
const sqrtVoters = bnSqrt(votedTotal);
|
||||
|
||||
return sqrtVoters.isZero()
|
||||
@@ -77,76 +71,6 @@ export function calcPassing (threshold: VoteThreshold, sqrtElectorate: BN, voted
|
||||
: compareRationals(votedNay, sqrtElectorate, votedAye, sqrtVoters);
|
||||
}
|
||||
|
||||
function calcChangeAye (threshold: VoteThreshold, sqrtElectorate: BN, { votedAye, votedNay, votedTotal }: ApproxState, isPassing: boolean, changeAye: BN, inc: BN, isFinal: boolean): BN {
|
||||
while (true) {
|
||||
const newChangeAye = changeAye.add(inc);
|
||||
const diff = new BN(isPassing ? -1 : 1).mul(newChangeAye);
|
||||
|
||||
if (isPassing !== calcPassing(threshold, sqrtElectorate, votedAye.add(diff), votedNay, votedTotal.add(diff))) {
|
||||
return isFinal
|
||||
? newChangeAye
|
||||
: changeAye;
|
||||
}
|
||||
|
||||
changeAye = newChangeAye;
|
||||
}
|
||||
}
|
||||
|
||||
function calcChangeNay (threshold: VoteThreshold, sqrtElectorate: BN, { votedAye, votedNay, votedTotal }: ApproxState, isPassing: boolean, changeNay: BN, inc: BN, isFinal: boolean): BN {
|
||||
while (true) {
|
||||
const newChangeNay = changeNay.add(inc);
|
||||
const diff = new BN(isPassing ? 1 : -1).mul(newChangeNay);
|
||||
|
||||
if (isPassing !== calcPassing(threshold, sqrtElectorate, votedAye, votedNay.add(diff), votedTotal.add(diff))) {
|
||||
return isFinal
|
||||
? newChangeNay
|
||||
: changeNay;
|
||||
}
|
||||
|
||||
changeNay = newChangeNay;
|
||||
}
|
||||
}
|
||||
|
||||
export function approxChanges (threshold: VoteThreshold, sqrtElectorate: BN, state: ApproxState): Approx {
|
||||
const isPassing = calcPassing(threshold, sqrtElectorate, state.votedAye, state.votedNay, state.votedTotal);
|
||||
|
||||
if (threshold.isSimplemajority) {
|
||||
const change = isPassing
|
||||
? state.votedAye.sub(state.votedNay)
|
||||
: state.votedNay.sub(state.votedAye);
|
||||
|
||||
return {
|
||||
changeAye: change,
|
||||
changeNay: change,
|
||||
isPassing
|
||||
};
|
||||
}
|
||||
|
||||
let inc = state.votedTotal.divn(2);
|
||||
let changeAye = new BN(0);
|
||||
let changeNay = new BN(0);
|
||||
|
||||
while (!inc.isZero()) {
|
||||
const nextInc = inc.divn(2);
|
||||
const isFinal = nextInc.isZero();
|
||||
|
||||
changeAye = calcChangeAye(threshold, sqrtElectorate, state, isPassing, changeAye, inc, isFinal);
|
||||
changeNay = calcChangeNay(threshold, sqrtElectorate, state, isPassing, changeNay, inc, isFinal);
|
||||
|
||||
inc = nextInc;
|
||||
}
|
||||
|
||||
return {
|
||||
changeAye: isPassing
|
||||
? BN.min(changeAye, state.votedAye)
|
||||
: changeAye,
|
||||
changeNay: isPassing
|
||||
? changeNay
|
||||
: BN.min(changeNay, state.votedNay),
|
||||
isPassing
|
||||
};
|
||||
}
|
||||
|
||||
function calcVotesPrev (votesFor: DeriveReferendumVote[]): DeriveReferendumVoteState {
|
||||
return votesFor.reduce((state: DeriveReferendumVoteState, derived): DeriveReferendumVoteState => {
|
||||
const { balance, vote } = derived;
|
||||
@@ -212,7 +136,7 @@ export function calcVotes (sqrtElectorate: BN, referendum: DeriveReferendum, vot
|
||||
|
||||
return {
|
||||
...state,
|
||||
...approxChanges(referendum.status.threshold, sqrtElectorate, state),
|
||||
isPassing: calcPassing(referendum.status.threshold, sqrtElectorate, state),
|
||||
votes
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user