Browse Source

Merge branch 'olympia' into council_olympia

ondratra 4 years ago
parent
commit
4af4d7224c
100 changed files with 1907 additions and 11326 deletions
  1. 9 16
      .env
  2. 1 1
      .github/workflows/content-directory-schemas.yml
  3. 1 1
      .github/workflows/joystream-node-docker.yml
  4. 4 4
      .github/workflows/run-network-tests.yml
  5. 113 295
      Cargo.lock
  6. 2 6
      Cargo.toml
  7. 0 8698
      _Cargo.lock
  8. 3 3
      build.sh
  9. 225 63
      cli/README.md
  10. 1 1
      cli/package.json
  11. 0 3
      cli/src/@types/@ffmpeg-installer/ffmpeg/index.d.ts
  12. 3 0
      cli/src/@types/@ffprobe-installer/ffprobe/index.d.ts
  13. 5 2
      cli/src/base/AccountsCommandBase.ts
  14. 33 13
      cli/src/base/ContentDirectoryCommandBase.ts
  15. 10 5
      cli/src/base/MediaCommandBase.ts
  16. 19 4
      cli/src/commands/account/choose.ts
  17. 3 3
      cli/src/commands/content-directory/addClassSchema.ts
  18. 3 3
      cli/src/commands/content-directory/createClass.ts
  19. 2 2
      cli/src/commands/content-directory/entity.ts
  20. 15 8
      cli/src/commands/content-directory/initialize.ts
  21. 2 2
      cli/src/commands/content-directory/updateClassPermissions.ts
  22. 12 7
      cli/src/commands/media/createChannel.ts
  23. 3 3
      cli/src/commands/media/curateContent.ts
  24. 36 0
      cli/src/commands/media/featuredVideos.ts
  25. 2 2
      cli/src/commands/media/myChannels.ts
  26. 1 1
      cli/src/commands/media/myVideos.ts
  27. 3 3
      cli/src/commands/media/removeChannel.ts
  28. 1 1
      cli/src/commands/media/removeVideo.ts
  29. 79 0
      cli/src/commands/media/setFeaturedVideos.ts
  30. 7 6
      cli/src/commands/media/updateChannel.ts
  31. 4 4
      cli/src/commands/media/updateVideo.ts
  32. 2 2
      cli/src/commands/media/updateVideoLicense.ts
  33. 131 73
      cli/src/commands/media/uploadVideo.ts
  34. 11 7
      cli/src/helpers/InputOutput.ts
  35. 40 35
      cli/src/helpers/JsonSchemaPrompt.ts
  36. 1 1
      cli/src/helpers/display.ts
  37. 20 20
      content-directory-schemas/README.md
  38. 5 5
      content-directory-schemas/examples/createChannel.ts
  39. 6 6
      content-directory-schemas/examples/createChannelWithoutTransaction.ts
  40. 6 6
      content-directory-schemas/examples/createVideo.ts
  41. 5 5
      content-directory-schemas/examples/updateChannelTitle.ts
  42. 6 6
      content-directory-schemas/examples/updateChannelTitleWithoutTransaction.ts
  43. 6 0
      content-directory-schemas/inputs/classes/FeaturedVideoClass.json
  44. 18 0
      content-directory-schemas/inputs/classes/index.js
  45. 0 13
      content-directory-schemas/inputs/entityBatches/ChannelBatch.json
  46. 48 6
      content-directory-schemas/inputs/entityBatches/KnownLicenseBatch.json
  47. 0 63
      content-directory-schemas/inputs/entityBatches/VideoBatch.json
  48. 5 6
      content-directory-schemas/inputs/schemas/ChannelSchema.json
  49. 12 0
      content-directory-schemas/inputs/schemas/FeaturedVideoSchema.json
  50. 9 0
      content-directory-schemas/inputs/schemas/KnownLicenseSchema.json
  51. 6 0
      content-directory-schemas/inputs/schemas/LicenseSchema.json
  52. 2 3
      content-directory-schemas/inputs/schemas/VideoSchema.json
  53. 3 3
      content-directory-schemas/package.json
  54. 2 7
      content-directory-schemas/scripts/initializeContentDir.ts
  55. 1 1
      content-directory-schemas/scripts/inputSchemasToEntitySchemas.ts
  56. 4 8
      content-directory-schemas/src/helpers/InputParser.ts
  57. 25 5
      content-directory-schemas/src/helpers/inputs.ts
  58. 1 1
      content-directory-schemas/src/index.ts
  59. 25 15
      docker-compose.yml
  60. 0 391
      node/src/chain_spec/content_config.rs
  61. 2 1
      node/src/chain_spec/forum_config.rs
  62. 5 58
      node/src/chain_spec/mod.rs
  63. 2 2
      package.json
  64. 0 62
      query-node/.env
  65. 5 1
      query-node/README.md
  66. 19 1
      query-node/build.sh
  67. 13 0
      query-node/db-migrate.sh
  68. 64 57
      query-node/mappings/content-directory/content-dir-consts.ts
  69. 29 13
      query-node/mappings/content-directory/decode.ts
  70. 105 46
      query-node/mappings/content-directory/entity/create.ts
  71. 29 3
      query-node/mappings/content-directory/entity/index.ts
  72. 69 46
      query-node/mappings/content-directory/entity/remove.ts
  73. 105 33
      query-node/mappings/content-directory/entity/update.ts
  74. 69 40
      query-node/mappings/content-directory/get-or-create.ts
  75. 1 1
      query-node/mappings/content-directory/mapping.ts
  76. 45 21
      query-node/mappings/content-directory/transaction.ts
  77. 19 9
      query-node/mappings/types.ts
  78. 6 7
      query-node/package.json
  79. 15 0
      query-node/processor-start.sh
  80. 21 10
      query-node/run-tests.sh
  81. 80 32
      query-node/schema.graphql
  82. 0 974
      query-node/typedefs.json
  83. 2 1
      runtime-modules/constitution/Cargo.toml
  84. 55 0
      runtime-modules/constitution/src/benchmarking.rs
  85. 22 2
      runtime-modules/constitution/src/lib.rs
  86. 7 0
      runtime-modules/constitution/src/tests/mocks.rs
  87. 1 1
      runtime-modules/constitution/src/tests/mod.rs
  88. 102 45
      runtime-modules/content-directory/src/lib.rs
  89. 2 1
      runtime-modules/content-directory/src/mock.rs
  90. 1 1
      runtime-modules/content-directory/src/tests.rs
  91. 1 1
      runtime-modules/content-directory/src/tests/add_class_schema.rs
  92. 1 1
      runtime-modules/content-directory/src/tests/add_curator_group.rs
  93. 1 1
      runtime-modules/content-directory/src/tests/add_curator_to_group.rs
  94. 1 1
      runtime-modules/content-directory/src/tests/add_maintainer_to_class.rs
  95. 1 1
      runtime-modules/content-directory/src/tests/clear_entity_property_vector.rs
  96. 1 1
      runtime-modules/content-directory/src/tests/create_class.rs
  97. 1 1
      runtime-modules/content-directory/src/tests/create_entity.rs
  98. 1 1
      runtime-modules/content-directory/src/tests/insert_at_entity_property_vector.rs
  99. 1 1
      runtime-modules/content-directory/src/tests/remove_at_entity_property_vector.rs
  100. 1 1
      runtime-modules/content-directory/src/tests/remove_curator_from_group.rs

+ 9 - 16
.env

@@ -1,17 +1,14 @@
 COMPOSE_PROJECT_NAME=joystream
+PROJECT_NAME=query_node
 
-###########################
-#     Common settings     #
-###########################
-
-# The env variables below are by default used by all services and should be
-# overriden in local env files (e.g. ./generated/indexer) if needed
-# DB config
-DB_NAME=query_node
+# We will use a single postgres service with multiple databases
+INDEXER_DB_NAME=query_node_indexer
+PROCESSOR_DB_NAME=query_node_processor
 DB_USER=postgres
 DB_PASS=postgres
 DB_HOST=localhost
 DB_PORT=5432
+
 DEBUG=index-builder:*
 TYPEORM_LOGGING=error
 
@@ -20,16 +17,12 @@ TYPEORM_LOGGING=error
 ###########################
 
 # Substrate endpoint to source events from
-WS_PROVIDER_ENDPOINT_URI=ws://joystream-node:9944/
+WS_PROVIDER_ENDPOINT_URI=ws://localhost:9944/
+
 # Block height to start indexing from.
 # Note, that if there are already some indexed events, this setting is ignored
 BLOCK_HEIGHT=0
 
-# Custom types to register for Substrate API
-# TYPE_REGISTER_PACKAGE_NAME=
-# TYPE_REGISTER_PACKAGE_VERSION=
-# TYPE_REGISTER_FUNCTION=
-
 # Redis cache server
 REDIS_URI=redis://localhost:6379/0
 
@@ -38,10 +31,10 @@ REDIS_URI=redis://localhost:6379/0
 ###########################
 
 # Where the mapping scripts are located, relative to ./generated/indexer
-TYPES_JSON=../../typedefs.json
+TYPES_JSON=../../../types/augment/all/defs.json
 
 # Indexer GraphQL API endpoint to fetch indexed events
-INDEXER_ENDPOINT_URL=http://localhost:4100/graphql
+INDEXER_ENDPOINT_URL=http://localhost:4000/graphql
 
 # Block height from which the processor starts. Note that if
 # there are already processed events in the database, this setting is ignored

+ 1 - 1
.github/workflows/content-directory-schemas.yml

@@ -17,4 +17,4 @@ jobs:
     - name: validate
       run: |
         yarn install --frozen-lockfile
-        yarn workspace cd-schemas checks --quiet
+        yarn workspace @joystream/cd-schemas checks --quiet

+ 1 - 1
.github/workflows/joystream-node-docker.yml

@@ -55,7 +55,7 @@ jobs:
             docker save --output joystream-node-docker-image.tar joystream/node
             gzip joystream-node-docker-image.tar
             cp joystream-node-docker-image.tar.gz ~/docker-images/
-            echo "::set-env name=NEW_BUILD::true"
+            echo "NEW_BUILD=true" >> $GITHUB_ENV
           fi
 
       - name: Save joystream/node image to Artifacts

+ 4 - 4
.github/workflows/run-network-tests.yml

@@ -77,7 +77,7 @@ jobs:
         with:
           name: ${{ steps.compute_shasum.outputs.shasum }}-joystream-node-docker-image.tar.gz
           path: joystream-node-docker-image.tar.gz
-  
+
   basic_runtime_with_upgrade:
     name: Integration Tests (Runtime Upgrade)
     needs: build_images
@@ -146,11 +146,11 @@ jobs:
       - name: Install packages and dependencies
         run: yarn install --frozen-lockfile
       - name: Ensure tests are runnable
-        run: yarn workspace cd-schemas checks --quiet
+        run: yarn workspace @joystream/cd-schemas checks --quiet
       - name: Start chain
         run: docker-compose up -d joystream-node
       - name: Initialize the content directory
-        run: yarn workspace cd-schemas initialize:dev
+        run: yarn workspace @joystream/cd-schemas initialize:dev
 
   query_node:
     name: Query Node Integration Tests
@@ -179,7 +179,7 @@ jobs:
       # integration tests
       - name: Execute Tests
         run: query-node/run-tests.sh
-  
+
   storage_node:
     name: Storage Node Tests
     needs: build_images

File diff suppressed because it is too large
+ 113 - 295
Cargo.lock


+ 2 - 6
Cargo.toml

@@ -5,28 +5,24 @@ members = [
 	"runtime-modules/proposals/codex",
 	"runtime-modules/proposals/discussion",
 	"runtime-modules/common",
-	"runtime-modules/content-working-group",
 	"runtime-modules/council",
 	"runtime-modules/forum",
 	"runtime-modules/governance",
-	"runtime-modules/hiring",
 	"runtime-modules/membership",
 	"runtime-modules/memo",
 	"runtime-modules/recurring-reward",
 	"runtime-modules/referendum",
 	"runtime-modules/service-discovery",
-	"runtime-modules/stake",
 	"runtime-modules/storage",
 	"runtime-modules/token-minting",
-	"runtime-modules/versioned-store",
-	"runtime-modules/versioned-store-permissions",
 	"runtime-modules/working-group",
 	"runtime-modules/content-directory",
 	"runtime-modules/constitution",
+	"runtime-modules/staking-handler",
 	"node",
 	"utils/chain-spec-builder/"
 ]
 
 [profile.release]
 # Substrate runtime requires unwinding.
-panic = "unwind"
+panic = "unwind"

+ 0 - 8698
_Cargo.lock

@@ -1,8698 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "Inflector"
-version = "0.11.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
-dependencies = [
- "lazy_static",
- "regex",
-]
-
-[[package]]
-name = "addr2line"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423"
-dependencies = [
- "gimli",
-]
-
-[[package]]
-name = "adler"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
-
-[[package]]
-name = "aead"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331"
-dependencies = [
- "generic-array 0.14.4",
-]
-
-[[package]]
-name = "aes"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd2bc6d3f370b5666245ff421e231cba4353df936e26986d2918e61a8fd6aef6"
-dependencies = [
- "aes-soft",
- "aesni",
- "block-cipher",
-]
-
-[[package]]
-name = "aes-gcm"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0301c9e9c443494d970a07885e8cf3e587bae8356a1d5abd0999068413f7205f"
-dependencies = [
- "aead",
- "aes",
- "block-cipher",
- "ghash",
- "subtle 2.3.0",
-]
-
-[[package]]
-name = "aes-soft"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63dd91889c49327ad7ef3b500fd1109dbd3c509a03db0d4a9ce413b79f575cb6"
-dependencies = [
- "block-cipher",
- "byteorder 1.3.4",
- "opaque-debug 0.3.0",
-]
-
-[[package]]
-name = "aesni"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a6fe808308bb07d393e2ea47780043ec47683fcf19cf5efc8ca51c50cc8c68a"
-dependencies = [
- "block-cipher",
- "opaque-debug 0.3.0",
-]
-
-[[package]]
-name = "ahash"
-version = "0.2.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29661b60bec623f0586702976ff4d0c9942dcb6723161c2df0eea78455cfedfb"
-dependencies = [
- "const-random",
-]
-
-[[package]]
-name = "ahash"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
-
-[[package]]
-name = "ahash"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6789e291be47ace86a60303502173d84af8327e3627ecf334356ee0f87a164c"
-
-[[package]]
-name = "aho-corasick"
-version = "0.7.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "alga"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2"
-dependencies = [
- "approx",
- "num-complex",
- "num-traits",
-]
-
-[[package]]
-name = "ansi_term"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
-dependencies = [
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "ansi_term"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
-dependencies = [
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "anyhow"
-version = "1.0.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7"
-
-[[package]]
-name = "approx"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "arc-swap"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034"
-
-[[package]]
-name = "arrayref"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
-
-[[package]]
-name = "arrayvec"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
-dependencies = [
- "nodrop",
-]
-
-[[package]]
-name = "arrayvec"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
-
-[[package]]
-name = "asn1_der"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fce6b6a0ffdafebd82c87e79e3f40e8d2c523e5fea5566ff6b90509bf98d638"
-dependencies = [
- "asn1_der_derive",
-]
-
-[[package]]
-name = "asn1_der_derive"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502"
-dependencies = [
- "quote",
- "syn",
-]
-
-[[package]]
-name = "async-channel"
-version = "1.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59740d83946db6a5af71ae25ddf9562c2b176b2ca42cf99a455f09f4a220d6b9"
-dependencies = [
- "concurrent-queue",
- "event-listener",
- "futures-core",
-]
-
-[[package]]
-name = "async-executor"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb877970c7b440ead138f6321a3b5395d6061183af779340b65e20c0fede9146"
-dependencies = [
- "async-task",
- "concurrent-queue",
- "fastrand",
- "futures-lite",
- "once_cell 1.4.1",
- "vec-arena",
-]
-
-[[package]]
-name = "async-global-executor"
-version = "1.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73079b49cd26b8fd5a15f68fc7707fc78698dc2a3d61430f2a7a9430230dfa04"
-dependencies = [
- "async-executor",
- "async-io",
- "futures-lite",
- "num_cpus",
- "once_cell 1.4.1",
-]
-
-[[package]]
-name = "async-io"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40a0b2bb8ae20fede194e779150fe283f65a4a08461b496de546ec366b174ad9"
-dependencies = [
- "concurrent-queue",
- "fastrand",
- "futures-lite",
- "libc",
- "log",
- "nb-connect",
- "once_cell 1.4.1",
- "parking",
- "polling",
- "vec-arena",
- "waker-fn",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "async-mutex"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e"
-dependencies = [
- "event-listener",
-]
-
-[[package]]
-name = "async-std"
-version = "1.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7e82538bc65a25dbdff70e4c5439d52f068048ab97cdea0acd73f131594caa1"
-dependencies = [
- "async-global-executor",
- "async-io",
- "async-mutex",
- "blocking",
- "crossbeam-utils 0.8.0",
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-lite",
- "gloo-timers",
- "kv-log-macro",
- "log",
- "memchr",
- "num_cpus",
- "once_cell 1.4.1",
- "pin-project-lite",
- "pin-utils",
- "slab",
- "wasm-bindgen-futures",
-]
-
-[[package]]
-name = "async-task"
-version = "4.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0"
-
-[[package]]
-name = "async-tls"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df097e3f506bec0e1a24f06bb3c962c228f36671de841ff579cb99f371772634"
-dependencies = [
- "futures 0.3.8",
- "rustls",
- "webpki",
- "webpki-roots 0.19.0",
-]
-
-[[package]]
-name = "async-trait"
-version = "0.1.41"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "atomic"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64f46ca51dca4837f1520754d1c8c36636356b81553d928dc9c177025369a06e"
-
-[[package]]
-name = "atomic-waker"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a"
-
-[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi",
- "libc",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "autocfg"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
-
-[[package]]
-name = "autocfg"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
-
-[[package]]
-name = "backtrace"
-version = "0.3.54"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2baad346b2d4e94a24347adeee9c7a93f412ee94b9cc26e5b59dea23848e9f28"
-dependencies = [
- "addr2line",
- "cfg-if 1.0.0",
- "libc",
- "miniz_oxide",
- "object",
- "rustc-demangle",
-]
-
-[[package]]
-name = "base58"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83"
-
-[[package]]
-name = "base64"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
-
-[[package]]
-name = "base64"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
-
-[[package]]
-name = "bindgen"
-version = "0.54.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66c0bb6167449588ff70803f4127f0684f9063097eca5016f37eb52b92c2cf36"
-dependencies = [
- "bitflags",
- "cexpr",
- "cfg-if 0.1.10",
- "clang-sys",
- "clap",
- "env_logger",
- "lazy_static",
- "lazycell",
- "log",
- "peeking_take_while",
- "proc-macro2",
- "quote",
- "regex",
- "rustc-hash",
- "shlex",
- "which",
-]
-
-[[package]]
-name = "bip39"
-version = "0.6.0-beta.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7059804e226b3ac116519a252d7f5fb985a5ccc0e93255e036a5f7e7283323f4"
-dependencies = [
- "failure",
- "hashbrown 0.1.8",
- "hmac",
- "once_cell 0.1.8",
- "pbkdf2",
- "rand 0.6.5",
- "sha2 0.8.2",
-]
-
-[[package]]
-name = "bitflags"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
-
-[[package]]
-name = "bitmask"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead"
-
-[[package]]
-name = "bitvec"
-version = "0.17.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c"
-dependencies = [
- "either",
- "radium",
-]
-
-[[package]]
-name = "blake2"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10a5720225ef5daecf08657f23791354e1685a8c91a4c60c7f3d3b2892f978f4"
-dependencies = [
- "crypto-mac 0.8.0",
- "digest 0.9.0",
- "opaque-debug 0.3.0",
-]
-
-[[package]]
-name = "blake2-rfc"
-version = "0.2.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
-dependencies = [
- "arrayvec 0.4.12",
- "constant_time_eq",
-]
-
-[[package]]
-name = "blake2b_simd"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
-dependencies = [
- "arrayref",
- "arrayvec 0.5.2",
- "constant_time_eq",
-]
-
-[[package]]
-name = "blake2s_simd"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2"
-dependencies = [
- "arrayref",
- "arrayvec 0.5.2",
- "constant_time_eq",
-]
-
-[[package]]
-name = "block-buffer"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
-dependencies = [
- "block-padding 0.1.5",
- "byte-tools",
- "byteorder 1.3.4",
- "generic-array 0.12.3",
-]
-
-[[package]]
-name = "block-buffer"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
-dependencies = [
- "block-padding 0.2.1",
- "generic-array 0.14.4",
-]
-
-[[package]]
-name = "block-cipher"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f337a3e6da609650eb74e02bc9fac7b735049f7623ab12f2e4c719316fcc7e80"
-dependencies = [
- "generic-array 0.14.4",
-]
-
-[[package]]
-name = "block-padding"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
-dependencies = [
- "byte-tools",
-]
-
-[[package]]
-name = "block-padding"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
-
-[[package]]
-name = "blocking"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9"
-dependencies = [
- "async-channel",
- "async-task",
- "atomic-waker",
- "fastrand",
- "futures-lite",
- "once_cell 1.4.1",
-]
-
-[[package]]
-name = "bs58"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb"
-
-[[package]]
-name = "bs58"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
-
-[[package]]
-name = "bstr"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "bumpalo"
-version = "3.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
-
-[[package]]
-name = "byte-slice-cast"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3"
-
-[[package]]
-name = "byte-tools"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
-
-[[package]]
-name = "byteorder"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
-
-[[package]]
-name = "byteorder"
-version = "1.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
-
-[[package]]
-name = "bytes"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
-dependencies = [
- "byteorder 1.3.4",
- "either",
- "iovec",
-]
-
-[[package]]
-name = "bytes"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
-
-[[package]]
-name = "c_linked_list"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b"
-
-[[package]]
-name = "cache-padded"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
-
-[[package]]
-name = "cc"
-version = "1.0.62"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1770ced377336a88a67c473594ccc14eca6f4559217c34f64aac8f83d641b40"
-dependencies = [
- "jobserver",
-]
-
-[[package]]
-name = "cexpr"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
-dependencies = [
- "nom",
-]
-
-[[package]]
-name = "cfg-if"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "chacha20"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "244fbce0d47e97e8ef2f63b81d5e05882cb518c68531eb33194990d7b7e85845"
-dependencies = [
- "stream-cipher",
- "zeroize",
-]
-
-[[package]]
-name = "chacha20poly1305"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9bf18d374d66df0c05cdddd528a7db98f78c28e2519b120855c4f84c5027b1f5"
-dependencies = [
- "aead",
- "chacha20",
- "poly1305",
- "stream-cipher",
- "zeroize",
-]
-
-[[package]]
-name = "chain-spec-builder"
-version = "3.1.1"
-dependencies = [
- "ansi_term 0.12.1",
- "enum-utils",
- "joystream-node",
- "rand 0.7.3",
- "sc-chain-spec",
- "sc-keystore",
- "sc-telemetry",
- "sp-core",
- "structopt",
-]
-
-[[package]]
-name = "chrono"
-version = "0.4.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
-dependencies = [
- "js-sys",
- "libc",
- "num-integer",
- "num-traits",
- "time",
- "wasm-bindgen",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "clang-sys"
-version = "0.29.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a"
-dependencies = [
- "glob",
- "libc",
- "libloading",
-]
-
-[[package]]
-name = "clap"
-version = "2.33.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
-dependencies = [
- "ansi_term 0.11.0",
- "atty",
- "bitflags",
- "strsim",
- "textwrap",
- "unicode-width",
- "vec_map",
-]
-
-[[package]]
-name = "cloudabi"
-version = "0.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "cloudabi"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "concurrent-queue"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
-dependencies = [
- "cache-padded",
-]
-
-[[package]]
-name = "console_error_panic_hook"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
-dependencies = [
- "cfg-if 0.1.10",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "console_log"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e7871d2947441b0fdd8e2bd1ce2a2f75304f896582c0d572162d48290683c48"
-dependencies = [
- "log",
- "web-sys",
-]
-
-[[package]]
-name = "const-random"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02dc82c12dc2ee6e1ded861cf7d582b46f66f796d1b6c93fa28b911ead95da02"
-dependencies = [
- "const-random-macro",
- "proc-macro-hack",
-]
-
-[[package]]
-name = "const-random-macro"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc757bbb9544aa296c2ae00c679e81f886b37e28e59097defe0cf524306f6685"
-dependencies = [
- "getrandom 0.2.0",
- "proc-macro-hack",
-]
-
-[[package]]
-name = "const_fn"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab"
-
-[[package]]
-name = "constant_time_eq"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
-
-[[package]]
-name = "core-foundation"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "core-foundation-sys"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
-
-[[package]]
-name = "cpuid-bool"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
-
-[[package]]
-name = "crc32fast"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
-dependencies = [
- "cfg-if 1.0.0",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
-dependencies = [
- "cfg-if 1.0.0",
- "crossbeam-utils 0.8.0",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
-dependencies = [
- "crossbeam-epoch 0.8.2",
- "crossbeam-utils 0.7.2",
- "maybe-uninit",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
-dependencies = [
- "cfg-if 1.0.0",
- "crossbeam-epoch 0.9.0",
- "crossbeam-utils 0.8.0",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
-dependencies = [
- "autocfg 1.0.1",
- "cfg-if 0.1.10",
- "crossbeam-utils 0.7.2",
- "lazy_static",
- "maybe-uninit",
- "memoffset",
- "scopeguard 1.1.0",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f"
-dependencies = [
- "cfg-if 1.0.0",
- "const_fn",
- "crossbeam-utils 0.8.0",
- "lazy_static",
- "memoffset",
- "scopeguard 1.1.0",
-]
-
-[[package]]
-name = "crossbeam-queue"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
-dependencies = [
- "cfg-if 0.1.10",
- "crossbeam-utils 0.7.2",
- "maybe-uninit",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
-dependencies = [
- "autocfg 1.0.1",
- "cfg-if 0.1.10",
- "lazy_static",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5"
-dependencies = [
- "autocfg 1.0.1",
- "cfg-if 1.0.0",
- "const_fn",
- "lazy_static",
-]
-
-[[package]]
-name = "crunchy"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
-
-[[package]]
-name = "crypto-mac"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
-dependencies = [
- "generic-array 0.12.3",
- "subtle 1.0.0",
-]
-
-[[package]]
-name = "crypto-mac"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
-dependencies = [
- "generic-array 0.14.4",
- "subtle 2.3.0",
-]
-
-[[package]]
-name = "ct-logs"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c8e13110a84b6315df212c045be706af261fd364791cad863285439ebba672e"
-dependencies = [
- "sct",
-]
-
-[[package]]
-name = "cuckoofilter"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f"
-dependencies = [
- "byteorder 0.5.3",
- "rand 0.3.23",
-]
-
-[[package]]
-name = "curve25519-dalek"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d85653f070353a16313d0046f173f70d1aadd5b42600a14de626f0dfb3473a5"
-dependencies = [
- "byteorder 1.3.4",
- "digest 0.8.1",
- "rand_core 0.5.1",
- "subtle 2.3.0",
- "zeroize",
-]
-
-[[package]]
-name = "curve25519-dalek"
-version = "3.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8492de420e9e60bc9a1d66e2dbb91825390b738a388606600663fc529b4b307"
-dependencies = [
- "byteorder 1.3.4",
- "digest 0.9.0",
- "rand_core 0.5.1",
- "subtle 2.3.0",
- "zeroize",
-]
-
-[[package]]
-name = "data-encoding"
-version = "2.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "993a608597367c6377b258c25d7120740f00ed23a2252b729b1932dd7866f908"
-
-[[package]]
-name = "derive_more"
-version = "0.99.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "difference"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
-
-[[package]]
-name = "digest"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
-dependencies = [
- "generic-array 0.12.3",
-]
-
-[[package]]
-name = "digest"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
-dependencies = [
- "generic-array 0.14.4",
-]
-
-[[package]]
-name = "directories"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c"
-dependencies = [
- "cfg-if 0.1.10",
- "dirs-sys",
-]
-
-[[package]]
-name = "dirs-sys"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
-dependencies = [
- "libc",
- "redox_users",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "dns-parser"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea"
-dependencies = [
- "byteorder 1.3.4",
- "quick-error",
-]
-
-[[package]]
-name = "downcast"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d"
-
-[[package]]
-name = "dyn-clonable"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4"
-dependencies = [
- "dyn-clonable-impl",
- "dyn-clone",
-]
-
-[[package]]
-name = "dyn-clonable-impl"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "dyn-clone"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d55796afa1b20c2945ca8eabfc421839f2b766619209f1ede813cf2484f31804"
-
-[[package]]
-name = "ed25519"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37c66a534cbb46ab4ea03477eae19d5c22c01da8258030280b7bd9d8433fb6ef"
-dependencies = [
- "signature",
-]
-
-[[package]]
-name = "ed25519-dalek"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
-dependencies = [
- "curve25519-dalek 3.0.0",
- "ed25519",
- "rand 0.7.3",
- "serde",
- "sha2 0.9.2",
- "zeroize",
-]
-
-[[package]]
-name = "either"
-version = "1.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
-
-[[package]]
-name = "enum-utils"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed327f716d0d351d86c9fd3398d20ee39ad8f681873cc081da2ca1c10fed398a"
-dependencies = [
- "enum-utils-from-str",
- "failure",
- "proc-macro2",
- "quote",
- "serde_derive_internals",
- "syn",
-]
-
-[[package]]
-name = "enum-utils-from-str"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d49be08bad6e4ca87b2b8e74146987d4e5cb3b7512efa50ef505b51a22227ee1"
-dependencies = [
- "proc-macro2",
- "quote",
-]
-
-[[package]]
-name = "env_logger"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
-dependencies = [
- "atty",
- "humantime",
- "log",
- "regex",
- "termcolor",
-]
-
-[[package]]
-name = "environmental"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6576a1755ddffd988788025e75bce9e74b018f7cc226198fe931d077911c6d7e"
-
-[[package]]
-name = "erased-serde"
-version = "0.3.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ca8b296792113e1500fd935ae487be6e00ce318952a6880555554824d6ebf38"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "event-listener"
-version = "2.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59"
-
-[[package]]
-name = "exit-future"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5"
-dependencies = [
- "futures 0.3.8",
-]
-
-[[package]]
-name = "failure"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
-dependencies = [
- "backtrace",
- "failure_derive",
-]
-
-[[package]]
-name = "failure_derive"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "synstructure",
-]
-
-[[package]]
-name = "fake-simd"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
-
-[[package]]
-name = "fastrand"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3"
-dependencies = [
- "instant",
-]
-
-[[package]]
-name = "fdlimit"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c4c9e43643f5a3be4ca5b67d26b98031ff9db6806c3440ae32e02e3ceac3f1b"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "finality-grandpa"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8feb87a63249689640ac9c011742c33139204e3c134293d3054022276869133b"
-dependencies = [
- "either",
- "futures 0.3.8",
- "futures-timer 2.0.2",
- "log",
- "num-traits",
- "parity-scale-codec",
- "parking_lot 0.9.0",
-]
-
-[[package]]
-name = "fixed-hash"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c"
-dependencies = [
- "byteorder 1.3.4",
- "rand 0.7.3",
- "rustc-hex",
- "static_assertions",
-]
-
-[[package]]
-name = "fixedbitset"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
-
-[[package]]
-name = "flate2"
-version = "1.0.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129"
-dependencies = [
- "cfg-if 1.0.0",
- "crc32fast",
- "libc",
- "libz-sys",
- "miniz_oxide",
-]
-
-[[package]]
-name = "float-cmp"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "fnv"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-
-[[package]]
-name = "fork-tree"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
-]
-
-[[package]]
-name = "form_urlencoded"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00"
-dependencies = [
- "matches",
- "percent-encoding 2.1.0",
-]
-
-[[package]]
-name = "fragile"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69a039c3498dc930fe810151a34ba0c1c70b02b8625035592e74432f678591f2"
-
-[[package]]
-name = "frame-benchmarking"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "frame-system",
- "linregress",
- "parity-scale-codec",
- "paste",
- "sp-api",
- "sp-io",
- "sp-runtime",
- "sp-runtime-interface",
- "sp-std",
- "sp-storage",
-]
-
-[[package]]
-name = "frame-benchmarking-cli"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-benchmarking",
- "parity-scale-codec",
- "sc-cli",
- "sc-client-db",
- "sc-executor",
- "sc-service",
- "sp-core",
- "sp-externalities",
- "sp-runtime",
- "sp-state-machine",
- "structopt",
-]
-
-[[package]]
-name = "frame-executive"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "frame-system",
- "parity-scale-codec",
- "serde",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
- "sp-tracing",
-]
-
-[[package]]
-name = "frame-metadata"
-version = "12.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "serde",
- "sp-core",
- "sp-std",
-]
-
-[[package]]
-name = "frame-support"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "bitmask",
- "frame-metadata",
- "frame-support-procedural",
- "impl-trait-for-tuples",
- "log",
- "once_cell 1.4.1",
- "parity-scale-codec",
- "paste",
- "serde",
- "smallvec 1.4.2",
- "sp-arithmetic",
- "sp-core",
- "sp-inherents",
- "sp-io",
- "sp-runtime",
- "sp-state-machine",
- "sp-std",
- "sp-tracing",
-]
-
-[[package]]
-name = "frame-support-procedural"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support-procedural-tools",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "frame-support-procedural-tools"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support-procedural-tools-derive",
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "frame-support-procedural-tools-derive"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "frame-system"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "impl-trait-for-tuples",
- "parity-scale-codec",
- "serde",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
- "sp-version",
-]
-
-[[package]]
-name = "frame-system-benchmarking"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "parity-scale-codec",
- "sp-core",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "frame-system-rpc-runtime-api"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "sp-api",
-]
-
-[[package]]
-name = "fs-swap"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb"
-dependencies = [
- "lazy_static",
- "libc",
- "libloading",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "fuchsia-cprng"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
-
-[[package]]
-name = "fuchsia-zircon"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
-dependencies = [
- "bitflags",
- "fuchsia-zircon-sys",
-]
-
-[[package]]
-name = "fuchsia-zircon-sys"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
-
-[[package]]
-name = "futures"
-version = "0.1.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c7e4c2612746b0df8fed4ce0c69156021b704c9aefa360311c04e6e9e002eed"
-
-[[package]]
-name = "futures"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-channel"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64"
-dependencies = [
- "futures-core",
- "futures-sink",
-]
-
-[[package]]
-name = "futures-channel-preview"
-version = "0.3.0-alpha.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5e5f4df964fa9c1c2f8bddeb5c3611631cacd93baf810fc8bb2fb4b495c263a"
-dependencies = [
- "futures-core-preview",
-]
-
-[[package]]
-name = "futures-core"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748"
-
-[[package]]
-name = "futures-core-preview"
-version = "0.3.0-alpha.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a"
-
-[[package]]
-name = "futures-cpupool"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
-dependencies = [
- "futures 0.1.30",
- "num_cpus",
-]
-
-[[package]]
-name = "futures-diagnose"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdcef58a173af8148b182684c9f2d5250875adbcaff7b5794073894f9d8634a9"
-dependencies = [
- "futures 0.1.30",
- "futures 0.3.8",
- "lazy_static",
- "log",
- "parking_lot 0.9.0",
- "pin-project 0.4.27",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "futures-executor"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4caa2b2b68b880003057c1dd49f1ed937e38f22fcf6c212188a121f08cf40a65"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
- "num_cpus",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb"
-
-[[package]]
-name = "futures-lite"
-version = "1.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e6c079abfac3ab269e2927ec048dabc89d009ebfdda6b8ee86624f30c689658"
-dependencies = [
- "fastrand",
- "futures-core",
- "futures-io",
- "memchr",
- "parking",
- "pin-project-lite",
- "waker-fn",
-]
-
-[[package]]
-name = "futures-macro"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556"
-dependencies = [
- "proc-macro-hack",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "futures-sink"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d"
-
-[[package]]
-name = "futures-task"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d"
-dependencies = [
- "once_cell 1.4.1",
-]
-
-[[package]]
-name = "futures-timer"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6"
-
-[[package]]
-name = "futures-timer"
-version = "3.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
-dependencies = [
- "gloo-timers",
- "send_wrapper 0.4.0",
-]
-
-[[package]]
-name = "futures-util"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2"
-dependencies = [
- "futures 0.1.30",
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-macro",
- "futures-sink",
- "futures-task",
- "memchr",
- "pin-project 1.0.1",
- "pin-utils",
- "proc-macro-hack",
- "proc-macro-nested",
- "slab",
-]
-
-[[package]]
-name = "futures-util-preview"
-version = "0.3.0-alpha.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d"
-dependencies = [
- "futures-channel-preview",
- "futures-core-preview",
- "pin-utils",
- "slab",
-]
-
-[[package]]
-name = "futures_codec"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce54d63f8b0c75023ed920d46fd71d0cbbb830b0ee012726b5b4f506fb6dea5b"
-dependencies = [
- "bytes 0.5.6",
- "futures 0.3.8",
- "memchr",
- "pin-project 0.4.27",
-]
-
-[[package]]
-name = "gcc"
-version = "0.3.55"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
-
-[[package]]
-name = "generator"
-version = "0.6.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cdc09201b2e8ca1b19290cf7e65de2246b8e91fb6874279722189c4de7b94dc"
-dependencies = [
- "cc",
- "libc",
- "log",
- "rustc_version",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "generic-array"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
-dependencies = [
- "typenum",
-]
-
-[[package]]
-name = "generic-array"
-version = "0.14.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
-dependencies = [
- "typenum",
- "version_check",
-]
-
-[[package]]
-name = "get_if_addrs"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7"
-dependencies = [
- "c_linked_list",
- "get_if_addrs-sys",
- "libc",
- "winapi 0.2.8",
-]
-
-[[package]]
-name = "get_if_addrs-sys"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48"
-dependencies = [
- "gcc",
- "libc",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.1.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "wasi 0.9.0+wasi-snapshot-preview1",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "wasi 0.9.0+wasi-snapshot-preview1",
-]
-
-[[package]]
-name = "ghash"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6e27f0689a6e15944bdce7e45425efb87eaa8ab0c6e87f11d0987a9133e2531"
-dependencies = [
- "polyval",
-]
-
-[[package]]
-name = "gimli"
-version = "0.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
-
-[[package]]
-name = "glob"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
-
-[[package]]
-name = "globset"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a"
-dependencies = [
- "aho-corasick",
- "bstr",
- "fnv",
- "log",
- "regex",
-]
-
-[[package]]
-name = "gloo-timers"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f"
-dependencies = [
- "futures-channel",
- "futures-core",
- "js-sys",
- "wasm-bindgen",
- "web-sys",
-]
-
-[[package]]
-name = "h2"
-version = "0.1.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
-dependencies = [
- "byteorder 1.3.4",
- "bytes 0.4.12",
- "fnv",
- "futures 0.1.30",
- "http 0.1.21",
- "indexmap",
- "log",
- "slab",
- "string",
- "tokio-io",
-]
-
-[[package]]
-name = "h2"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535"
-dependencies = [
- "bytes 0.5.6",
- "fnv",
- "futures-core",
- "futures-sink",
- "futures-util",
- "http 0.2.1",
- "indexmap",
- "slab",
- "tokio 0.2.22",
- "tokio-util",
- "tracing",
- "tracing-futures",
-]
-
-[[package]]
-name = "hash-db"
-version = "0.15.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a"
-
-[[package]]
-name = "hash256-std-hasher"
-version = "0.15.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2"
-dependencies = [
- "crunchy",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da"
-dependencies = [
- "byteorder 1.3.4",
- "scopeguard 0.3.3",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
-dependencies = [
- "ahash 0.2.19",
- "autocfg 0.1.7",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25"
-dependencies = [
- "ahash 0.3.8",
- "autocfg 1.0.1",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
-dependencies = [
- "ahash 0.4.6",
-]
-
-[[package]]
-name = "heck"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
-dependencies = [
- "unicode-segmentation",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hex"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
-
-[[package]]
-name = "hex-literal"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "hex-literal"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8"
-
-[[package]]
-name = "hex_fmt"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f"
-
-[[package]]
-name = "hmac"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695"
-dependencies = [
- "crypto-mac 0.7.0",
- "digest 0.8.1",
-]
-
-[[package]]
-name = "hmac-drbg"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b"
-dependencies = [
- "digest 0.8.1",
- "generic-array 0.12.3",
- "hmac",
-]
-
-[[package]]
-name = "http"
-version = "0.1.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0"
-dependencies = [
- "bytes 0.4.12",
- "fnv",
- "itoa",
-]
-
-[[package]]
-name = "http"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
-dependencies = [
- "bytes 0.5.6",
- "fnv",
- "itoa",
-]
-
-[[package]]
-name = "http-body"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.30",
- "http 0.1.21",
- "tokio-buf",
-]
-
-[[package]]
-name = "http-body"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
-dependencies = [
- "bytes 0.5.6",
- "http 0.2.1",
-]
-
-[[package]]
-name = "httparse"
-version = "1.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
-
-[[package]]
-name = "httpdate"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
-
-[[package]]
-name = "humantime"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
-dependencies = [
- "quick-error",
-]
-
-[[package]]
-name = "hyper"
-version = "0.12.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.30",
- "futures-cpupool",
- "h2 0.1.26",
- "http 0.1.21",
- "http-body 0.1.0",
- "httparse",
- "iovec",
- "itoa",
- "log",
- "net2",
- "rustc_version",
- "time",
- "tokio 0.1.22",
- "tokio-buf",
- "tokio-executor 0.1.10",
- "tokio-io",
- "tokio-reactor",
- "tokio-tcp",
- "tokio-threadpool",
- "tokio-timer",
- "want 0.2.0",
-]
-
-[[package]]
-name = "hyper"
-version = "0.13.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6ad767baac13b44d4529fcf58ba2cd0995e36e7b435bc5b039de6f47e880dbf"
-dependencies = [
- "bytes 0.5.6",
- "futures-channel",
- "futures-core",
- "futures-util",
- "h2 0.2.7",
- "http 0.2.1",
- "http-body 0.3.1",
- "httparse",
- "httpdate",
- "itoa",
- "pin-project 1.0.1",
- "socket2",
- "tokio 0.2.22",
- "tower-service",
- "tracing",
- "want 0.3.0",
-]
-
-[[package]]
-name = "hyper-rustls"
-version = "0.21.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37743cc83e8ee85eacfce90f2f4102030d9ff0a95244098d781e9bee4a90abb6"
-dependencies = [
- "bytes 0.5.6",
- "ct-logs",
- "futures-util",
- "hyper 0.13.9",
- "log",
- "rustls",
- "rustls-native-certs",
- "tokio 0.2.22",
- "tokio-rustls",
- "webpki",
-]
-
-[[package]]
-name = "idna"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
-dependencies = [
- "matches",
- "unicode-bidi",
- "unicode-normalization",
-]
-
-[[package]]
-name = "idna"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
-dependencies = [
- "matches",
- "unicode-bidi",
- "unicode-normalization",
-]
-
-[[package]]
-name = "impl-codec"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53"
-dependencies = [
- "parity-scale-codec",
-]
-
-[[package]]
-name = "impl-serde"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "impl-trait-for-tuples"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "indexmap"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
-dependencies = [
- "autocfg 1.0.1",
- "hashbrown 0.9.1",
-]
-
-[[package]]
-name = "instant"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb1fc4429a33e1f80d41dc9fea4d108a88bec1de8053878898ae448a0b52f613"
-dependencies = [
- "cfg-if 1.0.0",
-]
-
-[[package]]
-name = "integer-sqrt"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "intervalier"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64fa110ec7b8f493f416eed552740d10e7030ad5f63b2308f82c9608ec2df275"
-dependencies = [
- "futures 0.3.8",
- "futures-timer 2.0.2",
-]
-
-[[package]]
-name = "iovec"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "ip_network"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ee15951c035f79eddbef745611ec962f63f4558f1dadf98ab723cc603487c6f"
-
-[[package]]
-name = "ipnet"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135"
-
-[[package]]
-name = "itertools"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
-dependencies = [
- "either",
-]
-
-[[package]]
-name = "itoa"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
-
-[[package]]
-name = "jobserver"
-version = "0.1.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "joystream-node"
-version = "4.0.0"
-dependencies = [
- "frame-benchmarking",
- "frame-benchmarking-cli",
- "frame-system",
- "futures 0.3.8",
- "hex",
- "joystream-node-runtime",
- "jsonrpc-core",
- "node-inspect",
- "pallet-grandpa",
- "pallet-im-online",
- "pallet-transaction-payment",
- "pallet-transaction-payment-rpc",
- "parity-scale-codec",
- "sc-authority-discovery",
- "sc-basic-authorship",
- "sc-chain-spec",
- "sc-cli",
- "sc-client-api",
- "sc-consensus",
- "sc-consensus-babe",
- "sc-consensus-babe-rpc",
- "sc-consensus-epochs",
- "sc-executor",
- "sc-finality-grandpa",
- "sc-finality-grandpa-rpc",
- "sc-keystore",
- "sc-network",
- "sc-rpc",
- "sc-rpc-api",
- "sc-service",
- "sc-service-test",
- "sc-transaction-pool",
- "serde",
- "serde_json",
- "sp-api",
- "sp-authority-discovery",
- "sp-block-builder",
- "sp-blockchain",
- "sp-consensus",
- "sp-consensus-babe",
- "sp-core",
- "sp-finality-grandpa",
- "sp-finality-tracker",
- "sp-inherents",
- "sp-keyring",
- "sp-runtime",
- "sp-timestamp",
- "sp-transaction-pool",
- "structopt",
- "substrate-browser-utils",
- "substrate-build-script-utils",
- "substrate-frame-rpc-system",
- "tempfile",
- "wasm-bindgen",
- "wasm-bindgen-futures",
-]
-
-[[package]]
-name = "joystream-node-runtime"
-version = "7.8.0"
-dependencies = [
- "frame-benchmarking",
- "frame-executive",
- "frame-support",
- "frame-system",
- "frame-system-benchmarking",
- "frame-system-rpc-runtime-api",
- "hex-literal 0.3.1",
- "lazy_static",
- "lite-json",
- "pallet-authority-discovery",
- "pallet-authorship",
- "pallet-babe",
- "pallet-balances",
- "pallet-common",
- "pallet-constitution",
- "pallet-content-directory",
- "pallet-content-working-group",
- "pallet-finality-tracker",
- "pallet-forum",
- "pallet-governance",
- "pallet-grandpa",
- "pallet-hiring",
- "pallet-im-online",
- "pallet-membership",
- "pallet-memo",
- "pallet-offences",
- "pallet-offences-benchmarking",
- "pallet-proposals-codex",
- "pallet-proposals-discussion",
- "pallet-proposals-engine",
- "pallet-randomness-collective-flip",
- "pallet-recurring-reward",
- "pallet-service-discovery",
- "pallet-session",
- "pallet-session-benchmarking",
- "pallet-stake",
- "pallet-staking",
- "pallet-staking-reward-curve",
- "pallet-storage",
- "pallet-sudo",
- "pallet-timestamp",
- "pallet-token-mint",
- "pallet-transaction-payment",
- "pallet-transaction-payment-rpc-runtime-api",
- "pallet-utility",
- "pallet-versioned-store",
- "pallet-versioned-store-permissions",
- "pallet-working-group",
- "parity-scale-codec",
- "serde",
- "sp-api",
- "sp-application-crypto",
- "sp-arithmetic",
- "sp-authority-discovery",
- "sp-block-builder",
- "sp-consensus-babe",
- "sp-core",
- "sp-io",
- "sp-offchain",
- "sp-runtime",
- "sp-session",
- "sp-staking",
- "sp-std",
- "sp-transaction-pool",
- "sp-version",
- "strum 0.19.5",
- "substrate-wasm-builder-runner",
-]
-
-[[package]]
-name = "js-sys"
-version = "0.3.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8"
-dependencies = [
- "wasm-bindgen",
-]
-
-[[package]]
-name = "jsonrpc-client-transports"
-version = "15.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "489b9c612e60c766f751ab40fcb43cbb55a1e10bb44a9b4307ed510ca598cbd7"
-dependencies = [
- "failure",
- "futures 0.1.30",
- "jsonrpc-core",
- "jsonrpc-pubsub",
- "log",
- "serde",
- "serde_json",
- "url 1.7.2",
-]
-
-[[package]]
-name = "jsonrpc-core"
-version = "15.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0745a6379e3edc893c84ec203589790774e4247420033e71a76d3ab4687991fa"
-dependencies = [
- "futures 0.1.30",
- "log",
- "serde",
- "serde_derive",
- "serde_json",
-]
-
-[[package]]
-name = "jsonrpc-core-client"
-version = "15.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f764902d7b891344a0acb65625f32f6f7c6db006952143bd650209fbe7d94db"
-dependencies = [
- "jsonrpc-client-transports",
-]
-
-[[package]]
-name = "jsonrpc-derive"
-version = "15.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99a847f9ec7bb52149b2786a17c9cb260d6effc6b8eeb8c16b343a487a7563a3"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "jsonrpc-http-server"
-version = "15.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb5c4513b7b542f42da107942b7b759f27120b5cc894729f88254b28dff44b7"
-dependencies = [
- "hyper 0.12.35",
- "jsonrpc-core",
- "jsonrpc-server-utils",
- "log",
- "net2",
- "parking_lot 0.10.2",
- "unicase",
-]
-
-[[package]]
-name = "jsonrpc-ipc-server"
-version = "15.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf50e53e4eea8f421a7316c5f63e395f7bc7c4e786a6dc54d76fab6ff7aa7ce7"
-dependencies = [
- "jsonrpc-core",
- "jsonrpc-server-utils",
- "log",
- "parity-tokio-ipc",
- "parking_lot 0.10.2",
- "tokio-service",
-]
-
-[[package]]
-name = "jsonrpc-pubsub"
-version = "15.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "639558e0604013be9787ae52f798506ae42bf4220fe587bdc5625871cc8b9c77"
-dependencies = [
- "jsonrpc-core",
- "log",
- "parking_lot 0.10.2",
- "rand 0.7.3",
- "serde",
-]
-
-[[package]]
-name = "jsonrpc-server-utils"
-version = "15.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72f1f3990650c033bd8f6bd46deac76d990f9bbfb5f8dc8c4767bf0a00392176"
-dependencies = [
- "bytes 0.4.12",
- "globset",
- "jsonrpc-core",
- "lazy_static",
- "log",
- "tokio 0.1.22",
- "tokio-codec",
- "unicase",
-]
-
-[[package]]
-name = "jsonrpc-ws-server"
-version = "15.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6596fe75209b73a2a75ebe1dce4e60e03b88a2b25e8807b667597f6315150d22"
-dependencies = [
- "jsonrpc-core",
- "jsonrpc-server-utils",
- "log",
- "parity-ws",
- "parking_lot 0.10.2",
- "slab",
-]
-
-[[package]]
-name = "keccak"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
-
-[[package]]
-name = "kernel32-sys"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-dependencies = [
- "winapi 0.2.8",
- "winapi-build",
-]
-
-[[package]]
-name = "kv-log-macro"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
-dependencies = [
- "log",
-]
-
-[[package]]
-name = "kvdb"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0315ef2f688e33844400b31f11c263f2b3dc21d8b9355c6891c5f185fae43f9a"
-dependencies = [
- "parity-util-mem",
- "smallvec 1.4.2",
-]
-
-[[package]]
-name = "kvdb-memorydb"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73de822b260a3bdfb889dbbb65bb2d473eee2253973d6fa4a5d149a2a4a7c66e"
-dependencies = [
- "kvdb",
- "parity-util-mem",
- "parking_lot 0.10.2",
-]
-
-[[package]]
-name = "kvdb-rocksdb"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44947dd392f09475af614d740fe0320b66d01cb5b977f664bbbb5e45a70ea4c1"
-dependencies = [
- "fs-swap",
- "kvdb",
- "log",
- "num_cpus",
- "owning_ref",
- "parity-util-mem",
- "parking_lot 0.10.2",
- "regex",
- "rocksdb",
- "smallvec 1.4.2",
-]
-
-[[package]]
-name = "kvdb-web"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2701a1369d6ea4f1b9f606db46e5e2a4a8e47f22530a07823d653f85ab1f6c34"
-dependencies = [
- "futures 0.3.8",
- "js-sys",
- "kvdb",
- "kvdb-memorydb",
- "log",
- "parity-util-mem",
- "send_wrapper 0.3.0",
- "wasm-bindgen",
- "web-sys",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-dependencies = [
- "spin",
-]
-
-[[package]]
-name = "lazycell"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
-
-[[package]]
-name = "libc"
-version = "0.2.80"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
-
-[[package]]
-name = "libloading"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
-dependencies = [
- "cc",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "libm"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
-
-[[package]]
-name = "libp2p"
-version = "0.28.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "571f5a4604c1a40d75651da141dfde29ad15329f537a779528803297d2220274"
-dependencies = [
- "atomic",
- "bytes 0.5.6",
- "futures 0.3.8",
- "lazy_static",
- "libp2p-core",
- "libp2p-core-derive",
- "libp2p-deflate",
- "libp2p-dns",
- "libp2p-floodsub",
- "libp2p-gossipsub",
- "libp2p-identify",
- "libp2p-kad",
- "libp2p-mdns",
- "libp2p-mplex",
- "libp2p-noise",
- "libp2p-ping",
- "libp2p-plaintext",
- "libp2p-pnet",
- "libp2p-request-response",
- "libp2p-swarm",
- "libp2p-tcp",
- "libp2p-uds",
- "libp2p-wasm-ext",
- "libp2p-websocket",
- "libp2p-yamux",
- "multihash",
- "parity-multiaddr",
- "parking_lot 0.10.2",
- "pin-project 0.4.27",
- "smallvec 1.4.2",
- "wasm-timer",
-]
-
-[[package]]
-name = "libp2p-core"
-version = "0.22.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52f13ba8c7df0768af2eb391696d562c7de88cc3a35122531aaa6a7d77754d25"
-dependencies = [
- "asn1_der",
- "bs58 0.3.1",
- "ed25519-dalek",
- "either",
- "fnv",
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "lazy_static",
- "libsecp256k1",
- "log",
- "multihash",
- "multistream-select",
- "parity-multiaddr",
- "parking_lot 0.10.2",
- "pin-project 0.4.27",
- "prost",
- "prost-build",
- "rand 0.7.3",
- "ring",
- "rw-stream-sink",
- "sha2 0.8.2",
- "smallvec 1.4.2",
- "thiserror",
- "unsigned-varint 0.4.0",
- "void",
- "zeroize",
-]
-
-[[package]]
-name = "libp2p-core-derive"
-version = "0.20.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f753d9324cd3ec14bf04b8a8cd0d269c87f294153d6bf2a84497a63a5ad22213"
-dependencies = [
- "quote",
- "syn",
-]
-
-[[package]]
-name = "libp2p-deflate"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74029ae187f35f4b8ddf26b9779a68b340045d708528a103917cdca49a296db5"
-dependencies = [
- "flate2",
- "futures 0.3.8",
- "libp2p-core",
-]
-
-[[package]]
-name = "libp2p-dns"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cf319822e08dd65c8e060d2354e9f952895bbc433f5706c75ed010c152aee5e"
-dependencies = [
- "futures 0.3.8",
- "libp2p-core",
- "log",
-]
-
-[[package]]
-name = "libp2p-floodsub"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8a9acb43a3e4a4e413e0c4abe0fa49308df7c6335c88534757b647199cb8a51"
-dependencies = [
- "cuckoofilter",
- "fnv",
- "futures 0.3.8",
- "libp2p-core",
- "libp2p-swarm",
- "prost",
- "prost-build",
- "rand 0.7.3",
- "smallvec 1.4.2",
-]
-
-[[package]]
-name = "libp2p-gossipsub"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab20fcb60edebe3173bbb708c6ac3444afdf1e3152dc2866b10c4f5497f17467"
-dependencies = [
- "base64 0.11.0",
- "byteorder 1.3.4",
- "bytes 0.5.6",
- "fnv",
- "futures 0.3.8",
- "futures_codec",
- "hex_fmt",
- "libp2p-core",
- "libp2p-swarm",
- "log",
- "lru_time_cache",
- "prost",
- "prost-build",
- "rand 0.7.3",
- "sha2 0.8.2",
- "smallvec 1.4.2",
- "unsigned-varint 0.4.0",
- "wasm-timer",
-]
-
-[[package]]
-name = "libp2p-identify"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56396ee63aa9164eacf40c2c5d2bda8c4133c2f57e1b0425d51d3a4e362583b1"
-dependencies = [
- "futures 0.3.8",
- "libp2p-core",
- "libp2p-swarm",
- "log",
- "prost",
- "prost-build",
- "smallvec 1.4.2",
- "wasm-timer",
-]
-
-[[package]]
-name = "libp2p-kad"
-version = "0.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc7fa9047f8b8f544278a35c2d9d45d3b2c1785f2d86d4e1629d6edf97be3955"
-dependencies = [
- "arrayvec 0.5.2",
- "bytes 0.5.6",
- "either",
- "fnv",
- "futures 0.3.8",
- "futures_codec",
- "libp2p-core",
- "libp2p-swarm",
- "log",
- "multihash",
- "prost",
- "prost-build",
- "rand 0.7.3",
- "sha2 0.8.2",
- "smallvec 1.4.2",
- "uint",
- "unsigned-varint 0.4.0",
- "void",
- "wasm-timer",
-]
-
-[[package]]
-name = "libp2p-mdns"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3173b5a6b2f690c29ae07798d85b9441a131ac76ddae9015ef22905b623d0c69"
-dependencies = [
- "async-std",
- "data-encoding",
- "dns-parser",
- "either",
- "futures 0.3.8",
- "lazy_static",
- "libp2p-core",
- "libp2p-swarm",
- "log",
- "net2",
- "rand 0.7.3",
- "smallvec 1.4.2",
- "void",
- "wasm-timer",
-]
-
-[[package]]
-name = "libp2p-mplex"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a73a799cc8410b36e40b8f4c4b6babbcb9efd3727111bf517876e4acfa612d3"
-dependencies = [
- "bytes 0.5.6",
- "fnv",
- "futures 0.3.8",
- "futures_codec",
- "libp2p-core",
- "log",
- "parking_lot 0.10.2",
- "unsigned-varint 0.4.0",
-]
-
-[[package]]
-name = "libp2p-noise"
-version = "0.24.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ef6c490042f549fb1025f2892dfe6083d97a77558f450c1feebe748ca9eb15a"
-dependencies = [
- "bytes 0.5.6",
- "curve25519-dalek 2.1.0",
- "futures 0.3.8",
- "lazy_static",
- "libp2p-core",
- "log",
- "prost",
- "prost-build",
- "rand 0.7.3",
- "sha2 0.8.2",
- "snow",
- "static_assertions",
- "x25519-dalek 0.6.0",
- "zeroize",
-]
-
-[[package]]
-name = "libp2p-ping"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad063c21dfcea4518ac9e8bd4119d33a5b26c41e674f602f41f05617a368a5c8"
-dependencies = [
- "futures 0.3.8",
- "libp2p-core",
- "libp2p-swarm",
- "log",
- "rand 0.7.3",
- "void",
- "wasm-timer",
-]
-
-[[package]]
-name = "libp2p-plaintext"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "903a12e99c72dbebefea258de887982adeacc7025baa1ceb10b7fa9928f54791"
-dependencies = [
- "bytes 0.5.6",
- "futures 0.3.8",
- "futures_codec",
- "libp2p-core",
- "log",
- "prost",
- "prost-build",
- "rw-stream-sink",
- "unsigned-varint 0.4.0",
- "void",
-]
-
-[[package]]
-name = "libp2p-pnet"
-version = "0.19.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96b3c2d5d26a9500e959a0e19743897239a6c4be78dadf99b70414301a70c006"
-dependencies = [
- "futures 0.3.8",
- "log",
- "pin-project 0.4.27",
- "rand 0.7.3",
- "salsa20",
- "sha3",
-]
-
-[[package]]
-name = "libp2p-request-response"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c0c9e8a4cd69d97e9646c54313d007512f411aba8c5226cfcda16df6a6e84a3"
-dependencies = [
- "async-trait",
- "bytes 0.5.6",
- "futures 0.3.8",
- "libp2p-core",
- "libp2p-swarm",
- "log",
- "lru 0.6.1",
- "minicbor",
- "rand 0.7.3",
- "smallvec 1.4.2",
- "unsigned-varint 0.5.1",
- "wasm-timer",
-]
-
-[[package]]
-name = "libp2p-swarm"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7193e444210132237b81b755ec7fe53f1c4bd2f53cf719729b94c0c72eb6eaa1"
-dependencies = [
- "either",
- "futures 0.3.8",
- "libp2p-core",
- "log",
- "rand 0.7.3",
- "smallvec 1.4.2",
- "void",
- "wasm-timer",
-]
-
-[[package]]
-name = "libp2p-tcp"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44f42ec130d7a37a7e47bf4398026b7ad9185c08ed26972e2720f8b94112796f"
-dependencies = [
- "async-std",
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "get_if_addrs",
- "ipnet",
- "libp2p-core",
- "log",
- "socket2",
-]
-
-[[package]]
-name = "libp2p-uds"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dea7acb0a034f70d7db94c300eba3f65c0f6298820105624088a9609c9974d77"
-dependencies = [
- "async-std",
- "futures 0.3.8",
- "libp2p-core",
- "log",
-]
-
-[[package]]
-name = "libp2p-wasm-ext"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34c1faac6f92c21fbe155417957863ea822fba9e9fd5eb24c0912336a100e63f"
-dependencies = [
- "futures 0.3.8",
- "js-sys",
- "libp2p-core",
- "parity-send-wrapper",
- "wasm-bindgen",
- "wasm-bindgen-futures",
-]
-
-[[package]]
-name = "libp2p-websocket"
-version = "0.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d650534ebd99f48f6fa292ed5db10d30df2444943afde4407ceeddab8e513fca"
-dependencies = [
- "async-tls",
- "either",
- "futures 0.3.8",
- "libp2p-core",
- "log",
- "quicksink",
- "rustls",
- "rw-stream-sink",
- "soketto",
- "url 2.2.0",
- "webpki",
- "webpki-roots 0.18.0",
-]
-
-[[package]]
-name = "libp2p-yamux"
-version = "0.25.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "781d9b9f043dcdabc40640807125368596b849fd4d96cdca2dcf052fdf6f33fd"
-dependencies = [
- "futures 0.3.8",
- "libp2p-core",
- "parking_lot 0.11.0",
- "thiserror",
- "yamux",
-]
-
-[[package]]
-name = "librocksdb-sys"
-version = "6.11.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb5b56f651c204634b936be2f92dbb42c36867e00ff7fe2405591f3b9fa66f09"
-dependencies = [
- "bindgen",
- "cc",
- "glob",
- "libc",
-]
-
-[[package]]
-name = "libsecp256k1"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962"
-dependencies = [
- "arrayref",
- "crunchy",
- "digest 0.8.1",
- "hmac-drbg",
- "rand 0.7.3",
- "sha2 0.8.2",
- "subtle 2.3.0",
- "typenum",
-]
-
-[[package]]
-name = "libz-sys"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
-dependencies = [
- "cc",
- "pkg-config",
- "vcpkg",
-]
-
-[[package]]
-name = "linked-hash-map"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
-
-[[package]]
-name = "linked_hash_set"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588"
-dependencies = [
- "linked-hash-map",
-]
-
-[[package]]
-name = "linregress"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9290cf6f928576eeb9c096c6fad9d8d452a0a1a70a2bbffa6e36064eedc0aac9"
-dependencies = [
- "failure",
- "nalgebra",
- "statrs",
-]
-
-[[package]]
-name = "lite-json"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0460d985423a026b4d9b828a7c6eed1bcf606f476322f3f9b507529686a61715"
-dependencies = [
- "lite-parser",
-]
-
-[[package]]
-name = "lite-parser"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c50092e40e0ccd1bf2015a10333fde0502ff95b832b0895dc1ca0d7ac6c52f6"
-dependencies = [
- "paste",
-]
-
-[[package]]
-name = "lock_api"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
-dependencies = [
- "scopeguard 0.3.3",
-]
-
-[[package]]
-name = "lock_api"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
-dependencies = [
- "scopeguard 1.1.0",
-]
-
-[[package]]
-name = "lock_api"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
-dependencies = [
- "scopeguard 1.1.0",
-]
-
-[[package]]
-name = "log"
-version = "0.4.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
-dependencies = [
- "cfg-if 0.1.10",
-]
-
-[[package]]
-name = "loom"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0e8460f2f2121162705187214720353c517b97bdfb3494c0b1e33d83ebe4bed"
-dependencies = [
- "cfg-if 0.1.10",
- "generator",
- "scoped-tls",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "lru"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0609345ddee5badacf857d4f547e0e5a2e987db77085c24cd887f73573a04237"
-dependencies = [
- "hashbrown 0.6.3",
-]
-
-[[package]]
-name = "lru"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be716eb6878ca2263eb5d00a781aa13264a794f519fe6af4fbb2668b2d5441c0"
-dependencies = [
- "hashbrown 0.9.1",
-]
-
-[[package]]
-name = "lru_time_cache"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adb241df5c4caeb888755363fc95f8a896618dc0d435e9e775f7930cb099beab"
-
-[[package]]
-name = "matchers"
-version = "0.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
-dependencies = [
- "regex-automata",
-]
-
-[[package]]
-name = "matches"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
-
-[[package]]
-name = "matrixmultiply"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4f7ec66360130972f34830bfad9ef05c6610a43938a467bcc9ab9369ab3478f"
-dependencies = [
- "rawpointer",
-]
-
-[[package]]
-name = "maybe-uninit"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
-
-[[package]]
-name = "memchr"
-version = "2.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
-
-[[package]]
-name = "memmap"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
-dependencies = [
- "libc",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "memoffset"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
-dependencies = [
- "autocfg 1.0.1",
-]
-
-[[package]]
-name = "memory-db"
-version = "0.24.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36f36ddb0b2cdc25d38babba472108798e3477f02be5165f038c5e393e50c57a"
-dependencies = [
- "hash-db",
- "hashbrown 0.8.2",
- "parity-util-mem",
-]
-
-[[package]]
-name = "memory_units"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
-
-[[package]]
-name = "merlin"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6feca46f4fa3443a01769d768727f10c10a20fdb65e52dc16a81f0c8269bb78"
-dependencies = [
- "byteorder 1.3.4",
- "keccak",
- "rand_core 0.5.1",
- "zeroize",
-]
-
-[[package]]
-name = "minicbor"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fc03ad6f8f548db7194a5ff5a6f96342ecae4e3ef67d2bf18bacc0e245cd041"
-dependencies = [
- "minicbor-derive",
-]
-
-[[package]]
-name = "minicbor-derive"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c214bf3d90099b52f3e4b328ae0fe34837fd0fab683ad1e10fceb4629106df48"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
-dependencies = [
- "adler",
- "autocfg 1.0.1",
-]
-
-[[package]]
-name = "mio"
-version = "0.6.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
-dependencies = [
- "cfg-if 0.1.10",
- "fuchsia-zircon",
- "fuchsia-zircon-sys",
- "iovec",
- "kernel32-sys",
- "libc",
- "log",
- "miow 0.2.1",
- "net2",
- "slab",
- "winapi 0.2.8",
-]
-
-[[package]]
-name = "mio-extras"
-version = "2.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
-dependencies = [
- "lazycell",
- "log",
- "mio",
- "slab",
-]
-
-[[package]]
-name = "mio-named-pipes"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656"
-dependencies = [
- "log",
- "mio",
- "miow 0.3.5",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "mio-uds"
-version = "0.6.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
-dependencies = [
- "iovec",
- "libc",
- "mio",
-]
-
-[[package]]
-name = "miow"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
-dependencies = [
- "kernel32-sys",
- "net2",
- "winapi 0.2.8",
- "ws2_32-sys",
-]
-
-[[package]]
-name = "miow"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e"
-dependencies = [
- "socket2",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "mockall"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01458f8a19b10cb28195290942e3149161c75acf67ebc8fbf714ab67a2b943bc"
-dependencies = [
- "cfg-if 0.1.10",
- "downcast",
- "fragile",
- "lazy_static",
- "mockall_derive",
- "predicates",
- "predicates-tree",
-]
-
-[[package]]
-name = "mockall_derive"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a673cb441f78cd9af4f5919c28576a3cc325fb6b54e42f7047dacce3c718c17b"
-dependencies = [
- "cfg-if 0.1.10",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "multihash"
-version = "0.11.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "567122ab6492f49b59def14ecc36e13e64dca4188196dd0cd41f9f3f979f3df6"
-dependencies = [
- "blake2b_simd",
- "blake2s_simd",
- "digest 0.9.0",
- "sha-1 0.9.2",
- "sha2 0.9.2",
- "sha3",
- "unsigned-varint 0.5.1",
-]
-
-[[package]]
-name = "multimap"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333"
-
-[[package]]
-name = "multistream-select"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93faf2e41f9ee62fb01680ed48f3cc26652352327aa2e59869070358f6b7dd75"
-dependencies = [
- "bytes 0.5.6",
- "futures 0.3.8",
- "log",
- "pin-project 1.0.1",
- "smallvec 1.4.2",
- "unsigned-varint 0.5.1",
-]
-
-[[package]]
-name = "nalgebra"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aaa9fddbc34c8c35dd2108515587b8ce0cab396f17977b8c738568e4edb521a2"
-dependencies = [
- "alga",
- "approx",
- "generic-array 0.12.3",
- "matrixmultiply",
- "num-complex",
- "num-rational",
- "num-traits",
- "rand 0.6.5",
- "typenum",
-]
-
-[[package]]
-name = "names"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da"
-dependencies = [
- "rand 0.3.23",
-]
-
-[[package]]
-name = "nb-connect"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8123a81538e457d44b933a02faf885d3fe8408806b23fa700e8f01c6c3a98998"
-dependencies = [
- "libc",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "net2"
-version = "0.2.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "nix"
-version = "0.17.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
-dependencies = [
- "bitflags",
- "cc",
- "cfg-if 0.1.10",
- "libc",
- "void",
-]
-
-[[package]]
-name = "node-inspect"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "log",
- "parity-scale-codec",
- "sc-cli",
- "sc-client-api",
- "sc-service",
- "sp-blockchain",
- "sp-core",
- "sp-runtime",
- "structopt",
-]
-
-[[package]]
-name = "nodrop"
-version = "0.1.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
-
-[[package]]
-name = "nohash-hasher"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
-
-[[package]]
-name = "nom"
-version = "5.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
-dependencies = [
- "memchr",
- "version_check",
-]
-
-[[package]]
-name = "normalize-line-endings"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
-
-[[package]]
-name = "num-bigint"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
-dependencies = [
- "autocfg 1.0.1",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-complex"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
-dependencies = [
- "autocfg 1.0.1",
- "num-traits",
-]
-
-[[package]]
-name = "num-integer"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
-dependencies = [
- "autocfg 1.0.1",
- "num-traits",
-]
-
-[[package]]
-name = "num-rational"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
-dependencies = [
- "autocfg 1.0.1",
- "num-bigint",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
-dependencies = [
- "autocfg 1.0.1",
- "libm",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
-dependencies = [
- "hermit-abi",
- "libc",
-]
-
-[[package]]
-name = "object"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
-
-[[package]]
-name = "once_cell"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37"
-dependencies = [
- "parking_lot 0.7.1",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
-dependencies = [
- "parking_lot 0.11.0",
-]
-
-[[package]]
-name = "opaque-debug"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
-
-[[package]]
-name = "opaque-debug"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
-
-[[package]]
-name = "openssl-probe"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
-
-[[package]]
-name = "owning_ref"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce"
-dependencies = [
- "stable_deref_trait",
-]
-
-[[package]]
-name = "pallet-authority-discovery"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-session",
- "parity-scale-codec",
- "serde",
- "sp-application-crypto",
- "sp-authority-discovery",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-authorship"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "frame-system",
- "impl-trait-for-tuples",
- "parity-scale-codec",
- "sp-authorship",
- "sp-inherents",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-babe"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "pallet-authorship",
- "pallet-session",
- "pallet-timestamp",
- "parity-scale-codec",
- "serde",
- "sp-application-crypto",
- "sp-consensus-babe",
- "sp-consensus-vrf",
- "sp-inherents",
- "sp-io",
- "sp-runtime",
- "sp-session",
- "sp-staking",
- "sp-std",
- "sp-timestamp",
-]
-
-[[package]]
-name = "pallet-balances"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "parity-scale-codec",
- "serde",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-common"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-timestamp",
- "parity-scale-codec",
- "serde",
- "sp-runtime",
- "strum 0.19.5",
- "strum_macros 0.19.4",
-]
-
-[[package]]
-name = "pallet-constitution"
-version = "1.0.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "parity-scale-codec",
- "serde",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-content-directory"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-content-working-group"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-common",
- "pallet-hiring",
- "pallet-membership",
- "pallet-recurring-reward",
- "pallet-stake",
- "pallet-timestamp",
- "pallet-token-mint",
- "pallet-versioned-store",
- "pallet-versioned-store-permissions",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-finality-tracker"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "frame-system",
- "impl-trait-for-tuples",
- "parity-scale-codec",
- "serde",
- "sp-finality-tracker",
- "sp-inherents",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-forum"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-common",
- "pallet-timestamp",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-governance"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-common",
- "pallet-membership",
- "pallet-recurring-reward",
- "pallet-timestamp",
- "pallet-token-mint",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-grandpa"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "pallet-authorship",
- "pallet-finality-tracker",
- "pallet-session",
- "parity-scale-codec",
- "serde",
- "sp-application-crypto",
- "sp-core",
- "sp-finality-grandpa",
- "sp-runtime",
- "sp-session",
- "sp-staking",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-hiring"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "mockall",
- "pallet-balances",
- "pallet-stake",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-im-online"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "pallet-authorship",
- "pallet-session",
- "parity-scale-codec",
- "serde",
- "sp-application-crypto",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-staking",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-membership"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-common",
- "pallet-timestamp",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-memo"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-common",
- "parity-scale-codec",
- "sp-arithmetic",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-offences"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "parity-scale-codec",
- "serde",
- "sp-runtime",
- "sp-staking",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-offences-benchmarking"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "pallet-babe",
- "pallet-balances",
- "pallet-grandpa",
- "pallet-im-online",
- "pallet-offences",
- "pallet-session",
- "pallet-staking",
- "parity-scale-codec",
- "sp-runtime",
- "sp-staking",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-proposals-codex"
-version = "4.0.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-common",
- "pallet-constitution",
- "pallet-governance",
- "pallet-hiring",
- "pallet-membership",
- "pallet-proposals-discussion",
- "pallet-proposals-engine",
- "pallet-recurring-reward",
- "pallet-stake",
- "pallet-staking",
- "pallet-staking-reward-curve",
- "pallet-timestamp",
- "pallet-token-mint",
- "pallet-working-group",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-staking",
- "sp-std",
- "strum 0.19.5",
-]
-
-[[package]]
-name = "pallet-proposals-discussion"
-version = "4.0.0"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-common",
- "pallet-membership",
- "pallet-timestamp",
- "parity-scale-codec",
- "serde",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-proposals-engine"
-version = "4.0.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-common",
- "pallet-membership",
- "pallet-timestamp",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-randomness-collective-flip"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "frame-system",
- "parity-scale-codec",
- "safe-mix",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-recurring-reward"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-token-mint",
- "parity-scale-codec",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
-]
-
-[[package]]
-name = "pallet-service-discovery"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-common",
- "pallet-hiring",
- "pallet-membership",
- "pallet-recurring-reward",
- "pallet-stake",
- "pallet-timestamp",
- "pallet-token-mint",
- "pallet-working-group",
- "parity-scale-codec",
- "serde",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-session"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "frame-system",
- "impl-trait-for-tuples",
- "pallet-timestamp",
- "parity-scale-codec",
- "serde",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-session",
- "sp-staking",
- "sp-std",
- "sp-trie",
-]
-
-[[package]]
-name = "pallet-session-benchmarking"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "pallet-session",
- "pallet-staking",
- "rand 0.7.3",
- "sp-runtime",
- "sp-session",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-stake"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-timestamp",
- "parity-scale-codec",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-staking"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "pallet-authorship",
- "pallet-session",
- "parity-scale-codec",
- "rand_chacha 0.2.2",
- "serde",
- "sp-application-crypto",
- "sp-io",
- "sp-npos-elections",
- "sp-runtime",
- "sp-staking",
- "sp-std",
- "static_assertions",
-]
-
-[[package]]
-name = "pallet-staking-reward-curve"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "pallet-storage"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-common",
- "pallet-hiring",
- "pallet-membership",
- "pallet-recurring-reward",
- "pallet-stake",
- "pallet-timestamp",
- "pallet-token-mint",
- "pallet-working-group",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-sudo"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "frame-system",
- "parity-scale-codec",
- "serde",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-timestamp"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "impl-trait-for-tuples",
- "parity-scale-codec",
- "serde",
- "sp-inherents",
- "sp-io",
- "sp-runtime",
- "sp-std",
- "sp-timestamp",
-]
-
-[[package]]
-name = "pallet-token-mint"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "parity-scale-codec",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
-]
-
-[[package]]
-name = "pallet-transaction-payment"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-transaction-payment-rpc-runtime-api",
- "parity-scale-codec",
- "serde",
- "smallvec 1.4.2",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-transaction-payment-rpc"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "jsonrpc-core",
- "jsonrpc-core-client",
- "jsonrpc-derive",
- "pallet-transaction-payment-rpc-runtime-api",
- "parity-scale-codec",
- "serde",
- "sp-api",
- "sp-blockchain",
- "sp-core",
- "sp-rpc",
- "sp-runtime",
-]
-
-[[package]]
-name = "pallet-transaction-payment-rpc-runtime-api"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-support",
- "parity-scale-codec",
- "serde",
- "sp-api",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-utility"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-benchmarking",
- "frame-support",
- "frame-system",
- "parity-scale-codec",
- "serde",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-versioned-store"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-common",
- "pallet-timestamp",
- "parity-scale-codec",
- "serde",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-versioned-store-permissions"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-common",
- "pallet-timestamp",
- "pallet-versioned-store",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "pallet-working-group"
-version = "3.1.0"
-dependencies = [
- "frame-support",
- "frame-system",
- "pallet-balances",
- "pallet-common",
- "pallet-hiring",
- "pallet-membership",
- "pallet-recurring-reward",
- "pallet-stake",
- "pallet-timestamp",
- "pallet-token-mint",
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-core",
- "sp-io",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "parity-db"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00d595e372d119261593297debbe4193811a4dc811d2a1ccbb8caaa6666ad7ab"
-dependencies = [
- "blake2-rfc",
- "crc32fast",
- "libc",
- "log",
- "memmap",
- "parking_lot 0.10.2",
-]
-
-[[package]]
-name = "parity-multiaddr"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22fe99b938abd57507e37f8d4ef30cd74b33c71face2809b37b8beb71bab15ab"
-dependencies = [
- "arrayref",
- "bs58 0.4.0",
- "byteorder 1.3.4",
- "data-encoding",
- "multihash",
- "percent-encoding 2.1.0",
- "serde",
- "static_assertions",
- "unsigned-varint 0.5.1",
- "url 2.2.0",
-]
-
-[[package]]
-name = "parity-scale-codec"
-version = "1.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c740e5fbcb6847058b40ac7e5574766c6388f585e184d769910fe0d3a2ca861"
-dependencies = [
- "arrayvec 0.5.2",
- "bitvec",
- "byte-slice-cast",
- "parity-scale-codec-derive",
- "serde",
-]
-
-[[package]]
-name = "parity-scale-codec-derive"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "198db82bb1c18fc00176004462dd809b2a6d851669550aa17af6dacd21ae0c14"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "parity-send-wrapper"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f"
-
-[[package]]
-name = "parity-tokio-ipc"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e57fea504fea33f9fbb5f49f378359030e7e026a6ab849bb9e8f0787376f1bf"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.30",
- "libc",
- "log",
- "mio-named-pipes",
- "miow 0.3.5",
- "rand 0.7.3",
- "tokio 0.1.22",
- "tokio-named-pipes",
- "tokio-uds",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "parity-util-mem"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c"
-dependencies = [
- "cfg-if 0.1.10",
- "hashbrown 0.8.2",
- "impl-trait-for-tuples",
- "parity-util-mem-derive",
- "parking_lot 0.10.2",
- "primitive-types",
- "smallvec 1.4.2",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "parity-util-mem-derive"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2"
-dependencies = [
- "proc-macro2",
- "syn",
- "synstructure",
-]
-
-[[package]]
-name = "parity-wasm"
-version = "0.41.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865"
-
-[[package]]
-name = "parity-ws"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e02a625dd75084c2a7024f07c575b61b782f729d18702dabb3cdbf31911dc61"
-dependencies = [
- "byteorder 1.3.4",
- "bytes 0.4.12",
- "httparse",
- "log",
- "mio",
- "mio-extras",
- "rand 0.7.3",
- "sha-1 0.8.2",
- "slab",
- "url 2.2.0",
-]
-
-[[package]]
-name = "parking"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
-
-[[package]]
-name = "parking_lot"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
-dependencies = [
- "lock_api 0.1.5",
- "parking_lot_core 0.4.0",
-]
-
-[[package]]
-name = "parking_lot"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
-dependencies = [
- "lock_api 0.3.4",
- "parking_lot_core 0.6.2",
- "rustc_version",
-]
-
-[[package]]
-name = "parking_lot"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
-dependencies = [
- "lock_api 0.3.4",
- "parking_lot_core 0.7.2",
-]
-
-[[package]]
-name = "parking_lot"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
-dependencies = [
- "instant",
- "lock_api 0.4.1",
- "parking_lot_core 0.8.0",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
-dependencies = [
- "libc",
- "rand 0.6.5",
- "rustc_version",
- "smallvec 0.6.13",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
-dependencies = [
- "cfg-if 0.1.10",
- "cloudabi 0.0.3",
- "libc",
- "redox_syscall",
- "rustc_version",
- "smallvec 0.6.13",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
-dependencies = [
- "cfg-if 0.1.10",
- "cloudabi 0.0.3",
- "libc",
- "redox_syscall",
- "smallvec 1.4.2",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
-dependencies = [
- "cfg-if 0.1.10",
- "cloudabi 0.1.0",
- "instant",
- "libc",
- "redox_syscall",
- "smallvec 1.4.2",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "paste"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
-dependencies = [
- "paste-impl",
- "proc-macro-hack",
-]
-
-[[package]]
-name = "paste-impl"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
-dependencies = [
- "proc-macro-hack",
-]
-
-[[package]]
-name = "pbkdf2"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9"
-dependencies = [
- "byteorder 1.3.4",
- "crypto-mac 0.7.0",
- "rayon",
-]
-
-[[package]]
-name = "pdqselect"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27"
-
-[[package]]
-name = "peeking_take_while"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
-
-[[package]]
-name = "percent-encoding"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
-
-[[package]]
-name = "percent-encoding"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
-
-[[package]]
-name = "petgraph"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
-dependencies = [
- "fixedbitset",
- "indexmap",
-]
-
-[[package]]
-name = "pin-project"
-version = "0.4.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15"
-dependencies = [
- "pin-project-internal 0.4.27",
-]
-
-[[package]]
-name = "pin-project"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee41d838744f60d959d7074e3afb6b35c7456d0f61cad38a24e35e6553f73841"
-dependencies = [
- "pin-project-internal 1.0.1",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "0.4.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "pin-project-lite"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b"
-
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-[[package]]
-name = "pkg-config"
-version = "0.3.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
-
-[[package]]
-name = "platforms"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "feb3b2b1033b8a60b4da6ee470325f887758c95d5320f52f9ce0df055a55940e"
-
-[[package]]
-name = "polling"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "log",
- "wepoll-sys",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "poly1305"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22ce46de8e53ee414ca4d02bfefac75d8c12fba948b76622a40b4be34dfce980"
-dependencies = [
- "universal-hash",
-]
-
-[[package]]
-name = "polyval"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5884790f1ce3553ad55fec37b5aaac5882e0e845a2612df744d6c85c9bf046c"
-dependencies = [
- "cfg-if 0.1.10",
- "universal-hash",
-]
-
-[[package]]
-name = "ppv-lite86"
-version = "0.2.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
-
-[[package]]
-name = "predicates"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96bfead12e90dccead362d62bb2c90a5f6fc4584963645bc7f71a735e0b0735a"
-dependencies = [
- "difference",
- "float-cmp",
- "normalize-line-endings",
- "predicates-core",
- "regex",
-]
-
-[[package]]
-name = "predicates-core"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06075c3a3e92559ff8929e7a280684489ea27fe44805174c3ebd9328dcb37178"
-
-[[package]]
-name = "predicates-tree"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e63c4859013b38a76eca2414c64911fba30def9e3202ac461a2d22831220124"
-dependencies = [
- "predicates-core",
- "treeline",
-]
-
-[[package]]
-name = "primitive-types"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c55c21c64d0eaa4d7ed885d959ef2d62d9e488c27c0e02d9aa5ce6c877b7d5f8"
-dependencies = [
- "fixed-hash",
- "impl-codec",
- "impl-serde",
- "uint",
-]
-
-[[package]]
-name = "proc-macro-crate"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
-dependencies = [
- "toml",
-]
-
-[[package]]
-name = "proc-macro-error"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
-dependencies = [
- "proc-macro-error-attr",
- "proc-macro2",
- "quote",
- "syn",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-error-attr"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
-dependencies = [
- "proc-macro2",
- "quote",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-hack"
-version = "0.5.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
-
-[[package]]
-name = "proc-macro-nested"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
-dependencies = [
- "unicode-xid",
-]
-
-[[package]]
-name = "prometheus"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30d70cf4412832bcac9cffe27906f4a66e450d323525e977168c70d1b36120ae"
-dependencies = [
- "cfg-if 0.1.10",
- "fnv",
- "lazy_static",
- "parking_lot 0.11.0",
- "regex",
- "thiserror",
-]
-
-[[package]]
-name = "prost"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212"
-dependencies = [
- "bytes 0.5.6",
- "prost-derive",
-]
-
-[[package]]
-name = "prost-build"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26"
-dependencies = [
- "bytes 0.5.6",
- "heck",
- "itertools",
- "log",
- "multimap",
- "petgraph",
- "prost",
- "prost-types",
- "tempfile",
- "which",
-]
-
-[[package]]
-name = "prost-derive"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72"
-dependencies = [
- "anyhow",
- "itertools",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "prost-types"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa"
-dependencies = [
- "bytes 0.5.6",
- "prost",
-]
-
-[[package]]
-name = "quick-error"
-version = "1.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
-
-[[package]]
-name = "quicksink"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77de3c815e5a160b1539c6592796801df2043ae35e123b46d73380cfa57af858"
-dependencies = [
- "futures-core",
- "futures-sink",
- "pin-project-lite",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "radium"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac"
-
-[[package]]
-name = "rand"
-version = "0.3.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
-dependencies = [
- "libc",
- "rand 0.4.6",
-]
-
-[[package]]
-name = "rand"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
-dependencies = [
- "fuchsia-cprng",
- "libc",
- "rand_core 0.3.1",
- "rdrand",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rand"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
-dependencies = [
- "cloudabi 0.0.3",
- "fuchsia-cprng",
- "libc",
- "rand_core 0.3.1",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rand"
-version = "0.6.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
-dependencies = [
- "autocfg 0.1.7",
- "libc",
- "rand_chacha 0.1.1",
- "rand_core 0.4.2",
- "rand_hc 0.1.0",
- "rand_isaac",
- "rand_jitter",
- "rand_os",
- "rand_pcg 0.1.2",
- "rand_xorshift",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rand"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
-dependencies = [
- "getrandom 0.1.15",
- "libc",
- "rand_chacha 0.2.2",
- "rand_core 0.5.1",
- "rand_hc 0.2.0",
- "rand_pcg 0.2.1",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
-dependencies = [
- "autocfg 0.1.7",
- "rand_core 0.3.1",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
-dependencies = [
- "ppv-lite86",
- "rand_core 0.5.1",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
-dependencies = [
- "rand_core 0.4.2",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
-
-[[package]]
-name = "rand_core"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
-dependencies = [
- "getrandom 0.1.15",
-]
-
-[[package]]
-name = "rand_hc"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
-dependencies = [
- "rand_core 0.3.1",
-]
-
-[[package]]
-name = "rand_hc"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
-dependencies = [
- "rand_core 0.5.1",
-]
-
-[[package]]
-name = "rand_isaac"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
-dependencies = [
- "rand_core 0.3.1",
-]
-
-[[package]]
-name = "rand_jitter"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
-dependencies = [
- "libc",
- "rand_core 0.4.2",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rand_os"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
-dependencies = [
- "cloudabi 0.0.3",
- "fuchsia-cprng",
- "libc",
- "rand_core 0.4.2",
- "rdrand",
- "wasm-bindgen",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rand_pcg"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
-dependencies = [
- "autocfg 0.1.7",
- "rand_core 0.4.2",
-]
-
-[[package]]
-name = "rand_pcg"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
-dependencies = [
- "rand_core 0.5.1",
-]
-
-[[package]]
-name = "rand_xorshift"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
-dependencies = [
- "rand_core 0.3.1",
-]
-
-[[package]]
-name = "rawpointer"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
-
-[[package]]
-name = "rayon"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
-dependencies = [
- "autocfg 1.0.1",
- "crossbeam-deque 0.8.0",
- "either",
- "rayon-core",
-]
-
-[[package]]
-name = "rayon-core"
-version = "1.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
-dependencies = [
- "crossbeam-channel",
- "crossbeam-deque 0.8.0",
- "crossbeam-utils 0.8.0",
- "lazy_static",
- "num_cpus",
-]
-
-[[package]]
-name = "rdrand"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
-dependencies = [
- "rand_core 0.3.1",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.1.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
-
-[[package]]
-name = "redox_users"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
-dependencies = [
- "getrandom 0.1.15",
- "redox_syscall",
- "rust-argon2",
-]
-
-[[package]]
-name = "ref-cast"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e17626b2f4bcf35b84bf379072a66e28cfe5c3c6ae58b38e4914bb8891dabece"
-dependencies = [
- "ref-cast-impl",
-]
-
-[[package]]
-name = "ref-cast-impl"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c523ccaed8ac4b0288948849a350b37d3035827413c458b6a40ddb614bb4f72"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "regex"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-syntax",
- "thread_local",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
-dependencies = [
- "byteorder 1.3.4",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.6.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
-
-[[package]]
-name = "remove_dir_all"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
-dependencies = [
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "retain_mut"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e005d658ad26eacc2b6c506dfde519f4e277e328d0eb3379ca61647d70a8f531"
-
-[[package]]
-name = "ring"
-version = "0.16.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4"
-dependencies = [
- "cc",
- "libc",
- "once_cell 1.4.1",
- "spin",
- "untrusted",
- "web-sys",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rocksdb"
-version = "0.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23d83c02c429044d58474eaf5ae31e062d0de894e21125b47437ec0edc1397e6"
-dependencies = [
- "libc",
- "librocksdb-sys",
-]
-
-[[package]]
-name = "rpassword"
-version = "4.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99371657d3c8e4d816fb6221db98fa408242b0b53bac08f8676a41f8554fe99f"
-dependencies = [
- "libc",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "rust-argon2"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19"
-dependencies = [
- "base64 0.12.3",
- "blake2b_simd",
- "constant_time_eq",
- "crossbeam-utils 0.7.2",
-]
-
-[[package]]
-name = "rustc-demangle"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
-
-[[package]]
-name = "rustc-hash"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
-
-[[package]]
-name = "rustc-hex"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
-
-[[package]]
-name = "rustc_version"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
-dependencies = [
- "semver",
-]
-
-[[package]]
-name = "rustls"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81"
-dependencies = [
- "base64 0.12.3",
- "log",
- "ring",
- "sct",
- "webpki",
-]
-
-[[package]]
-name = "rustls-native-certs"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "629d439a7672da82dd955498445e496ee2096fe2117b9f796558a43fdb9e59b8"
-dependencies = [
- "openssl-probe",
- "rustls",
- "schannel",
- "security-framework",
-]
-
-[[package]]
-name = "rw-stream-sink"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020"
-dependencies = [
- "futures 0.3.8",
- "pin-project 0.4.27",
- "static_assertions",
-]
-
-[[package]]
-name = "ryu"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
-
-[[package]]
-name = "safe-mix"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d3d055a2582e6b00ed7a31c1524040aa391092bf636328350813f3a0605215c"
-dependencies = [
- "rustc_version",
-]
-
-[[package]]
-name = "salsa20"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7f47b10fa80f6969bbbd9c8e7cc998f082979d402a9e10579e2303a87955395"
-dependencies = [
- "stream-cipher",
-]
-
-[[package]]
-name = "sc-authority-discovery"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "bytes 0.5.6",
- "derive_more",
- "either",
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "libp2p",
- "log",
- "parity-scale-codec",
- "prost",
- "prost-build",
- "rand 0.7.3",
- "sc-client-api",
- "sc-keystore",
- "sc-network",
- "serde_json",
- "sp-api",
- "sp-authority-discovery",
- "sp-blockchain",
- "sp-core",
- "sp-runtime",
- "substrate-prometheus-endpoint",
-]
-
-[[package]]
-name = "sc-basic-authorship"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "log",
- "parity-scale-codec",
- "sc-block-builder",
- "sc-client-api",
- "sc-proposer-metrics",
- "sc-telemetry",
- "sp-api",
- "sp-blockchain",
- "sp-consensus",
- "sp-core",
- "sp-inherents",
- "sp-runtime",
- "sp-transaction-pool",
- "substrate-prometheus-endpoint",
- "tokio-executor 0.2.0-alpha.6",
-]
-
-[[package]]
-name = "sc-block-builder"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "sc-client-api",
- "sp-api",
- "sp-block-builder",
- "sp-blockchain",
- "sp-consensus",
- "sp-core",
- "sp-inherents",
- "sp-runtime",
- "sp-state-machine",
-]
-
-[[package]]
-name = "sc-chain-spec"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "impl-trait-for-tuples",
- "parity-scale-codec",
- "sc-chain-spec-derive",
- "sc-network",
- "sc-telemetry",
- "serde",
- "serde_json",
- "sp-chain-spec",
- "sp-core",
- "sp-runtime",
-]
-
-[[package]]
-name = "sc-chain-spec-derive"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "sc-cli"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "ansi_term 0.12.1",
- "atty",
- "bip39",
- "chrono",
- "derive_more",
- "fdlimit",
- "futures 0.3.8",
- "hex",
- "lazy_static",
- "libp2p",
- "log",
- "names",
- "nix",
- "parity-scale-codec",
- "parity-util-mem",
- "rand 0.7.3",
- "regex",
- "rpassword",
- "sc-client-api",
- "sc-informant",
- "sc-keystore",
- "sc-network",
- "sc-service",
- "sc-telemetry",
- "sc-tracing",
- "serde",
- "serde_json",
- "sp-blockchain",
- "sp-core",
- "sp-keyring",
- "sp-panic-handler",
- "sp-runtime",
- "sp-state-machine",
- "sp-utils",
- "sp-version",
- "structopt",
- "substrate-prometheus-endpoint",
- "time",
- "tokio 0.2.22",
- "tracing",
- "tracing-log",
- "tracing-subscriber",
-]
-
-[[package]]
-name = "sc-client-api"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "fnv",
- "futures 0.3.8",
- "hash-db",
- "hex-literal 0.2.1",
- "kvdb",
- "lazy_static",
- "log",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "sc-executor",
- "sc-telemetry",
- "sp-api",
- "sp-blockchain",
- "sp-consensus",
- "sp-core",
- "sp-database",
- "sp-externalities",
- "sp-inherents",
- "sp-keyring",
- "sp-runtime",
- "sp-state-machine",
- "sp-std",
- "sp-storage",
- "sp-transaction-pool",
- "sp-trie",
- "sp-utils",
- "sp-version",
- "substrate-prometheus-endpoint",
-]
-
-[[package]]
-name = "sc-client-db"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "blake2-rfc",
- "hash-db",
- "kvdb",
- "kvdb-memorydb",
- "kvdb-rocksdb",
- "linked-hash-map",
- "log",
- "parity-db",
- "parity-scale-codec",
- "parity-util-mem",
- "parking_lot 0.10.2",
- "sc-client-api",
- "sc-executor",
- "sc-state-db",
- "sp-arithmetic",
- "sp-blockchain",
- "sp-consensus",
- "sp-core",
- "sp-database",
- "sp-runtime",
- "sp-state-machine",
- "sp-trie",
- "substrate-prometheus-endpoint",
-]
-
-[[package]]
-name = "sc-consensus"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "sc-client-api",
- "sp-blockchain",
- "sp-consensus",
- "sp-runtime",
-]
-
-[[package]]
-name = "sc-consensus-babe"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "fork-tree",
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "log",
- "merlin",
- "num-bigint",
- "num-rational",
- "num-traits",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "pdqselect",
- "rand 0.7.3",
- "retain_mut",
- "sc-client-api",
- "sc-consensus-epochs",
- "sc-consensus-slots",
- "sc-consensus-uncles",
- "sc-keystore",
- "sc-telemetry",
- "schnorrkel",
- "serde",
- "sp-api",
- "sp-application-crypto",
- "sp-block-builder",
- "sp-blockchain",
- "sp-consensus",
- "sp-consensus-babe",
- "sp-consensus-vrf",
- "sp-core",
- "sp-inherents",
- "sp-io",
- "sp-runtime",
- "sp-timestamp",
- "sp-utils",
- "sp-version",
- "substrate-prometheus-endpoint",
-]
-
-[[package]]
-name = "sc-consensus-babe-rpc"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "futures 0.3.8",
- "jsonrpc-core",
- "jsonrpc-core-client",
- "jsonrpc-derive",
- "sc-consensus-babe",
- "sc-consensus-epochs",
- "sc-keystore",
- "sc-rpc-api",
- "serde",
- "sp-api",
- "sp-application-crypto",
- "sp-blockchain",
- "sp-consensus",
- "sp-consensus-babe",
- "sp-core",
- "sp-runtime",
-]
-
-[[package]]
-name = "sc-consensus-epochs"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "fork-tree",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "sc-client-api",
- "sp-blockchain",
- "sp-runtime",
-]
-
-[[package]]
-name = "sc-consensus-slots"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "log",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "sc-client-api",
- "sc-telemetry",
- "sp-api",
- "sp-application-crypto",
- "sp-blockchain",
- "sp-consensus",
- "sp-consensus-slots",
- "sp-core",
- "sp-inherents",
- "sp-runtime",
- "sp-state-machine",
-]
-
-[[package]]
-name = "sc-consensus-uncles"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "log",
- "sc-client-api",
- "sp-authorship",
- "sp-consensus",
- "sp-core",
- "sp-inherents",
- "sp-runtime",
-]
-
-[[package]]
-name = "sc-executor"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "lazy_static",
- "libsecp256k1",
- "log",
- "parity-scale-codec",
- "parity-wasm",
- "parking_lot 0.10.2",
- "sc-executor-common",
- "sc-executor-wasmi",
- "sp-api",
- "sp-core",
- "sp-externalities",
- "sp-io",
- "sp-panic-handler",
- "sp-runtime-interface",
- "sp-serializer",
- "sp-trie",
- "sp-version",
- "sp-wasm-interface",
- "wasmi",
-]
-
-[[package]]
-name = "sc-executor-common"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "log",
- "parity-scale-codec",
- "parity-wasm",
- "sp-allocator",
- "sp-core",
- "sp-runtime-interface",
- "sp-serializer",
- "sp-wasm-interface",
- "wasmi",
-]
-
-[[package]]
-name = "sc-executor-wasmi"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "log",
- "parity-scale-codec",
- "sc-executor-common",
- "sp-allocator",
- "sp-core",
- "sp-runtime-interface",
- "sp-wasm-interface",
- "wasmi",
-]
-
-[[package]]
-name = "sc-finality-grandpa"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "finality-grandpa",
- "fork-tree",
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "log",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "pin-project 0.4.27",
- "rand 0.7.3",
- "sc-block-builder",
- "sc-client-api",
- "sc-consensus",
- "sc-keystore",
- "sc-network",
- "sc-network-gossip",
- "sc-telemetry",
- "serde_json",
- "sp-api",
- "sp-application-crypto",
- "sp-arithmetic",
- "sp-blockchain",
- "sp-consensus",
- "sp-core",
- "sp-finality-grandpa",
- "sp-finality-tracker",
- "sp-inherents",
- "sp-runtime",
- "sp-utils",
- "substrate-prometheus-endpoint",
-]
-
-[[package]]
-name = "sc-finality-grandpa-rpc"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "finality-grandpa",
- "futures 0.3.8",
- "jsonrpc-core",
- "jsonrpc-core-client",
- "jsonrpc-derive",
- "jsonrpc-pubsub",
- "log",
- "parity-scale-codec",
- "sc-client-api",
- "sc-finality-grandpa",
- "sc-rpc",
- "serde",
- "serde_json",
- "sp-blockchain",
- "sp-core",
- "sp-runtime",
-]
-
-[[package]]
-name = "sc-informant"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "ansi_term 0.12.1",
- "futures 0.3.8",
- "log",
- "parity-util-mem",
- "sc-client-api",
- "sc-network",
- "sp-blockchain",
- "sp-runtime",
- "sp-transaction-pool",
- "sp-utils",
- "wasm-timer",
-]
-
-[[package]]
-name = "sc-keystore"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "hex",
- "merlin",
- "parking_lot 0.10.2",
- "rand 0.7.3",
- "serde_json",
- "sp-application-crypto",
- "sp-core",
- "subtle 2.3.0",
-]
-
-[[package]]
-name = "sc-light"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "hash-db",
- "lazy_static",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "sc-client-api",
- "sc-executor",
- "sp-api",
- "sp-blockchain",
- "sp-core",
- "sp-externalities",
- "sp-runtime",
- "sp-state-machine",
-]
-
-[[package]]
-name = "sc-network"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "async-std",
- "async-trait",
- "bitflags",
- "bs58 0.3.1",
- "bytes 0.5.6",
- "derive_more",
- "either",
- "erased-serde",
- "fnv",
- "fork-tree",
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "futures_codec",
- "hex",
- "ip_network",
- "libp2p",
- "linked-hash-map",
- "linked_hash_set",
- "log",
- "lru 0.4.3",
- "nohash-hasher",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "pin-project 0.4.27",
- "prost",
- "prost-build",
- "rand 0.7.3",
- "sc-block-builder",
- "sc-client-api",
- "sc-peerset",
- "serde",
- "serde_json",
- "slog",
- "slog_derive",
- "smallvec 0.6.13",
- "sp-arithmetic",
- "sp-blockchain",
- "sp-consensus",
- "sp-core",
- "sp-runtime",
- "sp-utils",
- "substrate-prometheus-endpoint",
- "thiserror",
- "unsigned-varint 0.4.0",
- "void",
- "wasm-timer",
- "zeroize",
-]
-
-[[package]]
-name = "sc-network-gossip"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "libp2p",
- "log",
- "lru 0.4.3",
- "sc-network",
- "sp-runtime",
- "wasm-timer",
-]
-
-[[package]]
-name = "sc-offchain"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "bytes 0.5.6",
- "fnv",
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "hyper 0.13.9",
- "hyper-rustls",
- "log",
- "num_cpus",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "rand 0.7.3",
- "sc-client-api",
- "sc-keystore",
- "sc-network",
- "sp-api",
- "sp-core",
- "sp-offchain",
- "sp-runtime",
- "sp-utils",
- "threadpool",
-]
-
-[[package]]
-name = "sc-peerset"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "futures 0.3.8",
- "libp2p",
- "log",
- "serde_json",
- "sp-utils",
- "wasm-timer",
-]
-
-[[package]]
-name = "sc-proposer-metrics"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "log",
- "substrate-prometheus-endpoint",
-]
-
-[[package]]
-name = "sc-rpc"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "futures 0.3.8",
- "hash-db",
- "jsonrpc-core",
- "jsonrpc-pubsub",
- "log",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "sc-block-builder",
- "sc-client-api",
- "sc-executor",
- "sc-keystore",
- "sc-rpc-api",
- "serde_json",
- "sp-api",
- "sp-blockchain",
- "sp-chain-spec",
- "sp-core",
- "sp-offchain",
- "sp-rpc",
- "sp-runtime",
- "sp-session",
- "sp-state-machine",
- "sp-transaction-pool",
- "sp-utils",
- "sp-version",
-]
-
-[[package]]
-name = "sc-rpc-api"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "futures 0.3.8",
- "jsonrpc-core",
- "jsonrpc-core-client",
- "jsonrpc-derive",
- "jsonrpc-pubsub",
- "log",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "serde",
- "serde_json",
- "sp-chain-spec",
- "sp-core",
- "sp-rpc",
- "sp-runtime",
- "sp-transaction-pool",
- "sp-version",
-]
-
-[[package]]
-name = "sc-rpc-server"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "futures 0.1.30",
- "jsonrpc-core",
- "jsonrpc-http-server",
- "jsonrpc-ipc-server",
- "jsonrpc-pubsub",
- "jsonrpc-ws-server",
- "log",
- "serde",
- "serde_json",
- "sp-runtime",
- "substrate-prometheus-endpoint",
-]
-
-[[package]]
-name = "sc-service"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "directories",
- "exit-future",
- "futures 0.1.30",
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "hash-db",
- "jsonrpc-core",
- "jsonrpc-pubsub",
- "lazy_static",
- "log",
- "parity-scale-codec",
- "parity-util-mem",
- "parking_lot 0.10.2",
- "pin-project 0.4.27",
- "rand 0.7.3",
- "sc-block-builder",
- "sc-chain-spec",
- "sc-client-api",
- "sc-client-db",
- "sc-executor",
- "sc-informant",
- "sc-keystore",
- "sc-light",
- "sc-network",
- "sc-offchain",
- "sc-rpc",
- "sc-rpc-server",
- "sc-telemetry",
- "sc-tracing",
- "sc-transaction-pool",
- "serde",
- "serde_json",
- "slog",
- "sp-api",
- "sp-application-crypto",
- "sp-block-builder",
- "sp-blockchain",
- "sp-consensus",
- "sp-core",
- "sp-externalities",
- "sp-inherents",
- "sp-io",
- "sp-runtime",
- "sp-session",
- "sp-state-machine",
- "sp-tracing",
- "sp-transaction-pool",
- "sp-trie",
- "sp-utils",
- "sp-version",
- "substrate-prometheus-endpoint",
- "tempfile",
- "tracing",
- "wasm-timer",
-]
-
-[[package]]
-name = "sc-service-test"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "fdlimit",
- "futures 0.1.30",
- "futures 0.3.8",
- "hex-literal 0.2.1",
- "log",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "sc-block-builder",
- "sc-client-api",
- "sc-client-db",
- "sc-executor",
- "sc-light",
- "sc-network",
- "sc-service",
- "sp-api",
- "sp-blockchain",
- "sp-consensus",
- "sp-core",
- "sp-externalities",
- "sp-panic-handler",
- "sp-runtime",
- "sp-state-machine",
- "sp-storage",
- "sp-tracing",
- "sp-transaction-pool",
- "sp-trie",
- "substrate-test-runtime",
- "substrate-test-runtime-client",
- "tempfile",
- "tokio 0.1.22",
-]
-
-[[package]]
-name = "sc-state-db"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "log",
- "parity-scale-codec",
- "parity-util-mem",
- "parity-util-mem-derive",
- "parking_lot 0.10.2",
- "sc-client-api",
- "sp-core",
-]
-
-[[package]]
-name = "sc-telemetry"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "libp2p",
- "log",
- "parking_lot 0.10.2",
- "pin-project 0.4.27",
- "rand 0.7.3",
- "serde",
- "slog",
- "slog-json",
- "slog-scope",
- "take_mut",
- "void",
- "wasm-timer",
-]
-
-[[package]]
-name = "sc-tracing"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "erased-serde",
- "log",
- "parking_lot 0.10.2",
- "rustc-hash",
- "sc-telemetry",
- "serde",
- "serde_json",
- "slog",
- "sp-tracing",
- "tracing",
- "tracing-core",
- "tracing-subscriber",
-]
-
-[[package]]
-name = "sc-transaction-graph"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "futures 0.3.8",
- "linked-hash-map",
- "log",
- "parity-util-mem",
- "parking_lot 0.10.2",
- "retain_mut",
- "serde",
- "sp-blockchain",
- "sp-core",
- "sp-runtime",
- "sp-transaction-pool",
- "sp-utils",
- "wasm-timer",
-]
-
-[[package]]
-name = "sc-transaction-pool"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "futures 0.3.8",
- "futures-diagnose",
- "intervalier",
- "log",
- "parity-scale-codec",
- "parity-util-mem",
- "parking_lot 0.10.2",
- "sc-client-api",
- "sc-transaction-graph",
- "sp-api",
- "sp-blockchain",
- "sp-core",
- "sp-runtime",
- "sp-tracing",
- "sp-transaction-pool",
- "sp-utils",
- "substrate-prometheus-endpoint",
- "wasm-timer",
-]
-
-[[package]]
-name = "schannel"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
-dependencies = [
- "lazy_static",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "schnorrkel"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862"
-dependencies = [
- "arrayref",
- "arrayvec 0.5.2",
- "curve25519-dalek 2.1.0",
- "getrandom 0.1.15",
- "merlin",
- "rand 0.7.3",
- "rand_core 0.5.1",
- "sha2 0.8.2",
- "subtle 2.3.0",
- "zeroize",
-]
-
-[[package]]
-name = "scoped-tls"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
-
-[[package]]
-name = "scopeguard"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
-
-[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
-name = "sct"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
-dependencies = [
- "ring",
- "untrusted",
-]
-
-[[package]]
-name = "secrecy"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f"
-dependencies = [
- "zeroize",
-]
-
-[[package]]
-name = "security-framework"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad502866817f0575705bd7be36e2b2535cc33262d493aa733a2ec862baa2bc2b"
-dependencies = [
- "bitflags",
- "core-foundation",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
-]
-
-[[package]]
-name = "security-framework-sys"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51ceb04988b17b6d1dcd555390fa822ca5637b4a14e1f5099f13d351bed4d6c7"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "semver"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
-dependencies = [
- "semver-parser",
-]
-
-[[package]]
-name = "semver-parser"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-
-[[package]]
-name = "send_wrapper"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "686ef91cf020ad8d4aca9a7047641fd6add626b7b89e14546c2b6a76781cf822"
-
-[[package]]
-name = "send_wrapper"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0"
-
-[[package]]
-name = "serde"
-version = "1.0.117"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.117"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_derive_internals"
-version = "0.25.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.59"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95"
-dependencies = [
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "sha-1"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
-dependencies = [
- "block-buffer 0.7.3",
- "digest 0.8.1",
- "fake-simd",
- "opaque-debug 0.2.3",
-]
-
-[[package]]
-name = "sha-1"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce3cdf1b5e620a498ee6f2a171885ac7e22f0e12089ec4b3d22b84921792507c"
-dependencies = [
- "block-buffer 0.9.0",
- "cfg-if 1.0.0",
- "cpuid-bool",
- "digest 0.9.0",
- "opaque-debug 0.3.0",
-]
-
-[[package]]
-name = "sha2"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
-dependencies = [
- "block-buffer 0.7.3",
- "digest 0.8.1",
- "fake-simd",
- "opaque-debug 0.2.3",
-]
-
-[[package]]
-name = "sha2"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8"
-dependencies = [
- "block-buffer 0.9.0",
- "cfg-if 1.0.0",
- "cpuid-bool",
- "digest 0.9.0",
- "opaque-debug 0.3.0",
-]
-
-[[package]]
-name = "sha3"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809"
-dependencies = [
- "block-buffer 0.9.0",
- "digest 0.9.0",
- "keccak",
- "opaque-debug 0.3.0",
-]
-
-[[package]]
-name = "sharded-slab"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b4921be914e16899a80adefb821f8ddb7974e3f1250223575a44ed994882127"
-dependencies = [
- "lazy_static",
- "loom",
-]
-
-[[package]]
-name = "shlex"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
-
-[[package]]
-name = "signal-hook-registry"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "signature"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210"
-
-[[package]]
-name = "slab"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
-
-[[package]]
-name = "slog"
-version = "2.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cc9c640a4adbfbcc11ffb95efe5aa7af7309e002adab54b185507dbf2377b99"
-dependencies = [
- "erased-serde",
-]
-
-[[package]]
-name = "slog-json"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a"
-dependencies = [
- "chrono",
- "erased-serde",
- "serde",
- "serde_json",
- "slog",
-]
-
-[[package]]
-name = "slog-scope"
-version = "4.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c44c89dd8b0ae4537d1ae318353eaf7840b4869c536e31c41e963d1ea523ee6"
-dependencies = [
- "arc-swap",
- "lazy_static",
- "slog",
-]
-
-[[package]]
-name = "slog_derive"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a945ec7f7ce853e89ffa36be1e27dce9a43e82ff9093bf3461c30d5da74ed11b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "smallvec"
-version = "0.6.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
-dependencies = [
- "maybe-uninit",
-]
-
-[[package]]
-name = "smallvec"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
-
-[[package]]
-name = "snow"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "795dd7aeeee24468e5a32661f6d27f7b5cbed802031b2d7640c7b10f8fb2dd50"
-dependencies = [
- "aes-gcm",
- "blake2",
- "chacha20poly1305",
- "rand 0.7.3",
- "rand_core 0.5.1",
- "ring",
- "rustc_version",
- "sha2 0.9.2",
- "subtle 2.3.0",
- "x25519-dalek 1.1.0",
-]
-
-[[package]]
-name = "socket2"
-version = "0.3.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fd8b795c389288baa5f355489c65e71fd48a02104600d15c4cfbc561e9e429d"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "redox_syscall",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "soketto"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5c71ed3d54db0a699f4948e1bb3e45b450fa31fe602621dee6680361d569c88"
-dependencies = [
- "base64 0.12.3",
- "bytes 0.5.6",
- "flate2",
- "futures 0.3.8",
- "httparse",
- "log",
- "rand 0.7.3",
- "sha-1 0.9.2",
-]
-
-[[package]]
-name = "sp-allocator"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "log",
- "sp-core",
- "sp-std",
- "sp-wasm-interface",
-]
-
-[[package]]
-name = "sp-api"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "hash-db",
- "parity-scale-codec",
- "sp-api-proc-macro",
- "sp-core",
- "sp-runtime",
- "sp-state-machine",
- "sp-std",
- "sp-version",
-]
-
-[[package]]
-name = "sp-api-proc-macro"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "blake2-rfc",
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "sp-application-crypto"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "serde",
- "sp-core",
- "sp-io",
- "sp-std",
-]
-
-[[package]]
-name = "sp-arithmetic"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "integer-sqrt",
- "num-traits",
- "parity-scale-codec",
- "serde",
- "sp-debug-derive",
- "sp-std",
-]
-
-[[package]]
-name = "sp-authority-discovery"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "sp-api",
- "sp-application-crypto",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "sp-authorship"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "sp-inherents",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "sp-block-builder"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "sp-api",
- "sp-inherents",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "sp-blockchain"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "log",
- "lru 0.4.3",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "sp-block-builder",
- "sp-consensus",
- "sp-database",
- "sp-runtime",
- "sp-state-machine",
-]
-
-[[package]]
-name = "sp-chain-spec"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "sp-consensus"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "libp2p",
- "log",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "serde",
- "sp-api",
- "sp-core",
- "sp-inherents",
- "sp-runtime",
- "sp-state-machine",
- "sp-std",
- "sp-trie",
- "sp-utils",
- "sp-version",
- "substrate-prometheus-endpoint",
- "wasm-timer",
-]
-
-[[package]]
-name = "sp-consensus-aura"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "sp-api",
- "sp-application-crypto",
- "sp-inherents",
- "sp-runtime",
- "sp-std",
- "sp-timestamp",
-]
-
-[[package]]
-name = "sp-consensus-babe"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "merlin",
- "parity-scale-codec",
- "sp-api",
- "sp-application-crypto",
- "sp-consensus",
- "sp-consensus-slots",
- "sp-consensus-vrf",
- "sp-core",
- "sp-inherents",
- "sp-runtime",
- "sp-std",
- "sp-timestamp",
-]
-
-[[package]]
-name = "sp-consensus-slots"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "sp-runtime",
-]
-
-[[package]]
-name = "sp-consensus-vrf"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "schnorrkel",
- "sp-core",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "sp-core"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "base58",
- "blake2-rfc",
- "byteorder 1.3.4",
- "derive_more",
- "dyn-clonable",
- "ed25519-dalek",
- "futures 0.3.8",
- "hash-db",
- "hash256-std-hasher",
- "hex",
- "impl-serde",
- "lazy_static",
- "libsecp256k1",
- "log",
- "merlin",
- "num-traits",
- "parity-scale-codec",
- "parity-util-mem",
- "parking_lot 0.10.2",
- "primitive-types",
- "rand 0.7.3",
- "regex",
- "schnorrkel",
- "secrecy",
- "serde",
- "sha2 0.8.2",
- "sp-debug-derive",
- "sp-externalities",
- "sp-runtime-interface",
- "sp-std",
- "sp-storage",
- "substrate-bip39",
- "tiny-bip39",
- "tiny-keccak",
- "twox-hash",
- "wasmi",
- "zeroize",
-]
-
-[[package]]
-name = "sp-database"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "kvdb",
- "parking_lot 0.10.2",
-]
-
-[[package]]
-name = "sp-debug-derive"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "sp-externalities"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "environmental",
- "parity-scale-codec",
- "sp-std",
- "sp-storage",
-]
-
-[[package]]
-name = "sp-finality-grandpa"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "finality-grandpa",
- "log",
- "parity-scale-codec",
- "serde",
- "sp-api",
- "sp-application-crypto",
- "sp-core",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "sp-finality-tracker"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "sp-inherents",
- "sp-std",
-]
-
-[[package]]
-name = "sp-inherents"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "sp-core",
- "sp-std",
-]
-
-[[package]]
-name = "sp-io"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "futures 0.3.8",
- "hash-db",
- "libsecp256k1",
- "log",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "sp-core",
- "sp-externalities",
- "sp-runtime-interface",
- "sp-state-machine",
- "sp-std",
- "sp-tracing",
- "sp-trie",
- "sp-wasm-interface",
- "tracing",
- "tracing-core",
-]
-
-[[package]]
-name = "sp-keyring"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "lazy_static",
- "sp-core",
- "sp-runtime",
- "strum 0.16.0",
-]
-
-[[package]]
-name = "sp-npos-elections"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "serde",
- "sp-arithmetic",
- "sp-npos-elections-compact",
- "sp-std",
-]
-
-[[package]]
-name = "sp-npos-elections-compact"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "sp-offchain"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "sp-api",
- "sp-core",
- "sp-runtime",
-]
-
-[[package]]
-name = "sp-panic-handler"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "backtrace",
- "log",
-]
-
-[[package]]
-name = "sp-rpc"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "serde",
- "sp-core",
-]
-
-[[package]]
-name = "sp-runtime"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "either",
- "hash256-std-hasher",
- "impl-trait-for-tuples",
- "log",
- "parity-scale-codec",
- "parity-util-mem",
- "paste",
- "rand 0.7.3",
- "serde",
- "sp-application-crypto",
- "sp-arithmetic",
- "sp-core",
- "sp-inherents",
- "sp-io",
- "sp-std",
-]
-
-[[package]]
-name = "sp-runtime-interface"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "primitive-types",
- "sp-externalities",
- "sp-runtime-interface-proc-macro",
- "sp-std",
- "sp-storage",
- "sp-tracing",
- "sp-wasm-interface",
- "static_assertions",
-]
-
-[[package]]
-name = "sp-runtime-interface-proc-macro"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "Inflector",
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "sp-serializer"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "sp-session"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "sp-api",
- "sp-core",
- "sp-runtime",
- "sp-staking",
- "sp-std",
-]
-
-[[package]]
-name = "sp-staking"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "parity-scale-codec",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "sp-state-machine"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "hash-db",
- "log",
- "num-traits",
- "parity-scale-codec",
- "parking_lot 0.10.2",
- "rand 0.7.3",
- "smallvec 1.4.2",
- "sp-core",
- "sp-externalities",
- "sp-panic-handler",
- "sp-std",
- "sp-trie",
- "trie-db",
- "trie-root",
-]
-
-[[package]]
-name = "sp-std"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-
-[[package]]
-name = "sp-storage"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "impl-serde",
- "parity-scale-codec",
- "ref-cast",
- "serde",
- "sp-debug-derive",
- "sp-std",
-]
-
-[[package]]
-name = "sp-timestamp"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "impl-trait-for-tuples",
- "parity-scale-codec",
- "sp-api",
- "sp-inherents",
- "sp-runtime",
- "sp-std",
- "wasm-timer",
-]
-
-[[package]]
-name = "sp-tracing"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "log",
- "parity-scale-codec",
- "sp-std",
- "tracing",
- "tracing-core",
- "tracing-subscriber",
-]
-
-[[package]]
-name = "sp-transaction-pool"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "derive_more",
- "futures 0.3.8",
- "log",
- "parity-scale-codec",
- "serde",
- "sp-api",
- "sp-blockchain",
- "sp-runtime",
-]
-
-[[package]]
-name = "sp-trie"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "hash-db",
- "memory-db",
- "parity-scale-codec",
- "sp-core",
- "sp-std",
- "trie-db",
- "trie-root",
-]
-
-[[package]]
-name = "sp-utils"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "futures 0.3.8",
- "futures-core",
- "futures-timer 3.0.2",
- "lazy_static",
- "prometheus",
-]
-
-[[package]]
-name = "sp-version"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "impl-serde",
- "parity-scale-codec",
- "serde",
- "sp-runtime",
- "sp-std",
-]
-
-[[package]]
-name = "sp-wasm-interface"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "impl-trait-for-tuples",
- "parity-scale-codec",
- "sp-std",
- "wasmi",
-]
-
-[[package]]
-name = "spin"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
-
-[[package]]
-name = "stable_deref_trait"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
-
-[[package]]
-name = "static_assertions"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
-
-[[package]]
-name = "statrs"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10102ac8d55e35db2b3fafc26f81ba8647da2e15879ab686a67e6d19af2685e8"
-dependencies = [
- "rand 0.5.6",
-]
-
-[[package]]
-name = "stream-cipher"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c80e15f898d8d8f25db24c253ea615cc14acf418ff307822995814e7d42cfa89"
-dependencies = [
- "block-cipher",
- "generic-array 0.14.4",
-]
-
-[[package]]
-name = "string"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
-dependencies = [
- "bytes 0.4.12",
-]
-
-[[package]]
-name = "strsim"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
-
-[[package]]
-name = "structopt"
-version = "0.3.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "126d630294ec449fae0b16f964e35bf3c74f940da9dca17ee9b905f7b3112eb8"
-dependencies = [
- "clap",
- "lazy_static",
- "structopt-derive",
-]
-
-[[package]]
-name = "structopt-derive"
-version = "0.4.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65e51c492f9e23a220534971ff5afc14037289de430e3c83f9daf6a1b6ae91e8"
-dependencies = [
- "heck",
- "proc-macro-error",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "strum"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6138f8f88a16d90134763314e3fc76fa3ed6a7db4725d6acf9a3ef95a3188d22"
-dependencies = [
- "strum_macros 0.16.0",
-]
-
-[[package]]
-name = "strum"
-version = "0.19.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b89a286a7e3b5720b9a477b23253bc50debac207c8d21505f8e70b36792f11b5"
-
-[[package]]
-name = "strum_macros"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81"
-dependencies = [
- "heck",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "strum_macros"
-version = "0.19.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e61bb0be289045cb80bfce000512e32d09f8337e54c186725da381377ad1f8d5"
-dependencies = [
- "heck",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "substrate-bip39"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bed6646a0159b9935b5d045611560eeef842b78d7adc3ba36f5ca325a13a0236"
-dependencies = [
- "hmac",
- "pbkdf2",
- "schnorrkel",
- "sha2 0.8.2",
- "zeroize",
-]
-
-[[package]]
-name = "substrate-browser-utils"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "chrono",
- "console_error_panic_hook",
- "console_log",
- "futures 0.1.30",
- "futures 0.3.8",
- "futures-timer 3.0.2",
- "js-sys",
- "kvdb-web",
- "libp2p-wasm-ext",
- "log",
- "rand 0.6.5",
- "rand 0.7.3",
- "sc-chain-spec",
- "sc-informant",
- "sc-network",
- "sc-service",
- "sp-database",
- "wasm-bindgen",
- "wasm-bindgen-futures",
-]
-
-[[package]]
-name = "substrate-build-script-utils"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "platforms",
-]
-
-[[package]]
-name = "substrate-frame-rpc-system"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "frame-system-rpc-runtime-api",
- "futures 0.3.8",
- "jsonrpc-core",
- "jsonrpc-core-client",
- "jsonrpc-derive",
- "log",
- "parity-scale-codec",
- "sc-client-api",
- "sc-rpc-api",
- "serde",
- "sp-api",
- "sp-block-builder",
- "sp-blockchain",
- "sp-core",
- "sp-runtime",
- "sp-transaction-pool",
-]
-
-[[package]]
-name = "substrate-prometheus-endpoint"
-version = "0.8.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "async-std",
- "derive_more",
- "futures-util",
- "hyper 0.13.9",
- "log",
- "prometheus",
- "tokio 0.2.22",
-]
-
-[[package]]
-name = "substrate-test-client"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "futures 0.1.30",
- "futures 0.3.8",
- "hash-db",
- "hex",
- "parity-scale-codec",
- "sc-client-api",
- "sc-client-db",
- "sc-consensus",
- "sc-executor",
- "sc-light",
- "sc-service",
- "serde",
- "serde_json",
- "sp-blockchain",
- "sp-consensus",
- "sp-core",
- "sp-keyring",
- "sp-runtime",
- "sp-state-machine",
-]
-
-[[package]]
-name = "substrate-test-runtime"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "cfg-if 0.1.10",
- "frame-executive",
- "frame-support",
- "frame-system",
- "frame-system-rpc-runtime-api",
- "log",
- "memory-db",
- "pallet-babe",
- "pallet-timestamp",
- "parity-scale-codec",
- "parity-util-mem",
- "sc-service",
- "serde",
- "sp-api",
- "sp-application-crypto",
- "sp-block-builder",
- "sp-consensus-aura",
- "sp-consensus-babe",
- "sp-core",
- "sp-externalities",
- "sp-finality-grandpa",
- "sp-inherents",
- "sp-io",
- "sp-keyring",
- "sp-offchain",
- "sp-runtime",
- "sp-runtime-interface",
- "sp-session",
- "sp-state-machine",
- "sp-std",
- "sp-transaction-pool",
- "sp-trie",
- "sp-version",
- "substrate-wasm-builder-runner",
- "trie-db",
-]
-
-[[package]]
-name = "substrate-test-runtime-client"
-version = "2.0.0"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-dependencies = [
- "futures 0.3.8",
- "parity-scale-codec",
- "sc-block-builder",
- "sc-client-api",
- "sc-consensus",
- "sc-light",
- "sc-service",
- "sp-api",
- "sp-blockchain",
- "sp-consensus",
- "sp-core",
- "sp-runtime",
- "substrate-test-client",
- "substrate-test-runtime",
-]
-
-[[package]]
-name = "substrate-wasm-builder-runner"
-version = "1.0.6"
-source = "git+https://github.com/paritytech/substrate.git?rev=a200cdb93c6af5763b9c7bf313fa708764ac88ca#a200cdb93c6af5763b9c7bf313fa708764ac88ca"
-
-[[package]]
-name = "subtle"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
-
-[[package]]
-name = "subtle"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd"
-
-[[package]]
-name = "syn"
-version = "1.0.48"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
-]
-
-[[package]]
-name = "synstructure"
-version = "0.12.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "unicode-xid",
-]
-
-[[package]]
-name = "take_mut"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
-
-[[package]]
-name = "tempfile"
-version = "3.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "rand 0.7.3",
- "redox_syscall",
- "remove_dir_all",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "termcolor"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
-name = "textwrap"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
-dependencies = [
- "unicode-width",
-]
-
-[[package]]
-name = "thiserror"
-version = "1.0.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e"
-dependencies = [
- "thiserror-impl",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "1.0.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "thread_local"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
-dependencies = [
- "lazy_static",
-]
-
-[[package]]
-name = "threadpool"
-version = "1.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
-dependencies = [
- "num_cpus",
-]
-
-[[package]]
-name = "time"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
-dependencies = [
- "libc",
- "wasi 0.10.0+wasi-snapshot-preview1",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "tiny-bip39"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2"
-dependencies = [
- "failure",
- "hmac",
- "once_cell 1.4.1",
- "pbkdf2",
- "rand 0.7.3",
- "rustc-hash",
- "sha2 0.8.2",
- "unicode-normalization",
-]
-
-[[package]]
-name = "tiny-keccak"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
-dependencies = [
- "crunchy",
-]
-
-[[package]]
-name = "tinyvec"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117"
-
-[[package]]
-name = "tokio"
-version = "0.1.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.30",
- "mio",
- "num_cpus",
- "tokio-codec",
- "tokio-current-thread",
- "tokio-executor 0.1.10",
- "tokio-fs",
- "tokio-io",
- "tokio-reactor",
- "tokio-sync 0.1.8",
- "tokio-tcp",
- "tokio-threadpool",
- "tokio-timer",
- "tokio-udp",
- "tokio-uds",
-]
-
-[[package]]
-name = "tokio"
-version = "0.2.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
-dependencies = [
- "bytes 0.5.6",
- "fnv",
- "futures-core",
- "iovec",
- "lazy_static",
- "libc",
- "memchr",
- "mio",
- "mio-uds",
- "num_cpus",
- "pin-project-lite",
- "signal-hook-registry",
- "slab",
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "tokio-buf"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46"
-dependencies = [
- "bytes 0.4.12",
- "either",
- "futures 0.1.30",
-]
-
-[[package]]
-name = "tokio-codec"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.30",
- "tokio-io",
-]
-
-[[package]]
-name = "tokio-current-thread"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e"
-dependencies = [
- "futures 0.1.30",
- "tokio-executor 0.1.10",
-]
-
-[[package]]
-name = "tokio-executor"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671"
-dependencies = [
- "crossbeam-utils 0.7.2",
- "futures 0.1.30",
-]
-
-[[package]]
-name = "tokio-executor"
-version = "0.2.0-alpha.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ee9ceecf69145923834ea73f32ba40c790fd877b74a7817dd0b089f1eb9c7c8"
-dependencies = [
- "futures-util-preview",
- "lazy_static",
- "tokio-sync 0.2.0-alpha.6",
-]
-
-[[package]]
-name = "tokio-fs"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4"
-dependencies = [
- "futures 0.1.30",
- "tokio-io",
- "tokio-threadpool",
-]
-
-[[package]]
-name = "tokio-io"
-version = "0.1.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.30",
- "log",
-]
-
-[[package]]
-name = "tokio-named-pipes"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d282d483052288b2308ba5ee795f5673b159c9bdf63c385a05609da782a5eae"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.30",
- "mio",
- "mio-named-pipes",
- "tokio 0.1.22",
-]
-
-[[package]]
-name = "tokio-reactor"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351"
-dependencies = [
- "crossbeam-utils 0.7.2",
- "futures 0.1.30",
- "lazy_static",
- "log",
- "mio",
- "num_cpus",
- "parking_lot 0.9.0",
- "slab",
- "tokio-executor 0.1.10",
- "tokio-io",
- "tokio-sync 0.1.8",
-]
-
-[[package]]
-name = "tokio-rustls"
-version = "0.14.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a"
-dependencies = [
- "futures-core",
- "rustls",
- "tokio 0.2.22",
- "webpki",
-]
-
-[[package]]
-name = "tokio-service"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162"
-dependencies = [
- "futures 0.1.30",
-]
-
-[[package]]
-name = "tokio-sync"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee"
-dependencies = [
- "fnv",
- "futures 0.1.30",
-]
-
-[[package]]
-name = "tokio-sync"
-version = "0.2.0-alpha.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f1aaeb685540f7407ea0e27f1c9757d258c7c6bf4e3eb19da6fc59b747239d2"
-dependencies = [
- "fnv",
- "futures-core-preview",
- "futures-util-preview",
-]
-
-[[package]]
-name = "tokio-tcp"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.30",
- "iovec",
- "mio",
- "tokio-io",
- "tokio-reactor",
-]
-
-[[package]]
-name = "tokio-threadpool"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89"
-dependencies = [
- "crossbeam-deque 0.7.3",
- "crossbeam-queue",
- "crossbeam-utils 0.7.2",
- "futures 0.1.30",
- "lazy_static",
- "log",
- "num_cpus",
- "slab",
- "tokio-executor 0.1.10",
-]
-
-[[package]]
-name = "tokio-timer"
-version = "0.2.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296"
-dependencies = [
- "crossbeam-utils 0.7.2",
- "futures 0.1.30",
- "slab",
- "tokio-executor 0.1.10",
-]
-
-[[package]]
-name = "tokio-udp"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.30",
- "log",
- "mio",
- "tokio-codec",
- "tokio-io",
- "tokio-reactor",
-]
-
-[[package]]
-name = "tokio-uds"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0"
-dependencies = [
- "bytes 0.4.12",
- "futures 0.1.30",
- "iovec",
- "libc",
- "log",
- "mio",
- "mio-uds",
- "tokio-codec",
- "tokio-io",
- "tokio-reactor",
-]
-
-[[package]]
-name = "tokio-util"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
-dependencies = [
- "bytes 0.5.6",
- "futures-core",
- "futures-sink",
- "log",
- "pin-project-lite",
- "tokio 0.2.22",
-]
-
-[[package]]
-name = "toml"
-version = "0.5.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "tower-service"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"
-
-[[package]]
-name = "tracing"
-version = "0.1.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27"
-dependencies = [
- "cfg-if 0.1.10",
- "log",
- "pin-project-lite",
- "tracing-attributes",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-attributes"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "tracing-core"
-version = "0.1.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f"
-dependencies = [
- "lazy_static",
-]
-
-[[package]]
-name = "tracing-futures"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c"
-dependencies = [
- "pin-project 0.4.27",
- "tracing",
-]
-
-[[package]]
-name = "tracing-log"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9"
-dependencies = [
- "lazy_static",
- "log",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-serde"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b"
-dependencies = [
- "serde",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-subscriber"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1fa8f0c8f4c594e4fc9debc1990deab13238077271ba84dd853d54902ee3401"
-dependencies = [
- "ansi_term 0.12.1",
- "chrono",
- "lazy_static",
- "matchers",
- "regex",
- "serde",
- "serde_json",
- "sharded-slab",
- "smallvec 1.4.2",
- "thread_local",
- "tracing",
- "tracing-core",
- "tracing-log",
- "tracing-serde",
-]
-
-[[package]]
-name = "treeline"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
-
-[[package]]
-name = "trie-db"
-version = "0.22.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e55f7ace33d6237e14137e386f4e1672e2a5c6bbc97fef9f438581a143971f0"
-dependencies = [
- "hash-db",
- "hashbrown 0.8.2",
- "log",
- "rustc-hex",
- "smallvec 1.4.2",
-]
-
-[[package]]
-name = "trie-root"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "652931506d2c1244d7217a70b99f56718a7b4161b37f04e7cd868072a99f68cd"
-dependencies = [
- "hash-db",
-]
-
-[[package]]
-name = "try-lock"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
-
-[[package]]
-name = "twox-hash"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59"
-dependencies = [
- "cfg-if 0.1.10",
- "rand 0.7.3",
- "static_assertions",
-]
-
-[[package]]
-name = "typenum"
-version = "1.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
-
-[[package]]
-name = "uint"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177"
-dependencies = [
- "byteorder 1.3.4",
- "crunchy",
- "rustc-hex",
- "static_assertions",
-]
-
-[[package]]
-name = "unicase"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
-dependencies = [
- "version_check",
-]
-
-[[package]]
-name = "unicode-bidi"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
-dependencies = [
- "matches",
-]
-
-[[package]]
-name = "unicode-normalization"
-version = "0.1.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
-dependencies = [
- "tinyvec",
-]
-
-[[package]]
-name = "unicode-segmentation"
-version = "1.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
-
-[[package]]
-name = "unicode-width"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
-
-[[package]]
-name = "universal-hash"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402"
-dependencies = [
- "generic-array 0.14.4",
- "subtle 2.3.0",
-]
-
-[[package]]
-name = "unsigned-varint"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "669d776983b692a906c881fcd0cfb34271a48e197e4d6cb8df32b05bfc3d3fa5"
-dependencies = [
- "bytes 0.5.6",
- "futures-io",
- "futures-util",
- "futures_codec",
-]
-
-[[package]]
-name = "unsigned-varint"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fdeedbf205afadfe39ae559b75c3240f24e257d0ca27e85f85cb82aa19ac35"
-dependencies = [
- "futures-io",
- "futures-util",
-]
-
-[[package]]
-name = "untrusted"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
-
-[[package]]
-name = "url"
-version = "1.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
-dependencies = [
- "idna 0.1.5",
- "matches",
- "percent-encoding 1.0.1",
-]
-
-[[package]]
-name = "url"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e"
-dependencies = [
- "form_urlencoded",
- "idna 0.2.0",
- "matches",
- "percent-encoding 2.1.0",
-]
-
-[[package]]
-name = "vcpkg"
-version = "0.2.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c"
-
-[[package]]
-name = "vec-arena"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d"
-
-[[package]]
-name = "vec_map"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
-
-[[package]]
-name = "version_check"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
-
-[[package]]
-name = "void"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
-
-[[package]]
-name = "waker-fn"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
-
-[[package]]
-name = "want"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230"
-dependencies = [
- "futures 0.1.30",
- "log",
- "try-lock",
-]
-
-[[package]]
-name = "want"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
-dependencies = [
- "log",
- "try-lock",
-]
-
-[[package]]
-name = "wasi"
-version = "0.9.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
-
-[[package]]
-name = "wasi"
-version = "0.10.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.68"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
-dependencies = [
- "cfg-if 0.1.10",
- "wasm-bindgen-macro",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.68"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
-dependencies = [
- "bumpalo",
- "lazy_static",
- "log",
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-futures"
-version = "0.4.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da"
-dependencies = [
- "cfg-if 0.1.10",
- "js-sys",
- "wasm-bindgen",
- "web-sys",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.68"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.68"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.68"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
-
-[[package]]
-name = "wasm-timer"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f"
-dependencies = [
- "futures 0.3.8",
- "js-sys",
- "parking_lot 0.11.0",
- "pin-utils",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
-]
-
-[[package]]
-name = "wasmi"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff"
-dependencies = [
- "libc",
- "memory_units",
- "num-rational",
- "num-traits",
- "parity-wasm",
- "wasmi-validation",
-]
-
-[[package]]
-name = "wasmi-validation"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93"
-dependencies = [
- "parity-wasm",
-]
-
-[[package]]
-name = "web-sys"
-version = "0.3.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "webpki"
-version = "0.21.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae"
-dependencies = [
- "ring",
- "untrusted",
-]
-
-[[package]]
-name = "webpki-roots"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4"
-dependencies = [
- "webpki",
-]
-
-[[package]]
-name = "webpki-roots"
-version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8eff4b7516a57307f9349c64bf34caa34b940b66fed4b2fb3136cb7386e5739"
-dependencies = [
- "webpki",
-]
-
-[[package]]
-name = "wepoll-sys"
-version = "3.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "which"
-version = "3.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "winapi"
-version = "0.2.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-build"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-util"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
-dependencies = [
- "winapi 0.3.9",
-]
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "ws2_32-sys"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
-dependencies = [
- "winapi 0.2.8",
- "winapi-build",
-]
-
-[[package]]
-name = "x25519-dalek"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "637ff90c9540fa3073bb577e65033069e4bae7c79d49d74aa3ffdf5342a53217"
-dependencies = [
- "curve25519-dalek 2.1.0",
- "rand_core 0.5.1",
- "zeroize",
-]
-
-[[package]]
-name = "x25519-dalek"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc614d95359fd7afc321b66d2107ede58b246b844cf5d8a0adcca413e439f088"
-dependencies = [
- "curve25519-dalek 3.0.0",
- "rand_core 0.5.1",
- "zeroize",
-]
-
-[[package]]
-name = "yamux"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aeb8c4043cac71c3c299dff107171c220d179492350ea198e109a414981b83c"
-dependencies = [
- "futures 0.3.8",
- "log",
- "nohash-hasher",
- "parking_lot 0.11.0",
- "rand 0.7.3",
- "static_assertions",
-]
-
-[[package]]
-name = "zeroize"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05f33972566adbd2d3588b0491eb94b98b43695c4ef897903470ede4f3f5a28a"
-dependencies = [
- "zeroize_derive",
-]
-
-[[package]]
-name = "zeroize_derive"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "synstructure",
-]

+ 3 - 3
build.sh

@@ -4,8 +4,8 @@ set -e
 
 yarn
 yarn workspace @joystream/types build
-yarn workspace cd-schemas generate:all
-yarn workspace cd-schemas build
+yarn workspace @joystream/cd-schemas generate:all
+yarn workspace @joystream/cd-schemas build
 yarn workspace @joystream/cli build
 yarn workspace query-node-root build
 yarn workspace storage-node build
@@ -52,4 +52,4 @@ do
 
    * )     break;;
   esac
-done
+done

+ 225 - 63
cli/README.md

@@ -87,17 +87,26 @@ When using the CLI for the first time there are a few common steps you might wan
 * [`joystream-cli content-directory:curatorGroups`](#joystream-cli-content-directorycuratorgroups)
 * [`joystream-cli content-directory:entities CLASSNAME [PROPERTIES]`](#joystream-cli-content-directoryentities-classname-properties)
 * [`joystream-cli content-directory:entity ID`](#joystream-cli-content-directoryentity-id)
+* [`joystream-cli content-directory:initialize`](#joystream-cli-content-directoryinitialize)
+* [`joystream-cli content-directory:removeCuratorFromGroup [GROUPID] [CURATORID]`](#joystream-cli-content-directoryremovecuratorfromgroup-groupid-curatorid)
 * [`joystream-cli content-directory:removeCuratorGroup [ID]`](#joystream-cli-content-directoryremovecuratorgroup-id)
+* [`joystream-cli content-directory:removeEntity ID`](#joystream-cli-content-directoryremoveentity-id)
 * [`joystream-cli content-directory:removeMaintainerFromClass [CLASSNAME] [GROUPID]`](#joystream-cli-content-directoryremovemaintainerfromclass-classname-groupid)
 * [`joystream-cli content-directory:setCuratorGroupStatus [ID] [STATUS]`](#joystream-cli-content-directorysetcuratorgroupstatus-id-status)
 * [`joystream-cli content-directory:updateClassPermissions [CLASSNAME]`](#joystream-cli-content-directoryupdateclasspermissions-classname)
 * [`joystream-cli council:info`](#joystream-cli-councilinfo)
 * [`joystream-cli help [COMMAND]`](#joystream-cli-help-command)
 * [`joystream-cli media:createChannel`](#joystream-cli-mediacreatechannel)
+* [`joystream-cli media:curateContent`](#joystream-cli-mediacuratecontent)
+* [`joystream-cli media:featuredVideos`](#joystream-cli-mediafeaturedvideos)
 * [`joystream-cli media:myChannels`](#joystream-cli-mediamychannels)
 * [`joystream-cli media:myVideos`](#joystream-cli-mediamyvideos)
+* [`joystream-cli media:removeChannel [ID]`](#joystream-cli-mediaremovechannel-id)
+* [`joystream-cli media:removeVideo [ID]`](#joystream-cli-mediaremovevideo-id)
+* [`joystream-cli media:setFeaturedVideos VIDEOIDS`](#joystream-cli-mediasetfeaturedvideos-videoids)
 * [`joystream-cli media:updateChannel [ID]`](#joystream-cli-mediaupdatechannel-id)
 * [`joystream-cli media:updateVideo [ID]`](#joystream-cli-mediaupdatevideo-id)
+* [`joystream-cli media:updateVideoLicense [ID]`](#joystream-cli-mediaupdatevideolicense-id)
 * [`joystream-cli media:uploadVideo FILEPATH`](#joystream-cli-mediauploadvideo-filepath)
 * [`joystream-cli working-groups:application WGAPPLICATIONID`](#joystream-cli-working-groupsapplication-wgapplicationid)
 * [`joystream-cli working-groups:createOpening`](#joystream-cli-working-groupscreateopening)
@@ -109,6 +118,7 @@ When using the CLI for the first time there are a few common steps you might wan
 * [`joystream-cli working-groups:opening WGOPENINGID`](#joystream-cli-working-groupsopening-wgopeningid)
 * [`joystream-cli working-groups:openings`](#joystream-cli-working-groupsopenings)
 * [`joystream-cli working-groups:overview`](#joystream-cli-working-groupsoverview)
+* [`joystream-cli working-groups:setDefaultGroup`](#joystream-cli-working-groupssetdefaultgroup)
 * [`joystream-cli working-groups:slashWorker WORKERID`](#joystream-cli-working-groupsslashworker-workerid)
 * [`joystream-cli working-groups:startAcceptingApplications WGOPENINGID`](#joystream-cli-working-groupsstartacceptingapplications-wgopeningid)
 * [`joystream-cli working-groups:startReviewPeriod WGOPENINGID`](#joystream-cli-working-groupsstartreviewperiod-wgopeningid)
@@ -126,7 +136,8 @@ USAGE
   $ joystream-cli account:choose
 
 OPTIONS
-  --showSpecial  Whether to show special (DEV chain) accounts
+  -S, --showSpecial      Whether to show special (DEV chain) accounts
+  -a, --address=address  Select account by address (if available)
 ```
 
 _See code: [src/commands/account/choose.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/account/choose.ts)_
@@ -319,7 +330,9 @@ USAGE
 
 OPTIONS
   -i, --input=input    Path to JSON file to use as input (if not specified - the input can be provided interactively)
-  -o, --output=output  Path where the output JSON file should be placed (can be then reused as input)
+
+  -o, --output=output  Path to the directory where the output JSON file should be placed (the output file can be then
+                       reused as input)
 ```
 
 _See code: [src/commands/content-directory/addClassSchema.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/content-directory/addClassSchema.ts)_
@@ -389,7 +402,9 @@ USAGE
 
 OPTIONS
   -i, --input=input    Path to JSON file to use as input (if not specified - the input can be provided interactively)
-  -o, --output=output  Path where the output JSON file should be placed (can be then reused as input)
+
+  -o, --output=output  Path to the directory where the output JSON file should be placed (the output file can be then
+                       reused as input)
 ```
 
 _See code: [src/commands/content-directory/createClass.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/content-directory/createClass.ts)_
@@ -469,6 +484,35 @@ ARGUMENTS
 
 _See code: [src/commands/content-directory/entity.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/content-directory/entity.ts)_
 
+## `joystream-cli content-directory:initialize`
+
+Initialize content directory with input data from @joystream/content library or custom, provided one. Requires lead access.
+
+```
+USAGE
+  $ joystream-cli content-directory:initialize
+
+OPTIONS
+  --rootInputsDir=rootInputsDir  Custom inputs directory (must follow @joystream/content directory structure)
+```
+
+_See code: [src/commands/content-directory/initialize.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/content-directory/initialize.ts)_
+
+## `joystream-cli content-directory:removeCuratorFromGroup [GROUPID] [CURATORID]`
+
+Remove Curator from Curator Group.
+
+```
+USAGE
+  $ joystream-cli content-directory:removeCuratorFromGroup [GROUPID] [CURATORID]
+
+ARGUMENTS
+  GROUPID    ID of the Curator Group
+  CURATORID  ID of the curator
+```
+
+_See code: [src/commands/content-directory/removeCuratorFromGroup.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/content-directory/removeCuratorFromGroup.ts)_
+
 ## `joystream-cli content-directory:removeCuratorGroup [ID]`
 
 Remove existing Curator Group.
@@ -483,6 +527,23 @@ ARGUMENTS
 
 _See code: [src/commands/content-directory/removeCuratorGroup.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/content-directory/removeCuratorGroup.ts)_
 
+## `joystream-cli content-directory:removeEntity ID`
+
+Removes a single entity by id (can be executed in Member, Curator or Lead context)
+
+```
+USAGE
+  $ joystream-cli content-directory:removeEntity ID
+
+ARGUMENTS
+  ID  ID of the entity to remove
+
+OPTIONS
+  --context=(Member|Curator|Lead)  Actor context to execute the command in (Member/Curator/Lead)
+```
+
+_See code: [src/commands/content-directory/removeEntity.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/content-directory/removeEntity.ts)_
+
 ## `joystream-cli content-directory:removeMaintainerFromClass [CLASSNAME] [GROUPID]`
 
 Remove maintainer (Curator Group) from class.
@@ -565,11 +626,42 @@ USAGE
 
 OPTIONS
   -i, --input=input    Path to JSON file to use as input (if not specified - the input can be provided interactively)
-  -o, --output=output  Path where the output JSON file should be placed (can be then reused as input)
+
+  -o, --output=output  Path to the directory where the output JSON file should be placed (the output file can be then
+                       reused as input)
+
+  -y, --confirm        Confirm the provided input
 ```
 
 _See code: [src/commands/media/createChannel.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/media/createChannel.ts)_
 
+## `joystream-cli media:curateContent`
+
+Set the curation status of given entity (Channel/Video). Requires Curator access.
+
+```
+USAGE
+  $ joystream-cli media:curateContent
+
+OPTIONS
+  -c, --className=(Channel|Video)   (required) Name of the class of the entity to curate (Channel/Video)
+  -s, --status=(Accepted|Censored)  (required) Specifies the curation status (Accepted/Censored)
+  --id=id                           (required) ID of the entity to curate
+```
+
+_See code: [src/commands/media/curateContent.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/media/curateContent.ts)_
+
+## `joystream-cli media:featuredVideos`
+
+Show a list of currently featured videos.
+
+```
+USAGE
+  $ joystream-cli media:featuredVideos
+```
+
+_See code: [src/commands/media/featuredVideos.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/media/featuredVideos.ts)_
+
 ## `joystream-cli media:myChannels`
 
 Show the list of channels associated with current account's membership.
@@ -595,6 +687,51 @@ OPTIONS
 
 _See code: [src/commands/media/myVideos.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/media/myVideos.ts)_
 
+## `joystream-cli media:removeChannel [ID]`
+
+Removes a channel (required controller access).
+
+```
+USAGE
+  $ joystream-cli media:removeChannel [ID]
+
+ARGUMENTS
+  ID  ID of the Channel entity
+```
+
+_See code: [src/commands/media/removeChannel.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/media/removeChannel.ts)_
+
+## `joystream-cli media:removeVideo [ID]`
+
+Remove given Video entity and associated entities (VideoMedia, License) from content directory.
+
+```
+USAGE
+  $ joystream-cli media:removeVideo [ID]
+
+ARGUMENTS
+  ID  ID of the Video entity
+```
+
+_See code: [src/commands/media/removeVideo.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/media/removeVideo.ts)_
+
+## `joystream-cli media:setFeaturedVideos VIDEOIDS`
+
+Set currently featured videos (requires lead/maintainer access).
+
+```
+USAGE
+  $ joystream-cli media:setFeaturedVideos VIDEOIDS
+
+ARGUMENTS
+  VIDEOIDS  Comma-separated video ids
+
+OPTIONS
+  --add  If provided - currently featured videos will not be removed.
+```
+
+_See code: [src/commands/media/setFeaturedVideos.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/media/setFeaturedVideos.ts)_
+
 ## `joystream-cli media:updateChannel [ID]`
 
 Update one of the owned channels on Joystream (requires a membership).
@@ -608,14 +745,18 @@ ARGUMENTS
 
 OPTIONS
   -i, --input=input    Path to JSON file to use as input (if not specified - the input can be provided interactively)
-  -o, --output=output  Path where the output JSON file should be placed (can be then reused as input)
+
+  -o, --output=output  Path to the directory where the output JSON file should be placed (the output file can be then
+                       reused as input)
+
+  --asCurator          Provide this flag in order to use Curator context for the update
 ```
 
 _See code: [src/commands/media/updateChannel.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/media/updateChannel.ts)_
 
 ## `joystream-cli media:updateVideo [ID]`
 
-Update existing video information (requires a membership).
+Update existing video information (requires controller/maintainer access).
 
 ```
 USAGE
@@ -623,10 +764,27 @@ USAGE
 
 ARGUMENTS
   ID  ID of the Video to update
+
+OPTIONS
+  --asCurator  Specify in order to update the video as curator
 ```
 
 _See code: [src/commands/media/updateVideo.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/media/updateVideo.ts)_
 
+## `joystream-cli media:updateVideoLicense [ID]`
+
+Update existing video license (requires controller/maintainer access).
+
+```
+USAGE
+  $ joystream-cli media:updateVideoLicense [ID]
+
+ARGUMENTS
+  ID  ID of the Video
+```
+
+_See code: [src/commands/media/updateVideoLicense.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/media/updateVideoLicense.ts)_
+
 ## `joystream-cli media:uploadVideo FILEPATH`
 
 Upload a new Video to a channel (requires a membership).
@@ -641,6 +799,10 @@ ARGUMENTS
 OPTIONS
   -c, --channel=channel  ID of the channel to assign the video to (if omitted - one of the owned channels can be
                          selected from the list)
+
+  -i, --input=input      Path to JSON file to use as input (if not specified - the input can be provided interactively)
+
+  -y, --confirm          Confirm the provided input
 ```
 
 _See code: [src/commands/media/uploadVideo.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/media/uploadVideo.ts)_
@@ -657,9 +819,8 @@ ARGUMENTS
   WGAPPLICATIONID  Working Group Application ID
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/application.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/application.ts)_
@@ -673,19 +834,20 @@ USAGE
   $ joystream-cli working-groups:createOpening
 
 OPTIONS
-  -c, --createDraftOnly      If provided - the extrinsic will not be executed. Use this flag if you only want to create
-                             a draft.
+  -e, --edit                               If provided along with --input - launches in edit mode allowing to modify the
+                                           input before sending the exstinsic
 
-  -d, --useDraft             Whether to create the opening from existing draft.
-                             If provided without --draftName - the list of choices will be displayed.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 
-  -g, --group=group          (required) [default: storageProviders] The working group context in which the command
-                             should be executed
-                             Available values are: storageProviders, curators.
+  -i, --input=input                        Path to JSON file to use as input (if not specified - the input can be
+                                           provided interactively)
 
-  -n, --draftName=draftName  Name of the draft to create the opening from.
+  -o, --output=output                      Path to the file where the output JSON should be saved (this output can be
+                                           then reused as input)
 
-  -s, --skipPrompts          Whether to skip all prompts when adding from draft (will use all default values)
+  --dryRun                                 If provided along with --output - skips sending the actual extrinsic(can be
+                                           used to generate a "draft" which can be provided as input later)
 ```
 
 _See code: [src/commands/working-groups/createOpening.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/createOpening.ts)_
@@ -702,9 +864,8 @@ ARGUMENTS
   WORKERID  Worker ID
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/decreaseWorkerStake.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/decreaseWorkerStake.ts)_
@@ -721,9 +882,8 @@ ARGUMENTS
   WORKERID  Worker ID
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/evictWorker.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/evictWorker.ts)_
@@ -740,9 +900,8 @@ ARGUMENTS
   WGOPENINGID  Working Group Opening ID
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/fillOpening.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/fillOpening.ts)_
@@ -756,9 +915,8 @@ USAGE
   $ joystream-cli working-groups:increaseStake
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/increaseStake.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/increaseStake.ts)_
@@ -772,9 +930,8 @@ USAGE
   $ joystream-cli working-groups:leaveRole
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/leaveRole.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/leaveRole.ts)_
@@ -791,9 +948,8 @@ ARGUMENTS
   WGOPENINGID  Working Group Opening ID
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/opening.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/opening.ts)_
@@ -807,9 +963,8 @@ USAGE
   $ joystream-cli working-groups:openings
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/openings.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/openings.ts)_
@@ -823,13 +978,27 @@ USAGE
   $ joystream-cli working-groups:overview
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/overview.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/overview.ts)_
 
+## `joystream-cli working-groups:setDefaultGroup`
+
+Change the default group context for working-groups commands.
+
+```
+USAGE
+  $ joystream-cli working-groups:setDefaultGroup
+
+OPTIONS
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
+```
+
+_See code: [src/commands/working-groups/setDefaultGroup.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/setDefaultGroup.ts)_
+
 ## `joystream-cli working-groups:slashWorker WORKERID`
 
 Slashes given worker stake. Requires lead access.
@@ -842,9 +1011,8 @@ ARGUMENTS
   WORKERID  Worker ID
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/slashWorker.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/slashWorker.ts)_
@@ -861,9 +1029,8 @@ ARGUMENTS
   WGOPENINGID  Working Group Opening ID
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/startAcceptingApplications.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/startAcceptingApplications.ts)_
@@ -880,9 +1047,8 @@ ARGUMENTS
   WGOPENINGID  Working Group Opening ID
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/startReviewPeriod.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/startReviewPeriod.ts)_
@@ -899,9 +1065,8 @@ ARGUMENTS
   WGAPPLICATIONID  Working Group Application ID
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/terminateApplication.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/terminateApplication.ts)_
@@ -918,9 +1083,8 @@ ARGUMENTS
   ACCOUNTADDRESS  New reward account address (if omitted, one of the existing CLI accounts can be selected)
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/updateRewardAccount.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/updateRewardAccount.ts)_
@@ -937,9 +1101,8 @@ ARGUMENTS
   ACCOUNTADDRESS  New role account address (if omitted, one of the existing CLI accounts can be selected)
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/updateRoleAccount.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/updateRoleAccount.ts)_
@@ -956,9 +1119,8 @@ ARGUMENTS
   WORKERID  Worker ID
 
 OPTIONS
-  -g, --group=group  (required) [default: storageProviders] The working group context in which the command should be
-                     executed
-                     Available values are: storageProviders, curators.
+  -g, --group=(storageProviders|curators)  The working group context in which the command should be executed
+                                           Available values are: storageProviders, curators.
 ```
 
 _See code: [src/commands/working-groups/updateWorkerReward.ts](https://github.com/Joystream/joystream/blob/master/cli/src/commands/working-groups/updateWorkerReward.ts)_

+ 1 - 1
cli/package.json

@@ -9,7 +9,7 @@
   "bugs": "https://github.com/Joystream/joystream/issues",
   "dependencies": {
     "@apidevtools/json-schema-ref-parser": "^9.0.6",
-    "@ffmpeg-installer/ffmpeg": "^1.0.20",
+    "@ffprobe-installer/ffprobe": "^1.1.0",
     "@joystream/types": "^0.14.0",
     "@oclif/command": "^1.5.19",
     "@oclif/config": "^1.14.0",

+ 0 - 3
cli/src/@types/@ffmpeg-installer/ffmpeg/index.d.ts

@@ -1,3 +0,0 @@
-declare module '@ffmpeg-installer/ffmpeg' {
-  export const path: string
-}

+ 3 - 0
cli/src/@types/@ffprobe-installer/ffprobe/index.d.ts

@@ -0,0 +1,3 @@
+declare module '@ffprobe-installer/ffprobe' {
+  export const path: string
+}

+ 5 - 2
cli/src/base/AccountsCommandBase.ts

@@ -177,8 +177,11 @@ export default abstract class AccountsCommandBase extends ApiCommandBase {
     return password
   }
 
-  async requireConfirmation(message = 'Are you sure you want to execute this action?'): Promise<void> {
-    const { confirmed } = await inquirer.prompt([{ type: 'confirm', name: 'confirmed', message, default: false }])
+  async requireConfirmation(
+    message = 'Are you sure you want to execute this action?',
+    defaultVal = false
+  ): Promise<void> {
+    const { confirmed } = await inquirer.prompt([{ type: 'confirm', name: 'confirmed', message, default: defaultVal }])
     if (!confirmed) this.exit(ExitCodes.OK)
   }
 

+ 33 - 13
cli/src/base/ContentDirectoryCommandBase.ts

@@ -1,7 +1,7 @@
 import ExitCodes from '../ExitCodes'
 import { WorkingGroups } from '../Types'
-import { ReferenceProperty } from 'cd-schemas/types/extrinsics/AddClassSchema'
-import { FlattenRelations } from 'cd-schemas/types/utility'
+import { ReferenceProperty } from '@joystream/cd-schemas/types/extrinsics/AddClassSchema'
+import { FlattenRelations } from '@joystream/cd-schemas/types/utility'
 import { BOOL_PROMPT_OPTIONS } from '../helpers/prompting'
 import {
   Class,
@@ -11,10 +11,13 @@ import {
   Entity,
   EntityId,
   Actor,
+  PropertyType,
 } from '@joystream/types/content-directory'
 import { Worker } from '@joystream/types/working-group'
 import { CLIError } from '@oclif/errors'
 import { Codec } from '@polkadot/types/types'
+import AbstractInt from '@polkadot/types/codec/AbstractInt'
+import { AnyJson } from '@polkadot/types/types/helpers'
 import _ from 'lodash'
 import { RolesCommandBase } from './WorkingGroupsCommandBase'
 import { createType } from '@joystream/types'
@@ -24,6 +27,8 @@ import { flags } from '@oclif/command'
 const CONTEXTS = ['Member', 'Curator', 'Lead'] as const
 type Context = typeof CONTEXTS[number]
 
+type ParsedPropertyValue = { value: Codec | null; type: PropertyType['type']; subtype: PropertyType['subtype'] }
+
 /**
  * Abstract base class for commands related to content directory
  */
@@ -234,14 +239,14 @@ export default abstract class ContentDirectoryCommandBase extends RolesCommandBa
     }
 
     if (requireSchema && !entity.supported_schemas.toArray().length) {
-      this.error(`${requiredClass || ''}Entity of id ${id} has no schema support added!`)
+      this.error(`${requiredClass || ''} entity of id ${id} has no schema support added!`)
     }
 
     return entity
   }
 
-  async getAndParseKnownEntity<T>(id: string | number): Promise<FlattenRelations<T>> {
-    const entity = await this.getEntity(id)
+  async getAndParseKnownEntity<T>(id: string | number, className?: string): Promise<FlattenRelations<T>> {
+    const entity = await this.getEntity(id, className)
     return this.parseToKnownEntityJson<T>(entity)
   }
 
@@ -278,7 +283,7 @@ export default abstract class ContentDirectoryCommandBase extends RolesCommandBa
       choices: entityEntries.map(([id, entity]) => {
         const parsedEntityPropertyValues = this.parseEntityPropertyValues(entity, entityClass)
         return {
-          name: (propName && parsedEntityPropertyValues[propName]?.value.toString()) || `ID:${id.toString()}`,
+          name: (propName && parsedEntityPropertyValues[propName]?.value?.toString()) || `ID:${id.toString()}`,
           value: id.toString(), // With numbers there are issues with "default"
         }
       }),
@@ -298,31 +303,46 @@ export default abstract class ContentDirectoryCommandBase extends RolesCommandBa
     return (await this.promptForEntityEntry(message, className, propName, ownerMemberId, defaultId))[0].toNumber()
   }
 
+  parseStoredPropertyInnerValue(value: Codec | null): AnyJson {
+    if (value === null) {
+      return null
+    }
+
+    if (value instanceof AbstractInt) {
+      return value.toNumber() // Integers (signed ones) are by default converted to hex when using .toJson()
+    }
+
+    return value.toJSON()
+  }
+
   parseEntityPropertyValues(
     entity: Entity,
     entityClass: Class,
     includedProperties?: string[]
-  ): Record<string, { value: Codec; type: string }> {
+  ): Record<string, ParsedPropertyValue> {
     const { properties } = entityClass
     return Array.from(entity.getField('values').entries()).reduce((columns, [propId, propValue]) => {
       const prop = properties[propId.toNumber()]
       const propName = prop.name.toString()
       const included = !includedProperties || includedProperties.some((p) => p.toLowerCase() === propName.toLowerCase())
+      const { type: propType, subtype: propSubtype } = prop.property_type
 
       if (included) {
         columns[propName] = {
-          value: propValue.getValue(),
-          type: `${prop.property_type.type}<${prop.property_type.subtype}>`,
+          // If type doesn't match (Boolean(false) for optional fields case) - use "null" as value
+          value: propType !== propValue.type || propSubtype !== propValue.subtype ? null : propValue.getValue(),
+          type: propType,
+          subtype: propSubtype,
         }
       }
       return columns
-    }, {} as Record<string, { value: Codec; type: string }>)
+    }, {} as Record<string, ParsedPropertyValue>)
   }
 
   async parseToKnownEntityJson<T>(entity: Entity): Promise<FlattenRelations<T>> {
     const entityClass = (await this.classEntryByNameOrId(entity.class_id.toString()))[1]
     return (_.mapValues(this.parseEntityPropertyValues(entity, entityClass), (v) =>
-      v.type !== 'Single<Bool>' && v.value.toJSON() === false ? null : v.value.toJSON()
+      this.parseStoredPropertyInnerValue(v.value)
     ) as unknown) as FlattenRelations<T>
   }
 
@@ -337,7 +357,7 @@ export default abstract class ContentDirectoryCommandBase extends RolesCommandBa
     const defaultValues = entityClass.properties
       .map((p) => p.name.toString())
       .reduce((d, propName) => {
-        if (includedProps?.includes(propName)) {
+        if (!includedProps || includedProps.includes(propName)) {
           d[propName] = chalk.grey('[not set]')
         }
         return d
@@ -349,7 +369,7 @@ export default abstract class ContentDirectoryCommandBase extends RolesCommandBa
         'ID': id.toString(),
         ...defaultValues,
         ..._.mapValues(this.parseEntityPropertyValues(entity, entityClass, includedProps), (v) =>
-          v.value.toJSON() === false && v.type !== 'Single<Bool>' ? chalk.grey('[not set]') : v.value.toString()
+          v.value === null ? chalk.grey('[not set]') : v.value.toString()
         ),
       }))
     )) as Record<string, string>[]

+ 10 - 5
cli/src/base/MediaCommandBase.ts

@@ -1,5 +1,5 @@
 import ContentDirectoryCommandBase from './ContentDirectoryCommandBase'
-import { VideoEntity } from 'cd-schemas/types/entities'
+import { VideoEntity, KnownLicenseEntity, LicenseEntity } from '@joystream/cd-schemas/types/entities'
 import fs from 'fs'
 import { DistinctQuestion } from 'inquirer'
 import path from 'path'
@@ -12,7 +12,7 @@ const MAX_USER_LICENSE_CONTENT_LENGTH = 4096
  */
 export default abstract class MediaCommandBase extends ContentDirectoryCommandBase {
   async promptForNewLicense(): Promise<VideoEntity['license']> {
-    let license: VideoEntity['license']
+    let licenseInput: LicenseEntity
     const licenseType: 'known' | 'custom' = await this.simplePrompt({
       type: 'list',
       message: 'Choose license type',
@@ -22,7 +22,12 @@ export default abstract class MediaCommandBase extends ContentDirectoryCommandBa
       ],
     })
     if (licenseType === 'known') {
-      license = { new: { knownLicense: await this.promptForEntityId('Choose License', 'KnownLicense', 'code') } }
+      const [id, knownLicenseEntity] = await this.promptForEntityEntry('Choose License', 'KnownLicense', 'code')
+      const knownLicense = await this.parseToKnownEntityJson<KnownLicenseEntity>(knownLicenseEntity)
+      licenseInput = { knownLicense: id.toNumber() }
+      if (knownLicense.attributionRequired) {
+        licenseInput.attribution = await this.simplePrompt({ message: 'Attribution' })
+      }
     } else {
       let licenseContent: null | string = null
       while (licenseContent === null) {
@@ -38,10 +43,10 @@ export default abstract class MediaCommandBase extends ContentDirectoryCommandBa
           licenseContent = null
         }
       }
-      license = { new: { userDefinedLicense: { new: { content: licenseContent } } } }
+      licenseInput = { userDefinedLicense: { new: { content: licenseContent } } }
     }
 
-    return license
+    return { new: licenseInput }
   }
 
   async promptForPublishedBeforeJoystream(current?: number | null): Promise<number | null> {

+ 19 - 4
cli/src/commands/account/choose.ts

@@ -9,13 +9,19 @@ export default class AccountChoose extends AccountsCommandBase {
   static flags = {
     showSpecial: flags.boolean({
       description: 'Whether to show special (DEV chain) accounts',
+      char: 'S',
+      required: false,
+    }),
+    address: flags.string({
+      description: 'Select account by address (if available)',
+      char: 'a',
       required: false,
     }),
   }
 
   async run() {
-    const { showSpecial } = this.parse(AccountChoose).flags
-    const accounts: NamedKeyringPair[] = this.fetchAccounts(showSpecial)
+    const { showSpecial, address } = this.parse(AccountChoose).flags
+    const accounts: NamedKeyringPair[] = this.fetchAccounts(!!address || showSpecial)
     const selectedAccount: NamedKeyringPair | null = this.getSelectedAccount()
 
     this.log(chalk.white(`Found ${accounts.length} existing accounts...\n`))
@@ -25,9 +31,18 @@ export default class AccountChoose extends AccountsCommandBase {
       this.exit(ExitCodes.NoAccountFound)
     }
 
-    const choosenAccount: NamedKeyringPair = await this.promptForAccount(accounts, selectedAccount)
+    let choosenAccount: NamedKeyringPair
+    if (address) {
+      const matchingAccount = accounts.find((a) => a.address === address)
+      if (!matchingAccount) {
+        this.error(`No matching account found by address: ${address}`, { exit: ExitCodes.InvalidInput })
+      }
+      choosenAccount = matchingAccount
+    } else {
+      choosenAccount = await this.promptForAccount(accounts, selectedAccount)
+    }
 
     await this.setSelectedAccount(choosenAccount)
-    this.log(chalk.greenBright('\nAccount switched!'))
+    this.log(chalk.greenBright(`\nAccount switched to ${chalk.white(choosenAccount.address)}!`))
   }
 }

+ 3 - 3
cli/src/commands/content-directory/addClassSchema.ts

@@ -1,7 +1,7 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
-import AddClassSchemaSchema from 'cd-schemas/schemas/extrinsics/AddClassSchema.schema.json'
-import { AddClassSchema } from 'cd-schemas/types/extrinsics/AddClassSchema'
-import { InputParser } from 'cd-schemas'
+import AddClassSchemaSchema from '@joystream/cd-schemas/schemas/extrinsics/AddClassSchema.schema.json'
+import { AddClassSchema } from '@joystream/cd-schemas/types/extrinsics/AddClassSchema'
+import { InputParser } from '@joystream/cd-schemas'
 import { JsonSchemaPrompter, JsonSchemaCustomPrompts } from '../../helpers/JsonSchemaPrompt'
 import { JSONSchema } from '@apidevtools/json-schema-ref-parser'
 import { IOFlags, getInputJson, saveOutputJson } from '../../helpers/InputOutput'

+ 3 - 3
cli/src/commands/content-directory/createClass.ts

@@ -1,7 +1,7 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
-import CreateClassSchema from 'cd-schemas/schemas/extrinsics/CreateClass.schema.json'
-import { CreateClass } from 'cd-schemas/types/extrinsics/CreateClass'
-import { InputParser } from 'cd-schemas'
+import CreateClassSchema from '@joystream/cd-schemas/schemas/extrinsics/CreateClass.schema.json'
+import { CreateClass } from '@joystream/cd-schemas/types/extrinsics/CreateClass'
+import { InputParser } from '@joystream/cd-schemas'
 import { JsonSchemaPrompter, JsonSchemaCustomPrompts } from '../../helpers/JsonSchemaPrompt'
 import { JSONSchema } from '@apidevtools/json-schema-ref-parser'
 import { IOFlags, getInputJson, saveOutputJson } from '../../helpers/InputOutput'

+ 2 - 2
cli/src/commands/content-directory/entity.ts

@@ -36,8 +36,8 @@ export default class EntityCommand extends ContentDirectoryCommandBase {
       _.mapValues(
         propertyValues,
         (v) =>
-          (v.value.toJSON() === false && v.type !== 'Single<Bool>' ? chalk.grey('[not set]') : v.value.toString()) +
-          ` ${chalk.green(`${v.type}`)}`
+          (v.value === null ? chalk.grey('[not set]') : v.value.toString()) +
+          ` ${chalk.green(`${v.type}<${v.subtype}>`)}`
       )
     )
   }

+ 15 - 8
cli/src/commands/content-directory/initialize.ts

@@ -1,21 +1,28 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
-import { CreateClass } from 'cd-schemas/types/extrinsics/CreateClass'
-import { getInputs, InputParser, ExtrinsicsHelper } from 'cd-schemas'
-import { AddClassSchema } from 'cd-schemas/types/extrinsics/AddClassSchema'
-import { EntityBatch } from 'cd-schemas/types/EntityBatch'
+import { InputParser, ExtrinsicsHelper, getInitializationInputs } from '@joystream/cd-schemas'
+import { flags } from '@oclif/command'
 
 export default class InitializeCommand extends ContentDirectoryCommandBase {
   static description =
-    'Initialize content directory with input data from @joystream/content library. Requires lead access.'
+    'Initialize content directory with input data from @joystream/content library or custom, provided one. Requires lead access.'
+
+  static flags = {
+    rootInputsDir: flags.string({
+      required: false,
+      description: 'Custom inputs directory (must follow @joystream/content directory structure)',
+    }),
+  }
 
   async run() {
     const account = await this.getRequiredSelectedAccount()
     await this.requireLead()
     await this.requestAccountDecoding(account)
 
-    const classInputs = getInputs<CreateClass>('classes').map(({ data }) => data)
-    const schemaInputs = getInputs<AddClassSchema>('schemas').map(({ data }) => data)
-    const entityBatchInputs = getInputs<EntityBatch>('entityBatches').map(({ data }) => data)
+    const {
+      flags: { rootInputsDir },
+    } = this.parse(InitializeCommand)
+
+    const { classInputs, schemaInputs, entityBatchInputs } = getInitializationInputs(rootInputsDir)
 
     const currentClasses = await this.getApi().availableClasses()
 

+ 2 - 2
cli/src/commands/content-directory/updateClassPermissions.ts

@@ -1,8 +1,8 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
-import CreateClassSchema from 'cd-schemas/schemas/extrinsics/CreateClass.schema.json'
+import CreateClassSchema from '@joystream/cd-schemas/schemas/extrinsics/CreateClass.schema.json'
 import chalk from 'chalk'
 import { JsonSchemaCustomPrompts, JsonSchemaPrompter } from '../../helpers/JsonSchemaPrompt'
-import { CreateClass } from 'cd-schemas/types/extrinsics/CreateClass'
+import { CreateClass } from '@joystream/cd-schemas/types/extrinsics/CreateClass'
 import { JSONSchema } from '@apidevtools/json-schema-ref-parser'
 
 export default class UpdateClassPermissionsCommand extends ContentDirectoryCommandBase {

+ 12 - 7
cli/src/commands/media/createChannel.ts

@@ -1,15 +1,19 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
-import ChannelEntitySchema from 'cd-schemas/schemas/entities/ChannelEntity.schema.json'
-import { ChannelEntity } from 'cd-schemas/types/entities/ChannelEntity'
-import { InputParser } from 'cd-schemas'
+import ChannelEntitySchema from '@joystream/cd-schemas/schemas/entities/ChannelEntity.schema.json'
+import { ChannelEntity } from '@joystream/cd-schemas/types/entities/ChannelEntity'
+import { InputParser } from '@joystream/cd-schemas'
 import { IOFlags, getInputJson, saveOutputJson } from '../../helpers/InputOutput'
 import { JSONSchema } from '@apidevtools/json-schema-ref-parser'
 import { JsonSchemaCustomPrompts, JsonSchemaPrompter } from '../../helpers/JsonSchemaPrompt'
 
+import { flags } from '@oclif/command'
+import _ from 'lodash'
+
 export default class CreateChannelCommand extends ContentDirectoryCommandBase {
   static description = 'Create a new channel on Joystream (requires a membership).'
   static flags = {
     ...IOFlags,
+    confirm: flags.boolean({ char: 'y', name: 'confirm', required: false, description: 'Confirm the provided input' }),
   }
 
   async run() {
@@ -21,7 +25,7 @@ export default class CreateChannelCommand extends ContentDirectoryCommandBase {
 
     const channelJsonSchema = (ChannelEntitySchema as unknown) as JSONSchema
 
-    const { input, output } = this.parse(CreateChannelCommand).flags
+    const { input, output, confirm } = this.parse(CreateChannelCommand).flags
 
     let inputJson = await getInputJson<ChannelEntity>(input, channelJsonSchema)
     if (!inputJson) {
@@ -32,14 +36,15 @@ export default class CreateChannelCommand extends ContentDirectoryCommandBase {
 
       const prompter = new JsonSchemaPrompter<ChannelEntity>(channelJsonSchema, undefined, customPrompts)
 
-      inputJson = await prompter.promptAll(true)
+      inputJson = await prompter.promptAll()
     }
 
     this.jsonPrettyPrint(JSON.stringify(inputJson))
-    const confirmed = await this.simplePrompt({ type: 'confirm', message: 'Do you confirm the provided input?' })
+    const confirmed =
+      confirm || (await this.simplePrompt({ type: 'confirm', message: 'Do you confirm the provided input?' }))
 
     if (confirmed) {
-      saveOutputJson(output, `${inputJson.title}Channel.json`, inputJson)
+      saveOutputJson(output, `${_.startCase(inputJson.handle)}Channel.json`, inputJson)
       const inputParser = InputParser.createWithKnownSchemas(this.getOriginalApi(), [
         {
           className: 'Channel',

+ 3 - 3
cli/src/commands/media/curateContent.ts

@@ -1,8 +1,8 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
-import { InputParser } from 'cd-schemas'
+import { InputParser } from '@joystream/cd-schemas'
 import { flags } from '@oclif/command'
-import { ChannelEntity } from 'cd-schemas/types/entities/ChannelEntity'
-import { VideoEntity } from 'cd-schemas/types/entities/VideoEntity'
+import { ChannelEntity } from '@joystream/cd-schemas/types/entities/ChannelEntity'
+import { VideoEntity } from '@joystream/cd-schemas/types/entities/VideoEntity'
 
 const CLASSES = ['Channel', 'Video'] as const
 const STATUSES = ['Accepted', 'Censored'] as const

+ 36 - 0
cli/src/commands/media/featuredVideos.ts

@@ -0,0 +1,36 @@
+import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
+import { displayTable } from '../../helpers/display'
+import { FeaturedVideoEntity, VideoEntity } from '@joystream/cd-schemas/types/entities'
+import chalk from 'chalk'
+
+export default class FeaturedVideosCommand extends ContentDirectoryCommandBase {
+  static description = 'Show a list of currently featured videos.'
+
+  async run() {
+    const featuredEntries = await this.entitiesByClassAndOwner('FeaturedVideo')
+    const featured = await Promise.all(
+      featuredEntries
+        .filter(([, entity]) => entity.supported_schemas.toArray().length) // Ignore FeaturedVideo entities without schema
+        .map(([, entity]) => this.parseToKnownEntityJson<FeaturedVideoEntity>(entity))
+    )
+
+    const videoIds: number[] = featured.map(({ video: videoId }) => videoId)
+
+    const videos = await Promise.all(videoIds.map((videoId) => this.getAndParseKnownEntity<VideoEntity>(videoId)))
+
+    if (videos.length) {
+      displayTable(
+        videos.map(({ title, channel }, index) => ({
+          featuredVideoEntityId: featuredEntries[index][0].toNumber(),
+          videoId: videoIds[index],
+          channelId: channel,
+          title,
+        })),
+        3
+      )
+      this.log(`\nTIP: Use ${chalk.bold('content-directory:entity ID')} command to see more details about given video`)
+    } else {
+      this.log(`No videos have been featured yet! Set some with ${chalk.bold('media:setFeaturedVideos')}`)
+    }
+  }
+}

+ 2 - 2
cli/src/commands/media/myChannels.ts

@@ -1,5 +1,5 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
-import { ChannelEntity } from 'cd-schemas/types/entities/ChannelEntity'
+import { ChannelEntity } from '@joystream/cd-schemas/types/entities/ChannelEntity'
 import { displayTable } from '../../helpers/display'
 import chalk from 'chalk'
 
@@ -9,7 +9,7 @@ export default class MyChannelsCommand extends ContentDirectoryCommandBase {
   async run() {
     const memberId = await this.getRequiredMemberId()
 
-    const props: (keyof ChannelEntity)[] = ['title', 'isPublic']
+    const props: (keyof ChannelEntity)[] = ['handle', 'isPublic']
 
     const list = await this.createEntityList('Channel', props, [], memberId)
 

+ 1 - 1
cli/src/commands/media/myVideos.ts

@@ -1,5 +1,5 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
-import { VideoEntity } from 'cd-schemas/types/entities/VideoEntity'
+import { VideoEntity } from '@joystream/cd-schemas/types/entities/VideoEntity'
 import { displayTable } from '../../helpers/display'
 import chalk from 'chalk'
 import { flags } from '@oclif/command'

+ 3 - 3
cli/src/commands/media/removeChannel.ts

@@ -1,7 +1,7 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
 import { Entity } from '@joystream/types/content-directory'
 import { createType } from '@joystream/types'
-import { ChannelEntity } from 'cd-schemas/types/entities'
+import { ChannelEntity } from '@joystream/cd-schemas/types/entities'
 
 export default class RemoveChannelCommand extends ContentDirectoryCommandBase {
   static description = 'Removes a channel (required controller access).'
@@ -29,13 +29,13 @@ export default class RemoveChannelCommand extends ContentDirectoryCommandBase {
       channelId = parseInt(id)
       channelEntity = await this.getEntity(channelId, 'Channel', memberId)
     } else {
-      const [id, channel] = await this.promptForEntityEntry('Select a channel to remove', 'Channel', 'title', memberId)
+      const [id, channel] = await this.promptForEntityEntry('Select a channel to remove', 'Channel', 'handle', memberId)
       channelId = id.toNumber()
       channelEntity = channel
     }
     const channel = await this.parseToKnownEntityJson<ChannelEntity>(channelEntity)
 
-    await this.requireConfirmation(`Are you sure you want to remove "${channel.title}" channel?`)
+    await this.requireConfirmation(`Are you sure you want to remove "${channel.handle}" channel?`)
 
     const api = this.getOriginalApi()
     this.log(`Removing Channel entity (ID: ${channelId})...`)

+ 1 - 1
cli/src/commands/media/removeVideo.ts

@@ -1,6 +1,6 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
 import { Entity } from '@joystream/types/content-directory'
-import { VideoEntity } from 'cd-schemas/types/entities'
+import { VideoEntity } from '@joystream/cd-schemas/types/entities'
 import { createType } from '@joystream/types'
 
 export default class RemoveVideoCommand extends ContentDirectoryCommandBase {

+ 79 - 0
cli/src/commands/media/setFeaturedVideos.ts

@@ -0,0 +1,79 @@
+import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
+import { VideoEntity } from '@joystream/cd-schemas/types/entities'
+import { InputParser, ExtrinsicsHelper } from '@joystream/cd-schemas'
+import { FlattenRelations } from '@joystream/cd-schemas/types/utility'
+import { flags } from '@oclif/command'
+import { createType } from '@joystream/types'
+
+export default class SetFeaturedVideosCommand extends ContentDirectoryCommandBase {
+  static description = 'Set currently featured videos (requires lead/maintainer access).'
+  static args = [
+    {
+      name: 'videoIds',
+      required: true,
+      description: 'Comma-separated video ids',
+    },
+  ]
+
+  static flags = {
+    add: flags.boolean({
+      description: 'If provided - currently featured videos will not be removed.',
+      required: false,
+    }),
+  }
+
+  async run() {
+    const account = await this.getRequiredSelectedAccount()
+    let actor = createType('Actor', { Lead: null })
+    try {
+      await this.getRequiredLead()
+    } catch (e) {
+      actor = await this.getCuratorContext(['FeaturedVideo'])
+    }
+
+    await this.requestAccountDecoding(account)
+
+    const {
+      args: { videoIds },
+      flags: { add },
+    } = this.parse(SetFeaturedVideosCommand)
+
+    const ids: number[] = videoIds.split(',').map((id: string) => parseInt(id))
+
+    const videos: [number, FlattenRelations<VideoEntity>][] = (
+      await Promise.all(ids.map((id) => this.getAndParseKnownEntity<VideoEntity>(id, 'Video')))
+    ).map((video, index) => [ids[index], video])
+
+    this.log(
+      `Featured videos that will ${add ? 'be added to' : 'replace'} existing ones:`,
+      videos.map(([id, { title }]) => ({ id, title }))
+    )
+
+    await this.requireConfirmation('Do you confirm the provided input?')
+
+    if (!add) {
+      const currentlyFeaturedIds = (await this.entitiesByClassAndOwner('FeaturedVideo')).map(([id]) => id.toNumber())
+      const removeTxs = currentlyFeaturedIds.map((id) =>
+        this.getOriginalApi().tx.contentDirectory.removeEntity(actor, id)
+      )
+
+      if (currentlyFeaturedIds.length) {
+        this.log(`Removing existing FeaturedVideo entities (${currentlyFeaturedIds.join(', ')})...`)
+
+        const txHelper = new ExtrinsicsHelper(this.getOriginalApi())
+        await txHelper.sendAndCheck(account, removeTxs, 'The removal of existing FeaturedVideo entities failed')
+      }
+    }
+
+    this.log('Adding new FeaturedVideo entities...')
+    const featuredVideoEntries = videos.map(([id]) => ({ video: id }))
+    const inputParser = InputParser.createWithKnownSchemas(this.getOriginalApi(), [
+      {
+        className: 'FeaturedVideo',
+        entries: featuredVideoEntries,
+      },
+    ])
+    const operations = await inputParser.getEntityBatchOperations()
+    await this.sendAndFollowNamedTx(account, 'contentDirectory', 'transaction', [actor, operations])
+  }
+}

+ 7 - 6
cli/src/commands/media/updateChannel.ts

@@ -1,13 +1,14 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
-import ChannelEntitySchema from 'cd-schemas/schemas/entities/ChannelEntity.schema.json'
-import { ChannelEntity } from 'cd-schemas/types/entities/ChannelEntity'
-import { InputParser } from 'cd-schemas'
+import ChannelEntitySchema from '@joystream/cd-schemas/schemas/entities/ChannelEntity.schema.json'
+import { ChannelEntity } from '@joystream/cd-schemas/types/entities/ChannelEntity'
+import { InputParser } from '@joystream/cd-schemas'
 import { IOFlags, getInputJson, saveOutputJson } from '../../helpers/InputOutput'
 import { JSONSchema } from '@apidevtools/json-schema-ref-parser'
 import { JsonSchemaCustomPrompts, JsonSchemaPrompter } from '../../helpers/JsonSchemaPrompt'
 import { Actor, Entity } from '@joystream/types/content-directory'
 import { flags } from '@oclif/command'
 import { createType } from '@joystream/types'
+import _ from 'lodash'
 
 export default class UpdateChannelCommand extends ContentDirectoryCommandBase {
   static description = 'Update one of the owned channels on Joystream (requires a membership).'
@@ -51,7 +52,7 @@ export default class UpdateChannelCommand extends ContentDirectoryCommandBase {
       channelId = parseInt(id)
       channelEntity = await this.getEntity(channelId, 'Channel', memberId)
     } else {
-      const [id, channel] = await this.promptForEntityEntry('Select a channel to update', 'Channel', 'title', memberId)
+      const [id, channel] = await this.promptForEntityEntry('Select a channel to update', 'Channel', 'handle', memberId)
       channelId = id.toNumber()
       channelEntity = channel
     }
@@ -80,14 +81,14 @@ export default class UpdateChannelCommand extends ContentDirectoryCommandBase {
 
       const prompter = new JsonSchemaPrompter<ChannelEntity>(channelJsonSchema, currentValues, customPrompts)
 
-      inputJson = await prompter.promptAll(true)
+      inputJson = await prompter.promptAll()
     }
 
     this.jsonPrettyPrint(JSON.stringify(inputJson))
     const confirmed = await this.simplePrompt({ type: 'confirm', message: 'Do you confirm the provided input?' })
 
     if (confirmed) {
-      saveOutputJson(output, `${inputJson.title}Channel.json`, inputJson)
+      saveOutputJson(output, `${_.startCase(inputJson.handle)}Channel.json`, inputJson)
       const inputParser = InputParser.createWithKnownSchemas(this.getOriginalApi())
       const updateOperations = await inputParser.getEntityUpdateOperations(inputJson, 'Channel', channelId)
       this.log('Sending the extrinsic...')

+ 4 - 4
cli/src/commands/media/updateVideo.ts

@@ -1,6 +1,6 @@
-import VideoEntitySchema from 'cd-schemas/schemas/entities/VideoEntity.schema.json'
-import { VideoEntity } from 'cd-schemas/types/entities/VideoEntity'
-import { InputParser } from 'cd-schemas'
+import VideoEntitySchema from '@joystream/cd-schemas/schemas/entities/VideoEntity.schema.json'
+import { VideoEntity } from '@joystream/cd-schemas/types/entities/VideoEntity'
+import { InputParser } from '@joystream/cd-schemas'
 import { JSONSchema } from '@apidevtools/json-schema-ref-parser'
 import { JsonSchemaCustomPrompts, JsonSchemaPrompter } from '../../helpers/JsonSchemaPrompt'
 import { Actor, Entity } from '@joystream/types/content-directory'
@@ -83,7 +83,7 @@ export default class UpdateVideoCommand extends MediaCommandBase {
       'category',
       'title',
       'description',
-      'thumbnailURL',
+      'thumbnailUrl',
       'duration',
       'isPublic',
       'isExplicit',

+ 2 - 2
cli/src/commands/media/updateVideoLicense.ts

@@ -1,6 +1,6 @@
 import MediaCommandBase from '../../base/MediaCommandBase'
-import { LicenseEntity, VideoEntity } from 'cd-schemas/types/entities'
-import { InputParser } from 'cd-schemas'
+import { LicenseEntity, VideoEntity } from '@joystream/cd-schemas/types/entities'
+import { InputParser } from '@joystream/cd-schemas'
 import { Entity } from '@joystream/types/content-directory'
 import { createType } from '@joystream/types'
 

+ 131 - 73
cli/src/commands/media/uploadVideo.ts

@@ -1,8 +1,8 @@
-import VideoEntitySchema from 'cd-schemas/schemas/entities/VideoEntity.schema.json'
-import VideoMediaEntitySchema from 'cd-schemas/schemas/entities/VideoMediaEntity.schema.json'
-import { VideoEntity } from 'cd-schemas/types/entities/VideoEntity'
-import { VideoMediaEntity } from 'cd-schemas/types/entities/VideoMediaEntity'
-import { InputParser } from 'cd-schemas'
+import VideoEntitySchema from '@joystream/cd-schemas/schemas/entities/VideoEntity.schema.json'
+import VideoMediaEntitySchema from '@joystream/cd-schemas/schemas/entities/VideoMediaEntity.schema.json'
+import { VideoEntity } from '@joystream/cd-schemas/types/entities/VideoEntity'
+import { VideoMediaEntity } from '@joystream/cd-schemas/types/entities/VideoMediaEntity'
+import { InputParser } from '@joystream/cd-schemas'
 import { JSONSchema } from '@apidevtools/json-schema-ref-parser'
 import { JsonSchemaPrompter } from '../../helpers/JsonSchemaPrompt'
 import { flags } from '@oclif/command'
@@ -17,14 +17,15 @@ import ipfsHttpClient from 'ipfs-http-client'
 import first from 'it-first'
 import last from 'it-last'
 import toBuffer from 'it-to-buffer'
-import ffmpegInstaller from '@ffmpeg-installer/ffmpeg'
+import ffprobeInstaller from '@ffprobe-installer/ffprobe'
 import ffmpeg from 'fluent-ffmpeg'
 import MediaCommandBase from '../../base/MediaCommandBase'
+import { getInputJson, validateInput, IOFlags } from '../../helpers/InputOutput'
 
-ffmpeg.setFfmpegPath(ffmpegInstaller.path)
+ffmpeg.setFfprobePath(ffprobeInstaller.path)
 
 const DATA_OBJECT_TYPE_ID = 1
-const MAX_FILE_SIZE = 500 * 1024 * 1024
+const MAX_FILE_SIZE = 2000 * 1024 * 1024
 
 type VideoMetadata = {
   width?: number
@@ -37,13 +38,14 @@ type VideoMetadata = {
 export default class UploadVideoCommand extends MediaCommandBase {
   static description = 'Upload a new Video to a channel (requires a membership).'
   static flags = {
-    // TODO: ...IOFlags, - providing input as json
+    input: IOFlags.input,
     channel: flags.integer({
       char: 'c',
       required: false,
       description:
         'ID of the channel to assign the video to (if omitted - one of the owned channels can be selected from the list)',
     }),
+    confirm: flags.boolean({ char: 'y', name: 'confirm', required: false, description: 'Confirm the provided input' }),
   }
 
   static args = [
@@ -217,6 +219,117 @@ export default class UploadVideoCommand extends MediaCommandBase {
     }
   }
 
+  private async promptForVideoInput(
+    channelId: number,
+    fileSize: number,
+    contentId: ContentId,
+    videoMetadata: VideoMetadata | null
+  ) {
+    // Set the defaults
+    const videoMediaDefaults: Partial<VideoMediaEntity> = {
+      pixelWidth: videoMetadata?.width,
+      pixelHeight: videoMetadata?.height,
+    }
+    const videoDefaults: Partial<VideoEntity> = {
+      duration: videoMetadata?.duration,
+      skippableIntroDuration: 0,
+    }
+
+    // Prompt for data
+    const videoJsonSchema = (VideoEntitySchema as unknown) as JSONSchema
+    const videoMediaJsonSchema = (VideoMediaEntitySchema as unknown) as JSONSchema
+
+    const videoMediaPrompter = new JsonSchemaPrompter<VideoMediaEntity>(videoMediaJsonSchema, videoMediaDefaults)
+    const videoPrompter = new JsonSchemaPrompter<VideoEntity>(videoJsonSchema, videoDefaults)
+
+    // Prompt for the data
+    const encodingSuggestion =
+      videoMetadata && videoMetadata.codecFullName ? ` (suggested: ${videoMetadata.codecFullName})` : ''
+    const encoding = await this.promptForEntityId(
+      `Choose Video encoding${encodingSuggestion}`,
+      'VideoMediaEncoding',
+      'name'
+    )
+    const { pixelWidth, pixelHeight } = await videoMediaPrompter.promptMultipleProps(['pixelWidth', 'pixelHeight'])
+    const language = await this.promptForEntityId('Choose Video language', 'Language', 'name')
+    const category = await this.promptForEntityId('Choose Video category', 'ContentCategory', 'name')
+    const videoProps = await videoPrompter.promptMultipleProps([
+      'title',
+      'description',
+      'thumbnailUrl',
+      'duration',
+      'isPublic',
+      'isExplicit',
+      'hasMarketing',
+      'skippableIntroDuration',
+    ])
+
+    const license = await videoPrompter.promptSingleProp('license', () => this.promptForNewLicense())
+    const publishedBeforeJoystream = await videoPrompter.promptSingleProp('publishedBeforeJoystream', () =>
+      this.promptForPublishedBeforeJoystream()
+    )
+
+    // Create final inputs
+    const videoMediaInput: VideoMediaEntity = {
+      encoding,
+      pixelWidth,
+      pixelHeight,
+      size: fileSize,
+      location: { new: { joystreamMediaLocation: { new: { dataObjectId: contentId.encode() } } } },
+    }
+    return {
+      ...videoProps,
+      channel: channelId,
+      language,
+      category,
+      license,
+      media: { new: videoMediaInput },
+      publishedBeforeJoystream,
+    }
+  }
+
+  private async getVideoInputFromFile(
+    filePath: string,
+    channelId: number,
+    fileSize: number,
+    contentId: ContentId,
+    videoMetadata: VideoMetadata | null
+  ) {
+    let videoInput = await getInputJson<any>(filePath)
+    if (typeof videoInput !== 'object' || videoInput === null) {
+      this.error('Invalid input json - expected an object', { exit: ExitCodes.InvalidInput })
+    }
+    const videoMediaDefaults: Partial<VideoMediaEntity> = {
+      pixelWidth: videoMetadata?.width,
+      pixelHeight: videoMetadata?.height,
+      size: fileSize,
+    }
+    const videoDefaults: Partial<VideoEntity> = {
+      channel: channelId,
+      duration: videoMetadata?.duration,
+    }
+    const inputVideoMedia =
+      videoInput.media && typeof videoInput.media === 'object' && (videoInput.media as any).new
+        ? (videoInput.media as any).new
+        : {}
+    videoInput = {
+      ...videoDefaults,
+      ...videoInput,
+      media: {
+        new: {
+          ...videoMediaDefaults,
+          ...inputVideoMedia,
+          location: { new: { joystreamMediaLocation: { new: { dataObjectId: contentId.encode() } } } },
+        },
+      },
+    }
+
+    const videoJsonSchema = (VideoEntitySchema as unknown) as JSONSchema
+    await validateInput(videoInput, videoJsonSchema)
+
+    return videoInput as VideoEntity
+  }
+
   async run() {
     const account = await this.getRequiredSelectedAccount()
     const memberId = await this.getRequiredMemberId()
@@ -226,7 +339,7 @@ export default class UploadVideoCommand extends MediaCommandBase {
 
     const {
       args: { filePath },
-      flags: { channel: inputChannelId },
+      flags: { channel: inputChannelId, input, confirm },
     } = this.parse(UploadVideoCommand)
 
     // Basic file validation
@@ -255,7 +368,7 @@ export default class UploadVideoCommand extends MediaCommandBase {
       channelId = await this.promptForEntityId(
         'Select a channel to publish the video under',
         'Channel',
-        'title',
+        'handle',
         memberId
       )
     } else {
@@ -303,71 +416,16 @@ export default class UploadVideoCommand extends MediaCommandBase {
 
     await this.uploadVideo(filePath, fileSize, uploadUrl)
 
-    // Prompting for the data:
-
-    // Set the defaults
-    const videoMediaDefaults: Partial<VideoMediaEntity> = {
-      pixelWidth: videoMetadata?.width,
-      pixelHeight: videoMetadata?.height,
-    }
-    const videoDefaults: Partial<VideoEntity> = {
-      duration: videoMetadata?.duration,
-      skippableIntroDuration: 0,
-    }
-    // Create prompting helpers
-    const videoJsonSchema = (VideoEntitySchema as unknown) as JSONSchema
-    const videoMediaJsonSchema = (VideoMediaEntitySchema as unknown) as JSONSchema
-
-    const videoMediaPrompter = new JsonSchemaPrompter<VideoMediaEntity>(videoMediaJsonSchema, videoMediaDefaults)
-    const videoPrompter = new JsonSchemaPrompter<VideoEntity>(videoJsonSchema, videoDefaults)
-
-    // Prompt for the data
-    const encodingSuggestion =
-      videoMetadata && videoMetadata.codecFullName ? ` (suggested: ${videoMetadata.codecFullName})` : ''
-    const encoding = await this.promptForEntityId(
-      `Choose Video encoding${encodingSuggestion}`,
-      'VideoMediaEncoding',
-      'name'
-    )
-    const { pixelWidth, pixelHeight } = await videoMediaPrompter.promptMultipleProps(['pixelWidth', 'pixelHeight'])
-    const language = await this.promptForEntityId('Choose Video language', 'Language', 'name')
-    const category = await this.promptForEntityId('Choose Video category', 'ContentCategory', 'name')
-    const videoProps = await videoPrompter.promptMultipleProps([
-      'title',
-      'description',
-      'thumbnailURL',
-      'duration',
-      'isPublic',
-      'isExplicit',
-      'hasMarketing',
-      'skippableIntroDuration',
-    ])
+    // No input, create prompting helpers
+    const videoInput = input
+      ? await this.getVideoInputFromFile(input, channelId, fileSize, contentId, videoMetadata)
+      : await this.promptForVideoInput(channelId, fileSize, contentId, videoMetadata)
 
-    const license = await videoPrompter.promptSingleProp('license', () => this.promptForNewLicense())
-    const publishedBeforeJoystream = await videoPrompter.promptSingleProp('publishedBeforeJoystream', () =>
-      this.promptForPublishedBeforeJoystream()
-    )
+    this.jsonPrettyPrint(JSON.stringify(videoInput))
 
-    // Create final inputs
-    const videoMediaInput: VideoMediaEntity = {
-      encoding,
-      pixelWidth,
-      pixelHeight,
-      size: fileSize,
-      location: { new: { joystreamMediaLocation: { new: { dataObjectId: contentId.encode() } } } },
+    if (!confirm) {
+      await this.requireConfirmation('Do you confirm the provided input?', true)
     }
-    const videoInput: VideoEntity = {
-      ...videoProps,
-      channel: channelId,
-      language,
-      category,
-      license,
-      media: { new: videoMediaInput },
-      publishedBeforeJoystream,
-    }
-
-    this.jsonPrettyPrint(JSON.stringify(videoInput))
-    await this.requireConfirmation('Do you confirm the provided input?')
 
     // Parse inputs into operations and send final extrinsic
     const inputParser = InputParser.createWithKnownSchemas(this.getOriginalApi(), [

+ 11 - 7
cli/src/helpers/InputOutput.ts

@@ -5,7 +5,7 @@ import fs from 'fs'
 import path from 'path'
 import Ajv from 'ajv'
 import $RefParser, { JSONSchema } from '@apidevtools/json-schema-ref-parser'
-import { getSchemasLocation } from 'cd-schemas'
+import { getSchemasLocation } from '@joystream/cd-schemas'
 import chalk from 'chalk'
 
 // Default schema path for resolving refs
@@ -39,12 +39,7 @@ export async function getInputJson<T>(inputPath?: string, schema?: JSONSchema, s
       throw new CLIError(`JSON parsing failed for file: ${inputPath}`, { exit: ExitCodes.InvalidInput })
     }
     if (schema) {
-      const ajv = new Ajv()
-      schema = await $RefParser.dereference(schemaPath || DEFAULT_SCHEMA_PATH, schema, {})
-      const valid = ajv.validate(schema, jsonObj) as boolean
-      if (!valid) {
-        throw new CLIError(`Input JSON file is not valid: ${ajv.errorsText()}`)
-      }
+      await validateInput(jsonObj, schema, schemaPath)
     }
 
     return jsonObj as T
@@ -53,6 +48,15 @@ export async function getInputJson<T>(inputPath?: string, schema?: JSONSchema, s
   return null
 }
 
+export async function validateInput(input: unknown, schema: JSONSchema, schemaPath?: string): Promise<void> {
+  const ajv = new Ajv({ allErrors: true })
+  schema = await $RefParser.dereference(schemaPath || DEFAULT_SCHEMA_PATH, schema, {})
+  const valid = ajv.validate(schema, input) as boolean
+  if (!valid) {
+    throw new CLIError(`Input JSON file is not valid: ${ajv.errorsText()}`)
+  }
+}
+
 export function saveOutputJson(outputPath: string | undefined, fileName: string, data: any): void {
   if (outputPath) {
     let outputFilePath = path.join(outputPath, fileName)

+ 40 - 35
cli/src/helpers/JsonSchemaPrompt.ts

@@ -4,7 +4,7 @@ import _ from 'lodash'
 import RefParser, { JSONSchema } from '@apidevtools/json-schema-ref-parser'
 import chalk from 'chalk'
 import { BOOL_PROMPT_OPTIONS } from './prompting'
-import { getSchemasLocation } from 'cd-schemas'
+import { getSchemasLocation } from '@joystream/cd-schemas'
 import path from 'path'
 
 type CustomPromptMethod = () => Promise<any>
@@ -106,7 +106,11 @@ export class JsonSchemaPrompter<JsonResult> {
     if (schema.oneOf) {
       const oneOf = schema.oneOf as JSONSchema[]
       const options = this.oneOfToOptions(oneOf, currentValue)
-      const { choosen } = await inquirer.prompt({ name: 'choosen', message: propDisplayName, type: 'list', ...options })
+      const choosen = await this.inquirerSinglePrompt({
+        message: propDisplayName,
+        type: 'list',
+        ...options,
+      })
       if (choosen !== options.default) {
         _.set(this.filledObject, propertyPath, undefined) // Clear any previous value if different variant selected
       }
@@ -128,18 +132,13 @@ export class JsonSchemaPrompter<JsonResult> {
         const required = allPropsRequired || (Array.isArray(schema.required) && schema.required.includes(pName))
 
         if (!required) {
-          confirmed = (
-            await inquirer.prompt([
-              {
-                message: `Do you want to provide optional ${chalk.greenBright(objectPropertyPath)}?`,
-                type: 'confirm',
-                name: 'confirmed',
-                default:
-                  _.get(this.filledObject, objectPropertyPath) !== undefined &&
-                  _.get(this.filledObject, objectPropertyPath) !== null,
-              },
-            ])
-          ).confirmed
+          confirmed = await this.inquirerSinglePrompt({
+            message: `Do you want to provide optional ${chalk.greenBright(objectPropertyPath)}?`,
+            type: 'confirm',
+            default:
+              _.get(this.filledObject, objectPropertyPath) !== undefined &&
+              _.get(this.filledObject, objectPropertyPath) !== null,
+          })
         }
         if (confirmed) {
           value[pName] = await this.prompt(pSchema, objectPropertyPath)
@@ -207,14 +206,11 @@ export class JsonSchemaPrompter<JsonResult> {
     let currItem = 0
     const result = []
     while (currItem < maxItems) {
-      const { next } = await inquirer.prompt([
-        {
-          ...BOOL_PROMPT_OPTIONS,
-          name: 'next',
-          message: `Do you want to add another item to ${this.propertyDisplayName(propertyPath)} array?`,
-          default: _.get(this.filledObject, `${propertyPath}[${currItem}]`) !== undefined,
-        },
-      ])
+      const next = await this.inquirerSinglePrompt({
+        ...BOOL_PROMPT_OPTIONS,
+        message: `Do you want to add another item to ${this.propertyDisplayName(propertyPath)} array?`,
+        default: _.get(this.filledObject, `${propertyPath}[${currItem}]`) !== undefined,
+      })
       if (!next) {
         break
       }
@@ -228,20 +224,17 @@ export class JsonSchemaPrompter<JsonResult> {
   }
 
   private async promptSimple(promptOptions: DistinctQuestion, propertyPath: string, normalize?: (v: any) => any) {
-    const { result } = await inquirer.prompt([
-      {
-        ...promptOptions,
-        name: 'result',
-        validate: (v) => {
-          v = normalize ? normalize(v) : v
-          return (
-            this.setValueAndGetError(propertyPath, v) ||
-            (promptOptions.validate ? promptOptions.validate(v) : true) ||
-            true
-          )
-        },
+    const result = await this.inquirerSinglePrompt({
+      ...promptOptions,
+      validate: (v) => {
+        v = normalize ? normalize(v) : v
+        return (
+          this.setValueAndGetError(propertyPath, v) ||
+          (promptOptions.validate ? promptOptions.validate(v) : true) ||
+          true
+        )
       },
-    ])
+    })
 
     return result
   }
@@ -291,4 +284,16 @@ export class JsonSchemaPrompter<JsonResult> {
     await this.prompt(mainSchema.properties![p] as JSONSchema, p, customPrompt)
     return this.filledObject[p] as Exclude<JsonResult[P], undefined>
   }
+
+  async inquirerSinglePrompt(question: DistinctQuestion) {
+    const { result } = await inquirer.prompt([
+      {
+        ...question,
+        name: 'result',
+        prefix: '',
+      },
+    ])
+
+    return result
+  }
 }

+ 1 - 1
cli/src/helpers/display.ts

@@ -44,7 +44,7 @@ export function displayTable(rows: { [k: string]: string | number }[], cellHoriz
   const maxLength = (columnName: string) =>
     rows.reduce((maxLength, row) => {
       const val = row[columnName]
-      const valLength = typeof val === 'string' ? val.length : val.toString().length
+      const valLength = typeof val === 'string' ? val.length : val !== undefined ? val.toString().length : 0
       return Math.max(maxLength, valLength)
     }, columnName.length)
   const columnDef = (columnName: string) => ({

+ 20 - 20
content-directory-schemas/README.md

@@ -14,7 +14,7 @@ In order to make this documentation as clear as possible it is important to make
 In order to intialize the content directory on a development chain based on data that is provided in form of json files inside `/inputs` directory (`classes`, `schemas` and example entities - `entityBatches`), we can run:
 
 ```
-yarn workspace cd-schemas initialize:dev
+yarn workspace @joystream/cd-schemas initialize:dev
 ```
 
 This will handle:
@@ -51,7 +51,7 @@ For more context, see: https://code.visualstudio.com/docs/languages/json
 
 ### Validate inputs and `json-schemas` via a command
 
-All inputs inside `inputs` directory and `json-schemas` used to validate those inputs can also be validated using `yarn workspace cd-schemas validate` command. This is mainly to facilitate checking the validity of `.json` and `.schema.json` files inside `content-directory-schemas` through CI.
+All inputs inside `inputs` directory and `json-schemas` used to validate those inputs can also be validated using `yarn workspace @joystream/cd-schemas validate` command. This is mainly to facilitate checking the validity of `.json` and `.schema.json` files inside `content-directory-schemas` through CI.
 
 ### Entity batches
 
@@ -109,7 +109,7 @@ We can do it by either using `"new"` or `"existing"` keyword.
 There is a script that provides an easy way of converting `runtime-schemas` (based on inputs from `inputs/schemas`) to `json-schemas` (`.schema.json` files) which allow validating the input (ie. json files) describing some specific entities. It can be run with:
 
 ```
-yarn workspace cd-schemas generate:entity-schemas
+yarn workspace @joystream/cd-schemas generate:entity-schemas
 ```
 
 Those `json-schemas` are currently mainly used for validating the inputs inside `inputs/entityBatches`.
@@ -125,7 +125,7 @@ The generated `json-schemas` include:
 Thanks to the `json-schema-to-typescript` library, we can very simply generate Typescript interfaces based on existing `json-schemas`. This can be done via:
 
 ```
-yarn workspace cd-schemas generate:types
+yarn workspace @joystream/cd-schemas generate:types
 ```
 
 This command will generate:
@@ -153,19 +153,19 @@ The best way to ilustrate this would be by providing some examples:
 
 #### Creating a channel
 ```
-  import { InputParser } from 'cd-schemas'
-  import { ChannelEntity } from 'cd-schemas/types/entities/ChannelEntity'
+  import { InputParser } from '@joystream/cd-schemas'
+  import { ChannelEntity } from '@joystream/cd-schemas/types/entities/ChannelEntity'
   // Other imports...
 
   async main() {
     // Initialize the api, SENDER_KEYPAIR and SENDER_MEMBER_ID...
 
     const channel: ChannelEntity = {
-      title: 'Example channel',
+      handle: 'Example channel',
       description: 'This is an example channel',
       language: { existing: { code: 'EN' } },
       coverPhotoUrl: '',
-      avatarPhotoURL: '',
+      avatarPhotoUrl: '',
       isPublic: true,
     }
 
@@ -182,12 +182,12 @@ The best way to ilustrate this would be by providing some examples:
       .signAndSend(SENDER_KEYPAIR)
   }
 ```
-_Full example with comments can be found in `content-directory-schemas/examples/createChannel.ts` and ran with `yarn workspace cd-schemas example:createChannel`_
+_Full example with comments can be found in `content-directory-schemas/examples/createChannel.ts` and ran with `yarn workspace @joystream/cd-schemas example:createChannel`_
 
 #### Creating a video
 ```
-import { InputParser } from 'cd-schemas'
-import { VideoEntity } from 'cd-schemas/types/entities/VideoEntity'
+import { InputParser } from '@joystream/cd-schemas'
+import { VideoEntity } from '@joystream/cd-schemas/types/entities/VideoEntity'
 // ...
 
 async main() {
@@ -198,7 +198,7 @@ async main() {
     description: 'This is an example video',
     language: { existing: { code: 'EN' } },
     category: { existing: { name: 'Education' } },
-    channel: { existing: { title: 'Example channel' } },
+    channel: { existing: { handle: 'Example channel' } },
     media: {
       new: {
         encoding: { existing: { name: 'H.263_MP4' } },
@@ -221,7 +221,7 @@ async main() {
       },
     },
     duration: 3600,
-    thumbnailURL: '',
+    thumbnailUrl: '',
     isExplicit: false,
     isPublic: true,
   }
@@ -239,25 +239,25 @@ async main() {
     .signAndSend(SENDER_KEYPAIR)
 }
 ```
-_Full example with comments can be found in `content-directory-schemas/examples/createVideo.ts` and ran with `yarn workspace cd-schemas example:createChannel`_
+_Full example with comments can be found in `content-directory-schemas/examples/createVideo.ts` and ran with `yarn workspace @joystream/cd-schemas example:createChannel`_
 
-#### Update channel title
+#### Update channel handle
 
 ```
-import { InputParser } from 'cd-schemas'
-import { ChannelEntity } from 'cd-schemas/types/entities/ChannelEntity'
+import { InputParser } from '@joystream/cd-schemas'
+import { ChannelEntity } from '@joystream/cd-schemas/types/entities/ChannelEntity'
 // ...
 
 async function main() {
   // ...
 
   const channelUpdateInput: Partial<ChannelEntity> = {
-    title: 'Updated channel title',
+    handle: 'Updated channel handle',
   }
 
   const parser = InputParser.createWithKnownSchemas(api)
 
-  const CHANNEL_ID = await parser.findEntityIdByUniqueQuery({ title: 'Example channel' }, 'Channel')
+  const CHANNEL_ID = await parser.findEntityIdByUniqueQuery({ handle: 'Example channel' }, 'Channel')
 
   const updateOperations = await parser.getEntityUpdateOperations(channelUpdateInput, 'Channel', CHANNEL_ID)
 
@@ -266,7 +266,7 @@ async function main() {
     .signAndSend(SENDER_KEYPAIR)
 }
 ```
-_Full example with comments can be found in `content-directory-schemas/examples/updateChannelTitle.ts` and ran with `yarn workspace cd-schemas example:updateChannelTitle`_
+_Full example with comments can be found in `content-directory-schemas/examples/updateChannelHandle.ts` and ran with `yarn workspace @joystream/cd-schemas example:updateChannelHandle`_
 
 Note: Updates can also inlucde `new` and `existing` keywords. In case `new` is specified inside the update - `CreateEntity` and `AddSchemaSupportToEntity` operations will be included as part of the operations returned by `InputParser.getEntityUpdateOperations`.
 

+ 5 - 5
content-directory-schemas/examples/createChannel.ts

@@ -1,9 +1,9 @@
 import { ApiPromise, WsProvider } from '@polkadot/api'
 import { types as joyTypes } from '@joystream/types'
 import { Keyring } from '@polkadot/keyring'
-// Import input parser and channel entity from cd-schemas (we use it as library here)
-import { InputParser } from 'cd-schemas'
-import { ChannelEntity } from 'cd-schemas/types/entities'
+// Import input parser and channel entity from @joystream/cd-schemas (we use it as library here)
+import { InputParser } from '@joystream/cd-schemas'
+import { ChannelEntity } from '@joystream/cd-schemas/types/entities'
 
 async function main() {
   // Initialize the api
@@ -16,14 +16,14 @@ async function main() {
   const [ALICE] = keyring.getPairs()
 
   const channel: ChannelEntity = {
-    title: 'Example channel',
+    handle: 'Example channel',
     description: 'This is an example channel',
     // We can use "existing" syntax to reference either an on-chain entity or other entity that's part of the same batch.
     // Here we reference language that we assume was added by initialization script (initialize:dev), as it is part of
     // input/entityBatches/LanguageBatch.json
     language: { existing: { code: 'EN' } },
     coverPhotoUrl: '',
-    avatarPhotoURL: '',
+    avatarPhotoUrl: '',
     isPublic: true,
   }
   // Create the parser with known entity schemas (the ones in content-directory-schemas/inputs)

+ 6 - 6
content-directory-schemas/examples/createChannelWithoutTransaction.ts

@@ -1,10 +1,10 @@
 import { ApiPromise, WsProvider } from '@polkadot/api'
 import { types as joyTypes } from '@joystream/types'
 import { Keyring } from '@polkadot/keyring'
-// Import input parser and channel entity from cd-schemas (we use it as library here)
-import { InputParser } from 'cd-schemas'
-import { ChannelEntity } from 'cd-schemas/types/entities'
-import { FlattenRelations } from 'cd-schemas/types/utility'
+// Import input parser and channel entity from @joystream/cd-schemas (we use it as library here)
+import { InputParser } from '@joystream/cd-schemas'
+import { ChannelEntity } from '@joystream/cd-schemas/types/entities'
+import { FlattenRelations } from '@joystream/cd-schemas/types/utility'
 import { EntityId } from '@joystream/types/content-directory'
 
 // Alternative way of creating a channel using separate extrinsics (instead of contentDirectory.transaction)
@@ -26,11 +26,11 @@ async function main() {
 
   // We use FlattenRelations to exlude { new } and { existing } (which are not allowed if we want to parse only a single entity)
   const channel: FlattenRelations<ChannelEntity> = {
-    title: 'Example channel 2',
+    handle: 'Example channel 2',
     description: 'This is an example channel',
     language: languageEntityId,
     coverPhotoUrl: '',
-    avatarPhotoURL: '',
+    avatarPhotoUrl: '',
     isPublic: true,
   }
 

+ 6 - 6
content-directory-schemas/examples/createVideo.ts

@@ -1,9 +1,9 @@
 import { ApiPromise, WsProvider } from '@polkadot/api'
 import { types as joyTypes } from '@joystream/types'
 import { Keyring } from '@polkadot/keyring'
-// Import input parser and video entity from cd-schemas (we use it as library here)
-import { InputParser } from 'cd-schemas'
-import { VideoEntity } from 'cd-schemas/types/entities/VideoEntity'
+// Import input parser and video entity from @joystream/cd-schemas (we use it as library here)
+import { InputParser } from '@joystream/cd-schemas'
+import { VideoEntity } from '@joystream/cd-schemas/types/entities/VideoEntity'
 
 async function main() {
   // Initialize the api
@@ -22,9 +22,9 @@ async function main() {
     // (those referenced here are part of inputs/entityBatches)
     language: { existing: { code: 'EN' } },
     category: { existing: { name: 'Education' } },
-    // We use the same "existing" syntax to reference a channel by unique property (title)
+    // We use the same "existing" syntax to reference a channel by unique property (handle)
     // In this case it's a channel that we created in createChannel example
-    channel: { existing: { title: 'Example channel' } },
+    channel: { existing: { handle: 'Example channel' } },
     media: {
       // We use "new" syntax to sygnalize we want to create a new VideoMedia entity that will be related to this Video entity
       new: {
@@ -46,7 +46,7 @@ async function main() {
       },
     },
     duration: 3600,
-    thumbnailURL: '',
+    thumbnailUrl: '',
     isExplicit: false,
     isPublic: true,
   }

+ 5 - 5
content-directory-schemas/examples/updateChannelTitle.ts

@@ -1,9 +1,9 @@
 import { ApiPromise, WsProvider } from '@polkadot/api'
 import { types as joyTypes } from '@joystream/types'
 import { Keyring } from '@polkadot/keyring'
-// Import input parser and channel entity from cd-schemas (we use it as library here)
-import { InputParser } from 'cd-schemas'
-import { ChannelEntity } from 'cd-schemas/types/entities/ChannelEntity'
+// Import input parser and channel entity from @joystream/cd-schemas (we use it as library here)
+import { InputParser } from '@joystream/cd-schemas'
+import { ChannelEntity } from '@joystream/cd-schemas/types/entities/ChannelEntity'
 
 async function main() {
   // Initialize the api
@@ -17,7 +17,7 @@ async function main() {
 
   // Create partial channel entity, only containing the fields we wish to update
   const channelUpdateInput: Partial<ChannelEntity> = {
-    title: 'Updated channel title',
+    handle: 'Updated channel handle',
   }
 
   // Create the parser with known entity schemas (the ones in content-directory-schemas/inputs)
@@ -25,7 +25,7 @@ async function main() {
 
   // We can reuse InputParser's `findEntityIdByUniqueQuery` method to find entityId of the channel we
   // created in ./createChannel.ts example (normally we would probably use some other way to do it, ie.: query node)
-  const CHANNEL_ID = await parser.findEntityIdByUniqueQuery({ title: 'Example channel' }, 'Channel')
+  const CHANNEL_ID = await parser.findEntityIdByUniqueQuery({ handle: 'Example channel' }, 'Channel')
 
   // Use getEntityUpdateOperations to parse the update input
   const updateOperations = await parser.getEntityUpdateOperations(

+ 6 - 6
content-directory-schemas/examples/updateChannelTitleWithoutTransaction.ts

@@ -1,10 +1,10 @@
 import { ApiPromise, WsProvider } from '@polkadot/api'
 import { types as joyTypes } from '@joystream/types'
 import { Keyring } from '@polkadot/keyring'
-// Import input parser and channel entity from cd-schemas (we use it as library here)
-import { InputParser } from 'cd-schemas'
-import { ChannelEntity } from 'cd-schemas/types/entities'
-import { FlattenRelations } from 'cd-schemas/types/utility'
+// Import input parser and channel entity from @joystream/cd-schemas (we use it as library here)
+import { InputParser } from '@joystream/cd-schemas'
+import { ChannelEntity } from '@joystream/cd-schemas/types/entities'
+import { FlattenRelations } from '@joystream/cd-schemas/types/utility'
 
 // Alternative way of update a channel using updateEntityPropertyValues extrinsic
 async function main() {
@@ -19,7 +19,7 @@ async function main() {
 
   // Create partial channel entity, only containing the fields we wish to update
   const channelUpdateInput: Partial<FlattenRelations<ChannelEntity>> = {
-    title: 'Updated channel title 2',
+    handle: 'Updated channel handle 2',
   }
 
   // Create the parser with known entity schemas (the ones in content-directory-schemas/inputs)
@@ -28,7 +28,7 @@ async function main() {
   // We can reuse InputParser's `findEntityIdByUniqueQuery` method to find entityId of the channel we
   // created in ./createChannelWithoutTransaction.ts example
   // (normally we would probably use some other way to do it, ie.: query node)
-  const CHANNEL_ID = await parser.findEntityIdByUniqueQuery({ title: 'Example channel 2' }, 'Channel')
+  const CHANNEL_ID = await parser.findEntityIdByUniqueQuery({ handle: 'Example channel 2' }, 'Channel')
 
   // We use parser to create input property values map
   const newPropertyValues = await parser.parseToInputEntityValuesMap(channelUpdateInput, 'Channel')

+ 6 - 0
content-directory-schemas/inputs/classes/FeaturedVideoClass.json

@@ -0,0 +1,6 @@
+{
+  "name": "FeaturedVideo",
+  "description": "Featured video references",
+  "maximum_entities_count": 400,
+  "default_entity_creation_voucher_upper_bound": 50
+}

+ 18 - 0
content-directory-schemas/inputs/classes/index.js

@@ -0,0 +1,18 @@
+const EXPECTED_CLASS_ORDER = [
+  'Channel',
+  'ContentCategory',
+  'HttpMediaLocation',
+  'JoystreamMediaLocation',
+  'KnownLicense',
+  'Language',
+  'License',
+  'MediaLocation',
+  'UserDefinedLicense',
+  'Video',
+  'VideoMedia',
+  'VideoMediaEncoding',
+  'FeaturedVideo',
+]
+
+// Exports class input jsons in a predictable order
+module.exports = EXPECTED_CLASS_ORDER.map((className) => require(`./${className}Class.json`))

+ 0 - 13
content-directory-schemas/inputs/entityBatches/ChannelBatch.json

@@ -1,13 +0,0 @@
-{
-  "className": "Channel",
-  "entries": [
-    {
-      "title": "Joystream Cartoons",
-      "description": "Joystream Cartoons channel",
-      "language": { "existing": { "code": "EN" } },
-      "coverPhotoUrl": "https://user-images.githubusercontent.com/4144334/91547902-7e90db00-e91c-11ea-9f5c-45d4921928d5.png",
-      "avatarPhotoURL": "https://user-images.githubusercontent.com/4144334/91546674-ba2aa580-e91a-11ea-96e2-abc7654c0461.png",
-      "isPublic": true
-    }
-  ]
-}

+ 48 - 6
content-directory-schemas/inputs/entityBatches/KnownLicenseBatch.json

@@ -1,11 +1,53 @@
 {
   "className": "KnownLicense",
   "entries": [
-    { "code": "CC_BY" },
-    { "code": "CC_BY_SA" },
-    { "code": "CC_BY_ND" },
-    { "code": "CC_BY_NC" },
-    { "code": "CC_BY_NC_SA" },
-    { "code": "CC_BY_NC_ND" }
+    {
+      "code": "PDM",
+      "name": "Public Domain",
+      "url": "https://creativecommons.org/share-your-work/public-domain/pdm",
+      "attributionRequired": false
+    },
+    {
+      "code": "CC0",
+      "name": "Public Domain Dedication",
+      "url": "https://creativecommons.org/share-your-work/public-domain/cc0",
+      "attributionRequired": true
+    },
+    {
+      "code": "CC_BY",
+      "name": "Creative Commons Attribution License",
+      "url": "https://creativecommons.org/licenses/by/4.0",
+      "attributionRequired": true
+    },
+    {
+      "code": "CC_BY_SA",
+      "name": "Creative Commons Attribution-ShareAlike License",
+      "url": "https://creativecommons.org/licenses/by-sa/4.0",
+      "attributionRequired": true
+    },
+    {
+      "code": "CC_BY_ND",
+      "name": "Creative Commons Attribution-NoDerivs License",
+      "url": "https://creativecommons.org/licenses/by-nd/4.0",
+      "attributionRequired": true
+    },
+    {
+      "code": "CC_BY_NC",
+      "name": "Creative Commons Attribution-NonCommercial License",
+      "url": "https://creativecommons.org/licenses/by-nc/4.0",
+      "attributionRequired": true
+    },
+    {
+      "code": "CC_BY_NC_SA",
+      "name": "Creative Commons Attribution-NonCommercial-ShareAlike License",
+      "url": "https://creativecommons.org/licenses/by-nc-sa/4.0",
+      "attributionRequired": true
+    },
+    {
+      "code": "CC_BY_NC_ND",
+      "name": "Creative Commons Attribution-NonCommercial-NoDerivs License",
+      "url": "https://creativecommons.org/licenses/by-nc-nd/4.0",
+      "attributionRequired": true
+    }
   ]
 }

+ 0 - 63
content-directory-schemas/inputs/entityBatches/VideoBatch.json

@@ -1,63 +0,0 @@
-{
-  "className": "Video",
-  "entries": [
-    {
-      "title": "Caminades 2",
-      "description": "Caminandes 2: Gran Dillama",
-      "language": { "existing": { "code": "EN" } },
-      "category": { "existing": { "name": "Film & Animation" } },
-      "channel": { "existing": { "title": "Joystream Cartoons" } },
-      "duration": 146,
-      "hasMarketing": false,
-      "isPublic": true,
-      "media": {
-        "new": {
-          "encoding": { "existing": { "name": "H.264_MP4" } },
-          "location": {
-            "new": {
-              "httpMediaLocation": {
-                "new": {
-                  "url": "http://www.caminandes.com/download/02_gran_dillama_1080p.zip"
-                }
-              }
-            }
-          },
-          "pixelWidth": 1920,
-          "pixelHeight": 1080
-        }
-      },
-      "thumbnailURL": "http://www.caminandes.com/wp-content/uploads/2016/02/web_header4.png",
-      "isExplicit": false,
-      "license": { "new": { "knownLicense": { "existing": { "code": "CC_BY" } } } }
-    },
-    {
-      "title": "Caminades 3",
-      "description": "Caminandes 3: Llamigos",
-      "language": { "existing": { "code": "EN" } },
-      "category": { "existing": { "name": "Film & Animation" } },
-      "channel": { "existing": { "title": "Joystream Cartoons" } },
-      "duration": 150,
-      "hasMarketing": false,
-      "isPublic": true,
-      "media": {
-        "new": {
-          "encoding": { "existing": { "name": "H.264_MP4" } },
-          "location": {
-            "new": {
-              "httpMediaLocation": {
-                "new": {
-                  "url": "http://www.caminandes.com/download/03_caminandes_llamigos_1080p.mp4"
-                }
-              }
-            }
-          },
-          "pixelWidth": 1920,
-          "pixelHeight": 1080
-        }
-      },
-      "thumbnailURL": "http://www.caminandes.com/wp-content/uploads/2016/02/web_header4.png",
-      "isExplicit": false,
-      "license": { "new": { "knownLicense": { "existing": { "code": "CC_BY" } } } }
-    }
-  ]
-}

+ 5 - 6
content-directory-schemas/inputs/schemas/ChannelSchema.json

@@ -2,8 +2,8 @@
   "className": "Channel",
   "newProperties": [
     {
-      "name": "title",
-      "description": "The title of the Channel",
+      "name": "handle",
+      "description": "The handle of the Channel",
       "required": true,
       "unique": true,
       "property_type": { "Single": { "Text": 64 } }
@@ -17,13 +17,13 @@
     {
       "name": "coverPhotoUrl",
       "description": "Url for Channel's cover (background) photo. Recommended ratio: 16:9.",
-      "required": true,
+      "required": false,
       "property_type": { "Single": { "Text": 256 } }
     },
     {
-      "name": "avatarPhotoURL",
+      "name": "avatarPhotoUrl",
       "description": "Channel's avatar photo.",
-      "required": true,
+      "required": false,
       "property_type": { "Single": { "Text": 256 } }
     },
     {
@@ -36,7 +36,6 @@
       "name": "isCensored",
       "description": "Channel censorship status set by the Curator.",
       "required": false,
-      "unique": true,
       "property_type": { "Single": "Bool" },
       "locking_policy": { "is_locked_from_controller": true }
     },

+ 12 - 0
content-directory-schemas/inputs/schemas/FeaturedVideoSchema.json

@@ -0,0 +1,12 @@
+{
+  "className": "FeaturedVideo",
+  "newProperties": [
+    {
+      "name": "video",
+      "description": "Reference to a video",
+      "required": true,
+      "unique": true,
+      "property_type": { "Single": { "Reference": { "className": "Video" } } }
+    }
+  ]
+}

+ 9 - 0
content-directory-schemas/inputs/schemas/KnownLicenseSchema.json

@@ -38,6 +38,15 @@
         "Single": { "Text": 256 }
       },
       "locking_policy": { "is_locked_from_controller": true }
+    },
+    {
+      "name": "attributionRequired",
+      "description": "Whether this license requires an attribution",
+      "required": false,
+      "property_type": {
+        "Single": "Bool"
+      },
+      "locking_policy": { "is_locked_from_controller": true }
     }
   ]
 }

+ 6 - 0
content-directory-schemas/inputs/schemas/LicenseSchema.json

@@ -12,6 +12,12 @@
       "description": "Reference to user-defined license",
       "required": false,
       "property_type": { "Single": { "Reference": { "className": "UserDefinedLicense", "sameOwner": true } } }
+    },
+    {
+      "name": "attribution",
+      "description": "Attribution (if required by the license)",
+      "required": false,
+      "property_type": { "Single": { "Text": 512 } }
     }
   ]
 }

+ 2 - 3
content-directory-schemas/inputs/schemas/VideoSchema.json

@@ -38,7 +38,7 @@
       "property_type": { "Single": "Uint16" }
     },
     {
-      "name": "thumbnailURL",
+      "name": "thumbnailUrl",
       "description": "Video thumbnail url (recommended ratio: 16:9)",
       "required": true,
       "property_type": { "Single": { "Text": 256 } }
@@ -67,7 +67,7 @@
       "name": "publishedBeforeJoystream",
       "description": "If the Video was published on other platform before beeing published on Joystream - the original publication date",
       "required": false,
-      "property_type": { "Single": "Uint32" }
+      "property_type": { "Single": "Int32" }
     },
     {
       "name": "isPublic",
@@ -92,7 +92,6 @@
       "name": "isCensored",
       "description": "Video censorship status set by the Curator.",
       "required": false,
-      "unique": true,
       "property_type": { "Single": "Bool" },
       "locking_policy": { "is_locked_from_controller": true }
     }

+ 3 - 3
content-directory-schemas/package.json

@@ -1,5 +1,5 @@
 {
-  "name": "cd-schemas",
+  "name": "@joystream/cd-schemas",
   "version": "0.1.0",
   "description": "JSON schemas, inputs and related tooling for Joystream content directory 2.0",
   "author": "Joystream contributors",
@@ -19,9 +19,9 @@
     "initialize:dev": "yarn initialize:alice-as-lead && yarn initialize:content-dir",
     "example:createChannel": "ts-node ./examples/createChannel.ts",
     "example:createVideo": "ts-node ./examples/createVideo.ts",
-    "example:updateChannelTitle": "ts-node ./examples/updateChannelTitle.ts",
+    "example:updateChannelHandle": "ts-node ./examples/updateChannelHandle.ts",
     "example:createChannelWithoutTransaction": "ts-node ./examples/createChannelWithoutTransaction.ts",
-    "example:updateChannelTitlelWithoutTransaction": "ts-node ./examples/updateChannelTitleWithoutTransaction.ts"
+    "example:updateChannelHandlelWithoutTransaction": "ts-node ./examples/updateChannelHandleWithoutTransaction.ts"
   },
   "dependencies": {
     "ajv": "6.12.5",

+ 2 - 7
content-directory-schemas/scripts/initializeContentDir.ts

@@ -1,20 +1,15 @@
-import { CreateClass } from '../types/extrinsics/CreateClass'
-import { AddClassSchema } from '../types/extrinsics/AddClassSchema'
 import { types } from '@joystream/types'
 import { ApiPromise, WsProvider } from '@polkadot/api'
-import { getInputs } from '../src/helpers/inputs'
+import { getInitializationInputs } from '../src/helpers/inputs'
 import fs from 'fs'
 import path from 'path'
-import { EntityBatch } from '../types/EntityBatch'
 import { InputParser } from '../src/helpers/InputParser'
 import { ExtrinsicsHelper, getAlicePair } from '../src/helpers/extrinsics'
 
 // Save entity operations output here for easier debugging
 const ENTITY_OPERATIONS_OUTPUT_PATH = path.join(__dirname, '../operations.json')
 
-const classInputs = getInputs<CreateClass>('classes').map(({ data }) => data)
-const schemaInputs = getInputs<AddClassSchema>('schemas').map(({ data }) => data)
-const entityBatchInputs = getInputs<EntityBatch>('entityBatches').map(({ data }) => data)
+const { classInputs, schemaInputs, entityBatchInputs } = getInitializationInputs()
 
 async function main() {
   // Init api

+ 1 - 1
content-directory-schemas/scripts/inputSchemasToEntitySchemas.ts

@@ -42,7 +42,7 @@ const HashPropertyDef = ({ Hash: maxLength }: HashProperty): JSONSchema7 => ({
 
 const ReferencePropertyDef = ({ Reference: ref }: ReferenceProperty): JSONSchema7 => ({
   'oneOf': [
-    onePropertyObjectDef('new', { '$ref': `./${ref.className}Entity.schema.json` }),
+    onePropertyObjectDef('new', { '$ref': `../entities/${ref.className}Entity.schema.json` }),
     onePropertyObjectDef('existing', { '$ref': `../entityReferences/${ref.className}Ref.schema.json` }),
     PRIMITIVE_PROPERTY_DEFS.definitions.Uint64 as JSONSchema7,
   ],

+ 4 - 8
content-directory-schemas/src/helpers/InputParser.ts

@@ -18,7 +18,7 @@ import { ApiPromise } from '@polkadot/api'
 import { JoyBTreeSet } from '@joystream/types/common'
 import { CreateClass } from '../../types/extrinsics/CreateClass'
 import { EntityBatch } from '../../types/EntityBatch'
-import { getInputs } from './inputs'
+import { getInitializationInputs, getInputs } from './inputs'
 
 type SimpleEntityValue = string | boolean | number | string[] | boolean[] | number[] | undefined | null
 // Input without "new" or "extising" keywords
@@ -38,12 +38,8 @@ export class InputParser {
   private classIdByNameMap = new Map<string, number>()
 
   static createWithInitialInputs(api: ApiPromise): InputParser {
-    return new InputParser(
-      api,
-      getInputs<CreateClass>('classes').map(({ data }) => data),
-      getInputs<AddClassSchema>('schemas').map(({ data }) => data),
-      getInputs<EntityBatch>('entityBatches').map(({ data }) => data)
-    )
+    const { classInputs, schemaInputs, entityBatchInputs } = getInitializationInputs()
+    return new InputParser(api, classInputs, schemaInputs, entityBatchInputs)
   }
 
   static createWithKnownSchemas(api: ApiPromise, entityBatches?: EntityBatch[]): InputParser {
@@ -198,7 +194,7 @@ export class InputParser {
         const schemaPropertyType = schema.newProperties.find((p) => p.name === propertyName)!.property_type
         // Handle entities "nested" via "new"
         if (isSingle(schemaPropertyType) && isReference(schemaPropertyType.Single)) {
-          if (Object.keys(propertyValue).includes('new')) {
+          if (propertyValue !== null && Object.keys(propertyValue).includes('new')) {
             const refEntitySchema = this.schemaByClassName(schemaPropertyType.Single.Reference.className)
             this.includeEntityInputInUniqueQueryMap(propertyValue.new, refEntitySchema)
           }

+ 25 - 5
content-directory-schemas/src/helpers/inputs.ts

@@ -1,5 +1,7 @@
 import path from 'path'
 import fs from 'fs'
+import { CreateClass, AddClassSchema } from '../../types/extrinsics'
+import { EntityBatch } from '../../types/EntityBatch'
 
 export const INPUTS_LOCATION = path.join(__dirname, '../../inputs')
 export const INPUT_TYPES = ['classes', 'schemas', 'entityBatches'] as const
@@ -9,12 +11,30 @@ export type FetchedInput<Schema = any> = { fileName: string; data: Schema }
 
 export const getInputsLocation = (inputType: InputType) => path.join(INPUTS_LOCATION, inputType)
 
-export function getInputs<Schema = any>(inputType: InputType): FetchedInput<Schema>[] {
-  return fs.readdirSync(getInputsLocation(inputType)).map((fileName) => {
-    const inputJson = fs.readFileSync(path.join(INPUTS_LOCATION, inputType, fileName)).toString()
-    return {
+export function getInputs<Schema = any>(
+  inputType: InputType,
+  rootInputsLocation = INPUTS_LOCATION
+): FetchedInput<Schema>[] {
+  const inputs: FetchedInput<Schema>[] = []
+  fs.readdirSync(path.join(rootInputsLocation, inputType)).forEach((fileName) => {
+    const inputFilePath = path.join(rootInputsLocation, inputType, fileName)
+    if (path.extname(inputFilePath) !== '.json') {
+      return
+    }
+    const inputJson = fs.readFileSync(inputFilePath).toString()
+    inputs.push({
       fileName,
       data: JSON.parse(inputJson) as Schema,
-    }
+    })
   })
+  return inputs
+}
+
+export function getInitializationInputs(rootInputsLocation = INPUTS_LOCATION) {
+  return {
+    // eslint-disable-next-line @typescript-eslint/no-var-requires
+    classInputs: require('../../inputs/classes/index.js') as CreateClass[],
+    schemaInputs: getInputs<AddClassSchema>('schemas').map(({ data }) => data),
+    entityBatchInputs: getInputs<EntityBatch>('entityBatches').map(({ data }) => data),
+  }
 }

+ 1 - 1
content-directory-schemas/src/index.ts

@@ -1,6 +1,6 @@
 export { ExtrinsicsHelper, getAlicePair } from './helpers/extrinsics'
 export { InputParser } from './helpers/InputParser'
-export { getInputs, getInputsLocation } from './helpers/inputs'
+export { getInputs, getInitializationInputs, getInputsLocation } from './helpers/inputs'
 export { isReference, isSingle } from './helpers/propertyType'
 export { getSchemasLocation } from './helpers/schemas'
 export { default as initializeContentDir } from './helpers/initialize'

+ 25 - 15
docker-compose.yml

@@ -44,7 +44,7 @@ services:
       dockerfile: apps.Dockerfile
     ports:
       - '127.0.0.1:3001:3001'
-    command: colossus --dev --ws-provider ${WS_PROVIDER_ENDPOINT_URI} --ipfs-host ipfs
+    command: colossus --dev --ws-provider ws://joystream-node:9944 --ipfs-host ipfs
     environment:
       - DEBUG=*
 
@@ -55,10 +55,13 @@ services:
       - "127.0.0.1:${DB_PORT}:5432"
     volumes:
       - /var/lib/postgresql/data
+    env_file:
+      # relative to working directory where docker-compose was run from
+      - .env
     environment:
       POSTGRES_USER: ${DB_USER}
       POSTGRES_PASSWORD: ${DB_PASS}
-      POSTGRES_DB: ${DB_NAME}
+      POSTGRES_DB: ${INDEXER_DB_NAME}
 
   graphql-server:
     image: joystream/apps
@@ -67,10 +70,11 @@ services:
       context: .
       dockerfile: apps.Dockerfile
     env_file:
-      # relative to working directory where docker-compose was run from 
+      # relative to working directory where docker-compose was run from
       - .env
     environment:
       - DB_HOST=db
+      - DB_NAME=${PROCESSOR_DB_NAME}
     ports:
       - "127.0.0.1:8081:${GRAPHQL_SERVER_PORT}"
     depends_on: 
@@ -84,14 +88,14 @@ services:
       context: .
       dockerfile: apps.Dockerfile
     env_file:
-      # relative to working directory where docker-compose was run from 
+      # relative to working directory where docker-compose was run from
       - .env
     environment:
-      - INDEXER_ENDPOINT_URL=http://indexer-api-gateway:4000/graphql
-      - DB_HOST=db
+      - INDEXER_ENDPOINT_URL=http://indexer-api-gateway:${WARTHOG_APP_PORT}/graphql
       - TYPEORM_HOST=db
+      - TYPEORM_DATABASE=${PROCESSOR_DB_NAME}
       - DEBUG=index-builder:*
-      - WS_PROVIDER_ENDPOINT_URI=${WS_PROVIDER_ENDPOINT_URI}
+      - WS_PROVIDER_ENDPOINT_URI=ws://joystream-node:9944
     depends_on:
       - indexer-api-gateway
     command: ["workspace", "query-node-root", "processor:start"]
@@ -103,15 +107,16 @@ services:
       context: .
       dockerfile: apps.Dockerfile
     env_file:
-      # relative to working directory where docker-compose was run from 
-      - .env 
+      # relative to working directory where docker-compose was run from
+      - .env
     environment:
       - TYPEORM_HOST=db
+      - TYPEORM_DATABASE=${INDEXER_DB_NAME}
       - INDEXER_WORKERS=5
       - PROCESSOR_POLL_INTERVAL=1000 # refresh every second 
       - REDIS_URI=redis://redis:6379/0
       - DEBUG=index-builder:*
-      - WS_PROVIDER_ENDPOINT_URI=${WS_PROVIDER_ENDPOINT_URI}
+      - WS_PROVIDER_ENDPOINT_URI=ws://joystream-node:9944
     depends_on: 
       - db
     command: ["workspace", "query-node-root", "indexer:start"] 
@@ -119,16 +124,21 @@ services:
   indexer-api-gateway:
     image: joystream/hydra-indexer-gateway:latest
     restart: unless-stopped
+    env_file:
+      # relative to working directory where docker-compose was run from
+      - .env
     environment:
-      - WARTHOG_STARTER_DB_DATABASE=${DB_NAME}
-      - WARTHOG_STARTER_DB_HOST=db 
+      - WARTHOG_STARTER_DB_DATABASE=${INDEXER_DB_NAME}
+      - WARTHOG_STARTER_DB_HOST=db
       - WARTHOG_STARTER_DB_PASSWORD=${DB_PASS}
       - WARTHOG_STARTER_DB_PORT=${DB_PORT}
       - WARTHOG_STARTER_DB_USERNAME=${DB_USER}
-      - WARTHOG_STARTER_REDIS_URI=redis://redis:6379/0 
-      - PORT=4000
+      - WARTHOG_STARTER_REDIS_URI=redis://redis:6379/0
+      - WARTHOG_APP_PORT=${WARTHOG_APP_PORT}
+      - PORT=${WARTHOG_APP_PORT}
+      - DEBUG=*
     ports:
-      - "127.0.0.1:4000:4000"
+      - "127.0.0.1:4000:4002"
     depends_on:
       - redis
       - db

+ 0 - 391
node/src/chain_spec/content_config.rs

@@ -1,391 +0,0 @@
-use codec::Decode;
-use node_runtime::common::constraints::InputValidationLengthConstraint;
-use node_runtime::{
-    content_wg::{Channel, ChannelId, Principal, PrincipalId},
-    data_directory::DataObject,
-    primitives::{AccountId, BlockNumber, Credential},
-    versioned_store::{Class, ClassId, Entity, EntityId},
-    versioned_store_permissions::ClassPermissions,
-    ContentId, ContentWorkingGroupConfig, DataDirectoryConfig, Runtime, VersionedStoreConfig,
-    VersionedStorePermissionsConfig,
-};
-use serde::Deserialize;
-use std::{fs, path::Path};
-
-// Because of the way that the @joystream/types were implemented the getters for
-// the string types return a `string` not the `Text` type so when we are serializing
-// them to json we get a string rather than an array of bytes, so deserializing them
-// is failing. So we are relying on parity codec encoding instead..
-#[derive(Decode)]
-struct ClassAndPermissions {
-    class: Class,
-    permissions: ClassPermissions<ClassId, Credential, u16, BlockNumber>,
-}
-
-#[derive(Decode)]
-struct EntityAndMaintainer {
-    entity: Entity,
-    maintainer: Option<Credential>,
-}
-
-#[derive(Decode)]
-struct DataObjectAndContentId {
-    content_id: ContentId,
-    data_object: DataObject<Runtime>,
-}
-
-#[derive(Decode)]
-struct ContentData {
-    /// classes and their associted permissions
-    classes: Vec<ClassAndPermissions>,
-    /// entities and their associated maintainer
-    entities: Vec<EntityAndMaintainer>,
-    /// DataObject(s) and ContentId
-    data_objects: Vec<DataObjectAndContentId>,
-    /// Media Channels
-    channels: Vec<ChannelAndId>,
-}
-
-#[derive(Deserialize)]
-struct EncodedClassAndPermissions {
-    /// hex encoded Class
-    class: String,
-    /// hex encoded ClassPermissions<ClassId, Credential, u16, BlockNumber>,
-    permissions: String,
-}
-
-impl EncodedClassAndPermissions {
-    fn decode(&self) -> ClassAndPermissions {
-        // hex string must not include '0x' prefix!
-        let encoded_class =
-            hex::decode(&self.class[2..].as_bytes()).expect("failed to parse class hex string");
-        let encoded_permissions = hex::decode(&self.permissions[2..].as_bytes())
-            .expect("failed to parse class permissions hex string");
-        ClassAndPermissions {
-            class: Decode::decode(&mut encoded_class.as_slice()).unwrap(),
-            permissions: Decode::decode(&mut encoded_permissions.as_slice()).unwrap(),
-        }
-    }
-}
-
-#[derive(Deserialize)]
-struct EncodedEntityAndMaintainer {
-    /// hex encoded Entity
-    entity: String,
-    /// hex encoded Option<Credential>
-    maintainer: Option<String>,
-}
-
-impl EncodedEntityAndMaintainer {
-    fn decode(&self) -> EntityAndMaintainer {
-        // hex string must not include '0x' prefix!
-        let encoded_entity =
-            hex::decode(&self.entity[2..].as_bytes()).expect("failed to parse entity hex string");
-        let encoded_maintainer = self.maintainer.as_ref().map(|maintainer| {
-            hex::decode(&maintainer[2..].as_bytes()).expect("failed to parse maintainer hex string")
-        });
-        EntityAndMaintainer {
-            entity: Decode::decode(&mut encoded_entity.as_slice()).unwrap(),
-            maintainer: encoded_maintainer
-                .map(|maintainer| Decode::decode(&mut maintainer.as_slice()).unwrap()),
-        }
-    }
-}
-
-#[derive(Deserialize)]
-struct EncodedDataObjectAndContentId {
-    /// hex encoded ContentId
-    content_id: String,
-    /// hex encoded DataObject<Runtime>
-    data_object: String,
-}
-
-impl EncodedDataObjectAndContentId {
-    fn decode(&self) -> DataObjectAndContentId {
-        // hex string must not include '0x' prefix!
-        let encoded_content_id = hex::decode(&self.content_id[2..].as_bytes())
-            .expect("failed to parse content_id hex string");
-        let encoded_data_object = hex::decode(&self.data_object[2..].as_bytes())
-            .expect("failed to parse data_object hex string");
-        DataObjectAndContentId {
-            content_id: Decode::decode(&mut encoded_content_id.as_slice()).unwrap(),
-            data_object: Decode::decode(&mut encoded_data_object.as_slice()).unwrap(),
-        }
-    }
-}
-
-#[derive(Decode)]
-struct ChannelAndId {
-    id: ChannelId<Runtime>,
-    channel: Channel<u64, AccountId, BlockNumber, PrincipalId<Runtime>>,
-}
-
-#[derive(Deserialize)]
-struct EncodedChannelAndId {
-    /// ChannelId number
-    id: u64,
-    /// hex encoded Channel
-    channel: String,
-}
-
-impl EncodedChannelAndId {
-    fn decode(&self) -> ChannelAndId {
-        let id = self.id;
-        let encoded_channel =
-            hex::decode(&self.channel[2..].as_bytes()).expect("failed to parse channel hex string");
-        ChannelAndId {
-            id: id as ChannelId<Runtime>,
-            channel: Decode::decode(&mut encoded_channel.as_slice()).unwrap(),
-        }
-    }
-}
-
-#[derive(Deserialize)]
-struct EncodedContentData {
-    /// classes and their associted permissions
-    classes: Vec<EncodedClassAndPermissions>,
-    /// entities and their associated maintainer
-    entities: Vec<EncodedEntityAndMaintainer>,
-    /// DataObject(s) and ContentId
-    data_objects: Vec<EncodedDataObjectAndContentId>,
-    /// Media Channels
-    channels: Vec<EncodedChannelAndId>,
-}
-
-fn parse_content_data(data_file: &Path) -> EncodedContentData {
-    let data = fs::read_to_string(data_file).expect("Failed reading file");
-    serde_json::from_str(&data).expect("failed parsing content data")
-}
-
-impl EncodedContentData {
-    pub fn decode(&self) -> ContentData {
-        ContentData {
-            classes: self
-                .classes
-                .iter()
-                .map(|class_and_perm| class_and_perm.decode())
-                .collect(),
-            entities: self
-                .entities
-                .iter()
-                .map(|entities_and_maintainer| entities_and_maintainer.decode())
-                .collect(),
-            data_objects: self
-                .data_objects
-                .iter()
-                .map(|data_objects| data_objects.decode())
-                .collect(),
-            channels: self
-                .channels
-                .iter()
-                .map(|channel_and_id| channel_and_id.decode())
-                .collect(),
-        }
-    }
-}
-
-/// Generates a VersionedStoreConfig genesis config
-/// with pre-populated classes and entities parsed from a json file serialized
-/// as a ContentData struct.
-pub fn versioned_store_config_from_json(data_file: &Path) -> VersionedStoreConfig {
-    let content = parse_content_data(data_file).decode();
-    let base_config = empty_versioned_store_config();
-    let first_id = 1;
-
-    let next_class_id: ClassId = content
-        .classes
-        .last()
-        .map_or(first_id, |class_and_perm| class_and_perm.class.id + 1);
-    assert_eq!(next_class_id, (content.classes.len() + 1) as ClassId);
-
-    let next_entity_id: EntityId = content
-        .entities
-        .last()
-        .map_or(first_id, |entity_and_maintainer| {
-            entity_and_maintainer.entity.id + 1
-        });
-
-    VersionedStoreConfig {
-        class_by_id: content
-            .classes
-            .into_iter()
-            .map(|class_and_permissions| {
-                (class_and_permissions.class.id, class_and_permissions.class)
-            })
-            .collect(),
-        entity_by_id: content
-            .entities
-            .into_iter()
-            .map(|entity_and_maintainer| {
-                (
-                    entity_and_maintainer.entity.id,
-                    entity_and_maintainer.entity,
-                )
-            })
-            .collect(),
-        next_class_id,
-        next_entity_id,
-        ..base_config
-    }
-}
-
-/// Generates basic empty VersionedStoreConfig genesis config
-pub fn empty_versioned_store_config() -> VersionedStoreConfig {
-    VersionedStoreConfig {
-        class_by_id: vec![],
-        entity_by_id: vec![],
-        next_class_id: 1,
-        next_entity_id: 1,
-        property_name_constraint: InputValidationLengthConstraint::new(1, 99),
-        property_description_constraint: InputValidationLengthConstraint::new(1, 999),
-        class_name_constraint: InputValidationLengthConstraint::new(1, 99),
-        class_description_constraint: InputValidationLengthConstraint::new(1, 999),
-    }
-}
-
-/// Generates a basic empty VersionedStorePermissionsConfig genesis config
-pub fn empty_versioned_store_permissions_config() -> VersionedStorePermissionsConfig {
-    VersionedStorePermissionsConfig {
-        class_permissions_by_class_id: vec![],
-        entity_maintainer_by_entity_id: vec![],
-    }
-}
-
-/// Generates a `VersionedStorePermissionsConfig` genesis config
-/// pre-populated with permissions and entity maintainers parsed from
-/// a json file serialized as a `ContentData` struct.
-pub fn versioned_store_permissions_config_from_json(
-    data_file: &Path,
-) -> VersionedStorePermissionsConfig {
-    let content = parse_content_data(data_file).decode();
-
-    VersionedStorePermissionsConfig {
-        class_permissions_by_class_id: content
-            .classes
-            .into_iter()
-            .map(|class_and_perm| (class_and_perm.class.id, class_and_perm.permissions))
-            .collect(),
-        entity_maintainer_by_entity_id: content
-            .entities
-            .into_iter()
-            .filter_map(|entity_and_maintainer| {
-                entity_and_maintainer
-                    .maintainer
-                    .map(|maintainer| (entity_and_maintainer.entity.id, maintainer))
-            })
-            .collect(),
-    }
-}
-
-/// Generates a basic empty `DataDirectoryConfig` genesis config
-pub fn empty_data_directory_config() -> DataDirectoryConfig {
-    DataDirectoryConfig {
-        data_object_by_content_id: vec![],
-        known_content_ids: vec![],
-    }
-}
-
-/// Generates a `DataDirectoryConfig` genesis config
-/// pre-populated with data objects and known content ids parsed from
-/// a json file serialized as a `ContentData` struct
-pub fn data_directory_config_from_json(data_file: &Path) -> DataDirectoryConfig {
-    let content = parse_content_data(data_file).decode();
-
-    DataDirectoryConfig {
-        data_object_by_content_id: content
-            .data_objects
-            .iter()
-            .map(|object| (object.content_id, object.data_object.clone()))
-            .collect(),
-        known_content_ids: content
-            .data_objects
-            .into_iter()
-            .map(|object| object.content_id)
-            .collect(),
-    }
-}
-
-/// Generates a basic `ContentWorkingGroupConfig` genesis config without any active curators
-/// curator lead or channels.
-pub fn empty_content_working_group_config() -> ContentWorkingGroupConfig {
-    ContentWorkingGroupConfig {
-        mint_capacity: 0,
-        curator_opening_by_id: vec![],
-        next_curator_opening_id: 0,
-        curator_application_by_id: vec![],
-        next_curator_application_id: 0,
-        channel_by_id: vec![],
-        next_channel_id: 1,
-        channel_id_by_handle: vec![],
-        curator_by_id: vec![],
-        next_curator_id: 0,
-        principal_by_id: vec![],
-        next_principal_id: 0,
-        channel_creation_enabled: true, // there is no extrinsic to change it so enabling at genesis
-        unstaker_by_stake_id: vec![],
-        channel_handle_constraint: InputValidationLengthConstraint::new(5, 20),
-        channel_description_constraint: InputValidationLengthConstraint::new(1, 1024),
-        opening_human_readable_text: InputValidationLengthConstraint::new(1, 2048),
-        curator_application_human_readable_text: InputValidationLengthConstraint::new(1, 2048),
-        curator_exit_rationale_text: InputValidationLengthConstraint::new(1, 2048),
-        channel_avatar_constraint: InputValidationLengthConstraint::new(5, 1024),
-        channel_banner_constraint: InputValidationLengthConstraint::new(5, 1024),
-        channel_title_constraint: InputValidationLengthConstraint::new(5, 1024),
-    }
-}
-
-/// Generates a `ContentWorkingGroupConfig` genesis config
-/// pre-populated with channels and corresponding princial channel owners
-/// parsed from a json file serialized as a `ContentData` struct
-pub fn content_working_group_config_from_json(data_file: &Path) -> ContentWorkingGroupConfig {
-    let content = parse_content_data(data_file).decode();
-    let first_channel_id = 1;
-    let first_principal_id = 0;
-
-    let next_channel_id: ChannelId<Runtime> = content
-        .channels
-        .last()
-        .map_or(first_channel_id, |channel_and_id| channel_and_id.id + 1);
-    assert_eq!(
-        next_channel_id,
-        (content.channels.len() + 1) as ChannelId<Runtime>
-    );
-
-    let base_config = empty_content_working_group_config();
-
-    ContentWorkingGroupConfig {
-        channel_by_id: content
-            .channels
-            .iter()
-            .enumerate()
-            .map(|(ix, channel_and_id)| {
-                (
-                    channel_and_id.id,
-                    Channel {
-                        principal_id: first_principal_id + ix as PrincipalId<Runtime>,
-                        ..channel_and_id.channel.clone()
-                    },
-                )
-            })
-            .collect(),
-        next_channel_id,
-        channel_id_by_handle: content
-            .channels
-            .iter()
-            .map(|channel_and_id| (channel_and_id.channel.handle.clone(), channel_and_id.id))
-            .collect(),
-        principal_by_id: content
-            .channels
-            .iter()
-            .enumerate()
-            .map(|(ix, channel_and_id)| {
-                (
-                    first_principal_id + ix as PrincipalId<Runtime>,
-                    Principal::ChannelOwner(channel_and_id.id),
-                )
-            })
-            .collect(),
-        next_principal_id: first_principal_id + content.channels.len() as PrincipalId<Runtime>,
-        ..base_config
-    }
-}

+ 2 - 1
node/src/chain_spec/forum_config.rs

@@ -108,7 +108,8 @@ pub fn empty(forum_sudo: AccountId) -> ForumConfig {
         threads: vec![],
         posts: vec![],
         category_by_moderator: vec![],
-        data_migration_done: String::new(),
+        // true
+        data_migration_done: String::from("0x01"),
     };
     create(forum_sudo, forum_data)
 }

+ 5 - 58
node/src/chain_spec/mod.rs

@@ -30,18 +30,15 @@ use sp_runtime::Perbill;
 
 use node_runtime::{
     membership, wasm_binary_unwrap, AuthorityDiscoveryConfig, BabeConfig, Balance, BalancesConfig,
-    ContentDirectoryConfig, ContentDirectoryWorkingGroupConfig, ContentWorkingGroupConfig,
-    CouncilConfig, CouncilElectionConfig, DataDirectoryConfig, DataObjectStorageRegistryConfig,
-    DataObjectTypeRegistryConfig, ElectionParameters, ForumConfig, ForumWorkingGroupConfig,
-    GrandpaConfig, ImOnlineConfig, MembersConfig, Moment, SessionConfig, SessionKeys, Signature,
-    StakerStatus, StakingConfig, StorageWorkingGroupConfig, SudoConfig, SystemConfig,
-    VersionedStoreConfig, VersionedStorePermissionsConfig, DAYS,
+    ContentDirectoryConfig, CouncilConfig, CouncilElectionConfig, DataObjectStorageRegistryConfig,
+    DataObjectTypeRegistryConfig, ElectionParameters, ForumConfig, GrandpaConfig, ImOnlineConfig,
+    MembersConfig, Moment, SessionConfig, SessionKeys, Signature, StakerStatus, StakingConfig,
+    SudoConfig, SystemConfig, DAYS,
 };
 
 // Exported to be used by chain-spec-builder
 pub use node_runtime::{AccountId, GenesisConfig};
 
-pub mod content_config;
 pub mod forum_config;
 pub mod initial_balances;
 pub mod initial_members;
@@ -134,10 +131,6 @@ impl Alternative {
                         ],
                         initial_members::none(),
                         forum_config::empty(get_account_id_from_seed::<sr25519::Public>("Alice")),
-                        content_config::empty_versioned_store_config(),
-                        content_config::empty_versioned_store_permissions_config(),
-                        content_config::empty_data_directory_config(),
-                        content_config::empty_content_working_group_config(),
                         vec![],
                     )
                 },
@@ -174,10 +167,6 @@ impl Alternative {
                         ],
                         initial_members::none(),
                         forum_config::empty(get_account_id_from_seed::<sr25519::Public>("Alice")),
-                        content_config::empty_versioned_store_config(),
-                        content_config::empty_versioned_store_permissions_config(),
-                        content_config::empty_data_directory_config(),
-                        content_config::empty_content_working_group_config(),
                         vec![],
                     )
                 },
@@ -219,17 +208,11 @@ pub fn testnet_genesis(
     endowed_accounts: Vec<AccountId>,
     members: Vec<membership::genesis::Member<u64, AccountId, Moment>>,
     forum_config: ForumConfig,
-    versioned_store_config: VersionedStoreConfig,
-    versioned_store_permissions_config: VersionedStorePermissionsConfig,
-    data_directory_config: DataDirectoryConfig,
-    content_working_group_config: ContentWorkingGroupConfig,
     initial_balances: Vec<(AccountId, Balance)>,
 ) -> GenesisConfig {
     const STASH: Balance = 5_000;
     const ENDOWMENT: Balance = 100_000_000;
 
-    let default_text_constraint = node_runtime::working_group::default_text_constraint();
-
     GenesisConfig {
         frame_system: Some(SystemConfig {
             code: wasm_binary_unwrap().to_vec(),
@@ -298,39 +281,14 @@ pub fn testnet_genesis(
                 min_voting_stake: 100,
             },
         }),
-        membership: Some(MembersConfig {
-            default_paid_membership_fee: 100u128,
-            members,
-        }),
+        membership: Some(MembersConfig { members }),
         forum: Some(forum_config),
-        data_directory: Some(data_directory_config),
         data_object_type_registry: Some(DataObjectTypeRegistryConfig {
             first_data_object_type_id: 1,
         }),
         data_object_storage_registry: Some(DataObjectStorageRegistryConfig {
             first_relationship_id: 1,
         }),
-        working_group_Instance1: Some(ForumWorkingGroupConfig {
-            phantom: Default::default(),
-            working_group_mint_capacity: 0,
-            opening_human_readable_text_constraint: default_text_constraint,
-            worker_application_human_readable_text_constraint: default_text_constraint,
-            worker_exit_rationale_text_constraint: default_text_constraint,
-        }),
-        working_group_Instance2: Some(StorageWorkingGroupConfig {
-            phantom: Default::default(),
-            working_group_mint_capacity: 0,
-            opening_human_readable_text_constraint: default_text_constraint,
-            worker_application_human_readable_text_constraint: default_text_constraint,
-            worker_exit_rationale_text_constraint: default_text_constraint,
-        }),
-        working_group_Instance3: Some(ContentDirectoryWorkingGroupConfig {
-            phantom: Default::default(),
-            working_group_mint_capacity: 0,
-            opening_human_readable_text_constraint: default_text_constraint,
-            worker_application_human_readable_text_constraint: default_text_constraint,
-            worker_exit_rationale_text_constraint: default_text_constraint,
-        }),
         content_directory: Some({
             ContentDirectoryConfig {
                 class_by_id: vec![],
@@ -341,9 +299,6 @@ pub fn testnet_genesis(
                 next_curator_group_id: 1,
             }
         }),
-        versioned_store: Some(versioned_store_config),
-        versioned_store_permissions: Some(versioned_store_permissions_config),
-        content_wg: Some(content_working_group_config),
     }
 }
 
@@ -360,10 +315,6 @@ pub(crate) mod tests {
             vec![get_authority_keys_from_seed("Alice").0],
             initial_members::none(),
             forum_config::empty(get_account_id_from_seed::<sr25519::Public>("Alice")),
-            content_config::empty_versioned_store_config(),
-            content_config::empty_versioned_store_permissions_config(),
-            content_config::empty_data_directory_config(),
-            content_config::empty_content_working_group_config(),
             vec![],
         )
     }
@@ -396,10 +347,6 @@ pub(crate) mod tests {
             ],
             initial_members::none(),
             forum_config::empty(get_account_id_from_seed::<sr25519::Public>("Alice")),
-            content_config::empty_versioned_store_config(),
-            content_config::empty_versioned_store_permissions_config(),
-            content_config::empty_data_directory_config(),
-            content_config::empty_content_working_group_config(),
             vec![],
         )
     }

+ 2 - 2
package.json

@@ -4,7 +4,7 @@
   "version": "1.0.0",
   "license": "GPL-3.0-only",
   "scripts": {
-    "postinstall": "yarn workspace @joystream/types build && yarn workspace cd-schemas generate:all && yarn workspace cd-schemas build && yarn workspace @joystream/cli build",
+    "postinstall": "yarn workspace @joystream/types build && yarn workspace @joystream/cd-schemas generate:all && yarn workspace @joystream/cd-schemas build && yarn workspace @joystream/cli build",
     "build": "./build.sh",
     "start": "./start.sh",
     "cargo-checks": "devops/git-hooks/pre-commit && devops/git-hooks/pre-push",
@@ -36,7 +36,7 @@
     "babel-core": "^7.0.0-bridge.0",
     "typescript": "^3.9.7",
     "bn.js": "^5.1.2",
-    "@dzlzv/hydra-indexer-lib": "0.0.19-legacy.1.26.1"
+    "@dzlzv/hydra-indexer-lib": "0.0.21-legacy.1.26.1"
   },
   "devDependencies": {
     "eslint": "^7.6.0",

+ 0 - 62
query-node/.env

@@ -1,62 +0,0 @@
-COMPOSE_PROJECT_NAME=joystream
-
-# Project name
-PROJECT_NAME=query_node
-
-###########################
-#     Common settings     #
-###########################
-
-# The env variables below are by default used by all services and should be
-# overriden in local env files (e.g. ./generated/indexer) if needed
-# DB config
-DB_NAME=query_node
-DB_USER=postgres
-DB_PASS=postgres
-DB_HOST=localhost
-DB_PORT=5432
-DEBUG=index-builder:*
-TYPEORM_LOGGING=error
-
-###########################
-#    Indexer options      #
-###########################
-
-# Substrate endpoint to source events from
-WS_PROVIDER_ENDPOINT_URI=ws://localhost:9944/
-# Block height to start indexing from.
-# Note, that if there are already some indexed events, this setting is ignored
-BLOCK_HEIGHT=0
-
-# Custom types to register for Substrate API
-# TYPE_REGISTER_PACKAGE_NAME=
-# TYPE_REGISTER_PACKAGE_VERSION=
-# TYPE_REGISTER_FUNCTION=
-
-# Redis cache server
-REDIS_URI=redis://localhost:6379/0
-
-###########################
-#    Processor options    #
-###########################
-
-# Where the mapping scripts are located, relative to ./generated/indexer
-# this env var is deprecated!
-MAPPINGS_LOCATION=../../src
-TYPES_JSON=../../typedefs.json
-
-# Indexer GraphQL API endpoint to fetch indexed events
-INDEXER_ENDPOINT_URL=http://localhost:4100/graphql
-
-# Block height from which the processor starts. Note that if
-# there are already processed events in the database, this setting is ignored
-BLOCK_HEIGHT=0
-
-###############################
-#    Processor GraphQL API    #
-###############################
-
-GRAPHQL_SERVER_PORT=4002
-GRAPHQL_SERVER_HOST=localhost
-WARTHOG_APP_PORT=4002
-WARTHOG_APP_HOST=localhost

+ 5 - 1
query-node/README.md

@@ -11,6 +11,10 @@ $ cd query-node
 $ yarn build
 ```
 
+## Starting services
+
+To start services defined in the project docker-compose.yml, you should run docker-compose from the project root folder to use the correct .env file
+
 ## Run mapping processor
 
 Before running mappings make sure indexer(`yarn indexer:start`) and indexer-api-server (mappings get the chain data from this graphql server) are both running:
@@ -26,7 +30,7 @@ Once processor start to store event data you will be able to query this data fro
 ```graphql
 query {
   channels {
-    title
+    handle
   }
 }
 ```

+ 19 - 1
query-node/build.sh

@@ -4,8 +4,26 @@ set -e
 SCRIPT_PATH="$(dirname "${BASH_SOURCE[0]}")"
 cd $SCRIPT_PATH
 
+# Load and export variables from root .env file into shell environment
+set -a
+. ../.env
+set +a
+
 yarn clean
-yarn codegen:all
+
+# We generate the code for each service separately to be able to specify
+# separate database names.
+
+# Build indexer customizing DB name
+DB_NAME=${INDEXER_DB_NAME} yarn codegen:indexer
+
+# Build graphql-server customizing DB name
+DB_NAME=${PROCESSOR_DB_NAME} yarn codegen:server
+
+# We run yarn again to ensure processor and indexer dependencies are installed
+# and are inline with root workspace resolutions
 yarn
+
 ln -s ../../../../../node_modules/typeorm/cli.js generated/graphql-server/node_modules/.bin/typeorm || :
+
 yarn tsc --build tsconfig.json

+ 13 - 0
query-node/db-migrate.sh

@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+set -e
+
+SCRIPT_PATH="$(dirname "${BASH_SOURCE[0]}")"
+cd $SCRIPT_PATH
+
+set -a
+. ../.env
+set +a
+
+yarn workspace query-node-root db:indexer:migrate
+yarn workspace query-node-root db:schema:migrate
+TYPEORM_DATABASE=${PROCESSOR_DB_NAME} yarn workspace query-node-root db:indexer:migrate

+ 64 - 57
query-node/mappings/content-directory/content-dir-consts.ts

@@ -1,4 +1,4 @@
-import { IPropertyIdWithName } from '../types'
+import { IPropertyWithId } from '../types'
 
 // Content directory predefined class names
 export enum ContentDirectoryKnownClasses {
@@ -14,6 +14,7 @@ export enum ContentDirectoryKnownClasses {
   VIDEO = 'Video',
   VIDEOMEDIA = 'VideoMedia',
   VIDEOMEDIAENCODING = 'VideoMediaEncoding',
+  FEATUREDVIDEOS = 'FeaturedVideo',
 }
 
 // Predefined content-directory classes, classId may change after the runtime seeding
@@ -30,87 +31,93 @@ export const contentDirectoryClassNamesWithId: { classId: number; name: string }
   { name: ContentDirectoryKnownClasses.VIDEO, classId: 10 },
   { name: ContentDirectoryKnownClasses.VIDEOMEDIA, classId: 11 },
   { name: ContentDirectoryKnownClasses.VIDEOMEDIAENCODING, classId: 12 },
+  { name: ContentDirectoryKnownClasses.FEATUREDVIDEOS, classId: 13 },
 ]
 
-export const CategoryPropertyNamesWithId: IPropertyIdWithName = {
-  0: 'name',
-  1: 'description',
+export const categoryPropertyNamesWithId: IPropertyWithId = {
+  0: { name: 'name', type: 'string', required: true },
+  1: { name: 'description', type: 'string', required: false },
 }
 
-export const channelPropertyNamesWithId: IPropertyIdWithName = {
-  0: 'title',
-  1: 'description',
-  2: 'coverPhotoURL',
-  3: 'avatarPhotoURL',
-  4: 'isPublic',
-  5: 'isCurated',
-  6: 'language',
+export const channelPropertyNamesWithId: IPropertyWithId = {
+  0: { name: 'handle', type: 'string', required: true },
+  1: { name: 'description', type: 'string', required: false },
+  2: { name: 'coverPhotoUrl', type: 'string', required: false },
+  3: { name: 'avatarPhotoUrl', type: 'string', required: false },
+  4: { name: 'isPublic', type: 'boolean', required: true },
+  5: { name: 'isCurated', type: 'boolean', required: false },
+  6: { name: 'language', type: 'number', required: false },
 }
 
-export const licensePropertyNamesWithId: IPropertyIdWithName = {
-  0: 'knownLicense',
-  1: 'userDefinedLicense',
+export const licensePropertyNamesWithId: IPropertyWithId = {
+  0: { name: 'knownLicense', type: 'number', required: false },
+  1: { name: 'userDefinedLicense', type: 'number', required: false },
+  2: { name: 'attribution', type: 'string', required: false },
 }
 
-export const knownLicensePropertyNamesWIthId: IPropertyIdWithName = {
-  0: 'code',
-  1: 'name',
-  2: 'description',
-  3: 'url',
+export const knownLicensePropertyNamesWIthId: IPropertyWithId = {
+  0: { name: 'code', type: 'string', required: true },
+  1: { name: 'name', type: 'string', required: false },
+  2: { name: 'description', type: 'string', required: false },
+  3: { name: 'url', type: 'string', required: false },
 }
 
-export const languagePropertyNamesWIthId: IPropertyIdWithName = {
-  0: 'name',
-  1: 'code',
+export const languagePropertyNamesWIthId: IPropertyWithId = {
+  0: { name: 'name', type: 'string', required: true },
+  1: { name: 'code', type: 'string', required: true },
 }
 
-export const userDefinedLicensePropertyNamesWithId: IPropertyIdWithName = {
-  0: 'content',
+export const userDefinedLicensePropertyNamesWithId: IPropertyWithId = {
+  0: { name: 'content', type: 'string', required: false },
 }
 
-export const mediaLocationPropertyNamesWithId: IPropertyIdWithName = {
-  0: 'httpMediaLocation',
-  1: 'joystreamMediaLocation',
+export const mediaLocationPropertyNamesWithId: IPropertyWithId = {
+  0: { name: 'httpMediaLocation', type: 'number', required: false },
+  1: { name: 'joystreamMediaLocation', type: 'number', required: false },
 }
 
-export const joystreamMediaLocationPropertyNamesWithId: IPropertyIdWithName = {
-  0: 'dataObjectId',
+export const joystreamMediaLocationPropertyNamesWithId: IPropertyWithId = {
+  0: { name: 'dataObjectId', type: 'string', required: true },
 }
 
-export const httpMediaLocationPropertyNamesWithId: IPropertyIdWithName = {
-  0: 'url',
-  1: 'port',
+export const httpMediaLocationPropertyNamesWithId: IPropertyWithId = {
+  0: { name: 'url', type: 'string', required: false },
+  1: { name: 'port', type: 'number', required: false },
 }
 
-export const videoMediaEncodingPropertyNamesWithId: IPropertyIdWithName = {
-  0: 'name',
+export const videoMediaEncodingPropertyNamesWithId: IPropertyWithId = {
+  0: { name: 'name', type: 'string', required: true },
 }
 
-export const videoMediaPropertyNamesWithId: IPropertyIdWithName = {
-  0: 'encoding',
-  1: 'pixelWidth',
-  2: 'pixelHeight',
-  3: 'size',
-  4: 'location',
+export const videoMediaPropertyNamesWithId: IPropertyWithId = {
+  0: { name: 'encoding', type: 'number', required: true },
+  1: { name: 'pixelWidth', type: 'number', required: true },
+  2: { name: 'pixelHeight', type: 'number', required: true },
+  3: { name: 'size', type: 'number', required: false },
+  4: { name: 'location', type: 'number', required: true },
 }
 
-export const videoPropertyNamesWithId: IPropertyIdWithName = {
+export const videoPropertyNamesWithId: IPropertyWithId = {
   // referenced entity's id
-  0: 'channel',
+  0: { name: 'channel', type: 'number', required: true },
   // referenced entity's id
-  1: 'category',
-  2: 'title',
-  3: 'description',
-  4: 'duration',
-  5: 'skippableIntroDuration',
-  6: 'thumbnailURL',
-  7: 'language',
+  1: { name: 'category', type: 'number', required: true },
+  2: { name: 'title', type: 'string', required: false },
+  3: { name: 'description', type: 'string', required: false },
+  4: { name: 'duration', type: 'number', required: true },
+  5: { name: 'skippableIntroDuration', type: 'number', required: false },
+  6: { name: 'thumbnailUrl', type: 'string', required: true },
+  7: { name: 'language', type: 'number', required: false },
   // referenced entity's id
-  8: 'media',
-  9: 'hasMarketing',
-  10: 'publishedBeforeJoystream',
-  11: 'isPublic',
-  12: 'isExplicit',
-  13: 'license',
-  14: 'isCurated',
+  8: { name: 'media', type: 'number', required: true },
+  9: { name: 'hasMarketing', type: 'boolean', required: false },
+  10: { name: 'publishedBeforeJoystream', type: 'number', required: false },
+  11: { name: 'isPublic', type: 'boolean', required: true },
+  12: { name: 'isExplicit', type: 'boolean', required: true },
+  13: { name: 'license', type: 'number', required: true },
+  14: { name: 'isCurated', type: 'boolean', required: true },
+}
+
+export const featuredVideoPropertyNamesWithId: IPropertyWithId = {
+  0: { name: 'video', type: 'number', required: true },
 }

+ 29 - 13
query-node/mappings/content-directory/decode.ts

@@ -1,17 +1,22 @@
 import { SubstrateEvent } from '../../generated/indexer'
 import {
-  IPropertyIdWithName,
   IClassEntity,
   IProperty,
   IBatchOperation,
   ICreateEntityOperation,
   IEntity,
   IReference,
+  IPropertyWithId,
 } from '../types'
 import Debug from 'debug'
 
-import { ParametrizedClassPropertyValue, UpdatePropertyValuesOperation } from '@joystream/types/content-directory'
+import {
+  OperationType,
+  ParametrizedClassPropertyValue,
+  UpdatePropertyValuesOperation,
+} from '@joystream/types/content-directory'
 import { createType } from '@joystream/types'
+import { Vec } from '@polkadot/types'
 
 const debug = Debug('mappings:cd:decode')
 
@@ -20,18 +25,23 @@ function stringIfyEntityId(event: SubstrateEvent): string {
   return entityId.value as string
 }
 
-function setProperties<T>({ extrinsic, blockNumber }: SubstrateEvent, propNamesWithId: IPropertyIdWithName): T {
+function setProperties<T>({ extrinsic, blockNumber }: SubstrateEvent, propNamesWithId: IPropertyWithId): T {
   if (extrinsic === undefined) throw Error('Undefined extrinsic')
 
   const { 3: newPropertyValues } = extrinsic!.args
   const properties: { [key: string]: any; reference?: IReference } = {}
 
   for (const [k, v] of Object.entries(newPropertyValues.value)) {
-    const propertyName = propNamesWithId[k]
+    const prop = propNamesWithId[k]
     const singlePropVal = createType('InputPropertyValue', v as any).asType('Single')
-    properties[propertyName] = singlePropVal.isOfType('Reference')
-      ? { entityId: singlePropVal.asType('Reference').toJSON(), existing: true }
-      : singlePropVal.value.toJSON()
+
+    if (singlePropVal.isOfType('Reference')) {
+      properties[prop.name] = { entityId: singlePropVal.asType('Reference').toJSON(), existing: true }
+    } else {
+      const val = singlePropVal.value.toJSON()
+      if (typeof val !== prop.type && !prop.required) properties[prop.name] = undefined
+      else properties[prop.name] = val
+    }
   }
   properties.version = blockNumber
 
@@ -54,16 +64,18 @@ function getClassEntity(event: SubstrateEvent): IClassEntity {
  * @param properties
  * @param propertyNamesWithId
  */
-function setEntityPropertyValues<T>(properties: IProperty[], propertyNamesWithId: IPropertyIdWithName): T {
+function setEntityPropertyValues<T>(properties: IProperty[], propertyNamesWithId: IPropertyWithId): T {
   const entityProperties: { [key: string]: any; reference?: IReference } = {}
 
   for (const [propId, propName] of Object.entries(propertyNamesWithId)) {
     // get the property value by id
     const p = properties.find((p) => p.id === propId)
     if (!p) continue
-    entityProperties[propName] = p.reference ? p.reference : p.value
+
+    if (typeof p.value !== propName.type && !propName.required) entityProperties[propName.name] = undefined
+    else entityProperties[propName.name] = p.reference ? p.reference : p.value
   }
-  // debug(`Entity properties ${JSON.stringify(entityProperties)}`)
+  debug(`Entity properties: ${JSON.stringify(entityProperties)}`)
   return entityProperties as T
 }
 
@@ -101,9 +113,12 @@ function getEntityProperties(propertyValues: ParametrizedClassPropertyValue[]):
   return properties
 }
 
-function getOperations({ extrinsic }: SubstrateEvent): IBatchOperation {
-  const operations = createType('Vec<OperationType>', extrinsic!.args[1].value as any)
+function getOperations(event: SubstrateEvent): Vec<OperationType> {
+  if (!event.extrinsic) throw Error(`No extrinsic found for ${event.id}`)
+  return createType('Vec<OperationType>', (event.extrinsic.args[1].value as unknown) as Vec<OperationType>)
+}
 
+function getOperationsByTypes(operations: OperationType[]): IBatchOperation {
   const updatePropertyValuesOperations: IEntity[] = []
   const addSchemaSupportToEntityOperations: IEntity[] = []
   const createEntityOperations: ICreateEntityOperation[] = []
@@ -153,6 +168,7 @@ export const decode = {
   getClassEntity,
   setEntityPropertyValues,
   getEntityProperties,
-  getOperations,
+  getOperationsByTypes,
   setProperties,
+  getOperations,
 }

+ 105 - 46
query-node/mappings/content-directory/entity/create.ts

@@ -1,18 +1,19 @@
 import { DB } from '../../../generated/indexer'
 import { Channel } from '../../../generated/graphql-server/src/modules/channel/channel.model'
 import { Category } from '../../../generated/graphql-server/src/modules/category/category.model'
-import { KnownLicense } from '../../../generated/graphql-server/src/modules/known-license/known-license.model'
-import { UserDefinedLicense } from '../../../generated/graphql-server/src/modules/user-defined-license/user-defined-license.model'
-import { JoystreamMediaLocation } from '../../../generated/graphql-server/src/modules/joystream-media-location/joystream-media-location.model'
-import { HttpMediaLocation } from '../../../generated/graphql-server/src/modules/http-media-location/http-media-location.model'
+import { KnownLicenseEntity } from '../../../generated/graphql-server/src/modules/known-license-entity/known-license-entity.model'
+import { UserDefinedLicenseEntity } from '../../../generated/graphql-server/src/modules/user-defined-license-entity/user-defined-license-entity.model'
+import { JoystreamMediaLocationEntity } from '../../../generated/graphql-server/src/modules/joystream-media-location-entity/joystream-media-location-entity.model'
+import { HttpMediaLocationEntity } from '../../../generated/graphql-server/src/modules/http-media-location-entity/http-media-location-entity.model'
 import { VideoMedia } from '../../../generated/graphql-server/src/modules/video-media/video-media.model'
 import { Video } from '../../../generated/graphql-server/src/modules/video/video.model'
 import { Block, Network } from '../../../generated/graphql-server/src/modules/block/block.model'
 import { Language } from '../../../generated/graphql-server/src/modules/language/language.model'
 import { VideoMediaEncoding } from '../../../generated/graphql-server/src/modules/video-media-encoding/video-media-encoding.model'
 import { ClassEntity } from '../../../generated/graphql-server/src/modules/class-entity/class-entity.model'
-import { License } from '../../../generated/graphql-server/src/modules/license/license.model'
-import { MediaLocation } from '../../../generated/graphql-server/src/modules/media-location/media-location.model'
+import { LicenseEntity } from '../../../generated/graphql-server/src/modules/license-entity/license-entity.model'
+import { MediaLocationEntity } from '../../../generated/graphql-server/src/modules/media-location-entity/media-location-entity.model'
+import { FeaturedVideo } from '../../../generated/graphql-server/src/modules/featured-video/featured-video.model'
 
 import { contentDirectoryClassNamesWithId } from '../content-dir-consts'
 import {
@@ -22,6 +23,7 @@ import {
   ICreateEntityOperation,
   IDBBlockId,
   IEntity,
+  IFeaturedVideo,
   IHttpMediaLocation,
   IJoystreamMediaLocation,
   IKnownLicense,
@@ -35,6 +37,12 @@ import {
 } from '../../types'
 import { getOrCreate } from '../get-or-create'
 import BN from 'bn.js'
+import {
+  HttpMediaLocation,
+  JoystreamMediaLocation,
+  KnownLicense,
+  UserDefinedLicense,
+} from '../../../generated/graphql-server/src/modules/variants/variants.model'
 
 async function createBlockOrGetFromDatabase(db: DB, blockNumber: number): Promise<Block> {
   let b = await db.get(Block, { where: { block: blockNumber } })
@@ -59,16 +67,16 @@ async function createChannel(
 
   channel.version = block
   channel.id = id
-  channel.title = p.title
+  channel.handle = p.handle
   channel.description = p.description
-  channel.isCurated = p.isCurated || false
+  channel.isCurated = !!p.isCurated
   channel.isPublic = p.isPublic
-  channel.coverPhotoUrl = p.coverPhotoURL
-  channel.avatarPhotoUrl = p.avatarPhotoURL
+  channel.coverPhotoUrl = p.coverPhotoUrl
+  channel.avatarPhotoUrl = p.avatarPhotoUrl
 
   channel.happenedIn = await createBlockOrGetFromDatabase(db, block)
   const { language } = p
-  if (language !== undefined) {
+  if (language) {
     channel.language = await getOrCreate.language(
       { db, block, id },
       classEntityMap,
@@ -95,11 +103,11 @@ async function createCategory({ db, block, id }: IDBBlockId, p: ICategory): Prom
   return category
 }
 
-async function createKnownLicense({ db, block, id }: IDBBlockId, p: IKnownLicense): Promise<KnownLicense> {
-  const record = await db.get(KnownLicense, { where: { id } })
+async function createKnownLicense({ db, block, id }: IDBBlockId, p: IKnownLicense): Promise<KnownLicenseEntity> {
+  const record = await db.get(KnownLicenseEntity, { where: { id } })
   if (record) return record
 
-  const knownLicence = new KnownLicense()
+  const knownLicence = new KnownLicenseEntity()
 
   knownLicence.id = id
   knownLicence.code = p.code
@@ -115,28 +123,28 @@ async function createKnownLicense({ db, block, id }: IDBBlockId, p: IKnownLicens
 async function createUserDefinedLicense(
   { db, block, id }: IDBBlockId,
   p: IUserDefinedLicense
-): Promise<UserDefinedLicense> {
-  const record = await db.get(UserDefinedLicense, { where: { id } })
+): Promise<UserDefinedLicenseEntity> {
+  const record = await db.get(UserDefinedLicenseEntity, { where: { id } })
   if (record) return record
 
-  const userDefinedLicense = new UserDefinedLicense()
+  const userDefinedLicense = new UserDefinedLicenseEntity()
 
   userDefinedLicense.id = id
   userDefinedLicense.content = p.content
   userDefinedLicense.version = block
   userDefinedLicense.happenedIn = await createBlockOrGetFromDatabase(db, block)
-  await db.save<UserDefinedLicense>(userDefinedLicense)
+  await db.save<UserDefinedLicenseEntity>(userDefinedLicense)
   return userDefinedLicense
 }
 
 async function createJoystreamMediaLocation(
   { db, block, id }: IDBBlockId,
   p: IJoystreamMediaLocation
-): Promise<JoystreamMediaLocation> {
-  const record = await db.get(JoystreamMediaLocation, { where: { id } })
+): Promise<JoystreamMediaLocationEntity> {
+  const record = await db.get(JoystreamMediaLocationEntity, { where: { id } })
   if (record) return record
 
-  const joyMediaLoc = new JoystreamMediaLocation()
+  const joyMediaLoc = new JoystreamMediaLocationEntity()
 
   joyMediaLoc.id = id
   joyMediaLoc.dataObjectId = p.dataObjectId
@@ -149,11 +157,11 @@ async function createJoystreamMediaLocation(
 async function createHttpMediaLocation(
   { db, block, id }: IDBBlockId,
   p: IHttpMediaLocation
-): Promise<HttpMediaLocation> {
-  const record = await db.get(HttpMediaLocation, { where: { id } })
+): Promise<HttpMediaLocationEntity> {
+  const record = await db.get(HttpMediaLocationEntity, { where: { id } })
   if (record) return record
 
-  const httpMediaLoc = new HttpMediaLocation()
+  const httpMediaLoc = new HttpMediaLocationEntity()
 
   httpMediaLoc.id = id
   httpMediaLoc.url = p.url
@@ -187,16 +195,29 @@ async function createVideoMedia(
     )
   }
   if (location !== undefined) {
-    videoMedia.location = await getOrCreate.mediaLocation(
+    const m = await getOrCreate.mediaLocation(
       { db, block, id },
       classEntityMap,
       location,
       nextEntityIdBeforeTransaction
     )
+    videoMedia.locationEntity = m
+    const { httpMediaLocation, joystreamMediaLocation } = m
+    if (httpMediaLocation) {
+      const mediaLoc = new HttpMediaLocation()
+      mediaLoc.port = httpMediaLocation.port
+      mediaLoc.url = httpMediaLocation.url
+      videoMedia.location = mediaLoc
+    }
+    if (joystreamMediaLocation) {
+      const mediaLoc = new JoystreamMediaLocation()
+      mediaLoc.dataObjectId = joystreamMediaLocation.dataObjectId
+      videoMedia.location = mediaLoc
+    }
   }
 
   videoMedia.happenedIn = await createBlockOrGetFromDatabase(db, block)
-  await db.save(videoMedia)
+  await db.save<VideoMedia>(videoMedia)
   return videoMedia
 }
 
@@ -216,14 +237,14 @@ async function createVideo(
   video.description = p.description
   video.duration = p.duration
   video.hasMarketing = p.hasMarketing
-  // TODO: needs to be handled correctly, from runtime CurationStatus is coming
-  video.isCurated = p.isCurated || true
+  video.isCurated = !!p.isCurated
   video.isExplicit = p.isExplicit
   video.isPublic = p.isPublic
   video.publishedBeforeJoystream = p.publishedBeforeJoystream
   video.skippableIntroDuration = p.skippableIntroDuration
-  video.thumbnailUrl = p.thumbnailURL
+  video.thumbnailUrl = p.thumbnailUrl
   video.version = block
+  video.isFeatured = false
 
   const { language, license, category, channel, media } = p
   if (language !== undefined) {
@@ -234,8 +255,9 @@ async function createVideo(
       nextEntityIdBeforeTransaction
     )
   }
-  if (license !== undefined) {
-    video.license = await getOrCreate.license({ db, block, id }, classEntityMap, license, nextEntityIdBeforeTransaction)
+  if (license) {
+    const lic = await getOrCreate.license({ db, block, id }, classEntityMap, license, nextEntityIdBeforeTransaction)
+    video.license = lic
   }
   if (category !== undefined) {
     video.category = await getOrCreate.category(
@@ -293,32 +315,45 @@ async function createLicense(
   classEntityMap: ClassEntityMap,
   p: ILicense,
   nextEntityIdBeforeTransaction: number
-): Promise<License> {
-  const record = await db.get(License, { where: { id } })
+): Promise<LicenseEntity> {
+  const record = await db.get(LicenseEntity, { where: { id } })
   if (record) return record
 
-  const { knownLicense, userDefinedLicense } = p
+  const license = new LicenseEntity()
 
-  const license = new License()
-  license.id = id
-  if (knownLicense !== undefined) {
-    license.knownLicense = await getOrCreate.knownLicense(
+  if (p.knownLicense) {
+    const kLicense = await getOrCreate.knownLicense(
       { db, block, id },
       classEntityMap,
-      knownLicense,
+      p.knownLicense,
       nextEntityIdBeforeTransaction
     )
+    const k = new KnownLicense()
+    k.code = kLicense.code
+    k.description = kLicense.description
+    k.name = kLicense.name
+    k.url = kLicense.url
+    // Set the license type
+    license.type = k
   }
-  if (userDefinedLicense !== undefined) {
-    license.userdefinedLicense = await getOrCreate.userDefinedLicense(
+  if (p.userDefinedLicense) {
+    const { content } = await getOrCreate.userDefinedLicense(
       { db, block, id },
       classEntityMap,
-      userDefinedLicense,
+      p.userDefinedLicense,
       nextEntityIdBeforeTransaction
     )
+    const u = new UserDefinedLicense()
+    u.content = content
+    // Set the license type
+    license.type = u
   }
+
+  license.id = id
+  license.attribution = p.attribution
   license.happenedIn = await createBlockOrGetFromDatabase(db, block)
-  await db.save<License>(license)
+
+  await db.save<LicenseEntity>(license)
   return license
 }
 
@@ -327,10 +362,10 @@ async function createMediaLocation(
   classEntityMap: ClassEntityMap,
   p: IMediaLocation,
   nextEntityIdBeforeTransaction: number
-): Promise<MediaLocation> {
+): Promise<MediaLocationEntity> {
   const { httpMediaLocation, joystreamMediaLocation } = p
 
-  const location = new MediaLocation()
+  const location = new MediaLocationEntity()
   location.id = id
   if (httpMediaLocation !== undefined) {
     location.httpMediaLocation = await getOrCreate.httpMediaLocation(
@@ -349,10 +384,33 @@ async function createMediaLocation(
     )
   }
   location.happenedIn = await createBlockOrGetFromDatabase(db, block)
-  await db.save<License>(location)
+  await db.save<MediaLocationEntity>(location)
   return location
 }
 
+async function createFeaturedVideo(
+  { db, block, id }: IDBBlockId,
+  classEntityMap: ClassEntityMap,
+  p: IFeaturedVideo,
+  nextEntityIdBeforeTransaction: number
+): Promise<void> {
+  const featuredVideo = new FeaturedVideo()
+
+  featuredVideo.video = await getOrCreate.video(
+    { db, block, id },
+    classEntityMap,
+    p.video!,
+    nextEntityIdBeforeTransaction
+  )
+
+  featuredVideo.id = id
+  featuredVideo.version = block
+  featuredVideo.video.isFeatured = true
+
+  await db.save<Video>(featuredVideo.video)
+  await db.save<FeaturedVideo>(featuredVideo)
+}
+
 async function getClassName(
   db: DB,
   entity: IEntity,
@@ -394,4 +452,5 @@ export {
   createMediaLocation,
   createBlockOrGetFromDatabase,
   getClassName,
+  createFeaturedVideo,
 }

+ 29 - 3
query-node/mappings/content-directory/entity/index.ts

@@ -16,6 +16,7 @@ import {
   updateVideoMediaEncodingEntityPropertyValues,
   updateLicenseEntityPropertyValues,
   updateMediaLocationEntityPropertyValues,
+  updateFeaturedVideoEntityPropertyValues,
 } from './update'
 import {
   removeCategory,
@@ -30,6 +31,7 @@ import {
   removeVideoMediaEncoding,
   removeLicense,
   removeMediaLocation,
+  removeFeaturedVideo,
 } from './remove'
 import {
   createCategory,
@@ -43,9 +45,10 @@ import {
   createLanguage,
   createVideoMediaEncoding,
   createBlockOrGetFromDatabase,
+  createFeaturedVideo,
 } from './create'
 import {
-  CategoryPropertyNamesWithId,
+  categoryPropertyNamesWithId,
   channelPropertyNamesWithId,
   httpMediaLocationPropertyNamesWithId,
   joystreamMediaLocationPropertyNamesWithId,
@@ -56,6 +59,7 @@ import {
   videoPropertyNamesWithId,
   contentDirectoryClassNamesWithId,
   ContentDirectoryKnownClasses,
+  featuredVideoPropertyNamesWithId,
 } from '../content-dir-consts'
 
 import {
@@ -74,6 +78,7 @@ import {
   IEntity,
   ILicense,
   IMediaLocation,
+  IFeaturedVideo,
 } from '../../types'
 import { getOrCreate } from '../get-or-create'
 
@@ -112,7 +117,7 @@ async function contentDirectory_EntitySchemaSupportAdded(db: DB, event: Substrat
       break
 
     case ContentDirectoryKnownClasses.CATEGORY:
-      await createCategory(arg, decode.setProperties<ICategory>(event, CategoryPropertyNamesWithId))
+      await createCategory(arg, decode.setProperties<ICategory>(event, categoryPropertyNamesWithId))
       break
 
     case ContentDirectoryKnownClasses.KNOWNLICENSE:
@@ -168,6 +173,14 @@ async function contentDirectory_EntitySchemaSupportAdded(db: DB, event: Substrat
         decode.setProperties<IVideoMediaEncoding>(event, videoMediaEncodingPropertyNamesWithId)
       )
       break
+    case ContentDirectoryKnownClasses.FEATUREDVIDEOS:
+      await createFeaturedVideo(
+        arg,
+        new Map<string, IEntity[]>(),
+        decode.setProperties<IFeaturedVideo>(event, featuredVideoPropertyNamesWithId),
+        0
+      )
+      break
 
     default:
       throw new Error(`Unknown class name: ${cls.name}`)
@@ -241,6 +254,10 @@ async function contentDirectory_EntityRemoved(db: DB, event: SubstrateEvent): Pr
       await removeMediaLocation(db, where)
       break
 
+    case ContentDirectoryKnownClasses.FEATUREDVIDEOS:
+      await removeFeaturedVideo(db, where)
+      break
+
     default:
       throw new Error(`Unknown class name: ${cls.name}`)
   }
@@ -296,7 +313,7 @@ async function contentDirectory_EntityPropertyValuesUpdated(db: DB, event: Subst
       await updateCategoryEntityPropertyValues(
         db,
         where,
-        decode.setProperties<ICategory>(event, CategoryPropertyNamesWithId)
+        decode.setProperties<ICategory>(event, categoryPropertyNamesWithId)
       )
       break
 
@@ -379,6 +396,15 @@ async function contentDirectory_EntityPropertyValuesUpdated(db: DB, event: Subst
       )
       break
 
+    case ContentDirectoryKnownClasses.FEATUREDVIDEOS:
+      await updateFeaturedVideoEntityPropertyValues(
+        db,
+        where,
+        decode.setProperties<IFeaturedVideo>(event, featuredVideoPropertyNamesWithId),
+        0
+      )
+      break
+
     default:
       throw new Error(`Unknown class name: ${cls.name}`)
   }

+ 69 - 46
query-node/mappings/content-directory/entity/remove.ts

@@ -1,97 +1,119 @@
+import assert from 'assert'
+
 import { DB } from '../../../generated/indexer'
 import { Channel } from '../../../generated/graphql-server/src/modules/channel/channel.model'
 import { Category } from '../../../generated/graphql-server/src/modules/category/category.model'
-import { KnownLicense } from '../../../generated/graphql-server/src/modules/known-license/known-license.model'
-import { UserDefinedLicense } from '../../../generated/graphql-server/src/modules/user-defined-license/user-defined-license.model'
-import { JoystreamMediaLocation } from '../../../generated/graphql-server/src/modules/joystream-media-location/joystream-media-location.model'
-import { HttpMediaLocation } from '../../../generated/graphql-server/src/modules/http-media-location/http-media-location.model'
+import { KnownLicenseEntity } from '../../../generated/graphql-server/src/modules/known-license-entity/known-license-entity.model'
+import { UserDefinedLicenseEntity } from '../../../generated/graphql-server/src/modules/user-defined-license-entity/user-defined-license-entity.model'
+import { JoystreamMediaLocationEntity } from '../../../generated/graphql-server/src/modules/joystream-media-location-entity/joystream-media-location-entity.model'
+import { HttpMediaLocationEntity } from '../../../generated/graphql-server/src/modules/http-media-location-entity/http-media-location-entity.model'
 import { VideoMedia } from '../../../generated/graphql-server/src/modules/video-media/video-media.model'
 import { Video } from '../../../generated/graphql-server/src/modules/video/video.model'
 import { Language } from '../../../generated/graphql-server/src/modules/language/language.model'
 import { VideoMediaEncoding } from '../../../generated/graphql-server/src/modules/video-media-encoding/video-media-encoding.model'
-import { License } from '../../../generated/graphql-server/src/modules/license/license.model'
-import { MediaLocation } from '../../../generated/graphql-server/src/modules/media-location/media-location.model'
+import { LicenseEntity } from '../../../generated/graphql-server/src/modules/license-entity/license-entity.model'
+import { MediaLocationEntity } from '../../../generated/graphql-server/src/modules/media-location-entity/media-location-entity.model'
+import { FeaturedVideo } from '../../../generated/graphql-server/src/modules/featured-video/featured-video.model'
 
 import { IWhereCond } from '../../types'
 
+function assertKeyViolation(entityName: string, entityId: string) {
+  assert(false, `Can not remove ${entityName}(${entityId})! There are references to this entity`)
+}
+
 async function removeChannel(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(Channel, where)
-  if (record === undefined) throw Error(`Channel not found`)
-  if (record.videos) record.videos.map(async (v) => await removeVideo(db, { where: { id: v.id } }))
+  if (!record) throw Error(`Channel(${where.where.id}) not found`)
+  if (record.videos && record.videos.length) assertKeyViolation(`Channel`, record.id)
   await db.remove<Channel>(record)
 }
+
 async function removeCategory(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(Category, where)
-  if (record === undefined) throw Error(`Category not found`)
-  if (record.videos) record.videos.map(async (v) => await removeVideo(db, { where: { id: v.id } }))
+  if (!record) throw Error(`Category(${where.where.id}) not found`)
+  if (record.videos && record.videos.length) assertKeyViolation(`Category`, record.id)
   await db.remove<Category>(record)
 }
 async function removeVideoMedia(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(VideoMedia, where)
-  if (record === undefined) throw Error(`VideoMedia not found`)
-  if (record.video) await db.remove<Video>(record.video)
+  if (!record) throw Error(`VideoMedia(${where.where.id}) not found`)
+  if (record.video) assertKeyViolation(`VideoMedia`, record.id)
   await db.remove<VideoMedia>(record)
 }
 async function removeVideo(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(Video, where)
-  if (record === undefined) throw Error(`Video not found`)
+  if (!record) throw Error(`Video(${where.where.id}) not found`)
   await db.remove<Video>(record)
 }
 
 async function removeLicense(db: DB, where: IWhereCond): Promise<void> {
-  const record = await db.get(License, where)
-  if (record === undefined) throw Error(`License not found`)
-  // Remove all the videos under this license
-  if (record.videolicense) record.videolicense.map(async (v) => await removeVideo(db, { where: { id: v.id } }))
-  await db.remove<License>(record)
+  const record = await db.get(LicenseEntity, where)
+  if (!record) throw Error(`License(${where.where.id}) not found`)
+  if (record.videolicense && record.videolicense.length) assertKeyViolation(`License`, record.id)
+  await db.remove<LicenseEntity>(record)
 }
+
 async function removeUserDefinedLicense(db: DB, where: IWhereCond): Promise<void> {
-  const record = await db.get(UserDefinedLicense, where)
-  if (record === undefined) throw Error(`UserDefinedLicense not found`)
-  if (record.licenseuserdefinedLicense)
-    record.licenseuserdefinedLicense.map(async (l) => await removeLicense(db, { where: { id: l.id } }))
-  await db.remove<UserDefinedLicense>(record)
+  const record = await db.get(UserDefinedLicenseEntity, where)
+  if (!record) throw Error(`UserDefinedLicense(${where.where.id}) not found`)
+  await db.remove<UserDefinedLicenseEntity>(record)
 }
+
 async function removeKnownLicense(db: DB, where: IWhereCond): Promise<void> {
-  const record = await db.get(KnownLicense, where)
-  if (record === undefined) throw Error(`KnownLicense not found`)
-  if (record.licenseknownLicense)
-    record.licenseknownLicense.map(async (k) => await removeLicense(db, { where: { id: k.id } }))
-  await db.remove<KnownLicense>(record)
+  const record = await db.get(KnownLicenseEntity, where)
+  if (!record) throw Error(`KnownLicense(${where.where.id}) not found`)
+  await db.remove<KnownLicenseEntity>(record)
 }
 async function removeMediaLocation(db: DB, where: IWhereCond): Promise<void> {
-  const record = await db.get(MediaLocation, where)
-  if (record === undefined) throw Error(`MediaLocation not found`)
-  if (record.videoMedia) await removeVideo(db, { where: { id: record.videoMedia.id } })
-  await db.remove<MediaLocation>(record)
+  const record = await db.get(MediaLocationEntity, where)
+  if (!record) throw Error(`MediaLocation(${where.where.id}) not found`)
+  if (record.videoMedia) assertKeyViolation('MediaLocation', record.id)
+  await db.remove<MediaLocationEntity>(record)
 }
+
 async function removeHttpMediaLocation(db: DB, where: IWhereCond): Promise<void> {
-  const record = await db.get(HttpMediaLocation, where)
-  if (record === undefined) throw Error(`HttpMediaLocation not found`)
-  if (record.medialocationhttpMediaLocation)
-    record.medialocationhttpMediaLocation.map(async (v) => await removeMediaLocation(db, { where: { id: v.id } }))
-  await db.remove<HttpMediaLocation>(record)
+  const record = await db.get(HttpMediaLocationEntity, where)
+  if (!record) throw Error(`HttpMediaLocation(${where.where.id}) not found`)
+  if (record.medialocationentityhttpMediaLocation && record.medialocationentityhttpMediaLocation.length) {
+    assertKeyViolation('HttpMediaLocation', record.id)
+  }
+  await db.remove<HttpMediaLocationEntity>(record)
 }
+
 async function removeJoystreamMediaLocation(db: DB, where: IWhereCond): Promise<void> {
-  const record = await db.get(JoystreamMediaLocation, where)
-  if (record === undefined) throw Error(`JoystreamMediaLocation not found`)
-  if (record.medialocationjoystreamMediaLocation)
-    record.medialocationjoystreamMediaLocation.map(async (v) => await removeVideo(db, { where: { id: v.id } }))
-  await db.remove<JoystreamMediaLocation>(record)
+  const record = await db.get(JoystreamMediaLocationEntity, where)
+  if (!record) throw Error(`JoystreamMediaLocation(${where.where.id}) not found`)
+  if (record.medialocationentityjoystreamMediaLocation && record.medialocationentityjoystreamMediaLocation.length) {
+    assertKeyViolation('JoystreamMediaLocation', record.id)
+  }
+  await db.remove<JoystreamMediaLocationEntity>(record)
 }
+
 async function removeLanguage(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(Language, where)
-  if (record === undefined) throw Error(`Language not found`)
-  if (record.channellanguage) record.channellanguage.map(async (c) => await removeChannel(db, { where: { id: c.id } }))
-  if (record.videolanguage) record.videolanguage.map(async (v) => await removeVideo(db, { where: { id: v.id } }))
+  if (!record) throw Error(`Language(${where.where.id}) not found`)
+  if (record.channellanguage && record.channellanguage.length) assertKeyViolation('Language', record.id)
+  if (record.videolanguage && record.videolanguage.length) assertKeyViolation('Language', record.id)
   await db.remove<Language>(record)
 }
+
 async function removeVideoMediaEncoding(db: DB, where: IWhereCond): Promise<void> {
   const record = await db.get(VideoMediaEncoding, where)
-  if (record === undefined) throw Error(`Language not found`)
+  if (!record) throw Error(`VideoMediaEncoding(${where.where.id}) not found`)
   await db.remove<VideoMediaEncoding>(record)
 }
 
+async function removeFeaturedVideo(db: DB, where: IWhereCond): Promise<void> {
+  const record = await db.get(FeaturedVideo, { ...where, relations: ['video'] })
+  if (!record) throw Error(`FeaturedVideo(${where.where.id}) not found`)
+
+  record.video.isFeatured = false
+  record.video.featured = undefined
+
+  await db.save<Video>(record.video)
+  await db.remove<FeaturedVideo>(record)
+}
+
 export {
   removeCategory,
   removeChannel,
@@ -105,4 +127,5 @@ export {
   removeVideoMediaEncoding,
   removeMediaLocation,
   removeLicense,
+  removeFeaturedVideo,
 }

+ 105 - 33
query-node/mappings/content-directory/entity/update.ts

@@ -1,20 +1,22 @@
 import { DB } from '../../../generated/indexer'
 import { Channel } from '../../../generated/graphql-server/src/modules/channel/channel.model'
 import { Category } from '../../../generated/graphql-server/src/modules/category/category.model'
-import { KnownLicense } from '../../../generated/graphql-server/src/modules/known-license/known-license.model'
-import { UserDefinedLicense } from '../../../generated/graphql-server/src/modules/user-defined-license/user-defined-license.model'
-import { JoystreamMediaLocation } from '../../../generated/graphql-server/src/modules/joystream-media-location/joystream-media-location.model'
-import { HttpMediaLocation } from '../../../generated/graphql-server/src/modules/http-media-location/http-media-location.model'
+import { KnownLicenseEntity } from '../../../generated/graphql-server/src/modules/known-license-entity/known-license-entity.model'
+import { UserDefinedLicenseEntity } from '../../../generated/graphql-server/src/modules/user-defined-license-entity/user-defined-license-entity.model'
 import { VideoMedia } from '../../../generated/graphql-server/src/modules/video-media/video-media.model'
 import { Video } from '../../../generated/graphql-server/src/modules/video/video.model'
 import { Language } from '../../../generated/graphql-server/src/modules/language/language.model'
 import { VideoMediaEncoding } from '../../../generated/graphql-server/src/modules/video-media-encoding/video-media-encoding.model'
-import { License } from '../../../generated/graphql-server/src/modules/license/license.model'
-import { MediaLocation } from '../../../generated/graphql-server/src/modules/media-location/media-location.model'
+import { LicenseEntity } from '../../../generated/graphql-server/src/modules/license-entity/license-entity.model'
+import { MediaLocationEntity } from '../../../generated/graphql-server/src/modules/media-location-entity/media-location-entity.model'
+import { HttpMediaLocationEntity } from '../../../generated/graphql-server/src/modules/http-media-location-entity/http-media-location-entity.model'
+import { JoystreamMediaLocationEntity } from '../../../generated/graphql-server/src/modules/joystream-media-location-entity/joystream-media-location-entity.model'
+import { FeaturedVideo } from '../../../generated/graphql-server/src/modules/featured-video/featured-video.model'
 
 import {
   ICategory,
   IChannel,
+  IFeaturedVideo,
   IHttpMediaLocation,
   IJoystreamMediaLocation,
   IKnownLicense,
@@ -28,6 +30,12 @@ import {
   IVideoMediaEncoding,
   IWhereCond,
 } from '../../types'
+import {
+  HttpMediaLocation,
+  JoystreamMediaLocation,
+  KnownLicense,
+  UserDefinedLicense,
+} from '../../../generated/graphql-server/src/modules/variants/variants.model'
 
 function getEntityIdFromReferencedField(ref: IReference, entityIdBeforeTransaction: number): string {
   const { entityId, existing } = ref
@@ -42,18 +50,18 @@ async function updateMediaLocationEntityPropertyValues(
   entityIdBeforeTransaction: number
 ): Promise<void> {
   const { httpMediaLocation, joystreamMediaLocation } = props
-  const record = await db.get(MediaLocation, where)
+  const record = await db.get(MediaLocationEntity, where)
   if (record === undefined) throw Error(`MediaLocation entity not found: ${where.where.id}`)
 
   if (httpMediaLocation) {
     const id = getEntityIdFromReferencedField(httpMediaLocation, entityIdBeforeTransaction)
-    record.httpMediaLocation = await db.get(HttpMediaLocation, { where: { id } })
+    record.httpMediaLocation = await db.get(HttpMediaLocationEntity, { where: { id } })
   }
   if (joystreamMediaLocation) {
     const id = getEntityIdFromReferencedField(joystreamMediaLocation, entityIdBeforeTransaction)
-    record.joystreamMediaLocation = await db.get(JoystreamMediaLocation, { where: { id } })
+    record.joystreamMediaLocation = await db.get(JoystreamMediaLocationEntity, { where: { id } })
   }
-  await db.save<MediaLocation>(record)
+  await db.save<MediaLocationEntity>(record)
 }
 
 async function updateLicenseEntityPropertyValues(
@@ -62,19 +70,36 @@ async function updateLicenseEntityPropertyValues(
   props: ILicense,
   entityIdBeforeTransaction: number
 ): Promise<void> {
-  const record = await db.get(License, where)
+  const record = await db.get(LicenseEntity, where)
   if (record === undefined) throw Error(`License entity not found: ${where.where.id}`)
 
   const { knownLicense, userDefinedLicense } = props
   if (knownLicense) {
     const id = getEntityIdFromReferencedField(knownLicense, entityIdBeforeTransaction)
-    record.knownLicense = await db.get(KnownLicense, { where: { id } })
+    const kLicense = await db.get(KnownLicenseEntity, { where: { id } })
+    if (!kLicense) throw Error(`KnownLicense not found ${id}`)
+
+    const k = new KnownLicense()
+    k.code = kLicense.code
+    k.description = kLicense.description
+    k.name = kLicense.name
+    k.url = kLicense.url
+    // Set the license type
+    record.type = k
   }
   if (userDefinedLicense) {
     const id = getEntityIdFromReferencedField(userDefinedLicense, entityIdBeforeTransaction)
-    record.userdefinedLicense = await db.get(UserDefinedLicense, { where: { id } })
+    const udl = await db.get(UserDefinedLicenseEntity, { where: { id } })
+    if (!udl) throw Error(`UserDefinedLicense not found ${id}`)
+
+    const u = new UserDefinedLicense()
+    u.content = udl.content
+    // Set the license type
+    record.type = u
   }
-  await db.save<License>(record)
+
+  record.attribution = props.attribution || record.attribution
+  await db.save<LicenseEntity>(record)
 }
 
 async function updateCategoryEntityPropertyValues(db: DB, where: IWhereCond, props: ICategory): Promise<void> {
@@ -83,6 +108,7 @@ async function updateCategoryEntityPropertyValues(db: DB, where: IWhereCond, pro
   Object.assign(record, props)
   await db.save<Category>(record)
 }
+
 async function updateChannelEntityPropertyValues(
   db: DB,
   where: IWhereCond,
@@ -92,8 +118,8 @@ async function updateChannelEntityPropertyValues(
   const record = await db.get(Channel, where)
   if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
 
-  let lang: Language | undefined
-  if (props.language !== undefined) {
+  let lang: Language | undefined = record.language
+  if (props.language) {
     const id = getEntityIdFromReferencedField(props.language, entityIdBeforeTransaction)
     lang = await db.get(Language, { where: { id } })
     if (lang === undefined) throw Error(`Language entity not found: ${id}`)
@@ -101,9 +127,10 @@ async function updateChannelEntityPropertyValues(
   }
   Object.assign(record, props)
 
-  record.language = lang || record.language
+  record.language = lang
   await db.save<Channel>(record)
 }
+
 async function updateVideoMediaEntityPropertyValues(
   db: DB,
   where: IWhereCond,
@@ -114,7 +141,7 @@ async function updateVideoMediaEntityPropertyValues(
   if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
 
   let enco: VideoMediaEncoding | undefined
-  let mediaLoc: MediaLocation | undefined
+  let mediaLoc: HttpMediaLocation | JoystreamMediaLocation = record.location
   const { encoding, location } = props
   if (encoding) {
     const id = getEntityIdFromReferencedField(encoding, entityIdBeforeTransaction)
@@ -122,18 +149,31 @@ async function updateVideoMediaEntityPropertyValues(
     if (enco === undefined) throw Error(`VideoMediaEncoding entity not found: ${id}`)
     props.encoding = undefined
   }
+
   if (location) {
     const id = getEntityIdFromReferencedField(location, entityIdBeforeTransaction)
-    mediaLoc = await db.get(MediaLocation, { where: { id } })
-    if (!mediaLoc) throw Error(`MediaLocation entity not found: ${id}`)
+    const mLoc = await db.get(MediaLocationEntity, { where: { id } })
+    if (!mLoc) throw Error(`MediaLocation entity not found: ${id}`)
+    const { httpMediaLocation, joystreamMediaLocation } = mLoc
+
+    if (httpMediaLocation) {
+      mediaLoc = new HttpMediaLocation()
+      mediaLoc.url = httpMediaLocation.url
+      mediaLoc.port = httpMediaLocation.port
+    }
+    if (joystreamMediaLocation) {
+      mediaLoc = new JoystreamMediaLocation()
+      mediaLoc.dataObjectId = joystreamMediaLocation.dataObjectId
+    }
     props.location = undefined
   }
   Object.assign(record, props)
 
   record.encoding = enco || record.encoding
-  record.location = mediaLoc || record.location
+  record.location = mediaLoc
   await db.save<VideoMedia>(record)
 }
+
 async function updateVideoEntityPropertyValues(
   db: DB,
   where: IWhereCond,
@@ -147,7 +187,7 @@ async function updateVideoEntityPropertyValues(
   let cat: Category | undefined
   let lang: Language | undefined
   let vMedia: VideoMedia | undefined
-  let lic: License | undefined
+
   const { channel, category, language, media, license } = props
   if (channel) {
     const id = getEntityIdFromReferencedField(channel, entityIdBeforeTransaction)
@@ -169,8 +209,9 @@ async function updateVideoEntityPropertyValues(
   }
   if (license) {
     const id = getEntityIdFromReferencedField(license, entityIdBeforeTransaction)
-    lic = await db.get(License, { where: { id } })
-    if (!lic) throw Error(`License entity not found: ${id}`)
+    const licenseEntity = await db.get(LicenseEntity, { where: { id } })
+    if (!licenseEntity) throw Error(`License entity not found: ${id}`)
+    record.license = licenseEntity
     props.license = undefined
   }
   if (language) {
@@ -185,36 +226,38 @@ async function updateVideoEntityPropertyValues(
   record.channel = chann || record.channel
   record.category = cat || record.category
   record.media = vMedia || record.media
-  record.license = lic || record.license
   record.language = lang
 
   await db.save<Video>(record)
 }
+
 async function updateUserDefinedLicenseEntityPropertyValues(
   db: DB,
   where: IWhereCond,
   props: IUserDefinedLicense
 ): Promise<void> {
-  const record = await db.get(UserDefinedLicense, where)
+  const record = await db.get(UserDefinedLicenseEntity, where)
   if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
   Object.assign(record, props)
-  await db.save<UserDefinedLicense>(record)
+  await db.save<UserDefinedLicenseEntity>(record)
 }
+
 async function updateKnownLicenseEntityPropertyValues(db: DB, where: IWhereCond, props: IKnownLicense): Promise<void> {
-  const record = await db.get(KnownLicense, where)
+  const record = await db.get(KnownLicenseEntity, where)
   if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
   Object.assign(record, props)
-  await db.save<KnownLicense>(record)
+  await db.save<KnownLicenseEntity>(record)
 }
+
 async function updateHttpMediaLocationEntityPropertyValues(
   db: DB,
   where: IWhereCond,
   props: IHttpMediaLocation
 ): Promise<void> {
-  const record = await db.get(HttpMediaLocation, where)
+  const record = await db.get(HttpMediaLocationEntity, where)
   if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
   Object.assign(record, props)
-  await db.save<HttpMediaLocation>(record)
+  await db.save<HttpMediaLocationEntity>(record)
 }
 
 async function updateJoystreamMediaLocationEntityPropertyValues(
@@ -222,17 +265,19 @@ async function updateJoystreamMediaLocationEntityPropertyValues(
   where: IWhereCond,
   props: IJoystreamMediaLocation
 ): Promise<void> {
-  const record = await db.get(JoystreamMediaLocation, where)
+  const record = await db.get(JoystreamMediaLocationEntity, where)
   if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
   Object.assign(record, props)
-  await db.save<JoystreamMediaLocation>(record)
+  await db.save<JoystreamMediaLocationEntity>(record)
 }
+
 async function updateLanguageEntityPropertyValues(db: DB, where: IWhereCond, props: ILanguage): Promise<void> {
   const record = await db.get(Language, where)
   if (record === undefined) throw Error(`Entity not found: ${where.where.id}`)
   Object.assign(record, props)
   await db.save<Language>(record)
 }
+
 async function updateVideoMediaEncodingEntityPropertyValues(
   db: DB,
   where: IWhereCond,
@@ -244,6 +289,32 @@ async function updateVideoMediaEncodingEntityPropertyValues(
   await db.save<VideoMediaEncoding>(record)
 }
 
+async function updateFeaturedVideoEntityPropertyValues(
+  db: DB,
+  where: IWhereCond,
+  props: IFeaturedVideo,
+  entityIdBeforeTransaction: number
+): Promise<void> {
+  const record = await db.get(FeaturedVideo, { ...where, relations: ['video'] })
+  if (record === undefined) throw Error(`FeaturedVideo entity not found: ${where.where.id}`)
+
+  if (props.video) {
+    const id = getEntityIdFromReferencedField(props.video, entityIdBeforeTransaction)
+    const video = await db.get(Video, { where: { id } })
+    if (!video) throw Error(`Video entity not found: ${id}`)
+
+    // Update old video isFeatured to false
+    record.video.isFeatured = false
+    await db.save<Video>(record.video)
+
+    video.isFeatured = true
+    record.video = video
+
+    await db.save<Video>(video)
+    await db.save<FeaturedVideo>(record)
+  }
+}
+
 export {
   updateCategoryEntityPropertyValues,
   updateChannelEntityPropertyValues,
@@ -257,4 +328,5 @@ export {
   updateVideoMediaEncodingEntityPropertyValues,
   updateLicenseEntityPropertyValues,
   updateMediaLocationEntityPropertyValues,
+  updateFeaturedVideoEntityPropertyValues,
 }

+ 69 - 40
query-node/mappings/content-directory/get-or-create.ts

@@ -1,19 +1,20 @@
 import { Channel } from '../../generated/graphql-server/src/modules/channel/channel.model'
 import { Category } from '../../generated/graphql-server/src/modules/category/category.model'
-import { KnownLicense } from '../../generated/graphql-server/src/modules/known-license/known-license.model'
-import { UserDefinedLicense } from '../../generated/graphql-server/src/modules/user-defined-license/user-defined-license.model'
-import { JoystreamMediaLocation } from '../../generated/graphql-server/src/modules/joystream-media-location/joystream-media-location.model'
-import { HttpMediaLocation } from '../../generated/graphql-server/src/modules/http-media-location/http-media-location.model'
+import { KnownLicenseEntity } from '../../generated/graphql-server/src/modules/known-license-entity/known-license-entity.model'
+import { UserDefinedLicenseEntity } from '../../generated/graphql-server/src/modules/user-defined-license-entity/user-defined-license-entity.model'
+import { JoystreamMediaLocationEntity } from '../../generated/graphql-server/src/modules/joystream-media-location-entity/joystream-media-location-entity.model'
+import { HttpMediaLocationEntity } from '../../generated/graphql-server/src/modules/http-media-location-entity/http-media-location-entity.model'
 import { VideoMedia } from '../../generated/graphql-server/src/modules/video-media/video-media.model'
 import { Language } from '../../generated/graphql-server/src/modules/language/language.model'
 import { VideoMediaEncoding } from '../../generated/graphql-server/src/modules/video-media-encoding/video-media-encoding.model'
-import { License } from '../../generated/graphql-server/src/modules/license/license.model'
-import { MediaLocation } from '../../generated/graphql-server/src/modules/media-location/media-location.model'
+import { LicenseEntity } from '../../generated/graphql-server/src/modules/license-entity/license-entity.model'
+import { MediaLocationEntity } from '../../generated/graphql-server/src/modules/media-location-entity/media-location-entity.model'
+import { Video } from '../../generated/graphql-server/src/modules/video/video.model'
 import { NextEntityId } from '../../generated/graphql-server/src/modules/next-entity-id/next-entity-id.model'
 
 import { decode } from './decode'
 import {
-  CategoryPropertyNamesWithId,
+  categoryPropertyNamesWithId,
   channelPropertyNamesWithId,
   httpMediaLocationPropertyNamesWithId,
   joystreamMediaLocationPropertyNamesWithId,
@@ -39,6 +40,7 @@ import {
   IMediaLocation,
   IReference,
   IUserDefinedLicense,
+  IVideo,
   IVideoMedia,
   IVideoMediaEncoding,
 } from '../types'
@@ -55,6 +57,7 @@ import {
   createVideoMediaEncoding,
   createLicense,
   createMediaLocation,
+  createVideo,
 } from './entity/create'
 
 import { DB } from '../../generated/indexer'
@@ -76,7 +79,12 @@ function findEntity(entityId: number, className: string, classEntityMap: ClassEn
   if (newlyCreatedEntities === undefined) throw Error(`Couldn't find '${className}' entities in the classEntityMap`)
   const entity = newlyCreatedEntities.find((e) => e.indexOf === entityId)
   if (!entity) throw Error(`Unknown ${className} entity id: ${entityId}`)
-  removeInsertedEntity(className, entityId, classEntityMap)
+
+  // Remove the inserted entity from the list
+  classEntityMap.set(
+    className,
+    newlyCreatedEntities.filter((e) => e.entityId !== entityId)
+  )
   return entity
 }
 
@@ -167,17 +175,17 @@ async function knownLicense(
   classEntityMap: ClassEntityMap,
   knownLicense: IReference,
   nextEntityIdBeforeTransaction: number
-): Promise<KnownLicense> {
-  let kLicense: KnownLicense | undefined
+): Promise<KnownLicenseEntity> {
+  let kLicense: KnownLicenseEntity | undefined
   const { entityId, existing } = knownLicense
   if (existing) {
-    kLicense = await db.get(KnownLicense, { where: { id: entityId.toString() } })
+    kLicense = await db.get(KnownLicenseEntity, { where: { id: entityId.toString() } })
     if (!kLicense) throw Error(`KnownLicense entity not found`)
     return kLicense
   }
   const id = generateEntityIdFromIndex(nextEntityIdBeforeTransaction + entityId)
   // could be created in the transaction
-  kLicense = await db.get(KnownLicense, { where: { id } })
+  kLicense = await db.get(KnownLicenseEntity, { where: { id } })
   if (kLicense) return kLicense
 
   const { properties } = findEntity(entityId, 'KnownLicense', classEntityMap)
@@ -191,17 +199,17 @@ async function userDefinedLicense(
   classEntityMap: ClassEntityMap,
   userDefinedLicense: IReference,
   nextEntityIdBeforeTransaction: number
-): Promise<UserDefinedLicense> {
-  let udLicense: UserDefinedLicense | undefined
+): Promise<UserDefinedLicenseEntity> {
+  let udLicense: UserDefinedLicenseEntity | undefined
   const { entityId, existing } = userDefinedLicense
   if (existing) {
-    udLicense = await db.get(UserDefinedLicense, { where: { id: entityId.toString() } })
+    udLicense = await db.get(UserDefinedLicenseEntity, { where: { id: entityId.toString() } })
     if (!udLicense) throw Error(`UserDefinedLicense entity not found`)
     return udLicense
   }
   const id = generateEntityIdFromIndex(nextEntityIdBeforeTransaction + entityId)
   // could be created in the transaction
-  udLicense = await db.get(UserDefinedLicense, {
+  udLicense = await db.get(UserDefinedLicenseEntity, {
     where: { id },
   })
   if (udLicense) return udLicense
@@ -264,7 +272,7 @@ async function category(
   const { properties } = findEntity(entityId, 'Category', classEntityMap)
   return await createCategory(
     { db, block, id },
-    decode.setEntityPropertyValues<ICategory>(properties, CategoryPropertyNamesWithId)
+    decode.setEntityPropertyValues<ICategory>(properties, categoryPropertyNamesWithId)
   )
 }
 
@@ -273,19 +281,19 @@ async function httpMediaLocation(
   classEntityMap: ClassEntityMap,
   httpMediaLoc: IReference,
   nextEntityIdBeforeTransaction: number
-): Promise<HttpMediaLocation | undefined> {
-  let loc: HttpMediaLocation | undefined
+): Promise<HttpMediaLocationEntity | undefined> {
+  let loc: HttpMediaLocationEntity | undefined
   const { entityId, existing } = httpMediaLoc
 
   if (existing) {
-    loc = await db.get(HttpMediaLocation, { where: { id: entityId.toString() } })
+    loc = await db.get(HttpMediaLocationEntity, { where: { id: entityId.toString() } })
     if (!loc) throw Error(`HttpMediaLocation entity not found`)
     return loc
   }
   const id = generateEntityIdFromIndex(nextEntityIdBeforeTransaction + entityId)
 
   // could be created in the transaction
-  loc = await db.get(HttpMediaLocation, {
+  loc = await db.get(HttpMediaLocationEntity, {
     where: { id },
   })
   if (loc) return loc
@@ -302,12 +310,12 @@ async function joystreamMediaLocation(
   classEntityMap: ClassEntityMap,
   joyMediaLoc: IReference,
   nextEntityIdBeforeTransaction: number
-): Promise<JoystreamMediaLocation | undefined> {
-  let loc: JoystreamMediaLocation | undefined
+): Promise<JoystreamMediaLocationEntity | undefined> {
+  let loc: JoystreamMediaLocationEntity | undefined
   const { entityId, existing } = joyMediaLoc
 
   if (existing) {
-    loc = await db.get(JoystreamMediaLocation, { where: { id: entityId.toString() } })
+    loc = await db.get(JoystreamMediaLocationEntity, { where: { id: entityId.toString() } })
     if (!loc) throw Error(`JoystreamMediaLocation entity not found`)
     return loc
   }
@@ -315,7 +323,7 @@ async function joystreamMediaLocation(
   const id = generateEntityIdFromIndex(nextEntityIdBeforeTransaction + entityId)
 
   // could be created in the transaction
-  loc = await db.get(JoystreamMediaLocation, {
+  loc = await db.get(JoystreamMediaLocationEntity, {
     where: { id },
   })
   if (loc) return loc
@@ -332,19 +340,19 @@ async function license(
   classEntityMap: ClassEntityMap,
   license: IReference,
   nextEntityIdBeforeTransaction: number
-): Promise<License> {
-  let lic: License | undefined
+): Promise<LicenseEntity> {
+  let lic: LicenseEntity | undefined
   const { entityId, existing } = license
 
   if (existing) {
-    lic = await db.get(License, { where: { id: entityId.toString() } })
+    lic = await db.get(LicenseEntity, { where: { id: entityId.toString() } })
     if (!lic) throw Error(`License entity not found`)
     return lic
   }
 
   const id = generateEntityIdFromIndex(nextEntityIdBeforeTransaction + entityId)
   // could be created in the transaction
-  lic = await db.get(License, { where: { id } })
+  lic = await db.get(LicenseEntity, { where: { id } })
   if (lic) return lic
 
   const { properties } = findEntity(entityId, 'License', classEntityMap)
@@ -361,21 +369,24 @@ async function mediaLocation(
   classEntityMap: ClassEntityMap,
   location: IReference,
   nextEntityIdBeforeTransaction: number
-): Promise<MediaLocation> {
-  let loc: MediaLocation | undefined
+): Promise<MediaLocationEntity> {
+  let loc: MediaLocationEntity | undefined
   const { entityId, existing } = location
   if (existing) {
-    loc = await db.get(MediaLocation, { where: { id: entityId.toString() } })
+    loc = await db.get(MediaLocationEntity, { where: { id: entityId.toString() } })
     if (!loc) throw Error(`MediaLocation entity not found`)
     return loc
   }
   const id = generateEntityIdFromIndex(nextEntityIdBeforeTransaction + entityId)
 
   // could be created in the transaction
-  loc = await db.get(MediaLocation, {
+  loc = await db.get(MediaLocationEntity, {
     where: { id },
+    relations: ['httpMediaLocation', 'joystreamMediaLocation'],
   })
-  if (loc) return loc
+  if (loc) {
+    return loc
+  }
 
   const { properties } = findEntity(entityId, 'MediaLocation', classEntityMap)
   return await createMediaLocation(
@@ -386,12 +397,29 @@ async function mediaLocation(
   )
 }
 
-function removeInsertedEntity(key: string, insertedEntityId: number, classEntityMap: ClassEntityMap) {
-  const newlyCreatedEntities = classEntityMap.get(key)
-  // Remove the inserted entity from the list
-  classEntityMap.set(
-    key,
-    newlyCreatedEntities!.filter((e) => e.entityId !== insertedEntityId)
+async function video(
+  { db, block }: IDBBlockId,
+  classEntityMap: ClassEntityMap,
+  video: IReference,
+  nextEntityIdBeforeTransaction: number
+): Promise<Video> {
+  const { existing, entityId } = video
+  if (existing) {
+    const v = await db.get(Video, { where: { id: entityId.toString() } })
+    if (!v) throw Error(`Video not found. id ${entityId}`)
+    return v
+  }
+
+  const id = generateEntityIdFromIndex(nextEntityIdBeforeTransaction + entityId)
+  const v = await db.get(Video, { where: { id } })
+  if (v) return v
+
+  const { properties } = findEntity(entityId, 'MediaVideo', classEntityMap)
+  return await createVideo(
+    { db, block, id },
+    classEntityMap,
+    decode.setEntityPropertyValues<IVideo>(properties, videoPropertyNamesWithId),
+    nextEntityIdBeforeTransaction
   )
 }
 
@@ -408,4 +436,5 @@ export const getOrCreate = {
   license,
   mediaLocation,
   nextEntityId,
+  video,
 }

+ 1 - 1
query-node/mappings/content-directory/mapping.ts

@@ -4,4 +4,4 @@ export {
   contentDirectory_EntityCreated,
   contentDirectory_EntityPropertyValuesUpdated,
 } from './entity'
-export { contentDirectory_TransactionCompleted } from './transaction'
+export { contentDirectory_TransactionCompleted, contentDirectory_TransactionFailed } from './transaction'

+ 45 - 21
query-node/mappings/content-directory/transaction.ts

@@ -7,11 +7,13 @@ import { ClassEntity } from '../../generated/graphql-server/src/modules/class-en
 import { decode } from './decode'
 import {
   ClassEntityMap,
+  IBatchOperation,
   ICategory,
   IChannel,
   ICreateEntityOperation,
   IDBBlockId,
   IEntity,
+  IFeaturedVideo,
   IHttpMediaLocation,
   IJoystreamMediaLocation,
   IKnownLicense,
@@ -25,7 +27,7 @@ import {
   IWhereCond,
 } from '../types'
 import {
-  CategoryPropertyNamesWithId,
+  categoryPropertyNamesWithId,
   channelPropertyNamesWithId,
   knownLicensePropertyNamesWIthId,
   userDefinedLicensePropertyNamesWithId,
@@ -38,6 +40,7 @@ import {
   ContentDirectoryKnownClasses,
   licensePropertyNamesWithId,
   mediaLocationPropertyNamesWithId,
+  featuredVideoPropertyNamesWithId,
 } from './content-dir-consts'
 import {
   updateCategoryEntityPropertyValues,
@@ -52,6 +55,7 @@ import {
   updateVideoMediaEncodingEntityPropertyValues,
   updateLicenseEntityPropertyValues,
   updateMediaLocationEntityPropertyValues,
+  updateFeaturedVideoEntityPropertyValues,
 } from './entity/update'
 
 import {
@@ -69,6 +73,7 @@ import {
   createLicense,
   createMediaLocation,
   createBlockOrGetFromDatabase,
+  createFeaturedVideo,
 } from './entity/create'
 import { getOrCreate } from './get-or-create'
 
@@ -81,33 +86,35 @@ async function getNextEntityId(db: DB): Promise<number> {
   return e.nextId
 }
 
+// eslint-disable-next-line @typescript-eslint/naming-convention
+export async function contentDirectory_TransactionFailed(db: DB, event: SubstrateEvent): Promise<void> {
+  debug(`TransactionFailed event: ${JSON.stringify(event)}`)
+
+  const failedOperationIndex = event.params[1].value as number
+  const operations = decode.getOperations(event)
+
+  const successfulOperations = operations.toArray().slice(0, failedOperationIndex)
+  if (!successfulOperations.length) return // No succesfull operations
+
+  await applyOperations(decode.getOperationsByTypes(successfulOperations), db, event)
+}
+
 // eslint-disable-next-line @typescript-eslint/naming-convention
 export async function contentDirectory_TransactionCompleted(db: DB, event: SubstrateEvent): Promise<void> {
   debug(`TransactionCompleted event: ${JSON.stringify(event)}`)
 
-  const { extrinsic, blockNumber: block } = event
-  if (!extrinsic) {
-    throw Error(`No extrinsic found for the event: ${event.id}`)
-  }
-
-  const { 1: operations } = extrinsic.args
-  if (operations.name.toString() !== 'operations') {
-    throw Error(`Could not found 'operations' in the extrinsic.args[1]`)
-  }
+  const operations = decode.getOperations(event)
 
-  const {
-    addSchemaSupportToEntityOperations,
-    createEntityOperations,
-    updatePropertyValuesOperations,
-  } = decode.getOperations(event)
+  await applyOperations(decode.getOperationsByTypes(operations), db, event)
+}
 
+async function applyOperations(operations: IBatchOperation, db: DB, event: SubstrateEvent) {
+  const { addSchemaSupportToEntityOperations, createEntityOperations, updatePropertyValuesOperations } = operations
   // Create entities before adding schema support
   // We need this to know which entity belongs to which class(we will need to know to update/create
   // Channel, Video etc.). For example if there is a property update operation there is no class id
-  await batchCreateClassEntities(db, block, createEntityOperations)
-
-  await batchAddSchemaSupportToEntity(db, createEntityOperations, addSchemaSupportToEntityOperations, block)
-
+  await batchCreateClassEntities(db, event.blockNumber, createEntityOperations)
+  await batchAddSchemaSupportToEntity(db, createEntityOperations, addSchemaSupportToEntityOperations, event.blockNumber)
   await batchUpdatePropertyValue(db, createEntityOperations, updatePropertyValuesOperations)
 }
 
@@ -167,7 +174,7 @@ async function batchAddSchemaSupportToEntity(
 
       switch (className) {
         case ContentDirectoryKnownClasses.CATEGORY:
-          await createCategory(arg, decode.setEntityPropertyValues<ICategory>(properties, CategoryPropertyNamesWithId))
+          await createCategory(arg, decode.setEntityPropertyValues<ICategory>(properties, categoryPropertyNamesWithId))
           break
 
         case ContentDirectoryKnownClasses.CHANNEL:
@@ -256,6 +263,15 @@ async function batchAddSchemaSupportToEntity(
           )
           break
 
+        case ContentDirectoryKnownClasses.FEATUREDVIDEOS:
+          await createFeaturedVideo(
+            arg,
+            classEntityMap,
+            decode.setEntityPropertyValues<IFeaturedVideo>(properties, featuredVideoPropertyNamesWithId),
+            nextEntityIdBeforeTransaction
+          )
+          break
+
         default:
           console.log(`Unknown class name: ${className}`)
           break
@@ -299,7 +315,7 @@ async function batchUpdatePropertyValue(db: DB, createEntityOperations: ICreateE
         await updateCategoryEntityPropertyValues(
           db,
           where,
-          decode.setEntityPropertyValues<ICategory>(properties, CategoryPropertyNamesWithId)
+          decode.setEntityPropertyValues<ICategory>(properties, categoryPropertyNamesWithId)
         )
         break
 
@@ -384,6 +400,14 @@ async function batchUpdatePropertyValue(db: DB, createEntityOperations: ICreateE
           entityIdBeforeTransaction
         )
         break
+      case ContentDirectoryKnownClasses.FEATUREDVIDEOS:
+        await updateFeaturedVideoEntityPropertyValues(
+          db,
+          where,
+          decode.setEntityPropertyValues<IFeaturedVideo>(properties, featuredVideoPropertyNamesWithId),
+          entityIdBeforeTransaction
+        )
+        break
 
       default:
         console.log(`Unknown class name: ${className}`)

+ 19 - 9
query-node/mappings/types.ts

@@ -40,12 +40,12 @@ export interface IReference {
 }
 
 export interface IChannel {
-  title: string
+  handle: string
   description: string
-  coverPhotoURL: string
-  avatarPhotoURL: string
+  coverPhotoUrl: string
+  avatarPhotoUrl: string
   isPublic: boolean
-  isCurated: boolean
+  isCurated?: boolean
   language?: IReference
 }
 
@@ -100,14 +100,14 @@ export interface IVideo {
   description: string
   duration: number
   skippableIntroDuration?: number
-  thumbnailURL: string
+  thumbnailUrl: string
   language?: IReference
   // referenced entity's id
   media?: IReference
   hasMarketing?: boolean
   publishedBeforeJoystream?: number
   isPublic: boolean
-  isCurated: boolean
+  isCurated?: boolean
   isExplicit: boolean
   license?: IReference
 }
@@ -115,6 +115,7 @@ export interface IVideo {
 export interface ILicense {
   knownLicense?: IReference
   userDefinedLicense?: IReference
+  attribution?: string
 }
 
 export interface IMediaLocation {
@@ -170,9 +171,14 @@ export interface IEntity {
   properties: IProperty[]
 }
 
-export interface IPropertyIdWithName {
-  // propertyId - property name
-  [propertyId: string]: string
+export interface IPropertyDef {
+  name: string
+  type: string
+  required: boolean
+}
+
+export interface IPropertyWithId {
+  [inClassIndex: string]: IPropertyDef
 }
 
 export interface IWhereCond {
@@ -192,3 +198,7 @@ export interface IDBBlockId {
 }
 
 export type ClassEntityMap = Map<string, IEntity[]>
+
+export interface IFeaturedVideo {
+  video?: IReference
+}

+ 6 - 7
query-node/package.json

@@ -6,17 +6,16 @@
 		"build": "./build.sh",
 		"test": "echo \"Error: no test specified\" && exit 1",
 		"clean": "rm -rf ./generated",
-		"processor:start": "(cd ./generated/indexer && yarn && DEBUG=${DEBUG} yarn start:processor)",
-		"indexer:start": "(cd ./generated/indexer && yarn && DEBUG=${DEBUG} yarn start:indexer)",
+		"processor:start": "./processor-start.sh",
+		"indexer:start": "(cd ./generated/indexer && yarn && DEBUG=${DEBUG} yarn start:indexer --env ../../../.env)",
 		"server:start:dev": "(cd ./generated/graphql-server && yarn start:dev)",
 		"server:start:prod": "(cd ./generated/graphql-server && yarn start:prod)",
 		"configure": "(cd ./generated/graphql-server && yarn config:dev)",
-		"db:up": "docker-compose up -d db",
+		"db:up": "(cd ../ && docker-compose up -d db)",
 		"db:drop": "(cd ./generated/graphql-server && yarn db:drop)",
+		"db:migrate": "./db-migrate.sh",
 		"db:schema:migrate": "(cd ./generated/graphql-server && yarn db:create && yarn db:sync && yarn db:migrate)",
 		"db:indexer:migrate": "(cd ./generated/indexer && yarn db:migrate)",
-		"db:migrate": "yarn db:schema:migrate && yarn db:indexer:migrate",
-		"codegen:all": "yarn hydra-cli codegen --no-install && cp indexer-tsconfig.json generated/indexer/tsconfig.json",
 		"codegen:indexer": "yarn hydra-cli codegen --no-install --no-graphql && cp indexer-tsconfig.json generated/indexer/tsconfig.json",
 		"codegen:server": "yarn hydra-cli codegen --no-install --no-indexer",
 		"cd-classes": "ts-node scripts/get-class-id-and-name.ts"
@@ -24,10 +23,10 @@
 	"author": "",
 	"license": "ISC",
 	"devDependencies": {
-		"@dzlzv/hydra-cli": "^0.0.20"
+		"@dzlzv/hydra-cli": "^0.0.24"
 	},
 	"dependencies": {
-		"@dzlzv/hydra-indexer-lib": "^0.0.19-legacy.1.26.1",
+		"@dzlzv/hydra-indexer-lib": "^0.0.21-legacy.1.26.1",
 		"@joystream/types": "^0.14.0",
 		"@types/bn.js": "^4.11.6",
 		"@types/debug": "^4.1.5",

+ 15 - 0
query-node/processor-start.sh

@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+set -e
+
+SCRIPT_PATH="$(dirname "${BASH_SOURCE[0]}")"
+cd $SCRIPT_PATH
+
+# set +a
+# . ../.env
+# export TYPEORM_DATABASE=${PROCESSOR_DB_NAME}
+
+export TYPEORM_DATABASE=${PROCESSOR_DB_NAME:=query_node_processor}
+
+cd ./generated/indexer
+yarn
+DEBUG=${DEBUG} yarn start:processor --env ../../../.env

+ 21 - 10
query-node/run-tests.sh

@@ -4,31 +4,42 @@ set -e
 SCRIPT_PATH="$(dirname "${BASH_SOURCE[0]}")"
 cd $SCRIPT_PATH
 
+# Only run codegen if no generated files found
+[ ! -d "generated/" ] && yarn build
+
+# Make sure typeorm is available.. it get removed when yarn is run again
+# typeorm commandline is used by db:migrate step below.
+ln -s ../../../../../node_modules/typeorm/cli.js generated/graphql-server/node_modules/.bin/typeorm || :
+
+set -a
+. ../.env
+set +a
+
+# Clean start
+docker-compose down -v
+
 function cleanup() {
     # Show tail end of logs for the processor and indexer containers to
     # see any possible errors
     (echo "## Processor Logs ##" && docker logs joystream_processor_1 --tail 50) || :
     (echo "## Indexer Logs ##" && docker logs joystream_indexer_1 --tail 50) || :
+    (echo "## Indexer API Gateway Logs ##" && docker logs joystream_indexer-api-gateway_1 --tail 50) || :
     docker-compose down -v
 }
 
 trap cleanup EXIT
 
+# We expect docker image to be started by test runner
 export WS_PROVIDER_ENDPOINT_URI=ws://joystream-node:9944/
 
-# Only run codegen if no generated files found
-[ ! -d "generated/" ] && yarn build
-
-# Make sure typeorm is available.. it get removed again when yarn is run again
-# typeorm commandline is used by db:migrate step below.
-ln -s ../../../../../node_modules/typeorm/cli.js generated/graphql-server/node_modules/.bin/typeorm || :
+# Bring up db
+docker-compose up -d db
 
-# clean start
-docker-compose down -v
+# Migrate the databases
+yarn workspace query-node-root db:migrate
 
-docker-compose up -d db
-yarn db:migrate
 docker-compose up -d graphql-server
+
 # Starting up processor will bring up all services it depends on
 docker-compose up -d processor
 

+ 80 - 32
query-node/schema.graphql

@@ -18,7 +18,7 @@ type Member @entity {
   id: ID!
 
   "The unique handle chosen by member"
-  handle: String @unique @fulltext(query: "handles")
+  handle: String @unique @fulltext(query: "membersByHandle")
 
   "A Url to member's Avatar image"
   avatarUri: String
@@ -84,16 +84,16 @@ type Channel @entity {
   # owner: Member!
 
   "The title of the Channel"
-  title: String! @fulltext(query: "titles")
+  handle: String! @fulltext(query: "search")
 
   "The description of a Channel"
   description: String!
 
   "Url for Channel's cover (background) photo. Recommended ratio: 16:9."
-  coverPhotoURL: String!
+  coverPhotoUrl: String
 
   "Channel's avatar photo."
-  avatarPhotoURL: String!
+  avatarPhotoUrl: String
 
   "Flag signaling whether a channel is public."
   isPublic: Boolean!
@@ -102,7 +102,7 @@ type Channel @entity {
   isCurated: Boolean!
 
   "The primary langauge of the channel's content"
-  language: Language!
+  language: Language
 
   videos: [Video!] @derivedFrom(field: "channel")
 
@@ -114,7 +114,7 @@ type Category @entity {
   id: ID!
 
   "The name of the category"
-  name: String! @unique @fulltext(query: "names")
+  name: String! @unique @fulltext(query: "categoriesByName")
 
   "The description of the category"
   description: String
@@ -134,7 +134,7 @@ type VideoMediaEncoding @entity {
   happenedIn: Block!
 }
 
-type KnownLicense @entity {
+type KnownLicenseEntity @entity {
   "Runtime entity identifier (EntityId)"
   id: ID!
 
@@ -153,7 +153,7 @@ type KnownLicense @entity {
   happenedIn: Block!
 }
 
-type UserDefinedLicense @entity {
+type UserDefinedLicenseEntity @entity {
   "Runtime entity identifier (EntityId)"
   id: ID!
 
@@ -163,39 +163,24 @@ type UserDefinedLicense @entity {
   happenedIn: Block!
 }
 
-type License @entity {
-  "Runtime entity identifier (EntityId)"
-  id: ID!
-
-  # One of the following field will be non-null
-
-  "Reference to a known license"
-  knownLicense: KnownLicense
-
-  "Reference to user-defined license"
-  userdefinedLicense: UserDefinedLicense
-
-  happenedIn: Block!
-}
-
-type MediaLocation @entity {
+type MediaLocationEntity @entity {
   "Runtime entity identifier (EntityId)"
   id: ID!
 
   # One of the following field will be non-null
 
   "A reference to HttpMediaLocation"
-  httpMediaLocation: HttpMediaLocation
+  httpMediaLocation: HttpMediaLocationEntity
 
   "A reference to JoystreamMediaLocation"
-  joystreamMediaLocation: JoystreamMediaLocation
+  joystreamMediaLocation: JoystreamMediaLocationEntity
 
-  videoMedia: VideoMedia @derivedFrom(field: "location")
+  videoMedia: VideoMedia @derivedFrom(field: "locationEntity")
 
   happenedIn: Block!
 }
 
-type JoystreamMediaLocation @entity {
+type JoystreamMediaLocationEntity @entity {
   "Runtime entity identifier (EntityId)"
   id: ID!
 
@@ -205,7 +190,7 @@ type JoystreamMediaLocation @entity {
   happenedIn: Block!
 }
 
-type HttpMediaLocation @entity {
+type HttpMediaLocationEntity @entity {
   "Runtime entity identifier (EntityId)"
   id: ID!
 
@@ -239,6 +224,8 @@ type VideoMedia @entity {
   "Location of the video media object"
   location: MediaLocation!
 
+  locationEntity: MediaLocationEntity
+
   happenedIn: Block!
 }
 
@@ -253,7 +240,7 @@ type Video @entity {
   category: Category!
 
   "The title of the video"
-  title: String! @fulltext(query: "titles")
+  title: String! @fulltext(query: "search")
 
   "The description of the Video"
   description: String!
@@ -265,7 +252,7 @@ type Video @entity {
   skippableIntroDuration: Int
 
   "Video thumbnail url (recommended ratio: 16:9)"
-  thumbnailURL: String!
+  thumbnailUrl: String!
 
   "Video's main langauge"
   language: Language
@@ -288,7 +275,68 @@ type Video @entity {
   "Whether the Video contains explicit material."
   isExplicit: Boolean!
 
-  license: License!
+  license: LicenseEntity!
+
+  happenedIn: Block!
+
+  "Is video featured or not"
+  isFeatured: Boolean!
+
+  featured: FeaturedVideo @derivedFrom(field: "video")
+}
+
+type JoystreamMediaLocation @variant {
+  "Id of the data object in the Joystream runtime dataDirectory module"
+  dataObjectId: String!
+}
+
+type HttpMediaLocation @variant {
+  "The http url pointing to the media"
+  url: String!
+
+  "The port to use when connecting to the http url (defaults to 80)"
+  port: Int
+}
+
+union MediaLocation = HttpMediaLocation | JoystreamMediaLocation
+
+type KnownLicense @variant {
+  "Short, commonly recognized code of the licence (ie. CC_BY_SA)"
+  code: String!
+
+  "Full, descriptive name of the license (ie. Creative Commons - Attribution-NonCommercial-NoDerivs)"
+  name: String
+
+  "Short description of the license conditions"
+  description: String
+
+  "An url pointing to full license content"
+  url: String
+}
+
+type UserDefinedLicense @variant {
+  "Custom license content"
+  content: String!
+}
+
+union License = KnownLicense | UserDefinedLicense
+
+type LicenseEntity @entity {
+  "Runtime entity identifier (EntityId)"
+  id: ID!
+
+  type: License!
+
+  "Attribution (if required by the license)"
+  attribution: String
 
   happenedIn: Block!
 }
+
+type FeaturedVideo @entity {
+  "Runtime entity identifier (EntityId)"
+  id: ID!
+
+  "Reference to a video"
+  video: Video!
+}

+ 0 - 974
query-node/typedefs.json

@@ -1,974 +0,0 @@
-{
-    "Credential": "u64",
-    "CredentialSet": "BTreeSet<Credential>",
-    "BlockAndTime": {
-        "block": "u32",
-        "time": "u64"
-    },
-    "ThreadId": "u64",
-    "PostId": "u64",
-    "InputValidationLengthConstraint": {
-        "min": "u16",
-        "max_min_diff": "u16"
-    },
-    "WorkingGroup": {
-        "_enum": [
-            "Storage",
-            "Content"
-        ]
-    },
-    "SlashingTerms": {
-        "_enum": {
-            "Unslashable": "Null",
-            "Slashable": "SlashableTerms"
-        }
-    },
-    "SlashableTerms": {
-        "max_count": "u16",
-        "max_percent_pts_per_time": "u16"
-    },
-    "MemoText": "Text",
-    "Address": "AccountId",
-    "LookupSource": "AccountId",
-    "EntryMethod": {
-        "_enum": {
-            "Paid": "u64",
-            "Screening": "AccountId",
-            "Genesis": "Null"
-        }
-    },
-    "MemberId": "u64",
-    "PaidTermId": "u64",
-    "SubscriptionId": "u64",
-    "Membership": {
-        "handle": "Text",
-        "avatar_uri": "Text",
-        "about": "Text",
-        "registered_at_block": "u32",
-        "registered_at_time": "u64",
-        "entry": "EntryMethod",
-        "suspended": "bool",
-        "subscription": "Option<SubscriptionId>",
-        "root_account": "GenericAccountId",
-        "controller_account": "GenericAccountId"
-    },
-    "PaidMembershipTerms": {
-        "fee": "u128",
-        "text": "Text"
-    },
-    "ActorId": "u64",
-    "ElectionStage": {
-        "_enum": {
-            "Announcing": "u32",
-            "Voting": "u32",
-            "Revealing": "u32"
-        }
-    },
-    "ElectionStake": {
-        "new": "u128",
-        "transferred": "u128"
-    },
-    "SealedVote": {
-        "voter": "GenericAccountId",
-        "commitment": "Hash",
-        "stake": "ElectionStake",
-        "vote": "Option<GenericAccountId>"
-    },
-    "TransferableStake": {
-        "seat": "u128",
-        "backing": "u128"
-    },
-    "ElectionParameters": {
-        "announcing_period": "u32",
-        "voting_period": "u32",
-        "revealing_period": "u32",
-        "council_size": "u32",
-        "candidacy_limit": "u32",
-        "new_term_duration": "u32",
-        "min_council_stake": "u128",
-        "min_voting_stake": "u128"
-    },
-    "Seat": {
-        "member": "GenericAccountId",
-        "stake": "u128",
-        "backers": "Backers"
-    },
-    "Seats": "Vec<Seat>",
-    "Backer": {
-        "member": "GenericAccountId",
-        "stake": "u128"
-    },
-    "Backers": "Vec<Backer>",
-    "RoleParameters": {
-        "min_stake": "u128",
-        "min_actors": "u32",
-        "max_actors": "u32",
-        "reward": "u128",
-        "reward_period": "u32",
-        "bonding_period": "u32",
-        "unbonding_period": "u32",
-        "min_service_period": "u32",
-        "startup_grace_period": "u32",
-        "entry_request_fee": "u128"
-    },
-    "PostTextChange": {
-        "expired_at": "BlockAndTime",
-        "text": "Text"
-    },
-    "ModerationAction": {
-        "moderated_at": "BlockAndTime",
-        "moderator_id": "GenericAccountId",
-        "rationale": "Text"
-    },
-    "ChildPositionInParentCategory": {
-        "parent_id": "CategoryId",
-        "child_nr_in_parent_category": "u32"
-    },
-    "CategoryId": "u64",
-    "Category": {
-        "id": "CategoryId",
-        "title": "Text",
-        "description": "Text",
-        "created_at": "BlockAndTime",
-        "deleted": "bool",
-        "archived": "bool",
-        "num_direct_subcategories": "u32",
-        "num_direct_unmoderated_threads": "u32",
-        "num_direct_moderated_threads": "u32",
-        "position_in_parent_category": "Option<ChildPositionInParentCategory>",
-        "moderator_id": "GenericAccountId"
-    },
-    "Thread": {
-        "id": "ThreadId",
-        "title": "Text",
-        "category_id": "CategoryId",
-        "nr_in_category": "u32",
-        "moderation": "Option<ModerationAction>",
-        "num_unmoderated_posts": "u32",
-        "num_moderated_posts": "u32",
-        "created_at": "BlockAndTime",
-        "author_id": "GenericAccountId"
-    },
-    "Post": {
-        "id": "PostId",
-        "thread_id": "ThreadId",
-        "nr_in_thread": "u32",
-        "current_text": "Text",
-        "moderation": "Option<ModerationAction>",
-        "text_change_history": "Vec<PostTextChange>",
-        "created_at": "BlockAndTime",
-        "author_id": "GenericAccountId"
-    },
-    "ReplyId": "u64",
-    "Reply": {
-        "owner": "GenericAccountId",
-        "thread_id": "ThreadId",
-        "text": "Text",
-        "moderation": "Option<ModerationAction>"
-    },
-    "StakeId": "u64",
-    "Stake": {
-        "created": "u32",
-        "staking_status": "StakingStatus"
-    },
-    "StakingStatus": {
-        "_enum": {
-            "NotStaked": "Null",
-            "Staked": "Staked"
-        }
-    },
-    "Staked": {
-        "staked_amount": "u128",
-        "staked_status": "StakedStatus",
-        "next_slash_id": "u64",
-        "ongoing_slashes": "BTreeMap<u64,Slash>"
-    },
-    "StakedStatus": {
-        "_enum": {
-            "Normal": "Null",
-            "Unstaking": "Unstaking"
-        }
-    },
-    "Unstaking": {
-        "started_at_block": "u32",
-        "is_active": "bool",
-        "blocks_remaining_in_active_period_for_unstaking": "u32"
-    },
-    "Slash": {
-        "started_at_block": "u32",
-        "is_active": "bool",
-        "blocks_remaining_in_active_period_for_slashing": "u32",
-        "slash_amount": "u128"
-    },
-    "MintId": "u64",
-    "Mint": {
-        "capacity": "u128",
-        "next_adjustment": "Option<NextAdjustment>",
-        "created_at": "u32",
-        "total_minted": "u128"
-    },
-    "MintBalanceOf": "u128",
-    "BalanceOfMint": "u128",
-    "NextAdjustment": {
-        "adjustment": "AdjustOnInterval",
-        "at_block": "u32"
-    },
-    "AdjustOnInterval": {
-        "block_interval": "u32",
-        "adjustment_type": "AdjustCapacityBy"
-    },
-    "AdjustCapacityBy": {
-        "_enum": {
-            "Setting": "u128",
-            "Adding": "u128",
-            "Reducing": "u128"
-        }
-    },
-    "RecipientId": "u64",
-    "RewardRelationshipId": "u64",
-    "Recipient": {
-        "total_reward_received": "u128",
-        "total_reward_missed": "u128"
-    },
-    "RewardRelationship": {
-        "recipient": "RecipientId",
-        "mint_id": "MintId",
-        "account": "GenericAccountId",
-        "amount_per_payout": "u128",
-        "next_payment_at_block": "Option<u32>",
-        "payout_interval": "Option<u32>",
-        "total_reward_received": "u128",
-        "total_reward_missed": "u128"
-    },
-    "ApplicationId": "u64",
-    "OpeningId": "u64",
-    "Application": {
-        "opening_id": "OpeningId",
-        "application_index_in_opening": "u32",
-        "add_to_opening_in_block": "u32",
-        "active_role_staking_id": "Option<StakeId>",
-        "active_application_staking_id": "Option<StakeId>",
-        "stage": "ApplicationStage",
-        "human_readable_text": "Text"
-    },
-    "ApplicationStage": {
-        "_enum": {
-            "Active": "Null",
-            "Unstaking": "UnstakingApplicationStage",
-            "Inactive": "InactiveApplicationStage"
-        }
-    },
-    "ActivateOpeningAt": {
-        "_enum": {
-            "CurrentBlock": "Null",
-            "ExactBlock": "u32"
-        }
-    },
-    "ApplicationRationingPolicy": {
-        "max_active_applicants": "u32"
-    },
-    "OpeningStage": {
-        "_enum": {
-            "WaitingToBegin": "WaitingToBeingOpeningStageVariant",
-            "Active": "ActiveOpeningStageVariant"
-        }
-    },
-    "StakingPolicy": {
-        "amount": "u128",
-        "amount_mode": "StakingAmountLimitMode",
-        "crowded_out_unstaking_period_length": "Option<u32>",
-        "review_period_expired_unstaking_period_length": "Option<u32>"
-    },
-    "Opening": {
-        "created": "u32",
-        "stage": "OpeningStage",
-        "max_review_period_length": "u32",
-        "application_rationing_policy": "Option<ApplicationRationingPolicy>",
-        "application_staking_policy": "Option<StakingPolicy>",
-        "role_staking_policy": "Option<StakingPolicy>",
-        "human_readable_text": "Text"
-    },
-    "WaitingToBeingOpeningStageVariant": {
-        "begins_at_block": "u32"
-    },
-    "ActiveOpeningStageVariant": {
-        "stage": "ActiveOpeningStage",
-        "applications_added": "Vec<ApplicationId>",
-        "active_application_count": "u32",
-        "unstaking_application_count": "u32",
-        "deactivated_application_count": "u32"
-    },
-    "ActiveOpeningStage": {
-        "_enum": {
-            "AcceptingApplications": "AcceptingApplications",
-            "ReviewPeriod": "ReviewPeriod",
-            "Deactivated": "Deactivated"
-        }
-    },
-    "AcceptingApplications": {
-        "started_accepting_applicants_at_block": "u32"
-    },
-    "ReviewPeriod": {
-        "started_accepting_applicants_at_block": "u32",
-        "started_review_period_at_block": "u32"
-    },
-    "Deactivated": {
-        "cause": "OpeningDeactivationCause",
-        "deactivated_at_block": "u32",
-        "started_accepting_applicants_at_block": "u32",
-        "started_review_period_at_block": "Option<u32>"
-    },
-    "OpeningDeactivationCause": {
-        "_enum": [
-            "CancelledBeforeActivation",
-            "CancelledAcceptingApplications",
-            "CancelledInReviewPeriod",
-            "ReviewPeriodExpired",
-            "Filled"
-        ]
-    },
-    "InactiveApplicationStage": {
-        "deactivation_initiated": "u32",
-        "deactivated": "u32",
-        "cause": "ApplicationDeactivationCause"
-    },
-    "UnstakingApplicationStage": {
-        "deactivation_initiated": "u32",
-        "cause": "ApplicationDeactivationCause"
-    },
-    "ApplicationDeactivationCause": {
-        "_enum": [
-            "External",
-            "Hired",
-            "NotHired",
-            "CrowdedOut",
-            "OpeningCancelled",
-            "ReviewPeriodExpired",
-            "OpeningFilled"
-        ]
-    },
-    "StakingAmountLimitMode": {
-        "_enum": [
-            "AtLeast",
-            "Exact"
-        ]
-    },
-    "ChannelId": "u64",
-    "CuratorId": "u64",
-    "CuratorOpeningId": "u64",
-    "CuratorApplicationId": "u64",
-    "LeadId": "u64",
-    "PrincipalId": "u64",
-    "OptionalText": "Option<Text>",
-    "Channel": {
-        "verified": "bool",
-        "handle": "Text",
-        "title": "OptionalText",
-        "description": "OptionalText",
-        "avatar": "OptionalText",
-        "banner": "OptionalText",
-        "content": "ChannelContentType",
-        "owner": "MemberId",
-        "role_account": "GenericAccountId",
-        "publication_status": "ChannelPublicationStatus",
-        "curation_status": "ChannelCurationStatus",
-        "created": "u32",
-        "principal_id": "PrincipalId"
-    },
-    "ChannelContentType": {
-        "_enum": [
-            "Video",
-            "Music",
-            "Ebook"
-        ]
-    },
-    "ChannelCurationStatus": {
-        "_enum": [
-            "Normal",
-            "Censored"
-        ]
-    },
-    "ChannelPublicationStatus": {
-        "_enum": [
-            "Public",
-            "Unlisted"
-        ]
-    },
-    "CurationActor": {
-        "_enum": {
-            "Lead": "Null",
-            "Curator": "CuratorId"
-        }
-    },
-    "Curator": {
-        "role_account": "GenericAccountId",
-        "reward_relationship": "Option<RewardRelationshipId>",
-        "role_stake_profile": "Option<CuratorRoleStakeProfile>",
-        "stage": "CuratorRoleStage",
-        "induction": "CuratorInduction",
-        "principal_id": "PrincipalId"
-    },
-    "CuratorApplication": {
-        "role_account": "GenericAccountId",
-        "curator_opening_id": "CuratorOpeningId",
-        "member_id": "MemberId",
-        "application_id": "ApplicationId"
-    },
-    "CuratorOpening": {
-        "opening_id": "OpeningId",
-        "curator_applications": "Vec<CuratorApplicationId>",
-        "policy_commitment": "OpeningPolicyCommitment"
-    },
-    "Lead": {
-        "member_id": "MemberId",
-        "role_account": "GenericAccountId",
-        "reward_relationship": "Option<RewardRelationshipId>",
-        "inducted": "u32",
-        "stage": "LeadRoleState"
-    },
-    "OpeningPolicyCommitment": {
-        "application_rationing_policy": "Option<ApplicationRationingPolicy>",
-        "max_review_period_length": "u32",
-        "application_staking_policy": "Option<StakingPolicy>",
-        "role_staking_policy": "Option<StakingPolicy>",
-        "role_slashing_terms": "SlashingTerms",
-        "fill_opening_successful_applicant_application_stake_unstaking_period": "Option<u32>",
-        "fill_opening_failed_applicant_application_stake_unstaking_period": "Option<u32>",
-        "fill_opening_failed_applicant_role_stake_unstaking_period": "Option<u32>",
-        "terminate_curator_application_stake_unstaking_period": "Option<u32>",
-        "terminate_curator_role_stake_unstaking_period": "Option<u32>",
-        "exit_curator_role_application_stake_unstaking_period": "Option<u32>",
-        "exit_curator_role_stake_unstaking_period": "Option<u32>"
-    },
-    "Principal": {
-        "_enum": {
-            "Lead": "Null",
-            "Curator": "CuratorId",
-            "ChannelOwner": "ChannelId"
-        }
-    },
-    "WorkingGroupUnstaker": {
-        "_enum": {
-            "Lead": "LeadId",
-            "Curator": "CuratorId"
-        }
-    },
-    "CuratorApplicationIdToCuratorIdMap": "BTreeMap<ApplicationId,CuratorId>",
-    "CuratorApplicationIdSet": "BTreeSet<CuratorApplicationId>",
-    "CuratorRoleStakeProfile": {
-        "stake_id": "StakeId",
-        "termination_unstaking_period": "Option<u32>",
-        "exit_unstaking_period": "Option<u32>"
-    },
-    "CuratorRoleStage": {
-        "_enum": {
-            "Active": "Null",
-            "Unstaking": "CuratorExitSummary",
-            "Exited": "CuratorExitSummary"
-        }
-    },
-    "CuratorExitSummary": {
-        "origin": "CuratorExitInitiationOrigin",
-        "initiated_at_block_number": "u32",
-        "rationale_text": "Text"
-    },
-    "CuratorExitInitiationOrigin": {
-        "_enum": [
-            "Lead",
-            "Curator"
-        ]
-    },
-    "LeadRoleState": {
-        "_enum": {
-            "Active": "Null",
-            "Exited": "ExitedLeadRole"
-        }
-    },
-    "ExitedLeadRole": {
-        "initiated_at_block_number": "u32"
-    },
-    "CuratorInduction": {
-        "lead": "LeadId",
-        "curator_application_id": "CuratorApplicationId",
-        "at_block": "u32"
-    },
-    "RationaleText": "Bytes",
-    "ApplicationOf": {
-        "role_account_id": "GenericAccountId",
-        "opening_id": "OpeningId",
-        "member_id": "MemberId",
-        "application_id": "ApplicationId"
-    },
-    "ApplicationIdSet": "BTreeSet<ApplicationId>",
-    "ApplicationIdToWorkerIdMap": "BTreeMap<ApplicationId,WorkerId>",
-    "WorkerId": "u64",
-    "WorkerOf": {
-        "member_id": "MemberId",
-        "role_account_id": "GenericAccountId",
-        "reward_relationship": "Option<RewardRelationshipId>",
-        "role_stake_profile": "Option<RoleStakeProfile>"
-    },
-    "OpeningOf": {
-        "hiring_opening_id": "OpeningId",
-        "applications": "Vec<ApplicationId>",
-        "policy_commitment": "WorkingGroupOpeningPolicyCommitment",
-        "opening_type": "OpeningType"
-    },
-    "StorageProviderId": "u64",
-    "OpeningType": {
-        "_enum": {
-            "Leader": "Null",
-            "Worker": "Null"
-        }
-    },
-    "HiringApplicationId": "u64",
-    "RewardPolicy": {
-        "amount_per_payout": "u128",
-        "next_payment_at_block": "u32",
-        "payout_interval": "Option<u32>"
-    },
-    "WorkingGroupOpeningPolicyCommitment": {
-        "application_rationing_policy": "Option<ApplicationRationingPolicy>",
-        "max_review_period_length": "u32",
-        "application_staking_policy": "Option<StakingPolicy>",
-        "role_staking_policy": "Option<StakingPolicy>",
-        "role_slashing_terms": "SlashingTerms",
-        "fill_opening_successful_applicant_application_stake_unstaking_period": "Option<u32>",
-        "fill_opening_failed_applicant_application_stake_unstaking_period": "Option<u32>",
-        "fill_opening_failed_applicant_role_stake_unstaking_period": "Option<u32>",
-        "terminate_application_stake_unstaking_period": "Option<u32>",
-        "terminate_role_stake_unstaking_period": "Option<u32>",
-        "exit_role_application_stake_unstaking_period": "Option<u32>",
-        "exit_role_stake_unstaking_period": "Option<u32>"
-    },
-    "RoleStakeProfile": {
-        "stake_id": "StakeId",
-        "termination_unstaking_period": "Option<u32>",
-        "exit_unstaking_period": "Option<u32>"
-    },
-    "Url": "Text",
-    "IPNSIdentity": "Text",
-    "ServiceProviderRecord": {
-        "identity": "IPNSIdentity",
-        "expires_at": "u32"
-    },
-    "ContentId": "[u8;32]",
-    "LiaisonJudgement": {
-        "_enum": [
-            "Pending",
-            "Accepted",
-            "Rejected"
-        ]
-    },
-    "DataObject": {
-        "owner": "MemberId",
-        "added_at": "BlockAndTime",
-        "type_id": "DataObjectTypeId",
-        "size": "u64",
-        "liaison": "StorageProviderId",
-        "liaison_judgement": "LiaisonJudgement",
-        "ipfs_content_id": "Text"
-    },
-    "DataObjectStorageRelationshipId": "u64",
-    "DataObjectStorageRelationship": {
-        "content_id": "ContentId",
-        "storage_provider": "StorageProviderId",
-        "ready": "bool"
-    },
-    "DataObjectTypeId": "u64",
-    "DataObjectType": {
-        "description": "Text",
-        "active": "bool"
-    },
-    "DataObjectsMap": "BTreeMap<ContentId,DataObject>",
-    "ProposalId": "u32",
-    "ProposalStatus": {
-        "_enum": {
-            "Active": "Option<ActiveStake>",
-            "Finalized": "Finalized"
-        }
-    },
-    "ProposalOf": {
-        "parameters": "ProposalParameters",
-        "proposerId": "MemberId",
-        "title": "Text",
-        "description": "Text",
-        "createdAt": "u32",
-        "status": "ProposalStatus",
-        "votingResults": "VotingResults"
-    },
-    "ProposalDetails": {
-        "_enum": {
-            "Text": "Text",
-            "RuntimeUpgrade": "Bytes",
-            "SetElectionParameters": "ElectionParameters",
-            "Spending": "(Balance,AccountId)",
-            "SetLead": "Option<SetLeadParams>",
-            "SetContentWorkingGroupMintCapacity": "u128",
-            "EvictStorageProvider": "GenericAccountId",
-            "SetValidatorCount": "u32",
-            "SetStorageRoleParameters": "RoleParameters",
-            "AddWorkingGroupLeaderOpening": "AddOpeningParameters",
-            "BeginReviewWorkingGroupLeaderApplication": "(OpeningId,WorkingGroup)",
-            "FillWorkingGroupLeaderOpening": "FillOpeningParameters",
-            "SetWorkingGroupMintCapacity": "(Balance,WorkingGroup)",
-            "DecreaseWorkingGroupLeaderStake": "(WorkerId,Balance,WorkingGroup)",
-            "SlashWorkingGroupLeaderStake": "(WorkerId,Balance,WorkingGroup)",
-            "SetWorkingGroupLeaderReward": "(WorkerId,Balance,WorkingGroup)",
-            "TerminateWorkingGroupLeaderRole": "TerminateRoleParameters"
-        }
-    },
-    "ProposalDetailsOf": {
-        "_enum": {
-            "Text": "Text",
-            "RuntimeUpgrade": "Bytes",
-            "SetElectionParameters": "ElectionParameters",
-            "Spending": "(Balance,AccountId)",
-            "SetLead": "Option<SetLeadParams>",
-            "SetContentWorkingGroupMintCapacity": "u128",
-            "EvictStorageProvider": "GenericAccountId",
-            "SetValidatorCount": "u32",
-            "SetStorageRoleParameters": "RoleParameters",
-            "AddWorkingGroupLeaderOpening": "AddOpeningParameters",
-            "BeginReviewWorkingGroupLeaderApplication": "(OpeningId,WorkingGroup)",
-            "FillWorkingGroupLeaderOpening": "FillOpeningParameters",
-            "SetWorkingGroupMintCapacity": "(Balance,WorkingGroup)",
-            "DecreaseWorkingGroupLeaderStake": "(WorkerId,Balance,WorkingGroup)",
-            "SlashWorkingGroupLeaderStake": "(WorkerId,Balance,WorkingGroup)",
-            "SetWorkingGroupLeaderReward": "(WorkerId,Balance,WorkingGroup)",
-            "TerminateWorkingGroupLeaderRole": "TerminateRoleParameters"
-        }
-    },
-    "VotingResults": {
-        "abstensions": "u32",
-        "approvals": "u32",
-        "rejections": "u32",
-        "slashes": "u32"
-    },
-    "ProposalParameters": {
-        "votingPeriod": "u32",
-        "gracePeriod": "u32",
-        "approvalQuorumPercentage": "u32",
-        "approvalThresholdPercentage": "u32",
-        "slashingQuorumPercentage": "u32",
-        "slashingThresholdPercentage": "u32",
-        "requiredStake": "Option<u128>"
-    },
-    "VoteKind": {
-        "_enum": [
-            "Approve",
-            "Reject",
-            "Slash",
-            "Abstain"
-        ]
-    },
-    "ThreadCounter": {
-        "author_id": "MemberId",
-        "counter": "u32"
-    },
-    "DiscussionThread": {
-        "title": "Bytes",
-        "created_at": "u32",
-        "author_id": "MemberId"
-    },
-    "DiscussionPost": {
-        "text": "Bytes",
-        "created_at": "u32",
-        "updated_at": "u32",
-        "author_id": "MemberId",
-        "thread_id": "ThreadId",
-        "edition_number": "u32"
-    },
-    "AddOpeningParameters": {
-        "activate_at": "ActivateOpeningAt",
-        "commitment": "WorkingGroupOpeningPolicyCommitment",
-        "human_readable_text": "Bytes",
-        "working_group": "WorkingGroup"
-    },
-    "FillOpeningParameters": {
-        "opening_id": "OpeningId",
-        "successful_application_id": "ApplicationId",
-        "reward_policy": "Option<RewardPolicy>",
-        "working_group": "WorkingGroup"
-    },
-    "TerminateRoleParameters": {
-        "worker_id": "WorkerId",
-        "rationale": "Bytes",
-        "slash": "bool",
-        "working_group": "WorkingGroup"
-    },
-    "ActiveStake": {
-        "stake_id": "StakeId",
-        "source_account_id": "GenericAccountId"
-    },
-    "Finalized": {
-        "proposalStatus": "ProposalDecisionStatus",
-        "finalizedAt": "u32",
-        "encodedUnstakingErrorDueToBrokenRuntime": "Option<Vec<u8>>",
-        "stakeDataAfterUnstakingError": "Option<ActiveStake>"
-    },
-    "ProposalDecisionStatus": {
-        "_enum": {
-            "Canceled": "Null",
-            "Vetoed": "Null",
-            "Rejected": "Null",
-            "Slashed": "Null",
-            "Expired": "Null",
-            "Approved": "Approved"
-        }
-    },
-    "ExecutionFailed": {
-        "error": "Text"
-    },
-    "Approved": {
-        "_enum": {
-            "PendingExecution": "Null",
-            "Executed": "Null",
-            "ExecutionFailed": "ExecutionFailed"
-        }
-    },
-    "SetLeadParams": "(MemberId,GenericAccountId)",
-    "Nonce": "u64",
-    "EntityId": "u64",
-    "ClassId": "u64",
-    "CuratorGroupId": "u64",
-    "VecMaxLength": "u16",
-    "TextMaxLength": "u16",
-    "HashedTextMaxLength": "Option<u16>",
-    "PropertyId": "u16",
-    "SchemaId": "u16",
-    "SameController": "bool",
-    "ClassPermissions": {
-        "any_member": "bool",
-        "entity_creation_blocked": "bool",
-        "all_entity_property_values_locked": "bool",
-        "maintainers": "Vec<CuratorGroupId>"
-    },
-    "PropertyTypeSingle": {
-        "_enum": {
-            "Bool": "Null",
-            "Uint16": "Null",
-            "Uint32": "Null",
-            "Uint64": "Null",
-            "Int16": "Null",
-            "Int32": "Null",
-            "Int64": "Null",
-            "Text": "TextMaxLength",
-            "Hash": "HashedTextMaxLength",
-            "Reference": "(ClassId,SameController)"
-        }
-    },
-    "PropertyTypeVector": {
-        "vec_type": "PropertyTypeSingle",
-        "max_length": "VecMaxLength"
-    },
-    "PropertyType": {
-        "_enum": {
-            "Single": "PropertyTypeSingle",
-            "Vector": "PropertyTypeVector"
-        }
-    },
-    "PropertyLockingPolicy": {
-        "is_locked_from_maintainer": "bool",
-        "is_locked_from_controller": "bool"
-    },
-    "Property": {
-        "property_type": "PropertyType",
-        "required": "bool",
-        "unique": "bool",
-        "name": "Text",
-        "description": "Text",
-        "locking_policy": "PropertyLockingPolicy"
-    },
-    "Schema": {
-        "properties": "Vec<PropertyId>",
-        "is_active": "bool"
-    },
-    "Class": {
-        "class_permissions": "ClassPermissions",
-        "properties": "Vec<Property>",
-        "schemas": "Vec<Schema>",
-        "name": "Text",
-        "description": "Text",
-        "maximum_entities_count": "EntityId",
-        "current_number_of_entities": "EntityId",
-        "default_entity_creation_voucher_upper_bound": "EntityId"
-    },
-    "ClassOf": {
-        "class_permissions": "ClassPermissions",
-        "properties": "Vec<Property>",
-        "schemas": "Vec<Schema>",
-        "name": "Text",
-        "description": "Text",
-        "maximum_entities_count": "EntityId",
-        "current_number_of_entities": "EntityId",
-        "default_entity_creation_voucher_upper_bound": "EntityId"
-    },
-    "EntityController": {
-        "_enum": {
-            "Maintainers": "Null",
-            "Member": "MemberId",
-            "Lead": "Null"
-        }
-    },
-    "EntityPermissions": {
-        "controller": "EntityController",
-        "frozen": "bool",
-        "referenceable": "bool"
-    },
-    "StoredValue": {
-        "_enum": {
-            "Bool": "bool",
-            "Uint16": "u16",
-            "Uint32": "u32",
-            "Uint64": "u64",
-            "Int16": "i16",
-            "Int32": "i32",
-            "Int64": "i64",
-            "Text": "Text",
-            "Hash": "Hash",
-            "Reference": "EntityId"
-        }
-    },
-    "VecStoredValue": {
-        "_enum": {
-            "Bool": "Vec<bool>",
-            "Uint16": "Vec<u16>",
-            "Uint32": "Vec<u32>",
-            "Uint64": "Vec<u64>",
-            "Int16": "Vec<i16>",
-            "Int32": "Vec<i32>",
-            "Int64": "Vec<i64>",
-            "Hash": "Vec<Hash>",
-            "Text": "Vec<Text>",
-            "Reference": "Vec<EntityId>"
-        }
-    },
-    "VecStoredPropertyValue": {
-        "vec_value": "VecStoredValue",
-        "nonce": "Nonce"
-    },
-    "StoredPropertyValue": {
-        "_enum": {
-            "Single": "StoredValue",
-            "Vector": "VecStoredPropertyValue"
-        }
-    },
-    "InboundReferenceCounter": {
-        "total": "u32",
-        "same_owner": "u32"
-    },
-    "Entity": {
-        "entity_permissions": "EntityPermissions",
-        "class_id": "ClassId",
-        "supported_schemas": "Vec<SchemaId>",
-        "values": "BTreeMap<PropertyId,StoredPropertyValue>",
-        "reference_counter": "InboundReferenceCounter"
-    },
-    "EntityOf": {
-        "entity_permissions": "EntityPermissions",
-        "class_id": "ClassId",
-        "supported_schemas": "Vec<SchemaId>",
-        "values": "BTreeMap<PropertyId,StoredPropertyValue>",
-        "reference_counter": "InboundReferenceCounter"
-    },
-    "CuratorGroup": {
-        "curators": "Vec<u64>",
-        "active": "bool",
-        "number_of_classes_maintained": "u32"
-    },
-    "EntityCreationVoucher": {
-        "maximum_entities_count": "EntityId",
-        "entities_created": "EntityId"
-    },
-    "Actor": {
-        "_enum": {
-            "Curator": "(CuratorGroupId,u64)",
-            "Member": "MemberId",
-            "Lead": "Null"
-        }
-    },
-    "EntityReferenceCounterSideEffect": {
-        "total": "i32",
-        "same_owner": "i32"
-    },
-    "ReferenceCounterSideEffects": "BTreeMap<EntityId,EntityReferenceCounterSideEffect>",
-    "SideEffects": "Option<ReferenceCounterSideEffects>",
-    "SideEffect": "Option<(EntityId,EntityReferenceCounterSideEffect)>",
-    "Status": "bool",
-    "InputValue": {
-        "_enum": {
-            "Bool": "bool",
-            "Uint16": "u16",
-            "Uint32": "u32",
-            "Uint64": "u64",
-            "Int16": "i16",
-            "Int32": "i32",
-            "Int64": "i64",
-            "Text": "Text",
-            "TextToHash": "Text",
-            "Reference": "EntityId"
-        }
-    },
-    "VecInputValue": {
-        "_enum": {
-            "Bool": "Vec<bool>",
-            "Uint16": "Vec<u16>",
-            "Uint32": "Vec<u32>",
-            "Uint64": "Vec<u64>",
-            "Int16": "Vec<i16>",
-            "Int32": "Vec<i32>",
-            "Int64": "Vec<i64>",
-            "TextToHash": "Vec<Text>",
-            "Text": "Vec<Text>",
-            "Reference": "Vec<EntityId>"
-        }
-    },
-    "InputPropertyValue": {
-        "_enum": {
-            "Single": "InputValue",
-            "Vector": "VecInputValue"
-        }
-    },
-    "ParameterizedEntity": {
-        "_enum": {
-            "InternalEntityJustAdded": "u32",
-            "ExistingEntity": "EntityId"
-        }
-    },
-    "ParametrizedPropertyValue": {
-        "_enum": {
-            "InputPropertyValue": "InputPropertyValue",
-            "InternalEntityJustAdded": "u32",
-            "InternalEntityVec": "Vec<ParameterizedEntity>"
-        }
-    },
-    "ParametrizedClassPropertyValue": {
-        "in_class_index": "PropertyId",
-        "value": "ParametrizedPropertyValue"
-    },
-    "CreateEntityOperation": {
-        "class_id": "ClassId"
-    },
-    "UpdatePropertyValuesOperation": {
-        "entity_id": "ParameterizedEntity",
-        "new_parametrized_property_values": "Vec<ParametrizedClassPropertyValue>"
-    },
-    "AddSchemaSupportToEntityOperation": {
-        "entity_id": "ParameterizedEntity",
-        "schema_id": "SchemaId",
-        "parametrized_property_values": "Vec<ParametrizedClassPropertyValue>"
-    },
-    "OperationType": {
-        "_enum": {
-            "CreateEntity": "CreateEntityOperation",
-            "UpdatePropertyValues": "UpdatePropertyValuesOperation",
-            "AddSchemaSupportToEntity": "AddSchemaSupportToEntityOperation"
-        }
-    },
-    "InputEntityValuesMap": "BTreeMap<PropertyId,InputPropertyValue>",
-    "ClassPermissionsType": "Null",
-    "ClassPropertyValue": "Null",
-    "Operation": "Null",
-    "ReferenceConstraint": "Null"
-}

+ 2 - 1
runtime-modules/constitution/Cargo.toml

@@ -11,14 +11,15 @@ sp-std = { package = 'sp-std', default-features = false, git = 'https://github.c
 frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
 frame_system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
 sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
+frame-benchmarking = { package = 'frame-benchmarking', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca', optional = true}
 
 [dev-dependencies]
 sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
 sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'a200cdb93c6af5763b9c7bf313fa708764ac88ca'}
 
-
 [features]
 default = ['std']
+runtime-benchmarks = ["frame-benchmarking"]
 std = [
     'serde',
     'codec/std',

+ 55 - 0
runtime-modules/constitution/src/benchmarking.rs

@@ -0,0 +1,55 @@
+#![cfg(feature = "runtime-benchmarks")]
+
+use crate::{Call, ConstitutionInfo, Event, Module, Trait};
+use frame_benchmarking::benchmarks;
+use frame_system::Module as System;
+use frame_system::{EventRecord, RawOrigin};
+use sp_runtime::traits::Hash;
+use sp_std::boxed::Box;
+use sp_std::vec;
+use sp_std::vec::Vec;
+
+fn assert_last_event<T: Trait>(generic_event: <T as Trait>::Event) {
+    let events = System::<T>::events();
+    let system_event: <T as frame_system::Trait>::Event = generic_event.into();
+    // compare to the last event record
+    let EventRecord { event, .. } = &events[events.len() - 1];
+    assert_eq!(event, &system_event);
+}
+
+const MAX_BYTES: u32 = 50000;
+
+benchmarks! {
+    _{ }
+
+    amend_constitution{
+        let i in 1 .. MAX_BYTES;
+        let text = vec![0u8].repeat(i as usize);
+
+    }: _ (RawOrigin::Root, text.clone())
+    verify {
+            let hashed = T::Hashing::hash(&text);
+            let hash = hashed.as_ref().to_vec();
+
+            let constitution_info = ConstitutionInfo{
+                text_hash: hash.clone(),
+            };
+
+            assert_eq!(Module::<T>::constitution(), constitution_info);
+            assert_last_event::<T>(Event::ConstutionAmended(hash).into());
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::tests::mocks::{build_test_externalities, Test};
+    use frame_support::assert_ok;
+
+    #[test]
+    fn amend_constitution() {
+        build_test_externalities().execute_with(|| {
+            assert_ok!(test_benchmark_amend_constitution::<Test>());
+        });
+    }
+}

+ 22 - 2
runtime-modules/constitution/src/lib.rs

@@ -8,18 +8,33 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 
 #[cfg(test)]
-mod tests;
+pub(crate) mod tests;
+
+mod benchmarking;
 
 use codec::{Decode, Encode};
+use frame_support::weights::Weight;
 use frame_support::{decl_event, decl_module, decl_storage};
 use frame_system::ensure_root;
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
 use sp_runtime::traits::Hash;
+use sp_runtime::SaturatedConversion;
 use sp_std::vec::Vec;
 
+/// pallet_constitution WeightInfo.
+/// Note: This was auto generated through the benchmark CLI using the `--weight-trait` flag
+pub trait WeightInfo {
+    fn amend_constitution(i: u32) -> Weight;
+}
+
+type WeightInfoConstitution<T> = <T as Trait>::WeightInfo;
+
 pub trait Trait: frame_system::Trait {
     type Event: From<Event> + Into<<Self as frame_system::Trait>::Event>;
+
+    /// Weight information for extrinsics in this pallet.
+    type WeightInfo: WeightInfo;
 }
 
 /// Contains constitution text hash and its amendment number.
@@ -50,7 +65,12 @@ decl_module! {
         fn deposit_event() = default;
 
         /// Sets the current constitution hash. Requires root origin.
-        #[weight = 10_000_000] // TODO: adjust weight
+        /// # <weight>
+        /// - Complexity: `O(C)` where C is the length of the constitution text.
+        /// - Db reads: 0
+        /// - Db writes: 1 (constant value)
+        /// # </weight>
+        #[weight = WeightInfoConstitution::<T>::amend_constitution(constitution_text.len().saturated_into())]
         fn amend_constitution(origin, constitution_text: Vec<u8>) {
             ensure_root(origin)?;
 

+ 7 - 0
runtime-modules/constitution/src/tests/mocks.rs

@@ -64,6 +64,13 @@ impl frame_system::Trait for Test {
 
 impl Trait for Test {
     type Event = TestEvent;
+    type WeightInfo = ();
+}
+
+impl crate::WeightInfo for () {
+    fn amend_constitution(_: u32) -> u64 {
+        0
+    }
 }
 
 pub fn build_test_externalities() -> sp_io::TestExternalities {

+ 1 - 1
runtime-modules/constitution/src/tests/mod.rs

@@ -1,6 +1,6 @@
 #![cfg(test)]
 
-mod mocks;
+pub(crate) mod mocks;
 
 use crate::{ConstitutionInfo, Event};
 use frame_support::dispatch::DispatchResult;

+ 102 - 45
runtime-modules/content-directory/src/lib.rs

@@ -142,7 +142,11 @@ use codec::{Codec, Decode, Encode};
 use frame_support::storage::IterableStorageMap;
 
 use frame_support::{
-    decl_event, decl_module, decl_storage, dispatch::DispatchResult, ensure, traits::Get, Parameter,
+    decl_event, decl_module, decl_storage,
+    dispatch::{DispatchError, DispatchResult},
+    ensure,
+    traits::Get,
+    Parameter,
 };
 use frame_system::ensure_signed;
 #[cfg(feature = "std")]
@@ -1628,64 +1632,115 @@ decl_module! {
             Ok(())
         }
 
-        /// Batch transaction
-        #[weight = 10_000_000] // TODO: adjust weight
-        pub fn transaction(origin, actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>, operations: Vec<OperationType<T>>) -> DispatchResult {
+       /// Batch transaction
+       #[weight = 10_000_000] // TODO: adjust weight
+       pub fn transaction(origin, actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>, operations: Vec<OperationType<T>>) -> DispatchResult {
 
-            // Ensure maximum number of operations during atomic batching limit not reached
-            Self::ensure_number_of_operations_during_atomic_batching_limit_not_reached(&operations)?;
+           // Ensure maximum number of operations during atomic batching limit not reached
+           Self::ensure_number_of_operations_during_atomic_batching_limit_not_reached(&operations)?;
 
-            //
-            // == MUTATION SAFE ==
-            //
+           //
+           // == MUTATION SAFE ==
+           //
 
-            // This BTreeMap holds the T::EntityId of the entity created as a result of executing a `CreateEntity` `Operation`
-            let mut entity_created_in_operation = BTreeMap::new();
+           // This BTreeMap holds the T::EntityId of the entity created as a result of executing a `CreateEntity` `Operation`
+           let mut entity_created_in_operation = BTreeMap::new();
 
-            // Create raw origin
-            let raw_origin = origin.into().map_err(|_| Error::<T>::OriginCanNotBeMadeIntoRawOrigin)?;
+           // Create raw origin
+           let raw_origin = origin.into().map_err(|_| Error::<T>::OriginCanNotBeMadeIntoRawOrigin)?;
 
-            for (index, operation_type) in operations.into_iter().enumerate() {
-                let origin = T::Origin::from(raw_origin.clone());
-                match operation_type {
-                    OperationType::CreateEntity(create_entity_operation) => {
-                        Self::create_entity(origin, create_entity_operation.class_id, actor)?;
+           for (index, operation_type) in operations.into_iter().enumerate() {
+               let origin = T::Origin::from(raw_origin.clone());
+               match operation_type {
+                   OperationType::CreateEntity(create_entity_operation) => {
+                        Self::ensure_transaction_failed_event(
+                            Self::create_entity(origin, create_entity_operation.class_id, actor),
+                            actor,
+                            index
+                        )?;
 
                         // entity id of newly created entity
                         let entity_id = Self::next_entity_id() - T::EntityId::one();
                         entity_created_in_operation.insert(index, entity_id);
-                    },
-                    OperationType::AddSchemaSupportToEntity(add_schema_support_to_entity_operation) => {
-                        let entity_id = operations::parametrized_entity_to_entity_id(
-                            &entity_created_in_operation, add_schema_support_to_entity_operation.entity_id
+                   },
+                   OperationType::AddSchemaSupportToEntity(add_schema_support_to_entity_operation) => {
+                       let entity_id =
+                            Self::ensure_transaction_failed_event(
+                                operations::parametrized_entity_to_entity_id(
+                                    &entity_created_in_operation, add_schema_support_to_entity_operation.entity_id
+                                ),
+                                actor,
+                                index
+                            )?;
+
+                       let schema_id = add_schema_support_to_entity_operation.schema_id;
+
+                       let property_values =
+                            Self::ensure_transaction_failed_event(
+                                operations::parametrized_property_values_to_property_values(
+                                    &entity_created_in_operation, add_schema_support_to_entity_operation.parametrized_property_values
+                                ),
+                                actor,
+                                index
+                            )?;
+                        Self::ensure_transaction_failed_event(
+                            Self::add_schema_support_to_entity(origin, actor, entity_id, schema_id, property_values),
+                            actor,
+                            index
                         )?;
-                        let schema_id = add_schema_support_to_entity_operation.schema_id;
-                        let property_values = operations::parametrized_property_values_to_property_values(
-                            &entity_created_in_operation, add_schema_support_to_entity_operation.parametrized_property_values
-                        )?;
-                        Self::add_schema_support_to_entity(origin, actor, entity_id, schema_id, property_values)?;
-                    },
-                    OperationType::UpdatePropertyValues(update_property_values_operation) => {
-                        let entity_id = operations::parametrized_entity_to_entity_id(
-                            &entity_created_in_operation, update_property_values_operation.entity_id
-                        )?;
-                        let property_values = operations::parametrized_property_values_to_property_values(
-                            &entity_created_in_operation, update_property_values_operation.new_parametrized_property_values
-                        )?;
-                        Self::update_entity_property_values(origin, actor, entity_id, property_values)?;
-                    },
-                }
-            }
-
-            // Trigger event
-            Self::deposit_event(RawEvent::TransactionCompleted(actor));
-
-            Ok(())
-        }
+                   },
+                   OperationType::UpdatePropertyValues(update_property_values_operation) => {
+                       let entity_id =
+                            Self::ensure_transaction_failed_event(
+                                operations::parametrized_entity_to_entity_id(
+                                    &entity_created_in_operation, update_property_values_operation.entity_id
+                                ),
+                                actor,
+                                index
+                            )?;
+
+                       let property_values =
+                            Self::ensure_transaction_failed_event(
+                                operations::parametrized_property_values_to_property_values(
+                                    &entity_created_in_operation, update_property_values_operation.new_parametrized_property_values
+                                ),
+                                actor,
+                                index
+                            )?;
+
+                       Self::ensure_transaction_failed_event(
+                            Self::update_entity_property_values(origin, actor, entity_id, property_values),
+                            actor,
+                            index
+                       )?;
+                   },
+               }
+           }
+
+           // Trigger event
+           Self::deposit_event(RawEvent::TransactionCompleted(actor));
+
+           Ok(())
+       }
     }
 }
 
 impl<T: Trait> Module<T> {
+    /// Deposits an `TransactionFailed` event if an error during `transaction` extrinsic execution occured
+    fn ensure_transaction_failed_event<R, E: Into<DispatchError>>(
+        result: Result<R, E>,
+        actor: Actor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
+        index: usize,
+    ) -> Result<R, DispatchError> {
+        match result {
+            Err(e) => {
+                Self::deposit_event(RawEvent::TransactionFailed(actor, index as u32));
+                Err(e.into())
+            }
+            Ok(result) => Ok(result),
+        }
+    }
+
     /// Updates corresponding `Entity` `reference_counter` by `reference_counter_delta`.
     fn update_entity_rc(
         entity_id: T::EntityId,
@@ -2830,6 +2885,7 @@ decl_event!(
         Nonce = <T as Trait>::Nonce,
         SideEffects = Option<ReferenceCounterSideEffects<T>>,
         SideEffect = Option<(<T as Trait>::EntityId, EntityReferenceCounterSideEffect)>,
+        FailedAt = u32,
     {
         CuratorGroupAdded(CuratorGroupId),
         CuratorGroupRemoved(CuratorGroupId),
@@ -2854,5 +2910,6 @@ decl_event!(
         InsertedAtVectorIndex(Actor, EntityId, PropertyId, VecMaxLength, Nonce, SideEffect),
         EntityOwnershipTransfered(EntityId, EntityController, SideEffects),
         TransactionCompleted(Actor),
+        TransactionFailed(Actor, FailedAt),
     }
 );

+ 2 - 1
runtime-modules/content-directory/src/mock.rs

@@ -434,13 +434,14 @@ type RawTestEvent = RawEvent<
     Nonce,
     Option<ReferenceCounterSideEffects<Runtime>>,
     Option<(EntityId, EntityReferenceCounterSideEffect)>,
+    u32,
 >;
 
 pub fn get_test_event(raw_event: RawTestEvent) -> TestEvent {
     TestEvent::test_events(raw_event)
 }
 
-pub fn assert_event_success(tested_event: TestEvent, number_of_events_after_call: usize) {
+pub fn assert_event(tested_event: TestEvent, number_of_events_after_call: usize) {
     // Ensure  runtime events length is equal to expected number of events after call
     assert_eq!(System::events().len(), number_of_events_after_call);
 

+ 1 - 1
runtime-modules/content-directory/src/tests.rs

@@ -145,7 +145,7 @@ pub fn add_entity_schemas_support() -> (
     ));
 
     // Last event checked
-    assert_event_success(
+    assert_event(
         entity_schema_support_added_event,
         number_of_events_before_calls + 2,
     );

+ 1 - 1
runtime-modules/content-directory/src/tests/add_class_schema.rs

@@ -52,7 +52,7 @@ fn add_class_schema_success() {
             get_test_event(RawEvent::ClassSchemaAdded(FIRST_CLASS_ID, SECOND_SCHEMA_ID));
 
         // Last event checked
-        assert_event_success(class_schema_added_event, number_of_events_before_call + 2);
+        assert_event(class_schema_added_event, number_of_events_before_call + 2);
     })
 }
 

+ 1 - 1
runtime-modules/content-directory/src/tests/add_curator_group.rs

@@ -31,7 +31,7 @@ fn add_curator_group_success() {
             get_test_event(RawEvent::CuratorGroupAdded(FIRST_CURATOR_GROUP_ID));
 
         // Event checked
-        assert_event_success(
+        assert_event(
             curator_group_created_event,
             number_of_events_before_call + 1,
         );

+ 1 - 1
runtime-modules/content-directory/src/tests/add_curator_to_group.rs

@@ -31,7 +31,7 @@ fn add_curator_to_group_success() {
         ));
 
         // Event checked
-        assert_event_success(
+        assert_event(
             curator_group_curator_added_event,
             number_of_events_before_call + 1,
         );

+ 1 - 1
runtime-modules/content-directory/src/tests/add_maintainer_to_class.rs

@@ -35,7 +35,7 @@ fn add_maintainer_to_class_success() {
         ));
 
         // Event checked
-        assert_event_success(maintainer_added_event, number_of_events_before_call + 1);
+        assert_event(maintainer_added_event, number_of_events_before_call + 1);
     })
 }
 

+ 1 - 1
runtime-modules/content-directory/src/tests/clear_entity_property_vector.rs

@@ -53,7 +53,7 @@ fn clear_entity_property_vector_success() {
         ));
 
         // Last event checked
-        assert_event_success(
+        assert_event(
             entity_property_vector_cleared_event,
             number_of_events_before_calls + 1,
         );

+ 1 - 1
runtime-modules/content-directory/src/tests/create_class.rs

@@ -23,7 +23,7 @@ fn create_class_success() {
         let class_created_event = get_test_event(RawEvent::ClassCreated(FIRST_CLASS_ID));
 
         // Event checked
-        assert_event_success(class_created_event, number_of_events_before_call + 1);
+        assert_event(class_created_event, number_of_events_before_call + 1);
     })
 }
 

+ 1 - 1
runtime-modules/content-directory/src/tests/create_entity.rs

@@ -71,7 +71,7 @@ fn create_entity_success() {
             get_test_event(RawEvent::EntityCreated(actor, next_entity_id() - 1));
 
         // Last event checked
-        assert_event_success(entity_created_event, number_of_events_before_call + 1);
+        assert_event(entity_created_event, number_of_events_before_call + 1);
     })
 }
 

+ 1 - 1
runtime-modules/content-directory/src/tests/insert_at_entity_property_vector.rs

@@ -64,7 +64,7 @@ fn insert_at_entity_property_vector_success() {
         ));
 
         // Last event checked
-        assert_event_success(
+        assert_event(
             inserted_at_vector_index_event,
             number_of_events_before_calls + 1,
         );

+ 1 - 1
runtime-modules/content-directory/src/tests/remove_at_entity_property_vector.rs

@@ -59,7 +59,7 @@ fn remove_at_entity_property_vector_success() {
         ));
 
         // Last event checked
-        assert_event_success(
+        assert_event(
             removed_at_vector_index_event,
             number_of_events_before_calls + 1,
         );

+ 1 - 1
runtime-modules/content-directory/src/tests/remove_curator_from_group.rs

@@ -44,7 +44,7 @@ fn remove_curator_from_group_success() {
         ));
 
         // Event checked
-        assert_event_success(
+        assert_event(
             curator_group_curator_removed_event,
             number_of_events_before_call + 1,
         );

Some files were not shown because too many files changed in this diff