From 7bc83868064ea42a7139cb0e3da35be67bc1c54d Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Sat, 13 Oct 2018 17:33:40 +0200 Subject: [PATCH] AccountIndex encoding updates via util/keyring (#281) * AccountIndex encoding updates via util/keyring * Proper ss58 AccountIndex decoding from keyring * Metadata allows both length and non-length prefixed * Update doc logo size & relative URL --- book.json | 2 +- docs/styles/website.css | 9 +++- packages/rpc-core/package.json | 2 +- packages/rpc-provider/package.json | 6 +-- packages/type-extrinsics/package.json | 2 +- packages/type-storage/package.json | 6 +-- packages/types/package.json | 4 +- packages/types/src/AccountIndex.ts | 64 ++++++++++++++++++--------- packages/types/src/Address.spec.js | 16 +++---- packages/types/src/Metadata.spec.js | 11 ++++- packages/types/src/Metadata.ts | 14 ++++-- yarn.lock | 24 +++++----- 12 files changed, 103 insertions(+), 57 deletions(-) diff --git a/book.json b/book.json index 0fd88e80a5..853271a80d 100644 --- a/book.json +++ b/book.json @@ -11,7 +11,7 @@ "root": "docs", "pluginsConfig": { "insert-logo-link": { - "src": "/logo.png", + "src": "logo.png", "url": "https://polkadot.js.org" }, "sunlight-highlighter": { diff --git a/docs/styles/website.css b/docs/styles/website.css index c6b403dd46..91bbc9fd4b 100644 --- a/docs/styles/website.css +++ b/docs/styles/website.css @@ -3,7 +3,12 @@ } .book .book-summary .book-logo { - padding: 25px 17px 22px 0px; + padding: 0.5em; + text-align: right; +} + +.book .book-summary .book-logo img { + width: 50%; } .book-summary ul.summary li.chapter.active { @@ -19,7 +24,7 @@ color: #fd8824; } -.book-summary ul.summary li.chapter a, +.book-summary ul.summary li.chapter a, .book-summary ul.summary li.chapter span { font-weight: 600; font-size: 1.1em; diff --git a/packages/rpc-core/package.json b/packages/rpc-core/package.json index 306235d9b2..9f0d757110 100644 --- a/packages/rpc-core/package.json +++ b/packages/rpc-core/package.json @@ -32,6 +32,6 @@ "@babel/runtime": "^7.0.0", "@polkadot/jsonrpc": "^0.31.30", "@polkadot/rpc-provider": "^0.31.30", - "@polkadot/util": "^0.31.1" + "@polkadot/util": "^0.31.3" } } diff --git a/packages/rpc-provider/package.json b/packages/rpc-provider/package.json index 66ac5a7b5a..a18da712fe 100644 --- a/packages/rpc-provider/package.json +++ b/packages/rpc-provider/package.json @@ -30,10 +30,10 @@ "homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-provider#readme", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/keyring": "^0.31.1", + "@polkadot/keyring": "^0.31.3", "@polkadot/storage": "^0.31.30", - "@polkadot/util": "^0.31.1", - "@polkadot/util-crypto": "^0.31.1", + "@polkadot/util": "^0.31.3", + "@polkadot/util-crypto": "^0.31.3", "@types/nock": "^9.1.3", "eventemitter3": "^3.1.0", "isomorphic-fetch": "^2.2.1", diff --git a/packages/type-extrinsics/package.json b/packages/type-extrinsics/package.json index af3a573b4e..35274401dd 100644 --- a/packages/type-extrinsics/package.json +++ b/packages/type-extrinsics/package.json @@ -11,6 +11,6 @@ "license": "ISC", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/util": "^0.31.1" + "@polkadot/util": "^0.31.3" } } diff --git a/packages/type-storage/package.json b/packages/type-storage/package.json index f0792ec5c0..b120cb7652 100644 --- a/packages/type-storage/package.json +++ b/packages/type-storage/package.json @@ -30,9 +30,9 @@ "homepage": "https://github.com/polkadot-js/api/tree/master/packages/type-storage#readme", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/keyring": "^0.31.1", + "@polkadot/keyring": "^0.31.3", "@polkadot/types": "^0.31.30", - "@polkadot/util": "^0.31.1", - "@polkadot/util-crypto": "^0.31.1" + "@polkadot/util": "^0.31.3", + "@polkadot/util-crypto": "^0.31.3" } } diff --git a/packages/types/package.json b/packages/types/package.json index cceb7b8e10..31b681b8a4 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -30,7 +30,7 @@ "homepage": "https://github.com/polkadot-js/api/tree/master/packages/types#readme", "dependencies": { "@babel/runtime": "^7.0.0", - "@polkadot/keyring": "^0.31.1", - "@polkadot/util": "^0.31.1" + "@polkadot/keyring": "^0.31.3", + "@polkadot/util": "^0.31.3" } } diff --git a/packages/types/src/AccountIndex.ts b/packages/types/src/AccountIndex.ts index cf235eacb9..83ffb44eb5 100644 --- a/packages/types/src/AccountIndex.ts +++ b/packages/types/src/AccountIndex.ts @@ -2,9 +2,12 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. +import decodeAddress from '@polkadot/keyring/address/decode'; +import encodeAddress from '@polkadot/keyring/address/encode'; +import hexToU8a from '@polkadot/util/hex/toU8a'; import isU8a from '@polkadot/util/is/u8a'; -import u8aToHex from '@polkadot/util/u8a/toHex'; -import u8aToU8a from '@polkadot/util/u8a/toU8a'; +import isHex from '@polkadot/util/is/hex'; +import u8aConcat from '@polkadot/util/u8a/concat'; import { AnyU8a } from './types'; import U8a from './codec/U8a'; @@ -19,41 +22,53 @@ export default class AccountIndex extends U8a { ); } - // FIXME Not 100% sure how to handle the encoding of short addresses. It is (mostly) - // unused atm, options are to go to hex or to utf8. Here we go the hex route. - static encode (value: Uint8Array): string { - return u8aToHex(value); - } - static decodeAccountIndex (value: AnyU8a): Uint8Array { if (value instanceof U8a) { return value.raw; + } else if (Array.isArray(value)) { + return AccountIndex.decodeAccountIndex(Uint8Array.from(value)); } else if (isU8a(value)) { if (!value.length) { return value; } - return value.subarray(0, AccountIndex.readLength(value)); + + const [offset, length] = AccountIndex.readLength(value); + + return value.subarray(offset, offset + length); + } else if (isHex(value)) { + return hexToU8a(value); } - return u8aToU8a(value); + + return decodeAddress(value); } - // TODO Double check the +1 with actual e2e data - static readLength (input: Uint8Array): number { + static readLength (input: Uint8Array): [number, number] { const first = input[0]; if (first <= 0xef) { - return 1; + return [0, 1]; } else if (first === 0xfc) { - return 2 + 1; + return [1, 2]; } else if (first === 0xfd) { - return 4 + 1; + return [1, 4]; } else if (first === 0xfe) { - return 8 + 1; + return [1, 8]; } throw new Error(`Invalid account index byte, 0x${first.toString(16)}`); } + static writeLength (input: Uint8Array): Uint8Array { + switch (input.length) { + case 1: return new Uint8Array([]); + case 2: return new Uint8Array([0xfc]); + case 4: return new Uint8Array([0xfd]); + case 8: return new Uint8Array([0xfe]); + } + + throw new Error(`Invalid account index length, ${input.length}`); + } + fromJSON (input: any): AccountIndex { super.fromJSON(AccountIndex.decodeAccountIndex(input)); @@ -61,9 +76,9 @@ export default class AccountIndex extends U8a { } fromU8a (input: Uint8Array): AccountIndex { - super.fromU8a( - input.subarray(0, AccountIndex.readLength(input)) - ); + const [offset, length] = AccountIndex.readLength(input); + + super.fromU8a(input.subarray(offset, offset + length)); return this; } @@ -72,7 +87,16 @@ export default class AccountIndex extends U8a { return this.toString(); } + toU8a (isBare?: boolean): Uint8Array { + return isBare + ? this.raw + : u8aConcat( + AccountIndex.writeLength(this.raw), + this.raw + ); + } + toString (): string { - return AccountIndex.encode(this.raw); + return encodeAddress(this.raw); } } diff --git a/packages/types/src/Address.spec.js b/packages/types/src/Address.spec.js index 47bed97378..bf3bc595f9 100644 --- a/packages/types/src/Address.spec.js +++ b/packages/types/src/Address.spec.js @@ -31,8 +31,8 @@ describe('Address', () => { ); testDecode( 'AccountIndex', - new AccountIndex('0x0102030405060708010203040506070801020304050607080102030405060708'), - '0x0102030405060708010203040506070801020304050607080102030405060708' + new AccountIndex('0x0001'), + '25GUyk' ); testDecode( 'Array', @@ -54,23 +54,23 @@ describe('Address', () => { ); testDecode( 'Uint8Array (with prefix 1 byte)', - Uint8Array.from([17]), - '0x11' + Uint8Array.from([1]), + 'F7L6' ); testDecode( 'Uint8Array (with prefix 2 bytes)', - Uint8Array.from([0xfc, 17, 18]), - '0xfc1112' + Uint8Array.from([0xfc, 0, 1]), + '25GUyk' ); testDecode( 'Uint8Array (with prefix 4 bytes)', Uint8Array.from([0xfd, 17, 18, 19, 20]), - '0xfd11121314' + 'Mwz15xN8' ); testDecode( 'Uint8Array (with prefix 8 bytes)', Uint8Array.from([0xfe, 17, 18, 19, 20, 21, 22, 23, 24]), - '0xfe1112131415161718' + '3N5RJXxM5fLd4h' ); // FIXME Add this diff --git a/packages/types/src/Metadata.spec.js b/packages/types/src/Metadata.spec.js index f9dd2de6b5..086dc2e7cd 100644 --- a/packages/types/src/Metadata.spec.js +++ b/packages/types/src/Metadata.spec.js @@ -2,6 +2,8 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. +import hexToU8a from '@polkadot/util/hex/toU8a'; + import Metadata from './Metadata'; import rpcdata from './Metadata.rpc'; @@ -13,6 +15,13 @@ describe('Metadata', () => { console.error(str); console.error(decoded.getUniqTypes()); - expect(str).not.toBe(null); + expect(decoded.events.length).not.toBe(0); + }); + + it('decodes when length not present (HACK)', () => { + const u8a = hexToU8a(rpcdata); + const decoded = new Metadata().fromU8a(u8a.subarray(2)); + + expect(decoded.events.length).not.toBe(0); }); }); diff --git a/packages/types/src/Metadata.ts b/packages/types/src/Metadata.ts index 9560020d36..2766ea0946 100644 --- a/packages/types/src/Metadata.ts +++ b/packages/types/src/Metadata.ts @@ -336,10 +336,18 @@ export default class RuntimeMetadata extends Struct { } fromU8a (input: Uint8Array): RuntimeMetadata { - // this does not look correct, metadata now has a length prefix. Strip, move on. - const [offset] = Compact.decodeU8a(input, DEFAULT_LENGTH_BITS); + // HACK 13 Oct 2018 - For current running BBQ nodes, Metadata is not properly + // encoded, it does not have a length prefix. For latest substrate master, it + // is properly encoded. Here we pull the prefix, check it agianst the length - + // if matches, then we have the length, otherwise we assume it is an older node + // and use the whole buffer + const [offset, length] = Compact.decodeU8a(input, DEFAULT_LENGTH_BITS); - super.fromU8a(input.subarray(offset)); + super.fromU8a( + input.length === (offset + length.toNumber()) + ? input.subarray(offset) + : input + ); return this; } diff --git a/yarn.lock b/yarn.lock index f2501cef98..f9726b61c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1219,13 +1219,13 @@ typedoc-plugin-markdown "^1.1.15" typescript "^3.0.1" -"@polkadot/keyring@^0.31.1": - version "0.31.1" - resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-0.31.1.tgz#f33cf0254f763af1d10a50db2edc21cd845a8f78" +"@polkadot/keyring@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-0.31.3.tgz#b069a7210d24a16e21ef4e5755cc77864e3008c4" dependencies: "@babel/runtime" "^7.0.0" - "@polkadot/util" "^0.31.1" - "@polkadot/util-crypto" "^0.31.1" + "@polkadot/util" "^0.31.3" + "@polkadot/util-crypto" "^0.31.3" "@types/bs58" "^3.0.30" bs58 "^4.0.1" @@ -1233,12 +1233,12 @@ version "0.1.30" resolved "https://registry.yarnpkg.com/@polkadot/ts/-/ts-0.1.30.tgz#d6d1498a5597e09de88f6117663bcf842040c801" -"@polkadot/util-crypto@^0.31.1": - version "0.31.1" - resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-0.31.1.tgz#f8283bd40547e5e169d35903cf8c863567a336ee" +"@polkadot/util-crypto@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-0.31.3.tgz#c871f47d55f6d9771bec504abcd2ac2c669b2314" dependencies: "@babel/runtime" "^7.0.0" - "@polkadot/util" "^0.31.1" + "@polkadot/util" "^0.31.3" "@types/bip39" "^2.4.0" bip39 "^2.5.0" blakejs "^1.1.0" @@ -1246,9 +1246,9 @@ tweetnacl "^1.0.0" xxhashjs "^0.2.2" -"@polkadot/util@^0.31.1": - version "0.31.1" - resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.31.1.tgz#c5321a8c9b1625525b579e6c35dc59d5a0f3f08d" +"@polkadot/util@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.31.3.tgz#895f86df135bb0bb7a9ef9d648371cf8b936fd55" dependencies: "@babel/runtime" "^7.0.0" "@types/bn.js" "^4.11.1"