Vote decoding tweaks (#1270)
This commit is contained in:
@@ -7,104 +7,115 @@ import '../../injector';
|
||||
import Vote from './Vote';
|
||||
|
||||
describe('Vote', (): void => {
|
||||
it('constructs via boolean true', (): void => {
|
||||
expect(new Vote(true).toU8a()).toEqual(new Uint8Array([128]));
|
||||
expect(new Vote(true).isAye).toBe(true);
|
||||
expect(new Vote(true).isNay).toBe(false);
|
||||
describe('construction', (): void => {
|
||||
it('constructs via boolean true', (): void => {
|
||||
expect(new Vote(true).toU8a()).toEqual(new Uint8Array([128]));
|
||||
expect(new Vote(true).isAye).toBe(true);
|
||||
expect(new Vote(true).isNay).toBe(false);
|
||||
});
|
||||
|
||||
it('constructs via boolean false', (): void => {
|
||||
expect(new Vote(false).toU8a()).toEqual(new Uint8Array([0]));
|
||||
expect(new Vote(false).isNay).toBe(true);
|
||||
expect(new Vote(false).isAye).toBe(false);
|
||||
});
|
||||
|
||||
it('has isYay for positive', (): void => {
|
||||
// eslint-disable-next-line no-new-wrappers
|
||||
expect(new Vote(true).isAye).toBe(true);
|
||||
});
|
||||
|
||||
it('has isNay for negative', (): void => {
|
||||
// eslint-disable-next-line no-new-wrappers
|
||||
expect(new Vote(false).isNay).toBe(true);
|
||||
});
|
||||
|
||||
it('is Aye for negative numbers', (): void => {
|
||||
expect(new Vote(-128).isAye).toBe(true);
|
||||
});
|
||||
|
||||
it('is Nay for positive numbers', (): void => {
|
||||
expect(new Vote(127).isNay).toBe(true);
|
||||
});
|
||||
|
||||
it('is Nay for 0', (): void => {
|
||||
expect(new Vote(0).isNay).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('constructs via boolean false', (): void => {
|
||||
expect(new Vote(false).toU8a()).toEqual(new Uint8Array([0]));
|
||||
expect(new Vote(false).isNay).toBe(true);
|
||||
expect(new Vote(false).isAye).toBe(false);
|
||||
describe('Vote with conviction', (): void => {
|
||||
it('constructs Vote with raw boolean', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'Locked1x'
|
||||
}).toU8a()
|
||||
).toEqual(new Uint8Array([0b10000001]));
|
||||
});
|
||||
|
||||
it('constructs with Vote aye is false, conviction is None', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: false,
|
||||
conviction: 'None'
|
||||
}).toU8a()
|
||||
).toEqual(new Uint8Array([0b00000000]));
|
||||
});
|
||||
|
||||
it('constructs with Vote aye is true, conviction is Locked4x', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'Locked4x'
|
||||
}).toU8a()
|
||||
).toEqual(new Uint8Array([0b10000100]));
|
||||
});
|
||||
});
|
||||
|
||||
it('has isYay for positive', (): void => {
|
||||
// eslint-disable-next-line no-new-wrappers
|
||||
expect(new Vote(true).isAye).toBe(true);
|
||||
});
|
||||
describe('getters', (): void => {
|
||||
it('Conviction getter works', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'Locked2x'
|
||||
}).conviction.toString()
|
||||
).toEqual('Locked2x');
|
||||
});
|
||||
|
||||
it('has isNay for negative', (): void => {
|
||||
// eslint-disable-next-line no-new-wrappers
|
||||
expect(new Vote(false).isNay).toBe(true);
|
||||
});
|
||||
it('Conviction getter works with raw boolean and string conviction', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'Locked2x'
|
||||
}).conviction.toString()
|
||||
).toEqual('Locked2x');
|
||||
});
|
||||
|
||||
it('is Aye for negative numbers', (): void => {
|
||||
expect(new Vote(-128).isAye).toBe(true);
|
||||
});
|
||||
it('Conviction getter works with raw boolean and conviction index', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 2
|
||||
}).conviction.toString()
|
||||
).toEqual('Locked2x');
|
||||
});
|
||||
|
||||
it('is Nay for positive numbers', (): void => {
|
||||
expect(new Vote(127).isNay).toBe(true);
|
||||
});
|
||||
it('isAye getter works', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'None'
|
||||
}).isAye)
|
||||
.toEqual(true);
|
||||
});
|
||||
|
||||
it('constructs V2 Vote with raw boolean', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'Locked1x'
|
||||
}).toU8a()
|
||||
).toEqual(new Uint8Array([0b10000001]));
|
||||
});
|
||||
|
||||
it('constructs with V2 Vote aye is false, conviction is None', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: false,
|
||||
conviction: 'None'
|
||||
}).toU8a()
|
||||
).toEqual(new Uint8Array([0b00000000]));
|
||||
});
|
||||
|
||||
it('constructs with Vote aye is true, conviction is Locked4x', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'Locked4x'
|
||||
}).toU8a()
|
||||
).toEqual(new Uint8Array([0b10000100]));
|
||||
});
|
||||
|
||||
it('Conviction getter works', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'Locked2x'
|
||||
}).conviction.toString()
|
||||
).toEqual('Locked2x');
|
||||
});
|
||||
|
||||
it('Conviction getter works with raw boolean and string conviction', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'Locked2x'
|
||||
}).conviction.toString()
|
||||
).toEqual('Locked2x');
|
||||
});
|
||||
it('Conviction getter works with raw boolean and conviction index', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 2
|
||||
}).conviction.toString()
|
||||
).toEqual('Locked2x');
|
||||
});
|
||||
|
||||
it('isAye getter works', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'None'
|
||||
}).isAye)
|
||||
.toEqual(true);
|
||||
});
|
||||
|
||||
it('isNay getter works', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'None'
|
||||
}).isNay)
|
||||
.toEqual(false);
|
||||
it('isNay getter works', (): void => {
|
||||
expect(
|
||||
new Vote({
|
||||
aye: true,
|
||||
conviction: 'None'
|
||||
}).isNay)
|
||||
.toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,18 +7,24 @@ import { Conviction } from '../../interfaces/democracy';
|
||||
import { isBoolean, isNumber, isObject, isU8a, isUndefined } from '@polkadot/util';
|
||||
|
||||
import createType from '../../codec/createType';
|
||||
import U8a from '../../codec/U8a';
|
||||
import U8aFixed from '../../codec/U8aFixed';
|
||||
import Bool from '../Bool';
|
||||
|
||||
// For votes, the topmost bit indicated aye/nay, the lower bits indicate the conviction
|
||||
const AYE_BITS = 0b10000000;
|
||||
const NAY_BITS = 0b00000000;
|
||||
const CON_MASK = 0b01111111;
|
||||
const DEF_CONV = 0b00000000; // the default conviction, None
|
||||
|
||||
/**
|
||||
* @name Vote
|
||||
* @description
|
||||
* A number of lock periods, plus a vote, one way or the other.
|
||||
*/
|
||||
export default class Vote extends U8a {
|
||||
private _aye: Bool;
|
||||
export default class Vote extends U8aFixed {
|
||||
private _aye: boolean;
|
||||
|
||||
private _conviction: Conviction; // for V1, default to None
|
||||
private _conviction: Conviction;
|
||||
|
||||
public constructor (value?: any) {
|
||||
// decoded is just 1 byte
|
||||
@@ -26,39 +32,34 @@ export default class Vote extends U8a {
|
||||
// Conviction: 0000 - 0101
|
||||
const decoded = Vote.decodeVote(value);
|
||||
|
||||
super(decoded);
|
||||
super(decoded, 8);
|
||||
|
||||
const msb = decoded[0] >> 7;
|
||||
const conviction = decoded[0] & 0b01111111;
|
||||
|
||||
this._aye = new Bool(msb);
|
||||
this._conviction = createType('Conviction', conviction);
|
||||
this._aye = (decoded[0] & AYE_BITS) === AYE_BITS;
|
||||
this._conviction = createType('Conviction', decoded[0] & CON_MASK);
|
||||
}
|
||||
|
||||
private static decodeVote (value?: any): Uint8Array {
|
||||
if (isUndefined(value)) {
|
||||
return new Uint8Array([0]);
|
||||
return new Uint8Array([NAY_BITS]);
|
||||
} else if (isBoolean(value)) {
|
||||
return value
|
||||
? new Uint8Array([0b10000000])
|
||||
: new Uint8Array([0b0]);
|
||||
} else if (value instanceof Bool) {
|
||||
? new Uint8Array([AYE_BITS | DEF_CONV])
|
||||
: new Uint8Array([NAY_BITS]);
|
||||
} else if (value instanceof Boolean) {
|
||||
return Vote.decodeVote(value.valueOf());
|
||||
} else if (isNumber(value)) {
|
||||
return value < 0
|
||||
? new Uint8Array([0b10000000])
|
||||
: new Uint8Array([0b0]);
|
||||
} else if (isObject(value) && !isUndefined(value.aye) && !isUndefined(value.conviction)) {
|
||||
const aye = new Bool(value.aye);
|
||||
const convictionIndex = createType('Conviction', value.conviction).index;
|
||||
|
||||
const result = convictionIndex | (aye.eq(true) ? 0b1 << 7 : 0b0);
|
||||
|
||||
return new Uint8Array([result]);
|
||||
? new Uint8Array([AYE_BITS | DEF_CONV])
|
||||
: new Uint8Array([NAY_BITS]);
|
||||
} else if (isU8a(value)) {
|
||||
return value.length
|
||||
? value
|
||||
: new Uint8Array([0]);
|
||||
? value.subarray(0, 1)
|
||||
: new Uint8Array([NAY_BITS]);
|
||||
} else if (isObject(value)) {
|
||||
const vote = new Bool(value.aye).eq(true) ? AYE_BITS : NAY_BITS;
|
||||
const conviction = createType('Conviction', isUndefined(value.conviction) ? DEF_CONV : value.conviction);
|
||||
|
||||
return new Uint8Array([vote | conviction.index]);
|
||||
}
|
||||
|
||||
throw new Error(`Unable to convert input ${value} to Vote`);
|
||||
@@ -75,7 +76,7 @@ export default class Vote extends U8a {
|
||||
* @description true if the wrapped value is a positive vote
|
||||
*/
|
||||
public get isAye (): boolean {
|
||||
return this._aye.eq(true);
|
||||
return this._aye;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,4 +85,11 @@ export default class Vote extends U8a {
|
||||
public get isNay (): boolean {
|
||||
return !this.isAye;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the base runtime type name for this instance
|
||||
*/
|
||||
public toRawType (): string {
|
||||
return 'Vote';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user