u8aSorted & sortAddresses (#588)

This commit is contained in:
Jaco Greeff
2020-04-24 19:15:43 +02:00
committed by GitHub
parent a2844a449c
commit 62ebe257a6
9 changed files with 94 additions and 44 deletions
+2
View File
@@ -1,6 +1,8 @@
# 2.9.0-beta.x
- Added `createKeyMulti` & `createKeySub` to create utility sub & multi keys
- Added `u8aSorted` to sort `Uint8Arrays`
- Added `sortAddresses` to sort addresses based on their internal representation
# 2.8.1 Apr 9, 2020
+3 -1
View File
@@ -9,6 +9,7 @@ import createKeySub from './keySub';
import decodeAddress from './decode';
import encodeAddress from './encode';
import setSS58Format from './setSS58Format';
import sortAddresses from './sort';
export {
checkAddress,
@@ -17,5 +18,6 @@ export {
createKeySub,
decodeAddress,
encodeAddress,
setSS58Format
setSS58Format,
sortAddresses
};
@@ -2,21 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import createKeyMulti, { sortU8a } from './keyMulti';
describe('sortU8a', (): void => {
it('sorts a simple set of u8a', (): void => {
expect(
sortU8a([new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]), new Uint8Array([2, 3, 4])])
).toEqual([new Uint8Array([1, 2, 3]), new Uint8Array([2, 3, 4]), new Uint8Array([4, 5, 6])]);
});
it('sorts a simple set of u8a (not the same lengths)', (): void => {
expect(
sortU8a([new Uint8Array([1, 2, 3, 4]), new Uint8Array([4, 5, 6]), new Uint8Array([1, 2, 3, 5])])
).toEqual([new Uint8Array([1, 2, 3, 4]), new Uint8Array([1, 2, 3, 5]), new Uint8Array([4, 5, 6])]);
});
});
import { createKeyMulti } from '.';
describe('createKeyMulti', (): void => {
it('creates a valid multikey (aligning with Rust, needs sorting)', (): void => {
+4 -28
View File
@@ -3,42 +3,18 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import BN from 'bn.js';
import { bnToU8a, compactToU8a, isUndefined, u8aConcat } from '@polkadot/util';
import { bnToU8a, compactToU8a, u8aConcat, u8aSorted } from '@polkadot/util';
import blake2AsU8a from '../blake2/asU8a';
import decodeAddress from './decode';
export function sortU8a (u8as: Uint8Array[]): Uint8Array[] {
return u8as.sort((a, b): number => {
let i = 0;
while (true) {
if (isUndefined(a[i]) && isUndefined(b[i])) {
return 0;
} else if (isUndefined(a[i])) {
return -1;
} else if (isUndefined(b[i])) {
return 1;
}
const cmp = a[i] - b[i];
if (cmp !== 0) {
return cmp;
}
i++;
}
});
}
export default function createKeyMulti (who: (Uint8Array | string)[], index: BigInt | BN | number): Uint8Array {
export default function createKeyMulti (who: (Uint8Array | string)[], threshold: BigInt | BN | number): Uint8Array {
return blake2AsU8a(
u8aConcat(
'modlpy/utilisuba',
compactToU8a(who.length),
...sortU8a(who.map((who) => decodeAddress(who))),
bnToU8a(index, { bitLength: 16, isLe: true })
...u8aSorted(who.map((who) => decodeAddress(who))),
bnToU8a(threshold, { bitLength: 16, isLe: true })
)
);
}
@@ -0,0 +1,21 @@
// Copyright 2017-2020 @polkadot/util-crypto 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 { sortAddresses } from '.';
describe('sortAddresses', (): void => {
it('sorts addresses by the publicKeys', (): void => {
expect(
sortAddresses([
'5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
'5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty',
'5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y'
])
).toEqual([
'5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty',
'5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y',
'5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'
]);
});
});
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2017-2020 @polkadot/util 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 { u8aSorted } from '@polkadot/util';
import decodeAddress from './decode';
import encodeAddress from './encode';
export default function sortAddresses (addresses: (Uint8Array | string)[]): string[] {
return u8aSorted(
addresses.map((who) => decodeAddress(who))
).map((u8a) => encodeAddress(u8a));
}
+1
View File
@@ -8,6 +8,7 @@
export { default as u8aConcat } from './concat';
export { default as u8aFixLength } from './fixLength';
export { default as u8aSorted } from './sorted';
export { default as u8aToBn } from './toBn';
export { default as u8aToBuffer } from './toBuffer';
export { default as u8aToHex } from './toHex';
+19
View File
@@ -0,0 +1,19 @@
// Copyright 2017-2020 @polkadot/util 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 { u8aSorted } from '.';
describe('u8aSorted', (): void => {
it('sorts a simple set of u8a', (): void => {
expect(
u8aSorted([new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]), new Uint8Array([2, 3, 4])])
).toEqual([new Uint8Array([1, 2, 3]), new Uint8Array([2, 3, 4]), new Uint8Array([4, 5, 6])]);
});
it('sorts a simple set of u8a (not the same lengths)', (): void => {
expect(
u8aSorted([new Uint8Array([1, 2, 3, 4]), new Uint8Array([4, 5, 6]), new Uint8Array([1, 2, 3, 5])])
).toEqual([new Uint8Array([1, 2, 3, 4]), new Uint8Array([1, 2, 3, 5]), new Uint8Array([4, 5, 6])]);
});
});
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2017-2020 @polkadot/util 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 isUndefined from '../is/undefined';
export default function u8aSorted (u8as: Uint8Array[]): Uint8Array[] {
return u8as.sort((a, b): number => {
let i = 0;
while (true) {
if (isUndefined(a[i]) && isUndefined(b[i])) {
return 0;
} else if (isUndefined(a[i])) {
return -1;
} else if (isUndefined(b[i])) {
return 1;
}
const cmp = a[i] - b[i];
if (cmp !== 0) {
return cmp;
}
i++;
}
});
}