From 78e01a0e1698e03a88df06a011fb5997500e498e Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Tue, 26 Jun 2018 21:26:51 +0200 Subject: [PATCH] Combine util, types & trie into common (#150) * Pull in trie repo * Bring in types repo --- README.md | 23 +- jest.config.js | 13 +- lerna.json | 2 +- packages/code-extrinsics/LICENSE | 15 + packages/code-extrinsics/README.md | 1 + packages/code-extrinsics/package.json | 25 + packages/code-extrinsics/src/decode/length.ts | 13 + .../code-extrinsics/src/encode/call.spec.js | 52 ++ packages/code-extrinsics/src/encode/call.ts | 19 + .../src/encode/extrinsic.spec.js | 27 + .../code-extrinsics/src/encode/extrinsic.ts | 17 + .../code-extrinsics/src/encode/index.spec.js | 34 + packages/code-extrinsics/src/encode/index.ts | 23 + packages/code-extrinsics/src/encode/length.ts | 15 + .../code-extrinsics/src/encode/prefixes.ts | 25 + .../src/encode/unchecked.spec.js | 115 +++ .../code-extrinsics/src/encode/unchecked.ts | 33 + packages/code-extrinsics/src/types.d.ts | 9 + packages/code-primitives-builder/LICENSE | 15 + packages/code-primitives-builder/README.md | 13 + packages/code-primitives-builder/package.json | 47 + .../code-primitives-builder/src/block.spec.js | 82 ++ packages/code-primitives-builder/src/block.ts | 15 + .../src/extrinsic/rootRaw.spec.js | 77 ++ .../src/extrinsic/rootRaw.ts | 14 + .../src/header.spec.js | 41 + .../code-primitives-builder/src/header.ts | 25 + .../code-primitives-builder/src/types.d.ts | 22 + packages/code-primitives-json/LICENSE | 15 + packages/code-primitives-json/README.md | 33 + packages/code-primitives-json/package.json | 41 + .../src/accountId/decode.ts | 12 + .../src/accountId/encode.ts | 12 + .../src/accountId/index.ts | 11 + .../src/bn/decode.spec.js | 25 + .../code-primitives-json/src/bn/decode.ts | 20 + .../src/bn/encode.spec.js | 21 + .../code-primitives-json/src/bn/encode.ts | 16 + packages/code-primitives-json/src/bn/index.ts | 11 + .../src/bytes/decode.spec.js | 13 + .../code-primitives-json/src/bytes/decode.ts | 12 + .../src/bytes/encode.spec.js | 13 + .../code-primitives-json/src/bytes/encode.ts | 12 + .../code-primitives-json/src/bytes/index.ts | 11 + .../src/hash/decode.spec.js | 19 + .../code-primitives-json/src/hash/decode.ts | 12 + .../src/hash/encode.spec.js | 21 + .../code-primitives-json/src/hash/encode.ts | 12 + .../code-primitives-json/src/hash/index.ts | 11 + .../src/header/decode.spec.js | 38 + .../code-primitives-json/src/header/decode.ts | 24 + .../src/header/encode.spec.js | 38 + .../code-primitives-json/src/header/encode.ts | 22 + .../code-primitives-json/src/header/index.ts | 11 + packages/code-primitives-json/src/index.ts | 12 + .../src/objectId/decode.ts | 12 + .../src/objectId/encode.ts | 12 + .../src/objectId/index.ts | 11 + .../src/parachainId/decode.ts | 12 + .../src/parachainId/encode.ts | 12 + .../src/parachainId/index.ts | 11 + .../src/signature/decode.ts | 12 + .../src/signature/encode.ts | 12 + .../src/signature/index.ts | 11 + packages/code-primitives-json/src/types.d.ts | 51 ++ packages/code-primitives/LICENSE | 15 + packages/code-primitives/README.md | 13 + packages/code-primitives/package.json | 43 + .../src/block/decodeRaw.spec.js | 54 ++ .../code-primitives/src/block/decodeRaw.ts | 39 + .../code-primitives/src/block/encode.spec.js | 46 + packages/code-primitives/src/block/encode.ts | 15 + .../src/block/encodeRaw.spec.js | 37 + .../code-primitives/src/block/encodeRaw.ts | 19 + packages/code-primitives/src/block/index.ts | 9 + .../code-primitives/src/decoder/array.spec.js | 37 + packages/code-primitives/src/decoder/array.ts | 18 + .../code-primitives/src/decoder/u8a.spec.js | 36 + packages/code-primitives/src/decoder/u8a.ts | 12 + .../code-primitives/src/encoder/array.spec.js | 22 + packages/code-primitives/src/encoder/array.ts | 18 + .../code-primitives/src/encoder/u8a.spec.js | 20 + packages/code-primitives/src/encoder/u8a.ts | 13 + .../code-primitives/src/header/decode.spec.js | 47 + packages/code-primitives/src/header/decode.ts | 24 + .../src/header/decodeRaw.spec.js | 57 ++ .../code-primitives/src/header/decodeRaw.ts | 39 + .../code-primitives/src/header/encode.spec.js | 45 + packages/code-primitives/src/header/encode.ts | 32 + packages/code-primitives/src/header/hash.ts | 16 + packages/code-primitives/src/header/index.ts | 11 + .../code-primitives/src/header/offsets.ts | 17 + packages/code-primitives/src/index.ts | 6 + packages/trie-db/LICENSE | 373 ++++++++ packages/trie-db/README.md | 30 + packages/trie-db/package.json | 47 + packages/trie-db/src/BaseTrie.ts | 827 ++++++++++++++++++ packages/trie-db/src/CheckpointTrie.ts | 161 ++++ packages/trie-db/src/Node.ts | 170 ++++ packages/trie-db/src/constants.ts | 13 + packages/trie-db/src/encoder/decode.ts | 29 + packages/trie-db/src/encoder/encode.ts | 29 + packages/trie-db/src/encoder/index.ts | 38 + packages/trie-db/src/index.ts | 23 + packages/trie-db/src/nibbles/fromU8a.ts | 17 + packages/trie-db/src/nibbles/index.ts | 15 + packages/trie-db/src/nibbles/isEqual.ts | 12 + .../trie-db/src/nibbles/matchingLength.ts | 14 + packages/trie-db/src/nibbles/toU8a.ts | 16 + packages/trie-db/src/nodeFactory.ts | 91 ++ packages/trie-db/src/proof/index.ts | 11 + packages/trie-db/src/proof/prove.ts | 35 + packages/trie-db/src/proof/verifyProof.ts | 85 ++ packages/trie-db/src/streams/ScratchRead.ts | 58 ++ packages/trie-db/src/streams/TrieRead.ts | 59 ++ packages/trie-db/src/types.d.ts | 28 + packages/trie-db/src/util/isRawNode.ts | 10 + packages/trie-db/src/util/rlpToString.ts | 19 + packages/trie-db/src/util/semaphore.ts | 27 + packages/trie-db/src/util/taskExecutor.ts | 53 ++ packages/trie-db/test/checkpoints.spec.js | 66 ++ packages/trie-db/test/ethereum.spec.js | 41 + packages/trie-db/test/index.spec.js | 205 +++++ packages/trie-db/test/offical.spec.js | 63 ++ .../trie-db/test/polkadotRefactor.spec.js | 94 ++ packages/trie-db/test/proof.spec.js | 106 +++ packages/trie-db/test/rawOPs.spec.js | 72 ++ packages/trie-db/test/streams.spec.js | 177 ++++ packages/trie-db/test/taskExecutor.spec.js | 30 + packages/{util-triehash => trie-hash}/LICENSE | 2 +- packages/trie-hash/README.md | 17 + .../docs/README.md | 12 +- .../{util-triehash => trie-hash}/package.json | 16 +- .../src/encode/.nodoc | 0 .../src/encode/aux.ts | 2 +- .../src/encode/hexPrefix.spec.js | 2 +- .../src/encode/hexPrefix.ts | 2 +- .../src/encode/index.ts | 2 +- .../src/encode/pairs.ts | 2 +- .../src/encode/shared.ts | 2 +- .../src/encode/single.ts | 2 +- .../{util-triehash => trie-hash}/src/index.ts | 2 +- .../src/root.spec.js | 2 +- .../{util-triehash => trie-hash}/src/root.ts | 4 +- .../src/rootOrdered.spec.js | 2 +- .../src/rootOrdered.ts | 2 +- .../src/types.d.ts | 2 +- .../src/util/.nodoc | 0 .../src/util/asNibbles.spec.js | 2 +- .../src/util/asNibbles.ts | 4 +- .../src/util/genRoot.ts | 2 +- .../src/util/pairsUniq.spec.js | 2 +- .../src/util/pairsUniq.ts | 2 +- .../src/util/sharedLength.ts | 2 +- .../src/util/sharedPrefixLength.spec.js | 2 +- .../src/util/sharedPrefixLength.ts | 2 +- packages/type-extrinsics/LICENSE | 15 + packages/type-extrinsics/README.md | 1 + packages/type-extrinsics/package.json | 23 + packages/type-extrinsics/src/consensus.ts | 48 + packages/type-extrinsics/src/council.ts | 114 +++ packages/type-extrinsics/src/councilVoting.ts | 69 ++ packages/type-extrinsics/src/democracy.ts | 71 ++ packages/type-extrinsics/src/index.ts | 29 + packages/type-extrinsics/src/parachains.ts | 28 + packages/type-extrinsics/src/session.ts | 46 + packages/type-extrinsics/src/staking.ts | 83 ++ packages/type-extrinsics/src/timestamp.ts | 28 + packages/type-extrinsics/src/treasury.ts | 13 + packages/type-extrinsics/src/types.d.ts | 21 + packages/type-jsonrpc/LICENSE | 15 + packages/type-jsonrpc/README.md | 30 + packages/type-jsonrpc/package.json | 40 + packages/type-jsonrpc/src/author.ts | 30 + packages/type-jsonrpc/src/chain.ts | 46 + packages/type-jsonrpc/src/index.spec.js | 12 + packages/type-jsonrpc/src/index.ts | 19 + packages/type-jsonrpc/src/state.ts | 105 +++ packages/type-jsonrpc/src/system.ts | 42 + packages/type-jsonrpc/src/types.d.ts | 14 + packages/type-params/LICENSE | 15 + packages/type-params/README.md | 11 + packages/type-params/package.json | 42 + packages/type-params/src/decode/index.spec.js | 71 ++ packages/type-params/src/decode/index.ts | 59 ++ packages/type-params/src/decode/types.d.ts | 7 + packages/type-params/src/decode/value/bn.ts | 16 + packages/type-params/src/decode/value/bool.ts | 12 + packages/type-params/src/decode/value/byte.ts | 12 + .../type-params/src/decode/value/bytes.ts | 16 + packages/type-params/src/decode/value/code.ts | 12 + .../type-params/src/decode/value/digest.ts | 31 + .../type-params/src/decode/value/header.ts | 18 + .../type-params/src/decode/value/index.ts | 106 +++ .../type-params/src/decode/value/keyValue.ts | 23 + .../type-params/src/decode/value/method.ts | 54 ++ .../src/decode/value/misbehavior.ts | 41 + .../src/decode/value/passThrough.ts | 12 + .../type-params/src/decode/value/string.ts | 19 + packages/type-params/src/decode/value/time.ts | 18 + packages/type-params/src/decode/value/u8a.ts | 14 + packages/type-params/src/encode/index.ts | 18 + packages/type-params/src/encode/param.spec.js | 49 ++ packages/type-params/src/encode/param.ts | 40 + packages/type-params/src/encode/type/index.ts | 101 +++ packages/type-params/src/method.ts | 26 + packages/type-params/src/param.ts | 13 + packages/type-params/src/section.ts | 36 + packages/type-params/src/signature.spec.js | 33 + packages/type-params/src/signature.ts | 26 + packages/type-params/src/sizes.ts | 23 + packages/type-params/src/typeToString.spec.js | 31 + packages/type-params/src/typeToString.ts | 17 + packages/type-params/src/types.d.ts | 115 +++ packages/type-primitives/LICENSE | 15 + packages/type-primitives/README.md | 33 + packages/type-primitives/package.json | 42 + packages/type-primitives/src/base.d.ts | 27 + packages/type-primitives/src/bft.d.ts | 13 + packages/type-primitives/src/block.d.ts | 11 + packages/type-primitives/src/candidate.d.ts | 24 + packages/type-primitives/src/digest.d.ts | 11 + packages/type-primitives/src/extrinsic.d.ts | 17 + packages/type-primitives/src/header.d.ts | 14 + packages/type-primitives/src/misbehavior.d.ts | 16 + .../type-primitives/src/parachain.unused-ts | 21 + packages/type-primitives/src/role/all.ts | 15 + .../type-primitives/src/role/fromId.spec.js | 19 + packages/type-primitives/src/role/fromId.ts | 19 + packages/type-primitives/src/role/index.d.ts | 5 + .../type-primitives/src/role/toId.spec.js | 19 + packages/type-primitives/src/role/toId.ts | 19 + packages/type-primitives/src/sizes.ts | 15 + packages/type-primitives/src/state.unused-ts | 14 + packages/type-storage/LICENSE | 15 + packages/type-storage/README.md | 13 + packages/type-storage/package.json | 44 + packages/type-storage/src/consensus.ts | 48 + packages/type-storage/src/council.ts | 202 +++++ packages/type-storage/src/councilVoting.ts | 88 ++ packages/type-storage/src/democracy.ts | 124 +++ packages/type-storage/src/governance.ts | 49 ++ packages/type-storage/src/index.ts | 31 + packages/type-storage/src/key/index.spec.js | 59 ++ packages/type-storage/src/key/index.ts | 29 + packages/type-storage/src/key/params.ts | 85 ++ packages/type-storage/src/parachains.ts | 56 ++ packages/type-storage/src/session.ts | 72 ++ packages/type-storage/src/staking.ts | 152 ++++ packages/type-storage/src/system.ts | 103 +++ packages/type-storage/src/timestamp.ts | 33 + packages/type-storage/src/types.d.ts | 23 + packages/util-crypto/README.md | 10 +- packages/util-crypto/package.json | 10 +- packages/util-keyring/package.json | 6 +- packages/util-rlp/README.md | 10 +- packages/util-rlp/package.json | 10 +- packages/util-triedb/README.md | 11 +- packages/util-triedb/package.json | 16 +- packages/util-triedb/src/temp/commit.ts | 2 +- packages/util-triedb/src/temp/index.ts | 4 +- packages/util-triedb/src/temp/pairs.ts | 2 +- packages/util-triedb/src/temp/types.d.ts | 2 +- packages/util-triedb/src/types.d.ts | 2 +- packages/util-triehash/README.md | 17 - packages/util/README.md | 10 +- packages/util/package.json | 8 +- tsconfig.json | 15 +- yarn.lock | 251 +++++- 269 files changed, 9406 insertions(+), 117 deletions(-) create mode 100644 packages/code-extrinsics/LICENSE create mode 100644 packages/code-extrinsics/README.md create mode 100644 packages/code-extrinsics/package.json create mode 100644 packages/code-extrinsics/src/decode/length.ts create mode 100644 packages/code-extrinsics/src/encode/call.spec.js create mode 100644 packages/code-extrinsics/src/encode/call.ts create mode 100644 packages/code-extrinsics/src/encode/extrinsic.spec.js create mode 100644 packages/code-extrinsics/src/encode/extrinsic.ts create mode 100644 packages/code-extrinsics/src/encode/index.spec.js create mode 100644 packages/code-extrinsics/src/encode/index.ts create mode 100644 packages/code-extrinsics/src/encode/length.ts create mode 100644 packages/code-extrinsics/src/encode/prefixes.ts create mode 100644 packages/code-extrinsics/src/encode/unchecked.spec.js create mode 100644 packages/code-extrinsics/src/encode/unchecked.ts create mode 100644 packages/code-extrinsics/src/types.d.ts create mode 100644 packages/code-primitives-builder/LICENSE create mode 100644 packages/code-primitives-builder/README.md create mode 100644 packages/code-primitives-builder/package.json create mode 100644 packages/code-primitives-builder/src/block.spec.js create mode 100644 packages/code-primitives-builder/src/block.ts create mode 100644 packages/code-primitives-builder/src/extrinsic/rootRaw.spec.js create mode 100644 packages/code-primitives-builder/src/extrinsic/rootRaw.ts create mode 100644 packages/code-primitives-builder/src/header.spec.js create mode 100644 packages/code-primitives-builder/src/header.ts create mode 100644 packages/code-primitives-builder/src/types.d.ts create mode 100644 packages/code-primitives-json/LICENSE create mode 100644 packages/code-primitives-json/README.md create mode 100644 packages/code-primitives-json/package.json create mode 100644 packages/code-primitives-json/src/accountId/decode.ts create mode 100644 packages/code-primitives-json/src/accountId/encode.ts create mode 100644 packages/code-primitives-json/src/accountId/index.ts create mode 100644 packages/code-primitives-json/src/bn/decode.spec.js create mode 100644 packages/code-primitives-json/src/bn/decode.ts create mode 100644 packages/code-primitives-json/src/bn/encode.spec.js create mode 100644 packages/code-primitives-json/src/bn/encode.ts create mode 100644 packages/code-primitives-json/src/bn/index.ts create mode 100644 packages/code-primitives-json/src/bytes/decode.spec.js create mode 100644 packages/code-primitives-json/src/bytes/decode.ts create mode 100644 packages/code-primitives-json/src/bytes/encode.spec.js create mode 100644 packages/code-primitives-json/src/bytes/encode.ts create mode 100644 packages/code-primitives-json/src/bytes/index.ts create mode 100644 packages/code-primitives-json/src/hash/decode.spec.js create mode 100644 packages/code-primitives-json/src/hash/decode.ts create mode 100644 packages/code-primitives-json/src/hash/encode.spec.js create mode 100644 packages/code-primitives-json/src/hash/encode.ts create mode 100644 packages/code-primitives-json/src/hash/index.ts create mode 100644 packages/code-primitives-json/src/header/decode.spec.js create mode 100644 packages/code-primitives-json/src/header/decode.ts create mode 100644 packages/code-primitives-json/src/header/encode.spec.js create mode 100644 packages/code-primitives-json/src/header/encode.ts create mode 100644 packages/code-primitives-json/src/header/index.ts create mode 100644 packages/code-primitives-json/src/index.ts create mode 100644 packages/code-primitives-json/src/objectId/decode.ts create mode 100644 packages/code-primitives-json/src/objectId/encode.ts create mode 100644 packages/code-primitives-json/src/objectId/index.ts create mode 100644 packages/code-primitives-json/src/parachainId/decode.ts create mode 100644 packages/code-primitives-json/src/parachainId/encode.ts create mode 100644 packages/code-primitives-json/src/parachainId/index.ts create mode 100644 packages/code-primitives-json/src/signature/decode.ts create mode 100644 packages/code-primitives-json/src/signature/encode.ts create mode 100644 packages/code-primitives-json/src/signature/index.ts create mode 100644 packages/code-primitives-json/src/types.d.ts create mode 100644 packages/code-primitives/LICENSE create mode 100644 packages/code-primitives/README.md create mode 100644 packages/code-primitives/package.json create mode 100644 packages/code-primitives/src/block/decodeRaw.spec.js create mode 100644 packages/code-primitives/src/block/decodeRaw.ts create mode 100644 packages/code-primitives/src/block/encode.spec.js create mode 100644 packages/code-primitives/src/block/encode.ts create mode 100644 packages/code-primitives/src/block/encodeRaw.spec.js create mode 100644 packages/code-primitives/src/block/encodeRaw.ts create mode 100644 packages/code-primitives/src/block/index.ts create mode 100644 packages/code-primitives/src/decoder/array.spec.js create mode 100644 packages/code-primitives/src/decoder/array.ts create mode 100644 packages/code-primitives/src/decoder/u8a.spec.js create mode 100644 packages/code-primitives/src/decoder/u8a.ts create mode 100644 packages/code-primitives/src/encoder/array.spec.js create mode 100644 packages/code-primitives/src/encoder/array.ts create mode 100644 packages/code-primitives/src/encoder/u8a.spec.js create mode 100644 packages/code-primitives/src/encoder/u8a.ts create mode 100644 packages/code-primitives/src/header/decode.spec.js create mode 100644 packages/code-primitives/src/header/decode.ts create mode 100644 packages/code-primitives/src/header/decodeRaw.spec.js create mode 100644 packages/code-primitives/src/header/decodeRaw.ts create mode 100644 packages/code-primitives/src/header/encode.spec.js create mode 100644 packages/code-primitives/src/header/encode.ts create mode 100644 packages/code-primitives/src/header/hash.ts create mode 100644 packages/code-primitives/src/header/index.ts create mode 100644 packages/code-primitives/src/header/offsets.ts create mode 100644 packages/code-primitives/src/index.ts create mode 100644 packages/trie-db/LICENSE create mode 100644 packages/trie-db/README.md create mode 100644 packages/trie-db/package.json create mode 100644 packages/trie-db/src/BaseTrie.ts create mode 100644 packages/trie-db/src/CheckpointTrie.ts create mode 100644 packages/trie-db/src/Node.ts create mode 100644 packages/trie-db/src/constants.ts create mode 100644 packages/trie-db/src/encoder/decode.ts create mode 100644 packages/trie-db/src/encoder/encode.ts create mode 100644 packages/trie-db/src/encoder/index.ts create mode 100644 packages/trie-db/src/index.ts create mode 100644 packages/trie-db/src/nibbles/fromU8a.ts create mode 100644 packages/trie-db/src/nibbles/index.ts create mode 100644 packages/trie-db/src/nibbles/isEqual.ts create mode 100644 packages/trie-db/src/nibbles/matchingLength.ts create mode 100644 packages/trie-db/src/nibbles/toU8a.ts create mode 100644 packages/trie-db/src/nodeFactory.ts create mode 100644 packages/trie-db/src/proof/index.ts create mode 100644 packages/trie-db/src/proof/prove.ts create mode 100644 packages/trie-db/src/proof/verifyProof.ts create mode 100644 packages/trie-db/src/streams/ScratchRead.ts create mode 100644 packages/trie-db/src/streams/TrieRead.ts create mode 100644 packages/trie-db/src/types.d.ts create mode 100644 packages/trie-db/src/util/isRawNode.ts create mode 100644 packages/trie-db/src/util/rlpToString.ts create mode 100644 packages/trie-db/src/util/semaphore.ts create mode 100644 packages/trie-db/src/util/taskExecutor.ts create mode 100644 packages/trie-db/test/checkpoints.spec.js create mode 100644 packages/trie-db/test/ethereum.spec.js create mode 100644 packages/trie-db/test/index.spec.js create mode 100644 packages/trie-db/test/offical.spec.js create mode 100644 packages/trie-db/test/polkadotRefactor.spec.js create mode 100644 packages/trie-db/test/proof.spec.js create mode 100644 packages/trie-db/test/rawOPs.spec.js create mode 100644 packages/trie-db/test/streams.spec.js create mode 100644 packages/trie-db/test/taskExecutor.spec.js rename packages/{util-triehash => trie-hash}/LICENSE (91%) create mode 100644 packages/trie-hash/README.md rename packages/{util-triehash => trie-hash}/docs/README.md (79%) rename packages/{util-triehash => trie-hash}/package.json (65%) rename packages/{util-triehash => trie-hash}/src/encode/.nodoc (100%) rename packages/{util-triehash => trie-hash}/src/encode/aux.ts (88%) rename packages/{util-triehash => trie-hash}/src/encode/hexPrefix.spec.js (95%) rename packages/{util-triehash => trie-hash}/src/encode/hexPrefix.ts (88%) rename packages/{util-triehash => trie-hash}/src/encode/index.ts (92%) rename packages/{util-triehash => trie-hash}/src/encode/pairs.ts (93%) rename packages/{util-triehash => trie-hash}/src/encode/shared.ts (87%) rename packages/{util-triehash => trie-hash}/src/encode/single.ts (84%) rename packages/{util-triehash => trie-hash}/src/index.ts (83%) rename packages/{util-triehash => trie-hash}/src/root.spec.js (97%) rename packages/{util-triehash => trie-hash}/src/root.ts (88%) rename packages/{util-triehash => trie-hash}/src/rootOrdered.spec.js (90%) rename packages/{util-triehash => trie-hash}/src/rootOrdered.ts (94%) rename packages/{util-triehash => trie-hash}/src/types.d.ts (76%) rename packages/{util-triehash => trie-hash}/src/util/.nodoc (100%) rename packages/{util-triehash => trie-hash}/src/util/asNibbles.spec.js (89%) rename packages/{util-triehash => trie-hash}/src/util/asNibbles.ts (86%) rename packages/{util-triehash => trie-hash}/src/util/genRoot.ts (88%) rename packages/{util-triehash => trie-hash}/src/util/pairsUniq.spec.js (94%) rename packages/{util-triehash => trie-hash}/src/util/pairsUniq.ts (88%) rename packages/{util-triehash => trie-hash}/src/util/sharedLength.ts (84%) rename packages/{util-triehash => trie-hash}/src/util/sharedPrefixLength.spec.js (92%) rename packages/{util-triehash => trie-hash}/src/util/sharedPrefixLength.ts (87%) create mode 100644 packages/type-extrinsics/LICENSE create mode 100644 packages/type-extrinsics/README.md create mode 100644 packages/type-extrinsics/package.json create mode 100644 packages/type-extrinsics/src/consensus.ts create mode 100644 packages/type-extrinsics/src/council.ts create mode 100644 packages/type-extrinsics/src/councilVoting.ts create mode 100644 packages/type-extrinsics/src/democracy.ts create mode 100644 packages/type-extrinsics/src/index.ts create mode 100644 packages/type-extrinsics/src/parachains.ts create mode 100644 packages/type-extrinsics/src/session.ts create mode 100644 packages/type-extrinsics/src/staking.ts create mode 100644 packages/type-extrinsics/src/timestamp.ts create mode 100644 packages/type-extrinsics/src/treasury.ts create mode 100644 packages/type-extrinsics/src/types.d.ts create mode 100644 packages/type-jsonrpc/LICENSE create mode 100644 packages/type-jsonrpc/README.md create mode 100644 packages/type-jsonrpc/package.json create mode 100644 packages/type-jsonrpc/src/author.ts create mode 100644 packages/type-jsonrpc/src/chain.ts create mode 100644 packages/type-jsonrpc/src/index.spec.js create mode 100644 packages/type-jsonrpc/src/index.ts create mode 100644 packages/type-jsonrpc/src/state.ts create mode 100644 packages/type-jsonrpc/src/system.ts create mode 100644 packages/type-jsonrpc/src/types.d.ts create mode 100644 packages/type-params/LICENSE create mode 100644 packages/type-params/README.md create mode 100644 packages/type-params/package.json create mode 100644 packages/type-params/src/decode/index.spec.js create mode 100644 packages/type-params/src/decode/index.ts create mode 100644 packages/type-params/src/decode/types.d.ts create mode 100644 packages/type-params/src/decode/value/bn.ts create mode 100644 packages/type-params/src/decode/value/bool.ts create mode 100644 packages/type-params/src/decode/value/byte.ts create mode 100644 packages/type-params/src/decode/value/bytes.ts create mode 100644 packages/type-params/src/decode/value/code.ts create mode 100644 packages/type-params/src/decode/value/digest.ts create mode 100644 packages/type-params/src/decode/value/header.ts create mode 100644 packages/type-params/src/decode/value/index.ts create mode 100644 packages/type-params/src/decode/value/keyValue.ts create mode 100644 packages/type-params/src/decode/value/method.ts create mode 100644 packages/type-params/src/decode/value/misbehavior.ts create mode 100644 packages/type-params/src/decode/value/passThrough.ts create mode 100644 packages/type-params/src/decode/value/string.ts create mode 100644 packages/type-params/src/decode/value/time.ts create mode 100644 packages/type-params/src/decode/value/u8a.ts create mode 100644 packages/type-params/src/encode/index.ts create mode 100644 packages/type-params/src/encode/param.spec.js create mode 100644 packages/type-params/src/encode/param.ts create mode 100644 packages/type-params/src/encode/type/index.ts create mode 100644 packages/type-params/src/method.ts create mode 100644 packages/type-params/src/param.ts create mode 100644 packages/type-params/src/section.ts create mode 100644 packages/type-params/src/signature.spec.js create mode 100644 packages/type-params/src/signature.ts create mode 100644 packages/type-params/src/sizes.ts create mode 100644 packages/type-params/src/typeToString.spec.js create mode 100644 packages/type-params/src/typeToString.ts create mode 100644 packages/type-params/src/types.d.ts create mode 100644 packages/type-primitives/LICENSE create mode 100644 packages/type-primitives/README.md create mode 100644 packages/type-primitives/package.json create mode 100644 packages/type-primitives/src/base.d.ts create mode 100644 packages/type-primitives/src/bft.d.ts create mode 100644 packages/type-primitives/src/block.d.ts create mode 100644 packages/type-primitives/src/candidate.d.ts create mode 100644 packages/type-primitives/src/digest.d.ts create mode 100644 packages/type-primitives/src/extrinsic.d.ts create mode 100644 packages/type-primitives/src/header.d.ts create mode 100644 packages/type-primitives/src/misbehavior.d.ts create mode 100644 packages/type-primitives/src/parachain.unused-ts create mode 100644 packages/type-primitives/src/role/all.ts create mode 100644 packages/type-primitives/src/role/fromId.spec.js create mode 100644 packages/type-primitives/src/role/fromId.ts create mode 100644 packages/type-primitives/src/role/index.d.ts create mode 100644 packages/type-primitives/src/role/toId.spec.js create mode 100644 packages/type-primitives/src/role/toId.ts create mode 100644 packages/type-primitives/src/sizes.ts create mode 100644 packages/type-primitives/src/state.unused-ts create mode 100644 packages/type-storage/LICENSE create mode 100644 packages/type-storage/README.md create mode 100644 packages/type-storage/package.json create mode 100644 packages/type-storage/src/consensus.ts create mode 100644 packages/type-storage/src/council.ts create mode 100644 packages/type-storage/src/councilVoting.ts create mode 100644 packages/type-storage/src/democracy.ts create mode 100644 packages/type-storage/src/governance.ts create mode 100644 packages/type-storage/src/index.ts create mode 100644 packages/type-storage/src/key/index.spec.js create mode 100644 packages/type-storage/src/key/index.ts create mode 100644 packages/type-storage/src/key/params.ts create mode 100644 packages/type-storage/src/parachains.ts create mode 100644 packages/type-storage/src/session.ts create mode 100644 packages/type-storage/src/staking.ts create mode 100644 packages/type-storage/src/system.ts create mode 100644 packages/type-storage/src/timestamp.ts create mode 100644 packages/type-storage/src/types.d.ts delete mode 100644 packages/util-triehash/README.md diff --git a/README.md b/README.md index 73f9a345c..d18f3fa85 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,32 @@ Various useful utility functions that are used across all projects in the [@polkadot](https://polkadot.js.org) namespace. It provides utility functions with additional safety checks, allowing not only for consistent coding, but also reducing the general boilerplate. -It is split up into a number of internal packages - +It is split up into a number of internal packages, namely utilities - - [util](packages/util/) General utilities - [util-crypto](packages/util-crypto/) Crypto and hashing utilities - [util-keyring](packages/util-keyring/) Keyring management - [util-rlp](packages/util-rlp/) RLP encoding & decoding -- [util-triehash](packages/util-triehash/) Calculation of trie hashes + +Various useful trie interfaces and utilities - + +- [trie-db](packages/trie-db/) Merkle Patricia Tree implementation adapcted for Polkadot +- [trie-hash](packages/trie-hash/) Calculate hashes (either ordered or unordered) from a set of inputs + +Type definitions for interfaces as exposed by Polkadot & Substrate clients - + +- [@polkadot/extrinsics](packages/type-extrinsics/) Base extrinsic definitions +- [@polkadot/jsonrpc](packages/type-jsonrpc/) Definitions for JSONRPC endpoints +- [@polkadot/params](packages/type-params/) Input/output parameter formatting +- [@polkadot/primitives](packages/type-primitives/) Primitive type definitions +- [@polkadot/storage](packages/type-storage/) Definitions for storage entries + +Codecs for types (possibly to be combined with types) - + +- [@polkadot/extrinsics-codec](packages/code-extrinsics/) Encoders for extrinsics +- [@polkadot/primitives-codec](packages/code-primitives/) Primitive encoding/decoding +- [@polkadot/primitives-builder](packages/code-primitives-builder/) Primitive creator +- [@polkadot/primitives-json](packages/code-primitives-json/) Primitive json encoding/decoding ## Contributing diff --git a/jest.config.js b/jest.config.js index 9a7e26241..dbdd9ee95 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,7 +2,18 @@ const config = require('@polkadot/dev/config/jest'); module.exports = Object.assign({}, config, { moduleNameMapper: { - '@polkadot/util-(crypto|keyring|rlp|triehash)(.*)$': '/packages/util-$1/src/$2', + '@polkadot/extrinsics-codec(.*)$': '/packages/code-extrinsics/src/$1', + '@polkadot/primitives-codec(.*)$': '/packages/code-primitives/src/$1', + '@polkadot/primitives-(builder|json)(.*)$': '/packages/code-primitives-$1/src/$2', + + '@polkadot/extrinsics(.*)$': '/packages/type-extrinsics/src/$1', + '@polkadot/jsonrpc(.*)$': '/packages/type-jsonrpc/src/$1', + '@polkadot/params(.*)$': '/packages/type-params/src/$1', + '@polkadot/primitives(.*)$': '/packages/type-primitives/src/$1', + '@polkadot/storage(.*)$': '/packages/type-storage/src/$1', + + '@polkadot/trie-(db|hash)(.*)$': '/packages/trie-$1/src/$2', + '@polkadot/util-(crypto|keyring|rlp)(.*)$': '/packages/util-$1/src/$2', '@polkadot/util(.*)$': '/packages/util/src/$1' } }); diff --git a/lerna.json b/lerna.json index 45eecccb8..020b5087a 100644 --- a/lerna.json +++ b/lerna.json @@ -10,5 +10,5 @@ "packages": [ "packages/*" ], - "version": "0.24.9" + "version": "0.25.0" } diff --git a/packages/code-extrinsics/LICENSE b/packages/code-extrinsics/LICENSE new file mode 100644 index 000000000..017811582 --- /dev/null +++ b/packages/code-extrinsics/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/code-extrinsics/README.md b/packages/code-extrinsics/README.md new file mode 100644 index 000000000..d48c42690 --- /dev/null +++ b/packages/code-extrinsics/README.md @@ -0,0 +1 @@ +# @polkadot/extrinsics-codec diff --git a/packages/code-extrinsics/package.json b/packages/code-extrinsics/package.json new file mode 100644 index 000000000..1d05960c0 --- /dev/null +++ b/packages/code-extrinsics/package.json @@ -0,0 +1,25 @@ +{ + "name": "@polkadot/extrinsics-codec", + "version": "0.25.0", + "main": "index.js", + "repository": "https://github.com/polkadot-js/apps.git", + "author": "Jaco Greeff ", + "maintainers": [ + "Jaco Greeff " + ], + "contributors": [], + "license": "ISC", + "scripts": { + "build": "polkadot-dev-build-babel", + "check": "stylelint 'src/**/*.css' && eslint src && flow check", + "test": "jest --coverage" + }, + "dependencies": { + "@babel/runtime": "^7.0.0-beta.51", + "@polkadot/extrinsics": "^0.25.0", + "@polkadot/params": "^0.25.0", + "@polkadot/util": "^0.25.0", + "@polkadot/util-keyring": "^0.25.0", + "bn.js": "^4.11.8" + } +} diff --git a/packages/code-extrinsics/src/decode/length.ts b/packages/code-extrinsics/src/decode/length.ts new file mode 100644 index 000000000..711d3bb64 --- /dev/null +++ b/packages/code-extrinsics/src/decode/length.ts @@ -0,0 +1,13 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { UncheckedRaw } from '@polkadot/primitives/extrinsic'; + +import u8aToBn from '@polkadot/util/u8a/toBn'; + +export default function decodeLength (unchecked: Uint8Array): UncheckedRaw { + const length = u8aToBn(unchecked.subarray(0, 4), true).toNumber(); + + return unchecked.slice(4, length + 4); +} diff --git a/packages/code-extrinsics/src/encode/call.spec.js b/packages/code-extrinsics/src/encode/call.spec.js new file mode 100644 index 000000000..a278020c6 --- /dev/null +++ b/packages/code-extrinsics/src/encode/call.spec.js @@ -0,0 +1,52 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import testingPairs from '@polkadot/util-keyring/testingPairs'; + +import call from './call'; + +const keyring = testingPairs(); + +describe('call', () => { + it('encodes the call correctly (poc-1)', () => { + expect( + call( + keyring.one.publicKey(), + 1234, + new Uint8Array([0xab, 0xcd]), + 'poc-1' + ) + ).toEqual( + new Uint8Array([ + // key + 47, 140, 97, 41, 216, 22, 207, 81, 195, 116, 188, 127, 8, 195, 230, 62, 209, 86, 207, 120, 174, 251, 74, 101, 80, 217, 123, 135, 153, 121, 119, 238, + // nonce (u64) + 210, 4, 0, 0, 0, 0, 0, 0, + // data + 171, 205 + ]) + ); + }); + + it('encodes the call correctly (latest)', () => { + expect( + call( + keyring.one.publicKey(), + 1234, + new Uint8Array([0xab, 0xcd]), + 'latest' + ) + ).toEqual( + new Uint8Array([ + // key + 47, 140, 97, 41, 216, 22, 207, 81, 195, 116, 188, 127, 8, 195, 230, 62, 209, 86, 207, 120, 174, 251, 74, 101, 80, 217, 123, 135, 153, 121, 119, 238, + // nonce (u32) + 210, 4, 0, 0, + // data + 171, 205 + ]) + ); + }); +}); diff --git a/packages/code-extrinsics/src/encode/call.ts b/packages/code-extrinsics/src/encode/call.ts new file mode 100644 index 000000000..378c1e5bd --- /dev/null +++ b/packages/code-extrinsics/src/encode/call.ts @@ -0,0 +1,19 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; +import { EncodingVersions } from '@polkadot/params/types'; +import { ExtrinsicWithAccount, ExtrinsicWithIndex } from '../types'; + +import sizes from '@polkadot/params/sizes'; +import bnToU8a from '@polkadot/util/bn/toU8a'; +import u8aConcat from '@polkadot/util/u8a/concat'; + +export default function encodeCall (publicKey: Uint8Array, nonce: number | BN, data: ExtrinsicWithIndex, version: EncodingVersions): ExtrinsicWithAccount { + return u8aConcat( + publicKey, + bnToU8a(nonce, sizes.Index.get(version), true), + data + ); +} diff --git a/packages/code-extrinsics/src/encode/extrinsic.spec.js b/packages/code-extrinsics/src/encode/extrinsic.spec.js new file mode 100644 index 000000000..48804b44e --- /dev/null +++ b/packages/code-extrinsics/src/encode/extrinsic.spec.js @@ -0,0 +1,27 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import extrinsics from '@polkadot/extrinsics'; + +import extrinsic from './extrinsic'; + +describe('extrinsic', () => { + it('encodes extrinsic correctly', () => { + expect( + extrinsic( + extrinsics.timestamp.public.set, + [10101], + 'latest' + ) + ).toEqual( + new Uint8Array([ + // index + 3, 0, + // values + 117, 39, 0, 0, 0, 0, 0, 0 + ]) + ); + }); +}); diff --git a/packages/code-extrinsics/src/encode/extrinsic.ts b/packages/code-extrinsics/src/encode/extrinsic.ts new file mode 100644 index 000000000..29a24466a --- /dev/null +++ b/packages/code-extrinsics/src/encode/extrinsic.ts @@ -0,0 +1,17 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Extrinsics } from '@polkadot/extrinsics/types'; +import { EncodingVersions, SectionItem } from '@polkadot/params/types'; +import { ExtrinsicWithIndex } from '../types'; + +import encodeParams from '@polkadot/params/encode'; +import u8aConcat from '@polkadot/util/u8a/concat'; + +export default function encodeExtrinsic (extrinsic: SectionItem, values: Array, version: EncodingVersions): ExtrinsicWithIndex { + return u8aConcat( + extrinsic.index, + encodeParams(extrinsic.params, values, version) + ); +} diff --git a/packages/code-extrinsics/src/encode/index.spec.js b/packages/code-extrinsics/src/encode/index.spec.js new file mode 100644 index 000000000..a8aca17cf --- /dev/null +++ b/packages/code-extrinsics/src/encode/index.spec.js @@ -0,0 +1,34 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import extrinsics from '@polkadot/extrinsics'; +import testingPairs from '@polkadot/util-keyring/testingPairs'; + +import encode from './index'; + +const keyring = testingPairs(); + +describe('encode', () => { + it('encodes extrinsic correctly', () => { + expect( + encode(keyring.nobody.publicKey(), 1234)( + extrinsics.timestamp.public.set, + [10101], + 'latest' + ) + ).toEqual( + new Uint8Array([ + // publicKey + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // account nonce + 210, 4, 0, 0, + // extrinsic index + 3, 0, + // values + 117, 39, 0, 0, 0, 0, 0, 0 + ]) + ); + }); +}); diff --git a/packages/code-extrinsics/src/encode/index.ts b/packages/code-extrinsics/src/encode/index.ts new file mode 100644 index 000000000..17c7f63d8 --- /dev/null +++ b/packages/code-extrinsics/src/encode/index.ts @@ -0,0 +1,23 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; +import { Extrinsics } from '@polkadot/extrinsics/types'; +import { EncodingVersions, SectionItem } from '@polkadot/params/types'; +import { ExtrinsicWithAccount } from '../types'; + +import encodeCall from './call'; +import encodeExtrinsic from './extrinsic'; + +type Encoder = (extrinsic: SectionItem, values: Array, version: EncodingVersions) => ExtrinsicWithAccount; + +export default function encode (publicKey: Uint8Array, index: number | BN): Encoder { + return (extrinsic: SectionItem, values: Array, version: EncodingVersions): ExtrinsicWithAccount => + encodeCall( + publicKey, + index, + encodeExtrinsic(extrinsic, values, version), + version + ); +} diff --git a/packages/code-extrinsics/src/encode/length.ts b/packages/code-extrinsics/src/encode/length.ts new file mode 100644 index 000000000..89db07329 --- /dev/null +++ b/packages/code-extrinsics/src/encode/length.ts @@ -0,0 +1,15 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { UncheckedRaw } from '@polkadot/primitives/extrinsic'; + +import bnToU8a from '@polkadot/util/bn/toU8a'; +import u8aConcat from '@polkadot/util/u8a/concat'; + +export default function encodeLength (unchecked: UncheckedRaw): Uint8Array { + return u8aConcat( + bnToU8a(unchecked.length, 32, true), + unchecked + ); +} diff --git a/packages/code-extrinsics/src/encode/prefixes.ts b/packages/code-extrinsics/src/encode/prefixes.ts new file mode 100644 index 000000000..6621ebac5 --- /dev/null +++ b/packages/code-extrinsics/src/encode/prefixes.ts @@ -0,0 +1,25 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +// https://github.com/paritytech/polkadot/pull/195 +// 0xff, 32-byte account id +// 0xfe, 8-byte account index +// 0xfd, 4-byte account index +// 0xfc, 2-byte account index +// [0xf0...0xfb] (invalid, reserved for future use) +// [0x00...0xef] 1-byte account index (less than 0xf0) + +const bytes8 = new Uint8Array([0xfe]); +const bytes4 = new Uint8Array([0xfd]); +const bytes2 = new Uint8Array([0xfc]); +const none = new Uint8Array([]); +const publicKey = new Uint8Array([0xff]); + +export default { + bytes8, + bytes4, + bytes2, + none, + publicKey +}; diff --git a/packages/code-extrinsics/src/encode/unchecked.spec.js b/packages/code-extrinsics/src/encode/unchecked.spec.js new file mode 100644 index 000000000..81049099f --- /dev/null +++ b/packages/code-extrinsics/src/encode/unchecked.spec.js @@ -0,0 +1,115 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import extrinsics from '@polkadot/extrinsics'; +import hexToU8a from '@polkadot/util/hex/toU8a'; +import testingPairs from '@polkadot/util-keyring/testingPairs'; + +import encode from './unchecked'; + +const keyring = testingPairs(); + +describe('unchecked', () => { + it('encodes extrinsic correctly (nobody)', () => { + expect( + encode(keyring.nobody, 1234)( + extrinsics.timestamp.public.set, + [10101] + ) + ).toEqual( + new Uint8Array([ + 255, + // publicKey + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // account nonce + 210, 4, 0, 0, + // extrinsic index + 3, 0, + // values + 117, 39, 0, 0, 0, 0, 0, 0, + // signature + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ]) + ); + }); + + it('encodes extrinsic correctly (one)', () => { + expect( + encode(keyring.one, 258, 'poc-1')( + extrinsics.staking.public.transfer, + [keyring.two.publicKey(), 69] + ) + ).toEqual( + new Uint8Array([ + // publicKey + 47, 140, 97, 41, 216, 22, 207, 81, 195, 116, 188, 127, 8, 195, 230, 62, 209, 86, 207, 120, 174, 251, 74, 101, 80, 217, 123, 135, 153, 121, 119, 238, + // account nonce + 2, 1, 0, 0, 0, 0, 0, 0, + // extrinsic index + 2, 0, + // values + // (recipient) + 215, 90, 152, 1, 130, 177, 10, 183, 213, 75, 254, 211, 201, 100, 7, 58, 14, 225, 114, 243, 218, 166, 35, 37, 175, 2, 26, 104, 247, 7, 81, 26, + // (amount) + 69, 0, 0, 0, 0, 0, 0, 0, + // signature + 144, 233, 93, 195, 106, 86, 2, 230, 182, 5, 62, 128, 120, 148, 21, 128, 86, 5, 74, 15, 128, 100, 255, 179, 172, 13, 102, 206, 117, 208, 175, 107, 107, 77, 209, 126, 129, 51, 1, 198, 184, 202, 100, 240, 0, 118, 150, 188, 67, 10, 154, 84, 224, 103, 17, 151, 163, 45, 78, 249, 219, 169, 96, 2 + ]) + ); + }); + + it('encodes extrinsic correctly (one + latest)', () => { + expect( + encode(keyring.one, 258)( + extrinsics.staking.public.transfer, + [keyring.two.publicKey(), 69] + ) + ).toEqual( + new Uint8Array([ + 255, + // publicKey + 47, 140, 97, 41, 216, 22, 207, 81, 195, 116, 188, 127, 8, 195, 230, 62, 209, 86, 207, 120, 174, 251, 74, 101, 80, 217, 123, 135, 153, 121, 119, 238, + // account nonce + 2, 1, 0, 0, + // extrinsic index + 2, 0, + // values + // (recipient) + 255, + 215, 90, 152, 1, 130, 177, 10, 183, 213, 75, 254, 211, 201, 100, 7, 58, 14, 225, 114, 243, 218, 166, 35, 37, 175, 2, 26, 104, 247, 7, 81, 26, + // (amount) + 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // signature + 56, 1, 89, 195, 60, 171, 128, 242, 136, 64, 45, 43, 252, 199, 13, 115, 2, 76, 9, 19, 16, 80, 38, 164, 58, 229, 107, 225, 141, 107, 115, 176, 241, 242, 153, 177, 48, 92, 6, 61, 104, 112, 45, 223, 86, 198, 203, 78, 240, 223, 59, 190, 156, 116, 135, 188, 244, 219, 182, 58, 39, 140, 159, 11 + ]) + ); + }); + + it('encodes timetamp.set extrinsic correctly (actual values)', () => { + expect( + encode(keyring.nobody, 0)( + extrinsics.timestamp.public.set, + [0x5b13c37b] + ) + ).toEqual( + hexToU8a( + '0xff00000000000000000000000000000000000000000000000000000000000000000000000003007bc3135b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + ) + ); + }); + + it('encoded parachains.setHeads correctly (actual values)', () => { + expect( + encode(keyring.nobody, 0)( + extrinsics.parachains.public.setHeads, + [[]] + ) + ).toEqual( + hexToU8a( + '0xff00000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + ) + ); + }); +}); diff --git a/packages/code-extrinsics/src/encode/unchecked.ts b/packages/code-extrinsics/src/encode/unchecked.ts new file mode 100644 index 000000000..58d4fbad9 --- /dev/null +++ b/packages/code-extrinsics/src/encode/unchecked.ts @@ -0,0 +1,33 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; +import { Extrinsics } from '@polkadot/extrinsics/types'; +import { EncodingVersions, SectionItem } from '@polkadot/params/types'; +import { UncheckedRaw } from '@polkadot/primitives/extrinsic'; +import { KeyringPair } from '@polkadot/util-keyring/types'; + +import u8aConcat from '@polkadot/util/u8a/concat'; + +import encode from './index'; +import prefixes from './prefixes'; + +type Encoder = (extrinsic: SectionItem, values: Array) => UncheckedRaw; + +export default function unchecked (pair: KeyringPair, index: number | BN, version: EncodingVersions = 'latest'): Encoder { + const encoder = encode(pair.publicKey(), index); + + return (extrinsic: SectionItem, values: Array): UncheckedRaw => { + const message = encoder(extrinsic, values, version); + const signature = pair.sign(message); + + return u8aConcat( + version === 'poc-1' + ? prefixes.none + : prefixes.publicKey, + message, + signature + ); + }; +} diff --git a/packages/code-extrinsics/src/types.d.ts b/packages/code-extrinsics/src/types.d.ts new file mode 100644 index 000000000..1f68885f1 --- /dev/null +++ b/packages/code-extrinsics/src/types.d.ts @@ -0,0 +1,9 @@ +// Copyright 2017-2018 @polkadot/extrinsics-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +export type ExtrinsicWithAccount = Uint8Array; + +export type ExtrinsicWithIndex = Uint8Array; + +export type ExtrinsicUnchecked = Uint8Array; diff --git a/packages/code-primitives-builder/LICENSE b/packages/code-primitives-builder/LICENSE new file mode 100644 index 000000000..9808dc309 --- /dev/null +++ b/packages/code-primitives-builder/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017-2018 @polkadot/primitives-builder authors & contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/code-primitives-builder/README.md b/packages/code-primitives-builder/README.md new file mode 100644 index 000000000..30cc45e09 --- /dev/null +++ b/packages/code-primitives-builder/README.md @@ -0,0 +1,13 @@ +[![polkadotjs](https://img.shields.io/badge/polkadot-js-orange.svg?style=flat-square)](https://polkadot.js.org) +![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) +[![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) +[![npm](https://img.shields.io/npm/v/@polkadot/primitives-builder.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/primitives-builder) +[![travis](https://img.shields.io/travis/polkadot-js/types.svg?style=flat-square)](https://travis-ci.org/polkadot-js/types) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/types.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/types/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/types.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/types?branch=master) +[![dependency](https://david-dm.org/polkadot-js/types.svg?style=flat-square&path=packages/primitives-builder)](https://david-dm.org/polkadot-js/types?path=packages/primitives-builder) +[![devDependency](https://david-dm.org/polkadot-js/types/dev-status.svg?style=flat-square&path=packages/primitives-builder)](https://david-dm.org/polkadot-js/types?path=packages/primitives-builder#info=devDependencies) + +# @polkadot/primitives-builder + +Creating of primitive types. diff --git a/packages/code-primitives-builder/package.json b/packages/code-primitives-builder/package.json new file mode 100644 index 000000000..d3ed482ad --- /dev/null +++ b/packages/code-primitives-builder/package.json @@ -0,0 +1,47 @@ +{ + "name": "@polkadot/primitives-builder", + "version": "0.25.0", + "description": "Builder for primitives for Polkadot", + "main": "index.js", + "engines": { + "node": ">=6.4" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-js/types.git" + }, + "keywords": [ + "Polkadot" + ], + "author": "Jaco Greeff ", + "maintainers": [ + "Jaco Greeff " + ], + "contributors": [], + "license": "ISC", + "bugs": { + "url": "https://github.com/polkadot-js/types/issues" + }, + "homepage": "https://github.com/polkadot-js/types/tree/master/packages/primitives-builder#readme", + "scripts": { + "build": "polkadot-dev-build-babel", + "check": "eslint src && flow check", + "test": "echo \"Tests only available from root wrapper\"" + }, + "dependencies": { + "@babel/runtime": "^7.0.0-beta.51", + "@polkadot/extrinsics-codec": "^0.25.0", + "@polkadot/primitives": "^0.25.0", + "@polkadot/primitives-codec": "^0.25.0", + "@polkadot/trie-hash": "^0.25.0", + "@polkadot/util": "^0.25.0", + "@polkadot/util-crypto": "^0.25.0" + }, + "devDependencies": { + "@polkadot/util-keyring": "^0.25.0" + } +} diff --git a/packages/code-primitives-builder/src/block.spec.js b/packages/code-primitives-builder/src/block.spec.js new file mode 100644 index 000000000..485ca0c8b --- /dev/null +++ b/packages/code-primitives-builder/src/block.spec.js @@ -0,0 +1,82 @@ +// Copyright 2017-2018 @polkadot/primitives-builder authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; +import extrinsics from '@polkadot/extrinsics'; +import encodeUnchecked from '@polkadot/extrinsics-codec/encode/unchecked'; +import hexToU8a from '@polkadot/util/hex/toU8a'; +import testingPairs from '@polkadot/util-keyring/testingPairs'; + +import block from './block'; + +const keyring = testingPairs(); + +describe('block', () => { + it('creates a complete block from incomplete details', () => { + expect( + block({}) + ).toEqual({ + header: { + digest: { + logs: [] + }, + number: new BN(0), + parentHash: new Uint8Array(32), + stateRoot: new Uint8Array(32), + extrinsicsRoot: new Uint8Array([ + 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33 + ]) + }, + extrinsics: [] + }); + }); + + it('creates a valid block, with defaults submitted', () => { + const transactions = [ + encodeUnchecked(keyring.nobody, 0)( + extrinsics.timestamp.public.set, + [0x5b13c3a4] + ), + encodeUnchecked(keyring.nobody, 0)( + extrinsics.parachains.public.setHeads, + [[]] + ) + ]; + + expect( + block({ + header: { + number: 1, + parentHash: hexToU8a( + '0x4545454545454545454545454545454545454545454545454545454545454545' + ), + stateRoot: hexToU8a( + '0x2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db' + ) + }, + extrinsics: transactions + }) + ).toEqual({ + header: { + digest: { + logs: [] + }, + number: new BN(1), + parentHash: hexToU8a( + '0x4545454545454545454545454545454545454545454545454545454545454545' + ), + stateRoot: hexToU8a( + '0x2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db' + ), + extrinsicsRoot: new Uint8Array([ + 140, 102, 133, 98, 214, 123, 73, 173, 122, 252, 247, 48, 181, 86, 77, 188, 213, 161, 17, 19, 73, 96, 158, 181, 249, 69, 97, 15, 186, 12, 45, 157 + ]) + // hexToU8a( + // '0xab602f7974bbfb513f021f39777e2195094dc64a2c1b7c82a1781cb9fd4768a8' + // ) + }, + extrinsics: transactions + }); + }); +}); diff --git a/packages/code-primitives-builder/src/block.ts b/packages/code-primitives-builder/src/block.ts new file mode 100644 index 000000000..0e91d8145 --- /dev/null +++ b/packages/code-primitives-builder/src/block.ts @@ -0,0 +1,15 @@ +// Copyright 2017-2018 @polkadot/primitives-builder authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Block } from '@polkadot/primitives/block'; +import { BlockIncomplete } from './types'; + +import headerBuilder from './header'; + +export default function block ({ header = {}, extrinsics = [] }: BlockIncomplete): Block { + return { + header: headerBuilder(header, extrinsics), + extrinsics + }; +} diff --git a/packages/code-primitives-builder/src/extrinsic/rootRaw.spec.js b/packages/code-primitives-builder/src/extrinsic/rootRaw.spec.js new file mode 100644 index 000000000..82cefe368 --- /dev/null +++ b/packages/code-primitives-builder/src/extrinsic/rootRaw.spec.js @@ -0,0 +1,77 @@ +// Copyright 2017-2018 @polkadot/primitives-builder authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import extrinsics from '@polkadot/extrinsics'; +import encodeUnchecked from '@polkadot/extrinsics-codec/encode/unchecked'; +import hexToU8a from '@polkadot/util/hex/toU8a'; +import testingPairs from '@polkadot/util-keyring/testingPairs'; + +import root from './rootRaw'; + +const keyring = testingPairs(); + +describe('root', () => { + it('calculates the root correctly for no transactions', () => { + expect( + root() + ).toEqual( + hexToU8a( + '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421' + ) + ); + }); + + it('calculates the root correctly (actual)', () => { + expect( + root([ + encodeUnchecked(keyring.nobody, 0)( + extrinsics.timestamp.public.set, + [0x5b13c3a4] + ), + encodeUnchecked(keyring.nobody, 0)( + extrinsics.parachains.public.setHeads, + [[]] + ) + ]) + ).toEqual( + new Uint8Array([ + 140, 102, 133, 98, 214, 123, 73, 173, 122, 252, 247, 48, 181, 86, 77, 188, 213, 161, 17, 19, 73, 96, 158, 181, 249, 69, 97, 15, 186, 12, 45, 157 + ]) + // hexToU8a( + // '0xab602f7974bbfb513f021f39777e2195094dc64a2c1b7c82a1781cb9fd4768a8' + // ) + ); + }); + + // [ + // 168, 135, 224, 93, 140, 222, 226, 83, 13, 116, 138, 197, 164, 6, 48, 190, 101, 18, 221, 166, 40, 179, 158, 112, 133, 154, 215, 198, 177, 76, 212, 228, + // 1, 0, 0, 0, 0, 0, 0, 0, + // 159, 216, 180, 61, 159, 12, 131, 80, 22, 196, 220, 94, 6, 222, 68, 159, 97, 60, 16, 69, 163, 149, 125, 138, 175, 36, 30, 93, 235, 4, 1, 168, + // 245, 208, 141, 24, 250, 136, 158, 84, 67, 170, 59, 146, 17, 149, 62, 67, 254, 66, 126, 53, 20, 146, 252, 243, 137, 89, 224, 145, 252, 79, 109, 15, + // 0, 0, 0, 0, + // 2, 0, 0, 0, + // 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 188, 29, 21, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + + it('calculates the root correctly (actual encoded)', () => { + expect( + root([ + new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, + 188, 29, 21, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ]), + new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ]) + ]) + ).toEqual( + new Uint8Array([ + 245, 208, 141, 24, 250, 136, 158, 84, 67, 170, 59, 146, 17, 149, 62, 67, 254, 66, 126, 53, 20, 146, 252, 243, 137, 89, 224, 145, 252, 79, 109, 15 + ]) + ); + }); +}); diff --git a/packages/code-primitives-builder/src/extrinsic/rootRaw.ts b/packages/code-primitives-builder/src/extrinsic/rootRaw.ts new file mode 100644 index 000000000..0dc0dd728 --- /dev/null +++ b/packages/code-primitives-builder/src/extrinsic/rootRaw.ts @@ -0,0 +1,14 @@ +// Copyright 2017-2018 @polkadot/primitives-builder authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { UncheckedRaw } from '@polkadot/primitives/extrinsic'; + +import uncheckedLength from '@polkadot/extrinsics-codec/encode/length'; +import trieRootOrdered from '@polkadot/trie-hash/rootOrdered'; + +export default function extrinsicsRootRaw (extrinsics: Array = []): Uint8Array { + return trieRootOrdered( + extrinsics.map(uncheckedLength) + ); +} diff --git a/packages/code-primitives-builder/src/header.spec.js b/packages/code-primitives-builder/src/header.spec.js new file mode 100644 index 000000000..ddaedbfc7 --- /dev/null +++ b/packages/code-primitives-builder/src/header.spec.js @@ -0,0 +1,41 @@ +// Copyright 2017-2018 @polkadot/primitives-builder authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import txRoot from './extrinsic/rootRaw'; +import extrinsics from '@polkadot/extrinsics'; +import encodeUnchecked from '@polkadot/extrinsics-codec/encode/unchecked'; +import testingPairs from '@polkadot/util-keyring/testingPairs'; + +import header from './header'; + +const keyring = testingPairs(); + +describe('header', () => { + it('applies the all transactions (no timestamp)', () => { + expect( + header({}).extrinsicsRoot + ).toEqual( + txRoot([]) + ); + }); + + it('applies the all transactions (extrinsicsRoot)', () => { + const transactions = [ + encodeUnchecked(keyring.nobody, 0)( + extrinsics.timestamp.public.set, + [54321] + ), + encodeUnchecked(keyring.one, 0)( + extrinsics.timestamp.public.set, + [12345] + ) + ]; + + expect( + header({}, transactions).extrinsicsRoot + ).toEqual( + txRoot(transactions) + ); + }); +}); diff --git a/packages/code-primitives-builder/src/header.ts b/packages/code-primitives-builder/src/header.ts new file mode 100644 index 000000000..a645b844a --- /dev/null +++ b/packages/code-primitives-builder/src/header.ts @@ -0,0 +1,25 @@ +// Copyright 2017-2018 @polkadot/primitives-builder authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Header } from '@polkadot/primitives/header'; +import { UncheckedRaw } from '@polkadot/primitives/extrinsic'; +import { HeaderIncomplete } from './types'; + +import bnToBn from '@polkadot/util/bn/toBn'; + +import extrinsicsRawRoot from './extrinsic/rootRaw'; + +export default function header ({ digest: { logs = [] } = {}, extrinsicsRoot, number, parentHash = new Uint8Array(32), stateRoot = new Uint8Array(32) }: HeaderIncomplete, extrinsics?: Array): Header { + return { + digest: { + logs + }, + extrinsicsRoot: extrinsics + ? extrinsicsRawRoot(extrinsics) + : (extrinsicsRoot || extrinsicsRawRoot([])), + number: bnToBn(number || 0), + parentHash, + stateRoot + }; +} diff --git a/packages/code-primitives-builder/src/types.d.ts b/packages/code-primitives-builder/src/types.d.ts new file mode 100644 index 000000000..9b85b8874 --- /dev/null +++ b/packages/code-primitives-builder/src/types.d.ts @@ -0,0 +1,22 @@ +// Copyright 2017-2018 @polkadot/primitives-builder authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { BlockNumber, Hash, HeaderHash } from '@polkadot/primitives/base'; +import { Digest$Log } from '@polkadot/primitives/digest'; +import { UncheckedRaw } from '@polkadot/primitives/extrinsic'; + +export type HeaderIncomplete = { + digest?: { + logs?: Array + }, + extrinsicsRoot?: Hash, + parentHash?: HeaderHash, + number?: BlockNumber | number, + stateRoot?: Hash +}; + +export type BlockIncomplete = { + header?: HeaderIncomplete, + extrinsics?: Array +}; diff --git a/packages/code-primitives-json/LICENSE b/packages/code-primitives-json/LICENSE new file mode 100644 index 000000000..751e34488 --- /dev/null +++ b/packages/code-primitives-json/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017-2018 @polkadot/primitives-json authors & contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/code-primitives-json/README.md b/packages/code-primitives-json/README.md new file mode 100644 index 000000000..3e4a41620 --- /dev/null +++ b/packages/code-primitives-json/README.md @@ -0,0 +1,33 @@ +[![polkadotjs](https://img.shields.io/badge/polkadot-js-orange.svg?style=flat-square)](https://polkadot.js.org) +![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) +[![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) +[![npm](https://img.shields.io/npm/v/@polkadot/primitives-json.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/primitives-json) +[![travis](https://img.shields.io/travis/polkadot-js/types.svg?style=flat-square)](https://travis-ci.org/polkadot-js/types) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/types.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/types/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/types.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/types?branch=master) +[![dependency](https://david-dm.org/polkadot-js/types.svg?style=flat-square&path=packages/primitives-json)](https://david-dm.org/polkadot-js/types?path=packages/primitives-json) +[![devDependency](https://david-dm.org/polkadot-js/types/dev-status.svg?style=flat-square&path=packages/primitives-json)](https://david-dm.org/polkadot-js/types?path=packages/primitives-json#info=devDependencies) + +# @polkadot/primitives-json + +Conversion of Polkadot types to and from a structure with Json-only primitives, ready for serialisation. As such, it does not stringify itself, rather converts from complex classes to the correct Json reprsentation. + +## Usage + +Installation - + +``` +npm install --save @polkadot/primitives-json +``` + +Usage - + +```js +const { parachainIdDecode, parachainIdEncode } from '@polkadot/primitives-json'); + +parachainIdDecode( // step 3 - BN `0x123456` + parachainIdEncode( // step 1 - string `'0x123456'` + new BN('0x123456') // step 0 - BN `0x123456` + ) +); +``` diff --git a/packages/code-primitives-json/package.json b/packages/code-primitives-json/package.json new file mode 100644 index 000000000..213fc4a8a --- /dev/null +++ b/packages/code-primitives-json/package.json @@ -0,0 +1,41 @@ +{ + "name": "@polkadot/primitives-json", + "version": "0.25.0", + "description": "Conversion utilities for primitives for JSON representation", + "main": "index.js", + "engines": { + "node": ">=6.4" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-js/types.git" + }, + "keywords": [ + "Polkadot" + ], + "author": "Jaco Greeff ", + "maintainers": [ + "Jaco Greeff " + ], + "contributors": [], + "license": "ISC", + "bugs": { + "url": "https://github.com/polkadot-js/types/issues" + }, + "homepage": "https://github.com/polkadot-js/types/tree/master/packages/primitives-json#readme", + "scripts": { + "build": "polkadot-dev-build-babel", + "check": "eslint src && flow check", + "test": "echo \"Tests only available from root wrapper\"" + }, + "dependencies": { + "@babel/runtime": "^7.0.0-beta.51", + "@polkadot/primitives": "^0.25.0", + "@polkadot/primitives-builder": "^0.25.0", + "@polkadot/util": "^0.25.0" + } +} diff --git a/packages/code-primitives-json/src/accountId/decode.ts b/packages/code-primitives-json/src/accountId/decode.ts new file mode 100644 index 000000000..e4aa0f187 --- /dev/null +++ b/packages/code-primitives-json/src/accountId/decode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { AccountId } from '@polkadot/primitives/base'; +import { JsonAccountId } from '../types'; + +import hashDecode from '../hash/decode'; + +export default function accountIdDecode (value: JsonAccountId): AccountId { + return hashDecode(value, 160); +} diff --git a/packages/code-primitives-json/src/accountId/encode.ts b/packages/code-primitives-json/src/accountId/encode.ts new file mode 100644 index 000000000..ebe0e3848 --- /dev/null +++ b/packages/code-primitives-json/src/accountId/encode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { AccountId } from '@polkadot/primitives/base'; +import { JsonAccountId } from '../types'; + +import hashEncode from '../hash/encode'; + +export default function accountIdEncode (value: AccountId): JsonAccountId { + return hashEncode(value, 160); +} diff --git a/packages/code-primitives-json/src/accountId/index.ts b/packages/code-primitives-json/src/accountId/index.ts new file mode 100644 index 000000000..ca8513429 --- /dev/null +++ b/packages/code-primitives-json/src/accountId/index.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import accountIdDecode from './decode'; +import accountIdEncode from './encode'; + +export { + accountIdDecode, + accountIdEncode +}; diff --git a/packages/code-primitives-json/src/bn/decode.spec.js b/packages/code-primitives-json/src/bn/decode.spec.js new file mode 100644 index 000000000..479276ec4 --- /dev/null +++ b/packages/code-primitives-json/src/bn/decode.spec.js @@ -0,0 +1,25 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { bnDecode } from './index'; + +describe('bnDecode', () => { + it('converts hex to a BN value', () => { + expect( + bnDecode('0x1234').toNumber() + ).toEqual(0x1234); + }); + + it('converts with the required bitLength', () => { + expect( + bnDecode('0x1234', 8).toNumber() + ).toEqual(0x34); + }); + + it('converts a non-hex/numeric value', () => { + expect( + bnDecode(10).toNumber() + ).toEqual(10); + }); +}); diff --git a/packages/code-primitives-json/src/bn/decode.ts b/packages/code-primitives-json/src/bn/decode.ts new file mode 100644 index 000000000..7322edf0d --- /dev/null +++ b/packages/code-primitives-json/src/bn/decode.ts @@ -0,0 +1,20 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { JsonBnType } from '../types'; + +import BN from 'bn.js'; +import hexFixLength from '@polkadot/util/hex/fixLength'; +import isHex from '@polkadot/util/is/hex'; +import hexToBn from '@polkadot/util/hex/toBn'; + +export default function bnDecode (value: JsonBnType, bitLength: number = -1): BN { + if (isHex(value)) { + return hexToBn( + hexFixLength(value, bitLength) + ); + } + + return new BN(value); +} diff --git a/packages/code-primitives-json/src/bn/encode.spec.js b/packages/code-primitives-json/src/bn/encode.spec.js new file mode 100644 index 000000000..7f44ef921 --- /dev/null +++ b/packages/code-primitives-json/src/bn/encode.spec.js @@ -0,0 +1,21 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; + +import { bnEncode } from './index'; + +describe('bnEncode', () => { + it('converts to a hex string', () => { + expect( + bnEncode(new BN(0x1234)) + ).toEqual('0x1234'); + }); + + it('converts to a hex with the provided bitLength', () => { + expect( + bnEncode(new BN(0x1234), 8) + ).toEqual('0x34'); + }); +}); diff --git a/packages/code-primitives-json/src/bn/encode.ts b/packages/code-primitives-json/src/bn/encode.ts new file mode 100644 index 000000000..b24a05901 --- /dev/null +++ b/packages/code-primitives-json/src/bn/encode.ts @@ -0,0 +1,16 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; +import { JsonBnType } from '../types'; + +import hexFixLength from '@polkadot/util/hex/fixLength'; +import bnToHex from '@polkadot/util/bn/toHex'; + +export default function bnEncode (value: BN | number, bitLength: number = -1): JsonBnType { + return hexFixLength( + bnToHex(value), + bitLength + ); +} diff --git a/packages/code-primitives-json/src/bn/index.ts b/packages/code-primitives-json/src/bn/index.ts new file mode 100644 index 000000000..e77bbf496 --- /dev/null +++ b/packages/code-primitives-json/src/bn/index.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import bnDecode from './decode'; +import bnEncode from './encode'; + +export { + bnDecode, + bnEncode +}; diff --git a/packages/code-primitives-json/src/bytes/decode.spec.js b/packages/code-primitives-json/src/bytes/decode.spec.js new file mode 100644 index 000000000..fb98a427d --- /dev/null +++ b/packages/code-primitives-json/src/bytes/decode.spec.js @@ -0,0 +1,13 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { bytesDecode } from './index'; + +describe('bytesDecode', () => { + it('creates the correct bytes U8a', () => { + expect( + bytesDecode('0x0012345600') + ).toEqual(new Uint8Array([0x00, 0x12, 0x34, 0x56, 0x00])); + }); +}); diff --git a/packages/code-primitives-json/src/bytes/decode.ts b/packages/code-primitives-json/src/bytes/decode.ts new file mode 100644 index 000000000..0b8e2a350 --- /dev/null +++ b/packages/code-primitives-json/src/bytes/decode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Bytes } from '@polkadot/primitives/base'; +import { JsonBytes } from '../types'; + +import hexToU8a from '@polkadot/util/hex/toU8a'; + +export default function bytesDecode (value: JsonBytes): Bytes { + return hexToU8a(value); +} diff --git a/packages/code-primitives-json/src/bytes/encode.spec.js b/packages/code-primitives-json/src/bytes/encode.spec.js new file mode 100644 index 000000000..7f4ab3273 --- /dev/null +++ b/packages/code-primitives-json/src/bytes/encode.spec.js @@ -0,0 +1,13 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { bytesEncode } from './index'; + +describe('bytesEncode', () => { + it('creates the correct bytes U8a', () => { + expect( + bytesEncode(new Uint8Array([0x00, 0x12, 0x34, 0x56, 0x00])) + ).toEqual('0x0012345600'); + }); +}); diff --git a/packages/code-primitives-json/src/bytes/encode.ts b/packages/code-primitives-json/src/bytes/encode.ts new file mode 100644 index 000000000..7c8c3cc18 --- /dev/null +++ b/packages/code-primitives-json/src/bytes/encode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Bytes } from '@polkadot/primitives/base'; +import { JsonBytes } from '../types'; + +import u8aToHex from '@polkadot/util/u8a/toHex'; + +export default function bytesEncode (value: Bytes): JsonBytes { + return u8aToHex(value); +} diff --git a/packages/code-primitives-json/src/bytes/index.ts b/packages/code-primitives-json/src/bytes/index.ts new file mode 100644 index 000000000..bac81b8b3 --- /dev/null +++ b/packages/code-primitives-json/src/bytes/index.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import bytesDecode from './decode'; +import bytesEncode from './encode'; + +export { + bytesDecode, + bytesEncode +}; diff --git a/packages/code-primitives-json/src/hash/decode.spec.js b/packages/code-primitives-json/src/hash/decode.spec.js new file mode 100644 index 000000000..716d5c306 --- /dev/null +++ b/packages/code-primitives-json/src/hash/decode.spec.js @@ -0,0 +1,19 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { hashDecode } from './index'; + +describe('hashDecode', () => { + it('returns the hash when no length specified', () => { + expect( + hashDecode('0x123456787890abcdef') + ).toEqual(new Uint8Array([0x12, 0x34, 0x56, 0x78, 0x78, 0x90, 0xab, 0xcd, 0xef])); + }); + + it('converts to the required length as specified', () => { + expect( + hashDecode('0x123456787890abcdef', 32) + ).toEqual(new Uint8Array([0x12, 0x34, 0x56, 0x78])); + }); +}); diff --git a/packages/code-primitives-json/src/hash/decode.ts b/packages/code-primitives-json/src/hash/decode.ts new file mode 100644 index 000000000..a9a908396 --- /dev/null +++ b/packages/code-primitives-json/src/hash/decode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Hash } from '@polkadot/primitives/base'; +import { JsonHash } from '../types'; + +import hexToU8a from '@polkadot/util/hex/toU8a'; + +export default function hashDecode (value: JsonHash, bitLength: number = -1): Hash { + return hexToU8a(value, bitLength); +} diff --git a/packages/code-primitives-json/src/hash/encode.spec.js b/packages/code-primitives-json/src/hash/encode.spec.js new file mode 100644 index 000000000..30650c74f --- /dev/null +++ b/packages/code-primitives-json/src/hash/encode.spec.js @@ -0,0 +1,21 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { hashEncode } from './index'; + +describe('hashEncode', () => { + it('returns the hash when no length specified', () => { + expect( + hashEncode( + new Uint8Array([0x12, 0x34, 0x56, 0x78, 0x78, 0x90, 0xab, 0xcd, 0xef]) + ) + ).toEqual('0x123456787890abcdef'); + }); + + it('converts to the required length as specified', () => { + expect( + hashEncode(new Uint8Array([0x34, 0x56, 0x78, 0x78, 0x90, 0xab, 0xcd, 0xef]), 64) + ).toEqual('0x3456787890abcdef'); + }); +}); diff --git a/packages/code-primitives-json/src/hash/encode.ts b/packages/code-primitives-json/src/hash/encode.ts new file mode 100644 index 000000000..a18e8f6fe --- /dev/null +++ b/packages/code-primitives-json/src/hash/encode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Hash } from '@polkadot/primitives/base'; +import { JsonHash } from '../types'; + +import u8aToHex from '@polkadot/util/u8a/toHex'; + +export default function hashEncode (value: Hash, bitLength: number = -1): JsonHash { + return u8aToHex(value); +} diff --git a/packages/code-primitives-json/src/hash/index.ts b/packages/code-primitives-json/src/hash/index.ts new file mode 100644 index 000000000..b5bd262d0 --- /dev/null +++ b/packages/code-primitives-json/src/hash/index.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import hashDecode from './decode'; +import hashEncode from './encode'; + +export { + hashDecode, + hashEncode +}; diff --git a/packages/code-primitives-json/src/header/decode.spec.js b/packages/code-primitives-json/src/header/decode.spec.js new file mode 100644 index 000000000..9f734ee53 --- /dev/null +++ b/packages/code-primitives-json/src/header/decode.spec.js @@ -0,0 +1,38 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; + +import { headerDecode } from './index'; + +describe('headerDecode', () => { + it('creates the correct structure', () => { + expect( + JSON.stringify( + headerDecode({ + digest: { + logs: ['0x5678', '0x789a'] + }, + extrinsicsRoot: '0xabcd', + number: '0x1234', + parentHash: '0x1234', + stateRoot: '0x5678' + }) + ) + ).toEqual( + JSON.stringify({ + digest: { + logs: [ + new Uint8Array([0x56, 0x78]), + new Uint8Array([0x78, 0x9a]) + ] + }, + extrinsicsRoot: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xab, 0xcd]), + number: new BN(0x1234), + parentHash: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x12, 0x34]), + stateRoot: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x56, 0x78]) + }) + ); + }); +}); diff --git a/packages/code-primitives-json/src/header/decode.ts b/packages/code-primitives-json/src/header/decode.ts new file mode 100644 index 000000000..613fb636c --- /dev/null +++ b/packages/code-primitives-json/src/header/decode.ts @@ -0,0 +1,24 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Header } from '@polkadot/primitives/header'; +import { JsonHeader } from '../types'; + +import headerBuilder from '@polkadot/primitives-builder/header'; + +import hashDecode from '../hash/decode'; +import bnDecode from '../bn/decode'; +import bytesDecode from '../bytes/decode'; + +export default function headerDecode ({ digest, extrinsicsRoot, number, parentHash, stateRoot }: JsonHeader): Header { + return headerBuilder({ + digest: { + logs: digest.logs.map(bytesDecode) + }, + extrinsicsRoot: hashDecode(extrinsicsRoot, 256), + number: bnDecode(number, 64), + parentHash: hashDecode(parentHash, 256), + stateRoot: hashDecode(stateRoot, 256) + }); +} diff --git a/packages/code-primitives-json/src/header/encode.spec.js b/packages/code-primitives-json/src/header/encode.spec.js new file mode 100644 index 000000000..8cfb44908 --- /dev/null +++ b/packages/code-primitives-json/src/header/encode.spec.js @@ -0,0 +1,38 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; + +import { headerEncode } from './index'; + +describe('headerEncode', () => { + it('creates the correct structure', () => { + expect( + JSON.stringify( + headerEncode({ + digest: { + logs: [ + new Uint8Array([0x56, 0x78]), + new Uint8Array([0x78, 0x9a]) + ] + }, + extrinsicsRoot: new Uint8Array([0xab, 0xcd]), + number: new BN(0x1234), + parentHash: new Uint8Array([0x12, 0x34]), + stateRoot: new Uint8Array([0x56, 0x78]) + }) + ) + ).toEqual( + JSON.stringify({ + digest: { + logs: ['0x5678', '0x789a'] + }, + extrinsicsRoot: '0xabcd', + number: '0x1234', + parentHash: '0x1234', + stateRoot: '0x5678' + }) + ); + }); +}); diff --git a/packages/code-primitives-json/src/header/encode.ts b/packages/code-primitives-json/src/header/encode.ts new file mode 100644 index 000000000..eca0eb571 --- /dev/null +++ b/packages/code-primitives-json/src/header/encode.ts @@ -0,0 +1,22 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Header } from '@polkadot/primitives/header'; +import { JsonHeader } from '../types'; + +import bnEncode from '../bn/encode'; +import bytesEncode from '../bytes/encode'; +import hashEncode from '../hash/encode'; + +export default function headerEncode ({ parentHash, number, stateRoot, extrinsicsRoot, digest }: Header): JsonHeader { + return { + digest: { + logs: digest.logs.map(bytesEncode) + }, + extrinsicsRoot: hashEncode(extrinsicsRoot, 256), + number: bnEncode(number, 64), + parentHash: hashEncode(parentHash, 256), + stateRoot: hashEncode(stateRoot, 256) + }; +} diff --git a/packages/code-primitives-json/src/header/index.ts b/packages/code-primitives-json/src/header/index.ts new file mode 100644 index 000000000..39391f341 --- /dev/null +++ b/packages/code-primitives-json/src/header/index.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import headerDecode from './decode'; +import headerEncode from './encode'; + +export { + headerDecode, + headerEncode +}; diff --git a/packages/code-primitives-json/src/index.ts b/packages/code-primitives-json/src/index.ts new file mode 100644 index 000000000..0dfdd269e --- /dev/null +++ b/packages/code-primitives-json/src/index.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +export * from './accountId'; +export * from './header'; +export * from './bn'; +export * from './bytes'; +export * from './hash'; +export * from './objectId'; +export * from './parachainId'; +export * from './signature'; diff --git a/packages/code-primitives-json/src/objectId/decode.ts b/packages/code-primitives-json/src/objectId/decode.ts new file mode 100644 index 000000000..d87eb8ed1 --- /dev/null +++ b/packages/code-primitives-json/src/objectId/decode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { ObjectId } from '@polkadot/primitives/base'; +import { JsonObjectId } from '../types'; + +import bnDecode from '../bn/decode'; + +export default function objectIdDecode (value: JsonObjectId): ObjectId { + return bnDecode(value, 64); +} diff --git a/packages/code-primitives-json/src/objectId/encode.ts b/packages/code-primitives-json/src/objectId/encode.ts new file mode 100644 index 000000000..e960c34a6 --- /dev/null +++ b/packages/code-primitives-json/src/objectId/encode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { ObjectId } from '@polkadot/primitives/base'; +import { JsonObjectId } from '../types'; + +import bnEncode from '../bn/encode'; + +export default function objectIdEncode (value: ObjectId): JsonObjectId { + return bnEncode(value, 64); +} diff --git a/packages/code-primitives-json/src/objectId/index.ts b/packages/code-primitives-json/src/objectId/index.ts new file mode 100644 index 000000000..3e8342757 --- /dev/null +++ b/packages/code-primitives-json/src/objectId/index.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import objectIdDecode from './decode'; +import objectIdEncode from './encode'; + +export { + objectIdDecode, + objectIdEncode +}; diff --git a/packages/code-primitives-json/src/parachainId/decode.ts b/packages/code-primitives-json/src/parachainId/decode.ts new file mode 100644 index 000000000..ddd8386b3 --- /dev/null +++ b/packages/code-primitives-json/src/parachainId/decode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { ParaChainId } from '@polkadot/primitives/base'; +import { JsonParaChainId } from '../types'; + +import bnDecode from '../bn/decode'; + +export default function parachainIdDecode (value: JsonParaChainId): ParaChainId { + return bnDecode(value, 64); +} diff --git a/packages/code-primitives-json/src/parachainId/encode.ts b/packages/code-primitives-json/src/parachainId/encode.ts new file mode 100644 index 000000000..cc30a8483 --- /dev/null +++ b/packages/code-primitives-json/src/parachainId/encode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { ParaChainId } from '@polkadot/primitives/base'; +import { JsonParaChainId } from '../types'; + +import bnEncode from '../bn/encode'; + +export default function parachainIdEncode (value: ParaChainId): JsonParaChainId { + return bnEncode(value, 64); +} diff --git a/packages/code-primitives-json/src/parachainId/index.ts b/packages/code-primitives-json/src/parachainId/index.ts new file mode 100644 index 000000000..0924d2c4a --- /dev/null +++ b/packages/code-primitives-json/src/parachainId/index.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import parachainIdDecode from './decode'; +import parachainIdEncode from './encode'; + +export { + parachainIdDecode, + parachainIdEncode +}; diff --git a/packages/code-primitives-json/src/signature/decode.ts b/packages/code-primitives-json/src/signature/decode.ts new file mode 100644 index 000000000..8b715a84d --- /dev/null +++ b/packages/code-primitives-json/src/signature/decode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Signature } from '@polkadot/primitives/base'; +import { JsonSignature } from '../types'; + +import hashDecode from '../hash/decode'; + +export default function signatureDecode (value: JsonSignature): Signature { + return hashDecode(value); +} diff --git a/packages/code-primitives-json/src/signature/encode.ts b/packages/code-primitives-json/src/signature/encode.ts new file mode 100644 index 000000000..3ba088f16 --- /dev/null +++ b/packages/code-primitives-json/src/signature/encode.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Signature } from '@polkadot/primitives/base'; +import { JsonSignature } from '../types'; + +import hashEncode from '../hash/encode'; + +export default function signatureEncode (value: Signature): JsonSignature { + return hashEncode(value); +} diff --git a/packages/code-primitives-json/src/signature/index.ts b/packages/code-primitives-json/src/signature/index.ts new file mode 100644 index 000000000..980e03d7d --- /dev/null +++ b/packages/code-primitives-json/src/signature/index.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import signatureDecode from './decode'; +import signatureEncode from './encode'; + +export { + signatureDecode, + signatureEncode +}; diff --git a/packages/code-primitives-json/src/types.d.ts b/packages/code-primitives-json/src/types.d.ts new file mode 100644 index 000000000..264c20da6 --- /dev/null +++ b/packages/code-primitives-json/src/types.d.ts @@ -0,0 +1,51 @@ +// Copyright 2017-2018 @polkadot/primitives-json authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +export type JsonBnType = string; +export type JsonHash = string; + +export type JsonBytes = string; +export type JsonH160 = JsonHash; +export type JsonH256 = JsonHash; +export type JsonH512 = JsonHash; +export type JsonHeaderHash = JsonH256; +export type JsonU64 = JsonBnType; +export type JsonU256 = JsonBnType; + +export type JsonAccountId = JsonHash; +export type JsonAuthorityId = JsonHash; +export type JsonBlockNumber = JsonU64; +export type JsonObjectId = JsonU64; +export type JsonParaChainId = JsonU64; +export type JsonSignature = JsonHash; + +export type JsonTransaction = { + from: JsonAuthorityId, + to: JsonAuthorityId, + amount: JsonBnType, + nonce: JsonBnType +} + +export type JsonUnchecked = { + tx: JsonTransaction, + signature: JsonH512 +} + +export type JsonDigest = { + logs: Array +}; + +export type JsonHeader = { + parentHash: JsonHeaderHash, + number: JsonBlockNumber, + stateRoot: JsonHash, + extrinsicsRoot: JsonHash, + digest: JsonDigest +}; + +export type JsonBlock = { + header: JsonHeader, + timestamp: JsonU64, + transactions: Array +}; diff --git a/packages/code-primitives/LICENSE b/packages/code-primitives/LICENSE new file mode 100644 index 000000000..5df1aa63b --- /dev/null +++ b/packages/code-primitives/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017-2018 @polkadot/primitives-codec authors & contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/code-primitives/README.md b/packages/code-primitives/README.md new file mode 100644 index 000000000..b2a337a4f --- /dev/null +++ b/packages/code-primitives/README.md @@ -0,0 +1,13 @@ +[![polkadotjs](https://img.shields.io/badge/polkadot-js-orange.svg?style=flat-square)](https://polkadot.js.org) +![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) +[![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) +[![npm](https://img.shields.io/npm/v/@polkadot/primitives-codec.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/primitives-codec) +[![travis](https://img.shields.io/travis/polkadot-js/types.svg?style=flat-square)](https://travis-ci.org/polkadot-js/types) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/types.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/types/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/types.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/types?branch=master) +[![dependency](https://david-dm.org/polkadot-js/types.svg?style=flat-square&path=packages/primitives-codec)](https://david-dm.org/polkadot-js/types?path=packages/primitives-codec) +[![devDependency](https://david-dm.org/polkadot-js/types/dev-status.svg?style=flat-square&path=packages/primitives-codec)](https://david-dm.org/polkadot-js/types?path=packages/primitives-codec#info=devDependencies) + +# @polkadot/primitives-codec + +Conversion of Polkadot types into `Uint8Array` values ready for inputs into the runtime. diff --git a/packages/code-primitives/package.json b/packages/code-primitives/package.json new file mode 100644 index 000000000..aaf5f4fbe --- /dev/null +++ b/packages/code-primitives/package.json @@ -0,0 +1,43 @@ +{ + "name": "@polkadot/primitives-codec", + "version": "0.25.0", + "description": "Encoding for primitives as runtime execution inputs", + "main": "index.js", + "engines": { + "node": ">=6.4" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-js/types.git" + }, + "keywords": [ + "Polkadot" + ], + "author": "Jaco Greeff ", + "maintainers": [ + "Jaco Greeff " + ], + "contributors": [], + "license": "ISC", + "bugs": { + "url": "https://github.com/polkadot-js/types/issues" + }, + "homepage": "https://github.com/polkadot-js/types/tree/master/packages/primitives-codec#readme", + "scripts": { + "build": "polkadot-dev-build-babel", + "check": "eslint src && flow check", + "test": "echo \"Tests only available from root wrapper\"" + }, + "dependencies": { + "@babel/runtime": "^7.0.0-beta.51", + "@polkadot/primitives": "^0.25.0", + "@polkadot/primitives-builder": "^0.25.0", + "@polkadot/util": "^0.25.0", + "@polkadot/util-crypto": "^0.25.0", + "@polkadot/util-keyring": "^0.25.0" + } +} diff --git a/packages/code-primitives/src/block/decodeRaw.spec.js b/packages/code-primitives/src/block/decodeRaw.spec.js new file mode 100644 index 000000000..c1f131806 --- /dev/null +++ b/packages/code-primitives/src/block/decodeRaw.spec.js @@ -0,0 +1,54 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import extrinsics from '@polkadot/extrinsics'; +import encodeUnchecked from '@polkadot/extrinsics-codec/encode/unchecked'; +import hexToU8a from '@polkadot/util/hex/toU8a'; +import testingPairs from '@polkadot/util-keyring/testingPairs'; + +import decode from './decodeRaw'; + +const keyring = testingPairs(); + +describe('decodeRaw', () => { + it('encodes the block properly', () => { + expect( + decode( + hexToU8a( + '0x' + + // parent_hash + '0900000000000000000000000000000000000000000000000000000000000009' + + // number + '4300000000000000' + + // state_root + '0800000000000000000000000000000000000000000000000000000000000008' + + // transaction_root + '0700000000000000000000000000000000000000000000000000000000000007' + + // digest + '02000000' + + '0100000001' + + '0100000002' + + // transactions + '01000000' + + '6f000000' + + // prefix + 'ff' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '00000000' + + '0300' + + '7527000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + ) + ) + ).toMatchObject({ + extrinsics: [ + encodeUnchecked(keyring.nobody, 0)( + extrinsics.timestamp.public.set, + [10101] + ) + ] + }); + }); +}); diff --git a/packages/code-primitives/src/block/decodeRaw.ts b/packages/code-primitives/src/block/decodeRaw.ts new file mode 100644 index 000000000..0fc6aa2e9 --- /dev/null +++ b/packages/code-primitives/src/block/decodeRaw.ts @@ -0,0 +1,39 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; + +import decodeExtrinsic from '@polkadot/extrinsics-codec/decode/length'; +import u8aToBn from '@polkadot/util/u8a/toBn'; + +import decodeHeader from '../header/decodeRaw'; + +type RawData = { + body: Uint8Array, + extrinsics: Array, + header: Uint8Array, + number: BN +}; + +export default function decodeRaw (u8a: Uint8Array): RawData { + const { body, header, number } = decodeHeader(u8a); + const length = u8aToBn(body.subarray(0, 4), true).toNumber(); + const extrinsics = []; + + for (let index = 0, offset = 4; index < length; index++) { + const extrinsic = decodeExtrinsic( + body.subarray(offset) + ); + + offset += extrinsic.length + 4; + extrinsics.push(extrinsic); + } + + return { + body, + extrinsics, + header, + number + }; +} diff --git a/packages/code-primitives/src/block/encode.spec.js b/packages/code-primitives/src/block/encode.spec.js new file mode 100644 index 000000000..48b16631e --- /dev/null +++ b/packages/code-primitives/src/block/encode.spec.js @@ -0,0 +1,46 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import extrinsics from '@polkadot/extrinsics'; +import encodeUnchecked from '@polkadot/extrinsics-codec/encode/unchecked'; +import blockBuilder from '@polkadot/primitives-builder/block'; +import hexToU8a from '@polkadot/util/hex/toU8a'; +import testingPairs from '@polkadot/util-keyring/testingPairs'; + +import { encodeBlock } from './index'; + +const keyring = testingPairs(); + +describe('encodeBlock', () => { + it('encodes a block correctly (actual values)', () => { + expect( + encodeBlock( + blockBuilder({ + header: { + number: 9, + parentHash: hexToU8a('0x737d699e4e42f78dc2fb098f01bb85389f2c7f0a77bb41918adac6bfa5b3ee46'), + stateRoot: hexToU8a('0xf707774183723f201b875024069f30e7089b7f83c3c3cdc534b10d15fca91262') + }, + extrinsics: [ + encodeUnchecked(keyring.nobody, 0)( + extrinsics.timestamp.public.set, + [0x5b13c3a4] + ), + encodeUnchecked(keyring.nobody, 0)( + extrinsics.parachains.public.setHeads, + [[]] + ) + ] + }) + ) + ).toEqual( + new Uint8Array([ + 115, 125, 105, 158, 78, 66, 247, 141, 194, 251, 9, 143, 1, 187, 133, 56, 159, 44, 127, 10, 119, 187, 65, 145, 138, 218, 198, 191, 165, 179, 238, 70, 9, 0, 0, 0, 0, 0, 0, 0, 247, 7, 119, 65, 131, 114, 63, 32, 27, 135, 80, 36, 6, 159, 48, 231, 8, 155, 127, 131, 195, 195, 205, 197, 52, 177, 13, 21, 252, 169, 18, 98, 140, 102, 133, 98, 214, 123, 73, 173, 122, 252, 247, 48, 181, 86, 77, 188, 213, 161, 17, 19, 73, 96, 158, 181, 249, 69, 97, 15, 186, 12, 45, 157, 0, 0, 0, 0, 2, 0, 0, 0, 111, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 164, 195, 19, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ]) + // hexToU8a( + // '0x737d699e4e42f78dc2fb098f01bb85389f2c7f0a77bb41918adac6bfa5b3ee460900000000000000f707774183723f201b875024069f30e7089b7f83c3c3cdc534b10d15fca91262ab602f7974bbfb513f021f39777e2195094dc64a2c1b7c82a1781cb9fd4768a800000000020000006e0000000000000000000000000000000000000000000000000000000000000000000000000000000300a4c3135b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a00000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + // ) + ); + }); +}); diff --git a/packages/code-primitives/src/block/encode.ts b/packages/code-primitives/src/block/encode.ts new file mode 100644 index 000000000..1171fef99 --- /dev/null +++ b/packages/code-primitives/src/block/encode.ts @@ -0,0 +1,15 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Block } from '@polkadot/primitives/block'; + +import headerEncode from '../header/encode'; +import encodeRaw from './encodeRaw'; + +export default function encodeBlock ({ extrinsics, header }: Block): Uint8Array { + return encodeRaw( + headerEncode(header, extrinsics), + extrinsics + ); +} diff --git a/packages/code-primitives/src/block/encodeRaw.spec.js b/packages/code-primitives/src/block/encodeRaw.spec.js new file mode 100644 index 000000000..d133ea511 --- /dev/null +++ b/packages/code-primitives/src/block/encodeRaw.spec.js @@ -0,0 +1,37 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import encodeRaw from './encodeRaw'; + +describe('encodeRaw', () => { + it('encodes correctly (actual values)', () => { + expect( + encodeRaw( + new Uint8Array([ + 168, 135, 224, 93, 140, 222, 226, 83, 13, 116, 138, 197, 164, 6, 48, 190, 101, 18, 221, 166, 40, 179, 158, 112, 133, 154, 215, 198, 177, 76, 212, 228, + 1, 0, 0, 0, 0, 0, 0, 0, + 159, 216, 180, 61, 159, 12, 131, 80, 22, 196, 220, 94, 6, 222, 68, 159, 97, 60, 16, 69, 163, 149, 125, 138, 175, 36, 30, 93, 235, 4, 1, 168, + 245, 208, 141, 24, 250, 136, 158, 84, 67, 170, 59, 146, 17, 149, 62, 67, 254, 66, 126, 53, 20, 146, 252, 243, 137, 89, 224, 145, 252, 79, 109, 15, + 0, 0, 0, 0 + ]), + [ + new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 188, 29, 21, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ]), + new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ]) + ] + ) + ).toEqual( + new Uint8Array([ + 168, 135, 224, 93, 140, 222, 226, 83, 13, 116, 138, 197, 164, 6, 48, 190, 101, 18, 221, 166, 40, 179, 158, 112, 133, 154, 215, 198, 177, 76, 212, 228, 1, 0, 0, 0, 0, 0, 0, 0, 159, 216, 180, 61, 159, 12, 131, 80, 22, 196, 220, 94, 6, 222, 68, 159, 97, 60, 16, 69, 163, 149, 125, 138, 175, 36, 30, 93, 235, 4, 1, 168, 245, 208, 141, 24, 250, 136, 158, 84, 67, 170, 59, 146, 17, 149, 62, 67, 254, 66, 126, 53, 20, 146, 252, 243, 137, 89, 224, 145, 252, 79, 109, 15, 0, 0, 0, 0, 2, 0, 0, 0, + 110, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 188, 29, 21, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ]) + ); + }); +}); diff --git a/packages/code-primitives/src/block/encodeRaw.ts b/packages/code-primitives/src/block/encodeRaw.ts new file mode 100644 index 000000000..8018e1ff6 --- /dev/null +++ b/packages/code-primitives/src/block/encodeRaw.ts @@ -0,0 +1,19 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { UncheckedRaw } from '@polkadot/primitives/extrinsic'; + +import uncheckedLength from '@polkadot/extrinsics-codec/encode/length'; +import u8aConcat from '@polkadot/util/u8a/concat'; + +import encodeArray from '../encoder/array'; + +export default function encodeBlockRaw (header: Uint8Array, extrinsics: Array = []): Uint8Array { + return u8aConcat( + header, + encodeArray( + extrinsics.map(uncheckedLength) + ) + ); +} diff --git a/packages/code-primitives/src/block/index.ts b/packages/code-primitives/src/block/index.ts new file mode 100644 index 000000000..eef941f1a --- /dev/null +++ b/packages/code-primitives/src/block/index.ts @@ -0,0 +1,9 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import encodeBlock from './encode'; + +export { + encodeBlock +}; diff --git a/packages/code-primitives/src/decoder/array.spec.js b/packages/code-primitives/src/decoder/array.spec.js new file mode 100644 index 000000000..dc628192d --- /dev/null +++ b/packages/code-primitives/src/decoder/array.spec.js @@ -0,0 +1,37 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import decodeArray from './array'; + +describe('decodeArray', () => { + it('decodes an array with the length', () => { + expect( + decodeArray( + new Uint8Array([ + 2, 0, 0, 0, // length + 1, 2, // first + 3, 4 // second + ]) + ) + ).toEqual({ + length: 2, + data: new Uint8Array([1, 2, 3, 4]) + }); + }); + + it('decodes where array is an subarray', () => { + expect( + decodeArray( + new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 0, // padding + 1, 0, 0, 0, // length + 1, 2, 3, 4 // entry + ]).subarray(8) + ) + ).toEqual({ + length: 1, + data: new Uint8Array([1, 2, 3, 4]) + }); + }); +}); diff --git a/packages/code-primitives/src/decoder/array.ts b/packages/code-primitives/src/decoder/array.ts new file mode 100644 index 000000000..bbc41e32b --- /dev/null +++ b/packages/code-primitives/src/decoder/array.ts @@ -0,0 +1,18 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import u8aToBn from '@polkadot/util/u8a/toBn'; + +type DecodedArray = { + length: number, + data: Uint8Array +}; + +export default function decodeArray (input: Uint8Array): DecodedArray { + return { + // FIXME: This conversion is horrible, however Dataview on subarray yields wrong getUint32 value + length: u8aToBn(input.subarray(0, 4), true).toNumber(), + data: input.slice(4) + }; +} diff --git a/packages/code-primitives/src/decoder/u8a.spec.js b/packages/code-primitives/src/decoder/u8a.spec.js new file mode 100644 index 000000000..aa906e1c6 --- /dev/null +++ b/packages/code-primitives/src/decoder/u8a.spec.js @@ -0,0 +1,36 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import decodeU8a from './u8a'; + +describe('decodeU8a', () => { + it('decodes an input with the length', () => { + expect( + decodeU8a( + new Uint8Array([ + 4, 0, 0, 0, // length + 1, 2, 3, 4, // data + 5, 5, 5, 5 // extra + ]) + ) + ).toEqual( + new Uint8Array([1, 2, 3, 4]) + ); + }); + + it('decodes an subarray', () => { + expect( + decodeU8a( + new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 0, // padding + 4, 0, 0, 0, // length + 1, 2, 3, 4, // data + 5, 5, 5, 5 // extra + ]).subarray(8) + ) + ).toEqual( + new Uint8Array([1, 2, 3, 4]) + ); + }); +}); diff --git a/packages/code-primitives/src/decoder/u8a.ts b/packages/code-primitives/src/decoder/u8a.ts new file mode 100644 index 000000000..43343436d --- /dev/null +++ b/packages/code-primitives/src/decoder/u8a.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import u8aToBn from '@polkadot/util/u8a/toBn'; + +export default function decodeU8a (input: Uint8Array): Uint8Array { + // FIXME: This conversion is horrible, however Dataview on subarray yields wrong getUint32 value + const length = u8aToBn(input.subarray(0, 4), true).toNumber(); + + return input.slice(4, 4 + length); +} diff --git a/packages/code-primitives/src/encoder/array.spec.js b/packages/code-primitives/src/encoder/array.spec.js new file mode 100644 index 000000000..3fdb5e5b3 --- /dev/null +++ b/packages/code-primitives/src/encoder/array.spec.js @@ -0,0 +1,22 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import encodeArray from './array'; + +describe('encodeArray', () => { + it('encodes an array with the length', () => { + expect( + encodeArray([ + new Uint8Array([1, 2]), + new Uint8Array([3, 4]) + ]) + ).toEqual( + new Uint8Array([ + 2, 0, 0, 0, // length + 1, 2, // first + 3, 4 // second + ]) + ); + }); +}); diff --git a/packages/code-primitives/src/encoder/array.ts b/packages/code-primitives/src/encoder/array.ts new file mode 100644 index 000000000..a1d9e3617 --- /dev/null +++ b/packages/code-primitives/src/encoder/array.ts @@ -0,0 +1,18 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +export default function encodeArray (input: Array): Uint8Array { + const total = input.reduce((total, input) => total + input.length, 0); + const output = new Uint8Array(total + 4); + let offset = 4; + + new DataView(output.buffer).setUint32(0, input.length, true); + + return input.reduce((output, input) => { + output.set(input, offset); + offset += input.length; + + return output; + }, output); +} diff --git a/packages/code-primitives/src/encoder/u8a.spec.js b/packages/code-primitives/src/encoder/u8a.spec.js new file mode 100644 index 000000000..f806c3cca --- /dev/null +++ b/packages/code-primitives/src/encoder/u8a.spec.js @@ -0,0 +1,20 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import encodeU8a from './u8a'; + +describe('encodeU8a', () => { + it('encodes an input with the length', () => { + expect( + encodeU8a( + new Uint8Array([1, 2, 3, 4]) + ) + ).toEqual( + new Uint8Array([ + 4, 0, 0, 0, // length + 1, 2, 3, 4 // data + ]) + ); + }); +}); diff --git a/packages/code-primitives/src/encoder/u8a.ts b/packages/code-primitives/src/encoder/u8a.ts new file mode 100644 index 000000000..826387d8e --- /dev/null +++ b/packages/code-primitives/src/encoder/u8a.ts @@ -0,0 +1,13 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +export default function encodeU8a (input: Uint8Array): Uint8Array { + const output = new Uint8Array(input.length + 4); + + new DataView(output.buffer).setUint32(0, input.length, true); + + output.set(input, 4); + + return output; +} diff --git a/packages/code-primitives/src/header/decode.spec.js b/packages/code-primitives/src/header/decode.spec.js new file mode 100644 index 000000000..2b12c301c --- /dev/null +++ b/packages/code-primitives/src/header/decode.spec.js @@ -0,0 +1,47 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import createHeader from '@polkadot/primitives-builder/header'; + +import { decodeHeader } from './index'; + +describe('decodeHeader', () => { + it('decodes properly', () => { + expect( + JSON.stringify( + decodeHeader( + new Uint8Array([ + // parent_hash + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + // number + 67, 0, 0, 0, 0, 0, 0, 0, + // state_root + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + // transaction_root + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + // digest (length, log1, log2) + 2, 0, 0, 0, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 2 + ]) + ) + ) + ).toEqual( + JSON.stringify( + createHeader({ + digest: { + logs: [ + new Uint8Array([1]), + new Uint8Array([2]) + ] + }, + extrinsicsRoot: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6]), + number: 67, + parentHash: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5]), + stateRoot: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]) + }) + ) + ); + }); +}); diff --git a/packages/code-primitives/src/header/decode.ts b/packages/code-primitives/src/header/decode.ts new file mode 100644 index 000000000..02a35190b --- /dev/null +++ b/packages/code-primitives/src/header/decode.ts @@ -0,0 +1,24 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Header } from '@polkadot/primitives/header'; + +import createHeader from '@polkadot/primitives-builder/header'; + +import decodeRaw from './decodeRaw'; +import { OFF_PARENT_HASH, OFF_STATE_ROOT, OFF_TX_ROOT } from './offsets'; + +export default function decodeHeader (u8a: Uint8Array): Header { + const { number, logs } = decodeRaw(u8a); + + return createHeader({ + digest: { + logs + }, + extrinsicsRoot: u8a.subarray(OFF_TX_ROOT, OFF_TX_ROOT + 32), + number, + parentHash: u8a.subarray(OFF_PARENT_HASH, OFF_PARENT_HASH + 32), + stateRoot: u8a.subarray(OFF_STATE_ROOT, OFF_STATE_ROOT + 32) + }); +} diff --git a/packages/code-primitives/src/header/decodeRaw.spec.js b/packages/code-primitives/src/header/decodeRaw.spec.js new file mode 100644 index 000000000..2379af48a --- /dev/null +++ b/packages/code-primitives/src/header/decodeRaw.spec.js @@ -0,0 +1,57 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; + +import decode from './decodeRaw'; + +describe('decodeRaw', () => { + it('returns the raw parts', () => { + expect( + JSON.stringify( + decode( + new Uint8Array([ + // parent_hash + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + // number + 67, 0, 0, 0, 0, 0, 0, 0, + // state_root + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + // transaction_root + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + // digest (length, log1, log2) + 2, 0, 0, 0, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 2, + // remainder + 1, 2, 3, 4, 5, 4, 3, 2, 1 + ]) + ) + ) + ).toEqual( + JSON.stringify({ + body: new Uint8Array([1, 2, 3, 4, 5, 4, 3, 2, 1]), + header: new Uint8Array([ + // parent_hash + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + // number + 67, 0, 0, 0, 0, 0, 0, 0, + // state_root + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + // transaction_root + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + // digest (length, log1, log2) + 2, 0, 0, 0, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 2 + ]), + logs: [ + new Uint8Array([1]), + new Uint8Array([2]) + ], + number: new BN(67) + }) + ); + }); +}); diff --git a/packages/code-primitives/src/header/decodeRaw.ts b/packages/code-primitives/src/header/decodeRaw.ts new file mode 100644 index 000000000..913711a1a --- /dev/null +++ b/packages/code-primitives/src/header/decodeRaw.ts @@ -0,0 +1,39 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; + +import u8aToBn from '@polkadot/util/u8a/toBn'; + +import decodeArray from '../decoder/array'; +import decodeU8a from '../decoder/u8a'; +import { OFF_DIGEST, OFF_NUMBER } from './offsets'; + +type DecodedRaw = { + body: Uint8Array, + header: Uint8Array, + logs: Array, + number: BN +}; + +export default function decodeHeader (u8a: Uint8Array): DecodedRaw { + const logs = []; + const dd = decodeArray(u8a.subarray(OFF_DIGEST)); + let offset = 0; + + for (let index = 0; index < dd.length; index++) { + const log = decodeU8a(dd.data.subarray(offset)); + + logs.push(log); + + offset += log.length + 4; + } + + return { + body: dd.data.subarray(offset), + header: u8a.subarray(0, OFF_DIGEST + offset + 4), + logs, + number: u8aToBn(u8a.subarray(OFF_NUMBER, OFF_NUMBER + 8), true) + }; +} diff --git a/packages/code-primitives/src/header/encode.spec.js b/packages/code-primitives/src/header/encode.spec.js new file mode 100644 index 000000000..0f4f580b0 --- /dev/null +++ b/packages/code-primitives/src/header/encode.spec.js @@ -0,0 +1,45 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { encodeHeader } from './index'; + +describe('encodeHeader', () => { + it('encodes the block header as u8a', () => { + expect( + encodeHeader({ + digest: { + logs: [ + new Uint8Array([1, 2, 3]), + new Uint8Array([7, 8, 9, 10]) + ] + }, + extrinsicsRoot: new Uint8Array([ + 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0 + ]), + parentHash: new Uint8Array([ + 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0 + ]), + number: 67, + stateRoot: new Uint8Array([ + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0 + ]) + }) + ).toEqual( + new Uint8Array([ + // parentHash + 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, + // number + 67, 0, 0, 0, 0, 0, 0, 0, + // stateRoot + 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, + // extrinsicsRoot + 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, + // digest (length, log1, log2) + 2, 0, 0, 0, + 3, 0, 0, 0, 1, 2, 3, + 4, 0, 0, 0, 7, 8, 9, 10 + ]) + ); + }); +}); diff --git a/packages/code-primitives/src/header/encode.ts b/packages/code-primitives/src/header/encode.ts new file mode 100644 index 000000000..aed2a54f6 --- /dev/null +++ b/packages/code-primitives/src/header/encode.ts @@ -0,0 +1,32 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { UncheckedRaw } from '@polkadot/primitives/extrinsic'; +import { Header } from '@polkadot/primitives/header'; + +import rootRaw from '@polkadot/primitives-builder/extrinsic/rootRaw'; +import bnToU8a from '@polkadot/util/bn/toU8a'; +import u8aConcat from '@polkadot/util/u8a/concat'; +import u8aToU8a from '@polkadot/util/u8a/toU8a'; + +import encodeArray from '../encoder/array'; +import encodeU8a from '../encoder/u8a'; + +export default function encodeHeader ({ digest: { logs }, extrinsicsRoot, parentHash, number, stateRoot }: Header, extrinsics?: Array): Uint8Array { + return u8aConcat( + u8aToU8a(parentHash), + bnToU8a(number, 64, true), + u8aToU8a(stateRoot), + extrinsics + ? rootRaw(extrinsics) + : u8aToU8a(extrinsicsRoot), + encodeArray( + logs.map((log) => + encodeU8a( + u8aToU8a(log) + ) + ) + ) + ); +} diff --git a/packages/code-primitives/src/header/hash.ts b/packages/code-primitives/src/header/hash.ts new file mode 100644 index 000000000..d40372b95 --- /dev/null +++ b/packages/code-primitives/src/header/hash.ts @@ -0,0 +1,16 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Header } from '@polkadot/primitives/header'; + +import blake2Asu8a from '@polkadot/util-crypto/blake2/asU8a'; + +import encode from './encode'; + +export default function headerHash (header: Header): Uint8Array { + return blake2Asu8a( + encode(header), + 256 + ); +} diff --git a/packages/code-primitives/src/header/index.ts b/packages/code-primitives/src/header/index.ts new file mode 100644 index 000000000..3945fdb14 --- /dev/null +++ b/packages/code-primitives/src/header/index.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import decodeHeader from './decode'; +import encodeHeader from './encode'; + +export { + decodeHeader, + encodeHeader +}; diff --git a/packages/code-primitives/src/header/offsets.ts b/packages/code-primitives/src/header/offsets.ts new file mode 100644 index 000000000..8a6ca8812 --- /dev/null +++ b/packages/code-primitives/src/header/offsets.ts @@ -0,0 +1,17 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +const OFF_PARENT_HASH = 0; +const OFF_NUMBER = OFF_PARENT_HASH + 32; +const OFF_STATE_ROOT = OFF_NUMBER + 8; +const OFF_TX_ROOT = OFF_STATE_ROOT + 32; +const OFF_DIGEST = OFF_TX_ROOT + 32; + +export { + OFF_PARENT_HASH, + OFF_NUMBER, + OFF_STATE_ROOT, + OFF_TX_ROOT, + OFF_DIGEST +}; diff --git a/packages/code-primitives/src/index.ts b/packages/code-primitives/src/index.ts new file mode 100644 index 000000000..f35f7d1e4 --- /dev/null +++ b/packages/code-primitives/src/index.ts @@ -0,0 +1,6 @@ +// Copyright 2017-2018 @polkadot/primitives-codec authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +export * from './block'; +export * from './header'; diff --git a/packages/trie-db/LICENSE b/packages/trie-db/LICENSE new file mode 100644 index 000000000..a612ad981 --- /dev/null +++ b/packages/trie-db/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/packages/trie-db/README.md b/packages/trie-db/README.md new file mode 100644 index 000000000..a748624ea --- /dev/null +++ b/packages/trie-db/README.md @@ -0,0 +1,30 @@ +[![polkadotjs](https://img.shields.io/badge/polkadot-js-orange.svg?style=flat-square)](https://polkadot.js.org) +![mpl-2](https://img.shields.io/badge/license-MPL-lightgrey.svg?style=flat-square) +[![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) +[![npm](https://img.shields.io/npm/v/@polkadot/trie-db.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/trie-db) +[![travis](https://img.shields.io/travis/polkadot-js/trie.svg?style=flat-square)](https://travis-ci.org/polkadot-js/trie) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/trie.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/trie/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/trie.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/trie?branch=master) +[![dependency](https://david-dm.org/polkadot-js/trie.svg?style=flat-square&path=packages/trie)](https://david-dm.org/polkadot-js/trie?path=packages/trie-db) +[![devDependency](https://david-dm.org/polkadot-js/trie/dev-status.svg?style=flat-square&path=packages/trie-db)](https://david-dm.org/polkadot-js/trie?path=packages/trie-db#info=devDependencies) + +# @polkadot/trie-db + +An Implementation of the [Ethereum Merkle Patricia Tree](https://github.com/ethereum/wiki/wiki/Patricia-Tree) that uses Blake2 for hashing. + +# Adapted from Ethereum + +The has been adapted from the [original EthereumJs implementation](https://github.com/ethereumjs/merkle-patricia-tree) with the following changes - + +- Introduce [TypeScript](https://www.typescriptlang.org/) into the mix +- ES6-ify as applicable (Classes, `self` -> `this`, `function() {}` -> `() => {}`) +- Moves to a Promise-based interface (as applicable) +- Support only Uint8Array key/values (Buffer/String in the original) +- Use utilities from [@polkadot/util](https://github.com/polkadot-js/common) +- Supports blake2 hashing (sha3 in the original), aligning with the Polkadot tech stack) +- Updated the build steps with sources moved to [src/](src/) +- Tests updated to use [Jest](https://facebook.github.io/jest/) +- Upgrade interfaces to latest [levelup](https://github.com/Level/levelup) +- Removed the secure interface (not applicable for Substrate chains) + +... well at least the above is the _idea_ behind the fork ... diff --git a/packages/trie-db/package.json b/packages/trie-db/package.json new file mode 100644 index 000000000..719590420 --- /dev/null +++ b/packages/trie-db/package.json @@ -0,0 +1,47 @@ +{ + "name": "@polkadot/trie-db", + "version": "0.25.0", + "description": "This is an implementation of the modified merkle patricia tree as speficed in Ethereum's yellow paper, adpated for Polkadot.", + "main": "index.js", + "scripts": {}, + "maintainers": [ + "Jaco Greeff " + ], + "contributors": [ + "mjbecze ", + "Aaron Kumavis (https://github.com/kumavis)" + ], + "repository": { + "type": "git", + "url": "https://github.com/polkadot-js/common.git" + }, + "bugs": { + "url": "https://github.com/polkadot-js/common/issues" + }, + "keywords": [ + "merkle", + "radix", + "trie", + "ethereum" + ], + "license": "MPL-2.0", + "dependencies": { + "@babel/runtime": "^7.0.0-beta.51", + "@polkadot/trie-hash": "^0.25.0", + "@polkadot/util": "^0.25.0", + "@polkadot/util-crypto": "^0.25.0", + "@polkadot/util-rlp": "^0.25.0", + "@types/async": "^2.0.49", + "@types/semaphore": "^1.1.0", + "async": "^1.4.2", + "encoding-down": "^5.0.3", + "level-ws": "0.1.0", + "levelup": "^3.0.1", + "memdown": "^3.0.0", + "readable-stream": "^2.2.8", + "semaphore": ">=1.0.1" + }, + "devDependencies": { + "ethereumjs-testing": "0.0.1" + } +} diff --git a/packages/trie-db/src/BaseTrie.ts b/packages/trie-db/src/BaseTrie.ts new file mode 100644 index 000000000..73a28b1f0 --- /dev/null +++ b/packages/trie-db/src/BaseTrie.ts @@ -0,0 +1,827 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import { SemaphorePromise } from './types'; + +import async from 'async'; +// @ts-ignore FIXME, we need to properly check the full file +import levelup from 'levelup'; +import memdown from 'memdown'; +import logger from '@polkadot/util/logger'; +import assert from '@polkadot/util/assert'; +import isU8a from '@polkadot/util/is/u8a'; +import promisify from '@polkadot/util/promisify'; +import u8aToHex from '@polkadot/util/u8a/toHex'; +import decodeRlp from '@polkadot/util-rlp/decode'; + +import { EMPTY_ROOT_U8A, EMPTY_ROOT_STR } from './constants'; +import encoder from './encoder'; +import { nibblesMatchingLength, nibblesIsEqual, nibblesFromU8a } from './nibbles'; +import ReadStream from './streams/TrieRead'; +import nodeFactory from './nodeFactory'; +import isRawNode from './util/isRawNode'; +import prioritizedTaskExecutor from './util/taskExecutor'; +import semaphore from './util/semaphore'; + +type RawPutFn = (key: Uint8Array, value: Uint8Array) => Promise; + +const l = logger('trie/base'); + +export default class BaseTrie { + // @ts-ignore we are assigning via this.root in constructor + _root: Uint8Array; + _getDBs: any[]; // FIXME + _putDBs: any[]; // FIXME + dbDown: any; // FIXME + db: any; // FIXME + putRaw: RawPutFn; + semaphore: SemaphorePromise; + + // @ts-ignore FIXME, we need to properly check the full file + constructor (db, root: Uint8Array) { + this.putRaw = this._putRaw; + + this.semaphore = semaphore(1); + this.dbDown = db || memdown(); + this.db = levelup(encoder(this.dbDown)); + this._getDBs = [this.db]; + this._putDBs = [this.db]; + this.root = root; + + l.debug(() => ['Created BaseTrie', typeof db, u8aToHex(root)]); + } + + get root (): Uint8Array { + return this._root; + } + + set root (value: Uint8Array) { + if (value) { + assert(isU8a(value) && value.length === 32, 'Invalid root length. Roots are Uint8Array 32 bytes'); + } else { + value = EMPTY_ROOT_U8A; + } + + this._root = value; + } + + /** + * Gets a value given a `key` + * @method get + * @param {Buffer|String} key - the key to search for + * @param {Function} cb A callback `Function` which is given the arguments `err` - for errors that may have occured and `value` - the found value in a `Buffer` or if no value was found `null` + */ + async get (key: Uint8Array) { + l.debug(() => ['get', 'key ->', u8aToHex(key)]); + + const result = await this.findPath(key); + + let value = null; + + if (result && result.node && result.remainder.length === 0) { + value = result.node.value; + } + + return value; + } + + /** + * Stores a given `value` at the given `key` + * @method put + * @param {Buffer|String} key + * @param {Buffer|String} Value + * @returns {Function} Promise + */ + async put (key: Uint8Array, value: Uint8Array) { + l.debug(() => ['put', 'key ->', u8aToHex(key), 'value ->', u8aToHex(value)]); + + if (!value || value.toString() === '') { + return this.del(key); + } + + return this.semaphore(async () => { + if (this.root.toString() === EMPTY_ROOT_STR) { + return this._createInitialNode(key, value); // if no root initialize this trie + } + + // first try to find the give key or its nearst node + const result = await this.findPath(key); + + return this._updateNode(key, value, result && result.remainder, result && result.stack); + }); + } + + /** + * deletes a value given a `key` + * @method del + * @param {Buffer|String} key + * @param {Function} callback the callback `Function` + */ + del (key: Uint8Array) { + l.debug(() => ['del', 'key ->', u8aToHex(key)]); + + return this.semaphore(async () => { + const result = await this.findPath(key); + + if (result && result.node) { + return this._deleteNode(key, result.stack); + } + }); + } + + /** + * Retrieves a raw value in the underlying db + * @method getRaw + * @param {Buffer} key + * @param {Function} callback A callback `Function`, which is given the arguments `err` - for errors that may have occured and `value` - the found value in a `Buffer` or if no value was found `null`. + */ + async getRaw (key: Uint8Array): Promise { + let found: Uint8Array; + + await Promise.all( + this._getDBs.map(async (db) => { + if (!found) { + try { + found = await db.get(key); + } catch (error) { + // l.error('getRaw', 'key ->', u8aToHex(key), error); + // not doing anything + } + } + + return found; + }) + ); + + // @ts-ignore FIXME, we need to properly check the full file + return found; + } + + // retrieves a node from dbs by hash + // @ts-ignore FIXME, we need to properly check the full file + async _lookupNode (node) { + if (isRawNode(node)) { + return nodeFactory.fromRaw(node); + } + + let value = await this.getRaw(node); + + if (value) { + try { + // @ts-ignore FIXME, we need to properly check the full file + value = nodeFactory.fromRaw(decodeRlp(value)); + } catch (error) { + l.error('_lookupNode decoding', typeof value, value); + throw error; + } + } + + return value; + } + + // TODO: remove the proxy method when changing the caching + async _putRaw (key: Uint8Array, value: Uint8Array) { + return Promise.all( + this._putDBs.map((db) => { + return db.put(key, value); + }) + ); + } + + /** + * Removes a raw value in the underlying db + * @method delRaw + * @param {Buffer|String} key + * @param {Function} callback A callback `Function`, which is given the argument `err` - for errors that may have occured + */ + delRaw (key: Uint8Array) { + return Promise.all( + this._putDBs.map((db) => { + return db.del(key); + }) + ); + } + + // writes a single node to dbs + // @ts-ignore FIXME, we need to properly check the full file + _putNode (node) { + const hash = node.hash(); + const serialized = node.serialize(); + + return this._putRaw(hash, serialized); + } + + // writes many nodes to db + // @ts-ignore FIXME, we need to properly check the full file + _batchNodes (opStack) { + return Promise.all( + this._putDBs.map((db) => { + return db.batch(opStack); + }) + ); + } + + /** + * Trys to find a path to the node for the given key + * It returns a `stack` of nodes to the closet node + * @method findPath + * @param {String|Buffer} - key - the search key + * @param {Function} - cb - the callback function. Its is given the following + * arguments + * - err - any errors encontered + * - node - the last node found + * - remainder - the remaining key nibbles not accounted for + * - stack - an array of nodes that forms the path to node we are searching for + */ + // @ts-ignore FIXME, we need to properly check the full file + findPath (_targetKey) { + const stack: any[] = []; // FIXME + const targetKey = nibblesFromU8a(_targetKey); + + l.debug(() => ['findPath', targetKey.join(', ')]); + + // @ts-ignore FIXME, we need to properly check the full file + const processNode = (nodeRef, node, keyProgress, walkController) => { + const nodeKey = node.key || []; + const remainder = targetKey.slice(nibblesMatchingLength(keyProgress, targetKey)); + const matchingLen = nibblesMatchingLength(remainder, nodeKey); + + stack.push(node); + + if (node.type === 'branch') { + if (remainder.length === 0) { + walkController.return(null, { node, remainder: [], stack }); + // we exhausted the key without finding a node + } else { + const branchIndex = remainder[0]; + const branchNode = node.getValue(branchIndex); + + if (!branchNode) { + // there are no more nodes to find and we didn't find the key + walkController.return(null, { node: null, remainder, stack }); + } else { + // node found, continuing search + walkController.only(branchIndex); + } + } + } else if (node.type === 'leaf') { + if (nibblesIsEqual(remainder, nodeKey)) { + // keys match, return node with empty key + walkController.return(null, { node, remainder: [], stack }); + } else { + // reached leaf but keys dont match + walkController.return(null, { node: null, remainder, stack }); + } + } else if (node.type === 'extention') { + if (matchingLen !== nodeKey.length) { + // keys dont match, fail + walkController.return(null, { node: null, remainder, stack }); + } else { + // keys match, continue search + walkController.next(); + } + } + }; + + return promisify(this, this._walkTrie, this.root, processNode); + } + + /* + * Finds all nodes that store k,v values + */ + // NOTE seems unused + // _findNode = function (key, root, stack, cb) { + // this.findPath(key, (...args) => { + // cb.apply(null, args); + // }); + // }; + + /* + * Finds all nodes that store k,v values + */ + // @ts-ignore FIXME, we need to properly check the full file + _findValueNodes (onFound, cb) { + // @ts-ignore FIXME, we need to properly check the full file + this._walkTrie(this.root, (nodeRef, node, key, walkController) => { + let fullKey = key; + + if (node.key) { + fullKey = key.concat(node.key); + } + + if (node.type === 'leaf') { + // found leaf node! + onFound(nodeRef, node, fullKey, walkController.next); + } else if (node.type === 'branch' && node.value) { + // found branch with value + onFound(nodeRef, node, fullKey, walkController.next); + } else { + // keep looking for value nodes + walkController.next(); + } + }, cb); + } + + /* + * Finds all nodes that are stored directly in the db + * (some nodes are stored raw inside other nodes) + */ + // @ts-ignore FIXME, we need to properly check the full file + _findDbNodes (onFound, cb) { + // @ts-ignore FIXME, we need to properly check the full file + this._walkTrie(this.root, (nodeRef, node, key, walkController) => { + if (isRawNode(nodeRef)) { + walkController.next(); + } else { + onFound(nodeRef, node, key, walkController.next); + } + }, cb); + } + + /** + * Updates a node + * @method _updateNode + * @param {Buffer} key + * @param {Buffer| String} value + * @param {Array} keyRemainder + * @param {Array} stack - + * @param {Function} cb - the callback + */ + // @ts-ignore FIXME, we need to properly check the full file + async _updateNode (key, value, keyRemainder, stack) { + // @ts-ignore FIXME, we need to properly check the full file + const toSave = []; + const lastNode = stack.pop(); + + // add the new nodes + key = nibblesFromU8a(key); + + // Check if the last node is a leaf and the key matches to this + let matchLeaf = false; + + if (lastNode.type === 'leaf') { + let l = 0; + + for (let i = 0; i < stack.length; i++) { + const n = stack[i]; + + if (n.type === 'branch') { + l++; + } else { + l += n.key.length; + } + } + + if ((nibblesMatchingLength(lastNode.key, key.slice(l)) === lastNode.key.length) && (keyRemainder.length === 0)) { + matchLeaf = true; + } + } + + if (matchLeaf) { + // just updating a found value + lastNode.value = value; + stack.push(lastNode); + } else if (lastNode.type === 'branch') { + stack.push(lastNode); + + if (keyRemainder !== 0) { + // add an extention to a branch node + keyRemainder.shift(); + // create a new leaf + stack.push(nodeFactory.fromLeaf(keyRemainder, value)); + } else { + lastNode.value = value; + } + } else { + // create a branch node + const lastKey = lastNode.key; + const matchingLength = nibblesMatchingLength(lastKey, keyRemainder); + // @ts-ignore FIXME, we need to properly check the full file + const newBranchNode = nodeFactory.fromBranch(); + + // create a new extention node + if (matchingLength !== 0) { + const newKey = lastNode.key.slice(0, matchingLength); + const newExtNode = nodeFactory.fromExtention(newKey, value); + + stack.push(newExtNode); + lastKey.splice(0, matchingLength); + keyRemainder.splice(0, matchingLength); + } + + stack.push(newBranchNode); + + if (lastKey.length !== 0) { + const branchKey = lastKey.shift(); + + if (lastKey.length !== 0 || lastNode.type === 'leaf') { + // shriking extention or leaf + lastNode.key = lastKey; + + // @ts-ignore FIXME, we need to properly check the full file + const formatedNode = this._formatNode(lastNode, false, toSave); + + // @ts-ignore FIXME, we need to properly check the full file + newBranchNode.setValue(branchKey, formatedNode); + } else { + // remove extention or attaching + // @ts-ignore FIXME, we need to properly check the full file + this._formatNode(lastNode, false, true, toSave); + + // @ts-ignore FIXME, we need to properly check the full file + newBranchNode.setValue(branchKey, lastNode.value); + } + } else { + newBranchNode.value = lastNode.value; + } + + if (keyRemainder.length !== 0) { + keyRemainder.shift(); + + // add a leaf node to the new branch node + stack.push(nodeFactory.fromLeaf(keyRemainder, value)); + } else { + newBranchNode.value = value; + } + } + + // @ts-ignore FIXME, we need to properly check the full file + return this._saveStack(key, stack, toSave); + } + + // walk tree + // @ts-ignore FIXME, we need to properly check the full file + async _walkTrie (root, onNode, onDone) { + root = root || this.root; + + let isAborted: boolean = false; + // @ts-ignore FIXME, we need to properly check the full file + let returnValues: any[] = []; + + if (root.toString() === EMPTY_ROOT_STR) { + onDone(); + return; + } + + // the maximum pool size should be high enough to utilise the parallelizability of reading nodes from disk and + // low enough to utilize the prioritisation of node lookup. + const maxPoolSize = 500; + const taskExecutor = prioritizedTaskExecutor(maxPoolSize); + + // @ts-ignore FIXME, we need to properly check the full file + const processNode = (nodeRef, node, key, cb) => { + if (!node || isAborted) { + return cb(); + } + + const self = this; + let isStopped = false; + + key = key || []; + + const walkController = { + stop: function () { + isStopped = true; + cb(); + }, + // end all traversal and return values to the onDone cb + return: function () { + isAborted = true; + // @ts-ignore FIXME, we need to properly check the full file + returnValues = arguments; + cb(); + }, + next: async function () { + if (isAborted || isStopped) { + return cb(); + } + + const children = node.getChildren(); + + // @ts-ignore FIXME callback + async.forEachOf(children, (childData: any[], index: number, cb) => { + // @ts-ignore FIXME, we need to properly check the full file + const keyExtension = childData[0]; + // @ts-ignore FIXME, we need to properly check the full file + const childRef = childData[1]; + const childKey = key.concat(keyExtension); + const priority = childKey.length; + + taskExecutor(priority, async (taskCallback) => { + const childNode = await self._lookupNode(childRef); + + // @ts-ignore FIXME, we need to properly check the full file + taskCallback(); + processNode(childRef, childNode, childKey, cb); + }); + }, cb); + }, + // @ts-ignore FIXME, we need to properly check the full file + only: function (childIndex) { + const childRef = node.getValue(childIndex); + const childKey = key.slice(); + + childKey.push(childIndex); + + const priority = childKey.length; + + taskExecutor(priority, async (taskCallback) => { + const childNode = await self._lookupNode(childRef); + + // @ts-ignore FIXME, we need to properly check the full file + taskCallback(); + processNode(childRef, childNode, childKey, cb); + }); + } + }; + onNode(nodeRef, node, key, walkController); + }; + + const node = await this._lookupNode(root); + + processNode(root, node, null, (error: Error | null) => { + if (error) { + onDone(error); + return; + } + + // @ts-ignore FIXME, we need to properly check the full file + onDone.apply(null, returnValues); + }); + } + + /** + * saves a stack + * @method _saveStack + * @param {Array} key - the key. Should follow the stack + * @param {Array} stack - a stack of nodes to the value given by the key + * @param {Array} opStack - a stack of levelup operations to commit at the end of this funciton + * @param {Function} cb + */ + // @ts-ignore FIXME, we need to properly check the full file + _saveStack (key, stack, opStack: any[]) { + let lastRoot; + + // update nodes + while (stack.length) { + const node = stack.pop(); + + if (node.type === 'leaf') { + key.splice(key.length - node.key.length); + } else if (node.type === 'extention') { + key.splice(key.length - node.key.length); + if (lastRoot) { + node.value = lastRoot; + } + } else if (node.type === 'branch') { + if (lastRoot) { + const branchKey = key.pop(); + + node.setValue(branchKey, lastRoot); + } + } + + // @ts-ignore FIXME, we need to properly check the full file + lastRoot = this._formatNode(node, stack.length === 0, opStack); + } + + if (lastRoot) { + this.root = lastRoot; + } + + return this._batchNodes(opStack); + } + + // @ts-ignore FIXME, we need to properly check the full file + async _deleteNode (key: Uint8Array, stack) { + // @ts-ignore FIXME, we need to properly check the full file + const processBranchNode = (key, branchKey, branchNode, parentNode, stack) => { + // branchNode is the node ON the branch node not THE branch node + const branchNodeKey = branchNode.key; + + if (!parentNode || parentNode.type === 'branch') { + // branch->? + if (parentNode) { + stack.push(parentNode); + } + + if (branchNode.type === 'branch') { + // create an extention node + // branch->extention->branch + // @ts-ignore FIXME, we need to properly check the full file + stack.push(nodeFactory.fromExtention([branchKey], null)); + key.push(branchKey); + } else { + // branch key is an extention or a leaf + // branch->(leaf or extention) + branchNodeKey.unshift(branchKey); + branchNode.key = branchNodeKey; + + // hackery. This is equvilant to array.concat except we need keep the + // rerfance to the `key` that was passed in. + branchNodeKey.unshift(0); + branchNodeKey.unshift(key.length); + key.splice.apply(key, branchNodeKey); + } + stack.push(branchNode); + } else { + // parent is a extention + let parentKey = parentNode.key; + + if (branchNode.type === 'branch') { + // ext->branch + parentKey.push(branchKey); + key.push(branchKey); + parentNode.key = parentKey; + stack.push(parentNode); + } else { + // branch node is an leaf or extention and parent node is an exstention + // add two keys together + // dont push the parent node + branchNodeKey.unshift(branchKey); + key = key.concat(branchNodeKey); + parentKey = parentKey.concat(branchNodeKey); + branchNode.key = parentKey; + } + stack.push(branchNode); + } + + return key; + }; + + // @ts-ignore FIXME, we need to properly check the full file + const opStack: any[] = []; + let lastNode = stack.pop(); + let parentNode = stack.pop(); + + if (!Array.isArray(key)) { + // @ts-ignore FIXME, we need to properly check the full file + key = nibblesFromU8a(key); + } + + if (!parentNode) { + // the root here has to be a leaf. + this.root = EMPTY_ROOT_U8A; + } else { + if (lastNode.type === 'branch') { + lastNode.value = null; + } else { + // the lastNode has to be a leaf if its not a branch. And a leaf's parent + // if it has one must be a branch. + const lastNodeKey = lastNode.key; + + // @ts-ignore FIXME, we need to properly check the full file + key.splice(key.length - lastNodeKey.length); + // delete the value + this._formatNode(lastNode, false, true, opStack); + // @ts-ignore FIXME, we need to properly check the full file + parentNode.setValue(key.pop(), null); + lastNode = parentNode; + parentNode = stack.pop(); + } + + // nodes on the branch + // @ts-ignore FIXME, we need to properly check the full file + const branchNodes = []; + + // count the number of nodes on the branch + // @ts-ignore FIXME, we need to properly check the full file + lastNode.raw.forEach(function (node, i) { + const val = lastNode.getValue(i); + + // @ts-ignore FIXME, we need to properly check the full file + if (val) branchNodes.push([i, val]); + }); + + // if there is only one branch node left, collapse the branch node + if (branchNodes.length === 1) { + // add the one remaing branch node to node above it + // @ts-ignore FIXME, we need to properly check the full file + const branchNode = branchNodes[0][1]; + // @ts-ignore FIXME, we need to properly check the full file + const branchNodeKey = branchNodes[0][0]; + + // look up node + const foundNode = await this._lookupNode(branchNode); + + // @ts-ignore FIXME, we need to properly check the full file + key = processBranchNode(key, branchNodeKey, foundNode, parentNode, stack, opStack); + + return this._saveStack(key, stack, opStack); + } else { + // simple removing a leaf and recaluclation the stack + if (parentNode) { + stack.push(parentNode); + } + + stack.push(lastNode); + + return this._saveStack(key, stack, opStack); + } + } + } + + // Creates the initial node from an empty tree + _createInitialNode (key: Uint8Array, value: Uint8Array) { + const newNode = nodeFactory.fromLeaf(key, value); + + this.root = newNode.hash(); + + return this._putNode(newNode); + } + + // formats node to be saved by levelup.batch. + // returns either the hash that will be used key or the rawNode + // @ts-ignore FIXME, we need to properly check the full file + _formatNode (node: any, topLevel: any, remove: any, opStack: any) { + if (arguments.length === 3) { + opStack = remove; + remove = false; + } + + const rlpNode = node.serialize(); + + if (rlpNode.length >= 32 || topLevel) { + const hashRoot = node.hash(); + + // FIXME Actually 2 things wrong here - this is on checkpoint, so one higher-level class... + // @ts-ignore FIXME, we need to properly check the full file + if (remove && this.isCheckpoint) { + opStack.push({ + type: 'del', + key: hashRoot + }); + } else { + opStack.push({ + type: 'put', + key: hashRoot, + value: rlpNode + }); + } + + return hashRoot; + } + + return node.raw; + } + + /** + * The `data` event is given an `Object` hat has two properties; the `key` and the `value`. Both should be Buffers. + * @method createReadStream + * @return {stream.Readable} Returns a [stream](https://nodejs.org/dist/latest-v5.x/docs/api/stream.html#stream_class_stream_readable) of the contents of the `trie` + */ + createReadStream () { + return new ReadStream(this); + } + + // creates a new trie backed by the same db + // and starting at the same root + copy () { + l.debug(() => ['Copying BaseTrie', typeof this.dbDown, u8aToHex(this.root)]); + + return new BaseTrie(this.dbDown, this.root); + } + + /** + * The given hash of operations (key additions or deletions) are executed on the DB + * @method batch + * @example + * const ops = [ + * { type: 'del', key: 'father' } + * , { type: 'put', key: 'name', value: 'Yuri Irsenovich Kim' } + * , { type: 'put', key: 'dob', value: '16 February 1941' } + * , { type: 'put', key: 'spouse', value: 'Kim Young-sook' } + * , { type: 'put', key: 'occupation', value: 'Clown' } + * ] + * trie.batch(ops) + * @param {Array} ops + * @param {Function} cb + */ + // @ts-ignore FIXME, we need to properly check the full file + batch (ops: any[]) { + return Promise.all( + // @ts-ignore FIXME, we need to properly check the full file + ops.map((op) => { + if (op.type === 'put') { + return this.put(op.key, op.value); + } else if (op.type === 'del') { + return this.del(op.key); + } + }) + ); + } + + /** + * Checks if a given root exists + * @method checkRoot + * @param {Buffer} root + * @param {Function} cb + */ + async checkRoot (root: Uint8Array): Promise { + const value = await this._lookupNode(root); + + return !!value; + } +} diff --git a/packages/trie-db/src/CheckpointTrie.ts b/packages/trie-db/src/CheckpointTrie.ts new file mode 100644 index 000000000..8476682df --- /dev/null +++ b/packages/trie-db/src/CheckpointTrie.ts @@ -0,0 +1,161 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +// @ts-ignore FIXME, we need to properly check the full file +import levelws from 'level-ws'; +// @ts-ignore FIXME, we need to properly check the full file +import levelup from 'levelup'; +import memdown from 'memdown'; +import assert from '@polkadot/util/assert'; +import logger from '@polkadot/util/logger'; +import u8aToHex from '@polkadot/util/u8a/toHex'; + +import BaseTrie from './BaseTrie'; +import encoder from './encoder'; +import ScratchReadStream from './streams/ScratchRead'; + +const l = logger('trie/checkpt'); + +function putRaw (key: Uint8Array, value: Uint8Array) { + return Promise.all( + // @ts-ignore FIXME, we need to properly check the full file + this.__putDBs.map((db) => { + return db.put(key, value); + }) + ); +} + +export default class CheckpointTrie extends BaseTrie { + _checkpoints: Array; + _scratch: any; // FIXME + // @ts-ignore FIXME, we need to properly check the full file + __putDBs: any[]; // FIXME + + // @ts-ignore FIXME, we need to properly check the full file + constructor (db, root: Uint8Array) { + super(db, root); + + this._scratch = null; + this._checkpoints = []; + + l.debug(() => 'Created CheckpointTrie'); + } + + get isCheckpoint () { + return !!this._checkpoints.length; + } + + copy () { + l.debug(() => ['Copying CheckpointTrie', typeof this.dbDown, u8aToHex(this.root)]); + + return new CheckpointTrie(this.dbDown, this.root); + } + + async checkpoint () { + l.debug(() => 'Marking checkpoint'); + + const wasCheckpoint = this.isCheckpoint; + + this._checkpoints.push(this.root); + + if (!wasCheckpoint && this.isCheckpoint) { + this._enterCpMode(); + } + } + + commit () { + l.debug(() => 'Committing checkpoint'); + + return this.semaphore(async () => { + assert(this.isCheckpoint, 'trying to commit when not checkpointed'); + + this._checkpoints.pop(); + + if (this.isCheckpoint) { + return; + } + + return this._exitCpMode(true); + }); + } + + revert () { + l.debug(() => 'Reverting checkpoint'); + + return this.semaphore(async () => { + if (!this.isCheckpoint) { + return; + } + + this.root = this._checkpoints.pop() as Uint8Array; + + if (this.isCheckpoint) { + return; + } + + return this._exitCpMode(false); + }); + } + + // @ts-ignore FIXME, we need to properly check the full file + createScratchReadStream (scratch) { + const trie = this.copy(); + + scratch = scratch || this._scratch; + + // only read from the scratch + trie._getDBs = [scratch]; + trie._scratch = scratch; + + return new ScratchReadStream(trie); + } + + _enterCpMode () { + l.debug(() => 'Entering checkpoint mode'); + + this._scratch = levelup(encoder(memdown())); + + this._getDBs = [this._scratch].concat(this._getDBs); + this.__putDBs = this._putDBs; + this._putDBs = [this._scratch]; + this._putRaw = this.putRaw; + this.putRaw = putRaw; + } + + // @ts-ignore FIXME, we need to properly check the full file + _exitCpMode (commitState) { + l.debug(() => 'Exiting checkpoint mode'); + + const scratch = this._scratch; + this._scratch = null; + this._getDBs = this._getDBs.slice(1); + this._putDBs = this.__putDBs; + this.putRaw = this._putRaw; + + if (!commitState) { + return; + } + + return Promise.all( + this._putDBs.map((db) => { + return new Promise((resolve) => { + if (!db.createWriteStream) { + db = levelws(db); + } + + this + // @ts-ignore FIXME, we need to properly check the full file + .createScratchReadStream(scratch) + // @ts-ignore FIXME, we need to properly check the full file + .pipe( + // @ts-ignore FIXME, we need to properly check the full file + db.createWriteStream(encoder.options) + ) + .on('close', resolve); + }); + }) + ); + } +} diff --git a/packages/trie-db/src/Node.ts b/packages/trie-db/src/Node.ts new file mode 100644 index 000000000..ff5acc0a1 --- /dev/null +++ b/packages/trie-db/src/Node.ts @@ -0,0 +1,170 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import { DecodedRlp, Trie$Node$Type } from './types'; + +import isU8a from '@polkadot/util/is/u8a'; +import u8aToHex from '@polkadot/util/u8a/toHex'; +import keccakAsU8a from '@polkadot/util-crypto/keccak/asU8a'; +import encodeRlp from '@polkadot/util-rlp/encode'; + +import nibblesFromU8a from './nibbles/fromU8a'; +import nibblesToU8a from './nibbles/toU8a'; + +function addHexPrefix (key: Array, isTerminator: boolean): Array { + // odd + if (key.length % 2) { + key.unshift(1); + } else { + // even + key.unshift(0); + key.unshift(0); + } + + if (isTerminator) { + key[0] += 2; + } + + return key; +} + +function removeHexPrefix (key: Uint8Array): Uint8Array { + return key[0] % 2 + ? key.slice(1) + : key.slice(2); +} + +export default class TrieNode { + raw: DecodedRlp; + type: Trie$Node$Type; + + constructor (type: Trie$Node$Type, raw: DecodedRlp) { + this.raw = raw; + this.type = type; + } + + get value () { + return this.getValue(); + } + + set value (v) { + this.setValue(v); + } + + get key () { + return this.getKey(); + } + + set key (k) { + // @ts-ignore FIXME, we need to properly check the full file + this.setKey(k); + } + + setValue (key: number | Uint8Array, value?: Uint8Array) { + if (this.type !== 'branch') { + this.raw[1] = key as Uint8Array; + return; + } + + if (arguments.length === 1) { + value = key as Uint8Array; + key = 16; + } + + this.raw[key as number] = value as Uint8Array; + } + + getValue (key?: number) { + if (this.type !== 'branch') { + return this.raw[1]; + } + + if (arguments.length === 0) { + key = 16; + } + + // @ts-ignore FIXME, we need to properly check the full file + const val = this.raw[key]; + + if (val !== null && val !== undefined && val.length !== 0) { + return val; + } + } + + setKey (key: Array | Uint8Array) { + if (this.type !== 'branch') { + if (Array.isArray(key)) { + key = key.slice(0); // copy the key + } else { + key = nibblesFromU8a(key); + } + + key = addHexPrefix(key, this.type === 'leaf'); + this.raw[0] = nibblesToU8a(key); + } + } + + getKey () { + if (this.type !== 'branch') { + return removeHexPrefix( + // @ts-ignore FIXME, we need to properly check the full file + nibblesFromU8a(this.raw[0]) + ); + } + } + + serialize (): Uint8Array { + return encodeRlp(this.raw); + } + + hash (): Uint8Array { + return keccakAsU8a(this.serialize()); + } + + toString (): string { + return this.raw.reduce((out, el, index) => { + if (index !== 0) { + out += ', '; + } + + if (isU8a(el)) { + out += u8aToHex(el); + } else if (el) { + out += 'object'; + } else { + out += 'empty'; + } + + return out; + }, `${this.type}: [`) + ']'; + } + + getChildren () { + const children = []; + + switch (this.type) { + case 'leaf': + // no children + break; + case 'extention': + // one child + children.push([this.key, this.getValue()]); + break; + case 'branch': + for (let index = 0, end = 16; index < end; index++) { + const value = this.getValue(index); + + if (value) { + children.push([ + [index], value + ]); + } + } + break; + } + + return children; + } +} diff --git a/packages/trie-db/src/constants.ts b/packages/trie-db/src/constants.ts new file mode 100644 index 000000000..3741cb114 --- /dev/null +++ b/packages/trie-db/src/constants.ts @@ -0,0 +1,13 @@ +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import trieRoot from '@polkadot/trie-hash/root'; + +const EMPTY_ROOT_U8A = trieRoot([]); +const EMPTY_ROOT_STR = EMPTY_ROOT_U8A.toString(); + +export { + EMPTY_ROOT_U8A, + EMPTY_ROOT_STR +}; diff --git a/packages/trie-db/src/encoder/decode.ts b/packages/trie-db/src/encoder/decode.ts new file mode 100644 index 000000000..839532c33 --- /dev/null +++ b/packages/trie-db/src/encoder/decode.ts @@ -0,0 +1,29 @@ +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import { Logger } from '@polkadot/util/types'; + +import assert from '@polkadot/util/assert'; +import isBuffer from '@polkadot/util/is/buffer'; +import isU8a from '@polkadot/util/is/u8a'; +import toU8a from '@polkadot/util/u8a/toU8a'; + +export default function decode (l: Logger) { + return (value: Buffer | Uint8Array | null): Uint8Array => { + // l.debug(() => ['decoding', value]); + + if (!value || !value.length) { + return new Uint8Array(0); + } + + const isBufferIn = isBuffer(value); + const isU8aIn = isU8a(value); + + assert(isBufferIn || isU8aIn, `Expected a Buffer | Uint8Array | null input type, received '${typeof value}'`); + + return isBufferIn + ? toU8a(value) + : value; + }; +} diff --git a/packages/trie-db/src/encoder/encode.ts b/packages/trie-db/src/encoder/encode.ts new file mode 100644 index 000000000..cb8dfabad --- /dev/null +++ b/packages/trie-db/src/encoder/encode.ts @@ -0,0 +1,29 @@ +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import { Logger } from '@polkadot/util/types'; + +import assert from '@polkadot/util/assert'; +import isBuffer from '@polkadot/util/is/buffer'; +import isU8a from '@polkadot/util/is/u8a'; +import u8aToBuffer from '@polkadot/util/u8a/toBuffer'; + +export default function encode (l: Logger) { + return (value: Buffer | Uint8Array | null): Buffer => { + // l.debug(() => ['encoding', value ? value.toString() : value]); + + if (!value || value.length === 0) { + return Buffer.alloc(0); + } + + const isBufferIn = isBuffer(value); + const isU8aIn = isU8a(value); + + assert(isBufferIn || isU8aIn, `Expected Buffer | Uint8Array | null input, received '${typeof value}'`); + + return isBufferIn + ? value as Buffer + : u8aToBuffer(value); + }; +} diff --git a/packages/trie-db/src/encoder/index.ts b/packages/trie-db/src/encoder/index.ts new file mode 100644 index 000000000..c8a87144b --- /dev/null +++ b/packages/trie-db/src/encoder/index.ts @@ -0,0 +1,38 @@ +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +// @ts-ignore FIXME, we need to properly check the full file +import { LevelUp$AbstractStorage } from 'levelup'; +// @ts-ignore FIXME, we need to properly check the full file +import { EncoderBufferOptions, EncodingBuffer } from 'encoding-down'; + +// @ts-ignore FIXME, we need to properly check the full file +import encodingDown from 'encoding-down'; +import logger from '@polkadot/util/logger'; + +import decode from './decode'; +import encode from './encode'; + +const l = logger('trie/codec'); + +const encoding: EncodingBuffer = { + buffer: true, + decode: decode(l), + encode: encode(l), + type: 'Uint8Array' +}; + +const options: EncoderBufferOptions = { + keyEncoding: encoding, + valueEncoding: encoding +}; + +function encoder (db: LevelUp$AbstractStorage) { + return encodingDown(db, options); +} + +// @ts-ignore FIXME, we need to properly check the full file +encoder.options = options; + +export default encoder; diff --git a/packages/trie-db/src/index.ts b/packages/trie-db/src/index.ts new file mode 100644 index 000000000..2cc544fc7 --- /dev/null +++ b/packages/trie-db/src/index.ts @@ -0,0 +1,23 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import logger from '@polkadot/util/logger'; + +import CheckpointTrie from './CheckpointTrie'; +import { prove, verifyProof } from './proof'; + +const l = logger('trie'); + +export default class Trie extends CheckpointTrie { + static prove = prove; + static verifyProof = verifyProof; + + // @ts-ignore FIXME, we need to properly check the full file + constructor (db, root) { + super(db, root); + + l.debug('Created Trie'); + } +} diff --git a/packages/trie-db/src/nibbles/fromU8a.ts b/packages/trie-db/src/nibbles/fromU8a.ts new file mode 100644 index 000000000..6382dcc35 --- /dev/null +++ b/packages/trie-db/src/nibbles/fromU8a.ts @@ -0,0 +1,17 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +export default function nibblesFromU8a (key: Uint8Array | Buffer): Array { + const nibbles = []; + + for (let i = 0; i < key.length; i++) { + const q = i * 2; + + nibbles[q] = key[i] >> 4; + nibbles[q + 1] = key[i] % 16; + } + + return nibbles; +} diff --git a/packages/trie-db/src/nibbles/index.ts b/packages/trie-db/src/nibbles/index.ts new file mode 100644 index 000000000..19df12f41 --- /dev/null +++ b/packages/trie-db/src/nibbles/index.ts @@ -0,0 +1,15 @@ +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import nibblesFromU8a from './fromU8a'; +import nibblesIsEqual from './isEqual'; +import nibblesMatchingLength from './matchingLength'; +import nibblesToU8a from './toU8a'; + +export { + nibblesFromU8a, + nibblesIsEqual, + nibblesMatchingLength, + nibblesToU8a +}; diff --git a/packages/trie-db/src/nibbles/isEqual.ts b/packages/trie-db/src/nibbles/isEqual.ts new file mode 100644 index 000000000..2183cb291 --- /dev/null +++ b/packages/trie-db/src/nibbles/isEqual.ts @@ -0,0 +1,12 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import matchingLength from './matchingLength'; + +export default function isEqual (keyA: Array, keyB: Array) { + const length = matchingLength(keyA, keyB); + + return length === keyA.length && length === keyB.length; +} diff --git a/packages/trie-db/src/nibbles/matchingLength.ts b/packages/trie-db/src/nibbles/matchingLength.ts new file mode 100644 index 000000000..3d477c69c --- /dev/null +++ b/packages/trie-db/src/nibbles/matchingLength.ts @@ -0,0 +1,14 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +export default function matchingLength (nib1: Array, nib2: Array): number { + let index = 0; + + while (nib1[index] === nib2[index] && nib1.length > index) { + index++; + } + + return index; +} diff --git a/packages/trie-db/src/nibbles/toU8a.ts b/packages/trie-db/src/nibbles/toU8a.ts new file mode 100644 index 000000000..2b151cfe1 --- /dev/null +++ b/packages/trie-db/src/nibbles/toU8a.ts @@ -0,0 +1,16 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +export default function nibblesToU8a (arr: Array): Uint8Array { + const u8a = new Uint8Array(arr.length / 2); + + for (let i = 0; i < u8a.length; i++) { + const q = i * 2; + + u8a[i] = (arr[q] << 4) + arr[q + 1]; + } + + return u8a; +} diff --git a/packages/trie-db/src/nodeFactory.ts b/packages/trie-db/src/nodeFactory.ts new file mode 100644 index 000000000..e22fee893 --- /dev/null +++ b/packages/trie-db/src/nodeFactory.ts @@ -0,0 +1,91 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import { Logger } from '@polkadot/util/types'; +import { DecodedRlp, Trie$Node, Trie$Node$Type } from './types'; + +import logger from '@polkadot/util/logger'; +import u8aToHex from '@polkadot/util/u8a/toHex'; + +import nibblesFromU8a from './nibbles/fromU8a'; +import rlpToString from './util/rlpToString'; + +import TrieNode from './Node'; + +const l = logger('trie/node'); + +/** + * Determines the node type. + * @returns {String} - the node type + * - leaf - if the node is a leaf + * - branch - if the node is a branch + * - extention - if the node is an extention + */ +function getNodeType (node: DecodedRlp): Trie$Node$Type { + if (node.length === 17) { + return 'branch'; + } + + if (node.length === 2) { + const key = nibblesFromU8a(node[0] as Uint8Array); + + if (key[0] > 1) { + return 'leaf'; + } + + return 'extention'; + } + + throw new Error(`Unable to determine Node type`); +} + +function fromBranch (l: Logger) { + return (rlp: DecodedRlp): Trie$Node => { + l.debug(() => ['fromBranch']); + + const node = new TrieNode('branch', Array.apply(null, Array(17))); + + // NOTE Removed since + // (1) 'branch' is never called with any keys, + // (b) `this.set` points to what exactly? + // if (key) { + // key.forEach(function (keyVal) { + // this.set.apply(this, keyVal); + // }); + // } + + return node; + }; +} + +function fromRaw (l: Logger) { + return (rlp: DecodedRlp): Trie$Node => { + l.debug(() => ['fromRaw ->', rlpToString(rlp)]); + + const node = new TrieNode(getNodeType(rlp), rlp); + + return node; + }; +} + +function fromType (l: Logger, type: Trie$Node$Type) { + return (key: Uint8Array, value: Uint8Array): Trie$Node => { + l.debug(() => ['fromType', 'type ->', type, 'key ->', u8aToHex(key), 'value ->', u8aToHex(value)]); + + const node = new TrieNode(type, Array(2)); + + node.setValue(value); + node.setKey(key); + + return node; + }; +} + +export default { + fromBranch: fromBranch(l), + fromExtention: fromType(l, 'extention'), + fromLeaf: fromType(l, 'leaf'), + fromRaw: fromRaw(l) +}; diff --git a/packages/trie-db/src/proof/index.ts b/packages/trie-db/src/proof/index.ts new file mode 100644 index 000000000..ac760afbe --- /dev/null +++ b/packages/trie-db/src/proof/index.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import prove from './prove'; +import verifyProof from './verifyProof'; + +export { + prove, + verifyProof +}; diff --git a/packages/trie-db/src/proof/prove.ts b/packages/trie-db/src/proof/prove.ts new file mode 100644 index 000000000..5565dba63 --- /dev/null +++ b/packages/trie-db/src/proof/prove.ts @@ -0,0 +1,35 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import assert from '@polkadot/util/assert'; + +/** + * Returns a merkle proof for a given key + * @method Trie.prove + * @param {Trie} trie + * @param {String} key + * @return Promise<{Array.}> `proof` + */ +// @ts-ignore FIXME, we need to properly check the full file +export default async function prove (trie, key) { + const result = await trie.findPath(key); + + assert(result, 'findPath does not contain a valid path'); + + const { remainder, stack } = result; + + assert(remainder.length === 0, 'Node does not contain the key'); + + // @ts-ignore FIXME, we need to properly check the full file + return stack.reduce((proofs, node, index) => { + const rlp = node.serialize(); + + if ((rlp.length >= 32) || (index === 0)) { + proofs.push(rlp); + } + + return proofs; + }, []); +} diff --git a/packages/trie-db/src/proof/verifyProof.ts b/packages/trie-db/src/proof/verifyProof.ts new file mode 100644 index 000000000..0b4ba534e --- /dev/null +++ b/packages/trie-db/src/proof/verifyProof.ts @@ -0,0 +1,85 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import assert from '@polkadot/util/assert'; +import decodeRlp from '@polkadot/util-rlp/decode'; +import keccakAsU8a from '@polkadot/util-crypto/keccak/asU8a'; + +import { nibblesMatchingLength, nibblesFromU8a } from '../nibbles'; +import nodeFactory from '../nodeFactory'; + +/** + * Verifies a merkle proof for a given key + * @method Trie.verifyProof + * @param {Buffer | Uint8Array} rootHash + * @param {String} key + * @param {Array.} proof + * @returns Promise<{String}> + */ +// @ts-ignore FIXME, we need to properly check the full file +export default async function verifyProof (rootHash, _key, proofs) { + const lastIndex = proofs.length - 1; + let key = nibblesFromU8a(_key); + let wantedHash = rootHash; + + for (let i = 0; i < proofs.length; i++) { + const proof = proofs[i]; + const hash = keccakAsU8a(proof); + + assert(hash.toString() === wantedHash.toString(), `Bad proof node ${i}: hash mismatch`); + + // @ts-ignore FIXME, we need to properly check the full file + const node = nodeFactory.fromRaw(decodeRlp(proof)); + let cld; + + if (node.type === 'branch') { + if (key.length === 0) { + assert(i === lastIndex, 'Additional nodes at end of proof (branch)'); + + return node.value; + } + + cld = node.raw[key[0]]; + key = key.slice(1); + + if (cld.length === 2) { + // @ts-ignore FIXME, we need to properly check the full file + const embeddedNode = nodeFactory.fromRaw(cld); + + assert(i === lastIndex, 'Additional nodes at end of proof (embeddedNode)'); + // @ts-ignore FIXME, we need to properly check the full file + assert(nibblesMatchingLength(embeddedNode.key, key) === embeddedNode.key.length, 'Key length does not match with the proof one (embeddedNode)'); + + // @ts-ignore FIXME, we need to properly check the full file + key = key.slice(embeddedNode.key.length); + + assert(key.length === 0, 'Key does not match with the proof one (embeddedNode)'); + + return embeddedNode.value; + } else { + wantedHash = cld; + } + } else if ((node.type === 'extention') || (node.type === 'leaf')) { + // @ts-ignore FIXME, we need to properly check the full file + assert(nibblesMatchingLength(node.key, key) === node.key.length, 'Key does not match with the proof one (extention|leaf)'); + + cld = node.value; + // @ts-ignore FIXME, we need to properly check the full file + key = key.slice(node.key.length); + + if (key.length === 0) { + assert(i === lastIndex, 'Additional nodes at end of proof (extention|leaf)'); + + return cld; + } else { + wantedHash = cld; + } + } else { + throw new Error('Invalid node type'); + } + } + + throw new Error('Unexpected end of proof'); +} diff --git a/packages/trie-db/src/streams/ScratchRead.ts b/packages/trie-db/src/streams/ScratchRead.ts new file mode 100644 index 000000000..7f4fdac61 --- /dev/null +++ b/packages/trie-db/src/streams/ScratchRead.ts @@ -0,0 +1,58 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import { Trie$Base } from '../types'; + +// @ts-ignore FIXME, we need to properly check the full file +import { Readable } from 'readable-stream'; +import logger from '@polkadot/util/logger'; +import u8aToHex from '@polkadot/util/u8a/toHex'; + +import rlpToString from '../util/rlpToString'; + +const l = logger('trie/scratch'); + +export default class ScratchReadStream extends Readable { + trie: Trie$Base; + next: null; // FIXME + // @ts-ignore FIXME, we need to properly check the full file + _started: boolean; + + constructor (trie: Trie$Base) { + super({ objectMode: true }); + + this.trie = trie; + this.next = null; + } + + _read () { + if (this._started) { + return; + } + + const onDone = () => { + l.debug(() => 'onDone'); + // @ts-ignore FIXME, we need to properly check the full file + this.push(null); + }; + // @ts-ignore FIXME, we need to properly check the full file + const onFound = (nodeRef, node, key, next) => { + l.debug(() => ['onFound', u8aToHex(nodeRef), node.type, rlpToString(node.raw)]); + + // @ts-ignore FIXME, we need to properly check the full file + this.push({ + key: nodeRef, + value: node.serialize() + }); + + next(); + }; + + l.debug(() => 'Starting stream'); + + this._started = true; + this.trie._findDbNodes(onFound, onDone); + } +} diff --git a/packages/trie-db/src/streams/TrieRead.ts b/packages/trie-db/src/streams/TrieRead.ts new file mode 100644 index 000000000..7f9e84374 --- /dev/null +++ b/packages/trie-db/src/streams/TrieRead.ts @@ -0,0 +1,59 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import { Trie$Base } from '../types'; + +// @ts-ignore FIXME, we need to properly check the full file +import { Readable } from 'readable-stream'; +import logger from '@polkadot/util/logger'; +import u8aToHex from '@polkadot/util/u8a/toHex'; + +import { nibblesToU8a } from '../nibbles'; + +const l = logger('trie/read'); + +export default class TrieReadStream extends Readable { + trie: Trie$Base; + next: null; // FIXME + // @ts-ignore FIXME, we need to properly check the full file + _started: boolean; + + constructor (trie: Trie$Base) { + super({ objectMode: true }); + + this.trie = trie; + this.next = null; + this._started = false; + } + + _read () { + if (this._started) { + return; + } + + const onDone = () => { + l.debug(() => 'onDone'); + // @ts-ignore FIXME, we need to properly check the full file + this.push(null); + }; + // @ts-ignore FIXME, we need to properly check the full file + const onFound = (nodeRef, node, nibbles, next) => { + l.debug(() => ['onFound', nibbles, u8aToHex(node.value)]); + + // @ts-ignore FIXME, we need to properly check the full file + this.push({ + key: nibblesToU8a(nibbles), + value: node.value + }); + + next(); + }; + + l.debug(() => 'Starting stream'); + + this._started = true; + this.trie._findValueNodes(onFound, onDone); + } +} diff --git a/packages/trie-db/src/types.d.ts b/packages/trie-db/src/types.d.ts new file mode 100644 index 000000000..4592cf6f8 --- /dev/null +++ b/packages/trie-db/src/types.d.ts @@ -0,0 +1,28 @@ +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +export type Callback = (error?: Error | null, result?: any) => void; + +// NOTE This is actually DecodedRlp = Array, but since the decoder is relatively simple, we get away with the definition below +export type DecodedRlp = Array>; + +export type Trie$Node$Type = 'branch' | 'extention' | 'leaf'; + +export interface Trie$Node { + hash: () => Uint8Array, + serialize: () => Uint8Array, + + raw: DecodedRlp, + type: Trie$Node$Type, + value: Uint8Array +} + +type Trie$Find$OnResult = (nodeRef: Uint8Array, node: Trie$Node, nibbles: Array, next: () => void) => void; + +export type Trie$Base = { + _findDbNodes (onResult: Trie$Find$OnResult, onDone: Callback): void, + _findValueNodes (onResult: Trie$Find$OnResult, onDone: Callback): void +}; + +export type SemaphorePromise = (fn: () => Promise) => Promise; diff --git a/packages/trie-db/src/util/isRawNode.ts b/packages/trie-db/src/util/isRawNode.ts new file mode 100644 index 000000000..77bf6f021 --- /dev/null +++ b/packages/trie-db/src/util/isRawNode.ts @@ -0,0 +1,10 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import isU8a from '@polkadot/util/is/u8a'; + +export default function isRawNode (node: Array | Buffer | Uint8Array) { + return Array.isArray(node) && !isU8a(node); +} diff --git a/packages/trie-db/src/util/rlpToString.ts b/packages/trie-db/src/util/rlpToString.ts new file mode 100644 index 000000000..a35fa5787 --- /dev/null +++ b/packages/trie-db/src/util/rlpToString.ts @@ -0,0 +1,19 @@ +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import { DecodedRlp } from '../types'; + +import assert from '@polkadot/util/assert'; +import isU8a from '@polkadot/util/is/u8a'; +import u8aToHex from '@polkadot/util/u8a/toHex'; + +export default function rlpToString (rlp: Uint8Array | DecodedRlp): string { + if (Array.isArray(rlp)) { + return `[ ${rlp.map(rlpToString).join(', ')} ]`; + } + + assert(isU8a(rlp), `Expected Array | Uint8Array inside rlp, found type '${typeof rlp}'`); + + return u8aToHex(rlp); +} diff --git a/packages/trie-db/src/util/semaphore.ts b/packages/trie-db/src/util/semaphore.ts new file mode 100644 index 000000000..a826b516e --- /dev/null +++ b/packages/trie-db/src/util/semaphore.ts @@ -0,0 +1,27 @@ +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import { SemaphorePromise } from '../types'; + +import semaphore from 'semaphore'; + +export default function semaphorePromise (max: number): SemaphorePromise { + const _semaphore = semaphore(max); + + return (fn: () => Promise): Promise => { + return new Promise((resolve, reject) => { + _semaphore.take(async () => { + try { + const result = await fn(); + + _semaphore.leave(); + resolve(result); + } catch (error) { + _semaphore.leave(); + reject(error); + } + }); + }); + }; +} diff --git a/packages/trie-db/src/util/taskExecutor.ts b/packages/trie-db/src/util/taskExecutor.ts new file mode 100644 index 000000000..e96778d01 --- /dev/null +++ b/packages/trie-db/src/util/taskExecutor.ts @@ -0,0 +1,53 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +type Task$Fn = (taskCb: (value: any) => any) => any; + +type Task = { + fn: Task$Fn, + priority: number, + reject: (error: Error) => void, + resolve: (value: any) => void, +} + +// https://github.com/ethereumjs/merkle-patricia-tree/pull/38 +export default function taskExecutor (maxPoolSize: number) { + let currentPoolSize = 0; + const queue: Array = []; + + const execute = (task: Task | undefined) => { + if (task === undefined) { + return; + } + + if (currentPoolSize < maxPoolSize) { + currentPoolSize++; + + task.fn((value: any): void => { + currentPoolSize--; + + task.resolve(value); + + if (queue.length > 0) { + queue.sort((a, b) => + b.priority - a.priority + ); + + execute(queue.shift()); + } + }); + + return; + } + + queue.push(task); + }; + + return (priority: number, fn: Task$Fn): Promise => { + return new Promise((resolve, reject) => { + execute({ fn, reject, resolve, priority }); + }); + }; +} diff --git a/packages/trie-db/test/checkpoints.spec.js b/packages/trie-db/test/checkpoints.spec.js new file mode 100644 index 000000000..aa2f07c05 --- /dev/null +++ b/packages/trie-db/test/checkpoints.spec.js @@ -0,0 +1,66 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import toU8a from '@polkadot/util/u8a/toU8a'; + +import Trie from '../src/index'; + +describe('testing checkpoints', () => { + let trie, preRoot, postRoot; + + it('sets up the trie', async () => { + trie = new Trie(); + + await trie.put(toU8a('do'), toU8a('verb')); + await trie.put(toU8a('doge'), toU8a('coin')); + + preRoot = trie.root; + }); + + it('should create a checkpoint', async () => { + await trie.checkpoint(); + }); + + it('should save to the cache', async () => { + await trie.put(toU8a('test'), toU8a('something')); + await trie.put(toU8a('love'), toU8a('emotion')); + + postRoot = trie.root; + }); + + it('should revert to the orginal root', async () => { + expect(trie.isCheckpoint).toEqual(true); + + await trie.revert(); + + expect(trie.root).toEqual(preRoot); + expect(trie.isCheckpoint).toEqual(false); + }); + + it('should commit a checkpoint', async () => { + await trie.checkpoint(); + await trie.put(toU8a('test'), toU8a('something')); + await trie.put(toU8a('love'), toU8a('emotion')); + await trie.commit(); + + expect(trie.isCheckpoint).toEqual(false); + expect(trie.root).toEqual(postRoot); + }); + + it('should commit a nested checkpoint', async () => { + await trie.checkpoint(); + await trie.put(toU8a('test'), toU8a('something else')); + + const root = trie.root; + + await trie.checkpoint(); + await trie.put(toU8a('the feels'), toU8a('emotion')); + await trie.revert(); + await trie.commit(); + + expect(trie.isCheckpoint).toEqual(false); + expect(trie.root).toEqual(root); + }); +}); diff --git a/packages/trie-db/test/ethereum.spec.js b/packages/trie-db/test/ethereum.spec.js new file mode 100644 index 000000000..61eca5fac --- /dev/null +++ b/packages/trie-db/test/ethereum.spec.js @@ -0,0 +1,41 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import u8aToHex from '@polkadot/util/u8a/toHex'; +import toU8a from '@polkadot/util/u8a/toU8a'; +import keccakAsU8a from '@polkadot/util-crypto/keccak/asU8a'; +import encodeRlp from '@polkadot/util-rlp/encode'; + +import Trie from '../src/index'; + +describe('it should create the genesis state root from ethereum', () => { + const trie4 = new Trie(); + const g = toU8a('0x8a40bfaa73256b60764c1bf40675a99083efb075'); + const j = toU8a('0xe6716f9544a56c530d868e4bfbacb172315bdead'); + const v = toU8a('0x1e12515ce3e0f817a4ddef9ca55788a1d66bd2df'); + const a = toU8a('0x1a26338f0d905e295fccb71fa9ea849ffa12aaf4'); + const stateRoot = new Uint8Array(32); + const startAmount = new Uint8Array(26); + + startAmount[0] = 1; + + const account = [startAmount, 0, stateRoot, keccakAsU8a(new Uint8Array())]; + const genesisStateRoot = '0x2f4399b08efe68945c1cf90ffe85bbe3ce978959da753f9e649f034015b8817d'; + const cppRlp = '0xf85e9a010000000000000000000000000000000000000000000000000080a00000000000000000000000000000000000000000000000000000000000000000a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'; + const rlpAccount = encodeRlp(account); + + it('matches the initial rlp', () => { + expect(cppRlp).toEqual(u8aToHex(rlpAccount)); + }); + + it('shall match the root', async () => { + await trie4.put(g, rlpAccount); + await trie4.put(j, rlpAccount); + await trie4.put(v, rlpAccount); + await trie4.put(a, rlpAccount); + + expect(u8aToHex(trie4.root)).toEqual(genesisStateRoot); + }); +}); diff --git a/packages/trie-db/test/index.spec.js b/packages/trie-db/test/index.spec.js new file mode 100644 index 000000000..08637c069 --- /dev/null +++ b/packages/trie-db/test/index.spec.js @@ -0,0 +1,205 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import u8aToHex from '@polkadot/util/u8a/toHex'; +import toU8a from '@polkadot/util/u8a/toU8a'; + +import Trie from '../src/index'; + +describe('simple save and retrive', () => { + it('should not crash if given a non-existant root', async () => { + const root = toU8a('0x3f4399b08efe68945c1cf90ffe85bbe3ce978959da753f9e649f034015b8817d'); + const trie = new Trie(null, root); + const value = await trie.get(toU8a('test')); + + expect(value).toEqual(null); + }); + + var trie = new Trie(); + + it('save a value', async () => { + await trie.put(toU8a('test'), toU8a('one')); + }); + + it('should get a value', async () => { + const value = await trie.get(toU8a('test')); + + expect(value).toEqual(toU8a('one')); + }); + + it('should update a value', async () => { + await trie.put(toU8a('test'), toU8a('two')); + + const value = await trie.get(toU8a('test')); + + expect(value).toEqual(toU8a('two')); + }); + + it('should delete a value', async () => { + await trie.del(toU8a('test')); + + const value = await trie.get(toU8a('test')); + + expect(value).toEqual(null); + }); + + it('should recreate a value', async () => { + await trie.put(toU8a('test'), toU8a('one')); + }); + + it('should get updated a value', async () => { + const value = await trie.get(toU8a('test')); + + expect(value).toEqual(toU8a('one')); + }); + + it('should create a branch here', async () => { + await trie.put(toU8a('doge'), toU8a('coin')); + + expect( + toU8a('0xde8a34a8c1d558682eae1528b47523a483dd8685d6db14b291451a66066bf0fc') + ).toEqual(trie.root); + }); + + it('should get a value that is in a branch', async () => { + const value = await trie.get(toU8a('doge')); + + expect(value).toEqual(toU8a('coin')); + }); + + it('should delete from a branch', async () => { + await trie.del(toU8a('doge')); + + const value = await trie.get(toU8a('doge')); + + expect(value).toEqual(null); + }); +}); + +describe('storing longer values', () => { + const trie = new Trie(); + const longString = 'this will be a really really really long value'; + const longStringRoot = '0xb173e2db29e79c78963cff5196f8a983fbe0171388972106b114ef7f5c24dfa3'; + + it('should store a longer string', async () => { + await trie.put(toU8a('done'), toU8a(longString)); + await trie.put(toU8a('doge'), toU8a('coin')); + + expect(longStringRoot).toEqual(u8aToHex(trie.root)); + }); + + it('should retreive a longer value', async () => { + const value = await trie.get(toU8a('done')); + + expect(value).toEqual(toU8a(longString)); + }); + + it('should when being modiefied delete the old value', async () => { + await trie.put(toU8a('done'), toU8a('test')); + }); +}); + +describe('testing Extentions and branches', () => { + const trie = new Trie(); + + it('should store a value', async () => { + await trie.put(toU8a('doge'), toU8a('coin')); + }); + + it('should create extention to store this value', async () => { + await trie.put(toU8a('do'), toU8a('verb')); + + expect( + toU8a('0xf803dfcb7e8f1afd45e88eedb4699a7138d6c07b71243d9ae9bff720c99925f9') + ).toEqual(trie.root); + }); + + it('should store this value under the extention ', async () => { + await trie.put(toU8a('done'), toU8a('finished')); + + expect( + '0x409cff4d820b394ed3fb1cd4497bdd19ffa68d30ae34157337a7043c94a3e8cb' + ).toEqual(u8aToHex(trie.root)); + }); +}); + +describe('testing Extentions and branches - reverse', () => { + const trie = new Trie(); + + it('should create extention to store this value', async () => { + await trie.put(toU8a('do'), toU8a('verb')); + + const value = await trie.get(toU8a('do')); + + expect(value).toEqual(toU8a('verb')); + }); + + it('should store a value', async () => { + await trie.put(toU8a('doge'), toU8a('coin')); + }); + + it('should store this value under the extention ', async () => { + await trie.put(toU8a('done'), toU8a('finished')); + + expect( + '0x409cff4d820b394ed3fb1cd4497bdd19ffa68d30ae34157337a7043c94a3e8cb' + ).toEqual(u8aToHex(trie.root)); + }); +}); + +describe('testing deletions cases', () => { + const trie = new Trie(); + + it('should delete from a branch->branch-branch', async () => { + await Promise.all([ + trie.put(new Uint8Array([11, 11, 11]), toU8a('first')), + trie.put(new Uint8Array([12, 22, 22]), toU8a('create the first branch')), + trie.put(new Uint8Array([12, 34, 44]), toU8a('create the last branch')) + ]); + await trie.del(new Uint8Array([12, 22, 22])); + + const value = await trie.get(new Uint8Array([12, 22, 22])); + + expect(null).toEqual(value); + }); + + it('should delete from a branch->branch-extention', async () => { + await Promise.all([ + trie.put(new Uint8Array([11, 11, 11]), toU8a('first')), + trie.put(new Uint8Array([12, 22, 22]), toU8a('create the first branch')), + trie.put(new Uint8Array([12, 33, 33]), toU8a('create the middle branch')), + trie.put(new Uint8Array([12, 33, 44]), toU8a('create the last branch')) + ]); + await trie.del(new Uint8Array([12, 22, 22])); + + const value = await trie.get(new Uint8Array([12, 22, 22])); + + expect(null).toEqual(value); + }); + + it('should delete from a extention->branch-extention', async () => { + await trie.put(new Uint8Array([11, 11, 11]), toU8a('first')); + await trie.put(new Uint8Array([12, 22, 22]), toU8a('create the first branch')); + await trie.put(new Uint8Array([12, 33, 33]), toU8a('create the middle branch')); + await trie.put(new Uint8Array([12, 33, 44]), toU8a('create the last branch')); + await trie.del(new Uint8Array([11, 11, 11])); + + const value = await trie.get(new Uint8Array([11, 11, 11])); + + expect(null).toEqual(value); + }); + + it('should delete from a extention->branch-branch', async () => { + await trie.put(new Uint8Array([11, 11, 11]), toU8a('first')); + await trie.put(new Uint8Array([12, 22, 22]), toU8a('create the first branch')); + await trie.put(new Uint8Array([12, 33, 33]), toU8a('create the middle branch')); + await trie.put(new Uint8Array([12, 34, 44]), toU8a('create the last branch')); + await trie.del(new Uint8Array([11, 11, 11])); + + const value = await trie.get(new Uint8Array([11, 11, 11])); + + expect(null).toEqual(value); + }); +}); diff --git a/packages/trie-db/test/offical.spec.js b/packages/trie-db/test/offical.spec.js new file mode 100644 index 000000000..cefe97727 --- /dev/null +++ b/packages/trie-db/test/offical.spec.js @@ -0,0 +1,63 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import toU8a from '@polkadot/util/u8a/toU8a'; +import u8aToHex from '@polkadot/util/u8a/toHex'; + +import Trie from '../src/index'; +import { tests } from 'ethereumjs-testing'; + +const jsonTests = tests.trieTests; + +describe('official tests', () => { + let trie; + + beforeEach(() => { + trie = new Trie(); + }); + + describe('ordered tests', () => { + const testNames = Object.keys(jsonTests.trietest); + + testNames.forEach((name) => { + it(name, async () => { + await Promise.all( + jsonTests.trietest[name].in.map((input) => + trie.put(toU8a(input[0]), toU8a(input[1])) + ) + ); + + expect( + u8aToHex(trie.root) + ).toEqual( + jsonTests.trietest[name].root + ); + }); + }); + }); + + describe('unordered tests', () => { + const testNames = Object.keys(jsonTests.trieanyorder); + + testNames.forEach((name) => { + const test = jsonTests.trieanyorder[name]; + const keys = Object.keys(test.in); + + it(name, async () => { + await Promise.all( + keys.map((key) => + trie.put(toU8a(key), toU8a(test.in[key])) + ) + ); + + expect( + u8aToHex(trie.root) + ).toEqual( + test.root + ); + }); + }); + }); +}); diff --git a/packages/trie-db/test/polkadotRefactor.spec.js b/packages/trie-db/test/polkadotRefactor.spec.js new file mode 100644 index 000000000..f924dd560 --- /dev/null +++ b/packages/trie-db/test/polkadotRefactor.spec.js @@ -0,0 +1,94 @@ +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import u8aToHex from '@polkadot/util/u8a/toHex'; +import toU8a from '@polkadot/util/u8a/toU8a'; + +import Trie from '../src/index'; + +const EMPTY_ROOT = '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421'; +const HELLO_ROOT = '0x0a915659b88f80bfa200570bd2767a6ab8cb0a4e44fd240cc5ed7a27728c4531'; +const FOO_ROOT = '0xed4e32371288ee83be74f78fb492f01261b7c3dc9c422581bb705c4376492dc6'; + +describe('@polkadot refactoring', () => { + const trie = new Trie(); + + it('has the correct starting trieroot', () => { + expect( + u8aToHex(trie.root) + ).toEqual( + EMPTY_ROOT + ); + }); + + it('has the correct root after a single insertion', async () => { + await trie.put(toU8a('hello'), toU8a('world')); + + expect( + u8aToHex(trie.root) + ).toEqual( + HELLO_ROOT + ); + }); + + it('has the correct root after a deletion', async () => { + await trie.del(toU8a('hello')); + + expect( + u8aToHex(trie.root) + ).toEqual( + EMPTY_ROOT + ); + }); + + it('has the correct root after a re-insertion', async () => { + await trie.put(toU8a('hello'), toU8a('world')); + + expect( + u8aToHex(trie.root) + ).toEqual( + HELLO_ROOT + ); + }); + + it('has the correct root after a second insertion', async () => { + await trie.put(toU8a('foo'), toU8a('bar')); + + expect( + u8aToHex(trie.root) + ).toEqual( + FOO_ROOT + ); + }); + + it('has the correct root after a re-deletion', async () => { + await trie.del(toU8a('hello')); + + expect( + u8aToHex(trie.root) + ).toEqual( + '0x99650c730bbb99f6f58ce8b09bca2a8d90b36ac662e71bf81ec401ed23d199fb' + ); + }); + + it('has the correct root after a re-re-insertion', async () => { + await trie.put(toU8a('hello'), toU8a('world')); + + expect( + u8aToHex(trie.root) + ).toEqual( + FOO_ROOT + ); + }); + + it('has the correct root after an update', async () => { + await trie.put(toU8a('hello'), toU8a('mars')); + + expect( + u8aToHex(trie.root) + ).toEqual( + '0x116267e482ab94eb8824af425ea7f20ee84d10a8fa735f26204d80000e2a907e' + ); + }); +}); diff --git a/packages/trie-db/test/proof.spec.js b/packages/trie-db/test/proof.spec.js new file mode 100644 index 000000000..18dc13736 --- /dev/null +++ b/packages/trie-db/test/proof.spec.js @@ -0,0 +1,106 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import toU8a from '@polkadot/util/u8a/toU8a'; +import u8aToUtf8 from '@polkadot/util/u8a/toUtf8'; + +import Trie from '../src/index'; + +describe('simple merkle proofs generation and verification', () => { + it('create a merkle proof and verify it with a single short key', async () => { + const trie = new Trie(); + + await trie.put(toU8a('key1aa'), toU8a('01234')); + + const prove = await Trie.prove(trie, toU8a('key1aa')); + const value = await Trie.verifyProof(trie.root, toU8a('key1aa'), prove); + + expect(u8aToUtf8(value)).toEqual('01234'); + }); + + it('create a merkle proof and verify it with a single long key', async () => { + const trie = new Trie(); + + await trie.put(toU8a('key1aa'), toU8a('0123456789012345678901234567890123456789xx')); + + const prove = await Trie.prove(trie, toU8a('key1aa')); + const value = await Trie.verifyProof(trie.root, toU8a('key1aa'), prove); + + expect(u8aToUtf8(value)).toEqual('0123456789012345678901234567890123456789xx'); + }); + + it('create a merkle proof and verify it', async () => { + const trie = new Trie(); + + await trie.put(toU8a('key1aa'), toU8a('0123456789012345678901234567890123456789xx')); + await trie.put(toU8a('key2bb'), toU8a('aval2')); + await trie.put(toU8a('key3cc'), toU8a('aval3')); + + let prove = await Trie.prove(trie, toU8a('key2bb')); + let value = await Trie.verifyProof(trie.root, toU8a('key2bb'), prove); + + expect(u8aToUtf8(value)).toEqual('aval2'); + + prove = await Trie.prove(trie, toU8a('key1aa')); + value = await Trie.verifyProof(trie.root, toU8a('key1aa'), prove); + + expect(u8aToUtf8(value)).toEqual('0123456789012345678901234567890123456789xx'); + + prove = await Trie.prove(trie, toU8a('key2bb')); + + try { + await Trie.verifyProof(trie.root, toU8a('randomkey'), prove); + expect('it should').toEqual('get here'); + } catch (error) { + expect(error).not.toEqual(null); + } + + prove = await Trie.prove(trie, toU8a('key2bb')); + + try { + await Trie.verifyProof(trie.root, toU8a('key2b'), prove); + expect('it should').toEqual('get here'); + } catch (error) { + expect(error).not.toEqual(null); + } + + prove = await Trie.prove(trie, toU8a('key2bb')); + + prove.push(toU8a('123456')); + + try { + await Trie.verifyProof(trie.root, toU8a('key2b'), prove); + expect('it should').toEqual('get here'); + } catch (error) { + expect(error).not.toEqual(null); + } + }); + + it('create a merkle proof and verify it with keys in the midle', async () => { + const trie = new Trie(); + + await trie.put(toU8a('key1aa'), toU8a('0123456789012345678901234567890123456789xxx')); + await trie.put(toU8a('key1'), toU8a('0123456789012345678901234567890123456789Very_Long')); + await trie.put(toU8a('key2bb'), toU8a('aval3')); + await trie.put(toU8a('key2'), toU8a('short')); + await trie.put(toU8a('key3cc'), toU8a('aval3')); + await trie.put(toU8a('key3'), toU8a('1234567890123456789012345678901')); + + let prove = await Trie.prove(trie, toU8a('key1')); + let value = await Trie.verifyProof(trie.root, toU8a('key1'), prove); + + expect(u8aToUtf8(value)).toEqual('0123456789012345678901234567890123456789Very_Long'); + + prove = await Trie.prove(trie, toU8a('key2')); + value = await Trie.verifyProof(trie.root, toU8a('key2'), prove); + + expect(u8aToUtf8(value)).toEqual('short'); + + prove = await Trie.prove(trie, toU8a('key3')); + value = await Trie.verifyProof(trie.root, toU8a('key3'), prove); + + expect(u8aToUtf8(value)).toEqual('1234567890123456789012345678901'); + }); +}); diff --git a/packages/trie-db/test/rawOPs.spec.js b/packages/trie-db/test/rawOPs.spec.js new file mode 100644 index 000000000..4300831a0 --- /dev/null +++ b/packages/trie-db/test/rawOPs.spec.js @@ -0,0 +1,72 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import randomAsU8a from '@polkadot/util-crypto/random/asU8a'; + +import Trie from '../src/index'; + +describe('put & get raw functions', () => { + var trie = new Trie(); + var key = randomAsU8a(32); + var val = randomAsU8a(32); + + it('putRaw', async () => { + await trie.putRaw(key, val); + }); + + it('getRaw', async () => { + const rVal = await trie.getRaw(key); + + expect(rVal).toEqual(val); + }); + + it('should checkpoint and get the rawVal', async () => { + await trie.checkpoint(); + + const rVal = await trie.getRaw(key); + + expect(rVal).toEqual(val); + }); + + var key2 = randomAsU8a(32); + var val2 = randomAsU8a(32); + + it('should store while in a checkpoint', async () => { + await trie.putRaw(key2, val2); + }); + + it('should retrieve from a checkpoint', async () => { + const rVal = await trie.getRaw(key2); + + expect(rVal).toEqual(val2); + }); + + it('should not retieve after revert', async () => { + await trie.revert(); + }); + + it('should delete raw', async () => { + await trie.delRaw(val2); + }); + + it('should not get val after delete ', async () => { + const rVal = await trie.getRaw(val2); + + expect(rVal).not.toBeDefined(); + }); + + var key3 = randomAsU8a(32); + var val3 = randomAsU8a(32); + + it('test commit behavoir', async () => { + await trie.checkpoint(); + await trie.putRaw(key3, val3); + await trie.commit(); + + const rVal = await trie.getRaw(key3); + + expect(rVal).toEqual(val3); + }); +}); diff --git a/packages/trie-db/test/streams.spec.js b/packages/trie-db/test/streams.spec.js new file mode 100644 index 000000000..daab147ea --- /dev/null +++ b/packages/trie-db/test/streams.spec.js @@ -0,0 +1,177 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import toU8a from '@polkadot/util/u8a/toU8a'; + +import Trie from '../src/index'; + +describe('kv stream test', () => { + var trie = new Trie(); + var init = [{ + type: 'del', + key: 'father' + }, { + type: 'put', + key: 'name', + value: 'Yuri Irsenovich Kim' + }, { + type: 'put', + key: 'dob', + value: '16 February 1941' + }, { + type: 'put', + key: 'spouse', + value: 'Kim Young-sook' + }, { + type: 'put', + key: 'occupation', + value: 'Clown' + }, { + type: 'put', + key: 'nameads', + value: 'Yuri Irsenovich Kim' + }, { + type: 'put', + key: 'namfde', + value: 'Yuri Irsenovich Kim' + }, { + type: 'put', + key: 'namsse', + value: 'Yuri Irsenovich Kim' + }, { + type: 'put', + key: 'dofab', + value: '16 February 1941' + }, { + type: 'put', + key: 'spoudse', + value: 'Kim Young-sook' + }, { + type: 'put', + key: 'occupdsation', + value: 'Clown' + }, { + type: 'put', + key: 'dozzzb', + value: '16 February 1941' + }, { + type: 'put', + key: 'spouszze', + value: 'Kim Young-sook' + }, { + type: 'put', + key: 'occupatdfion', + value: 'Clown' + }, { + type: 'put', + key: 'dssob', + value: '16 February 1941' + }, { + type: 'put', + key: 'spossuse', + value: 'Kim Young-sook' + }, { + type: 'put', + key: 'occupssation', + value: 'Clown' + }].map(({ type, key, value }) => ({ + type, + key: toU8a(key), + value: toU8a(value) + })); + + const valObj = init.reduce((result, { key, type, value }) => { + if (type === 'put') { + result[toU8a(key)] = toU8a(value); + } + + return result; + }, {}); + + it('should populate trie', async () => { + await trie.batch(init); + }); + + it('should fetch all of the nodes', (done) => { + const stream = trie.createReadStream(); + + stream.on('data', ({ key, value }) => { + expect(valObj[key]).toEqual(value); + + delete valObj[key]; + }); + + stream.on('end', () => { + const keys = Object.keys(valObj); + + expect(keys).toHaveLength(0); + done(); + }); + }); +}); + +describe('db stream test', () => { + var trie = new Trie(); + var init = [{ + type: 'put', + key: 'color', + value: 'purple' + }, { + type: 'put', + key: 'food', + value: 'sushi' + }, { + type: 'put', + key: 'fight', + value: 'fire' + }, { + type: 'put', + key: 'colo', + value: 'trolo' + }, { + type: 'put', + key: 'color', + value: 'blue' + }, { + type: 'put', + key: 'color', + value: 'pink' + }].map(({ type, key, value }) => ({ + type, + key: toU8a(key), + value: toU8a(value) + })); + + var expectedNodes = [ + '0x3c38d9aa6ad288c8e27da701e17fe99a5b67c8b12fd0469651c80494d36bc4c1', + '0xd5f61e1ff2b918d1c2a2c4b1732a3c68bd7e3fd64f35019f2f084896d4546298', + '0xe64329dadee2fb8a113b4c88cfe973aeaa9b523d4dc8510b84ca23f9d5bfbd90', + '0xc916d458bfb5f27603c5bd93b00f022266712514a59cde749f19220daffc743f', + '0x2386bfb0de9cf93902a110f5ab07b917ffc0b9ea599cb7f4f8bb6fd1123c866c' + ].reduce((result, hex) => { + result[toU8a(hex)] = true; + + return result; + }, {}); + + it('should populate trie', async () => { + await trie.checkpoint(); + await trie.batch(init); + }); + + it('should only fetch nodes in the current trie', (done) => { + const stream = trie.createScratchReadStream(); + + stream.on('data', ({ key }) => { + expect(!!expectedNodes[key]).toEqual(true); + delete expectedNodes[key]; + }); + + stream.on('end', () => { + expect(Object.keys(expectedNodes)).toHaveLength(0); + done(); + }); + }); +}); diff --git a/packages/trie-db/test/taskExecutor.spec.js b/packages/trie-db/test/taskExecutor.spec.js new file mode 100644 index 000000000..701a17785 --- /dev/null +++ b/packages/trie-db/test/taskExecutor.spec.js @@ -0,0 +1,30 @@ +// Copyright 2015-2018 authors & contributors of https://github.com/ethereumjs/merkle-patricia-tree +// Copyright 2017-2018 @polkadot/trie-db authors & contributors +// This software may be modified and distributed under the terms +// of the MPL-2.0 license. See the LICENSE file for details. + +import taskExecutor from '../src/util/taskExecutor'; + +const executor = taskExecutor(2); + +describe('taskExecutor', () => { + it('executes in order', async () => { + var tasks = [1, 2, 3, 4, 5, 6, 7]; + var executionOrder = []; + + await Promise.all( + tasks.map((priority) => + executor(priority, (cb) => { + executionOrder.push(priority); + setTimeout(cb, 50); + }) + ) + ); + + expect( + executionOrder + ).toEqual( + [1, 2, 7, 6, 5, 4, 3] + ); + }); +}); diff --git a/packages/util-triehash/LICENSE b/packages/trie-hash/LICENSE similarity index 91% rename from packages/util-triehash/LICENSE rename to packages/trie-hash/LICENSE index be137990d..09802fc0c 100644 --- a/packages/util-triehash/LICENSE +++ b/packages/trie-hash/LICENSE @@ -1,6 +1,6 @@ ISC License (ISC) -Copyright 2017-2018 @polkadot/util-triehash authors & contributors +Copyright 2017-2018 @polkadot/trie-hash authors & contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/packages/trie-hash/README.md b/packages/trie-hash/README.md new file mode 100644 index 000000000..93108e333 --- /dev/null +++ b/packages/trie-hash/README.md @@ -0,0 +1,17 @@ +[![polkadotjs](https://img.shields.io/badge/polkadot-js-orange.svg?style=flat-square)](https://polkadot.js.org) +![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) +[![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) +[![npm](https://img.shields.io/npm/v/@polkadot/trie-hash.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/trie-hash) +[![travis](https://img.shields.io/travis/polkadot-js/trie.svg?style=flat-square)](https://travis-ci.org/polkadot-js/trie) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/trie.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/trie/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/trie.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/trie?branch=master) +[![dependency](https://david-dm.org/polkadot-js/trie.svg?style=flat-square&path=packages/trie)](https://david-dm.org/polkadot-js/trie?path=packages/trie-hash) +[![devDependency](https://david-dm.org/polkadot-js/trie/dev-status.svg?style=flat-square&path=packages/trie-hash)](https://david-dm.org/polkadot-js/trie?path=packages/trie-hash#info=devDependencies) + +# @polkadot/trie-hash + +Calculate ordered and unordered [Ethereum Trie hashes](https://github.com/ethereum/wiki/wiki/Patricia-Tree) from inputs. + +## Available Utilities + +For a list of currently exposed methods, see the [library documentation](docs/README.md). diff --git a/packages/util-triehash/docs/README.md b/packages/trie-hash/docs/README.md similarity index 79% rename from packages/util-triehash/docs/README.md rename to packages/trie-hash/docs/README.md index ed22f7387..ca669df99 100644 --- a/packages/util-triehash/docs/README.md +++ b/packages/trie-hash/docs/README.md @@ -1,13 +1,13 @@ # Available interfaces -Utility methods to create [Ethereum Trie hashes](https://github.com/ethereum/wiki/wiki/Patricia-Tree) +Utility methods to create [Ethereum Trie hashes](https://github.com/ethereum/wiki/wiki/Patricia-Tree) # Available methods ## trieRoot -Creates a trie hash from the supplied pairs. +Creates a trie hash from the supplied pairs. ```js trieRoot (pairs: Trie$Pairs): Uint8Array @@ -18,7 +18,7 @@ From an `Array<{k: Uint8Array, v: Uint8Array}>` input, calculate the triehash an ```js import { u8aFromString } from '@polkadot/util'; -import { trieRoot } from '@polkadot/util-triehash'; +import { trieRoot } from '@polkadot/trie-hash'; trieRoot([{ k: u8aFromString('A'), @@ -28,7 +28,7 @@ v: u8aFromString('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') ## trieRootOrdered -Creates a trie hash from the supplied values. +Creates a trie hash from the supplied values. ```js trieRootOrdered (values: Array): Uint8Array @@ -39,10 +39,10 @@ From an `Array` input, calculate the ordered triehash and return the ```js import { u8aFromString } from '@polkadot/util'; -import { trieRootOrdered } from '@polkadot/util-triehash'; +import { trieRootOrdered } from '@polkadot/trie-hash'; trieRootOrdered([ u8aFromString('doe'), u8aFromString('reindeer') ]) // => 0xe766d5d51b89dc39d981b41bda63248d7abce4f0225eefd023792a540bcffee3 -``` \ No newline at end of file +``` diff --git a/packages/util-triehash/package.json b/packages/trie-hash/package.json similarity index 65% rename from packages/util-triehash/package.json rename to packages/trie-hash/package.json index e5a69fae5..6cf80ca78 100644 --- a/packages/util-triehash/package.json +++ b/packages/trie-hash/package.json @@ -1,6 +1,6 @@ { - "name": "@polkadot/util-triehash", - "version": "0.24.9", + "name": "@polkadot/trie-hash", + "version": "0.25.0", "description": "Creation of triehash values", "main": "index.js", "keywords": [ @@ -21,12 +21,12 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/polkadot-js/util.git" + "url": "git+https://github.com/polkadot-js/common.git" }, "bugs": { - "url": "https://github.com/polkadot-js/util/issues" + "url": "https://github.com/polkadot-js/common/issues" }, - "homepage": "https://github.com/polkadot-js/util/tree/master/packages/util-triehash#readme", + "homepage": "https://github.com/polkadot-js/common/tree/master/packages/trie-hash#readme", "scripts": { "build": "polkadot-dev-build-babel && polkadot-dev-build-docs", "check": "eslint src && flow check", @@ -34,8 +34,8 @@ }, "dependencies": { "@babel/runtime": "^7.0.0-beta.51", - "@polkadot/util": "^0.24.9", - "@polkadot/util-crypto": "^0.24.9", - "@polkadot/util-rlp": "^0.24.9" + "@polkadot/util": "^0.25.0", + "@polkadot/util-crypto": "^0.25.0", + "@polkadot/util-rlp": "^0.25.0" } } diff --git a/packages/util-triehash/src/encode/.nodoc b/packages/trie-hash/src/encode/.nodoc similarity index 100% rename from packages/util-triehash/src/encode/.nodoc rename to packages/trie-hash/src/encode/.nodoc diff --git a/packages/util-triehash/src/encode/aux.ts b/packages/trie-hash/src/encode/aux.ts similarity index 88% rename from packages/util-triehash/src/encode/aux.ts rename to packages/trie-hash/src/encode/aux.ts index 79e21a3f4..d8c89fcc6 100644 --- a/packages/util-triehash/src/encode/aux.ts +++ b/packages/trie-hash/src/encode/aux.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/encode/hexPrefix.spec.js b/packages/trie-hash/src/encode/hexPrefix.spec.js similarity index 95% rename from packages/util-triehash/src/encode/hexPrefix.spec.js rename to packages/trie-hash/src/encode/hexPrefix.spec.js index 426380909..e8167d09b 100644 --- a/packages/util-triehash/src/encode/hexPrefix.spec.js +++ b/packages/trie-hash/src/encode/hexPrefix.spec.js @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/encode/hexPrefix.ts b/packages/trie-hash/src/encode/hexPrefix.ts similarity index 88% rename from packages/util-triehash/src/encode/hexPrefix.ts rename to packages/trie-hash/src/encode/hexPrefix.ts index b81355947..a2069990c 100644 --- a/packages/util-triehash/src/encode/hexPrefix.ts +++ b/packages/trie-hash/src/encode/hexPrefix.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/encode/index.ts b/packages/trie-hash/src/encode/index.ts similarity index 92% rename from packages/util-triehash/src/encode/index.ts rename to packages/trie-hash/src/encode/index.ts index a06f45b2f..0ac2029b1 100644 --- a/packages/util-triehash/src/encode/index.ts +++ b/packages/trie-hash/src/encode/index.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/encode/pairs.ts b/packages/trie-hash/src/encode/pairs.ts similarity index 93% rename from packages/util-triehash/src/encode/pairs.ts rename to packages/trie-hash/src/encode/pairs.ts index 2d69ec10b..d43bcd4c5 100644 --- a/packages/util-triehash/src/encode/pairs.ts +++ b/packages/trie-hash/src/encode/pairs.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/encode/shared.ts b/packages/trie-hash/src/encode/shared.ts similarity index 87% rename from packages/util-triehash/src/encode/shared.ts rename to packages/trie-hash/src/encode/shared.ts index 3e90ac6ba..f491f33d2 100644 --- a/packages/util-triehash/src/encode/shared.ts +++ b/packages/trie-hash/src/encode/shared.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/encode/single.ts b/packages/trie-hash/src/encode/single.ts similarity index 84% rename from packages/util-triehash/src/encode/single.ts rename to packages/trie-hash/src/encode/single.ts index 9bff27a3e..94d90e157 100644 --- a/packages/util-triehash/src/encode/single.ts +++ b/packages/trie-hash/src/encode/single.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/index.ts b/packages/trie-hash/src/index.ts similarity index 83% rename from packages/util-triehash/src/index.ts rename to packages/trie-hash/src/index.ts index c563c2a5a..67935c9a6 100644 --- a/packages/util-triehash/src/index.ts +++ b/packages/trie-hash/src/index.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/root.spec.js b/packages/trie-hash/src/root.spec.js similarity index 97% rename from packages/util-triehash/src/root.spec.js rename to packages/trie-hash/src/root.spec.js index ad3a8cf78..ae2d315c5 100644 --- a/packages/util-triehash/src/root.spec.js +++ b/packages/trie-hash/src/root.spec.js @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/root.ts b/packages/trie-hash/src/root.ts similarity index 88% rename from packages/util-triehash/src/root.ts rename to packages/trie-hash/src/root.ts index 154ebbe26..bb67869bd 100644 --- a/packages/util-triehash/src/root.ts +++ b/packages/trie-hash/src/root.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. @@ -16,7 +16,7 @@ import pairsUniq from './util/pairsUniq'; From an `Array<{k: Uint8Array, v: Uint8Array}>` input, calculate the triehash and return the result as a `Uint8Array`. @example import { u8aFromString } from '@polkadot/util'; - import { trieRoot } from '@polkadot/util-triehash'; + import { trieRoot } from '@polkadot/trie-hash'; trieRoot([{ k: u8aFromString('A'), diff --git a/packages/util-triehash/src/rootOrdered.spec.js b/packages/trie-hash/src/rootOrdered.spec.js similarity index 90% rename from packages/util-triehash/src/rootOrdered.spec.js rename to packages/trie-hash/src/rootOrdered.spec.js index 1ffbb3443..09b165491 100644 --- a/packages/util-triehash/src/rootOrdered.spec.js +++ b/packages/trie-hash/src/rootOrdered.spec.js @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/rootOrdered.ts b/packages/trie-hash/src/rootOrdered.ts similarity index 94% rename from packages/util-triehash/src/rootOrdered.ts rename to packages/trie-hash/src/rootOrdered.ts index dc9f15963..f7f0ce870 100644 --- a/packages/util-triehash/src/rootOrdered.ts +++ b/packages/trie-hash/src/rootOrdered.ts @@ -15,7 +15,7 @@ import pairsUniq from './util/pairsUniq'; From an `Array` input, calculate the ordered triehash and return the result as a `Uint8Array`. @example import { u8aFromString } from '@polkadot/util'; - import { trieRootOrdered } from '@polkadot/util-triehash'; + import { trieRootOrdered } from '@polkadot/trie-hash'; trieRootOrdered([ u8aFromString('doe'), diff --git a/packages/util-triehash/src/types.d.ts b/packages/trie-hash/src/types.d.ts similarity index 76% rename from packages/util-triehash/src/types.d.ts rename to packages/trie-hash/src/types.d.ts index 20e168dde..71d947fd0 100644 --- a/packages/util-triehash/src/types.d.ts +++ b/packages/trie-hash/src/types.d.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/util/.nodoc b/packages/trie-hash/src/util/.nodoc similarity index 100% rename from packages/util-triehash/src/util/.nodoc rename to packages/trie-hash/src/util/.nodoc diff --git a/packages/util-triehash/src/util/asNibbles.spec.js b/packages/trie-hash/src/util/asNibbles.spec.js similarity index 89% rename from packages/util-triehash/src/util/asNibbles.spec.js rename to packages/trie-hash/src/util/asNibbles.spec.js index 9785fb145..9e55c784b 100644 --- a/packages/util-triehash/src/util/asNibbles.spec.js +++ b/packages/trie-hash/src/util/asNibbles.spec.js @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/util/asNibbles.ts b/packages/trie-hash/src/util/asNibbles.ts similarity index 86% rename from packages/util-triehash/src/util/asNibbles.ts rename to packages/trie-hash/src/util/asNibbles.ts index a6d621677..3e195b41e 100644 --- a/packages/util-triehash/src/util/asNibbles.ts +++ b/packages/trie-hash/src/util/asNibbles.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. @@ -9,7 +9,7 @@ @description From an `Uint8Array` input, calculate and return a list of nibbles that makes up the input. @example - import { asNibbles } from '@polkadot/util-triehash/util'; + import { asNibbles } from '@polkadot/trie-hash/util'; asNibbles(new Uint8Array([0x41, 0x20]) // => Uint8Array([4, 1, 2, 0]) */ diff --git a/packages/util-triehash/src/util/genRoot.ts b/packages/trie-hash/src/util/genRoot.ts similarity index 88% rename from packages/util-triehash/src/util/genRoot.ts rename to packages/trie-hash/src/util/genRoot.ts index 12c8e6d19..4411a0746 100644 --- a/packages/util-triehash/src/util/genRoot.ts +++ b/packages/trie-hash/src/util/genRoot.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/util/pairsUniq.spec.js b/packages/trie-hash/src/util/pairsUniq.spec.js similarity index 94% rename from packages/util-triehash/src/util/pairsUniq.spec.js rename to packages/trie-hash/src/util/pairsUniq.spec.js index 26f9eedcb..75165a62b 100644 --- a/packages/util-triehash/src/util/pairsUniq.spec.js +++ b/packages/trie-hash/src/util/pairsUniq.spec.js @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/util/pairsUniq.ts b/packages/trie-hash/src/util/pairsUniq.ts similarity index 88% rename from packages/util-triehash/src/util/pairsUniq.ts rename to packages/trie-hash/src/util/pairsUniq.ts index b3e578650..744284636 100644 --- a/packages/util-triehash/src/util/pairsUniq.ts +++ b/packages/trie-hash/src/util/pairsUniq.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/util/sharedLength.ts b/packages/trie-hash/src/util/sharedLength.ts similarity index 84% rename from packages/util-triehash/src/util/sharedLength.ts rename to packages/trie-hash/src/util/sharedLength.ts index 052de6046..55402c6c0 100644 --- a/packages/util-triehash/src/util/sharedLength.ts +++ b/packages/trie-hash/src/util/sharedLength.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/util/sharedPrefixLength.spec.js b/packages/trie-hash/src/util/sharedPrefixLength.spec.js similarity index 92% rename from packages/util-triehash/src/util/sharedPrefixLength.spec.js rename to packages/trie-hash/src/util/sharedPrefixLength.spec.js index 6549446ec..d458c820a 100644 --- a/packages/util-triehash/src/util/sharedPrefixLength.spec.js +++ b/packages/trie-hash/src/util/sharedPrefixLength.spec.js @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/util-triehash/src/util/sharedPrefixLength.ts b/packages/trie-hash/src/util/sharedPrefixLength.ts similarity index 87% rename from packages/util-triehash/src/util/sharedPrefixLength.ts rename to packages/trie-hash/src/util/sharedPrefixLength.ts index fadfcbd0e..279f91cd4 100644 --- a/packages/util-triehash/src/util/sharedPrefixLength.ts +++ b/packages/trie-hash/src/util/sharedPrefixLength.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2018 @polkadot/util-triehash authors & contributors +// Copyright 2017-2018 @polkadot/trie-hash authors & contributors // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. diff --git a/packages/type-extrinsics/LICENSE b/packages/type-extrinsics/LICENSE new file mode 100644 index 000000000..f4c79de42 --- /dev/null +++ b/packages/type-extrinsics/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017-2018 @polkadot/extrinsics authors & contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/type-extrinsics/README.md b/packages/type-extrinsics/README.md new file mode 100644 index 000000000..58f2e8919 --- /dev/null +++ b/packages/type-extrinsics/README.md @@ -0,0 +1 @@ +# @polkadot/extrinsics diff --git a/packages/type-extrinsics/package.json b/packages/type-extrinsics/package.json new file mode 100644 index 000000000..79787a7d3 --- /dev/null +++ b/packages/type-extrinsics/package.json @@ -0,0 +1,23 @@ +{ + "name": "@polkadot/extrinsics", + "version": "0.25.0", + "main": "index.js", + "repository": "https://github.com/polkadot-js/apps.git", + "author": "Jaco Greeff ", + "maintainers": [ + "Jaco Greeff " + ], + "contributors": [], + "license": "ISC", + "scripts": { + "build": "polkadot-dev-build-babel", + "check": "stylelint 'src/**/*.css' && eslint src && flow check", + "test": "jest --coverage" + }, + "dependencies": { + "@babel/runtime": "^7.0.0-beta.51", + "@polkadot/params": "^0.25.0", + "@polkadot/primitives": "^0.25.0", + "@polkadot/util": "^0.25.0" + } +} diff --git a/packages/type-extrinsics/src/consensus.ts b/packages/type-extrinsics/src/consensus.ts new file mode 100644 index 000000000..668582510 --- /dev/null +++ b/packages/type-extrinsics/src/consensus.ts @@ -0,0 +1,48 @@ +// Copyright 2017-2018 @polkadot/extrinsics authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Extrinsics, Extrinsic$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const reportMisbehavior: CreateItemOptions = { + description: 'Report misbehavior', + params: [ + param('report', 'MisbehaviorReport') + ], + type: [] +}; + +const setCode: CreateItemOptions = { + description: 'Set new code', + params: [ + param('code', 'Code') + ], + type: [] +}; + +const setStorage: CreateItemOptions = { + description: 'Set storage entries', + params: [ + param('entries', ['KeyValue']) + ], + type: [] +}; + +export default (name: Extrinsic$Sections, index: number): Section => + createSection(name, index)((createMethod: CreateItems) => ({ + description: 'Consensus', + public: { + reportMisbehavior: + createMethod('reportMisbehavior', 0)(reportMisbehavior) + }, + private: { + setCode: + createMethod('setCode', 0)(setCode), + setStorage: + createMethod('setStorage', 1)(setStorage) + } + })); diff --git a/packages/type-extrinsics/src/council.ts b/packages/type-extrinsics/src/council.ts new file mode 100644 index 000000000..f5f260368 --- /dev/null +++ b/packages/type-extrinsics/src/council.ts @@ -0,0 +1,114 @@ +// Copyright 2017-2018 @polkadot/extrinsics authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Extrinsics, Extrinsic$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const setApprovals: CreateItemOptions = { + description: 'Set approvals', + params: [ + param('votes', ['bool']), + param('index', 'u32') + ], + type: [] +}; + +const reapInactiveVoter: CreateItemOptions = { + description: 'Remove insactive voter', + params: [ + param('signedIndex', 'u32'), + param('who', 'AccountId'), + param('whoIndex', 'u32'), + param('assumedVoteIndex', 'u32') + ], + type: [] +}; + +const retractVoter: CreateItemOptions = { + description: 'Retract voter', + params: [ + param('index', 'u32') + ], + type: [] +}; + +const submitCandidacy: CreateItemOptions = { + description: 'Submit candidacy', + params: [ + param('slot', 'u32') + ], + type: [] +}; + +const presentWinner: CreateItemOptions = { + description: 'Present winner', + params: [ + param('candidate', 'AccountId'), + param('total', 'Balance'), + param('index', 'u32') + ], + type: [] +}; + +const setDesiredSeats: CreateItemOptions = { + description: 'Set desired seats', + params: [ + param('count', 'u32') + ], + type: [] +}; + +const removeMember: CreateItemOptions = { + description: 'Remove member', + params: [ + param('member', 'AccountId') + ], + type: [] +}; + +const setPresentationDuration: CreateItemOptions = { + description: 'Set presentation duration', + params: [ + param('duration', 'u64') + ], + type: [] +}; + +const setTermDuration: CreateItemOptions = { + description: 'Set term duration', + params: [ + param('duration', 'u64') + ], + type: [] +}; + +export default (name: Extrinsic$Sections, index: number): Section => + createSection(name, index)((createMethod: CreateItems) => ({ + description: 'Council', + public: { + setApprovals: + createMethod('setApprovals', 0)(setApprovals), + reapInactiveVoter: + createMethod('reapInactiveVoter', 1)(reapInactiveVoter), + retractVoter: + createMethod('retractVoter', 2)(retractVoter), + submitCandidacy: + createMethod('submitCandidacy', 3)(submitCandidacy), + presentWinner: + createMethod('presentWinner', 4)(presentWinner) + }, + private: { + setDesiredSeats: + createMethod('setDesiredSeats', 0)(setDesiredSeats), + removeMember: + createMethod('removeMember', 1)(removeMember), + setPresentationDuration: + createMethod('setPresentationDuration', 2)(setPresentationDuration), + setTermDuration: + createMethod('setTermDuration', 3)(setTermDuration) + } + })); diff --git a/packages/type-extrinsics/src/councilVoting.ts b/packages/type-extrinsics/src/councilVoting.ts new file mode 100644 index 000000000..f12b383a1 --- /dev/null +++ b/packages/type-extrinsics/src/councilVoting.ts @@ -0,0 +1,69 @@ +// Copyright 2017-2018 @polkadot/extrinsics authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Extrinsics, Extrinsic$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const propose: CreateItemOptions = { + description: 'Propose', + params: [ + param('proposal', 'Proposal') + ], + type: [] +}; + +const vote: CreateItemOptions = { + description: 'Vote', + params: [ + param('proposal', 'Hash'), + param('approve', 'bool') + ], + type: [] +}; + +const veto: CreateItemOptions = { + description: 'Veto', + params: [ + param('proposal', 'Hash') + ], + type: [] +}; + +const setCooloffPeriod: CreateItemOptions = { + description: 'Set cooloff period', + params: [ + param('blocks', 'BlockNumber') + ], + type: [] +}; + +const setVotingPeriod: CreateItemOptions = { + description: 'Set voting period', + params: [ + param('blocks', 'BlockNumber') + ], + type: [] +}; + +export default (name: Extrinsic$Sections, index: number): Section => + createSection(name, index)((createMethod: CreateItems) => ({ + description: 'Council Voting', + public: { + propose: + createMethod('propose', 0)(propose), + vote: + createMethod('vote', 1)(vote), + veto: + createMethod('veto', 2)(veto) + }, + private: { + setCooloffPeriod: + createMethod('setCooloffPeriod', 0)(setCooloffPeriod), + setVotingPeriod: + createMethod('setVotingPeriod', 1)(setVotingPeriod) + } + })); diff --git a/packages/type-extrinsics/src/democracy.ts b/packages/type-extrinsics/src/democracy.ts new file mode 100644 index 000000000..c5beb213e --- /dev/null +++ b/packages/type-extrinsics/src/democracy.ts @@ -0,0 +1,71 @@ +// Copyright 2017-2018 @polkadot/extrinsics authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Extrinsics, Extrinsic$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const propose: CreateItemOptions = { + description: 'Propose', + params: [ + param('proposal', 'Proposal'), + param('value', 'Balance') + ], + type: [] +}; + +const second: CreateItemOptions = { + description: 'Second', + params: [ + param('proposal', 'u32') + ], + type: [] +}; + +const vote: CreateItemOptions = { + description: 'Vote', + params: [ + param('referendumIndex', 'ReferendumIndex'), + param('vote', 'bool') + ], + type: [] +}; + +const startReferendum: CreateItemOptions = { + description: 'Start referendum', + params: [ + param('proposal', 'Proposal'), + param('voteThreshold', 'VoteThreshold') + ], + type: [] +}; + +const cancelReferendum: CreateItemOptions = { + description: 'Cancel referendum', + params: [ + param('referendumIndex', 'ReferendumIndex') + ], + type: [] +}; + +export default (name: Extrinsic$Sections, index: number): Section => + createSection(name, index)((createMethod: CreateItems) => ({ + description: 'Democracy', + public: { + propose: + createMethod('propose', 0)(propose), + second: + createMethod('second', 1)(second), + vote: + createMethod('vote', 2)(vote) + }, + private: { + startReferendum: + createMethod('startReferendum', 0)(startReferendum), + cancelReferendum: + createMethod('cancelReferendum', 1)(cancelReferendum) + } + })); diff --git a/packages/type-extrinsics/src/index.ts b/packages/type-extrinsics/src/index.ts new file mode 100644 index 000000000..57396d857 --- /dev/null +++ b/packages/type-extrinsics/src/index.ts @@ -0,0 +1,29 @@ +// Copyright 2017-2018 @polkadot/extrinsics authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Extrinsics } from '@polkadot/extrinsics/types'; + +import consensus from './consensus'; +import council from './council'; +import councilVoting from './councilVoting'; +import democracy from './democracy'; +import session from './session'; +import parachains from './parachains'; +import staking from './staking'; +import timestamp from './timestamp'; +import treasury from './treasury'; + +const extrinsics: Extrinsics = { + consensus: consensus('consensus', 0), + session: session('session', 1), + staking: staking('staking', 2), + timestamp: timestamp('timestamp', 3), + treasury: treasury('treasury', 4), + democracy: democracy('democracy', 5), + council: council('council', 6), + councilVoting: councilVoting('councilVoting', 7), + parachains: parachains('parachains', 8) +}; + +export default extrinsics; diff --git a/packages/type-extrinsics/src/parachains.ts b/packages/type-extrinsics/src/parachains.ts new file mode 100644 index 000000000..a6e8d377f --- /dev/null +++ b/packages/type-extrinsics/src/parachains.ts @@ -0,0 +1,28 @@ +// Copyright 2017-2018 @polkadot/extrinsics authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Extrinsics, Extrinsic$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const setHeads: CreateItemOptions = { + description: 'Sets parachain heads', + isHidden: true, // inherent + params: [ + param('heads', ['CandidateReceipt']) + ], + type: [] +}; + +export default (name: Extrinsic$Sections, index: number): Section => + createSection(name, index)((createMethod: CreateItems) => ({ + description: 'Parchains', + public: { + setHeads: + createMethod('setHeads', 0)(setHeads) + }, + private: {} + })); diff --git a/packages/type-extrinsics/src/session.ts b/packages/type-extrinsics/src/session.ts new file mode 100644 index 000000000..d8a3b52e6 --- /dev/null +++ b/packages/type-extrinsics/src/session.ts @@ -0,0 +1,46 @@ +// Copyright 2017-2018 @polkadot/extrinsics authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Extrinsics, Extrinsic$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const setKey: CreateItemOptions = { + description: 'Set session key', + params: [ + param('key', 'SessionKey') + ], + type: [] +}; + +const setLength: CreateItemOptions = { + description: 'Set session length', + params: [ + param('length', 'u64') + ], + type: [] +}; + +const forceNewSession: CreateItemOptions = { + description: 'Force new session', + params: [], + type: [] +}; + +export default (name: Extrinsic$Sections, index: number): Section => + createSection(name, index)((createMethod: CreateItems) => ({ + description: 'Session', + public: { + setKey: + createMethod('setKey', 0)(setKey) + }, + private: { + setLength: + createMethod('setLength', 0)(setLength), + forceNewSession: + createMethod('forceNewSession', 1)(forceNewSession) + } + })); diff --git a/packages/type-extrinsics/src/staking.ts b/packages/type-extrinsics/src/staking.ts new file mode 100644 index 000000000..26368b1cb --- /dev/null +++ b/packages/type-extrinsics/src/staking.ts @@ -0,0 +1,83 @@ +// Copyright 2017-2018 @polkadot/extrinsics authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Extrinsics, Extrinsic$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const transfer: CreateItemOptions = { + description: 'Transfer', + params: [ + param('recipient', 'AccountId'), + param('value', 'Balance') + ], + type: [] +}; + +const stake: CreateItemOptions = { + description: 'Stake', + params: [], + type: [] +}; + +const unstake: CreateItemOptions = { + description: 'Unstake', + params: [], + type: [] +}; + +const setSessionsPerEra: CreateItemOptions = { + description: 'Set sessions per era', + params: [ + param('sessions', 'BlockNumber') + ], + type: [] +}; + +const setBondingDuration: CreateItemOptions = { + description: 'Set bonding duration', + params: [ + param('duration', 'BlockNumber') + ], + type: [] +}; + +const setValidatorCount: CreateItemOptions = { + description: 'Set validator count', + params: [ + param('count', 'u32') + ], + type: [] +}; + +const forceNewEra: CreateItemOptions = { + description: 'Force new era', + params: [], + type: [] +}; + +export default (name: Extrinsic$Sections, index: number): Section => + createSection(name, index)((createMethod: CreateItems) => ({ + description: 'Staking', + public: { + transfer: + createMethod('transfer', 0)(transfer), + stake: + createMethod('stake', 1)(stake), + unstake: + createMethod('unstake', 2)(unstake) + }, + private: { + setSessionsPerEra: + createMethod('setSessionsPerEra', 0)(setSessionsPerEra), + setBondingDuration: + createMethod('setBondingDuration', 1)(setBondingDuration), + setValidatorCount: + createMethod('setValidatorCount', 2)(setValidatorCount), + forceNewEra: + createMethod('forceNewEra', 3)(forceNewEra) + } + })); diff --git a/packages/type-extrinsics/src/timestamp.ts b/packages/type-extrinsics/src/timestamp.ts new file mode 100644 index 000000000..5d624d774 --- /dev/null +++ b/packages/type-extrinsics/src/timestamp.ts @@ -0,0 +1,28 @@ +// Copyright 2017-2018 @polkadot/extrinsics authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Extrinsics, Extrinsic$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const set: CreateItemOptions = { + description: 'Set timestamp', + isHidden: true, // inherent + params: [ + param('timestamp', 'Timestamp') + ], + type: [] +}; + +export default (name: Extrinsic$Sections, index: number): Section => + createSection(name, index)((createMethod: CreateItems) => ({ + description: 'Timestamp', + public: { + set: + createMethod('set', 0)(set) + }, + private: {} + })); diff --git a/packages/type-extrinsics/src/treasury.ts b/packages/type-extrinsics/src/treasury.ts new file mode 100644 index 000000000..284760d41 --- /dev/null +++ b/packages/type-extrinsics/src/treasury.ts @@ -0,0 +1,13 @@ +// Copyright 2017-2018 @polkadot/extrinsics authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, Section } from '@polkadot/params/types'; +import { Extrinsics, Extrinsic$Sections } from './types'; + +import createSection from '@polkadot/params/section'; + +export default (name: Extrinsic$Sections, index: number): Section => + createSection(name, index)((createMethod: CreateItems) => ({ + description: 'Timestamp' + })); diff --git a/packages/type-extrinsics/src/types.d.ts b/packages/type-extrinsics/src/types.d.ts new file mode 100644 index 000000000..da6d17762 --- /dev/null +++ b/packages/type-extrinsics/src/types.d.ts @@ -0,0 +1,21 @@ +// Copyright 2017-2018 @polkadot/extrinsics authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Section } from '@polkadot/params/types'; + +export type Extrinsics = { + // substrate + consensus: Section, + council: Section, + councilVoting: Section, + democracy: Section, + session: Section, + staking: Section, + timestamp: Section, + treasury: Section, + // polkadot + parachains: Section +}; + +export type Extrinsic$Sections = keyof Extrinsics; diff --git a/packages/type-jsonrpc/LICENSE b/packages/type-jsonrpc/LICENSE new file mode 100644 index 000000000..5291406d4 --- /dev/null +++ b/packages/type-jsonrpc/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017-2018 @polkadot/jsonrpc authors & contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/type-jsonrpc/README.md b/packages/type-jsonrpc/README.md new file mode 100644 index 000000000..f263a87c1 --- /dev/null +++ b/packages/type-jsonrpc/README.md @@ -0,0 +1,30 @@ +[![polkadotjs](https://img.shields.io/badge/polkadot-js-orange.svg?style=flat-square)](https://polkadot.js.org) +![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) +[![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) +[![npm](https://img.shields.io/npm/v/@polkadot/jsonrpc.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/jsonrpc) +[![travis](https://img.shields.io/travis/polkadot-js/types.svg?style=flat-square)](https://travis-ci.org/polkadot-js/types) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/types.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/types/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/types.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/types?branch=master) +[![dependency](https://david-dm.org/polkadot-js/types.svg?style=flat-square&path=packages/jsonrpc)](https://david-dm.org/polkadot-js/types?path=packages/jsonrpc) +[![devDependency](https://david-dm.org/polkadot-js/types/dev-status.svg?style=flat-square&path=packages/jsonrpc)](https://david-dm.org/polkadot-js/types?path=packages/jsonrpc#info=devDependencies) + +# @polkadot/jsonrpc + +A defintion of all the methods exposed in a general Polkadot client application. These are used not only to provide a comprehensive code-generated document of the available methods, but are also used in the API to auto-generate endpoints with the required type-checking. + +For a list of currently exposed methods, see the [method documentation](docs/README.md). + +## Usage + +Installation - + +``` +npm install --save @polkadot/jsonrpc +``` + +## Adding methods + +As methods are added, simply adding the name, inputs & output will prepare it for use. + +- Add the method to the correct file in [src/rpc/](src/rpc/) (Input/Output types as cross-referenced from the canonical implementation and match one-to-one) +- Should a new type be required, add it to the type list, [src/types.js](src/types.js) (Required for flow type checking) diff --git a/packages/type-jsonrpc/package.json b/packages/type-jsonrpc/package.json new file mode 100644 index 000000000..a85e9596f --- /dev/null +++ b/packages/type-jsonrpc/package.json @@ -0,0 +1,40 @@ +{ + "name": "@polkadot/jsonrpc", + "version": "0.25.0", + "description": "Method definitions for the Polkadot RPC layer", + "main": "index.js", + "engines": { + "node": ">=6.4" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-js/api.git" + }, + "keywords": [ + "Polkadot", + "JsonRPC" + ], + "author": "Jaco Greeff ", + "maintainers": [ + "Jaco Greeff " + ], + "contributors": [], + "license": "ISC", + "bugs": { + "url": "https://github.com/polkadot-js/api/issues" + }, + "homepage": "https://github.com/polkadot-js/api/tree/master/packages/jsonrpc#readme", + "scripts": { + "build": "polkadot-dev-build-babel && polkadot-dev-build-docs", + "check": "eslint src && flow check", + "test": "echo \"Tests only available from root wrapper\"" + }, + "dependencies": { + "@polkadot/params": "^0.25.0", + "babel-runtime": "^6.26.0" + } +} diff --git a/packages/type-jsonrpc/src/author.ts b/packages/type-jsonrpc/src/author.ts new file mode 100644 index 000000000..4f5b69a51 --- /dev/null +++ b/packages/type-jsonrpc/src/author.ts @@ -0,0 +1,30 @@ +// Copyright 2017-2018 @polkadot/jsonrpc authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Interfaces, Interface$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const submitExtrinsic: CreateItemOptions = { + isSigned: true, + description: 'Submit a fully formatted extrinsic for block inclusion', + params: [ + param('extrinsic', 'Bytes') + ], + type: 'Header' +}; + +/** + @summary Methods to work with authors & contributors. +*/ +export default (name: Interface$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Authoring of network items', + public: { + submitExtrinsic: + createMethod('submitExtrinsic')(submitExtrinsic) + } + })); diff --git a/packages/type-jsonrpc/src/chain.ts b/packages/type-jsonrpc/src/chain.ts new file mode 100644 index 000000000..bbcf8419f --- /dev/null +++ b/packages/type-jsonrpc/src/chain.ts @@ -0,0 +1,46 @@ +// Copyright 2017-2018 @polkadot/jsonrpc authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Interfaces, Interface$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const getHead: CreateItemOptions = { + description: 'Retrieves the best headerHash', + params: [], + type: 'Hash' +}; + +const getHeader: CreateItemOptions = { + description: 'Retrieves the header for a specific block', + params: [ + param('hash', 'Hash') + ], + type: 'Header' +}; + +const newHead: CreateItemOptions = { + description: 'Retrieves the best header via subscription', + isSubscription: true, + params: [], + type: 'Header' +}; + +/** + @summary Methods to retrieve chain data. +*/ +export default (name: Interface$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Retrieval of chain data', + public: { + getHead: + createMethod('getHead')(getHead), + getHeader: + createMethod('getHeader')(getHeader), + newHead: + createMethod('newHead')(newHead) + } + })); diff --git a/packages/type-jsonrpc/src/index.spec.js b/packages/type-jsonrpc/src/index.spec.js new file mode 100644 index 000000000..bd546e302 --- /dev/null +++ b/packages/type-jsonrpc/src/index.spec.js @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/jsonrpc authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import interfaces from './index'; + +describe('jsonrpc', () => { + it('exports the available interfaces', () => { + expect(interfaces).toBeDefined(); + expect(Object.keys(interfaces).length).toBeGreaterThan(0); + }); +}); diff --git a/packages/type-jsonrpc/src/index.ts b/packages/type-jsonrpc/src/index.ts new file mode 100644 index 000000000..3a6557bbf --- /dev/null +++ b/packages/type-jsonrpc/src/index.ts @@ -0,0 +1,19 @@ +// Copyright 2017-2018 @polkadot/jsonrpc authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Interfaces, Interface$Sections } from './types'; + +import author from './author'; +import chain from './chain'; +import state from './state'; +import system from './system'; + +const interfaces: Interfaces = { + author: author('author'), + chain: chain('chain'), + state: state('state'), + system: system('system') +}; + +export default interfaces; diff --git a/packages/type-jsonrpc/src/state.ts b/packages/type-jsonrpc/src/state.ts new file mode 100644 index 000000000..96f35292b --- /dev/null +++ b/packages/type-jsonrpc/src/state.ts @@ -0,0 +1,105 @@ +// Copyright 2017-2018 @polkadot/jsonrpc authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Interfaces, Interface$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const call: CreateItemOptions = { + description: 'Perform a call to a builtin on the chain', + params: [ + param('method', 'String'), + param('data', 'Bytes') + ], + type: 'Bytes' +}; + +const callAt: CreateItemOptions = { + description: 'Perform a call to a builtin on the chain (At block)', + params: [ + param('method', 'String'), + param('data', 'Bytes'), + param('block', 'Hash') + ], + type: 'Bytes' +}; + +const getStorage: CreateItemOptions = { + description: 'Retrieves the storage for a key', + params: [ + param('key', 'Bytes') + ], + type: 'Bytes' +}; + +const getStorageAt: CreateItemOptions = { + description: 'Retrieves the storage for a key at a specific block', + params: [ + param('key', 'Bytes'), + param('block', 'Hash') + ], + type: 'Bytes' +}; + +const getStorageHash: CreateItemOptions = { + description: 'Retrieves the storage hash', + params: [ + param('key', 'Bytes') + ], + type: 'Hash' +}; + +const getStorageHashAt: CreateItemOptions = { + description: 'Retrieves the storage hash at a specific block', + params: [ + param('key', 'Bytes'), + param('block', 'Hash') + ], + type: 'Hash' +}; + +const getStorageSize: CreateItemOptions = { + description: 'Retrieves the storage size', + params: [ + param('key', 'Bytes') + ], + type: 'u64' +}; + +const getStorageSizeAt: CreateItemOptions = { + description: 'Retrieves the storage size at a specific block', + params: [ + param('key', 'Bytes'), + param('block', 'Hash') + ], + type: 'u64' +}; + +/** + @summary Query the state and state storage. +*/ +export default (name: Interface$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Query of state', + public: { + call: + createMethod('call')(call), + callAt: + createMethod('callAt')(callAt), + getStorage: + createMethod('getStorage')(getStorage), + getStorageAt: + createMethod('getStorageAt')(getStorageAt), + getStorageHash: + createMethod('getStorageHash')(getStorageHash), + getStorageHashAt: + createMethod('getStrorageHashAt')(getStorageHashAt), + getStorageSize: + createMethod('getStorageSize')(getStorageSize), + getStorageSizeAt: + createMethod('getStorageSizeAt')(getStorageSizeAt) + } + })); diff --git a/packages/type-jsonrpc/src/system.ts b/packages/type-jsonrpc/src/system.ts new file mode 100644 index 000000000..0c96df71c --- /dev/null +++ b/packages/type-jsonrpc/src/system.ts @@ -0,0 +1,42 @@ +// Copyright 2017-2018 @polkadot/jsonrpc authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Interfaces, Interface$Sections } from './types'; + +import createSection from '@polkadot/params/section'; + +const chain: CreateItemOptions = { + description: 'Retrieves the chain', + params: [], + type: 'String' +}; + +const name: CreateItemOptions = { + description: 'Retrieves the node name', + params: [], + type: 'String' +}; + +const version: CreateItemOptions = { + description: 'Retrieves the version of the node', + params: [], + type: 'String' +}; + +/** + @summary Methods to retrieve system info. +*/ +export default (sname: Interface$Sections): Section => + createSection(sname)((createMethod: CreateItems) => ({ + description: 'Methods to retrieve system info', + public: { + chain: + createMethod('chain')(chain), + name: + createMethod('name')(name), + version: + createMethod('version')(version) + } + })); diff --git a/packages/type-jsonrpc/src/types.d.ts b/packages/type-jsonrpc/src/types.d.ts new file mode 100644 index 000000000..faed54a95 --- /dev/null +++ b/packages/type-jsonrpc/src/types.d.ts @@ -0,0 +1,14 @@ +// Copyright 2017-2018 @polkadot/jsonrpc authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Section } from '@polkadot/params/types'; + +export type Interfaces = { + author: Section, + chain: Section, + state: Section, + system:Section +} + +export type Interface$Sections = keyof Interfaces; diff --git a/packages/type-params/LICENSE b/packages/type-params/LICENSE new file mode 100644 index 000000000..15ab4076c --- /dev/null +++ b/packages/type-params/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017-2018 @polkadot/params authors & contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/type-params/README.md b/packages/type-params/README.md new file mode 100644 index 000000000..974fae5f9 --- /dev/null +++ b/packages/type-params/README.md @@ -0,0 +1,11 @@ +[![polkadotjs](https://img.shields.io/badge/polkadot-js-orange.svg?style=flat-square)](https://polkadot.js.org) +![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) +[![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) +[![npm](https://img.shields.io/npm/v/@polkadot/primitives.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/primitives) +[![travis](https://img.shields.io/travis/polkadot-js/types.svg?style=flat-square)](https://travis-ci.org/polkadot-js/types) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/types.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/types/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/types.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/types?branch=master) +[![dependency](https://david-dm.org/polkadot-js/types.svg?style=flat-square&path=packages/params)](https://david-dm.org/polkadot-js/types?path=packages/params) +[![devDependency](https://david-dm.org/polkadot-js/types/dev-status.svg?style=flat-square&path=packages/params)](https://david-dm.org/polkadot-js/types?path=packages/params#info=devDependencies) + +# @polkadot/params diff --git a/packages/type-params/package.json b/packages/type-params/package.json new file mode 100644 index 000000000..9c8ef7511 --- /dev/null +++ b/packages/type-params/package.json @@ -0,0 +1,42 @@ +{ + "name": "@polkadot/params", + "version": "0.25.0", + "description": "Type defintions for parameters as passed in calls", + "main": "index.js", + "engines": { + "node": ">=6.4" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-js/types.git" + }, + "keywords": [ + "Polkadot" + ], + "author": "Jaco Greeff ", + "maintainers": [ + "Jaco Greeff " + ], + "contributors": [], + "license": "ISC", + "bugs": { + "url": "https://github.com/polkadot-js/types/issues" + }, + "homepage": "https://github.com/polkadot-js/types/tree/master/packages/params#readme", + "scripts": { + "build": "polkadot-dev-build-babel", + "check": "eslint src && flow check", + "test": "echo \"Tests only available from root wrapper\"" + }, + "dependencies": { + "@babel/runtime": "^7.0.0-beta.51", + "@polkadot/extrinsics": "^0.25.0", + "@polkadot/extrinsics-codec": "^0.25.0", + "@polkadot/primitives": "^0.25.0", + "@polkadot/util": "^0.25.0" + } +} diff --git a/packages/type-params/src/decode/index.spec.js b/packages/type-params/src/decode/index.spec.js new file mode 100644 index 000000000..e6a3d59b6 --- /dev/null +++ b/packages/type-params/src/decode/index.spec.js @@ -0,0 +1,71 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import decode from './index'; + +describe('decode', () => { + it('decodes single types', () => { + expect( + JSON.stringify( + decode('BlockNumber', new Uint8Array([ + 0x69, 0, 0, 0, 0, 0, 0, 0 + ])) + ) + ).toEqual('{"length":8,"value":"69"}'); + }); + + it('decodes simple arrays', () => { + expect( + JSON.stringify( + decode(['BlockNumber'], new Uint8Array([ + 0x03, 0, 0, 0, + 0x69, 0, 0, 0, 0, 0, 0, 0, + 0x42, 0, 0, 0, 0, 0, 0, 0, + 0x15, 0, 0, 0, 0, 0, 0, 0 + ])) + ) + ).toEqual('{"length":28,"value":["69","42","15"]}'); + }); + + it('decodes tuple arrays', () => { + expect( + JSON.stringify( + decode(['BlockNumber', 'bool'], new Uint8Array([ + 0x69, 0, 0, 0, 0, 0, 0, 0, + 0x01 + ])) + ) + ).toEqual('{"length":9,"value":["69",true]}'); + }); + + it('decodes arrays with tuples', () => { + expect( + JSON.stringify( + decode([['BlockNumber', 'bool']], new Uint8Array([ + 0x03, 0, 0, 0, + 0x69, 0, 0, 0, 0, 0, 0, 0, + 0x01, + 0x42, 0, 0, 0, 0, 0, 0, 0, + 0x00, + 0x15, 0, 0, 0, 0, 0, 0, 0, + 0x01 + ])) + ) + ).toEqual('{"length":31,"value":[["69",true],["42",false],["15",true]]}'); + }); + + it('decodes tuples with arrays', () => { + expect( + JSON.stringify( + decode(['BlockNumber', ['bool']], new Uint8Array([ + 0x69, 0, 0, 0, 0, 0, 0, 0, + 0x03, 0, 0, 0, + 0x01, + 0x00, + 0x01 + ])) + ) + ).toEqual('{"length":15,"value":["69",[true,false,true]]}'); + }); +}); diff --git a/packages/type-params/src/decode/index.ts b/packages/type-params/src/decode/index.ts new file mode 100644 index 000000000..43d3b7ba5 --- /dev/null +++ b/packages/type-params/src/decode/index.ts @@ -0,0 +1,59 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { EncodingVersions, Param$Decoded, Param$Type$Array, Param$Types, Param$Value, Param$Value$Array } from '../types'; + +import u8aToBn from '@polkadot/util/u8a/toBn'; + +import decodeValue from './value'; + +function decodeTuple (type: Param$Type$Array, input: Uint8Array, version: EncodingVersions): Param$Decoded { + const value: Param$Value$Array = []; + let length = 0; + + type.forEach((_type: Param$Types) => { + const decoded = decode(_type, input.subarray(length), version); + + // NOTE small TS hack, since we don't have recursive arrays, assume primitives to push + value.push(decoded.value as Param$Value); + length += decoded.length; + }); + + return { + length, + value + }; +} + +function decodeArray ([ type ]: Param$Type$Array, input: Uint8Array, version: EncodingVersions): Param$Decoded { + const arrayLength = u8aToBn(input.subarray(0, 4), true).toNumber(); + const value: Param$Value$Array = []; + let length = 4; + + for (let index = 0; index < arrayLength; index++) { + const decoded = decode(type, input.subarray(length), version); + + // NOTE small TS hack, since we don't have recursive arrays, assume primitives to push + value.push(decoded.value as Param$Value); + length += decoded.length; + } + + return { + length, + value + }; +} + +export default function decode (type: Param$Types, input: Uint8Array, version: EncodingVersions): Param$Decoded { + if (Array.isArray(type)) { + // Arrays have single entries, Tuples will have multiple types + if (type.length === 1) { + return decodeArray((type as Param$Type$Array), input, version); + } else { + return decodeTuple((type as Param$Type$Array), input, version); + } + } + + return decodeValue(decode, type, input, version); +} diff --git a/packages/type-params/src/decode/types.d.ts b/packages/type-params/src/decode/types.d.ts new file mode 100644 index 000000000..12f522f10 --- /dev/null +++ b/packages/type-params/src/decode/types.d.ts @@ -0,0 +1,7 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { EncodingVersions, Param$Types, Param$Decoded } from '../types'; + +export type Decoder = (type: Param$Types, input: Uint8Array, version: EncodingVersions) => Param$Decoded; diff --git a/packages/type-params/src/decode/value/bn.ts b/packages/type-params/src/decode/value/bn.ts new file mode 100644 index 000000000..c3b561fec --- /dev/null +++ b/packages/type-params/src/decode/value/bn.ts @@ -0,0 +1,16 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Decoded } from '../../types'; + +import u8aToBn from '@polkadot/util/u8a/toBn'; + +export default function bn (input: Uint8Array, bitLength: 32 | 64 | 128): Param$Decoded { + const length = bitLength / 8; + + return { + length, + value: u8aToBn(input.subarray(0, length), true) + }; +} diff --git a/packages/type-params/src/decode/value/bool.ts b/packages/type-params/src/decode/value/bool.ts new file mode 100644 index 000000000..cc6e98b74 --- /dev/null +++ b/packages/type-params/src/decode/value/bool.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Decoded } from '../../types'; + +export default function bool (input: Uint8Array): Param$Decoded { + return { + length: 1, + value: input[0] !== 0 + }; +} diff --git a/packages/type-params/src/decode/value/byte.ts b/packages/type-params/src/decode/value/byte.ts new file mode 100644 index 000000000..d340b0964 --- /dev/null +++ b/packages/type-params/src/decode/value/byte.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Decoded } from '../../types'; + +export default function byte (input: Uint8Array): Param$Decoded { + return { + length: 1, + value: input[0] + }; +} diff --git a/packages/type-params/src/decode/value/bytes.ts b/packages/type-params/src/decode/value/bytes.ts new file mode 100644 index 000000000..de3a6d771 --- /dev/null +++ b/packages/type-params/src/decode/value/bytes.ts @@ -0,0 +1,16 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Decoded } from '../../types'; + +import u8aToBn from '@polkadot/util/u8a/toBn'; + +export default function bytes (input: Uint8Array): Param$Decoded { + const length = u8aToBn(input.subarray(0, 4), true).toNumber(); + + return { + length: length + 4, + value: input.subarray(4, length + 4) + }; +} diff --git a/packages/type-params/src/decode/value/code.ts b/packages/type-params/src/decode/value/code.ts new file mode 100644 index 000000000..092d2bb48 --- /dev/null +++ b/packages/type-params/src/decode/value/code.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Decoded } from '../../types'; + +export default function code (input: Uint8Array): Param$Decoded { + return { + length: input.length, + value: input + }; +} diff --git a/packages/type-params/src/decode/value/digest.ts b/packages/type-params/src/decode/value/digest.ts new file mode 100644 index 000000000..569c62f91 --- /dev/null +++ b/packages/type-params/src/decode/value/digest.ts @@ -0,0 +1,31 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Digest } from '@polkadot/primitives/digest'; +import { Param$Decoded } from '../../types'; + +import u8aToBn from '@polkadot/util/u8a/toBn'; + +import bytes from './bytes'; + +export default function digest (input: Uint8Array): Param$Decoded { + const logLength = u8aToBn(input.subarray(0, 4), true).toNumber(); + const value: Digest = { + logs: [] + }; + + let length = 4; + + for (let index = 0; index < logLength; index++) { + const decoded = bytes(input.subarray(length)); + + length += decoded.length; + value.logs.push((decoded.value as Uint8Array)); + } + + return { + length, + value + }; +} diff --git a/packages/type-params/src/decode/value/header.ts b/packages/type-params/src/decode/value/header.ts new file mode 100644 index 000000000..e76a33486 --- /dev/null +++ b/packages/type-params/src/decode/value/header.ts @@ -0,0 +1,18 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Decoded } from '../../types'; + +import decodeHeader from '@polkadot/primitives-codec/header/decode'; + +export default function header (input: Uint8Array): Param$Decoded { + // FIXME We don't have a way to determine the length atm + const length = input.length; + const value = decodeHeader(input); + + return { + length, + value + }; +} diff --git a/packages/type-params/src/decode/value/index.ts b/packages/type-params/src/decode/value/index.ts new file mode 100644 index 000000000..656043b21 --- /dev/null +++ b/packages/type-params/src/decode/value/index.ts @@ -0,0 +1,106 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { EncodingVersions, Param$Decoded, Param$Type } from '../../types'; +import { Decoder } from '../types'; + +import sizes from '@polkadot/primitives/sizes'; + +import bool from './bool'; +import bn from './bn'; +import byte from './byte'; +import bytes from './bytes'; +import code from './code'; +import digest from './digest'; +import header from './header'; +import keyValue from './keyValue'; +import method from './method'; +import misbehavior from './misbehavior'; +import passThrough from './passThrough'; +import string from './string'; +import time from './time'; +import u8a from './u8a'; + +export default function decodeValue (decode: Decoder, type: Param$Type, input: Uint8Array, version: EncodingVersions): Param$Decoded { + try { + switch (type) { + // TODO Pass back the actual address, not publicKey? + case 'AccountId': + return u8a(input, 256, version === 'poc-1' ? 0 : 1); + + case 'Balance': + return bn(input, sizes.Balance); + + case 'BlockNumber': + case 'SessionKey': + case 'u64': + return bn(input, 64); + + case 'bool': + return bool(input); + + case 'Bytes': + return bytes(input); + + case 'Call': + case 'Proposal': + return method(decode, input, type === 'Call', version); + + case 'Code': + return code(input); + + case 'CandidateReceipt': + return passThrough(input); + + case 'Digest': + return digest(input); + + case 'Header': + return header(input); + + case 'Hash': + return u8a(input, 256, 0); + + case 'Index': + return bn(input, sizes.Index); + + case 'KeyValue': + case 'KeyValueStorage': + return keyValue(input); + + case 'MisbehaviorReport': + return misbehavior(input); + + case 'ParachainId': + case 'PropIndex': + case 'ReferendumIndex': + case 'u32': + case 'VoteIndex': + return bn(input, 32); + + case 'Signature': + return u8a(input, 512, 0); + + case 'String': + return string(input); + + case 'Timestamp': + return time(input); + + case 'u128': + return bn(input, 128); + + case 'VoteThreshold': + return byte(input); + + default: + (type as never); // eslint-disable-line no-unused-expressions + throw new Error(`No value decoder for type='${type}'`); + } + } catch (error) { + console.error('Failed decoding', type, 'encoded as', input, error); + + throw error; + } +} diff --git a/packages/type-params/src/decode/value/keyValue.ts b/packages/type-params/src/decode/value/keyValue.ts new file mode 100644 index 000000000..6e861f856 --- /dev/null +++ b/packages/type-params/src/decode/value/keyValue.ts @@ -0,0 +1,23 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Decoded } from '../../types'; + +import u8aToBn from '@polkadot/util/u8a/toBn'; + +export default function bytes (input: Uint8Array): Param$Decoded { + const keyLength = u8aToBn(input.subarray(0, 4), true).toNumber(); + const key = input.subarray(4, keyLength + 4); + const valLength = u8aToBn(input.subarray(keyLength, keyLength + 4), true).toNumber(); + const length = valLength + keyLength + 8; + const value = input.subarray(keyLength + 8, length); + + return { + length, + value: { + key, + value + } + }; +} diff --git a/packages/type-params/src/decode/value/method.ts b/packages/type-params/src/decode/value/method.ts new file mode 100644 index 000000000..9002d092d --- /dev/null +++ b/packages/type-params/src/decode/value/method.ts @@ -0,0 +1,54 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Extrinsics } from '@polkadot/extrinsics/types'; +import { EncodingVersions, ExtrinsicDecoded, Param, Param$Decoded, Section } from '../../types'; +import { Decoder } from '../types'; + +import assert from '@polkadot/util/assert'; +import extrinsics from '@polkadot/extrinsics/index'; +import isUndefined from '@polkadot/util/is/undefined'; + +// type Section = +type Result = { + length: number, + value: ExtrinsicDecoded +}; + +export default function call (decode: Decoder, input: Uint8Array, isPublic: boolean, version: EncodingVersions): Param$Decoded { + const section: Section | undefined = Object.values(extrinsics).find(({ index }) => + index[0] === input[0] + ); + + assert(!isUndefined(section), `Unable to find extrinsic section ${input[0]}`); + + // @ts-ignore checked above + const methods = section[isPublic ? 'public' : 'private']; + const extrinsic = Object.values(methods).find(({ index }) => + index[1] === input[1] + ); + + assert(!isUndefined(extrinsic), `Unable to find method ${input[1]}`); + + // @ts-ignore checked above + const params = extrinsic.params; + const result = { + length: 2, // sectionId + methodId + value: ({ + extrinsic, + params: [] + } as ExtrinsicDecoded) + }; + + return params.reduce(({ length, value }: Result, { type }: Param) => { + const decoded = decode(type, input.subarray(length), version); + + value.params.push(decoded.value); + + return { + length: length + decoded.length, + value + }; + }, result); +} diff --git a/packages/type-params/src/decode/value/misbehavior.ts b/packages/type-params/src/decode/value/misbehavior.ts new file mode 100644 index 000000000..34f5d1032 --- /dev/null +++ b/packages/type-params/src/decode/value/misbehavior.ts @@ -0,0 +1,41 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { MisbehaviorReport } from '@polkadot/primitives/misbehavior'; +import { Param$Decoded } from '../../types'; + +import u8aToBn from '@polkadot/util/u8a/toBn'; + +const O_PHASH = 0; +const O_PNUM = 32; +const O_AUTH = O_PNUM + 8; +const O_TYPE = O_AUTH + 32; +const A_HASH = O_TYPE + 1; +const A_SIG = A_HASH + 32; +const B_HASH = A_SIG + 64; +const B_SIG = B_HASH + 32; + +const length = B_SIG + 64; + +export default function misbehavior (input: Uint8Array): Param$Decoded { + return { + length, + value: ({ + parentHash: input.subarray(O_PHASH, O_PNUM), + number: u8aToBn(input.subarray(O_PNUM, O_AUTH), true), + authorityId: input.subarray(O_AUTH, O_TYPE), + type: input[O_TYPE], + data: [ + { + header: input.subarray(A_HASH, A_SIG), + signature: input.subarray(A_SIG, B_HASH) + }, + { + header: input.subarray(B_HASH, B_SIG), + signature: input.subarray(B_SIG) + } + ] + } as MisbehaviorReport) + }; +} diff --git a/packages/type-params/src/decode/value/passThrough.ts b/packages/type-params/src/decode/value/passThrough.ts new file mode 100644 index 000000000..9a20abfbd --- /dev/null +++ b/packages/type-params/src/decode/value/passThrough.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Decoded } from '../../types'; + +export default function passThrough (input: Uint8Array): Param$Decoded { + return { + length: input.length, + value: input + }; +} diff --git a/packages/type-params/src/decode/value/string.ts b/packages/type-params/src/decode/value/string.ts new file mode 100644 index 000000000..515985a6b --- /dev/null +++ b/packages/type-params/src/decode/value/string.ts @@ -0,0 +1,19 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Decoded } from '../../types'; + +import u8aToBn from '@polkadot/util/u8a/toBn'; +import u8aToUtf8 from '@polkadot/util/u8a/toUtf8'; + +export default function string (input: Uint8Array): Param$Decoded { + const length = u8aToBn(input.subarray(0, 4), true).toNumber(); + + return { + length: length + 4, + value: u8aToUtf8( + input.subarray(4, length + 4) + ) + }; +} diff --git a/packages/type-params/src/decode/value/time.ts b/packages/type-params/src/decode/value/time.ts new file mode 100644 index 000000000..dcf196a7c --- /dev/null +++ b/packages/type-params/src/decode/value/time.ts @@ -0,0 +1,18 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Decoded } from '../../types'; + +import u8aToBn from '@polkadot/util/u8a/toBn'; + +export default function time (input: Uint8Array): Param$Decoded { + return { + length: 8, + value: new Date( + u8aToBn(input.subarray(0, 8), true) + .imuln(1000) + .toNumber() + ) + }; +} diff --git a/packages/type-params/src/decode/value/u8a.ts b/packages/type-params/src/decode/value/u8a.ts new file mode 100644 index 000000000..c05c5b61b --- /dev/null +++ b/packages/type-params/src/decode/value/u8a.ts @@ -0,0 +1,14 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Decoded } from '../../types'; + +export default function u8a (input: Uint8Array, bitLength: 256 | 512, offset: number): Param$Decoded { + const length = (bitLength / 8) + offset; + + return { + length, + value: input.subarray(offset, length) + }; +} diff --git a/packages/type-params/src/encode/index.ts b/packages/type-params/src/encode/index.ts new file mode 100644 index 000000000..72afb5ab4 --- /dev/null +++ b/packages/type-params/src/encode/index.ts @@ -0,0 +1,18 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { EncodingVersions, Params } from '../types'; + +import assert from '@polkadot/util/assert'; +import u8aConcat from '@polkadot/util/u8a/concat'; + +import encodeParam from './param'; + +export default function encodeParams (params: Params, values: Array, version: EncodingVersions): Uint8Array { + assert(params.length === values.length, `Expected values to have ${params.length} items, found ${values.length} instead`); + + return u8aConcat.apply(null, params.map((param, index) => + encodeParam(param, values[index], version) + )); +} diff --git a/packages/type-params/src/encode/param.spec.js b/packages/type-params/src/encode/param.spec.js new file mode 100644 index 000000000..75421a0c9 --- /dev/null +++ b/packages/type-params/src/encode/param.spec.js @@ -0,0 +1,49 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import encodeParam from './param'; + +describe('encodeParam', () => { + it('encodes a single parameter', () => { + expect( + encodeParam({ type: 'Balance' }, 0) + ).toEqual(new Uint8Array(16)); + }); + + it('checks for array types with array values', () => { + expect( + () => encodeParam({ type: ['Balance'] }, 64) + ).toThrow(/Expected array values/); + }); + + it('encodes array types with empty array values', () => { + expect( + encodeParam({ type: ['Balance'] }, []) + ).toEqual(new Uint8Array(4)); + }); + + it('encodes array types with actual array values', () => { + expect( + encodeParam({ type: ['Balance'] }, [3, 4]) + ).toEqual( + new Uint8Array([ + 2, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ]) + ); + }); + + it('encodes tuple types with actual array values', () => { + expect( + encodeParam({ type: ['Balance', 'Index'] }, [3, 4]) + ).toEqual( + new Uint8Array([ + 2, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0 + ]) + ); + }); +}); diff --git a/packages/type-params/src/encode/param.ts b/packages/type-params/src/encode/param.ts new file mode 100644 index 000000000..7b1d96dbf --- /dev/null +++ b/packages/type-params/src/encode/param.ts @@ -0,0 +1,40 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { EncodingVersions, Param, Param$Type } from '../types'; + +import assert from '@polkadot/util/assert'; +import u8aConcat from '@polkadot/util/u8a/concat'; +import bnToU8a from '@polkadot/util/bn/toU8a'; + +import typeToString from '../typeToString'; +import encodeType from './type'; + +export default function encodeParam (param: Param, value: any, version: EncodingVersions = 'latest'): Uint8Array { + if (Array.isArray(param.type)) { + assert(Array.isArray(value), () => `Expected array values of type '${typeToString(param.type)}'`); + + const arr = (value as Array); + const types = (param.type as Array); + + if (types.length === 1) { + return u8aConcat( + bnToU8a(arr.length, 32, true), + u8aConcat.apply(null, arr.map((v, index) => + encodeType(types[0], v, version) + )) + ); + } + + return u8aConcat( + bnToU8a(arr.length, 32, true), + u8aConcat.apply(null, arr.map((v, index) => + // NOTE since we may have embedded again, move to Param shape + encodeParam(({ type: types[index] } as Param), v, version) + )) + ); + } + + return encodeType(param.type, value, version); +} diff --git a/packages/type-params/src/encode/type/index.ts b/packages/type-params/src/encode/type/index.ts new file mode 100644 index 000000000..ebeece0ee --- /dev/null +++ b/packages/type-params/src/encode/type/index.ts @@ -0,0 +1,101 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { EncodingVersions, Param$Type } from '../../types'; + +import addrPrefixes from '@polkadot/extrinsics-codec/encode/prefixes'; +import bnToU8a from '@polkadot/util/bn/toU8a'; +import u8aConcat from '@polkadot/util/u8a/concat'; +import u8aFromString from '@polkadot/util/u8a/fromString'; +import u8aToU8a from '@polkadot/util/u8a/toU8a'; +import addressDecode from '@polkadot/util-keyring/address/decode'; + +import sizes from '../../sizes'; + +export default function encodeType (type: Param$Type, value: any, version: EncodingVersions): Uint8Array { + try { + switch (type) { + case 'AccountId': + return u8aConcat( + version === 'poc-1' + ? addrPrefixes.none + : addrPrefixes.publicKey, + addressDecode(value) + ); + + case 'Balance': + return bnToU8a(value, sizes.Balance.get(version), true); + + case 'BlockNumber': + case 'SessionKey': + case 'u64': + return bnToU8a(value, 64, true); + + case 'bool': + return bnToU8a(value ? 1 : 0, 8, true); + + case 'Bytes': + case 'Code': + return u8aToU8a(value); + + // FIXME Here we should pass through the actual objects + case 'Call': + case 'CandidateReceipt': + case 'Digest': + case 'Header': + case 'KeyValue': + case 'KeyValueStorage': + case 'MisbehaviorReport': + case 'Proposal': + return u8aToU8a(value); + + // TODO Here we should do actual length conversions, i.e. 256/512 + case 'Hash': + case 'Signature': + return u8aToU8a(value); + + case 'Index': + return bnToU8a(value, sizes.Index.get(version), true); + + case 'ParachainId': + case 'PropIndex': + case 'ReferendumIndex': + case 'VoteIndex': + case 'u32': + return bnToU8a(value, 32, true); + + case 'String': + return (() => { + const u8a = u8aFromString(value); + + return u8aConcat( + bnToU8a(u8a.length, 32, true), + u8a + ); + })(); + + case 'Timestamp': + if (value instanceof Date) { + value = Math.ceil(value.getTime() / 1000); + } + + return bnToU8a(value, 64, true); + + case 'u128': + return bnToU8a(value, 128, true); + + // TODO enums? + case 'VoteThreshold': + return bnToU8a(value || 0, 8, true); + + default: + (type as never); // eslint-disable-line no-unused-expressions + throw new Error(`No formatter for ${type}`); + } + } catch (error) { + console.error('Failed encoding', type, 'with', value, error); + + throw error; + } +} diff --git a/packages/type-params/src/method.ts b/packages/type-params/src/method.ts new file mode 100644 index 000000000..b63ad2711 --- /dev/null +++ b/packages/type-params/src/method.ts @@ -0,0 +1,26 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { SectionItem, CreateItem, CreateItems, CreateItemOptions } from './types'; + +import bnToU8a from '@polkadot/util/bn/toU8a'; +import u8aConcat from '@polkadot/util/u8a/concat'; + +export default function createMethod (section: keyof T, sectionIndex: Uint8Array): CreateItems { + return (name: string, index: number = 0): CreateItem => + ({ description, key = '', params, type, isDeprecated = false, isHidden = false, isSigned = false, isSubscription = false, isUnhashed = false }: CreateItemOptions): SectionItem => ({ + description, + index: u8aConcat(sectionIndex, bnToU8a(index, 8)), + isDeprecated, + isHidden, + isSigned, + isSubscription, + isUnhashed, + key, + name, + params, + section, + type + }); +} diff --git a/packages/type-params/src/param.ts b/packages/type-params/src/param.ts new file mode 100644 index 000000000..c103a8926 --- /dev/null +++ b/packages/type-params/src/param.ts @@ -0,0 +1,13 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param, Param$Options, Param$Types } from './types'; + +export default function createParam (name: string, type: Param$Types, { isOptional = false }: Param$Options = { isOptional: false }): Param { + return { + isOptional, + name, + type + }; +} diff --git a/packages/type-params/src/section.ts b/packages/type-params/src/section.ts new file mode 100644 index 000000000..d68491184 --- /dev/null +++ b/packages/type-params/src/section.ts @@ -0,0 +1,36 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Section, CreateSection, CreateSectionOptions } from './types'; + +import bnToU8a from '@polkadot/util/bn/toU8a'; + +import createMethod from './method'; + +export default function createSection (name: keyof T, _index: number = 0): CreateSection { + const index = bnToU8a(_index, 8); + const creator = (optOrFn: CreateSectionOptions): Section => { + if (typeof optOrFn === 'function') { + return creator( + optOrFn( + createMethod(name, index) + ) + ); + } + + const { description, isDeprecated = false, isHidden = false } = optOrFn; + + return { + description, + isDeprecated, + isHidden, + index, + name, + private: optOrFn.private || {}, + public: optOrFn.public || {} + }; + }; + + return creator; +} diff --git a/packages/type-params/src/signature.spec.js b/packages/type-params/src/signature.spec.js new file mode 100644 index 000000000..1d3185d2d --- /dev/null +++ b/packages/type-params/src/signature.spec.js @@ -0,0 +1,33 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import param from './param'; +import signature from './signature'; + +describe('jsonrpcSignature', () => { + it('formats the signature according to the specification', () => { + expect( + signature({ + name: 'test', + description: 'test', + params: [ + param('a', 'AccountId'), + param('b', 'Bytes') + ], + type: 'Signature' + }) + ).toEqual('test (a: AccountId, b: Bytes): Signature'); + }); + + it('empty inputs format correctly', () => { + expect( + signature({ + name: 'test', + description: 'test', + params: [], + type: 'AccountId' + }) + ).toEqual('test (): AccountId'); + }); +}); diff --git a/packages/type-params/src/signature.ts b/packages/type-params/src/signature.ts new file mode 100644 index 000000000..c30a942c2 --- /dev/null +++ b/packages/type-params/src/signature.ts @@ -0,0 +1,26 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { SectionItem } from './types'; + +import typeToString from './typeToString'; + +/** + @name signature + @signature jsonrpcSignature (method: InterfaceMethodDefinition): string + @summary Returns a string representation of the method with inputs and outputs. + @description + Formats the name, inputs and outputs into a human-readable string. This contains the input parameter names, input types and output type. + @example + import signature from '@polkadot/params/signature'; + + console.log(signature({ name: 'test_method', params: [ { name: 'dest', type: 'Address' } ], type: 'Address' })); // => test_method (dest: Address): Address +*/ +export default function signature ({ name, params, type }: SectionItem): string { + const inputs = params.map(({ name, type }) => + `${name}: ${typeToString(type)}` + ).join(', '); + + return `${name} (${inputs}): ${typeToString(type)}`; +} diff --git a/packages/type-params/src/sizes.ts b/packages/type-params/src/sizes.ts new file mode 100644 index 000000000..b9078c06b --- /dev/null +++ b/packages/type-params/src/sizes.ts @@ -0,0 +1,23 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { SizeType } from '@polkadot/primitives/sizes'; +import { EncodingVersions } from './types'; + +import sizes from '@polkadot/primitives/sizes'; + +const Balance: Map = new Map([ + ['latest' as EncodingVersions, sizes.Balance], + ['poc-1' as EncodingVersions, 64 as SizeType] +]); + +const Index: Map = new Map([ + ['latest' as EncodingVersions, sizes.Index], + ['poc-1' as EncodingVersions, 64 as SizeType] +]); + +export default { + Balance, + Index +}; diff --git a/packages/type-params/src/typeToString.spec.js b/packages/type-params/src/typeToString.spec.js new file mode 100644 index 000000000..c413d871c --- /dev/null +++ b/packages/type-params/src/typeToString.spec.js @@ -0,0 +1,31 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import typeToString from './typeToString'; + +describe('typeToString', () => { + it('formats single types', () => { + expect( + typeToString('BlockNumber') + ).toEqual('BlockNumber'); + }); + + it('formats array types', () => { + expect( + typeToString(['BlockNumber']) + ).toEqual('Array'); + }); + + it('formats tuple types', () => { + expect( + typeToString(['AccountId', 'BlockNumber']) + ).toEqual('(AccountId, BlockNumber)'); + }); + + it('formats tuple arrays', () => { + expect( + typeToString([['AccountId', 'BlockNumber']]) + ).toEqual('Array<(AccountId, BlockNumber)>'); + }); +}); diff --git a/packages/type-params/src/typeToString.ts b/packages/type-params/src/typeToString.ts new file mode 100644 index 000000000..021264704 --- /dev/null +++ b/packages/type-params/src/typeToString.ts @@ -0,0 +1,17 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Param$Types } from './types'; + +export default function typeToString (type: Param$Types): string { + if (!Array.isArray(type)) { + return type; + } + + const text = type.map(typeToString).join(', '); + + return type.length !== 1 + ? `(${text})` + : `Array<${text}>`; +} diff --git a/packages/type-params/src/types.d.ts b/packages/type-params/src/types.d.ts new file mode 100644 index 000000000..82bd0cc33 --- /dev/null +++ b/packages/type-params/src/types.d.ts @@ -0,0 +1,115 @@ +// Copyright 2017-2018 @polkadot/params authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; +import { Extrinsics } from '@polkadot/extrinsics/types'; +import { Digest } from '@polkadot/primitives/digest'; +import { Header } from '@polkadot/primitives/header'; +import { MisbehaviorReport } from '@polkadot/primitives/misbehavior'; + +export type EncodingVersions = 'poc-1' | 'latest'; + +// TODO: Also update the following +// - @polkadot/storage/create/decode/index.js +// - decode/value/index.js +// - encode/type/index.js +export type Param$Type = 'AccountId' | 'Balance' | 'BlockNumber' | 'bool' | 'Bytes' | 'Call' | 'CandidateReceipt' | 'Code' | 'Digest' | 'Hash' | 'Header' | 'Index' | 'KeyValue' | 'KeyValueStorage' | 'MisbehaviorReport' | 'ParachainId' | 'PropIndex' | 'Proposal' | 'ReferendumIndex' | 'SessionKey' | 'Signature' | 'String' | 'Timestamp' | 'u32' | 'u64' | 'u128' | 'VoteIndex' | 'VoteThreshold'; + +export type Param$Type$Array = Array>>; + +export type Param$Types = Param$Type | Param$Type$Array; + +export type ExtrinsicDecoded = { + extrinsic: SectionItem, + params: Array +} + +export type KeyValue = { + key: Uint8Array, + value: Uint8Array +} + +export type Param$Value = Digest | Header | KeyValue | MisbehaviorReport | ExtrinsicDecoded | BN | Date | Uint8Array | boolean | number | string; + +export type Param$Value$Array = Array>>; + +export type Param$Values = Param$Value | Param$Value$Array; + +export type Param$Decoded = { + length: number, + value: Param$Values +} + +export type Param$Options = { + isOptional: boolean +}; + +export type Param = Param$Options & { + name: string, + type: Param$Types +}; + +export type Params = Array; + +// FIXME: This is a bit horrible, since not all the params (apart from deprecated/hidden) is applicable to all. Not a major inconveninece, but it is itching +export type SectionItem = { + description: string, + index: Uint8Array, // only for extrinsics, + isDeprecated: boolean, + isHidden: boolean, + isSigned: boolean, // only for extrinsics + isSubscription: boolean, // only for jsonrpc + isUnhashed: boolean, // only for storage + key: string, // only for storage + name: string, + params: Params, + section: keyof T, + type: Param$Types +}; + +export type SectionItems = { + [index: string]: SectionItem +}; + +export type Section = { + isDeprecated: boolean, + isHidden: boolean, + description: string, + index: Uint8Array, + name: keyof T, + private: SectionItems, + public: SectionItems +}; + +export type Sections = Map>; + +export type CreateItemOptions = { + description: string, + isDeprecated?: boolean, + isHidden?: boolean, + isSigned?: boolean, + isSubscription?: boolean, + isUnhashed?: boolean, + key?: string, + params: Params, + type: Param$Types +}; + +export type CreateItem = (options: CreateItemOptions) => SectionItem; + +export type CreateItems = (name: string, index?: number) => CreateItem; + +export type CreateSectionOptions$Only = { + description: string, + isDeprecated?: boolean, + isHidden?: boolean, + 'private'?: SectionItems, + 'public'?: SectionItems +}; + +export type CreateSectionOptions$Fn = (method: CreateItems) => CreateSectionOptions$Only; + +export type CreateSectionOptions = CreateSectionOptions$Only | CreateSectionOptions$Fn; + +export type CreateSection = (options: CreateSectionOptions) => Section; diff --git a/packages/type-primitives/LICENSE b/packages/type-primitives/LICENSE new file mode 100644 index 000000000..182ebe3bb --- /dev/null +++ b/packages/type-primitives/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017-2018 @polkadot/primitives authors & contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/type-primitives/README.md b/packages/type-primitives/README.md new file mode 100644 index 000000000..b14064e52 --- /dev/null +++ b/packages/type-primitives/README.md @@ -0,0 +1,33 @@ +[![polkadotjs](https://img.shields.io/badge/polkadot-js-orange.svg?style=flat-square)](https://polkadot.js.org) +![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) +[![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) +[![npm](https://img.shields.io/npm/v/@polkadot/primitives.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/primitives) +[![travis](https://img.shields.io/travis/polkadot-js/types.svg?style=flat-square)](https://travis-ci.org/polkadot-js/types) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/types.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/types/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/types.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/types?branch=master) +[![dependency](https://david-dm.org/polkadot-js/types.svg?style=flat-square&path=packages/primitives)](https://david-dm.org/polkadot-js/types?path=packages/primitives) +[![devDependency](https://david-dm.org/polkadot-js/types/dev-status.svg?style=flat-square&path=packages/primitives)](https://david-dm.org/polkadot-js/types?path=packages/primitives#info=devDependencies) + +# @polkadot/primitives + +Base [flow](https://flow.org/) definitions for the base Polkadot types as defined in the [specification](https://github.com/w3f/polkadot-spec). It is useful for implementations, applications and libraries, where type-checking of the JavaScript base types is of importance. + +## Usage + +Installation - + +``` +npm install --save @polkadot/primitives +``` + +Usage - + +```js +// @flow + +import type { AccountId, Balance } from '@polkadot/primitives/base'; + +function getBalance (accountId: AccountId): Balance { + ... +} +``` diff --git a/packages/type-primitives/package.json b/packages/type-primitives/package.json new file mode 100644 index 000000000..d9ce17bef --- /dev/null +++ b/packages/type-primitives/package.json @@ -0,0 +1,42 @@ +{ + "name": "@polkadot/primitives", + "version": "0.25.0", + "description": "Type defintions for the Polkadot network", + "main": "index.js", + "engines": { + "node": ">=6.4" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-js/types.git" + }, + "keywords": [ + "Polkadot" + ], + "author": "Jaco Greeff ", + "maintainers": [ + "Jaco Greeff " + ], + "contributors": [], + "license": "ISC", + "bugs": { + "url": "https://github.com/polkadot-js/types/issues" + }, + "homepage": "https://github.com/polkadot-js/types/tree/master/packages/primitives#readme", + "scripts": { + "build": "polkadot-dev-build-babel", + "check": "eslint src && flow check", + "test": "echo \"Tests only available from root wrapper\"" + }, + "dependencies": { + "@babel/runtime": "^7.0.0-beta.51", + "@polkadot/util": "^0.25.0" + }, + "devDependencies": { + "bn.js": "^4.11.8" + } +} diff --git a/packages/type-primitives/src/base.d.ts b/packages/type-primitives/src/base.d.ts new file mode 100644 index 000000000..7e1c52409 --- /dev/null +++ b/packages/type-primitives/src/base.d.ts @@ -0,0 +1,27 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; + +export type Bytes = Uint8Array; +export type Hash = Uint8Array; +export type H160 = Uint8Array; +export type H256 = Uint8Array; +export type H512 = Uint8Array; +export type U32 = BN; +export type U64 = BN; +export type U128 = BN; +export type U256 = BN; + +export type AccountId = H256; +export type Balance = U128; +export type BlockNumber = U64; +export type ChainId = U32; +export type HeaderHash = H256; +export type Index = U32; +export type ObjectId = U64; +export type ParaChainId = U64; +export type Proportion = U64; +export type Signature = H512; +export type Timestamp = U64; diff --git a/packages/type-primitives/src/bft.d.ts b/packages/type-primitives/src/bft.d.ts new file mode 100644 index 000000000..b0b849a0d --- /dev/null +++ b/packages/type-primitives/src/bft.d.ts @@ -0,0 +1,13 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { AccountId, HeaderHash, Signature } from './base'; + +export type Justification$Signature = [AccountId, Signature]; + +export type Justification = { + roundNumber: number, + hash: HeaderHash, + signatures: Array +} diff --git a/packages/type-primitives/src/block.d.ts b/packages/type-primitives/src/block.d.ts new file mode 100644 index 000000000..9db668a99 --- /dev/null +++ b/packages/type-primitives/src/block.d.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Header } from './header'; +import { UncheckedRaw } from './extrinsic'; + +export type Block = { + header: Header, + extrinsics: Array +}; diff --git a/packages/type-primitives/src/candidate.d.ts b/packages/type-primitives/src/candidate.d.ts new file mode 100644 index 000000000..0624915f9 --- /dev/null +++ b/packages/type-primitives/src/candidate.d.ts @@ -0,0 +1,24 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { AccountId, Balance, Bytes, ChainId, Hash, Signature } from './base'; + +export type Candidate = { + parachainIndex: ChainId, + collatorSignature: Signature, + unprocessedIngress: Array>>, + blockData: Bytes +}; + +export type CandidateReceipt$BalanceUpload = [AccountId, Balance]; +export type CandidateReceipt$EgressQueueRoot = [ChainId, Hash]; + +export type CandidateReceipt = { + parachainIndex: ChainId, + collator: AccountId, + headData: Bytes, + balanceUploads: Array, + egressQueueRoots: Array, + fees: Balance +}; diff --git a/packages/type-primitives/src/digest.d.ts b/packages/type-primitives/src/digest.d.ts new file mode 100644 index 000000000..1b941e3de --- /dev/null +++ b/packages/type-primitives/src/digest.d.ts @@ -0,0 +1,11 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Bytes } from './base'; + +export type Digest$Log = Bytes; + +export type Digest = { + logs: Array +}; diff --git a/packages/type-primitives/src/extrinsic.d.ts b/packages/type-primitives/src/extrinsic.d.ts new file mode 100644 index 000000000..2521fceca --- /dev/null +++ b/packages/type-primitives/src/extrinsic.d.ts @@ -0,0 +1,17 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { AccountId, Index, Signature } from './base'; + +// TODO Should be the actual decoded extrinsic +export type ExtrinsicFunction = Uint8Array; + +export type Unchecked = { + index: Index, + function: ExtrinsicFunction, + signed: AccountId, + signature: Signature +}; + +export type UncheckedRaw = Uint8Array; diff --git a/packages/type-primitives/src/header.d.ts b/packages/type-primitives/src/header.d.ts new file mode 100644 index 000000000..28fa684a8 --- /dev/null +++ b/packages/type-primitives/src/header.d.ts @@ -0,0 +1,14 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { BlockNumber, Hash, HeaderHash } from './base'; +import { Digest } from './digest'; + +export type Header = { + extrinsicsRoot: Hash, + digest: Digest, + number: BlockNumber, + parentHash: HeaderHash, + stateRoot: Hash +}; diff --git a/packages/type-primitives/src/misbehavior.d.ts b/packages/type-primitives/src/misbehavior.d.ts new file mode 100644 index 000000000..d016f692d --- /dev/null +++ b/packages/type-primitives/src/misbehavior.d.ts @@ -0,0 +1,16 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { AccountId, BlockNumber, HeaderHash, Signature } from './base'; + +export type MisbehaviorReport = { + authorityId: AccountId, + number: BlockNumber, + parentHash: HeaderHash, + type: number, + data: Array<{ + header: HeaderHash, + signature: Signature + }> +}; diff --git a/packages/type-primitives/src/parachain.unused-ts b/packages/type-primitives/src/parachain.unused-ts new file mode 100644 index 000000000..aa8d84373 --- /dev/null +++ b/packages/type-primitives/src/parachain.unused-ts @@ -0,0 +1,21 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { AccountId, Balance, Bytes, Hash } from './base'; + +export type ParachainState$BalanceDownload = [Balance, Bytes]; + +export type ParachainState$EgressRoot = Hash; + +export type ParachainState = { + headData: Bytes, + balance: Balance, + userBalances: { + [AccountId]: Balance + }, + balanceDownloads: { + [AccountId]: ParachainState$BalanceDownload + }, + egressRoots: Array +}; diff --git a/packages/type-primitives/src/role/all.ts b/packages/type-primitives/src/role/all.ts new file mode 100644 index 000000000..d5be02d7e --- /dev/null +++ b/packages/type-primitives/src/role/all.ts @@ -0,0 +1,15 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Role } from './index'; + +const all: Map = new Map([ + ['none' as Role, 0b00000000], + ['full' as Role, 0b00000001], + ['light' as Role, 0b00000010], + ['collator' as Role, 0b00000100], + ['validator' as Role, 0b00001000] +]); + +export default all; diff --git a/packages/type-primitives/src/role/fromId.spec.js b/packages/type-primitives/src/role/fromId.spec.js new file mode 100644 index 000000000..ba1917e96 --- /dev/null +++ b/packages/type-primitives/src/role/fromId.spec.js @@ -0,0 +1,19 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import roleFromId from './fromId'; + +describe('roleFromId', () => { + it('throws when valid mapping is not found', () => { + expect( + () => roleFromId() + ).toThrow(/Unable to find valid role/); + }); + + it('returns the role mapping an string', () => { + expect( + roleFromId(0b00000100) + ).toEqual('collator'); + }); +}); diff --git a/packages/type-primitives/src/role/fromId.ts b/packages/type-primitives/src/role/fromId.ts new file mode 100644 index 000000000..5539c22b0 --- /dev/null +++ b/packages/type-primitives/src/role/fromId.ts @@ -0,0 +1,19 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Role } from './index'; + +import assert from '@polkadot/util/assert'; +import isUndefined from '@polkadot/util/is/undefined'; + +import all from './all'; + +export default function roleFromId (roleId: number): Role { + const role = [...all].find(([key, value]) => value === roleId); + + assert(!isUndefined(role), `Unable to find valid role for '${roleId}'`); + + // @ts-ignore we have something, checked by assert + return role[0]; +} diff --git a/packages/type-primitives/src/role/index.d.ts b/packages/type-primitives/src/role/index.d.ts new file mode 100644 index 000000000..380b77f7d --- /dev/null +++ b/packages/type-primitives/src/role/index.d.ts @@ -0,0 +1,5 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +export type Role = 'collator' | 'full' | 'light' | 'none' | 'validator'; diff --git a/packages/type-primitives/src/role/toId.spec.js b/packages/type-primitives/src/role/toId.spec.js new file mode 100644 index 000000000..ba004c578 --- /dev/null +++ b/packages/type-primitives/src/role/toId.spec.js @@ -0,0 +1,19 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import roleToId from './toId'; + +describe('roleToId', () => { + it('throws when valid mapping is not found', () => { + expect( + () => roleToId() + ).toThrow(/mapping from role/); + }); + + it('returns the role mapping an string', () => { + expect( + roleToId('collator') + ).toEqual(0b00000100); + }); +}); diff --git a/packages/type-primitives/src/role/toId.ts b/packages/type-primitives/src/role/toId.ts new file mode 100644 index 000000000..f26055831 --- /dev/null +++ b/packages/type-primitives/src/role/toId.ts @@ -0,0 +1,19 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Role } from './index'; + +import assert from '@polkadot/util/assert'; +import isUndefined from '@polkadot/util/is/undefined'; + +import all from './all'; + +export default function roleToId (role: Role): number { + const roleId = all.get(role); + + assert(!isUndefined(roleId), `Unable to perform mapping from role '${role}'`); + + // @ts-ignore assert catches above + return roleId; +} diff --git a/packages/type-primitives/src/sizes.ts b/packages/type-primitives/src/sizes.ts new file mode 100644 index 000000000..1efe12a6c --- /dev/null +++ b/packages/type-primitives/src/sizes.ts @@ -0,0 +1,15 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +export type SizeType = 32 | 64 | 128; + +const Balance: SizeType = 128; +const BlockNumber: SizeType = 64; +const Index: SizeType = 32; + +export default { + Balance, + BlockNumber, + Index +}; diff --git a/packages/type-primitives/src/state.unused-ts b/packages/type-primitives/src/state.unused-ts new file mode 100644 index 000000000..33d617b70 --- /dev/null +++ b/packages/type-primitives/src/state.unused-ts @@ -0,0 +1,14 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Hash, ObjectId } from './base'; + +export type State$Storage = { + codeHash: Hash, + storageRoot: Hash +}; + +export type State = { + [index: ObjectId]: State$Storage +}; diff --git a/packages/type-storage/LICENSE b/packages/type-storage/LICENSE new file mode 100644 index 000000000..2cb93d924 --- /dev/null +++ b/packages/type-storage/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017-2018 @polkadot/storage authors & contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/type-storage/README.md b/packages/type-storage/README.md new file mode 100644 index 000000000..b1325bd64 --- /dev/null +++ b/packages/type-storage/README.md @@ -0,0 +1,13 @@ +[![polkadotjs](https://img.shields.io/badge/polkadot-js-orange.svg?style=flat-square)](https://polkadot.js.org) +![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) +[![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) +[![npm](https://img.shields.io/npm/v/@polkadot/storage.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/storage) +[![travis](https://img.shields.io/travis/polkadot-js/types.svg?style=flat-square)](https://travis-ci.org/polkadot-js/types) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/types.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/types/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/types.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/types?branch=master) +[![dependency](https://david-dm.org/polkadot-js/types.svg?style=flat-square&path=packages/storage)](https://david-dm.org/polkadot-js/types?path=packages/storage) +[![devDependency](https://david-dm.org/polkadot-js/types/dev-status.svg?style=flat-square&path=packages/storage)](https://david-dm.org/polkadot-js/types?path=packages/storage#info=devDependencies) + +# @polkadot/storage + +An base interface to the storage layer diff --git a/packages/type-storage/package.json b/packages/type-storage/package.json new file mode 100644 index 000000000..4aeb5468b --- /dev/null +++ b/packages/type-storage/package.json @@ -0,0 +1,44 @@ +{ + "name": "@polkadot/storage", + "version": "0.25.0", + "description": "Generic wrapper wrapper around state storage", + "main": "index.js", + "engines": { + "node": ">=8.0" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-js/types.git" + }, + "keywords": [ + "Polkadot", + "Merkel Patricia Tree" + ], + "author": "Jaco Greeff ", + "maintainers": [ + "Jaco Greeff " + ], + "contributors": [], + "license": "ISC", + "bugs": { + "url": "https://github.com/polkadot-js/types/issues" + }, + "homepage": "https://github.com/polkadot-js/types/tree/master/packages/storage#readme", + "scripts": { + "build": "polkadot-dev-build-babel", + "check": "eslint src && flow check", + "test": "echo \"Tests only available from root wrapper\"" + }, + "dependencies": { + "@babel/runtime": "^7.0.0-beta.51", + "@polkadot/params": "^0.25.0", + "@polkadot/primitives": "^0.25.0", + "@polkadot/util": "^0.25.0", + "@polkadot/util-crypto": "^0.25.0", + "@polkadot/util-keyring": "^0.25.0" + } +} diff --git a/packages/type-storage/src/consensus.ts b/packages/type-storage/src/consensus.ts new file mode 100644 index 000000000..6e1e159f7 --- /dev/null +++ b/packages/type-storage/src/consensus.ts @@ -0,0 +1,48 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Storages, Storage$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const authorityAt: CreateItemOptions = { + description: 'Authority at a specific index', + isUnhashed: true, + key: ':auth:', + params: [ + param('index', 'u32') + ], + type: 'AccountId' +}; + +const authorityCount: CreateItemOptions = { + description: 'The number of authorities', + isUnhashed: true, + key: ':auth:len', + params: [], + type: 'u32' +}; + +const code: CreateItemOptions = { + description: 'The current runtime code', + isUnhashed: true, + key: ':code', + params: [], + type: 'Code' +}; + +export default (name: Storage$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Consensus', + public: { + authorityAt: + createMethod('authorityAt')(authorityAt), + authorityCount: + createMethod('authorityCount')(authorityCount), + code: + createMethod('code')(code) + } + })); diff --git a/packages/type-storage/src/council.ts b/packages/type-storage/src/council.ts new file mode 100644 index 000000000..d9025e2a4 --- /dev/null +++ b/packages/type-storage/src/council.ts @@ -0,0 +1,202 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Storages, Storage$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const activeCouncil: CreateItemOptions = { + description: 'The current council', + key: 'cou:act', + params: [], + type: [['AccountId', 'BlockNumber']] +}; + +const approvalsOf: CreateItemOptions = { + description: 'The last cleared vote index that this voter was last active at', + key: 'cou:apr', + params: [ + param('who', 'AccountId') + ], + type: ['bool'] +}; + +const candidacyBond: CreateItemOptions = { + description: 'How much should be locked up in order to submit candidacy', + key: 'cou:cbo', + params: [], + type: 'Balance' +}; + +const carryCount: CreateItemOptions = { + description: 'How many runners-up should have their approvals persist until the next vote', + key: 'cou:cco', + params: [], + type: 'u32' +}; + +const candidateCount: CreateItemOptions = { + description: 'Number of candidates', + key: 'cou:cnc', + params: [], + type: 'u32' +}; + +const candidates: CreateItemOptions = { + description: 'The present candidate lis', + key: 'cou:can', + params: [], + type: ['AccountId'] +}; + +const desiredSeats: CreateItemOptions = { + description: 'The number of desired seats', + key: 'cou:sts', + params: [], + type: 'u32' +}; + +const inactiveGracePeriod: CreateItemOptions = { + description: 'How many votes need to go by after a last vote', + key: 'cou:vgp', + params: [], + type: 'VoteIndex' +}; + +const lastActiveOf: CreateItemOptions = { + description: 'The last cleared vote index that this voter was last active at', + key: 'cou:lac', + params: [ + param('who', 'AccountId') + ], + type: 'VoteIndex' +}; + +const leaderboard: CreateItemOptions = { + description: 'Get the leaderboard if we;re in the presentation phase', + key: 'cou:win', + params: [], + type: [['Balance', 'AccountId']] +}; + +const nextFinalise: CreateItemOptions = { + description: 'The accounts holding the seats that will become free', + key: 'cou:nxt', + params: [], + type: ['BlockNumber', 'u32', ['AccountId']] +}; + +const presentSlashPerVoter: CreateItemOptions = { + description: 'The punishment, per voter, if you provide an invalid presentation', + key: 'cou:pss', + params: [], + type: 'Balance' +}; + +const presentationDuration: CreateItemOptions = { + description: 'How long to give each top candidate to present themselves after the vote ends', + key: 'cou:pdu', + params: [], + type: 'BlockNumber' +}; + +const registerInfoOf: CreateItemOptions = { + description: 'The vote index and list slot that the candidate was registered', + key: 'cou:reg', + params: [ + param('who', 'AccountId') + ], + type: [['VoteIndex', 'u32']] +}; + +const snapshotedStakes: CreateItemOptions = { + description: 'The balances', + key: 'cou:sss', + params: [], + type: ['Balance'] +}; + +const termDuration: CreateItemOptions = { + description: 'How long each position is active for', + key: 'cou:trm', + params: [], + type: 'BlockNumber' +}; + +const voteCount: CreateItemOptions = { + description: 'The total number of votes that have happened or are in progress', + key: 'cou:vco', + params: [], + type: 'VoteIndex' +}; + +const votingBond: CreateItemOptions = { + description: 'How much should be locked up in order to be able to submit votes', + key: 'cou:vbo', + params: [], + type: 'Balance' +}; + +const votingPeriod: CreateItemOptions = { + description: 'How often (in blocks) to check for new votes', + key: 'cou:per', + params: [], + type: 'BlockNumber' +}; + +const voters: CreateItemOptions = { + description: 'The present voter list', + key: 'cou:vrs', + params: [], + type: ['AccountId'] +}; + +export default (name: keyof Storages): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Council', + public: { + candidacyBond: + createMethod('candidacyBond')(candidacyBond), + votingBond: + createMethod('votingBond')(votingBond), + presentSlashPerVoter: + createMethod('presentSlashPerVoter')(presentSlashPerVoter), + carryCount: + createMethod('carryCount')(carryCount), + presentationDuration: + createMethod('presentationDuration')(presentationDuration), + inactiveGracePeriod: + createMethod('inactiveGracePeriod')(inactiveGracePeriod), + votingPeriod: + createMethod('votingPeriod')(votingPeriod), + termDuration: + createMethod('termDuration')(termDuration), + desiredSeats: + createMethod('desiredSeats')(desiredSeats), + activeCouncil: + createMethod('activeCouncil')(activeCouncil), + voteCount: + createMethod('voteCount')(voteCount), + approvalsOf: + createMethod('approvalsOf')(approvalsOf), + registerInfoOf: + createMethod('registerInfoOf')(registerInfoOf), + lastActiveOf: + createMethod('lastActiveOf')(lastActiveOf), + voters: + createMethod('voters')(voters), + candidateCount: + createMethod('candidateCount')(candidateCount), + candidates: + createMethod('candidates')(candidates), + nextFinalise: + createMethod('nextFinalise')(nextFinalise), + snapshotedStakes: + createMethod('snapshotedStakes')(snapshotedStakes), + leaderboard: + createMethod('leaderboard')(leaderboard) + } + })); diff --git a/packages/type-storage/src/councilVoting.ts b/packages/type-storage/src/councilVoting.ts new file mode 100644 index 000000000..567a40fd9 --- /dev/null +++ b/packages/type-storage/src/councilVoting.ts @@ -0,0 +1,88 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Storages, Storage$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const cooloffPeriod: CreateItemOptions = { + description: 'The coolof period', + key: 'cov:cooloff', + params: [], + type: 'BlockNumber' +}; + +const votingPeriod: CreateItemOptions = { + description: 'The voting period', + key: 'cov:period', + params: [], + type: 'BlockNumber' +}; + +const proposals: CreateItemOptions = { + description: 'The current proposals', + key: 'cov:prs', + params: [], + type: [['BlockNumber', 'Hash']] +}; + +const proposalOf: CreateItemOptions = { + description: 'The proposal by hash', + key: 'cov:pro', + params: [ + param('hash', 'Hash') + ], + type: 'Proposal' +}; + +const proposalVoters: CreateItemOptions = { + description: 'Voters on a proposal', + key: 'cov:voters:', + params: [ + param('hash', 'Hash') + ], + type: ['AccountId'] +}; + +const councilVoteOf: CreateItemOptions = { + description: 'Council votes on proposal', + key: 'cov:vote:', + params: [ + param('hash', 'Hash'), + param('who', 'AccountId') + ], + type: 'bool' +}; + +const vetoedProposal: CreateItemOptions = { + description: 'Council vetos on a proposal', + key: 'cov:veto:', + params: [ + param('hash', 'Hash') + ], + type: ['BlockNumber', 'AccountId'] +}; + +export default (name: Storage$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Council voting', + public: { + cooloffPeriod: + createMethod('cooloffPeriod')(cooloffPeriod), + votingPeriod: + createMethod('votingPeriod')(votingPeriod), + proposals: + createMethod('proposals')(proposals), + proposalOf: + createMethod('proposalOf')(proposalOf), + proposalVoters: + createMethod('proposalVoters')(proposalVoters), + councilVoteOf: + createMethod('councilVoteOf')(councilVoteOf), + vetoedProposal: + createMethod('vetoedProposal')(vetoedProposal) + } + })); diff --git a/packages/type-storage/src/democracy.ts b/packages/type-storage/src/democracy.ts new file mode 100644 index 000000000..fabb4118c --- /dev/null +++ b/packages/type-storage/src/democracy.ts @@ -0,0 +1,124 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Storages, Storage$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const proposalCount: CreateItemOptions = { + description: 'The number of (public) proposals that have been made so far', + key: 'dem:ppc', + params: [], + type: 'PropIndex' +}; + +const proposals: CreateItemOptions = { + description: 'The public proposals. Unsorted.', + key: 'dem:pub', + params: [], + type: [['PropIndex', 'Proposal', 'AccountId']] +}; + +const depositOf: CreateItemOptions = { + description: 'Those who have locked a deposit', + key: 'dem:dep:', + params: [ + param('index', 'PropIndex') + ], + type: ['Balance', ['AccountId']] +}; + +const launchPeriod: CreateItemOptions = { + description: 'How often (in blocks) new public referenda are launched', + key: 'dem:lau', + params: [], + type: 'BlockNumber' +}; + +const minimumDeposit: CreateItemOptions = { + description: 'The minimum amount as a deposit for a public referendum', + key: 'dem:lau', + params: [], + type: 'Balance' +}; + +const votingPeriod: CreateItemOptions = { + description: 'How often (in blocks) to check for new votes', + key: 'dem:per', + params: [], + type: 'BlockNumber' +}; + +const referendumCount: CreateItemOptions = { + description: 'The number of referendums started so far', + key: 'dem:rco', + params: [], + type: 'ReferendumIndex' +}; + +const nextTally: CreateItemOptions = { + description: 'The next referendum index that should be tallied', + key: 'dem:nxt', + params: [], + type: 'ReferendumIndex' +}; + +const referendumInfoOf: CreateItemOptions = { + description: 'Details for a specific referendum', + key: 'dem:pro:', + params: [ + param('referendum', 'ReferendumIndex') + ], + type: ['BlockNumber', 'Proposal', 'VoteThreshold'] +}; + +const votersFor: CreateItemOptions = { + description: 'Get the voters for the current proposal', + key: 'dem:vtr:', + params: [ + param('referendum', 'ReferendumIndex') + ], + type: ['AccountId'] +}; + +const voteOf: CreateItemOptions = { + description: 'Get the vote for Account', + key: 'dem:vot:', + params: [ + param('referendum', 'ReferendumIndex'), + param('who', 'AccountId') + ], + type: 'bool' +}; + +export default (name: Storage$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Democracy', + public: { + proposalCount: + createMethod('proposalCount')(proposalCount), + proposals: + createMethod('proposals')(proposals), + depositOf: + createMethod('depositOf')(depositOf), + launchPeriod: + createMethod('launchPeriod')(launchPeriod), + minimumDeposit: + createMethod('minimumDeposit')(minimumDeposit), + votingPeriod: + createMethod('votingPeriod')(votingPeriod), + referendumCount: + createMethod('referendumCount')(referendumCount), + nextTally: + createMethod('nextTally')(nextTally), + referendumInfoOf: + createMethod('referendumInfoOf')(referendumInfoOf), + votersFor: + createMethod('votersFor')(votersFor), + voteOf: + createMethod('voteOf')(voteOf) + } + })); diff --git a/packages/type-storage/src/governance.ts b/packages/type-storage/src/governance.ts new file mode 100644 index 000000000..b250192c0 --- /dev/null +++ b/packages/type-storage/src/governance.ts @@ -0,0 +1,49 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Storages, Storage$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const approvalsOf: CreateItemOptions = { + description: 'Approvals for a specific account', + isDeprecated: true, + key: 'gov:app:', + params: [ + param('who', 'AccountId') + ], + type: 'Bytes' +}; + +const approvalsRatio: CreateItemOptions = { + description: 'The apprivals ratio', + isDeprecated: true, + key: 'gov:apr', + params: [], + type: 'u32' +}; + +const currentProposal: CreateItemOptions = { + description: 'The current proposal', + isDeprecated: true, + key: 'gov:pro', + params: [], + type: 'Bytes' +}; + +export default (name: Storage$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Governance (deprecated)', + isDeprecated: true, + public: { + approvalsOf: + createMethod('approvalsOf')(approvalsOf), + approvalsRatio: + createMethod('approvalsRatio')(approvalsRatio), + currentProposal: + createMethod('currentProposal')(currentProposal) + } + })); diff --git a/packages/type-storage/src/index.ts b/packages/type-storage/src/index.ts new file mode 100644 index 000000000..72f51858d --- /dev/null +++ b/packages/type-storage/src/index.ts @@ -0,0 +1,31 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { Storages } from './types'; + +import consensus from './consensus'; +import council from './council'; +import councilVoting from './councilVoting'; +import democracy from './democracy'; +import governance from './governance'; +import parachains from './parachains'; +import session from './session'; +import staking from './staking'; +import system from './system'; +import timestamp from './timestamp'; + +const storages: Storages = { + consensus: consensus('consensus'), + council: council('council'), + councilVoting: councilVoting('councilVoting'), + democracy: democracy('democracy'), + governance: governance('governance'), + parachains: parachains('parachains'), + session: session('session'), + staking: staking('staking'), + system: system('system'), + timestamp: timestamp('timestamp') +}; + +export default storages; diff --git a/packages/type-storage/src/key/index.spec.js b/packages/type-storage/src/key/index.spec.js new file mode 100644 index 000000000..7ed9b7149 --- /dev/null +++ b/packages/type-storage/src/key/index.spec.js @@ -0,0 +1,59 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// 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 u8aFromString from '@polkadot/util/u8a/fromString'; +import param from '@polkadot/params/param'; + +import key from './index'; + +describe('key', () => { + it('concats the values', () => { + expect( + key({ + key: 'sys:old:', + params: [ + param('first', 'Bytes') + ] + })( + hexToU8a('0x0100000000000000') + ) + ).toEqual( + hexToU8a('0x3117ecd3eaa7a8c27cb8d04eb597a1ef') + ); + }); + + it('concats the values (Array)', () => { + expect( + key({ + key: 'sys:old:', + params: [ + param('first', 'Bytes'), + param('second', 'Bytes') + ] + })( + hexToU8a('0x01000000'), + hexToU8a('0x00000000') + ) + ).toEqual( + hexToU8a('0x3117ecd3eaa7a8c27cb8d04eb597a1ef') + ); + }); + + it('concats with empty key', () => { + expect( + key({ key: 'ses:llc' })() + ).toEqual( + hexToU8a('0xe14daa763fce793346d4b7e131240849') + ); + }); + + it('does not hash when not required', () => { + expect( + key({ key: ':code', isUnhashed: true })() + ).toEqual( + u8aFromString(':code') + ); + }); +}); diff --git a/packages/type-storage/src/key/index.ts b/packages/type-storage/src/key/index.ts new file mode 100644 index 000000000..ba095fda3 --- /dev/null +++ b/packages/type-storage/src/key/index.ts @@ -0,0 +1,29 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { SectionItem } from '@polkadot/params/types'; +import { Storage$Key$Value } from '../types'; + +import u8aConcat from '@polkadot/util/u8a/concat'; +import u8aFromString from '@polkadot/util/u8a/fromString'; +import xxhash from '@polkadot/util-crypto/xxhash/asU8a'; + +import formatParams from './params'; + +export type Keygen = (...keyParams: Array) => Uint8Array; + +export default function bindKey ({ isUnhashed, key, params }: SectionItem): Keygen { + const prefix = u8aFromString(key); + + return (...keyParams: Array): Uint8Array => { + const postfix = keyParams.length !== 0 + ? u8aConcat.apply(null, formatParams(params, keyParams)) + : new Uint8Array([]); + const prefixedKey = u8aConcat(prefix, postfix); + + return isUnhashed + ? prefixedKey + : xxhash(prefixedKey, 128); + }; +} diff --git a/packages/type-storage/src/key/params.ts b/packages/type-storage/src/key/params.ts new file mode 100644 index 000000000..9c2eab966 --- /dev/null +++ b/packages/type-storage/src/key/params.ts @@ -0,0 +1,85 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; +import { Param, Params } from '@polkadot/params/types'; +import { Storage$Key$Value } from '../types'; + +import sizes from '@polkadot/primitives/sizes'; +import bnToU8a from '@polkadot/util/bn/toU8a'; +import u8aToU8a from '@polkadot/util/u8a/toU8a'; +import u8aFromString from '@polkadot/util/u8a/fromString'; +import addressDecode from '@polkadot/util-keyring/address/decode'; + +export default function formatParams (params: Params, values: Storage$Key$Value[] = []): Array { + const paramTypes = Object.values(params).map(({ type }: Param) => type); + + return values.map((value: any, index: number): Uint8Array => { + try { + if (Array.isArray(paramTypes[index])) { + throw new Error('Unable to handle Array type'); + } + + const type = paramTypes[index]; + + switch (type) { + case 'AccountId': + return addressDecode((value as Uint8Array)); + + case 'Balance': + return bnToU8a((value as BN), sizes.Balance, true); + + case 'u128': + return bnToU8a((value as BN), 128, true); + + case 'BlockNumber': + case 'u64': + return bnToU8a((value as BN), 64, true); + + case 'bool': + return new Uint8Array([value ? 1 : 0]); + + case 'Bytes': + case 'Call': + case 'CandidateReceipt': + case 'Code': + case 'Digest': + case 'Hash': + case 'Header': + case 'KeyValue': + case 'KeyValueStorage': + case 'MisbehaviorReport': + case 'Proposal': + case 'Signature': + return u8aToU8a((value as Uint8Array)); + + case 'Index': + return bnToU8a((value as BN), sizes.Index, true); + + case 'ParachainId': + case 'PropIndex': + case 'ReferendumIndex': + case 'SessionKey': + case 'VoteIndex': + case 'VoteThreshold': + case 'u32': + return bnToU8a((value as BN), 32, true); + + case 'String': + return u8aFromString((value as string)); + + case 'Timestamp': + return bnToU8a((value as Date).getTime(), 64, true); + + default: + (type as never); // eslint-disable-line + throw new Error('Unable to find handler'); + } + } catch (error) { + console.error('formatParams', value, index, paramTypes[index], error); + + throw error; + } + }); +} diff --git a/packages/type-storage/src/parachains.ts b/packages/type-storage/src/parachains.ts new file mode 100644 index 000000000..3bbf4d684 --- /dev/null +++ b/packages/type-storage/src/parachains.ts @@ -0,0 +1,56 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Storages, Storage$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const activeParachains: CreateItemOptions = { + description: 'All registered parachains', + key: 'para:chains', + params: [], + type: ['ParachainId'] +}; + +const parachainCode: CreateItemOptions = { + description: 'Gets the code for a specific parachain', + key: 'para:code', + params: [ + param('id', 'ParachainId') + ], + type: 'Code' +}; + +const parachainHeads: CreateItemOptions = { + description: 'The heads of the parachains registered at present', + key: 'para:head', + params: [ + param('id', 'ParachainId') + ], + type: 'Bytes' +}; + +const didUpdate: CreateItemOptions = { + description: 'Did the parachain heads get updated in this block', + key: 'para:did', + params: [], + type: 'bool' +}; + +export default (name: Storage$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Parachain related entries', + public: { + activeParachains: + createMethod('activeParachains')(activeParachains), + parachainCode: + createMethod('parachainCode')(parachainCode), + parachainHeads: + createMethod('parachainHeads')(parachainHeads), + didUpdate: + createMethod('didUpdate')(didUpdate) + } + })); diff --git a/packages/type-storage/src/session.ts b/packages/type-storage/src/session.ts new file mode 100644 index 000000000..60d27aad1 --- /dev/null +++ b/packages/type-storage/src/session.ts @@ -0,0 +1,72 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Storages, Storage$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const currentIndex: CreateItemOptions = { + description: 'Current index of the session', + key: 'ses:ind', + params: [], + type: 'BlockNumber' +}; + +const lastSessionChange: CreateItemOptions = { + description: 'Block at which the session length last changed', + key: 'ses:llc', + params: [], + type: 'BlockNumber' +}; + +const nextKeyFor: CreateItemOptions = { + description: 'The next key for a given validator', + key: 'ses:nxt:', + params: [ + param('who', 'AccountId') + ], + type: 'SessionKey' +}; + +const nextLength: CreateItemOptions = { + description: 'The next session length', + key: 'ses:nln', + params: [], + type: 'BlockNumber' +}; + +const length: CreateItemOptions = { + description: 'Current length of the session', + key: 'ses:len', + params: [], + type: 'BlockNumber' +}; + +const validators: CreateItemOptions = { + description: 'Current validators', + key: 'ses:val', + params: [], + type: ['AccountId'] +}; + +export default (name: Storage$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Session management information', + public: { + currentIndex: + createMethod('currentIndex')(currentIndex), + lastSessionChange: + createMethod('lastSessionChange')(lastSessionChange), + nextKeyFor: + createMethod('nextKeyFor')(nextKeyFor), + nextLength: + createMethod('nextLength')(nextLength), + length: + createMethod('length')(length), + validators: + createMethod('validators')(validators) + } + })); diff --git a/packages/type-storage/src/staking.ts b/packages/type-storage/src/staking.ts new file mode 100644 index 000000000..7d9c7edbb --- /dev/null +++ b/packages/type-storage/src/staking.ts @@ -0,0 +1,152 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Storages, Storage$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const freeBalanceOf: CreateItemOptions = { + description: 'The balance of a given account', + key: 'sta:bal:', + params: [ + param('who', 'AccountId') + ], + type: 'Balance' +}; + +const bondageOf: CreateItemOptions = { + key: 'sta:bon:', + description: 'The block at which the account becomes liquid', + params: [ + param('who', 'AccountId') + ], + type: 'Balance' +}; + +const codeOf: CreateItemOptions = { + key: 'sta:cod:', + description: 'The code associated with an account', + params: [ + param('who', 'AccountId') + ], + type: 'Bytes' +}; + +const transactionFee: CreateItemOptions = { + description: 'The fee to be paid for making a transaction', + key: 'sta:fee', + params: [], + type: 'Balance' +}; + +const bondingDuration: CreateItemOptions = { + description: 'The length of the bonding duration in eras', + key: 'sta:loc', + params: [], + type: 'BlockNumber' +}; + +const currentEra: CreateItemOptions = { + description: 'The current era index', + key: 'sta:era', + params: [], + type: 'BlockNumber' +}; + +const reservedBalanceOf: CreateItemOptions = { + description: 'The amount of a given account that is reserved', + key: 'sta:lbo:', + params: [ + param('who', 'AccountId') + ], + type: 'Balance' +}; + +const intentions: CreateItemOptions = { + description: 'All the accounts with a desire to stake', + key: 'sta:wil:', + params: [], + type: ['AccountId'] +}; + +const lastEraLengthChange: CreateItemOptions = { + description: 'The block number at which the era length last changed', + key: 'sta:lec', + params: [], + type: 'BlockNumber' +}; + +const nextSessionsPerEra: CreateItemOptions = { + description: 'The next value of sessions per era', + key: 'sta:nse', + params: [], + type: 'BlockNumber' +}; + +const sessionsPerEra: CreateItemOptions = { + description: 'The length of a staking era in sessions', + key: 'sta:spe', + params: [], + type: 'BlockNumber' +}; + +const storageOf: CreateItemOptions = { + description: 'The storage items associated with an account/key', + key: 'sta:sto:', + params: [ + param('who', 'AccountId') + ], + type: 'Bytes' +}; + +const totalStake: CreateItemOptions = { + description: 'The total amount of stake on the system', + key: 'sta:tot', + params: [], + type: 'Balance' +}; + +const validatorCount: CreateItemOptions = { + description: 'The number of validators', + key: 'sta:vac', + params: [], + type: 'u32' +}; + +export default (name: Storage$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Staking', + public: { + freeBalanceOf: + createMethod('freeBalanceOf')(freeBalanceOf), + bondageOf: + createMethod('bondageOf')(bondageOf), + codeOf: + createMethod('codeOf')(codeOf), + transactionFee: + createMethod('transactionFee')(transactionFee), + bondingDuration: + createMethod('bondingDuration')(bondingDuration), + currentEra: + createMethod('currentEra')(currentEra), + reservedBalanceOf: + createMethod('reservedBalanceOf')(reservedBalanceOf), + intentions: + createMethod('intentions')(intentions), + lastEraLengthChange: + createMethod('lastEraLengthChange')(lastEraLengthChange), + nextSessionsPerEra: + createMethod('nextSessionsPerEra')(nextSessionsPerEra), + sessionsPerEra: + createMethod('sessionsPerEra')(sessionsPerEra), + storageOf: + createMethod('storageOf')(storageOf), + totalStake: + createMethod('totalStake')(totalStake), + validatorCount: + createMethod('validatorCount')(validatorCount) + } + })); diff --git a/packages/type-storage/src/system.ts b/packages/type-storage/src/system.ts new file mode 100644 index 000000000..2b625ba7d --- /dev/null +++ b/packages/type-storage/src/system.ts @@ -0,0 +1,103 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Param$Type, Section } from '@polkadot/params/types'; +import { Storages, Storage$Sections } from './types'; + +import param from '@polkadot/params/param'; +import createSection from '@polkadot/params/section'; + +const blockHashAt: CreateItemOptions = { + description: 'The blockHash for a specific number', + key: 'sys:old', + params: [ + param('blockNumber', 'BlockNumber') + ], + type: 'Hash' +}; + +const blockNumber: CreateItemOptions = { + description: 'The current block number being processed', + key: 'sys:num', + params: [], + type: 'BlockNumber' +}; + +const digest: CreateItemOptions = { + description: 'The digest for the current block', + key: 'sys:dig', + params: [], + type: 'Digest' +}; + +const extrinsicData: CreateItemOptions = { + description: 'The data associated with an extrinsic', + key: 'sys:xtd', + params: [ + param('extrinsic', 'u32') + ], + type: 'Bytes' +}; + +const extrinsicIndex: CreateItemOptions = { + description: 'The extrinsics index', + key: 'sys:xti', + params: [], + type: 'u32' +}; + +const extrinsicsRoot: CreateItemOptions = { + description: 'The extrinsicsRoot for the current block', + key: 'sys:txr', + params: [], + type: 'Hash' +}; + +const accountIndexOf: CreateItemOptions = { + description: 'The index of the given account', + key: 'sys:non', + params: [ + param('who', 'AccountId') + ], + type: 'Index' +}; + +const parentHash: CreateItemOptions = { + description: 'The parentHash for the current block', + key: 'sys:pha', + params: [], + type: 'Hash' +}; + +const randomSeed: CreateItemOptions = { + description: 'The random seed', + key: 'sys:rnd', + params: [], + type: 'Hash' +}; + +export default (name: Storage$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'System', + public: { + blockHashAt: + createMethod('blockHashAt')(blockHashAt), + blockNumber: + createMethod('blockNumber')(blockNumber), + digest: + createMethod('digest')(digest), + extrinsicData: + createMethod('extrinsicData')(extrinsicData), + extrinsicIndex: + createMethod('extrinsicIndex')(extrinsicIndex), + extrinsicsRoot: + createMethod('extrinsicsRoot')(extrinsicsRoot), + accountIndexOf: + createMethod('accountIndexOf')(accountIndexOf), + parentHash: + createMethod('parentHash')(parentHash), + randomSeed: + createMethod('randomSeed')(randomSeed) + } + })); diff --git a/packages/type-storage/src/timestamp.ts b/packages/type-storage/src/timestamp.ts new file mode 100644 index 000000000..8643e9a9f --- /dev/null +++ b/packages/type-storage/src/timestamp.ts @@ -0,0 +1,33 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import { CreateItems, CreateItemOptions, Section } from '@polkadot/params/types'; +import { Storages, Storage$Sections } from './types'; + +import createSection from '@polkadot/params/section'; + +const current: CreateItemOptions = { + description: 'The current timestamp', + key: 'tim:val', + params: [], + type: 'Timestamp' +}; + +const didUpdate: CreateItemOptions = { + description: 'Did the timestamp update', + key: 'tim:did', + params: [], + type: 'bool' +}; + +export default (name: Storage$Sections): Section => + createSection(name)((createMethod: CreateItems) => ({ + description: 'Timestamp related entries', + public: { + current: + createMethod('current')(current), + didUpdate: + createMethod('didUpdate')(didUpdate) + } + })); diff --git a/packages/type-storage/src/types.d.ts b/packages/type-storage/src/types.d.ts new file mode 100644 index 000000000..c5a0eae87 --- /dev/null +++ b/packages/type-storage/src/types.d.ts @@ -0,0 +1,23 @@ +// Copyright 2017-2018 @polkadot/storage authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import BN from 'bn.js'; +import { Section } from '@polkadot/params/types'; + +export type Storage$Key$Value = number | BN | Uint8Array | string; + +export type Storages = { + consensus: Section, + council: Section, + councilVoting: Section, + democracy: Section, + governance: Section, + parachains: Section, + session: Section, + staking: Section, + system: Section, + timestamp: Section +}; + +export type Storage$Sections = keyof Storages; diff --git a/packages/util-crypto/README.md b/packages/util-crypto/README.md index 8da59f2ea..a9f8d24c1 100644 --- a/packages/util-crypto/README.md +++ b/packages/util-crypto/README.md @@ -2,11 +2,11 @@ ![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) [![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) [![npm](https://img.shields.io/npm/v/@polkadot/util-crypto.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/util-crypto) -[![travis](https://img.shields.io/travis/polkadot-js/util.svg?style=flat-square)](https://travis-ci.org/polkadot-js/util) -[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/util.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/util/maintainability) -[![coverage](https://img.shields.io/coveralls/polkadot-js/util.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/util?branch=master) -[![dependency](https://david-dm.org/polkadot-js/util.svg?style=flat-square&path=packages/util)](https://david-dm.org/polkadot-js/util?path=packages/util-crypto) -[![devDependency](https://david-dm.org/polkadot-js/util/dev-status.svg?style=flat-square&path=packages/util-crypto)](https://david-dm.org/polkadot-js/util?path=packages/util-crypto#info=devDependencies) +[![travis](https://img.shields.io/travis/polkadot-js/common.svg?style=flat-square)](https://travis-ci.org/polkadot-js/common) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/common.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/common/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/common.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/common?branch=master) +[![dependency](https://david-dm.org/polkadot-js/common.svg?style=flat-square&path=packages/util)](https://david-dm.org/polkadot-js/common?path=packages/util-crypto) +[![devDependency](https://david-dm.org/polkadot-js/common/dev-status.svg?style=flat-square&path=packages/util-crypto)](https://david-dm.org/polkadot-js/common?path=packages/util-crypto#info=devDependencies) # @polkadot/util-crypto diff --git a/packages/util-crypto/package.json b/packages/util-crypto/package.json index de32328e0..8100a095a 100644 --- a/packages/util-crypto/package.json +++ b/packages/util-crypto/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/util-crypto", - "version": "0.24.9", + "version": "0.25.0", "description": "A collection of useful crypto utilities for @polkadot", "main": "index.js", "keywords": [ @@ -21,12 +21,12 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/polkadot-js/util.git" + "url": "git+https://github.com/polkadot-js/common.git" }, "bugs": { - "url": "https://github.com/polkadot-js/util/issues" + "url": "https://github.com/polkadot-js/common/issues" }, - "homepage": "https://github.com/polkadot-js/util/tree/master/packages/util-crypto#readme", + "homepage": "https://github.com/polkadot-js/common/tree/master/packages/util-crypto#readme", "scripts": { "build": "polkadot-dev-build-babel && polkadot-dev-build-docs", "check": "eslint src && flow check", @@ -34,7 +34,7 @@ }, "dependencies": { "@babel/runtime": "^7.0.0-beta.51", - "@polkadot/util": "^0.24.9", + "@polkadot/util": "^0.25.0", "blakejs": "^1.1.0", "js-sha3": "^0.7.0", "tweetnacl": "^1.0.0", diff --git a/packages/util-keyring/package.json b/packages/util-keyring/package.json index 01d0681d5..40c12e7f9 100644 --- a/packages/util-keyring/package.json +++ b/packages/util-keyring/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/util-keyring", - "version": "0.24.9", + "version": "0.25.0", "description": "Keyring management", "main": "index.js", "engines": { @@ -36,8 +36,8 @@ }, "dependencies": { "@babel/runtime": "^7.0.0-beta.51", - "@polkadot/util": "^0.24.9", - "@polkadot/util-crypto": "^0.24.9", + "@polkadot/util": "^0.25.0", + "@polkadot/util-crypto": "^0.25.0", "@types/bs58": "^3.0.30", "bs58": "^4.0.1" } diff --git a/packages/util-rlp/README.md b/packages/util-rlp/README.md index 6d86c3792..797b67dbd 100644 --- a/packages/util-rlp/README.md +++ b/packages/util-rlp/README.md @@ -2,11 +2,11 @@ ![mpl-2](https://img.shields.io/badge/license-MPL-lightgrey.svg?style=flat-square) [![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) [![npm](https://img.shields.io/npm/v/@polkadot/util-rlp.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/util-rlp) -[![travis](https://img.shields.io/travis/polkadot-js/util.svg?style=flat-square)](https://travis-ci.org/polkadot-js/util) -[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/util.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/util/maintainability) -[![coverage](https://img.shields.io/coveralls/polkadot-js/util.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/util?branch=master) -[![dependency](https://david-dm.org/polkadot-js/util.svg?style=flat-square&path=packages/util)](https://david-dm.org/polkadot-js/util?path=packages/util-rlp) -[![devDependency](https://david-dm.org/polkadot-js/util/dev-status.svg?style=flat-square&path=packages/util-rlp)](https://david-dm.org/polkadot-js/util?path=packages/util-rlp#info=devDependencies) +[![travis](https://img.shields.io/travis/polkadot-js/common.svg?style=flat-square)](https://travis-ci.org/polkadot-js/common) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/common.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/common/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/common.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/common?branch=master) +[![dependency](https://david-dm.org/polkadot-js/common.svg?style=flat-square&path=packages/util)](https://david-dm.org/polkadot-js/common?path=packages/util-rlp) +[![devDependency](https://david-dm.org/polkadot-js/common/dev-status.svg?style=flat-square&path=packages/util-rlp)](https://david-dm.org/polkadot-js/common?path=packages/util-rlp#info=devDependencies) # @polkadot/util-rlp diff --git a/packages/util-rlp/package.json b/packages/util-rlp/package.json index b04c64770..c44bc7829 100644 --- a/packages/util-rlp/package.json +++ b/packages/util-rlp/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/util-rlp", - "version": "0.24.9", + "version": "0.25.0", "description": "RLP encoding and decoding", "main": "index.js", "keywords": [ @@ -23,12 +23,12 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/polkadot-js/util.git" + "url": "git+https://github.com/polkadot-js/common.git" }, "bugs": { - "url": "https://github.com/polkadot-js/util/issues" + "url": "https://github.com/polkadot-js/common/issues" }, - "homepage": "https://github.com/polkadot-js/util/tree/master/packages/util-triehash#readme", + "homepage": "https://github.com/polkadot-js/common/tree/master/packages/trie-hash#readme", "scripts": { "build": "polkadot-dev-build-babel && polkadot-dev-build-docs", "check": "eslint src && flow check", @@ -36,7 +36,7 @@ }, "dependencies": { "@babel/runtime": "^7.0.0-beta.51", - "@polkadot/util": "^0.24.9" + "@polkadot/util": "^0.25.0" }, "devDependencies": { "ethereumjs-testing": "^1.0.4" diff --git a/packages/util-triedb/README.md b/packages/util-triedb/README.md index e592192ad..12b08ecf6 100644 --- a/packages/util-triedb/README.md +++ b/packages/util-triedb/README.md @@ -2,11 +2,12 @@ ![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) [![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) [![npm](https://img.shields.io/npm/v/@polkadot/util-triedb.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/util-triedb) -[![travis](https://img.shields.io/travis/polkadot-js/util.svg?style=flat-square)](https://travis-ci.org/polkadot-js/util) -[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/util.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/util/maintainability) -[![coverage](https://img.shields.io/coveralls/polkadot-js/util.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/util?branch=master) -[![dependency](https://david-dm.org/polkadot-js/util.svg?style=flat-square&path=packages/util)](https://david-dm.org/polkadot-js/util?path=packages/util-triedb) -[![devDependency](https://david-dm.org/polkadot-js/util/dev-status.svg?style=flat-square&path=packages/util-triedb)](https://david-dm.org/polkadot-js/util?path=packages/util-triedb#info=devDependencies) +[![travis](https://img.shields.io/travis/polkadot-js/common.svg?style=flat-square)](https://travis-ci.org/polkadot-js/common) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/common.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/common/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/common.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/common?branch=master) +[![dependency](https://david-dm.org/polkadot-js/common.svg?style=flat-square&path=packages/util)](https://david-dm.org/polkadot-js/common?path=packages/util-triedb) +[![devDependency](https://david-dm.org/polkadot-js/common/dev-status.svg?style=flat-square&path=packages/util-triedb)](https://david-dm.org/polkadot-js/common?path=packages/util-triedb#info=devDependencies) # @polkadot/util-triedb +DEPRECTATED, but still used until converted diff --git a/packages/util-triedb/package.json b/packages/util-triedb/package.json index 9511c00b8..da68d21bf 100644 --- a/packages/util-triedb/package.json +++ b/packages/util-triedb/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/util-triedb", - "version": "0.24.9", + "version": "0.25.0", "description": "Creation of triehash values", "main": "index.js", "keywords": [ @@ -21,12 +21,12 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/polkadot-js/util.git" + "url": "git+https://github.com/polkadot-js/common.git" }, "bugs": { - "url": "https://github.com/polkadot-js/util/issues" + "url": "https://github.com/polkadot-js/common/issues" }, - "homepage": "https://github.com/polkadot-js/util/tree/master/packages/util-triehash#readme", + "homepage": "https://github.com/polkadot-js/common/tree/master/packages/trie-hash#readme", "scripts": { "build": "polkadot-dev-build-babel && polkadot-dev-build-docs", "check": "eslint src && flow check", @@ -34,10 +34,10 @@ }, "dependencies": { "@babel/runtime": "^7.0.0-beta.51", - "@polkadot/util": "^0.24.9", - "@polkadot/util-crypto": "^0.24.9", - "@polkadot/util-rlp": "^0.24.9", - "@polkadot/util-triehash": "^0.24.9", + "@polkadot/trie-hash": "^0.25.0", + "@polkadot/util": "^0.25.0", + "@polkadot/util-crypto": "^0.25.0", + "@polkadot/util-rlp": "^0.25.0", "leveldown": "^4.0.1", "levelup": "^3.0.1", "memdown": "^3.0.0" diff --git a/packages/util-triedb/src/temp/commit.ts b/packages/util-triedb/src/temp/commit.ts index fff69e78c..0ce138901 100644 --- a/packages/util-triedb/src/temp/commit.ts +++ b/packages/util-triedb/src/temp/commit.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. -import { Trie$Pairs } from '@polkadot/util-triehash/types'; +import { Trie$Pairs } from '@polkadot/trie-hash/types'; import { Temp$Storage } from './types'; import del from './del'; diff --git a/packages/util-triedb/src/temp/index.ts b/packages/util-triedb/src/temp/index.ts index 80763e53d..494794aed 100644 --- a/packages/util-triedb/src/temp/index.ts +++ b/packages/util-triedb/src/temp/index.ts @@ -2,11 +2,11 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. -import { Trie$Pairs } from '@polkadot/util-triehash/types'; +import { Trie$Pairs } from '@polkadot/trie-hash/types'; import { TrieDb } from '../types'; import { Temp$Storage } from './types'; -import trieRoot from '@polkadot/util-triehash/root'; +import trieRoot from '@polkadot/trie-hash/root'; import commit from './commit'; import del from './del'; diff --git a/packages/util-triedb/src/temp/pairs.ts b/packages/util-triedb/src/temp/pairs.ts index 550271e25..359294c82 100644 --- a/packages/util-triedb/src/temp/pairs.ts +++ b/packages/util-triedb/src/temp/pairs.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. -import { Trie$Pairs } from '@polkadot/util-triehash/types'; +import { Trie$Pairs } from '@polkadot/trie-hash/types'; import { Temp$Storage } from './types'; export default function pairs (storage: Temp$Storage): Trie$Pairs { diff --git a/packages/util-triedb/src/temp/types.d.ts b/packages/util-triedb/src/temp/types.d.ts index a1dd2a72e..e6c523bf0 100644 --- a/packages/util-triedb/src/temp/types.d.ts +++ b/packages/util-triedb/src/temp/types.d.ts @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. -import { Trie$Pair } from '@polkadot/util-triehash/types'; +import { Trie$Pair } from '@polkadot/trie-hash/types'; export type Temp$Storage = { [index: string]: Trie$Pair diff --git a/packages/util-triedb/src/types.d.ts b/packages/util-triedb/src/types.d.ts index 47ed8a018..a9015a683 100644 --- a/packages/util-triedb/src/types.d.ts +++ b/packages/util-triedb/src/types.d.ts @@ -3,7 +3,7 @@ // of the ISC license. See the LICENSE file for details. import { Logger } from '@polkadot/util/types'; -import { Trie$Pairs } from '@polkadot/util-triehash/types'; +import { Trie$Pairs } from '@polkadot/trie-hash/types'; export type TrieDb = { clear: () => void, diff --git a/packages/util-triehash/README.md b/packages/util-triehash/README.md deleted file mode 100644 index 7358fff54..000000000 --- a/packages/util-triehash/README.md +++ /dev/null @@ -1,17 +0,0 @@ -[![polkadotjs](https://img.shields.io/badge/polkadot-js-orange.svg?style=flat-square)](https://polkadot.js.org) -![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) -[![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) -[![npm](https://img.shields.io/npm/v/@polkadot/util-triehash.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/util-triehash) -[![travis](https://img.shields.io/travis/polkadot-js/util.svg?style=flat-square)](https://travis-ci.org/polkadot-js/util) -[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/util.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/util/maintainability) -[![coverage](https://img.shields.io/coveralls/polkadot-js/util.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/util?branch=master) -[![dependency](https://david-dm.org/polkadot-js/util.svg?style=flat-square&path=packages/util)](https://david-dm.org/polkadot-js/util?path=packages/util-triehash) -[![devDependency](https://david-dm.org/polkadot-js/util/dev-status.svg?style=flat-square&path=packages/util-triehash)](https://david-dm.org/polkadot-js/util?path=packages/util-triehash#info=devDependencies) - -# @polkadot/util-triehash - -Calculate [Ethereum Trie hashes](https://github.com/ethereum/wiki/wiki/Patricia-Tree) from inputs. - -## Available Utilities - -For a list of currently exposed methods, see the [library documentation](docs/README.md). diff --git a/packages/util/README.md b/packages/util/README.md index 3782acfcf..e28c444c2 100644 --- a/packages/util/README.md +++ b/packages/util/README.md @@ -2,11 +2,11 @@ ![isc](https://img.shields.io/badge/license-ISC-lightgrey.svg?style=flat-square) [![style](https://img.shields.io/badge/code%20style-semistandard-lightgrey.svg?style=flat-square)](https://github.com/Flet/semistandard) [![npm](https://img.shields.io/npm/v/@polkadot/util.svg?style=flat-square)](https://www.npmjs.com/package/@polkadot/util) -[![travis](https://img.shields.io/travis/polkadot-js/util.svg?style=flat-square)](https://travis-ci.org/polkadot-js/util) -[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/util.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/util/maintainability) -[![coverage](https://img.shields.io/coveralls/polkadot-js/util.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/util?branch=master) -[![dependency](https://david-dm.org/polkadot-js/util.svg?style=flat-square&path=packages/util)](https://david-dm.org/polkadot-js/util?path=packages/util) -[![devDependency](https://david-dm.org/polkadot-js/util/dev-status.svg?style=flat-square&path=packages/util)](https://david-dm.org/polkadot-js/util?path=packages/util#info=devDependencies) +[![travis](https://img.shields.io/travis/polkadot-js/common.svg?style=flat-square)](https://travis-ci.org/polkadot-js/common) +[![maintainability](https://img.shields.io/codeclimate/maintainability/polkadot-js/common.svg?style=flat-square)](https://codeclimate.com/github/polkadot-js/common/maintainability) +[![coverage](https://img.shields.io/coveralls/polkadot-js/common.svg?style=flat-square)](https://coveralls.io/github/polkadot-js/common?branch=master) +[![dependency](https://david-dm.org/polkadot-js/common.svg?style=flat-square&path=packages/util)](https://david-dm.org/polkadot-js/common?path=packages/util) +[![devDependency](https://david-dm.org/polkadot-js/common/dev-status.svg?style=flat-square&path=packages/util)](https://david-dm.org/polkadot-js/common?path=packages/util#info=devDependencies) # @polkadot/util diff --git a/packages/util/package.json b/packages/util/package.json index a920bd258..a545d5658 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/util", - "version": "0.24.9", + "version": "0.25.0", "description": "A collection of useful utilities for @polkadot", "main": "index.js", "keywords": [ @@ -21,12 +21,12 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/polkadot-js/util.git" + "url": "git+https://github.com/polkadot-js/common.git" }, "bugs": { - "url": "https://github.com/polkadot-js/util/issues" + "url": "https://github.com/polkadot-js/common/issues" }, - "homepage": "https://github.com/polkadot-js/util/tree/master/packages/util#readme", + "homepage": "https://github.com/polkadot-js/common/tree/master/packages/util#readme", "scripts": { "build": "polkadot-dev-build-babel && polkadot-dev-build-docs", "check": "eslint src && flow check", diff --git a/tsconfig.json b/tsconfig.json index 5892a2cf2..827a02c9c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,11 +3,24 @@ "compilerOptions": { "baseUrl": ".", "paths": { + "@polkadot/extrinsics-codec/*": [ "packages/code-extrinsics/src/*" ], + "@polkadot/primitives-builder/*": [ "packages/code-primitives-builder/src/*" ], + "@polkadot/primitives-codec/*": [ "packages/code-primitives/src/*" ], + "@polkadot/primitives-json/*": [ "packages/code-primitives-json/src/*" ], + + "@polkadot/extrinsics/*": [ "packages/type-extrinsics/src/*" ], + "@polkadot/jsonrpc/*": [ "packages/type-jsonrpc/src/*" ], + "@polkadot/params/*": [ "packages/type-params/src/*" ], + "@polkadot/primitives/*": [ "packages/type-primitives/src/*" ], + "@polkadot/storage/*": [ "packages/type-storage/src/*" ], + + "@polkadot/trie-db/*": [ "packages/trie-sb/src/*" ], + "@polkadot/trie-hash/*": [ "packages/trie-hash/src/*" ], + "@polkadot/util-crypto/*": [ "packages/util-crypto/src/*" ], "@polkadot/util-keyring/*": [ "packages/util-keyring/src/*" ], "@polkadot/util-rlp/*": [ "packages/util-rlp/src/*" ], "@polkadot/util-triedb/*": [ "packages/util-triedb/src/*" ], - "@polkadot/util-triehash/*": [ "packages/util-triehash/src/*" ], "@polkadot/util/*": [ "packages/util/src/*" ] }, "typeRoots": [ diff --git a/yarn.lock b/yarn.lock index 99f2843a9..148c7de55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -738,6 +738,19 @@ version "0.1.3" resolved "https://registry.yarnpkg.com/@polkadot/ts/-/ts-0.1.3.tgz#e277fb89c43a64b244a6d1ae03fc4ede128b155d" +"@polkadot/util-triehash@^0.24.9": + version "0.24.9" + resolved "https://registry.yarnpkg.com/@polkadot/util-triehash/-/util-triehash-0.24.9.tgz#59900a171b80ac3ed843329f5cee0ec3b623dfaa" + dependencies: + "@babel/runtime" "^7.0.0-beta.51" + "@polkadot/util" "^0.24.9" + "@polkadot/util-crypto" "^0.24.9" + "@polkadot/util-rlp" "^0.24.9" + +"@types/async@^2.0.49": + version "2.0.49" + resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0" + "@types/base-x@*": version "1.0.29" resolved "https://registry.yarnpkg.com/@types/base-x/-/base-x-1.0.29.tgz#8a2d73e4a5c3121757a5f8870cfa4509655186b6" @@ -768,6 +781,10 @@ version "10.3.4" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.3.4.tgz#c74e8aec19e555df44609b8057311052a2c84d9e" +"@types/semaphore@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@types/semaphore/-/semaphore-1.1.0.tgz#a2f8db75e6429ae2703bbbe7d288f0edc67894b2" + "@types/xxhashjs@^0.1.1": version "0.1.1" resolved "https://registry.yarnpkg.com/@types/xxhashjs/-/xxhashjs-0.1.1.tgz#980709096c7138713b7777f49dccd4b8f93908e5" @@ -787,7 +804,7 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" -abstract-leveldown@~5.0.0: +abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz#f7128e1f86ccabf7d2893077ce5d06d798e386c6" dependencies: @@ -994,7 +1011,7 @@ async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" -async@^1.4.0, async@^1.5.0, async@~1.5.2: +async@^1.4.0, async@^1.4.2, async@^1.5.0, async@~1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -1353,6 +1370,27 @@ builtin-modules@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" +bulk-require@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/bulk-require/-/bulk-require-0.2.1.tgz#f118d7833118b0a1a20b465b136d9db513479d25" + dependencies: + glob "~3.2.7" + +bulk-require@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bulk-require/-/bulk-require-1.0.1.tgz#cb3d039e698139a444fc574b261d6b3b2cf44c89" + dependencies: + glob "^7.1.1" + +bulkify@^1.1.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/bulkify/-/bulkify-1.4.2.tgz#7848f0f3ab97f12a41b923bf90e53e09eaafba4c" + dependencies: + bulk-require "^1.0.0" + concat-stream "^1.4.5" + static-module "^1.1.2" + through2 "~0.4.1" + byline@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" @@ -1645,6 +1683,15 @@ concat-stream@^1.4.10, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" +concat-stream@^1.4.5, concat-stream@~1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" @@ -2087,6 +2134,12 @@ dox@^0.9.0: jsdoctypeparser "^1.2.0" markdown-it "~7.0.0" +duplexer2@~0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + dependencies: + readable-stream "~1.1.9" + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" @@ -2105,6 +2158,16 @@ electron-to-chromium@^1.3.45: version "1.3.45" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.45.tgz#458ac1b1c5c760ce8811a16d2bfbd97ec30bafb8" +encoding-down@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-5.0.4.tgz#1e477da8e9e9d0f7c8293d320044f8b2cd8e9614" + dependencies: + abstract-leveldown "^5.0.0" + inherits "^2.0.3" + level-codec "^9.0.0" + level-errors "^2.0.0" + xtend "^4.0.1" + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" @@ -2160,6 +2223,25 @@ escodegen@^1.9.0: optionalDependencies: source-map "~0.5.6" +escodegen@~0.0.24: + version "0.0.28" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-0.0.28.tgz#0e4ff1715f328775d6cab51ac44a406cd7abffd3" + dependencies: + esprima "~1.0.2" + estraverse "~1.3.0" + optionalDependencies: + source-map ">= 0.1.2" + +escodegen@~1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.3.3.tgz#f024016f5a88e046fd12005055e939802e6c5f23" + dependencies: + esprima "~1.1.1" + estraverse "~1.5.0" + esutils "~1.0.0" + optionalDependencies: + source-map "~0.1.33" + eslint-config-semistandard@^12.0.1: version "12.0.1" resolved "https://registry.yarnpkg.com/eslint-config-semistandard/-/eslint-config-semistandard-12.0.1.tgz#e35d66959dfe6f0d8e8445d7a4de37d8fd8875f4" @@ -2293,6 +2375,14 @@ esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" +esprima@~1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" + +esprima@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549" + esquery@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" @@ -2310,10 +2400,30 @@ estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" +estraverse@~1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.3.2.tgz#37c2b893ef13d723f276d878d60d8535152a6c42" + +estraverse@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71" + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" +esutils@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570" + +ethereumjs-testing@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/ethereumjs-testing/-/ethereumjs-testing-0.0.1.tgz#ddc4f8324cd90375c98b0eab238ca0933ed489fb" + dependencies: + async "^1.4.2" + bulk-require "^0.2.1" + bulkify "^1.1.1" + ethereumjs-testing@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/ethereumjs-testing/-/ethereumjs-testing-1.0.4.tgz#8739f4104e9838ba92f3060eeb165c581041251d" @@ -2441,6 +2551,15 @@ extsprintf@1.3.0, extsprintf@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" +falafel@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/falafel/-/falafel-2.1.0.tgz#96bb17761daba94f46d001738b3cedf3a67fe06c" + dependencies: + acorn "^5.0.0" + foreach "^2.0.5" + isarray "0.0.1" + object-keys "^1.0.6" + fast-deep-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" @@ -2797,6 +2916,13 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" +glob@~3.2.7: + version "3.2.11" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" + dependencies: + inherits "2" + minimatch "0.3" + globals@^11.0.1: version "11.0.1" resolved "https://registry.yarnpkg.com/globals/-/globals-11.0.1.tgz#12a87bb010e5154396acc535e1e43fc753b0e5e8" @@ -2948,6 +3074,12 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" +has@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + dependencies: + function-bind "^1.1.1" + has@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" @@ -3969,7 +4101,11 @@ lerna@^2.11.0: write-pkg "^3.1.0" yargs "^8.0.2" -level-errors@~2.0.0: +level-codec@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.0.tgz#2d3a0e835c4aa8339ec63de3f5a37480b74a5f87" + +level-errors@^2.0.0, level-errors@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.0.tgz#2de5b566b62eef92f99e19be74397fbc512563fa" dependencies: @@ -3983,6 +4119,13 @@ level-iterator-stream@~2.0.0: readable-stream "^2.0.5" xtend "^4.0.0" +level-ws@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.1.0.tgz#9728f02f3e7f34607f05010c1e4a83242e90b0b2" + dependencies: + readable-stream "^2.2.8" + xtend "^4.0.0" + leveldown@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-4.0.1.tgz#7bc3df93c9fa574feb39ce45a0c4073aa948cfef" @@ -4112,6 +4255,10 @@ lowercase-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + lru-cache@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" @@ -4287,6 +4434,13 @@ mimic-response@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" +minimatch@0.3: + version "0.3.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" + dependencies: + lru-cache "2" + sigmund "~1.0.0" + minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -4542,10 +4696,22 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-inspect@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-0.4.0.tgz#f5157c116c1455b243b06ee97703392c5ad89fec" + +object-keys@^1.0.6: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + object-keys@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -4903,6 +5069,13 @@ quick-lru@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" +quote-stream@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/quote-stream/-/quote-stream-0.0.0.tgz#cde29e94c409b16e19dc7098b89b6658f9721d3b" + dependencies: + minimist "0.0.8" + through2 "~0.4.1" + randomatic@^1.1.3: version "1.1.7" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" @@ -4991,7 +5164,7 @@ readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" -readable-stream@^2.0.5, readable-stream@^2.3.0, readable-stream@^2.3.5: +readable-stream@^2.0.5, readable-stream@^2.2.8, readable-stream@^2.3.0, readable-stream@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: @@ -5003,7 +5176,7 @@ readable-stream@^2.0.5, readable-stream@^2.3.0, readable-stream@^2.3.5: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@~1.0.31: +readable-stream@~1.0.17, readable-stream@~1.0.27-1, readable-stream@~1.0.31: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" dependencies: @@ -5012,6 +5185,15 @@ readable-stream@~1.0.31: isarray "0.0.1" string_decoder "~0.10.x" +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readdirp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" @@ -5364,6 +5546,10 @@ sax@^1.2.1, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" +semaphore@>=1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" + "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -5398,6 +5584,10 @@ set-value@^2.0.0: is-plain-object "^2.0.3" split-string "^3.0.1" +shallow-copy@~0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -5412,6 +5602,10 @@ shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -5510,6 +5704,10 @@ source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" +"source-map@>= 0.1.2": + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + source-map@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" @@ -5524,6 +5722,12 @@ source-map@^0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" +source-map@~0.1.33: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + spdx-correct@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" @@ -5578,6 +5782,12 @@ stack-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" +static-eval@~0.2.0: + version "0.2.4" + resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-0.2.4.tgz#b7d34d838937b969f9641ca07d48f8ede263ea7b" + dependencies: + escodegen "~0.0.24" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -5585,6 +5795,22 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" +static-module@^1.1.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/static-module/-/static-module-1.5.0.tgz#27da9883c41a8cd09236f842f0c1ebc6edf63d86" + dependencies: + concat-stream "~1.6.0" + duplexer2 "~0.0.2" + escodegen "~1.3.2" + falafel "^2.1.0" + has "^1.0.0" + object-inspect "~0.4.0" + quote-stream "~0.0.0" + readable-stream "~1.0.27-1" + shallow-copy "~0.0.1" + static-eval "~0.2.0" + through2 "~0.4.1" + stealthy-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" @@ -5831,6 +6057,13 @@ through2@^2.0.0, through2@^2.0.1, through2@^2.0.2: readable-stream "^2.1.5" xtend "~4.0.1" +through2@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b" + dependencies: + readable-stream "~1.0.17" + xtend "~2.1.1" + through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -6212,10 +6445,16 @@ xml-name-validator@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" -xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + dependencies: + object-keys "~0.4.0" + xxhashjs@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/xxhashjs/-/xxhashjs-0.2.2.tgz#8a6251567621a1c46a5ae204da0249c7f8caa9d8"