Cleanup isPassing (#2147)

This commit is contained in:
Jaco Greeff
2020-04-09 09:19:56 +02:00
committed by GitHub
parent 041d06a6c8
commit c4708dcfca
3 changed files with 2 additions and 119 deletions
@@ -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);
});
});
+2 -78
View File
@@ -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
};
}