Parcourir la source

Merge branch 'substrate_version_upgrade' into iznik-substrate-version-upgrade

Mokhtar Naamani il y a 4 ans
Parent
commit
48d9c131de
100 fichiers modifiés avec 3450 ajouts et 3395 suppressions
  1. 385 231
      Cargo.lock
  2. 93 138
      node/Cargo.toml
  3. 3 20
      node/bin/main.rs
  4. 64 19
      node/build.rs
  5. 136 50
      node/src/chain_spec.rs
  6. 45 125
      node/src/cli.rs
  7. 100 0
      node/src/command.rs
  8. 4 0
      node/src/lib.rs
  9. 1 13
      node/src/members_config.rs
  10. 10 0
      node/src/node_executor.rs
  11. 188 0
      node/src/node_rpc.rs
  12. 529 225
      node/src/service.rs
  13. 15 43
      runtime-modules/common/Cargo.toml
  14. 2 2
      runtime-modules/common/src/currency.rs
  15. 2 2
      runtime-modules/common/src/lib.rs
  16. 37 120
      runtime-modules/content-working-group/Cargo.toml
  17. 2 60
      runtime-modules/content-working-group/src/genesis.rs
  18. 103 88
      runtime-modules/content-working-group/src/lib.rs
  19. 37 32
      runtime-modules/content-working-group/src/mock.rs
  20. 0 6
      runtime-modules/content-working-group/src/mod.rs
  21. 79 62
      runtime-modules/content-working-group/src/tests.rs
  22. 19 41
      runtime-modules/forum/Cargo.toml
  23. 59 66
      runtime-modules/forum/src/lib.rs
  24. 39 33
      runtime-modules/forum/src/mock.rs
  25. 1 1
      runtime-modules/forum/src/tests.rs
  26. 30 89
      runtime-modules/governance/Cargo.toml
  27. 33 22
      runtime-modules/governance/src/council.rs
  28. 76 48
      runtime-modules/governance/src/election.rs
  29. 9 6
      runtime-modules/governance/src/election_params.rs
  30. 4 0
      runtime-modules/governance/src/lib.rs
  31. 21 27
      runtime-modules/governance/src/mock.rs
  32. 2 2
      runtime-modules/governance/src/sealed_vote.rs
  33. 8 8
      runtime-modules/governance/src/stake.rs
  34. 18 44
      runtime-modules/hiring/Cargo.toml
  35. 2 2
      runtime-modules/hiring/src/hiring/application.rs
  36. 4 8
      runtime-modules/hiring/src/hiring/opening.rs
  37. 32 38
      runtime-modules/hiring/src/lib.rs
  38. 1 1
      runtime-modules/hiring/src/macroes.rs
  39. 25 30
      runtime-modules/hiring/src/mock.rs
  40. 3 3
      runtime-modules/hiring/src/test/mod.rs
  41. 10 6
      runtime-modules/hiring/src/test/public_api/add_application.rs
  42. 5 6
      runtime-modules/hiring/src/test/public_api/add_opening.rs
  43. 3 3
      runtime-modules/hiring/src/test/public_api/begin_accepting_applications.rs
  44. 2 2
      runtime-modules/hiring/src/test/public_api/begin_review.rs
  45. 3 3
      runtime-modules/hiring/src/test/public_api/cancel_opening.rs
  46. 5 5
      runtime-modules/hiring/src/test/public_api/deactivate_application.rs
  47. 4 4
      runtime-modules/hiring/src/test/public_api/ensure_can_add_application.rs
  48. 5 5
      runtime-modules/hiring/src/test/public_api/fill_opening.rs
  49. 4 4
      runtime-modules/hiring/src/test/public_api/mod.rs
  50. 1 1
      runtime-modules/hiring/src/test/public_api/on_finalize.rs
  51. 1 1
      runtime-modules/hiring/src/test/public_api/unstaked.rs
  52. 17 19
      runtime-modules/hiring/src/test/smoke.rs
  53. 5 5
      runtime-modules/hiring/src/test/staking_module/try_to_initiate_application_deactivation.rs
  54. 1 1
      runtime-modules/hiring/src/test/staking_module/would_application_get_added.rs
  55. 26 74
      runtime-modules/membership/Cargo.toml
  56. 0 1
      runtime-modules/membership/src/genesis.rs
  57. 64 43
      runtime-modules/membership/src/lib.rs
  58. 24 34
      runtime-modules/membership/src/mock.rs
  59. 12 10
      runtime-modules/membership/src/tests.rs
  60. 14 48
      runtime-modules/memo/Cargo.toml
  61. 9 8
      runtime-modules/memo/src/lib.rs
  62. 47 171
      runtime-modules/proposals/codex/Cargo.toml
  63. 99 112
      runtime-modules/proposals/codex/src/lib.rs
  64. 1 1
      runtime-modules/proposals/codex/src/proposal_types/mod.rs
  65. 58 38
      runtime-modules/proposals/codex/src/tests/mock.rs
  66. 54 52
      runtime-modules/proposals/codex/src/tests/mod.rs
  67. 24 85
      runtime-modules/proposals/discussion/Cargo.toml
  68. 33 45
      runtime-modules/proposals/discussion/src/lib.rs
  69. 32 15
      runtime-modules/proposals/discussion/src/tests/mock.rs
  70. 35 25
      runtime-modules/proposals/discussion/src/tests/mod.rs
  71. 1 2
      runtime-modules/proposals/discussion/src/types.rs
  72. 31 96
      runtime-modules/proposals/engine/Cargo.toml
  73. 82 61
      runtime-modules/proposals/engine/src/lib.rs
  74. 2 2
      runtime-modules/proposals/engine/src/tests/mock/balance_manager.rs
  75. 20 21
      runtime-modules/proposals/engine/src/tests/mock/mod.rs
  76. 4 3
      runtime-modules/proposals/engine/src/tests/mock/proposals.rs
  77. 1 1
      runtime-modules/proposals/engine/src/tests/mock/stakes.rs
  78. 115 92
      runtime-modules/proposals/engine/src/tests/mod.rs
  79. 8 8
      runtime-modules/proposals/engine/src/types/mod.rs
  80. 3 3
      runtime-modules/proposals/engine/src/types/proposal_statuses.rs
  81. 5 4
      runtime-modules/proposals/engine/src/types/stakes.rs
  82. 14 41
      runtime-modules/recurring-reward/Cargo.toml
  83. 19 16
      runtime-modules/recurring-reward/src/lib.rs
  84. 16 22
      runtime-modules/recurring-reward/src/mock/mod.rs
  85. 4 4
      runtime-modules/recurring-reward/src/tests.rs
  86. 30 104
      runtime-modules/service-discovery/Cargo.toml
  87. 21 17
      runtime-modules/service-discovery/src/lib.rs
  88. 21 18
      runtime-modules/service-discovery/src/mock.rs
  89. 18 15
      runtime-modules/service-discovery/src/tests.rs
  90. 17 37
      runtime-modules/stake/Cargo.toml
  91. 25 29
      runtime-modules/stake/src/lib.rs
  92. 1 1
      runtime-modules/stake/src/macroes.rs
  93. 16 36
      runtime-modules/stake/src/mock.rs
  94. 5 5
      runtime-modules/stake/src/tests.rs
  95. 32 105
      runtime-modules/storage/Cargo.toml
  96. 31 40
      runtime-modules/storage/src/data_directory.rs
  97. 23 35
      runtime-modules/storage/src/data_object_storage_registry.rs
  98. 26 34
      runtime-modules/storage/src/data_object_type_registry.rs
  99. 30 8
      runtime-modules/storage/src/tests/data_directory.rs
  100. 10 3
      runtime-modules/storage/src/tests/data_object_storage_registry.rs

Fichier diff supprimé car celui-ci est trop grand
+ 385 - 231
Cargo.lock


+ 93 - 138
node/Cargo.toml

@@ -1,9 +1,9 @@
 [package]
-authors = ['Joystream']
+authors = ['Joystream contributors']
 build = 'build.rs'
 edition = '2018'
 name = 'joystream-node'
-version = '2.7.0'
+version = '3.0.0'
 default-run = "joystream-node"
 
 [[bin]]
@@ -14,143 +14,98 @@ path = 'bin/main.rs'
 crate-type = ["cdylib", "rlib"]
 
 [dependencies]
-hex-literal = '0.2.1'
-derive_more = '0.14.0'
-exit-future = '0.1.4'
-futures = '0.1.29'
-log = '0.4.8'
-parking_lot = '0.9.0'
-tokio = '0.1.22'
-jsonrpc-core = '13.2.0'
-rand = '0.7.2'
-structopt = '=0.3.5'
+# third-party dependencies
+serde = { version = "1.0.102", features = ["derive"] }
+futures = { version = "0.3.1", features = ["compat"] }
+jsonrpc-core = "14.2.0"
+structopt = { version = "0.3.8", optional = true}
 serde_json = '1.0'
-serde = '1.0'
-hex = '0.4'
-# https://users.rust-lang.org/t/failure-derive-compilation-error/39062
-# quote = '<=1.0.2'
 
-[dependencies.node-runtime]
-package = 'joystream-node-runtime'
-path = '../runtime'
-
-[dependencies.substrate-basic-authorship]
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-basic-authorship'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.babe]
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-consensus-babe'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.babe-primitives]
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-consensus-babe-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.codec]
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dependencies.ctrlc]
-features = ['termination']
-version = '3.0'
-
-[dependencies.inherents]
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-inherents'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.network]
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-network'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.primitives]
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.sr-io]
-git = 'https://github.com/paritytech/substrate.git'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.substrate-cli]
-git = 'https://github.com/paritytech/substrate.git'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.substrate-client]
-git = 'https://github.com/paritytech/substrate.git'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.substrate-executor]
-git = 'https://github.com/paritytech/substrate.git'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.substrate-service]
-git = 'https://github.com/paritytech/substrate.git'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.transaction-pool]
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-transaction-pool'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.substrate-telemetry]
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-telemetry'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.grandpa]
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-finality-grandpa'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.grandpa-primitives]
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-finality-grandpa-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.im-online]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-im-online'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.substrate-rpc]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-rpc'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.authority-discovery]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-authority-discovery'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.client-db]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-client-db'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.runtime-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.offchain]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-offchain'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.libp2p]
-version = '0.13.2'
-default-features = false
+# primitives
+sp-authority-discovery = { package = 'sp-authority-discovery', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-consensus-babe = { package = 'sp-consensus-babe', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-finality-grandpa = { package = 'sp-finality-grandpa', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-core = { package = 'sp-core', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-runtime = { package = 'sp-runtime', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-finality-tracker = { package = 'sp-finality-tracker', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-inherents = { package = 'sp-inherents', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-consensus = { package = 'sp-consensus', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-transaction-pool = { package = 'sp-transaction-pool', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-api = { package = 'sp-api', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-blockchain = { package = 'sp-blockchain', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-block-builder = { package = 'sp-block-builder', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+
+# client dependencies
+sc-client-api = { package = 'sc-client-api', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-chain-spec = { package = 'sc-chain-spec', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-consensus = { package = 'sc-consensus', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-transaction-pool = { package = 'sc-transaction-pool', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-network = { package = 'sc-network', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-consensus-babe = { package = 'sc-consensus-babe', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sc-finality-grandpa = { package = 'sc-finality-grandpa', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-basic-authorship = { package = 'sc-basic-authorship', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-service = { package = 'sc-service', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-authority-discovery = { package = 'sc-authority-discovery', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-consensus-epochs = { package = 'sc-consensus-epochs', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-keystore = { package = 'sc-keystore', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-consensus-babe-rpc = { package = 'sc-consensus-babe-rpc', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-finality-grandpa-rpc = { package = 'sc-finality-grandpa-rpc', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-rpc-api = { package = 'sc-rpc-api', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-executor = { package = 'sc-executor', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+
+# frame dependencies
+pallet-im-online = { package = 'pallet-im-online', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+pallet-transaction-payment-rpc = { package = 'pallet-transaction-payment-rpc', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+substrate-frame-rpc-system = { package = 'substrate-frame-rpc-system', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+frame-benchmarking = { package = 'frame-benchmarking', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+
+# node-specific dependencies
+node-runtime = { package= "joystream-node-runtime", path = "../runtime" }
+
+# CLI-specific dependencies
+sc-cli = { package = 'sc-cli', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4', optional = true }
+frame-benchmarking-cli = { package = 'frame-benchmarking-cli', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4', optional = true }
+node-inspect = { package = 'node-inspect', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4', optional = true }
+
+# WASM-specific dependencies
+wasm-bindgen = { version = "0.2.57", optional = true }
+wasm-bindgen-futures = { version = "0.4.7", optional = true }
+browser-utils = { package = 'substrate-browser-utils', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4', optional = true}
+
+[dev-dependencies]
+tempfile = "3.1.0"
+codec = { package = "parity-scale-codec", version = "1.3.1" }
+sp-timestamp = { package = 'sp-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sp-keyring = { package = 'sp-keyring', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+sc-consensus-babe = { git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4', features = ["test-helpers"]}
+sc-service-test = { git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+frame-system = { package = 'frame-system', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+pallet-transaction-payment = { package = 'pallet-transaction-payment', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
+pallet-grandpa = { package = 'pallet-grandpa', git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4' }
 
 [build-dependencies]
-vergen = '3'
+structopt = { version = "0.3.8", optional = true }
+node-inspect = { git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4', optional = true}
+sc-cli = { git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4', optional = true}
+frame-benchmarking-cli = { git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4', optional = true }
+substrate-build-script-utils = { git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4', optional = true }
+
+[features]
+default = [ "cli" ]
+browser = [
+	"browser-utils",
+	"wasm-bindgen",
+	"wasm-bindgen-futures",
+]
+cli = [
+	"node-inspect",
+	"sc-cli",
+	"frame-benchmarking-cli",
+	"sc-service/db",
+	"structopt",
+	"substrate-build-script-utils",
+]
+runtime-benchmarks = [
+	"node-runtime/runtime-benchmarks",
+	"frame-benchmarking-cli",
+]

+ 3 - 20
node/bin/main.rs

@@ -14,27 +14,10 @@
 // You should have received a copy of the GNU General Public License
 // along with Joystream node.  If not, see <http://www.gnu.org/licenses/>.
 
-//! Substrate Node Template CLI library.
+//! Joystream Node.
 
 #![warn(missing_docs)]
-#![warn(unused_extern_crates)]
 
-use joystream_node::cli;
-pub use substrate_cli::{error, IntoExit, VersionInfo};
-
-fn main() {
-    let version = VersionInfo {
-        name: "Joystream Node",
-        commit: env!("VERGEN_SHA_SHORT"),
-        version: env!("CARGO_PKG_VERSION"),
-        executable_name: "joystream-node",
-        author: "Joystream",
-        description: "Joystream substrate node",
-        support_url: "https://www.joystream.org/",
-    };
-
-    if let Err(e) = cli::run(::std::env::args(), cli::Exit, version) {
-        eprintln!("Fatal error: {}\n\n{:?}", e, e);
-        std::process::exit(1)
-    }
+fn main() -> sc_cli::Result<()> {
+    joystream_node::command::run()
 }

+ 64 - 19
node/build.rs

@@ -1,27 +1,72 @@
-use std::{env, path::PathBuf};
+// This file is part of Substrate.
 
-use vergen::{generate_cargo_keys, ConstantsFlags};
+// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
 
-const ERROR_MSG: &str = "Failed to generate metadata files";
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
 
 fn main() {
-    generate_cargo_keys(ConstantsFlags::SHA_SHORT).expect(ERROR_MSG);
-
-    let mut manifest_dir = PathBuf::from(
-        env::var("CARGO_MANIFEST_DIR").expect("`CARGO_MANIFEST_DIR` is always set by cargo."),
-    );
-
-    while manifest_dir.parent().is_some() {
-        if manifest_dir.join(".git/HEAD").exists() {
-            println!(
-                "cargo:rerun-if-changed={}",
-                manifest_dir.join(".git/HEAD").display()
-            );
-            return;
-        }
+    #[cfg(feature = "cli")]
+    cli::main();
+}
+
+#[cfg(feature = "cli")]
+mod cli {
+    include!("src/cli.rs");
+
+    use sc_cli::structopt::clap::Shell;
+    use std::{env, fs, path::Path};
+    use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed};
+
+    pub fn main() {
+        build_shell_completion();
+        generate_cargo_keys();
 
-        manifest_dir.pop();
+        rerun_if_git_head_changed();
     }
 
-    println!("cargo:warning=Could not find `.git/HEAD` from manifest dir!");
+    /// Build shell completion scripts for all known shells
+    /// Full list in https://github.com/kbknapp/clap-rs/blob/e9d0562a1dc5dfe731ed7c767e6cee0af08f0cf9/src/app/parser.rs#L123
+    fn build_shell_completion() {
+        for shell in &[
+            Shell::Bash,
+            Shell::Fish,
+            Shell::Zsh,
+            Shell::Elvish,
+            Shell::PowerShell,
+        ] {
+            build_completion(shell);
+        }
+    }
+
+    /// Build the shell auto-completion for a given Shell
+    fn build_completion(shell: &Shell) {
+        let outdir = match env::var_os("OUT_DIR") {
+            None => return,
+            Some(dir) => dir,
+        };
+        let path = Path::new(&outdir)
+            .parent()
+            .unwrap()
+            .parent()
+            .unwrap()
+            .parent()
+            .unwrap()
+            .join("completion-scripts");
+
+        fs::create_dir(&path).ok();
+
+        Cli::clap().gen_completions("joystream-node", *shell, &path);
+    }
 }

+ 136 - 50
node/src/chain_spec.rs

@@ -19,30 +19,33 @@
 // Example:  voting_period: 1 * DAY
 #![allow(clippy::identity_op)]
 
+use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
+use serde_json as json;
+use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
+use sp_consensus_babe::AuthorityId as BabeId;
+use sp_core::{sr25519, Pair, Public};
+use sp_finality_grandpa::AuthorityId as GrandpaId;
+use sp_runtime::traits::{IdentifyAccount, Verify};
+use sp_runtime::Perbill;
+
 use node_runtime::{
     versioned_store::InputValidationLengthConstraint as VsInputValidation,
     AuthorityDiscoveryConfig, BabeConfig, Balance, BalancesConfig, ContentWorkingGroupConfig,
     CouncilConfig, CouncilElectionConfig, DataObjectStorageRegistryConfig,
-    DataObjectTypeRegistryConfig, ElectionParameters, GrandpaConfig, ImOnlineConfig, IndicesConfig,
-    MembersConfig, MigrationConfig, Perbill, ProposalsCodexConfig, SessionConfig, SessionKeys,
-    Signature, StakerStatus, StakingConfig, StorageWorkingGroupConfig, SudoConfig, SystemConfig,
-    VersionedStoreConfig, DAYS, WASM_BINARY,
+    DataObjectTypeRegistryConfig, ElectionParameters, GrandpaConfig, ImOnlineConfig, MembersConfig,
+    ProposalsCodexConfig, SessionConfig, SessionKeys, Signature, StakerStatus, StakingConfig,
+    StorageWorkingGroupConfig, SudoConfig, SystemConfig, VersionedStoreConfig, DAYS, WASM_BINARY,
 };
-pub use node_runtime::{AccountId, GenesisConfig};
-use primitives::{sr25519, Pair, Public};
-use runtime_primitives::traits::{IdentifyAccount, Verify};
 
-use babe_primitives::AuthorityId as BabeId;
-use grandpa_primitives::AuthorityId as GrandpaId;
-use im_online::sr25519::AuthorityId as ImOnlineId;
-use serde_json as json;
+pub use node_runtime::{AccountId, GenesisConfig};
 
 type AccountPublic = <Signature as Verify>::Signer;
 
 /// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
-pub type ChainSpec = substrate_service::ChainSpec<GenesisConfig>;
+pub type ChainSpec = sc_service::GenericChainSpec<GenesisConfig>;
 
 use node_runtime::common::constraints::InputValidationLengthConstraint;
+use sc_chain_spec::ChainType;
 
 /// The chain specification option. This is expected to come in from the CLI and
 /// is little more than one of a number of alternatives which can easily be converted
@@ -73,21 +76,35 @@ where
 /// Helper function to generate stash, controller and session key from seed
 pub fn get_authority_keys_from_seed(
     seed: &str,
-) -> (AccountId, AccountId, GrandpaId, BabeId, ImOnlineId) {
+) -> (
+    AccountId,
+    AccountId,
+    GrandpaId,
+    BabeId,
+    ImOnlineId,
+    AuthorityDiscoveryId,
+) {
     (
         get_account_id_from_seed::<sr25519::Public>(&format!("{}//stash", seed)),
         get_account_id_from_seed::<sr25519::Public>(seed),
         get_from_seed::<GrandpaId>(seed),
         get_from_seed::<BabeId>(seed),
         get_from_seed::<ImOnlineId>(seed),
+        get_from_seed::<AuthorityDiscoveryId>(seed),
     )
 }
 
-fn session_keys(grandpa: GrandpaId, babe: BabeId, im_online: ImOnlineId) -> SessionKeys {
+fn session_keys(
+    grandpa: GrandpaId,
+    babe: BabeId,
+    im_online: ImOnlineId,
+    authority_discovery: AuthorityDiscoveryId,
+) -> SessionKeys {
     SessionKeys {
         grandpa,
         babe,
         im_online,
+        authority_discovery,
     }
 }
 
@@ -98,6 +115,7 @@ impl Alternative {
             Alternative::Development => ChainSpec::from_genesis(
                 "Development",
                 "dev",
+                ChainType::Development,
                 || {
                     testnet_genesis(
                         vec![get_authority_keys_from_seed("Alice")],
@@ -111,7 +129,7 @@ impl Alternative {
                         crate::proposals_config::development(),
                     )
                 },
-                vec![],
+                Vec::new(),
                 None,
                 None,
                 Some(chain_spec_properties()),
@@ -120,6 +138,7 @@ impl Alternative {
             Alternative::LocalTestnet => ChainSpec::from_genesis(
                 "Local Testnet",
                 "local_testnet",
+                ChainType::Local,
                 || {
                     testnet_genesis(
                         vec![
@@ -144,7 +163,7 @@ impl Alternative {
                         crate::proposals_config::development(),
                     )
                 },
-                vec![],
+                Vec::new(),
                 None,
                 None,
                 Some(chain_spec_properties()),
@@ -152,14 +171,6 @@ impl Alternative {
             ),
         })
     }
-
-    pub(crate) fn from(s: &str) -> Option<Self> {
-        match s {
-            "dev" => Some(Alternative::Development),
-            "local" => Some(Alternative::LocalTestnet),
-            _ => None,
-        }
-    }
 }
 
 fn new_vs_validation(min: u16, max_min_diff: u16) -> VsInputValidation {
@@ -180,7 +191,14 @@ pub fn chain_spec_properties() -> json::map::Map<String, json::Value> {
 }
 
 pub fn testnet_genesis(
-    initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId)>,
+    initial_authorities: Vec<(
+        AccountId,
+        AccountId,
+        GrandpaId,
+        BabeId,
+        ImOnlineId,
+        AuthorityDiscoveryId,
+    )>,
     root_key: AccountId,
     endowed_accounts: Vec<AccountId>,
     cpcp: node_runtime::ProposalsConfigParameters,
@@ -197,29 +215,15 @@ pub fn testnet_genesis(
             code: WASM_BINARY.to_vec(),
             changes_trie_config: Default::default(),
         }),
-        balances: Some(BalancesConfig {
+        pallet_balances: Some(BalancesConfig {
             balances: endowed_accounts
                 .iter()
                 .cloned()
                 .map(|k| (k, ENDOWMENT))
                 .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
                 .collect(),
-            vesting: vec![],
-        }),
-        indices: Some(IndicesConfig { ids: vec![] }),
-        session: Some(SessionConfig {
-            keys: initial_authorities
-                .iter()
-                .map(|x| {
-                    (
-                        x.0.clone(),
-                        session_keys(x.2.clone(), x.3.clone(), x.4.clone()),
-                    )
-                })
-                .collect::<Vec<_>>(),
         }),
-        staking: Some(StakingConfig {
-            current_era: 0,
+        pallet_staking: Some(StakingConfig {
             validator_count: 20,
             minimum_validator_count: 1,
             stakers: initial_authorities
@@ -230,15 +234,29 @@ pub fn testnet_genesis(
             slash_reward_fraction: Perbill::from_percent(10),
             ..Default::default()
         }),
-        sudo: Some(SudoConfig { key: root_key }),
-        babe: Some(BabeConfig {
+        pallet_sudo: Some(SudoConfig {
+            key: root_key.clone(),
+        }),
+        pallet_babe: Some(BabeConfig {
             authorities: vec![],
         }),
-        im_online: Some(ImOnlineConfig { keys: vec![] }),
-        authority_discovery: Some(AuthorityDiscoveryConfig { keys: vec![] }),
-        grandpa: Some(GrandpaConfig {
+        pallet_im_online: Some(ImOnlineConfig { keys: vec![] }),
+        pallet_authority_discovery: Some(AuthorityDiscoveryConfig { keys: vec![] }),
+        pallet_grandpa: Some(GrandpaConfig {
             authorities: vec![],
         }),
+        pallet_session: Some(SessionConfig {
+            keys: initial_authorities
+                .iter()
+                .map(|x| {
+                    (
+                        x.0.clone(),
+                        x.0.clone(),
+                        session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone()),
+                    )
+                })
+                .collect::<Vec<_>>(),
+        }),
         council: Some(CouncilConfig {
             active_council: vec![],
             term_ends_at: 1,
@@ -260,9 +278,7 @@ pub fn testnet_genesis(
             default_paid_membership_fee: 100u128,
             members: vec![],
         }),
-        forum: Some(crate::forum_config::from_serialized::create(
-            endowed_accounts[0].clone(),
-        )),
+        forum: Some(crate::forum_config::from_serialized::create(root_key)),
         data_object_type_registry: Some(DataObjectTypeRegistryConfig {
             first_data_object_type_id: 1,
         }),
@@ -310,7 +326,6 @@ pub fn testnet_genesis(
             channel_banner_constraint: InputValidationLengthConstraint::new(5, 1024),
             channel_title_constraint: InputValidationLengthConstraint::new(5, 1024),
         }),
-        migration: Some(MigrationConfig {}),
         proposals_codex: Some(ProposalsCodexConfig {
             set_validator_count_proposal_voting_period: cpcp
                 .set_validator_count_proposal_voting_period,
@@ -367,3 +382,74 @@ pub fn testnet_genesis(
         }),
     }
 }
+
+#[cfg(test)]
+pub(crate) mod tests {
+    use super::*;
+    use crate::service::{new_full, new_light};
+    use sc_service_test;
+
+    fn local_testnet_genesis_instant_single() -> GenesisConfig {
+        testnet_genesis(
+            vec![get_authority_keys_from_seed("Alice")],
+            get_account_id_from_seed::<sr25519::Public>("Alice"),
+            vec![get_authority_keys_from_seed("Alice").0],
+            crate::proposals_config::development(),
+        )
+    }
+
+    /// Local testnet config (single validator - Alice)
+    pub fn integration_test_config_with_single_authority() -> ChainSpec {
+        ChainSpec::from_genesis(
+            "Integration Test",
+            "test",
+            ChainType::Development,
+            local_testnet_genesis_instant_single,
+            vec![],
+            None,
+            None,
+            None,
+            Default::default(),
+        )
+    }
+
+    fn local_testnet_genesis() -> GenesisConfig {
+        testnet_genesis(
+            vec![
+                get_authority_keys_from_seed("Alice"),
+                get_authority_keys_from_seed("Bob"),
+            ],
+            get_account_id_from_seed::<sr25519::Public>("Alice"),
+            vec![
+                get_authority_keys_from_seed("Alice").0,
+                get_authority_keys_from_seed("Bob").0,
+            ],
+            crate::proposals_config::development(),
+        )
+    }
+
+    /// Local testnet config (multivalidator Alice + Bob)
+    pub fn integration_test_config_with_two_authorities() -> ChainSpec {
+        ChainSpec::from_genesis(
+            "Integration Test",
+            "test",
+            ChainType::Development,
+            local_testnet_genesis,
+            vec![],
+            None,
+            None,
+            None,
+            Default::default(),
+        )
+    }
+
+    #[test]
+    #[ignore]
+    fn test_connectivity() {
+        sc_service_test::connectivity(
+            integration_test_config_with_two_authorities(),
+            |config| new_full(config),
+            |config| new_light(config),
+        );
+    }
+}

+ 45 - 125
node/src/cli.rs

@@ -1,128 +1,48 @@
-use crate::chain_spec;
-use crate::new_full_start;
-use crate::service;
-use futures::{future, sync::oneshot, Future};
-use log::info;
-use std::cell::RefCell;
-pub use substrate_cli::{error, IntoExit, VersionInfo};
-use substrate_cli::{informant, parse_and_prepare, NoCustom, ParseAndPrepare};
-use substrate_service::{AbstractService, Configuration, Roles as ServiceRoles};
-use tokio::runtime::Runtime;
-
-/// Parse command line arguments into service configuration.
-pub fn run<I, T, E>(args: I, exit: E, version: VersionInfo) -> error::Result<()>
-where
-    I: IntoIterator<Item = T>,
-    T: Into<std::ffi::OsString> + Clone,
-    E: IntoExit,
-{
-    type Config<T> = Configuration<(), T>;
-    match parse_and_prepare::<NoCustom, NoCustom, _>(&version, "joystream-node", args) {
-        ParseAndPrepare::Run(cmd) => cmd.run(
-            load_spec,
-            exit,
-            |exit, _cli_args, _custom_args, config: Config<_>| {
-                info!("{}", version.name);
-                info!("  version {}", config.full_version());
-                info!("  by {}, 2019", version.author);
-                info!("Chain specification: {}", config.chain_spec.name());
-                info!("Node name: {}", config.name);
-                info!("Roles: {:?}", config.roles);
-                let runtime = Runtime::new().map_err(|e| format!("{:?}", e))?;
-                match config.roles {
-                    ServiceRoles::LIGHT => run_until_exit(
-                        runtime,
-                        service::new_light(config).map_err(|e| format!("{:?}", e))?,
-                        exit,
-                    ),
-                    _ => run_until_exit(
-                        runtime,
-                        service::new_full(config).map_err(|e| format!("{:?}", e))?,
-                        exit,
-                    ),
-                }
-                .map_err(|e| format!("{:?}", e))
-            },
-        ),
-        ParseAndPrepare::BuildSpec(cmd) => cmd.run::<NoCustom, _, _, _>(load_spec),
-        ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(
-            |config: Config<_>| Ok(new_full_start!(config).0),
-            load_spec,
-            exit,
-        ),
-        ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder(
-            |config: Config<_>| Ok(new_full_start!(config).0),
-            load_spec,
-            exit,
-        ),
-        ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec),
-        ParseAndPrepare::RevertChain(cmd) => {
-            cmd.run_with_builder(|config: Config<_>| Ok(new_full_start!(config).0), load_spec)
-        }
-        ParseAndPrepare::CustomCommand(_) => Ok(()),
-    }?;
-
-    Ok(())
-}
-
-fn load_spec(id: &str) -> Result<Option<chain_spec::ChainSpec>, String> {
-    Ok(match chain_spec::Alternative::from(id) {
-        Some(spec) => Some(spec.load()?),
-        None => None,
-    })
-}
-
-fn run_until_exit<T, E>(mut runtime: Runtime, service: T, e: E) -> error::Result<()>
-where
-    T: AbstractService,
-    E: IntoExit,
-{
-    let (exit_send, exit) = exit_future::signal();
-
-    let informant = informant::build(&service);
-    runtime.executor().spawn(exit.until(informant).map(|_| ()));
-
-    // we eagerly drop the service so that the internal exit future is fired,
-    // but we need to keep holding a reference to the global telemetry guard
-    let _telemetry = service.telemetry();
-
-    let service_res = {
-        let exit = e
-            .into_exit()
-            .map_err(|_| error::Error::Other("Exit future failed.".into()));
-        let service = service.map_err(error::Error::Service);
-        let select = service.select(exit).map(|_| ()).map_err(|(err, _)| err);
-        runtime.block_on(select)
-    };
-
-    exit_send.fire();
-
-    // TODO [andre]: timeout this future #1318
-    let _ = runtime.shutdown_on_idle().wait();
-
-    service_res
+// Copyright 2019 Joystream Contributors
+// This file is part of Joystream node.
+
+// Joystream node is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Joystream node is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Joystream node.  If not, see <http://www.gnu.org/licenses/>.
+
+use sc_cli::RunCmd;
+use structopt::StructOpt;
+
+/// An overarching CLI command definition.
+#[derive(Debug, StructOpt)]
+pub struct Cli {
+    /// Possible subcommand with parameters.
+    #[structopt(subcommand)]
+    pub subcommand: Option<Subcommand>,
+    #[allow(missing_docs)]
+    #[structopt(flatten)]
+    pub run: RunCmd,
 }
 
-// handles ctrl-c
-pub struct Exit;
-impl IntoExit for Exit {
-    type Exit = future::MapErr<oneshot::Receiver<()>, fn(oneshot::Canceled) -> ()>;
-    fn into_exit(self) -> Self::Exit {
-        // can't use signal directly here because CtrlC takes only `Fn`.
-        let (exit_send, exit) = oneshot::channel();
-
-        let exit_send_cell = RefCell::new(Some(exit_send));
-        ctrlc::set_handler(move || {
-            let exit_send = exit_send_cell
-                .try_borrow_mut()
-                .expect("signal handler not reentrant; qed")
-                .take();
-            if let Some(exit_send) = exit_send {
-                exit_send.send(()).expect("Error sending exit notification");
-            }
-        })
-        .expect("Error setting Ctrl-C handler");
-
-        exit.map_err(drop)
-    }
+/// Possible subcommands of the main binary.
+#[derive(Debug, StructOpt)]
+pub enum Subcommand {
+    /// A set of base subcommands handled by `sc_cli`.
+    #[structopt(flatten)]
+    Base(sc_cli::Subcommand),
+
+    /// The custom inspect subcommmand for decoding blocks and extrinsics.
+    #[structopt(
+        name = "inspect",
+        about = "Decode given block or extrinsic using current native runtime."
+    )]
+    Inspect(node_inspect::cli::InspectCmd),
+
+    /// The custom benchmark subcommmand benchmarking runtime pallets.
+    #[structopt(name = "benchmark", about = "Benchmark runtime pallets.")]
+    Benchmark(frame_benchmarking_cli::BenchmarkCmd),
 }

+ 100 - 0
node/src/command.rs

@@ -0,0 +1,100 @@
+// Copyright 2019 Joystream Contributors
+// This file is part of Joystream node.
+
+// Joystream node is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Joystream node is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Joystream node.  If not, see <http://www.gnu.org/licenses/>.
+
+use crate::cli::{Cli, Subcommand};
+use crate::node_executor;
+use crate::node_rpc;
+use crate::{chain_spec, service};
+
+use node_executor::Executor;
+use node_runtime::{opaque::Block, RuntimeApi};
+use sc_cli::{Result, SubstrateCli};
+use sc_finality_grandpa::{self as grandpa};
+
+impl SubstrateCli for Cli {
+    fn impl_name() -> &'static str {
+        "Joystream Node"
+    }
+
+    fn support_url() -> &'static str {
+        "https://www.joystream.org/"
+    }
+
+    fn copyright_start_year() -> i32 {
+        2019
+    }
+
+    fn executable_name() -> &'static str {
+        "joystream-node"
+    }
+
+    fn impl_version() -> &'static str {
+        env!("SUBSTRATE_CLI_IMPL_VERSION")
+    }
+
+    fn description() -> &'static str {
+        env!("CARGO_PKG_DESCRIPTION")
+    }
+
+    fn author() -> &'static str {
+        env!("CARGO_PKG_AUTHORS")
+    }
+
+    fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
+        Ok(match id {
+            "dev" => Box::new(chain_spec::Alternative::Development.load()?),
+            "local" => Box::new(chain_spec::Alternative::LocalTestnet.load()?),
+            path => Box::new(chain_spec::ChainSpec::from_json_file(
+                std::path::PathBuf::from(path),
+            )?),
+        })
+    }
+}
+
+/// Parse command line arguments into service configuration.
+pub fn run() -> Result<()> {
+    let cli = Cli::from_args();
+
+    match &cli.subcommand {
+        None => {
+            let runner = cli.create_runner(&cli.run)?;
+            runner.run_node(service::new_light, service::new_full, node_runtime::VERSION)
+        }
+        Some(Subcommand::Inspect(cmd)) => {
+            let runner = cli.create_runner(cmd)?;
+
+            runner.sync_run(|config| cmd.run::<Block, RuntimeApi, Executor>(config))
+        }
+        Some(Subcommand::Benchmark(cmd)) => {
+            if cfg!(feature = "runtime-benchmarks") {
+                let runner = cli.create_runner(cmd)?;
+
+                runner.sync_run(|config| cmd.run::<Block, Executor>(config))
+            } else {
+                println!(
+                    "Benchmarking wasn't enabled when building the node. \
+				You can enable it with `--features runtime-benchmarks`."
+                );
+                Ok(())
+            }
+        }
+        Some(Subcommand::Base(subcommand)) => {
+            let runner = cli.create_runner(subcommand)?;
+
+            runner.run_subcommand(subcommand, |config| Ok(new_full_start!(config).0))
+        }
+    }
+}

+ 4 - 0
node/src/lib.rs

@@ -3,4 +3,8 @@ pub mod cli;
 pub mod forum_config;
 pub mod members_config;
 pub mod proposals_config;
+#[macro_use]
 pub mod service;
+pub mod command;
+pub mod node_executor;
+pub mod node_rpc;

+ 1 - 13
node/src/members_config.rs

@@ -1,7 +1,7 @@
 use serde::Deserialize;
 use serde_json::Result;
 
-use primitives::crypto::{AccountId32, Ss58Codec};
+use sp_core::crypto::{AccountId32, Ss58Codec};
 
 #[derive(Deserialize)]
 struct Member {
@@ -12,18 +12,6 @@ struct Member {
     about: String,
 }
 
-// fn test_load_members() -> Result<Vec<Member>> {
-//     let data = r#"
-//         [{
-//             "address": "5Gn9n7SDJ7VgHqHQWYzkSA4vX6DCmS5TFWdHxikTXp9b4L32",
-//             "handle": "mokhtar",
-//             "avatar_uri": "http://mokhtar.net/avatar.png",
-//             "about": "Mokhtar"
-//         }]"#;
-
-//     serde_json::from_str(data)
-// }
-
 fn parse_members_json() -> Result<Vec<Member>> {
     let data = include_str!("../res/acropolis_members.json");
     serde_json::from_str(data)

+ 10 - 0
node/src/node_executor.rs

@@ -0,0 +1,10 @@
+use sc_executor::native_executor_instance;
+
+// Declare an instance of the native executor named `Executor`. Include the wasm binary as the
+// equivalent wasm code.
+native_executor_instance!(
+    pub Executor,
+    node_runtime::api::dispatch,
+    node_runtime::native_version,
+    frame_benchmarking::benchmarking::HostFunctions,
+);

+ 188 - 0
node/src/node_rpc.rs

@@ -0,0 +1,188 @@
+// This file is part of Substrate.
+
+// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! A collection of node-specific RPC methods.
+//!
+//! Since `substrate` core functionality makes no assumptions
+//! about the modules used inside the runtime, so do
+//! RPC methods defined in `sc-rpc` crate.
+//! It means that `client/rpc` can't have any methods that
+//! need some strong assumptions about the particular runtime.
+//!
+//! The RPCs available in this crate however can make some assumptions
+//! about how the runtime is constructed and what FRAME pallets
+//! are part of it. Therefore all node-runtime-specific RPCs can
+//! be placed here or imported from corresponding FRAME RPC definitions.
+
+#![warn(missing_docs)]
+
+use std::sync::Arc;
+
+use node_runtime::UncheckedExtrinsic;
+use node_runtime::{opaque::Block, AccountId, Balance, BlockNumber, Hash, Index};
+use sc_consensus_babe::{Config, Epoch};
+use sc_consensus_babe_rpc::BabeRpcHandler;
+use sc_consensus_epochs::SharedEpochChanges;
+use sc_finality_grandpa::{SharedAuthoritySet, SharedVoterState};
+use sc_finality_grandpa_rpc::GrandpaRpcHandler;
+use sc_keystore::KeyStorePtr;
+use sc_rpc_api::DenyUnsafe;
+use sp_api::ProvideRuntimeApi;
+use sp_block_builder::BlockBuilder;
+use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
+use sp_consensus::SelectChain;
+use sp_consensus_babe::BabeApi;
+use sp_transaction_pool::TransactionPool;
+
+/// Light client extra dependencies.
+pub struct LightDeps<C, F, P> {
+    /// The client instance to use.
+    pub client: Arc<C>,
+    /// Transaction pool instance.
+    pub pool: Arc<P>,
+    /// Remote access to the blockchain (async).
+    pub remote_blockchain: Arc<dyn sc_client_api::light::RemoteBlockchain<Block>>,
+    /// Fetcher instance.
+    pub fetcher: Arc<F>,
+}
+
+/// Extra dependencies for BABE.
+pub struct BabeDeps {
+    /// BABE protocol config.
+    pub babe_config: Config,
+    /// BABE pending epoch changes.
+    pub shared_epoch_changes: SharedEpochChanges<Block, Epoch>,
+    /// The keystore that manages the keys of the node.
+    pub keystore: KeyStorePtr,
+}
+
+/// Extra dependencies for GRANDPA
+pub struct GrandpaDeps {
+    /// Voting round info.
+    pub shared_voter_state: SharedVoterState,
+    /// Authority set info.
+    pub shared_authority_set: SharedAuthoritySet<Hash, BlockNumber>,
+}
+
+/// Full client dependencies.
+pub struct FullDeps<C, P, SC> {
+    /// The client instance to use.
+    pub client: Arc<C>,
+    /// Transaction pool instance.
+    pub pool: Arc<P>,
+    /// The SelectChain Strategy
+    pub select_chain: SC,
+    /// Whether to deny unsafe calls
+    pub deny_unsafe: DenyUnsafe,
+    /// BABE specific dependencies.
+    pub babe: BabeDeps,
+    /// GRANDPA specific dependencies.
+    pub grandpa: GrandpaDeps,
+}
+
+/// Instantiate all Full RPC extensions.
+pub fn create_full<C, P, M, SC>(deps: FullDeps<C, P, SC>) -> jsonrpc_core::IoHandler<M>
+where
+    C: ProvideRuntimeApi<Block>,
+    C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
+    C: Send + Sync + 'static,
+    C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
+    C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<
+        Block,
+        Balance,
+        UncheckedExtrinsic,
+    >,
+    C::Api: BabeApi<Block>,
+    C::Api: BlockBuilder<Block>,
+    P: TransactionPool + 'static,
+    M: jsonrpc_core::Metadata + Default,
+    SC: SelectChain<Block> + 'static,
+{
+    use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
+    use substrate_frame_rpc_system::{FullSystem, SystemApi};
+
+    let mut io = jsonrpc_core::IoHandler::default();
+    let FullDeps {
+        client,
+        pool,
+        select_chain,
+        deny_unsafe,
+        babe,
+        grandpa,
+    } = deps;
+    let BabeDeps {
+        keystore,
+        babe_config,
+        shared_epoch_changes,
+    } = babe;
+    let GrandpaDeps {
+        shared_voter_state,
+        shared_authority_set,
+    } = grandpa;
+
+    io.extend_with(SystemApi::to_delegate(FullSystem::new(
+        client.clone(),
+        pool,
+        deny_unsafe,
+    )));
+    // Making synchronous calls in light client freezes the browser currently,
+    // more context: https://github.com/paritytech/substrate/pull/3480
+    // These RPCs should use an asynchronous caller instead.
+    io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(
+        client.clone(),
+    )));
+    io.extend_with(sc_consensus_babe_rpc::BabeApi::to_delegate(
+        BabeRpcHandler::new(
+            client,
+            shared_epoch_changes,
+            keystore,
+            babe_config,
+            select_chain,
+            deny_unsafe,
+        ),
+    ));
+    io.extend_with(sc_finality_grandpa_rpc::GrandpaApi::to_delegate(
+        GrandpaRpcHandler::new(shared_authority_set, shared_voter_state),
+    ));
+
+    io
+}
+
+/// Instantiate all Light RPC extensions.
+pub fn create_light<C, P, M, F>(deps: LightDeps<C, F, P>) -> jsonrpc_core::IoHandler<M>
+where
+    C: sp_blockchain::HeaderBackend<Block>,
+    C: Send + Sync + 'static,
+    F: sc_client_api::light::Fetcher<Block> + 'static,
+    P: TransactionPool + 'static,
+    M: jsonrpc_core::Metadata + Default,
+{
+    use substrate_frame_rpc_system::{LightSystem, SystemApi};
+
+    let LightDeps {
+        client,
+        pool,
+        remote_blockchain,
+        fetcher,
+    } = deps;
+    let mut io = jsonrpc_core::IoHandler::default();
+    io.extend_with(SystemApi::<Hash, AccountId, Index>::to_delegate(
+        LightSystem::new(client, remote_blockchain, fetcher, pool),
+    ));
+
+    io
+}

+ 529 - 225
node/src/service.rs

@@ -16,107 +16,141 @@
 
 #![warn(unused_extern_crates)]
 
-// Clippy linter warning.
-#![allow(clippy::type_complexity)] // disable it because this is foreign code and can be changed any time
-
-// Clippy linter warning.
-#![allow(clippy::redundant_closure_call)] // disable it because of the substrate lib design
-
-//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.
-
-use client_db::Backend;
-use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
-use inherents::InherentDataProviders;
-use network::{construct_simple_protocol, NetworkService};
-use node_runtime::{self, opaque::Block, GenesisConfig, RuntimeApi};
-use offchain::OffchainWorkers;
-use primitives::Blake2Hasher;
-use runtime_primitives::traits::Block as BlockT;
-use std::sync::Arc;
-use substrate_client::{Client, LocalCallExecutor, LongestChain};
-pub use substrate_executor::{native_executor_instance, NativeExecutor};
-use substrate_service::{
-    error::Error as ServiceError, AbstractService, Configuration, NetworkStatus, Service,
-    ServiceBuilder,
-};
-use transaction_pool::{self, txpool::Pool as TransactionPool};
+// Substrate implementation issue.
+#![allow(clippy::redundant_closure_call)]
 
-construct_simple_protocol! {
-    /// Demo protocol attachment for substrate.
-    pub struct NodeProtocol where Block = Block { }
-}
+//! Service implementation. Specialized wrapper over substrate service.
+
+use node_runtime::opaque::Block;
+use node_runtime::RuntimeApi;
+use sc_consensus::LongestChain;
+use sc_finality_grandpa::{
+    self as grandpa, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider,
+};
+use sc_service::{
+    config::Configuration, error::Error as ServiceError, AbstractService, ServiceBuilder,
+};
+use sp_inherents::InherentDataProviders;
+use std::sync::Arc;
 
-// Declare an instance of the native executor named `Executor`. Include the wasm binary as the
-// equivalent wasm code.
-native_executor_instance!(
-    pub Executor,
-    node_runtime::api::dispatch,
-    node_runtime::native_version
-);
+use crate::node_executor;
+use crate::node_rpc;
 
 /// Starts a `ServiceBuilder` for a full service.
 ///
 /// Use this macro if you don't actually need the full service, but just the builder in order to
 /// be able to perform chain operations.
-#[macro_export]
 macro_rules! new_full_start {
     ($config:expr) => {{
-        // type RpcExtension = jsonrpc_core::IoHandler<substrate_rpc::Metadata>;
+        use std::sync::Arc;
+
         let mut import_setup = None;
-        let inherent_data_providers = inherents::InherentDataProviders::new();
+        let mut rpc_setup = None;
+        let inherent_data_providers = sp_inherents::InherentDataProviders::new();
 
-        let builder = substrate_service::ServiceBuilder::new_full::<
-            node_runtime::opaque::Block,
-            node_runtime::RuntimeApi,
-            crate::service::Executor,
+        let builder = sc_service::ServiceBuilder::new_full::<
+            Block,
+            RuntimeApi,
+            node_executor::Executor,
         >($config)?
-        .with_select_chain(|_config, backend| {
-            Ok(substrate_client::LongestChain::new(backend.clone()))
-        })?
-        .with_transaction_pool(|config, client| {
-            Ok(transaction_pool::txpool::Pool::new(
-                config,
-                transaction_pool::FullChainApi::new(client),
+        .with_select_chain(|_config, backend| Ok(sc_consensus::LongestChain::new(backend.clone())))?
+        .with_transaction_pool(|builder| {
+            let pool_api = sc_transaction_pool::FullChainApi::new(builder.client().clone());
+            let config = builder.config();
+
+            Ok(sc_transaction_pool::BasicPool::new(
+                config.transaction_pool.clone(),
+                std::sync::Arc::new(pool_api),
+                builder.prometheus_registry(),
             ))
         })?
-        .with_import_queue(|_config, client, mut select_chain, _transaction_pool| {
-            let select_chain = select_chain
-                .take()
-                .ok_or_else(|| substrate_service::Error::SelectChainRequired)?;
-            let (grandpa_block_import, grandpa_link) =
-                grandpa::block_import::<_, _, _, node_runtime::RuntimeApi, _>(
+        .with_import_queue(
+            |_config,
+             client,
+             mut select_chain,
+             _transaction_pool,
+             spawn_task_handle,
+             prometheus_registry| {
+                let select_chain = select_chain
+                    .take()
+                    .ok_or_else(|| sc_service::Error::SelectChainRequired)?;
+                let (grandpa_block_import, grandpa_link) = grandpa::block_import(
                     client.clone(),
-                    &*client,
+                    &(client.clone() as Arc<_>),
                     select_chain,
                 )?;
-            let justification_import = grandpa_block_import.clone();
-
-            let (block_import, babe_link) = babe::block_import(
-                babe::Config::get_or_compute(&*client)?,
-                grandpa_block_import,
-                client.clone(),
-                client.clone(),
-            )?;
-
-            let import_queue = babe::import_queue(
-                babe_link.clone(),
-                block_import.clone(),
-                Some(Box::new(justification_import)),
-                None,
-                client.clone(),
-                client,
-                inherent_data_providers.clone(),
-            )?;
-
-            import_setup = Some((block_import, grandpa_link, babe_link));
-            Ok(import_queue)
+                let justification_import = grandpa_block_import.clone();
+
+                let (block_import, babe_link) = sc_consensus_babe::block_import(
+                    sc_consensus_babe::Config::get_or_compute(&*client)?,
+                    grandpa_block_import,
+                    client.clone(),
+                )?;
+
+                let import_queue = sc_consensus_babe::import_queue(
+                    babe_link.clone(),
+                    block_import.clone(),
+                    Some(Box::new(justification_import)),
+                    None,
+                    client,
+                    inherent_data_providers.clone(),
+                    spawn_task_handle,
+                    prometheus_registry,
+                )?;
+
+                import_setup = Some((block_import, grandpa_link, babe_link));
+                Ok(import_queue)
+            },
+        )?
+        .with_rpc_extensions_builder(|builder| {
+            let grandpa_link = import_setup
+                .as_ref()
+                .map(|s| &s.1)
+                .expect("GRANDPA LinkHalf is present for full services or set up failed; qed.");
+
+            let shared_authority_set = grandpa_link.shared_authority_set().clone();
+            let shared_voter_state = grandpa::SharedVoterState::empty();
+
+            rpc_setup = Some((shared_voter_state.clone()));
+
+            let babe_link = import_setup
+                .as_ref()
+                .map(|s| &s.2)
+                .expect("BabeLink is present for full services or set up failed; qed.");
+
+            let babe_config = babe_link.config().clone();
+            let shared_epoch_changes = babe_link.epoch_changes().clone();
+
+            let client = builder.client().clone();
+            let pool = builder.pool().clone();
+            let select_chain = builder
+                .select_chain()
+                .cloned()
+                .expect("SelectChain is present for full services or set up failed; qed.");
+            let keystore = builder.keystore().clone();
+
+            Ok(move |deny_unsafe| {
+                let deps = node_rpc::FullDeps {
+                    client: client.clone(),
+                    pool: pool.clone(),
+                    select_chain: select_chain.clone(),
+                    deny_unsafe,
+                    babe: node_rpc::BabeDeps {
+                        babe_config: babe_config.clone(),
+                        shared_epoch_changes: shared_epoch_changes.clone(),
+                        keystore: keystore.clone(),
+                    },
+                    grandpa: node_rpc::GrandpaDeps {
+                        shared_voter_state: shared_voter_state.clone(),
+                        shared_authority_set: shared_authority_set.clone(),
+                    },
+                };
+
+                node_rpc::create_full(deps)
+            })
         })?;
-        // We don't have any custom rpc commands...
-        // .with_rpc_extensions(|client, pool| -> RpcExtension {
-        // 	node_rpc::create(client, pool)
-        // })?;
 
-        (builder, import_setup, inherent_data_providers)
+        (builder, import_setup, inherent_data_providers, rpc_setup)
     }};
 }
 
@@ -126,58 +160,57 @@ macro_rules! new_full_start {
 /// concrete types instead.
 macro_rules! new_full {
 	($config:expr, $with_startup_data: expr) => {{
-		use futures::sync::mpsc;
-		use network::DhtEvent;
+		use futures::prelude::*;
+		use sc_network::Event;
+		use sc_client_api::ExecutorProvider;
+		use sp_core::traits::BareCryptoStorePtr;
 
 		let (
-			is_authority,
+			role,
 			force_authoring,
 			name,
-			disable_grandpa
+			disable_grandpa,
 		) = (
-			$config.roles.is_authority(),
+			$config.role.clone(),
 			$config.force_authoring,
-			$config.name.clone(),
-			$config.disable_grandpa
+			$config.network.node_name.clone(),
+			$config.disable_grandpa,
 		);
 
-        // sentry nodes announce themselves as authorities to the network
-		// and should run the same protocols authorities do, but it should
-		// never actively participate in any consensus process.
-        let participates_in_consensus = is_authority && !$config.sentry_mode;
+		let (builder, mut import_setup, inherent_data_providers, mut rpc_setup) =
+			new_full_start!($config);
 
-		let (builder, mut import_setup, inherent_data_providers) = new_full_start!($config);
-
-		// Dht event channel from the network to the authority discovery module. Use bounded channel to ensure
-		// back-pressure. Authority discovery is triggering one event per authority within the current authority set.
-		// This estimates the authority set size to be somewhere below 10 000 thereby setting the channel buffer size to
-		// 10 000.
-		let (dht_event_tx, _dht_event_rx) =
-			mpsc::channel::<DhtEvent>(10_000);
-
-		let service = builder.with_network_protocol(|_| Ok(crate::service::NodeProtocol::new()))?
-			.with_finality_proof_provider(|client, backend|
-				Ok(Arc::new(grandpa::FinalityProofProvider::new(backend, client)) as _)
-			)?
-			.with_dht_event_tx(dht_event_tx)?
-			.build()?;
+		let service = builder
+			.with_finality_proof_provider(|client, backend| {
+				// GenesisAuthoritySetProvider is implemented for StorageAndProofProvider
+				let provider = client as Arc<dyn grandpa::StorageAndProofProvider<_, _>>;
+				Ok(Arc::new(grandpa::FinalityProofProvider::new(backend, provider)) as _)
+			})?
+			.build_full()?;
 
 		let (block_import, grandpa_link, babe_link) = import_setup.take()
-				.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");
+			.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");
+
+		let shared_voter_state = rpc_setup.take()
+			.expect("The SharedVoterState is present for Full Services or setup failed before. qed");
 
 		($with_startup_data)(&block_import, &babe_link);
 
-		if participates_in_consensus {
-			let proposer = substrate_basic_authorship::ProposerFactory {
-				client: service.client(),
-				transaction_pool: service.transaction_pool(),
-			};
+		if let sc_service::config::Role::Authority { .. } = &role {
+			let proposer = sc_basic_authorship::ProposerFactory::new(
+				service.client(),
+				service.transaction_pool(),
+				service.prometheus_registry().as_ref(),
+			);
 
 			let client = service.client();
 			let select_chain = service.select_chain()
-				.ok_or(substrate_service::Error::SelectChainRequired)?;
+				.ok_or(sc_service::Error::SelectChainRequired)?;
+
+			let can_author_with =
+				sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());
 
-			let babe_config = babe::BabeParams {
+			let babe_config = sc_consensus_babe::BabeParams {
 				keystore: service.keystore(),
 				client,
 				select_chain,
@@ -187,62 +220,95 @@ macro_rules! new_full {
 				inherent_data_providers: inherent_data_providers.clone(),
 				force_authoring,
 				babe_link,
+				can_author_with,
 			};
 
-			let babe = babe::start_babe(babe_config)?;
-			service.spawn_essential_task(babe);
-        }
+			let babe = sc_consensus_babe::start_babe(babe_config)?;
+			service.spawn_essential_task_handle().spawn_blocking("babe-proposer", babe);
+		}
+
+		// Spawn authority discovery module.
+		if matches!(role, sc_service::config::Role::Authority{..} | sc_service::config::Role::Sentry {..}) {
+			let (sentries, authority_discovery_role) = match role {
+				sc_service::config::Role::Authority { ref sentry_nodes } => (
+					sentry_nodes.clone(),
+					sc_authority_discovery::Role::Authority (
+						service.keystore(),
+					),
+				),
+				sc_service::config::Role::Sentry {..} => (
+					vec![],
+					sc_authority_discovery::Role::Sentry,
+				),
+				_ => unreachable!("Due to outer matches! constraint; qed.")
+			};
+
+			let network = service.network();
+			let dht_event_stream = network.event_stream("authority-discovery").filter_map(|e| async move { match e {
+				Event::Dht(e) => Some(e),
+				_ => None,
+			}}).boxed();
+			let authority_discovery = sc_authority_discovery::AuthorityDiscovery::new(
+				service.client(),
+				network,
+				sentries,
+				dht_event_stream,
+				authority_discovery_role,
+				service.prometheus_registry(),
+			);
+
+			service.spawn_task_handle().spawn("authority-discovery", authority_discovery);
+		}
 
-        // if the node isn't actively participating in consensus then it doesn't
+		// if the node isn't actively participating in consensus then it doesn't
 		// need a keystore, regardless of which protocol we use below.
-		let keystore = if participates_in_consensus {
-			Some(service.keystore())
+		let keystore = if role.is_authority() {
+			Some(service.keystore() as BareCryptoStorePtr)
 		} else {
 			None
-        };
-
-        let config = grandpa::Config {
-            // FIXME #1578 make this available through chainspec
-            gossip_duration: std::time::Duration::from_millis(333),
-            justification_period: 512,
-            name: Some(name),
-            observer_enabled: true,
-            keystore,
-            is_authority,
-        };
-
-		match (is_authority, disable_grandpa) {
-			(false, false) => {
-				// start the lightweight GRANDPA observer
-				service.spawn_task(Box::new(grandpa::run_grandpa_observer(
-					config,
-					grandpa_link,
-					service.network(),
-					service.on_exit(),
-				)?));
-			},
-			(true, false) => {
-				// start the full GRANDPA voter
-				let grandpa_config = grandpa::GrandpaParams {
-					config,
-					link: grandpa_link,
-					network: service.network(),
-					inherent_data_providers: inherent_data_providers.clone(),
-					on_exit: service.on_exit(),
-					telemetry_on_connect: Some(service.telemetry_on_connect_stream()),
-					voting_rule: grandpa::VotingRulesBuilder::default().build(),
-                };
-                // the GRANDPA voter task is considered infallible, i.e.
-				// if it fails we take down the service with it.
-				service.spawn_essential_task(grandpa::run_grandpa_voter(grandpa_config)?);
-			},
-			(_, true) => {
-				grandpa::setup_disabled_grandpa(
-					service.client(),
-					&inherent_data_providers,
-					service.network(),
-				)?;
-			},
+		};
+
+		let config = grandpa::Config {
+			// FIXME #1578 make this available through chainspec
+			gossip_duration: std::time::Duration::from_millis(333),
+			justification_period: 512,
+			name: Some(name),
+			observer_enabled: false,
+			keystore,
+			is_authority: role.is_network_authority(),
+		};
+
+		let enable_grandpa = !disable_grandpa;
+		if enable_grandpa {
+			// start the full GRANDPA voter
+			// NOTE: non-authorities could run the GRANDPA observer protocol, but at
+			// this point the full voter should provide better guarantees of block
+			// and vote data availability than the observer. The observer has not
+			// been tested extensively yet and having most nodes in a network run it
+			// could lead to finality stalls.
+			let grandpa_config = grandpa::GrandpaParams {
+				config,
+				link: grandpa_link,
+				network: service.network(),
+				inherent_data_providers: inherent_data_providers.clone(),
+				telemetry_on_connect: Some(service.telemetry_on_connect_stream()),
+				voting_rule: grandpa::VotingRulesBuilder::default().build(),
+				prometheus_registry: service.prometheus_registry(),
+				shared_voter_state,
+			};
+
+			// the GRANDPA voter task is considered infallible, i.e.
+			// if it fails we take down the service with it.
+			service.spawn_essential_task_handle().spawn_blocking(
+				"grandpa-voter",
+				grandpa::run_grandpa_voter(grandpa_config)?
+			);
+		} else {
+			grandpa::setup_disabled_grandpa(
+				service.client(),
+				&inherent_data_providers,
+				service.network(),
+			)?;
 		}
 
 		Ok((service, inherent_data_providers))
@@ -252,70 +318,49 @@ macro_rules! new_full {
 	}}
 }
 
-#[allow(dead_code)]
-type ConcreteBlock = node_runtime::opaque::Block;
-#[allow(dead_code)]
-type ConcreteClient = Client<
-    Backend<ConcreteBlock>,
-    LocalCallExecutor<Backend<ConcreteBlock>, NativeExecutor<Executor>>,
-    ConcreteBlock,
-    node_runtime::RuntimeApi,
->;
-#[allow(dead_code)]
-type ConcreteBackend = Backend<ConcreteBlock>;
-
-/// A specialized configuration object for setting up the node..
-pub type NodeConfiguration<C> =
-    Configuration<C, GenesisConfig /*, crate::chain_spec::Extensions*/>;
-
 /// Builds a new service for a full client.
-pub fn new_full<C: Send + Default + 'static>(config: NodeConfiguration<C>)
--> Result<
-	Service<
-		ConcreteBlock,
-		ConcreteClient,
-		LongestChain<ConcreteBackend, ConcreteBlock>,
-		NetworkStatus<ConcreteBlock>,
-		NetworkService<ConcreteBlock, crate::service::NodeProtocol, <ConcreteBlock as BlockT>::Hash>,
-		TransactionPool<transaction_pool::FullChainApi<ConcreteClient, ConcreteBlock>>,
-		OffchainWorkers<
-			ConcreteClient,
-			<ConcreteBackend as substrate_client::backend::Backend<Block, Blake2Hasher>>::OffchainStorage,
-			ConcreteBlock,
-		>
-	>,
-	ServiceError,
->
-{
+pub fn new_full(config: Configuration) -> Result<impl AbstractService, ServiceError> {
     new_full!(config).map(|(service, _)| service)
 }
 
 /// Builds a new service for a light client.
-pub fn new_light<C: Send + Default + 'static>(
-    config: NodeConfiguration<C>,
-) -> Result<impl AbstractService, ServiceError> {
-    // type RpcExtension = jsonrpc_core::IoHandler<substrate_rpc::Metadata>;
+pub fn new_light(config: Configuration) -> Result<impl AbstractService, ServiceError> {
     let inherent_data_providers = InherentDataProviders::new();
 
-    let service = ServiceBuilder::new_light::<Block, RuntimeApi, Executor>(config)?
+    let service = ServiceBuilder::new_light::<Block, RuntimeApi, node_executor::Executor>(config)?
         .with_select_chain(|_config, backend| Ok(LongestChain::new(backend.clone())))?
-        .with_transaction_pool(|config, client| {
-            Ok(TransactionPool::new(
-                config,
-                transaction_pool::FullChainApi::new(client),
-            ))
+        .with_transaction_pool(|builder| {
+            let fetcher = builder
+                .fetcher()
+                .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?;
+            let pool_api =
+                sc_transaction_pool::LightChainApi::new(builder.client().clone(), fetcher);
+            let pool = sc_transaction_pool::BasicPool::with_revalidation_type(
+                builder.config().transaction_pool.clone(),
+                Arc::new(pool_api),
+                builder.prometheus_registry(),
+                sc_transaction_pool::RevalidationType::Light,
+            );
+            Ok(pool)
         })?
         .with_import_queue_and_fprb(
-            |_config, client, backend, fetcher, _select_chain, _tx_pool| {
+            |_config,
+             client,
+             backend,
+             fetcher,
+             _select_chain,
+             _tx_pool,
+             spawn_task_handle,
+             registry| {
                 let fetch_checker = fetcher
                     .map(|fetcher| fetcher.checker().clone())
                     .ok_or_else(|| {
                         "Trying to start light import queue without active fetch checker"
                     })?;
-                let grandpa_block_import = grandpa::light_block_import::<_, _, _, RuntimeApi>(
+                let grandpa_block_import = grandpa::light_block_import(
                     client.clone(),
                     backend,
-                    &*client,
+                    &(client.clone() as Arc<_>),
                     Arc::new(fetch_checker),
                 )?;
 
@@ -323,35 +368,294 @@ pub fn new_light<C: Send + Default + 'static>(
                 let finality_proof_request_builder =
                     finality_proof_import.create_finality_proof_request_builder();
 
-                let (babe_block_import, babe_link) = babe::block_import(
-                    babe::Config::get_or_compute(&*client)?,
+                let (babe_block_import, babe_link) = sc_consensus_babe::block_import(
+                    sc_consensus_babe::Config::get_or_compute(&*client)?,
                     grandpa_block_import,
                     client.clone(),
-                    client.clone(),
                 )?;
 
-                let import_queue = babe::import_queue(
+                let import_queue = sc_consensus_babe::import_queue(
                     babe_link,
                     babe_block_import,
                     None,
                     Some(Box::new(finality_proof_import)),
-                    client.clone(),
                     client,
                     inherent_data_providers.clone(),
+                    spawn_task_handle,
+                    registry,
                 )?;
 
                 Ok((import_queue, finality_proof_request_builder))
             },
         )?
-        .with_network_protocol(|_| Ok(NodeProtocol::new()))?
         .with_finality_proof_provider(|client, backend| {
-            Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _)
+            // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider
+            let provider = client as Arc<dyn StorageAndProofProvider<_, _>>;
+            Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)
+        })?
+        .with_rpc_extensions(|builder| {
+            let fetcher = builder
+                .fetcher()
+                .ok_or_else(|| "Trying to start node RPC without active fetcher")?;
+            let remote_blockchain = builder
+                .remote_backend()
+                .ok_or_else(|| "Trying to start node RPC without active remote blockchain")?;
+
+            let light_deps = node_rpc::LightDeps {
+                remote_blockchain,
+                fetcher,
+                client: builder.client().clone(),
+                pool: builder.pool(),
+            };
+
+            Ok(node_rpc::create_light(light_deps))
         })?
-        // We don't have any custom rpc extensions
-        // .with_rpc_extensions(|client, pool| -> RpcExtension {
-        // 	node_rpc::create(client, pool)
-        // })?
-        .build()?;
+        .build_light()?;
 
     Ok(service)
 }
+
+#[cfg(test)]
+mod tests {
+    use crate::node_executor;
+    use crate::node_rpc;
+    use crate::service::{new_full, new_light};
+    use codec::{Decode, Encode};
+    use node_runtime::RuntimeApi;
+    use node_runtime::{currency::CENTS, SLOT_DURATION};
+    use node_runtime::{opaque::Block, AccountId, DigestItem, Signature};
+    use node_runtime::{BalancesCall, Call, UncheckedExtrinsic};
+    use sc_consensus_babe::{BabeIntermediate, CompatibleDigestItem, INTERMEDIATE_KEY};
+    use sc_consensus_epochs::descendent_query;
+    use sc_finality_grandpa::{self as grandpa};
+    use sc_service::AbstractService;
+    use sp_consensus::{
+        BlockImport, BlockImportParams, BlockOrigin, Environment, ForkChoiceStrategy, Proposer,
+        RecordProof,
+    };
+    use sp_core::{crypto::Pair as CryptoPair, H256};
+    use sp_finality_tracker;
+    use sp_keyring::AccountKeyring;
+    use sp_runtime::traits::IdentifyAccount;
+    use sp_runtime::{
+        generic::{BlockId, Digest, Era, SignedPayload},
+        traits::Verify,
+        traits::{Block as BlockT, Header as HeaderT},
+        OpaqueExtrinsic,
+    };
+    use sp_timestamp;
+    use sp_transaction_pool::{ChainEvent, MaintainedTransactionPool};
+    use std::{any::Any, borrow::Cow, sync::Arc};
+
+    type AccountPublic = <Signature as Verify>::Signer;
+
+    // Long running test. Run it locally only after the node changes.
+    #[test]
+    // It is "ignored", but the node-cli ignored tests are running on the CI.
+    // This can be run locally with `cargo test --release -p node-cli test_sync -- --ignored`.
+    #[ignore]
+    fn test_sync() {
+        let keystore_path = tempfile::tempdir().expect("Creates keystore path");
+        let keystore =
+            sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore");
+        let alice = keystore
+            .write()
+            .insert_ephemeral_from_seed::<sc_consensus_babe::AuthorityPair>("//Alice")
+            .expect("Creates authority pair");
+
+        let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority();
+
+        // For the block factory
+        let mut slot_num = 1u64;
+
+        // For the extrinsics factory
+        let bob = Arc::new(AccountKeyring::Bob.pair());
+        let charlie = Arc::new(AccountKeyring::Charlie.pair());
+        let mut index = 0;
+
+        sc_service_test::sync(
+            chain_spec,
+            |config| {
+                let mut setup_handles = None;
+                new_full!(
+                    config,
+                    |block_import: &sc_consensus_babe::BabeBlockImport<Block, _, _>,
+                     babe_link: &sc_consensus_babe::BabeLink<Block>| {
+                        setup_handles = Some((block_import.clone(), babe_link.clone()));
+                    }
+                )
+                .map(move |(node, x)| (node, (x, setup_handles.unwrap())))
+            },
+            |config| new_light(config),
+            |service, &mut (ref inherent_data_providers, (ref mut block_import, ref babe_link))| {
+                let mut inherent_data = inherent_data_providers
+                    .create_inherent_data()
+                    .expect("Creates inherent data.");
+                inherent_data.replace_data(sp_finality_tracker::INHERENT_IDENTIFIER, &1u64);
+
+                let parent_id = BlockId::number(service.client().chain_info().best_number);
+                let parent_header = service.client().header(&parent_id).unwrap().unwrap();
+                let parent_hash = parent_header.hash();
+                let parent_number = *parent_header.number();
+
+                futures::executor::block_on(service.transaction_pool().maintain(
+                    ChainEvent::NewBlock {
+                        is_new_best: true,
+                        hash: parent_header.hash(),
+                        tree_route: None,
+                        header: parent_header.clone(),
+                    },
+                ));
+
+                let mut proposer_factory = sc_basic_authorship::ProposerFactory::new(
+                    service.client(),
+                    service.transaction_pool(),
+                    None,
+                );
+
+                let epoch_descriptor = babe_link
+                    .epoch_changes()
+                    .lock()
+                    .epoch_descriptor_for_child_of(
+                        descendent_query(&*service.client()),
+                        &parent_hash,
+                        parent_number,
+                        slot_num,
+                    )
+                    .unwrap()
+                    .unwrap();
+
+                let mut digest = Digest::<H256>::default();
+
+                // even though there's only one authority some slots might be empty,
+                // so we must keep trying the next slots until we can claim one.
+                let babe_pre_digest = loop {
+                    inherent_data.replace_data(
+                        sp_timestamp::INHERENT_IDENTIFIER,
+                        &(slot_num * SLOT_DURATION),
+                    );
+                    if let Some(babe_pre_digest) = sc_consensus_babe::test_helpers::claim_slot(
+                        slot_num,
+                        &parent_header,
+                        &*service.client(),
+                        &keystore,
+                        &babe_link,
+                    ) {
+                        break babe_pre_digest;
+                    }
+
+                    slot_num += 1;
+                };
+
+                digest.push(<DigestItem as CompatibleDigestItem>::babe_pre_digest(
+                    babe_pre_digest,
+                ));
+
+                let new_block = futures::executor::block_on(async move {
+                    let proposer = proposer_factory.init(&parent_header).await;
+                    proposer
+                        .unwrap()
+                        .propose(
+                            inherent_data,
+                            digest,
+                            std::time::Duration::from_secs(1),
+                            RecordProof::Yes,
+                        )
+                        .await
+                })
+                .expect("Error making test block")
+                .block;
+
+                let (new_header, new_body) = new_block.deconstruct();
+                let pre_hash = new_header.hash();
+                // sign the pre-sealed hash of the block and then
+                // add it to a digest item.
+                let to_sign = pre_hash.encode();
+                let signature = alice.sign(&to_sign[..]);
+                let item = <DigestItem as CompatibleDigestItem>::babe_seal(signature.into());
+                slot_num += 1;
+
+                let mut params = BlockImportParams::new(BlockOrigin::File, new_header);
+                params.post_digests.push(item);
+                params.body = Some(new_body);
+                params.intermediates.insert(
+                    Cow::from(INTERMEDIATE_KEY),
+                    Box::new(BabeIntermediate::<Block> { epoch_descriptor }) as Box<dyn Any>,
+                );
+                params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
+
+                block_import
+                    .import_block(params, Default::default())
+                    .expect("error importing test block");
+            },
+            |service, _| {
+                let amount = 5 * CENTS;
+                let to: AccountId = AccountPublic::from(bob.public()).into_account().into();
+                let from: AccountId = AccountPublic::from(charlie.public()).into_account().into();
+                let genesis_hash = service.client().block_hash(0).unwrap().unwrap();
+                let best_block_id = BlockId::number(service.client().chain_info().best_number);
+                let (spec_version, transaction_version) = {
+                    let version = service.client().runtime_version_at(&best_block_id).unwrap();
+                    (version.spec_version, version.transaction_version)
+                };
+                let signer = charlie.clone();
+
+                let function = Call::Balances(BalancesCall::transfer(to.into(), amount));
+
+                let check_spec_version = frame_system::CheckSpecVersion::new();
+                let check_tx_version = frame_system::CheckTxVersion::new();
+                let check_genesis = frame_system::CheckGenesis::new();
+                let check_era = frame_system::CheckEra::from(Era::Immortal);
+                let check_nonce = frame_system::CheckNonce::from(index);
+                let check_weight = frame_system::CheckWeight::new();
+                let payment = pallet_transaction_payment::ChargeTransactionPayment::from(0);
+                let validate_grandpa_equivocation =
+                    pallet_grandpa::ValidateEquivocationReport::new();
+                let extra = (
+                    check_spec_version,
+                    check_tx_version,
+                    check_genesis,
+                    check_era,
+                    check_nonce,
+                    check_weight,
+                    payment,
+                    validate_grandpa_equivocation,
+                );
+                let raw_payload = SignedPayload::from_raw(
+                    function,
+                    extra,
+                    (
+                        spec_version,
+                        transaction_version,
+                        genesis_hash,
+                        genesis_hash,
+                        (),
+                        (),
+                        (),
+                        (),
+                    ),
+                );
+                let signature = raw_payload.using_encoded(|payload| signer.sign(payload));
+                let (function, extra, _) = raw_payload.deconstruct();
+                let xt =
+                    UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), extra)
+                        .encode();
+                let v: Vec<u8> = Decode::decode(&mut xt.as_slice()).unwrap();
+
+                index += 1;
+                OpaqueExtrinsic(v)
+            },
+        );
+    }
+
+    #[test]
+    #[ignore]
+    fn test_consensus() {
+        sc_service_test::consensus(
+            crate::chain_spec::tests::integration_test_config_with_two_authorities(),
+            |config| new_full(config),
+            |config| new_light(config),
+            vec!["//Alice".into(), "//Bob".into()],
+        )
+    }
+}

+ 15 - 43
runtime-modules/common/Cargo.toml

@@ -1,52 +1,24 @@
 [package]
-name = 'substrate-common-module'
-version = '1.2.0'
+name = 'pallet-common'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
+[dependencies]
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+
 [features]
 default = ['std']
 std = [
-	'sr-primitives/std',
-	'srml-support/std',
-	'system/std',
-	'timestamp/std',
+	'serde',
 	'codec/std',
-	'serde'
+	'sp-runtime/std',
+	'frame-support/std',
+	'system/std',
+	'pallet-timestamp/std',
 ]
-
-
-[dependencies.sr-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.srml-support]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-support'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.system]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-system'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dependencies.serde]
-features = ['derive']
-optional = true
-version = '1.0.101'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'

+ 2 - 2
runtime-modules/common/src/currency.rs

@@ -1,5 +1,5 @@
-use sr_primitives::traits::Convert;
-use srml_support::traits::{Currency, LockableCurrency, ReservableCurrency};
+use frame_support::traits::{Currency, LockableCurrency, ReservableCurrency};
+use sp_runtime::traits::Convert;
 
 pub trait GovernanceCurrency: system::Trait + Sized {
     type Currency: Currency<Self::AccountId>

+ 2 - 2
runtime-modules/common/src/lib.rs

@@ -24,10 +24,10 @@ pub struct BlockAndTime<BlockNumber, Moment> {
 /// Gathers current block and time information for the runtime.
 /// If this function is used inside a config() at genesis the timestamp will be 0
 /// because the timestamp is actually produced by validators.
-pub fn current_block_time<T: system::Trait + timestamp::Trait>(
+pub fn current_block_time<T: system::Trait + pallet_timestamp::Trait>(
 ) -> BlockAndTime<T::BlockNumber, T::Moment> {
     BlockAndTime {
         block: <system::Module<T>>::block_number(),
-        time: <timestamp::Module<T>>::now(),
+        time: <pallet_timestamp::Module<T>>::now(),
     }
 }

+ 37 - 120
runtime-modules/content-working-group/Cargo.toml

@@ -1,131 +1,48 @@
 [package]
-name = 'substrate-content-working-group-module'
-version = '1.1.0'
+name = 'pallet-content-working-group'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
+[dependencies]
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+membership = { package = 'pallet-membership', default-features = false, path = '../membership'}
+stake = { package = 'pallet-stake', default-features = false, path = '../stake'}
+hiring = { package = 'pallet-hiring', default-features = false, path = '../hiring'}
+minting = { package = 'pallet-token-mint', default-features = false, path = '../token-minting'}
+recurringrewards = { package = 'pallet-recurring-reward', default-features = false, path = '../recurring-reward'}
+versioned_store = { package = 'pallet-versioned-store', default-features = false, path = '../versioned-store'}
+versioned_store_permissions = { package = 'pallet-versioned-store-permissions', default-features = false, path = '../versioned-store-permissions'}
+common = { package = 'pallet-common', default-features = false, path = '../common'}
+
+[dev-dependencies]
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+
 [features]
 default = ['std']
 std = [
-	'sr-primitives/std',
-	'srml-support/std',
+	'serde',
+	'codec/std',
+	'sp-std/std',
+	'frame-support/std',
 	'system/std',
-    'serde',
-    'codec/std',
-    'primitives/std',
-    'rstd/std',
-    'membership/std',
-    'forum/std',
-    'hiring/std',
-    'stake/std',
-    'minting/std',
+	'sp-arithmetic/std',
+	'sp-runtime/std',
+	'membership/std',
+	'stake/std',
+	'hiring/std',
+	'minting/std',
+	'recurringrewards/std',
     'versioned_store/std',
     'versioned_store_permissions/std',
-    'recurringrewards/std',
-    'common/std',
+	'common/std',
 ]
-
-
-[dependencies.sr-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.srml-support]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-support'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.system]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-system'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.rstd]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-std'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.serde]
-features = ['derive']
-optional = true
-version = '1.0.101'
-
-[dependencies.primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dependencies.forum]
-default_features = false
-package = 'substrate-forum-module'
-path = '../forum'
-
-[dependencies.minting]
-default_features = false
-package = 'substrate-token-mint-module'
-path = '../token-minting'
-
-[dependencies.stake]
-default_features = false
-package = 'substrate-stake-module'
-path = '../stake'
-
-[dependencies.recurringrewards]
-default_features = false
-package = 'substrate-recurring-reward-module'
-path = '../recurring-reward'
-
-[dependencies.hiring]
-default_features = false
-package = 'substrate-hiring-module'
-path = '../hiring'
-
-[dependencies.versioned_store]
-default_features = false
-package ='substrate-versioned-store'
-path = '../versioned-store'
-
-[dependencies.versioned_store_permissions]
-default_features = false
-package = 'substrate-versioned-store-permissions-module'
-path = '../versioned-store-permissions'
-
-[dependencies.membership]
-default_features = false
-package = 'substrate-membership-module'
-path = '../membership'
-
-[dependencies.common]
-default_features = false
-package = 'substrate-common-module'
-path = '../common'
-
-[dev-dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dev-dependencies.balances]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-balances'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dev-dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'

+ 2 - 60
runtime-modules/content-working-group/src/genesis.rs

@@ -1,36 +1,13 @@
 #![cfg(test)]
 
 use crate::{Trait, *};
-pub use primitives::{map, Blake2Hasher, H256};
-use rstd::prelude::*;
+use sp_std::map;
 
-/// DIRTY IMPORT BECAUSE
-/// InputValidationLengthConstraint has not been factored out yet!!!
 use common::constraints::InputValidationLengthConstraint;
 
-/// The way a map (linked_map) is represented in the GenesisConfig produced by decl_storage
-//pub type GenesisConfigMap<K, V> = std::vec::Vec<(K, V)>;
-
 /// Builder of genesis configuration of content working group.
 pub struct GenesisConfigBuilder<T: Trait> {
     mint_capacity: minting::BalanceOf<T>,
-    /*
-    lead_by_id: GenesisConfigMap<LeadId<T>, Lead<T::AccountId, T::RewardRelationshipId, T::BlockNumber>>,
-    next_lead_id: LeadId<T>,
-    curator_opening_by_id: GenesisConfigMap<CuratorOpeningId<T>, CuratorOpening<T::OpeningId, T::BlockNumber, BalanceOf<T>, CuratorApplicationId<T>>>,
-    next_curator_opening_id: CuratorOpeningId<T>,
-    curator_application_by_id: GenesisConfigMap<CuratorApplicationId<T>, CuratorApplication<T::AccountId, CuratorOpeningId<T>, T::MemberId, T::ApplicationId>>,
-    next_curator_application_id: CuratorApplicationId<T>,
-    channel_by_id: GenesisConfigMap<ChannelId<T>, Channel<T::MemberId, T::AccountId, T::BlockNumber, PrincipalId<T>>>,
-    next_channel_id: ChannelId<T>,
-    channel_id_by_handle: GenesisConfigMap<Vec<u8>, ChannelId<T>>,
-    curator_by_id: GenesisConfigMap<CuratorId<T>, Curator<T::AccountId, T::RewardRelationshipId, T::StakeId, T::BlockNumber, LeadId<T>, CuratorApplicationId<T>, PrincipalId<T>>>,
-    next_curator_id: CuratorId<T>,
-    principal_by_id: GenesisConfigMap<PrincipalId<T>, Principal<CuratorId<T>, ChannelId<T>>>,
-    next_principal_id: PrincipalId<T>,
-
-    unstaker_by_stake_id: GenesisConfigMap<TestStakeId, WorkingGroupUnstaker<LeadId<T>, CuratorId<T>>>,
-    */
     channel_creation_enabled: bool,
     channel_handle_constraint: InputValidationLengthConstraint,
     channel_description_constraint: InputValidationLengthConstraint,
@@ -47,20 +24,7 @@ impl<T: Trait> GenesisConfigBuilder<T> {
         self.mint_capacity = capacity;
         self
     }
-    /*
-    pub fn set_channel_handle_constraint(mut self, constraint: InputValidationLengthConstraint) -> Self {
-        self.channel_description_constraint = constraint;
-        self
-    }
-    pub fn set_channel_description_constraint(mut self, constraint: InputValidationLengthConstraint) -> Self {
-        self.channel_description_constraint = constraint;
-        self
-    }
-    pub fn set_channel_creation_enabled(mut self, channel_creation_enabled: bool) -> Self {
-        self.channel_creation_enabled = channel_creation_enabled;
-        self
-    }
-    */
+
     pub fn build(self) -> GenesisConfig<T> {
         GenesisConfig {
             mint_capacity: self.mint_capacity,
@@ -68,7 +32,6 @@ impl<T: Trait> GenesisConfigBuilder<T> {
             next_curator_opening_id: CuratorOpeningId::<T>::default(),
             curator_application_by_id: map![], //GenesisConfigMap<CuratorApplicationId,CuratorApplication>,
             next_curator_application_id: CuratorApplicationId::<T>::default(),
-
             channel_by_id: map![], //GenesisConfigMap<ChannelId, Channel>,
             next_channel_id: ChannelId::<T>::default(),
             channel_id_by_handle: map![], //GenesisConfigMap<Vec<u8>, ChannelId>,
@@ -78,12 +41,10 @@ impl<T: Trait> GenesisConfigBuilder<T> {
             next_principal_id: PrincipalId::<T>::default(),
             channel_creation_enabled: self.channel_creation_enabled,
             unstaker_by_stake_id: map![], //GenesisConfigMap<LeadId, CuratorId>,
-
             channel_handle_constraint: self.channel_handle_constraint,
             channel_description_constraint: self.channel_description_constraint,
             curator_application_human_readable_text: self.curator_application_human_readable_text,
             curator_exit_rationale_text: self.curator_exit_rationale_text,
-
             channel_title_constraint: self.channel_title_constraint,
             channel_avatar_constraint: self.channel_avatar_constraint,
             channel_banner_constraint: self.channel_banner_constraint,
@@ -101,25 +62,6 @@ impl<T: Trait> Default for GenesisConfigBuilder<T> {
 
         Self {
             mint_capacity: minting::BalanceOf::<T>::from(10000),
-
-            /*
-            current_lead_id: LeadId::<T>::default(), //Option<LeadId>,
-            lead_by_id: map![], //GenesisConfigMap<LeadId, Lead>,
-            next_lead_id: 0,
-            curator_opening_by_id: map![], //GenesisConfigMap<CuratorOpeningId, Opening>,
-            next_curator_opening_id: 0,
-            curator_application_by_id: map![], //GenesisConfigMap<CuratorApplicationId,CuratorApplication>,
-            next_curator_application_id: 0,
-            channel_by_id: map![], //GenesisConfigMap<ChannelId, Channel>,
-            next_channel_id: 0,
-            channel_id_by_handle: map![], //GenesisConfigMap<Vec<u8>, ChannelId>,
-            curator_by_id: map![], //GenesisConfigMap<CuratorId, Curator>,
-            next_curator_id: 0,
-            principal_by_id: map![], //GenesisConfigMap<PrinicipalId, Prinicipal>,
-            next_principal_id: 0,
-
-            unstaker_by_stake_id: map![], //GenesisConfigMap<LeadId, CuratorId>,
-            */
             channel_creation_enabled: true,
             channel_handle_constraint: default_constraint.clone(),
             channel_description_constraint: default_constraint.clone(),

+ 103 - 88
runtime-modules/content-working-group/src/lib.rs

@@ -20,15 +20,14 @@ pub mod genesis;
 use serde::{Deserialize, Serialize};
 
 use codec::{Decode, Encode};
-use rstd::borrow::ToOwned;
-use rstd::collections::btree_map::BTreeMap;
-use rstd::collections::btree_set::BTreeSet;
-use rstd::convert::From;
-use rstd::prelude::*;
-use sr_primitives::traits::{One, Zero};
-use srml_support::traits::{Currency, ExistenceRequirement, WithdrawReasons};
-use srml_support::{decl_event, decl_module, decl_storage, dispatch, ensure};
-use system::{self, ensure_root, ensure_signed};
+use frame_support::traits::{Currency, ExistenceRequirement, WithdrawReasons};
+use frame_support::{decl_event, decl_module, decl_storage, ensure};
+use sp_arithmetic::traits::{One, Zero};
+use sp_std::borrow::ToOwned;
+use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
+use sp_std::vec;
+use sp_std::vec::Vec;
+use system::{ensure_root, ensure_signed};
 
 use common::constraints::InputValidationLengthConstraint;
 
@@ -42,8 +41,6 @@ pub trait Trait:
     + versioned_store_permissions::Trait
     + membership::Trait
 {
-    // + Sized
-
     /// The event type.
     type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
 }
@@ -93,6 +90,10 @@ pub type CuratorApplicationIdToCuratorIdMap<T> = BTreeMap<CuratorApplicationId<T
 // Workaround for BTreeSet type
 pub type CuratorApplicationIdSet<T> = BTreeSet<CuratorApplicationId<T>>;
 
+//TODO: Convert errors to the Substrate decl_error! macro.
+/// Result with string error message. This exists for backward compatibility purpose.
+pub type DispatchResult = Result<(), &'static str>;
+
 /*
  * MOVE ALL OF THESE OUT TO COMMON LATER
  */
@@ -718,10 +719,7 @@ pub struct OpeningPolicyCommitment<BlockNumber, Balance> {
     /// Staking policy for role itself
     pub role_staking_policy: Option<hiring::StakingPolicy<Balance, BlockNumber>>,
 
-    // Slashing terms during application
-    // pub application_slashing_terms: SlashingTerms,
-
-    // Slashing terms during role, NOT application itself!
+    /// Slashing terms during role, NOT application itself!
     pub role_slashing_terms: SlashingTerms,
 
     /// When filling an opening: Unstaking period for application stake of successful applicants
@@ -769,12 +767,6 @@ impl<LeadId: Default, CuratorId> Default for WorkingGroupUnstaker<LeadId, Curato
 // Move section below, this out in its own file later                       //
 // ======================================================================== //
 
-/*
-struct WrappedBeginAcceptingApplicationsError { // can this be made generic, or does that undermine the whole orhpan rule spirit?
-    pub error: hiring::BeginAcceptingApplicationsError
-}
-*/
-
 pub struct WrappedError<E> {
     // can this be made generic, or does that undermine the whole orhpan rule spirit?
     pub error: E,
@@ -783,7 +775,9 @@ pub struct WrappedError<E> {
 /// ....
 macro_rules! ensure_on_wrapped_error {
     ($call:expr) => {{
-        { $call }.map_err(|err| WrappedError { error: err })
+        { $call }
+            .map_err(|err| WrappedError { error: err })
+            .map_err(<&str>::from)
     }};
 }
 
@@ -791,7 +785,7 @@ macro_rules! ensure_on_wrapped_error {
 //derive_from_impl(hiring::BeginAcceptingApplicationsError)
 //derive_from_impl(hiring::BeginAcceptingApplicationsError)
 
-impl rstd::convert::From<WrappedError<hiring::BeginAcceptingApplicationsError>> for &str {
+impl sp_std::convert::From<WrappedError<hiring::BeginAcceptingApplicationsError>> for &str {
     fn from(wrapper: WrappedError<hiring::BeginAcceptingApplicationsError>) -> Self {
         match wrapper.error {
             hiring::BeginAcceptingApplicationsError::OpeningDoesNotExist => {
@@ -804,7 +798,7 @@ impl rstd::convert::From<WrappedError<hiring::BeginAcceptingApplicationsError>>
     }
 }
 
-impl rstd::convert::From<WrappedError<hiring::AddOpeningError>> for &str {
+impl sp_std::convert::From<WrappedError<hiring::AddOpeningError>> for &str {
     fn from(wrapper: WrappedError<hiring::AddOpeningError>) -> Self {
         match wrapper.error {
             hiring::AddOpeningError::OpeningMustActivateInTheFuture => {
@@ -833,7 +827,7 @@ impl rstd::convert::From<WrappedError<hiring::AddOpeningError>> for &str {
     }
 }
 
-impl rstd::convert::From<WrappedError<hiring::BeginReviewError>> for &str {
+impl sp_std::convert::From<WrappedError<hiring::BeginReviewError>> for &str {
     fn from(wrapper: WrappedError<hiring::BeginReviewError>) -> Self {
         match wrapper.error {
             hiring::BeginReviewError::OpeningDoesNotExist => {
@@ -846,7 +840,7 @@ impl rstd::convert::From<WrappedError<hiring::BeginReviewError>> for &str {
     }
 }
 
-impl<T: hiring::Trait> rstd::convert::From<WrappedError<hiring::FillOpeningError<T>>> for &str {
+impl<T: hiring::Trait> sp_std::convert::From<WrappedError<hiring::FillOpeningError<T>>> for &str {
     fn from(wrapper: WrappedError<hiring::FillOpeningError<T>>) -> Self {
         match wrapper.error {
             hiring::FillOpeningError::<T>::OpeningDoesNotExist => MSG_FULL_CURATOR_OPENING_OPENING_DOES_NOT_EXIST,
@@ -884,7 +878,7 @@ impl<T: hiring::Trait> rstd::convert::From<WrappedError<hiring::FillOpeningError
     }
 }
 
-impl rstd::convert::From<WrappedError<hiring::DeactivateApplicationError>> for &str {
+impl sp_std::convert::From<WrappedError<hiring::DeactivateApplicationError>> for &str {
     fn from(wrapper: WrappedError<hiring::DeactivateApplicationError>) -> Self {
         match wrapper.error {
             hiring::DeactivateApplicationError::ApplicationDoesNotExist => {
@@ -906,7 +900,9 @@ impl rstd::convert::From<WrappedError<hiring::DeactivateApplicationError>> for &
     }
 }
 
-impl rstd::convert::From<WrappedError<membership::ControllerAccountForMemberCheckFailed>> for &str {
+impl sp_std::convert::From<WrappedError<membership::ControllerAccountForMemberCheckFailed>>
+    for &str
+{
     fn from(wrapper: WrappedError<membership::ControllerAccountForMemberCheckFailed>) -> Self {
         match wrapper.error {
             membership::ControllerAccountForMemberCheckFailed::NotMember => {
@@ -919,7 +915,7 @@ impl rstd::convert::From<WrappedError<membership::ControllerAccountForMemberChec
     }
 }
 
-impl rstd::convert::From<WrappedError<hiring::AddApplicationError>> for &str {
+impl sp_std::convert::From<WrappedError<hiring::AddApplicationError>> for &str {
     fn from(wrapper: WrappedError<hiring::AddApplicationError>) -> Self {
         match wrapper.error {
             hiring::AddApplicationError::OpeningDoesNotExist => {
@@ -944,7 +940,7 @@ impl rstd::convert::From<WrappedError<hiring::AddApplicationError>> for &str {
     }
 }
 
-impl rstd::convert::From<WrappedError<membership::MemberControllerAccountDidNotSign>> for &str {
+impl sp_std::convert::From<WrappedError<membership::MemberControllerAccountDidNotSign>> for &str {
     fn from(wrapper: WrappedError<membership::MemberControllerAccountDidNotSign>) -> Self {
         match wrapper.error {
             membership::MemberControllerAccountDidNotSign::UnsignedOrigin => {
@@ -974,83 +970,83 @@ decl_storage! {
     trait Store for Module<T: Trait> as ContentWorkingGroup {
 
         /// The mint currently funding the rewards for this module.
-        pub Mint get(mint) : <T as minting::Trait>::MintId;
+        pub Mint get(fn mint) : <T as minting::Trait>::MintId;
 
         /// The current lead.
-        pub CurrentLeadId get(current_lead_id) : Option<LeadId<T>>;
+        pub CurrentLeadId get(fn current_lead_id) : Option<LeadId<T>>;
 
         /// Maps identifier to corresponding lead.
-        pub LeadById get(lead_by_id): linked_map LeadId<T> => Lead<T::AccountId, T::RewardRelationshipId, T::BlockNumber, T::MemberId>;
+        pub LeadById get(fn lead_by_id): map hasher(blake2_128_concat)
+            LeadId<T> => Lead<T::AccountId, T::RewardRelationshipId, T::BlockNumber, T::MemberId>;
 
         /// Next identifier for new current lead.
-        pub NextLeadId get(next_lead_id): LeadId<T>;
+        pub NextLeadId get(fn next_lead_id): LeadId<T>;
 
         /// Maps identifeir to curator opening.
-        pub CuratorOpeningById get(curator_opening_by_id) config(): linked_map CuratorOpeningId<T> => CuratorOpening<T::OpeningId, T::BlockNumber, BalanceOf<T>, CuratorApplicationId<T>>;
+        pub CuratorOpeningById get(fn curator_opening_by_id) config(): map hasher(blake2_128_concat)
+            CuratorOpeningId<T> => CuratorOpening<T::OpeningId, T::BlockNumber, BalanceOf<T>, CuratorApplicationId<T>>;
 
         /// Next identifier valuefor new curator opening.
-        pub NextCuratorOpeningId get(next_curator_opening_id) config(): CuratorOpeningId<T>;
+        pub NextCuratorOpeningId get(fn next_curator_opening_id) config(): CuratorOpeningId<T>;
 
         /// Maps identifier to curator application on opening.
-        pub CuratorApplicationById get(curator_application_by_id) config(): linked_map CuratorApplicationId<T> => CuratorApplication<T::AccountId, CuratorOpeningId<T>, T::MemberId, T::ApplicationId>;
+        pub CuratorApplicationById get(fn curator_application_by_id) config(): map hasher(blake2_128_concat)
+            CuratorApplicationId<T> => CuratorApplication<T::AccountId, CuratorOpeningId<T>, T::MemberId, T::ApplicationId>;
 
         /// Next identifier value for new curator application.
-        pub NextCuratorApplicationId get(next_curator_application_id) config(): CuratorApplicationId<T>;
+        pub NextCuratorApplicationId get(fn next_curator_application_id) config(): CuratorApplicationId<T>;
 
         /// Maps identifier to corresponding channel.
-        pub ChannelById get(channel_by_id) config(): linked_map ChannelId<T> => Channel<T::MemberId, T::AccountId, T::BlockNumber, PrincipalId<T>>;
+        pub ChannelById get(fn channel_by_id) config(): map hasher(blake2_128_concat)
+            ChannelId<T> => Channel<T::MemberId, T::AccountId, T::BlockNumber, PrincipalId<T>>;
 
         /// Identifier to be used by the next channel introduced.
-        pub NextChannelId get(next_channel_id) config(): ChannelId<T>;
+        pub NextChannelId get(fn next_channel_id) config(): ChannelId<T>;
 
         /// Maps (unique) channel handle to the corresponding identifier for the channel.
         /// Mapping is required to allow efficient (O(log N)) on-chain verification that a proposed handle is indeed unique
         /// at the time it is being proposed.
-        pub ChannelIdByHandle get(channel_id_by_handle) config(): linked_map Vec<u8> => ChannelId<T>;
+        pub ChannelIdByHandle get(fn channel_id_by_handle) config(): map hasher(blake2_128_concat)
+            Vec<u8> => ChannelId<T>;
 
         /// Maps identifier to corresponding curator.
-        pub CuratorById get(curator_by_id) config(): linked_map CuratorId<T> => Curator<T::AccountId, T::RewardRelationshipId, T::StakeId, T::BlockNumber, LeadId<T>, CuratorApplicationId<T>, PrincipalId<T>>;
+        pub CuratorById get(fn curator_by_id) config(): map hasher(blake2_128_concat)
+            CuratorId<T> => Curator<T::AccountId, T::RewardRelationshipId, T::StakeId, T::BlockNumber, LeadId<T>, CuratorApplicationId<T>, PrincipalId<T>>;
 
         /// Next identifier for new curator.
-        pub NextCuratorId get(next_curator_id) config(): CuratorId<T>;
+        pub NextCuratorId get(fn next_curator_id) config(): CuratorId<T>;
 
         /// Maps identifier to principal.
-        pub PrincipalById get(principal_by_id) config(): linked_map PrincipalId<T> => Principal<CuratorId<T>, ChannelId<T>>;
+        pub PrincipalById get(fn principal_by_id) config(): map hasher(blake2_128_concat)
+            PrincipalId<T> => Principal<CuratorId<T>, ChannelId<T>>;
 
         /// Next identifier for
-        pub NextPrincipalId get(next_principal_id) config(): PrincipalId<T>;
+        pub NextPrincipalId get(fn next_principal_id) config(): PrincipalId<T>;
 
         /// Whether it is currently possible to create a channel via `create_channel` extrinsic.
-        pub ChannelCreationEnabled get(channel_creation_enabled) config(): bool;
+        pub ChannelCreationEnabled get(fn channel_creation_enabled) config(): bool;
 
         /// Recover curator by the role stake which is currently unstaking.
-        pub UnstakerByStakeId get(unstaker_by_stake_id) config(): linked_map StakeId<T> => WorkingGroupUnstaker<LeadId<T>, CuratorId<T>>;
-
-        // Limits
-
-        /// Limits the total number of curators which can be active.
-        //pub MaxSimultanouslyActiveCurators get(max_simultanously_active_curators) config(): Option<u16>;
+        pub UnstakerByStakeId get(fn unstaker_by_stake_id) config(): map hasher(blake2_128_concat)
+            StakeId<T> => WorkingGroupUnstaker<LeadId<T>, CuratorId<T>>;
 
-        // Limits the total number of openings which are not yet deactivated.
-        // pub MaxSimultaneouslyActiveOpenings get(max_simultaneously_active_openings) config(): Option<u16>,
 
         // Vector length input guards
-
-        pub ChannelHandleConstraint get(channel_handle_constraint) config(): InputValidationLengthConstraint;
-        pub ChannelTitleConstraint get(channel_title_constraint) config(): InputValidationLengthConstraint;
-        pub ChannelDescriptionConstraint get(channel_description_constraint) config(): InputValidationLengthConstraint;
-        pub ChannelAvatarConstraint get(channel_avatar_constraint) config(): InputValidationLengthConstraint;
-        pub ChannelBannerConstraint get(channel_banner_constraint) config(): InputValidationLengthConstraint;
-        pub OpeningHumanReadableText get(opening_human_readable_text) config(): InputValidationLengthConstraint;
-        pub CuratorApplicationHumanReadableText get(curator_application_human_readable_text) config(): InputValidationLengthConstraint;
-        pub CuratorExitRationaleText get(curator_exit_rationale_text) config(): InputValidationLengthConstraint;
+        pub ChannelHandleConstraint get(fn channel_handle_constraint) config(): InputValidationLengthConstraint;
+        pub ChannelTitleConstraint get(fn channel_title_constraint) config(): InputValidationLengthConstraint;
+        pub ChannelDescriptionConstraint get(fn channel_description_constraint) config(): InputValidationLengthConstraint;
+        pub ChannelAvatarConstraint get(fn channel_avatar_constraint) config(): InputValidationLengthConstraint;
+        pub ChannelBannerConstraint get(fn channel_banner_constraint) config(): InputValidationLengthConstraint;
+        pub OpeningHumanReadableText get(fn opening_human_readable_text) config(): InputValidationLengthConstraint;
+        pub CuratorApplicationHumanReadableText get(fn curator_application_human_readable_text) config(): InputValidationLengthConstraint;
+        pub CuratorExitRationaleText get(fn curator_exit_rationale_text) config(): InputValidationLengthConstraint;
     }
     add_extra_genesis {
         config(mint_capacity): minting::BalanceOf<T>;
-        // config(mint_adjustment): minting::Adjustment<BalanceOf<T>, T::BlockNumber> (add serialize/deserialize derivation for type)
         build(|config: &GenesisConfig<T>| {
             // create mint
-            let mint_id = <minting::Module<T>>::add_mint(config.mint_capacity, None).expect("Failed to create a mint for the content working group");
+            let mint_id = <minting::Module<T>>::add_mint(config.mint_capacity, None)
+                .expect("Failed to create a mint for the content working group");
             Mint::<T>::put(mint_id);
         });
     }
@@ -1075,7 +1071,7 @@ decl_event! {
         CuratorOpeningAdded(CuratorOpeningId),
         AcceptedCuratorApplications(CuratorOpeningId),
         BeganCuratorApplicationReview(CuratorOpeningId),
-        CuratorOpeningFilled(CuratorOpeningId, CuratorApplicationIdToCuratorIdMap), //BTreeSet<CuratorApplicationId>),
+        CuratorOpeningFilled(CuratorOpeningId, CuratorApplicationIdToCuratorIdMap),
         TerminatedCurator(CuratorId),
         AppliedOnCuratorOpening(CuratorOpeningId, CuratorApplicationId),
         CuratorExited(CuratorId),
@@ -1101,6 +1097,7 @@ decl_module! {
          */
 
         /// Create a new channel.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_channel(
             origin,
             owner: T::MemberId,
@@ -1187,6 +1184,7 @@ decl_module! {
         /// Notice that working group participants cannot do this.
         /// Notice that censored or unlisted channel may still be transferred.
         /// Notice that transfers are unilateral, so new owner cannot block. This may be problematic: https://github.com/Joystream/substrate-runtime-joystream/issues/95
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn transfer_channel_ownership(origin, channel_id: ChannelId<T>, new_owner: T::MemberId, new_role_account: T::AccountId) {
 
             // Ensure channel owner has signed
@@ -1211,6 +1209,7 @@ decl_module! {
         }
 
         /// Channel owner updates some channel properties
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn update_channel_as_owner(
             origin,
             channel_id: ChannelId<T>,
@@ -1268,6 +1267,7 @@ decl_module! {
         }
 
         /// Update channel as a curation actor
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn update_channel_as_curation_actor(
             origin,
             curation_actor: CurationActor<CuratorId<T>>,
@@ -1297,6 +1297,7 @@ decl_module! {
         }
 
         /// Add an opening for a curator role.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn add_curator_opening(origin, activate_at: hiring::ActivateOpeningAt<T::BlockNumber>, commitment: OpeningPolicyCommitment<T::BlockNumber, BalanceOf<T>>, human_readable_text: Vec<u8>)  {
 
             // Ensure lead is set and is origin signer
@@ -1344,6 +1345,7 @@ decl_module! {
         }
 
         /// Begin accepting curator applications to an opening that is active.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn accept_curator_applications(origin, curator_opening_id: CuratorOpeningId<T>)  {
 
             // Ensure lead is set and is origin signer
@@ -1370,6 +1372,7 @@ decl_module! {
         }
 
         /// Begin reviewing, and therefore not accepting new applications.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn begin_curator_applicant_review(origin, curator_opening_id: CuratorOpeningId<T>) {
 
             // Ensure lead is set and is origin signer
@@ -1396,6 +1399,7 @@ decl_module! {
         }
 
         /// Fill opening for curator
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn fill_curator_opening(
             origin,
             curator_opening_id: CuratorOpeningId<T>,
@@ -1414,7 +1418,7 @@ decl_module! {
                 let mint_id = Self::mint();
 
                 // Technically this is a bug-check and should not be here.
-                ensure!(<minting::Mints<T>>::exists(mint_id), MSG_FILL_CURATOR_OPENING_MINT_DOES_NOT_EXIST);
+                ensure!(<minting::Mints<T>>::contains_key(mint_id), MSG_FILL_CURATOR_OPENING_MINT_DOES_NOT_EXIST);
 
                 // Make sure valid parameters are selected for next payment at block number
                 ensure!(policy.next_payment_at_block > <system::Module<T>>::block_number(), MSG_FILL_CURATOR_OPENING_INVALID_NEXT_PAYMENT_BLOCK);
@@ -1555,6 +1559,7 @@ decl_module! {
 
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn withdraw_curator_application(
             origin,
             curator_application_id: CuratorApplicationId<T>
@@ -1591,6 +1596,7 @@ decl_module! {
         }
 
         /// Lead terminate curator application
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn terminate_curator_application(
             origin,
             curator_application_id: CuratorApplicationId<T>
@@ -1621,6 +1627,7 @@ decl_module! {
         }
 
         /// Apply on a curator opening.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn apply_on_curator_opening(
             origin,
             member_id: T::MemberId,
@@ -1709,6 +1716,7 @@ decl_module! {
         }
 
         /// An active curator can update the associated role account.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn update_curator_role_account(
             origin,
             member_id: T::MemberId,
@@ -1736,6 +1744,7 @@ decl_module! {
 
         /// An active curator can update the reward account associated
         /// with a set reward relationship.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn update_curator_reward_account(
             origin,
             curator_id: CuratorId<T>,
@@ -1767,6 +1776,7 @@ decl_module! {
         }
 
         /// An active curator leaves role
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn leave_curator_role(
             origin,
             curator_id: CuratorId<T>,
@@ -1788,6 +1798,7 @@ decl_module! {
         }
 
         /// Lead can terminate and active curator
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn terminate_curator_role(
             origin,
             curator_id: CuratorId<T>,
@@ -1819,6 +1830,7 @@ decl_module! {
         /// If a value is provided for new_lead it will then set that new lead.
         /// It is responsibility of the caller to ensure the new lead can be set
         /// to avoid the lead role being vacant at the end of the call.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn replace_lead(origin, new_lead: Option<(T::MemberId, T::AccountId)>) {
             // Ensure root is origin
             ensure_root(origin)?;
@@ -1835,6 +1847,7 @@ decl_module! {
         }
 
         /// Add an opening for a curator role.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_channel_creation_enabled(origin, enabled: bool)  {
 
             // Ensure lead is set and is origin signer
@@ -1856,6 +1869,7 @@ decl_module! {
         /// both increase and decrease capacity. Although when considering that it may be executed
         /// by a proposal, given the temporal delay in approving a proposal, it might be more suitable
         /// than set_mint_capacity?
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn increase_mint_capacity(
             origin,
             additional_capacity: minting::BalanceOf<T>
@@ -1865,7 +1879,7 @@ decl_module! {
             let mint_id = Self::mint();
             let mint = <minting::Module<T>>::mints(mint_id); // must exist
             let new_capacity = mint.capacity() + additional_capacity;
-            <minting::Module<T>>::set_mint_capacity(mint_id, new_capacity)?;
+            <minting::Module<T>>::set_mint_capacity(mint_id, new_capacity).map_err(<&str>::from)?;
 
             Self::deposit_event(RawEvent::MintCapacityIncreased(
                 mint_id, additional_capacity, new_capacity
@@ -1873,6 +1887,7 @@ decl_module! {
         }
 
         /// Sets the capacity of the current active mint
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_mint_capacity(
             origin,
             new_capacity: minting::BalanceOf<T>
@@ -1890,7 +1905,7 @@ decl_module! {
 
             if new_capacity != current_capacity {
                 // Cannot fail if mint exists
-                <minting::Module<T>>::set_mint_capacity(mint_id, new_capacity)?;
+                <minting::Module<T>>::set_mint_capacity(mint_id, new_capacity).map_err(<&str>::from)?;
 
                 if new_capacity > current_capacity {
                     Self::deposit_event(RawEvent::MintCapacityIncreased(
@@ -1902,7 +1917,6 @@ decl_module! {
                     ));
                 }
             }
-
         }
     }
 }
@@ -1910,7 +1924,7 @@ decl_module! {
 impl<T: Trait> versioned_store_permissions::CredentialChecker<T> for Module<T> {
     fn account_has_credential(account: &T::AccountId, id: PrincipalId<T>) -> bool {
         // Check that principal exists
-        if !PrincipalById::<T>::exists(&id) {
+        if !PrincipalById::<T>::contains_key(&id) {
             return false;
         }
 
@@ -1950,7 +1964,7 @@ impl<T: Trait> versioned_store_permissions::CredentialChecker<T> for Module<T> {
 
 impl<T: Trait> Module<T> {
     /// Introduce a lead when one is not currently set.
-    fn set_lead(member: T::MemberId, role_account: T::AccountId) -> dispatch::Result {
+    fn set_lead(member: T::MemberId, role_account: T::AccountId) -> DispatchResult {
         // Ensure there is no current lead
         ensure!(
             <CurrentLeadId<T>>::get().is_none(),
@@ -1988,7 +2002,7 @@ impl<T: Trait> Module<T> {
     }
 
     /// Evict the currently set lead
-    fn unset_lead() -> dispatch::Result {
+    fn unset_lead() -> DispatchResult {
         // Ensure there is a lead set
         let (lead_id, lead) = Self::ensure_lead_is_set()?;
 
@@ -2039,7 +2053,7 @@ impl<T: Trait> Module<T> {
     }
 
     // TODO: convert InputConstraint ensurer routines into macroes
-    fn ensure_channel_handle_is_valid(handle: &[u8]) -> dispatch::Result {
+    fn ensure_channel_handle_is_valid(handle: &[u8]) -> DispatchResult {
         ChannelHandleConstraint::get().ensure_valid(
             handle.len(),
             MSG_CHANNEL_HANDLE_TOO_SHORT,
@@ -2048,14 +2062,14 @@ impl<T: Trait> Module<T> {
 
         // Has to not already be occupied
         ensure!(
-            !ChannelIdByHandle::<T>::exists(handle),
+            !ChannelIdByHandle::<T>::contains_key(handle),
             MSG_CHANNEL_HANDLE_ALREADY_TAKEN
         );
 
         Ok(())
     }
 
-    fn ensure_channel_title_is_valid(text_opt: &OptionalText) -> dispatch::Result {
+    fn ensure_channel_title_is_valid(text_opt: &OptionalText) -> DispatchResult {
         if let Some(text) = text_opt {
             ChannelTitleConstraint::get().ensure_valid(
                 text.len(),
@@ -2067,7 +2081,7 @@ impl<T: Trait> Module<T> {
         }
     }
 
-    fn ensure_channel_description_is_valid(text_opt: &OptionalText) -> dispatch::Result {
+    fn ensure_channel_description_is_valid(text_opt: &OptionalText) -> DispatchResult {
         if let Some(text) = text_opt {
             ChannelDescriptionConstraint::get().ensure_valid(
                 text.len(),
@@ -2079,7 +2093,7 @@ impl<T: Trait> Module<T> {
         }
     }
 
-    fn ensure_channel_avatar_is_valid(text_opt: &OptionalText) -> dispatch::Result {
+    fn ensure_channel_avatar_is_valid(text_opt: &OptionalText) -> DispatchResult {
         if let Some(text) = text_opt {
             ChannelAvatarConstraint::get().ensure_valid(
                 text.len(),
@@ -2091,7 +2105,7 @@ impl<T: Trait> Module<T> {
         }
     }
 
-    fn ensure_channel_banner_is_valid(text_opt: &OptionalText) -> dispatch::Result {
+    fn ensure_channel_banner_is_valid(text_opt: &OptionalText) -> DispatchResult {
         if let Some(text) = text_opt {
             ChannelBannerConstraint::get().ensure_valid(
                 text.len(),
@@ -2103,7 +2117,7 @@ impl<T: Trait> Module<T> {
         }
     }
 
-    fn ensure_curator_application_text_is_valid(text: &[u8]) -> dispatch::Result {
+    fn ensure_curator_application_text_is_valid(text: &[u8]) -> DispatchResult {
         CuratorApplicationHumanReadableText::get().ensure_valid(
             text.len(),
             MSG_CURATOR_APPLICATION_TEXT_TOO_SHORT,
@@ -2111,7 +2125,7 @@ impl<T: Trait> Module<T> {
         )
     }
 
-    fn ensure_curator_exit_rationale_text_is_valid(text: &[u8]) -> dispatch::Result {
+    fn ensure_curator_exit_rationale_text_is_valid(text: &[u8]) -> DispatchResult {
         CuratorExitRationaleText::get().ensure_valid(
             text.len(),
             MSG_CURATOR_EXIT_RATIONALE_TEXT_TOO_SHORT,
@@ -2119,7 +2133,7 @@ impl<T: Trait> Module<T> {
         )
     }
 
-    fn ensure_opening_human_readable_text_is_valid(text: &[u8]) -> dispatch::Result {
+    fn ensure_opening_human_readable_text_is_valid(text: &[u8]) -> DispatchResult {
         OpeningHumanReadableText::get().ensure_valid(
             text.len(),
             MSG_CHANNEL_DESCRIPTION_TOO_SHORT,
@@ -2131,7 +2145,7 @@ impl<T: Trait> Module<T> {
         channel_id: &ChannelId<T>,
     ) -> Result<Channel<T::MemberId, T::AccountId, T::BlockNumber, PrincipalId<T>>, &'static str>
     {
-        if ChannelById::<T>::exists(channel_id) {
+        if ChannelById::<T>::contains_key(channel_id) {
             let channel = ChannelById::<T>::get(channel_id);
 
             Ok(channel)
@@ -2198,7 +2212,7 @@ impl<T: Trait> Module<T> {
         &'static str,
     > {
         ensure!(
-            CuratorOpeningById::<T>::exists(curator_opening_id),
+            CuratorOpeningById::<T>::contains_key(curator_opening_id),
             MSG_CURATOR_OPENING_DOES_NOT_EXIST
         );
 
@@ -2224,7 +2238,7 @@ impl<T: Trait> Module<T> {
         &'static str,
     > {
         ensure!(
-            CuratorById::<T>::exists(curator_id),
+            CuratorById::<T>::contains_key(curator_id),
             MSG_CURATOR_DOES_NOT_EXIST
         );
 
@@ -2237,7 +2251,7 @@ impl<T: Trait> Module<T> {
         stake_id: &StakeId<T>,
     ) -> Result<WorkingGroupUnstaker<LeadId<T>, CuratorId<T>>, &'static str> {
         ensure!(
-            UnstakerByStakeId::<T>::exists(stake_id),
+            UnstakerByStakeId::<T>::contains_key(stake_id),
             MSG_UNSTAKER_DOES_NOT_EXIST
         );
 
@@ -2353,7 +2367,7 @@ impl<T: Trait> Module<T> {
         &'static str,
     > {
         ensure!(
-            CuratorApplicationById::<T>::exists(curator_application_id),
+            CuratorApplicationById::<T>::contains_key(curator_application_id),
             MSG_CURATOR_APPLICATION_DOES_NOT_EXIST
         );
 
@@ -2424,6 +2438,7 @@ impl<T: Trait> Module<T> {
                     WithdrawReasons::all(),
                     new_balance,
                 )
+                .map_err(<&str>::from)
             }
         } else {
             Ok(())
@@ -2613,7 +2628,7 @@ impl<T: Trait> Module<T> {
     /// to this module.
     pub fn unstaked(stake_id: StakeId<T>) {
         // Ignore if unstaked doesn't exist
-        if !<UnstakerByStakeId<T>>::exists(stake_id) {
+        if !<UnstakerByStakeId<T>>::contains_key(stake_id) {
             return;
         }
 

+ 37 - 32
runtime-modules/content-working-group/src/mock.rs

@@ -1,18 +1,16 @@
 #![cfg(test)]
 
 pub use crate::*;
-pub use srml_support::traits::Currency;
-pub use system;
 
-pub use primitives::{map, Blake2Hasher, H256};
-pub use sr_primitives::{
-    testing::{Digest, DigestItem, Header, UintAuthorityId},
-    traits::{BlakeTwo256, Convert, IdentityLookup, OnFinalize},
-    weights::Weight,
-    BuildStorage, Perbill,
+use frame_support::traits::{OnFinalize, OnInitialize};
+use frame_support::{impl_outer_event, impl_outer_origin, parameter_types};
+use sp_core::H256;
+use sp_runtime::{
+    testing::Header,
+    traits::{BlakeTwo256, IdentityLookup},
+    Perbill,
 };
-
-use srml_support::{impl_outer_event, impl_outer_origin, parameter_types};
+pub use system;
 
 pub use common::currency::GovernanceCurrency;
 pub use hiring;
@@ -32,10 +30,6 @@ parameter_types! {
     pub const AvailableBlockRatio: Perbill = Perbill::one();
     pub const MinimumPeriod: u64 = 5;
     pub const ExistentialDeposit: u32 = 0;
-    pub const TransferFee: u32 = 0;
-    pub const CreationFee: u32 = 0;
-    pub const TransactionBaseFee: u32 = 1;
-    pub const TransactionByteFee: u32 = 0;
     pub const StakePoolId: [u8; 8] = *b"joystake";
 }
 
@@ -56,6 +50,7 @@ impl_outer_event! {
         versioned_store<T>,
         membership<T>,
         balances<T>,
+        system<T>,
         lib<T>,
     }
 }
@@ -80,47 +75,45 @@ pub fn get_last_event_or_panic() -> RawLibTestEvent {
     }
 }
 
-type TestAccountId = u64;
-type TestBlockNumber = u64;
 impl system::Trait for Test {
+    type BaseCallFilter = ();
     type Origin = Origin;
-    type Index = u64;
-    type BlockNumber = TestBlockNumber;
     type Call = ();
+    type Index = u64;
+    type BlockNumber = u64;
     type Hash = H256;
     type Hashing = BlakeTwo256;
-    type AccountId = TestAccountId;
+    type AccountId = u64;
     type Lookup = IdentityLookup<Self::AccountId>;
     type Header = Header;
     type Event = TestEvent;
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
-impl timestamp::Trait for Test {
+impl pallet_timestamp::Trait for Test {
     type Moment = u64;
     type OnTimestampSet = ();
     type MinimumPeriod = MinimumPeriod;
 }
 
 impl balances::Trait for Test {
-    /// The type for recording an account's balance.
     type Balance = u64;
-    /// What to do if an account's free balance gets zeroed.
-    type OnFreeBalanceZero = ();
-    /// What to do if a new account is created.
-    type OnNewAccount = ();
-    /// The ubiquitous event type.
-    type Event = TestEvent;
-
     type DustRemoval = ();
-    type TransferPayment = ();
+    type Event = TestEvent;
     type ExistentialDeposit = ExistentialDeposit;
-    type TransferFee = TransferFee;
-    type CreationFee = CreationFee;
+    type AccountStore = System;
 }
 
 impl GovernanceCurrency for Test {
@@ -206,7 +199,7 @@ impl<T: Trait> TestExternalitiesBuilder<T> {
         self
     }
 
-    pub fn build(self) -> runtime_io::TestExternalities {
+    pub fn build(self) -> sp_io::TestExternalities {
         // Add system
         let mut t = self
             .system_config
@@ -241,3 +234,15 @@ pub type System = system::Module<Test>;
 pub type Balances = balances::Module<Test>;
 pub type ContentWorkingGroup = Module<Test>;
 pub type Minting = minting::Module<Test>;
+
+// Recommendation from Parity on testing on_finalize
+// https://substrate.dev/docs/en/next/development/module/tests
+pub fn run_to_block(n: u64) {
+    while System::block_number() < n {
+        <System as OnFinalize<u64>>::on_finalize(System::block_number());
+        <ContentWorkingGroup as OnFinalize<u64>>::on_finalize(System::block_number());
+        System::set_block_number(System::block_number() + 1);
+        <System as OnInitialize<u64>>::on_initialize(System::block_number());
+        <ContentWorkingGroup as OnInitialize<u64>>::on_initialize(System::block_number());
+    }
+}

+ 0 - 6
runtime-modules/content-working-group/src/mod.rs

@@ -1,6 +0,0 @@
-pub mod genesis;
-pub mod lib;
-//pub mod types;
-
-mod mock;
-mod tests;

+ 79 - 62
runtime-modules/content-working-group/src/tests.rs

@@ -1,20 +1,28 @@
 #![cfg(test)]
 
 use super::genesis;
-use super::mock::{self, *};
-use hiring;
-use rstd::collections::btree_map::BTreeMap;
-use rstd::collections::btree_set::BTreeSet;
-use sr_primitives::traits::One;
-use srml_support::{assert_err, assert_ok, StorageLinkedMap, StorageValue};
+use super::mock::*;
+
+use frame_support::{assert_err, assert_ok, traits::Currency, StorageValue};
+use sp_arithmetic::traits::One;
+use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
+use system::RawOrigin;
 
 use common::constraints::InputValidationLengthConstraint;
+use hiring;
 
 #[test]
 fn create_channel_success() {
     TestExternalitiesBuilder::<Test>::default()
         .build()
         .execute_with(|| {
+            /*
+               Events are not emitted on block 0.
+               So any dispatchable calls made during genesis block formation will have no events emitted.
+               https://substrate.dev/recipes/2-appetizers/4-events.html
+            */
+            run_to_block(1);
+
             // Add channel creator as member
             let channel_creator_member_root_and_controller_account = 12312;
 
@@ -171,6 +179,13 @@ fn transfer_channel_ownership_success() {
     TestExternalitiesBuilder::<Test>::default()
         .build()
         .execute_with(|| {
+            /*
+               Events are not emitted on block 0.
+               So any dispatchable calls made during genesis block formation will have no events emitted.
+               https://substrate.dev/recipes/2-appetizers/4-events.html
+            */
+            run_to_block(1);
+
             // Add channel creator as member
             let channel_creator_member_root_and_controller_account_1 = 1111;
             let channel_creator_member_root_and_controller_account_2 = 2222;
@@ -242,6 +257,7 @@ impl UpdateChannelAsCurationActorFixture {
             self.new_verified,
             self.new_curation_status,
         )
+        .map_err(<&str>::from)
     }
 
     pub fn call_and_assert_success(&self, channel_id: ChannelId<Test>) {
@@ -284,7 +300,7 @@ impl UpdateChannelAsCurationActorFixture {
         assert_eq!(event_channel_id, channel_id);
 
         // Channel has been updated correctly
-        assert!(ChannelById::<Test>::exists(channel_id));
+        assert!(ChannelById::<Test>::contains_key(channel_id));
 
         let updated_channel = ChannelById::<Test>::get(channel_id);
 
@@ -394,7 +410,7 @@ fn add_curator_opening_success() {
 
             // Assert that given opening id has been added,
             // and has the right properties.
-            assert!(crate::CuratorOpeningById::<Test>::exists(
+            assert!(crate::CuratorOpeningById::<Test>::contains_key(
                 expected_curator_opening_id
             ));
 
@@ -748,7 +764,7 @@ fn apply_on_curator_opening_success() {
                 )
             );
 
-            assert!(CuratorApplicationById::<Test>::exists(
+            assert!(CuratorApplicationById::<Test>::contains_key(
                 new_curator_application_id
             ));
 
@@ -874,6 +890,7 @@ impl UpdateCuratorRoleAccountFixture {
             self.curator_id,
             self.new_role_account,
         )
+        .map_err(<&str>::from)
     }
 
     pub fn call_and_assert_success(&self) {
@@ -950,6 +967,7 @@ impl UpdateCuratorRewardAccountFixture {
             self.curator_id,
             self.new_reward_account,
         )
+        .map_err(<&str>::from)
     }
 
     #[allow(dead_code)] // delete if the method is unnecessary
@@ -1016,6 +1034,7 @@ impl LeaveCuratorRoleFixture {
             self.curator_id,
             self.rationale_text.clone(),
         )
+        .map_err(<&str>::from)
     }
 
     pub fn call_and_assert_success(&self) {
@@ -1046,7 +1065,9 @@ impl LeaveCuratorRoleFixture {
         // Tracking unstaking
         let curator_role_stake_id = original_curator.role_stake_profile.unwrap().stake_id;
 
-        assert!(UnstakerByStakeId::<Test>::exists(curator_role_stake_id));
+        assert!(UnstakerByStakeId::<Test>::contains_key(
+            curator_role_stake_id
+        ));
 
         let unstaker = UnstakerByStakeId::<Test>::get(curator_role_stake_id);
 
@@ -1089,6 +1110,7 @@ impl TerminateCuratorRoleFixture {
             self.curator_id,
             self.rationale_text.clone(),
         )
+        .map_err(<&str>::from)
     }
 
     pub fn call_and_assert_success(&self) {
@@ -1119,7 +1141,9 @@ impl TerminateCuratorRoleFixture {
         // Tracking unstaking
         let curator_role_stake_id = original_curator.role_stake_profile.unwrap().stake_id;
 
-        assert!(UnstakerByStakeId::<Test>::exists(curator_role_stake_id));
+        assert!(UnstakerByStakeId::<Test>::contains_key(
+            curator_role_stake_id
+        ));
 
         let unstaker = UnstakerByStakeId::<Test>::get(curator_role_stake_id);
 
@@ -1161,6 +1185,7 @@ impl SetLeadFixture {
             self.origin.clone(),
             Some((self.member_id, self.new_role_account)),
         )
+        .map_err(<&str>::from)
     }
 
     pub fn call_and_assert_success(&self) {
@@ -1204,11 +1229,18 @@ fn set_lead_success() {
     TestExternalitiesBuilder::<Test>::default()
         .build()
         .execute_with(|| {
+            /*
+               Events are not emitted on block 0.
+               So any dispatchable calls made during genesis block formation will have no events emitted.
+               https://substrate.dev/recipes/2-appetizers/4-events.html
+            */
+            run_to_block(1);
+
             let member_id =
                 add_member(LEAD_ROOT_AND_CONTROLLER_ACCOUNT, to_vec(LEAD_MEMBER_HANDLE));
 
             SetLeadFixture {
-                origin: Origin::system(system::RawOrigin::Root),
+                origin: RawOrigin::Root.into(),
                 member_id,
                 new_role_account: 44444,
             }
@@ -1222,7 +1254,7 @@ struct UnsetLeadFixture {
 
 impl UnsetLeadFixture {
     fn call(&self) -> Result<(), &'static str> {
-        ContentWorkingGroup::replace_lead(self.origin.clone(), None)
+        ContentWorkingGroup::replace_lead(self.origin.clone(), None).map_err(<&str>::from)
     }
 
     pub fn call_and_assert_success(&self) {
@@ -1261,7 +1293,7 @@ fn unset_lead_success() {
             let _ = add_member_and_set_as_lead();
 
             UnsetLeadFixture {
-                origin: Origin::system(system::RawOrigin::Root),
+                origin: RawOrigin::Root.into(),
             }
             .call_and_assert_success();
         });
@@ -1311,7 +1343,7 @@ impl UnstakedFixture {
         );
 
         // Unstaker gone
-        assert!(!UnstakerByStakeId::<Test>::exists(self.stake_id));
+        assert!(!UnstakerByStakeId::<Test>::contains_key(self.stake_id));
     }
 
     // pub fn call_and_assert_failed_result(&self, error_message: &'static str) {
@@ -1406,39 +1438,6 @@ pub fn to_vec(s: &str) -> Vec<u8> {
     s.as_bytes().to_vec()
 }
 
-/*
- * Setups
- */
-
-//type TestSeed = u128;
-
-/*
-fn account_from_seed(TestSeed: seed) -> <Test as system::Trait>::AccountId {
-
-}
-
-fn vector_from_seed(TestSeed: seed) {
-
-}
-*/
-
-/*
-static INITIAL_SEED_VALUE: u128 = 0;
-static CURRENT_SEED: u128 = INITIAL_SEED_VALUE;
-
-fn get_current_seed() {
-
-}
-
-fn update_seed() {
-
-}
-
-fn reset_seed() {
-    CURRENT_SEED: u128 = INITIAL_SEED_VALUE;
-}
-*/
-
 // MOVE THIS LATER WHEN fill_opening is factored out
 #[derive(Clone)]
 pub struct FillOpeningApplicantParams {
@@ -1568,7 +1567,7 @@ fn add_member_and_apply_on_opening(
         crate::RawEvent::AppliedOnCuratorOpening(curator_opening_id, new_curator_application_id)
     );
 
-    assert!(CuratorApplicationById::<Test>::exists(
+    assert!(CuratorApplicationById::<Test>::contains_key(
         new_curator_application_id
     ));
 
@@ -1718,7 +1717,6 @@ fn setup_and_fill_opening(
     let applicants_to_hire_iter = applicants.iter().filter(|params| params.hire);
 
     let num_applicants_hired = applicants_to_hire_iter.cloned().count();
-    //let num_applicants_not_to_hire = (applicants.len() - num_applicants_hired) as usize;
 
     let hired_applicant_and_result = setup_opening_in_review
         .added_members_application_result
@@ -1799,7 +1797,7 @@ fn setup_and_fill_opening(
         let expected_added_principal_id: u64 = (hired_index as u64) + original_next_principal_id;
 
         // Curator added
-        assert!(CuratorById::<Test>::exists(expected_added_curator_id));
+        assert!(CuratorById::<Test>::contains_key(expected_added_curator_id));
 
         let added_curator = CuratorById::<Test>::get(expected_added_curator_id);
 
@@ -1848,7 +1846,9 @@ fn setup_and_fill_opening(
         assert_eq!(expected_curator, added_curator);
 
         // Principal added
-        assert!(PrincipalById::<Test>::exists(expected_added_principal_id));
+        assert!(PrincipalById::<Test>::contains_key(
+            expected_added_principal_id
+        ));
 
         let added_principal = PrincipalById::<Test>::get(expected_added_principal_id);
 
@@ -1978,6 +1978,7 @@ impl CreateChannelFixture {
             self.banner.clone(),
             self.publication_status.clone(),
         )
+        .map_err(<&str>::from)
     }
 
     pub fn call_and_assert_error(&self, err_message: &'static str) {
@@ -2010,7 +2011,7 @@ impl CreateChannelFixture {
 
         // Assert that given channel id has been added,
         // and has the right properties.
-        assert!(crate::ChannelById::<Test>::exists(channel_id));
+        assert!(crate::ChannelById::<Test>::contains_key(channel_id));
 
         let created_channel = crate::ChannelById::<Test>::get(channel_id);
 
@@ -2044,7 +2045,7 @@ impl CreateChannelFixture {
         );
 
         // Check that principal actually has been added
-        assert!(crate::PrincipalById::<Test>::exists(
+        assert!(crate::PrincipalById::<Test>::contains_key(
             created_channel.principal_id
         ));
 
@@ -2113,15 +2114,18 @@ pub fn set_lead(
     member_id: <Test as membership::Trait>::MemberId,
     new_role_account: <Test as system::Trait>::AccountId,
 ) -> LeadId<Test> {
-    // Get controller account
-    //let lead_member_controller_account = membership::Module::<Test>::ensure_membership(member_id).unwrap().controller_account;
+    /*
+       Events are not emitted on block 0.
+       So any dispatchable calls made during genesis block formation will have no events emitted.
+       https://substrate.dev/recipes/2-appetizers/4-events.html
+    */
+    run_to_block(1);
 
     let expected_lead_id = NextLeadId::<Test>::get();
-
     // Set lead
     assert_eq!(
         ContentWorkingGroup::replace_lead(
-            mock::Origin::system(system::RawOrigin::Root),
+            RawOrigin::Root.into(),
             Some((member_id, new_role_account))
         )
         .unwrap(),
@@ -2136,7 +2140,6 @@ pub fn set_lead(
     expected_lead_id
 }
 
-// lead_role_account: <Test as system::Trait>::AccountId
 pub fn add_curator_opening() -> CuratorOpeningId<Test> {
     let activate_at = hiring::ActivateOpeningAt::ExactBlock(34);
 
@@ -2195,6 +2198,13 @@ fn increasing_mint_capacity() {
         )
         .build()
         .execute_with(|| {
+            /*
+               Events are not emitted on block 0.
+               So any dispatchable calls made during genesis block formation will have no events emitted.
+               https://substrate.dev/recipes/2-appetizers/4-events.html
+            */
+            run_to_block(1);
+
             let mint_id = ContentWorkingGroup::mint();
             let mint = Minting::mints(mint_id);
             assert_eq!(mint.capacity(), MINT_CAPACITY);
@@ -2203,7 +2213,7 @@ fn increasing_mint_capacity() {
             // Increasing mint capacity
             let expected_new_capacity = MINT_CAPACITY + increase;
             assert_ok!(ContentWorkingGroup::increase_mint_capacity(
-                Origin::ROOT,
+                RawOrigin::Root.into(),
                 increase
             ));
             // Excpected event after increasing
@@ -2229,6 +2239,13 @@ fn setting_mint_capacity() {
         )
         .build()
         .execute_with(|| {
+            /*
+               Events are not emitted on block 0.
+               So any dispatchable calls made during genesis block formation will have no events emitted.
+               https://substrate.dev/recipes/2-appetizers/4-events.html
+            */
+            run_to_block(1);
+
             let mint_id = ContentWorkingGroup::mint();
             let mint = Minting::mints(mint_id);
             assert_eq!(mint.capacity(), MINT_CAPACITY);
@@ -2237,7 +2254,7 @@ fn setting_mint_capacity() {
             let new_lower_capacity = 10000;
             let decrease = MINT_CAPACITY - new_lower_capacity;
             assert_ok!(ContentWorkingGroup::set_mint_capacity(
-                Origin::ROOT,
+                RawOrigin::Root.into(),
                 new_lower_capacity
             ));
             // Correct event after decreasing
@@ -2253,7 +2270,7 @@ fn setting_mint_capacity() {
             let new_higher_capacity = 25000;
             let increase = new_higher_capacity - mint.capacity();
             assert_ok!(ContentWorkingGroup::set_mint_capacity(
-                Origin::ROOT,
+                RawOrigin::Root.into(),
                 new_higher_capacity
             ));
             // Excpected event after increasing

+ 19 - 41
runtime-modules/forum/Cargo.toml

@@ -1,56 +1,34 @@
 [package]
-name = 'substrate-forum-module'
-version = '1.2.2'
+name = 'pallet-forum'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
 [dependencies]
-hex-literal = '0.1.0'
-serde = { version = '1.0.101', optional = true}
-serde_derive = { version = '1.0.101', optional = true }
-rstd = { package = 'sr-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-runtime-primitives = { package = 'sr-primitives', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-srml-support = { package = 'srml-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-srml-support-procedural = { package = 'srml-support-procedural', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-system = { package = 'srml-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-balances = { package = 'srml-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-codec = { package = 'parity-scale-codec', version = '1.0.0', default-features = false, features = ['derive'] }
-# https://users.rust-lang.org/t/failure-derive-compilation-error/39062
-quote = '<=1.0.2'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+common = { package = 'pallet-common', default-features = false, path = '../common'}
 
 [dev-dependencies]
-runtime-io = { package = 'sr-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-primitives = { package = 'substrate-primitives', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-
-[dependencies.common]
-default_features = false
-package = 'substrate-common-module'
-path = '../common'
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
 
 [features]
 default = ['std']
 std = [
 	'serde',
-	'serde_derive',
 	'codec/std',
-	'rstd/std',
-	'runtime-io/std',
-	'runtime-primitives/std',
-	'srml-support/std',
+	'frame-support/std',
 	'system/std',
-  	'balances/std',
-	'timestamp/std',
+	'sp-std/std',
+	'sp-arithmetic/std',
+	'sp-runtime/std',
+	'pallet-timestamp/std',
 	'common/std',
-]
+]

+ 59 - 66
runtime-modules/forum/src/lib.rs

@@ -7,14 +7,19 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 
 #[cfg(feature = "std")]
-use serde_derive::{Deserialize, Serialize};
+use serde::{Deserialize, Serialize};
 
-use rstd::borrow::ToOwned;
-use rstd::prelude::*;
+//TODO: Convert errors to the Substrate decl_error! macro.
+/// Result with string error message. This exists for backward compatibility purpose.
+pub type DispatchResult = Result<(), &'static str>;
 
 use codec::{Codec, Decode, Encode};
-use runtime_primitives::traits::{MaybeSerialize, Member, One, SimpleArithmetic};
-use srml_support::{decl_event, decl_module, decl_storage, dispatch, ensure, Parameter};
+use frame_support::{decl_event, decl_module, decl_storage, ensure, Parameter};
+use sp_arithmetic::traits::{BaseArithmetic, One};
+use sp_runtime::traits::{MaybeSerialize, Member};
+use sp_std::borrow::ToOwned;
+use sp_std::vec;
+use sp_std::vec::Vec;
 
 mod mock;
 mod tests;
@@ -256,7 +261,7 @@ impl<BlockNumber, Moment, AccountId> Category<BlockNumber, Moment, AccountId> {
 type CategoryTreePath<BlockNumber, Moment, AccountId> =
     Vec<Category<BlockNumber, Moment, AccountId>>;
 
-pub trait Trait: system::Trait + timestamp::Trait + Sized {
+pub trait Trait: system::Trait + pallet_timestamp::Trait + Sized {
     type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
 
     type MembershipRegistry: ForumUserRegistry<Self::AccountId>;
@@ -264,7 +269,7 @@ pub trait Trait: system::Trait + timestamp::Trait + Sized {
     /// Thread Id type
     type ThreadId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -274,7 +279,7 @@ pub trait Trait: system::Trait + timestamp::Trait + Sized {
     /// Post Id type
     type PostId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -286,59 +291,39 @@ decl_storage! {
     trait Store for Module<T: Trait> as Forum {
 
         /// Map category identifier to corresponding category.
-        pub CategoryById get(category_by_id) config(): map CategoryId => Category<T::BlockNumber, T::Moment, T::AccountId>;
+        pub CategoryById get(fn category_by_id) config(): map hasher(blake2_128_concat)
+            CategoryId => Category<T::BlockNumber, T::Moment, T::AccountId>;
 
         /// Category identifier value to be used for the next Category created.
-        pub NextCategoryId get(next_category_id) config(): CategoryId;
+        pub NextCategoryId get(fn next_category_id) config(): CategoryId;
 
         /// Map thread identifier to corresponding thread.
-        pub ThreadById get(thread_by_id) config(): map T::ThreadId => Thread<T::BlockNumber, T::Moment, T::AccountId, T::ThreadId>;
+        pub ThreadById get(fn thread_by_id) config(): map hasher(blake2_128_concat)
+            T::ThreadId => Thread<T::BlockNumber, T::Moment, T::AccountId, T::ThreadId>;
 
         /// Thread identifier value to be used for next Thread in threadById.
-        pub NextThreadId get(next_thread_id) config(): T::ThreadId;
+        pub NextThreadId get(fn next_thread_id) config(): T::ThreadId;
 
         /// Map post identifier to corresponding post.
-        pub PostById get(post_by_id) config(): map T::PostId => Post<T::BlockNumber, T::Moment, T::AccountId, T::ThreadId, T::PostId>;
+        pub PostById get(fn post_by_id) config(): map hasher(blake2_128_concat)
+            T::PostId => Post<T::BlockNumber, T::Moment, T::AccountId, T::ThreadId, T::PostId>;
 
         /// Post identifier value to be used for for next post created.
-        pub NextPostId get(next_post_id) config(): T::PostId;
+        pub NextPostId get(fn next_post_id) config(): T::PostId;
 
         /// Account of forum sudo.
-        pub ForumSudo get(forum_sudo) config(): Option<T::AccountId>;
+        pub ForumSudo get(fn forum_sudo) config(): Option<T::AccountId>;
 
         /// Input constraints
         /// These are all forward looking, that is they are enforced on all
         /// future calls.
-        pub CategoryTitleConstraint get(category_title_constraint) config(): InputValidationLengthConstraint;
-        pub CategoryDescriptionConstraint get(category_description_constraint) config(): InputValidationLengthConstraint;
-        pub ThreadTitleConstraint get(thread_title_constraint) config(): InputValidationLengthConstraint;
-        pub PostTextConstraint get(post_text_constraint) config(): InputValidationLengthConstraint;
-        pub ThreadModerationRationaleConstraint get(thread_moderation_rationale_constraint) config(): InputValidationLengthConstraint;
-        pub PostModerationRationaleConstraint get(post_moderation_rationale_constraint) config(): InputValidationLengthConstraint;
+        pub CategoryTitleConstraint get(fn category_title_constraint) config(): InputValidationLengthConstraint;
+        pub CategoryDescriptionConstraint get(fn category_description_constraint) config(): InputValidationLengthConstraint;
+        pub ThreadTitleConstraint get(fn thread_title_constraint) config(): InputValidationLengthConstraint;
+        pub PostTextConstraint get(fn post_text_constraint) config(): InputValidationLengthConstraint;
+        pub ThreadModerationRationaleConstraint get(fn thread_moderation_rationale_constraint) config(): InputValidationLengthConstraint;
+        pub PostModerationRationaleConstraint get(fn post_moderation_rationale_constraint) config(): InputValidationLengthConstraint;
     }
-    /*
-    JUST GIVING UP ON ALL THIS FOR NOW BECAUSE ITS TAKING TOO LONG
-    Review : https://github.com/paritytech/polkadot/blob/620b8610431e7b5fdd71ce3e94c3ee0177406dcc/runtime/src/parachains.rs#L123-L141
-
-    add_extra_genesis {
-
-        // Explain why we need to put this here.
-        config(initial_forum_sudo) : Option<T::AccountId>;
-
-        build(|
-            storage: &mut generator::StorageOverlay,
-            _: &mut generator::ChildrenStorageOverlay,
-            config: &GenesisConfig<T>
-            | {
-
-
-            if let Some(account_id) = &config.initial_forum_sudo {
-                println!("{}: <ForumSudo<T>>::put(account_id)", account_id);
-                <ForumSudo<T> as generator::StorageValue<_>>::put(&account_id, storage);
-            }
-        })
-    }
-    */
 }
 
 decl_event!(
@@ -383,7 +368,8 @@ decl_module! {
         fn deposit_event() = default;
 
         /// Set forum sudo.
-        fn set_forum_sudo(origin, new_forum_sudo: Option<T::AccountId>) -> dispatch::Result {
+        #[weight = 10_000_000] // TODO: adjust weight
+        fn set_forum_sudo(origin, new_forum_sudo: Option<T::AccountId>) -> DispatchResult {
             ensure_root(origin)?;
 
             /*
@@ -408,7 +394,8 @@ decl_module! {
         }
 
         /// Add a new category.
-        fn create_category(origin, parent: Option<CategoryId>, title: Vec<u8>, description: Vec<u8>) -> dispatch::Result {
+        #[weight = 10_000_000] // TODO: adjust weight
+        fn create_category(origin, parent: Option<CategoryId>, title: Vec<u8>, description: Vec<u8>) -> DispatchResult {
 
             // Check that its a valid signature
             let who = ensure_signed(origin)?;
@@ -487,7 +474,8 @@ decl_module! {
         }
 
         /// Update category
-        fn update_category(origin, category_id: CategoryId, new_archival_status: Option<bool>, new_deletion_status: Option<bool>) -> dispatch::Result {
+        #[weight = 10_000_000] // TODO: adjust weight
+        fn update_category(origin, category_id: CategoryId, new_archival_status: Option<bool>, new_deletion_status: Option<bool>) -> DispatchResult {
 
             // Check that its a valid signature
             let who = ensure_signed(origin)?;
@@ -550,7 +538,8 @@ decl_module! {
         }
 
         /// Create new thread in category
-        fn create_thread(origin, category_id: CategoryId, title: Vec<u8>, text: Vec<u8>) -> dispatch::Result {
+        #[weight = 10_000_000] // TODO: adjust weight
+        fn create_thread(origin, category_id: CategoryId, title: Vec<u8>, text: Vec<u8>) -> DispatchResult {
 
             /*
              * Update SPEC with new errors,
@@ -593,7 +582,8 @@ decl_module! {
         }
 
         /// Moderate thread
-        fn moderate_thread(origin, thread_id: T::ThreadId, rationale: Vec<u8>) -> dispatch::Result {
+        #[weight = 10_000_000] // TODO: adjust weight
+        fn moderate_thread(origin, thread_id: T::ThreadId, rationale: Vec<u8>) -> DispatchResult {
 
             // Check that its a valid signature
             let who = ensure_signed(origin)?;
@@ -644,7 +634,8 @@ decl_module! {
         }
 
         /// Edit post text
-        fn add_post(origin, thread_id: T::ThreadId, text: Vec<u8>) -> dispatch::Result {
+        #[weight = 10_000_000] // TODO: adjust weight
+        fn add_post(origin, thread_id: T::ThreadId, text: Vec<u8>) -> DispatchResult {
 
             /*
              * Update SPEC with new errors,
@@ -681,7 +672,8 @@ decl_module! {
         }
 
         /// Edit post text
-        fn edit_post_text(origin, post_id: T::PostId, new_text: Vec<u8>) -> dispatch::Result {
+        #[weight = 10_000_000] // TODO: adjust weight
+        fn edit_post_text(origin, post_id: T::PostId, new_text: Vec<u8>) -> DispatchResult {
 
             /* Edit spec.
               - forum member guard missing
@@ -728,7 +720,8 @@ decl_module! {
         }
 
         /// Moderate post
-        fn moderate_post(origin, post_id: T::PostId, rationale: Vec<u8>) -> dispatch::Result {
+        #[weight = 10_000_000] // TODO: adjust weight
+        fn moderate_post(origin, post_id: T::PostId, rationale: Vec<u8>) -> DispatchResult {
 
             // Check that its a valid signature
             let who = ensure_signed(origin)?;
@@ -772,7 +765,7 @@ decl_module! {
 }
 
 impl<T: Trait> Module<T> {
-    fn ensure_category_title_is_valid(title: &[u8]) -> dispatch::Result {
+    fn ensure_category_title_is_valid(title: &[u8]) -> DispatchResult {
         CategoryTitleConstraint::get().ensure_valid(
             title.len(),
             ERROR_CATEGORY_TITLE_TOO_SHORT,
@@ -780,7 +773,7 @@ impl<T: Trait> Module<T> {
         )
     }
 
-    fn ensure_category_description_is_valid(description: &[u8]) -> dispatch::Result {
+    fn ensure_category_description_is_valid(description: &[u8]) -> DispatchResult {
         CategoryDescriptionConstraint::get().ensure_valid(
             description.len(),
             ERROR_CATEGORY_DESCRIPTION_TOO_SHORT,
@@ -788,7 +781,7 @@ impl<T: Trait> Module<T> {
         )
     }
 
-    fn ensure_thread_moderation_rationale_is_valid(rationale: &[u8]) -> dispatch::Result {
+    fn ensure_thread_moderation_rationale_is_valid(rationale: &[u8]) -> DispatchResult {
         ThreadModerationRationaleConstraint::get().ensure_valid(
             rationale.len(),
             ERROR_THREAD_MODERATION_RATIONALE_TOO_SHORT,
@@ -796,7 +789,7 @@ impl<T: Trait> Module<T> {
         )
     }
 
-    fn ensure_thread_title_is_valid(title: &[u8]) -> dispatch::Result {
+    fn ensure_thread_title_is_valid(title: &[u8]) -> DispatchResult {
         ThreadTitleConstraint::get().ensure_valid(
             title.len(),
             ERROR_THREAD_TITLE_TOO_SHORT,
@@ -804,7 +797,7 @@ impl<T: Trait> Module<T> {
         )
     }
 
-    fn ensure_post_text_is_valid(text: &[u8]) -> dispatch::Result {
+    fn ensure_post_text_is_valid(text: &[u8]) -> DispatchResult {
         PostTextConstraint::get().ensure_valid(
             text.len(),
             ERROR_POST_TEXT_TOO_SHORT,
@@ -812,7 +805,7 @@ impl<T: Trait> Module<T> {
         )
     }
 
-    fn ensure_post_moderation_rationale_is_valid(rationale: &[u8]) -> dispatch::Result {
+    fn ensure_post_moderation_rationale_is_valid(rationale: &[u8]) -> DispatchResult {
         PostModerationRationaleConstraint::get().ensure_valid(
             rationale.len(),
             ERROR_POST_MODERATION_RATIONALE_TOO_SHORT,
@@ -840,7 +833,7 @@ impl<T: Trait> Module<T> {
         post_id: T::PostId,
     ) -> Result<Post<T::BlockNumber, T::Moment, T::AccountId, T::ThreadId, T::PostId>, &'static str>
     {
-        if <PostById<T>>::exists(post_id) {
+        if <PostById<T>>::contains_key(post_id) {
             Ok(<PostById<T>>::get(post_id))
         } else {
             Err(ERROR_POST_DOES_NOT_EXIST)
@@ -865,7 +858,7 @@ impl<T: Trait> Module<T> {
     fn ensure_thread_exists(
         thread_id: T::ThreadId,
     ) -> Result<Thread<T::BlockNumber, T::Moment, T::AccountId, T::ThreadId>, &'static str> {
-        if <ThreadById<T>>::exists(thread_id) {
+        if <ThreadById<T>>::contains_key(thread_id) {
             Ok(<ThreadById<T>>::get(thread_id))
         } else {
             Err(ERROR_THREAD_DOES_NOT_EXIST)
@@ -879,7 +872,7 @@ impl<T: Trait> Module<T> {
         }
     }
 
-    fn ensure_is_forum_sudo(account_id: &T::AccountId) -> dispatch::Result {
+    fn ensure_is_forum_sudo(account_id: &T::AccountId) -> DispatchResult {
         let forum_sudo_account = Self::ensure_forum_sudo_set()?;
 
         ensure!(
@@ -901,7 +894,7 @@ impl<T: Trait> Module<T> {
         }
     }
 
-    fn ensure_catgory_is_mutable(category_id: CategoryId) -> dispatch::Result {
+    fn ensure_catgory_is_mutable(category_id: CategoryId) -> DispatchResult {
         let category_tree_path = Self::build_category_tree_path(category_id);
 
         Self::ensure_can_mutate_in_path_leaf(&category_tree_path)
@@ -913,7 +906,7 @@ impl<T: Trait> Module<T> {
     #[allow(clippy::ptr_arg)]
     fn ensure_can_mutate_in_path_leaf(
         category_tree_path: &CategoryTreePath<T::BlockNumber, T::Moment, T::AccountId>,
-    ) -> dispatch::Result {
+    ) -> DispatchResult {
         // Is parent category directly or indirectly deleted or archived category
         ensure!(
             !category_tree_path.iter().any(
@@ -930,7 +923,7 @@ impl<T: Trait> Module<T> {
     #[allow(clippy::ptr_arg)] // disable it because of possible frontend API break
     fn ensure_can_add_subcategory_path_leaf(
         category_tree_path: &CategoryTreePath<T::BlockNumber, T::Moment, T::AccountId>,
-    ) -> dispatch::Result {
+    ) -> DispatchResult {
         Self::ensure_can_mutate_in_path_leaf(category_tree_path)?;
 
         // Does adding a new category exceed maximum depth
@@ -948,7 +941,7 @@ impl<T: Trait> Module<T> {
         category_id: CategoryId,
     ) -> Result<CategoryTreePath<T::BlockNumber, T::Moment, T::AccountId>, &'static str> {
         ensure!(
-            <CategoryById<T>>::exists(&category_id),
+            <CategoryById<T>>::contains_key(&category_id),
             ERROR_CATEGORY_DOES_NOT_EXIST
         );
 
@@ -990,7 +983,7 @@ impl<T: Trait> Module<T> {
 
         // Make recursive call on parent if we are not at root
         if let Some(child_position_in_parent) = position_in_parent_category_field {
-            assert!(<CategoryById<T>>::exists(
+            assert!(<CategoryById<T>>::contains_key(
                 &child_position_in_parent.parent_id
             ));
 

+ 39 - 33
runtime-modules/forum/src/mock.rs

@@ -3,22 +3,19 @@
 use crate::*;
 use common::BlockAndTime;
 
-use primitives::H256;
-
-use crate::{GenesisConfig, Module, Trait};
-use runtime_primitives::{
+use frame_support::{impl_outer_origin, parameter_types};
+use sp_core::H256;
+use sp_runtime::{
     testing::Header,
     traits::{BlakeTwo256, IdentityLookup},
     Perbill,
 };
-use srml_support::{impl_outer_origin, parameter_types};
 
 /// Module which has a full Substrate module for
 /// mocking behaviour of MembershipRegistry
 pub mod registry {
 
     use super::*;
-    // use srml_support::*;
 
     #[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
     pub struct Member<AccountId> {
@@ -27,9 +24,8 @@ pub mod registry {
 
     decl_storage! {
         trait Store for Module<T: Trait> as MockForumUserRegistry {
-
-            pub ForumUserById get(forum_user_by_id) config(): map T::AccountId => Member<T::AccountId>;
-
+            pub ForumUserById get(fn forum_user_by_id) config(): map hasher(blake2_128_concat)
+                T::AccountId => Member<T::AccountId>;
         }
     }
 
@@ -45,7 +41,7 @@ pub mod registry {
 
     impl<T: Trait> ForumUserRegistry<T::AccountId> for Module<T> {
         fn get_forum_user(id: &T::AccountId) -> Option<ForumUser<T::AccountId>> {
-            if <ForumUserById<T>>::exists(id) {
+            if <ForumUserById<T>>::contains_key(id) {
                 let m = <ForumUserById<T>>::get(id);
 
                 Some(ForumUser { id: m.id })
@@ -74,25 +70,33 @@ parameter_types! {
 }
 
 impl system::Trait for Runtime {
+    type BaseCallFilter = ();
     type Origin = Origin;
+    type Call = ();
     type Index = u64;
     type BlockNumber = u64;
-    type Call = ();
     type Hash = H256;
     type Hashing = BlakeTwo256;
     type AccountId = u64;
     type Lookup = IdentityLookup<Self::AccountId>;
     type Header = Header;
-    // type WeightMultiplierUpdate = ();
     type Event = ();
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = ();
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
-impl timestamp::Trait for Runtime {
+impl pallet_timestamp::Trait for Runtime {
     type Moment = u64;
     type OnTimestampSet = ();
     type MinimumPeriod = MinimumPeriod;
@@ -168,7 +172,7 @@ pub struct CreateCategoryFixture {
     pub parent: Option<CategoryId>,
     pub title: Vec<u8>,
     pub description: Vec<u8>,
-    pub result: dispatch::Result,
+    pub result: DispatchResult,
 }
 
 impl CreateCategoryFixture {
@@ -190,7 +194,7 @@ pub struct UpdateCategoryFixture {
     pub category_id: CategoryId,
     pub new_archival_status: Option<bool>,
     pub new_deletion_status: Option<bool>,
-    pub result: dispatch::Result,
+    pub result: DispatchResult,
 }
 
 impl UpdateCategoryFixture {
@@ -212,7 +216,7 @@ pub struct CreateThreadFixture {
     pub category_id: CategoryId,
     pub title: Vec<u8>,
     pub text: Vec<u8>,
-    pub result: dispatch::Result,
+    pub result: DispatchResult,
 }
 
 impl CreateThreadFixture {
@@ -233,7 +237,7 @@ pub struct CreatePostFixture {
     pub origin: OriginType,
     pub thread_id: RuntimeThreadId,
     pub text: Vec<u8>,
-    pub result: dispatch::Result,
+    pub result: DispatchResult,
 }
 
 impl CreatePostFixture {
@@ -259,7 +263,7 @@ pub fn create_forum_member() -> OriginType {
 pub fn assert_create_category(
     forum_sudo: OriginType,
     parent_category_id: Option<CategoryId>,
-    expected_result: dispatch::Result,
+    expected_result: DispatchResult,
 ) {
     CreateCategoryFixture {
         origin: forum_sudo,
@@ -274,7 +278,7 @@ pub fn assert_create_category(
 pub fn assert_create_thread(
     forum_sudo: OriginType,
     category_id: CategoryId,
-    expected_result: dispatch::Result,
+    expected_result: DispatchResult,
 ) {
     CreateThreadFixture {
         origin: forum_sudo,
@@ -289,7 +293,7 @@ pub fn assert_create_thread(
 pub fn assert_create_post(
     forum_sudo: OriginType,
     thread_id: RuntimeThreadId,
-    expected_result: dispatch::Result,
+    expected_result: DispatchResult,
 ) {
     CreatePostFixture {
         origin: forum_sudo,
@@ -353,7 +357,7 @@ pub fn moderate_thread(
     forum_sudo: OriginType,
     thread_id: RuntimeThreadId,
     rationale: Vec<u8>,
-) -> dispatch::Result {
+) -> DispatchResult {
     TestForumModule::moderate_thread(mock_origin(forum_sudo), thread_id, rationale)
 }
 
@@ -361,28 +365,28 @@ pub fn moderate_post(
     forum_sudo: OriginType,
     post_id: RuntimePostId,
     rationale: Vec<u8>,
-) -> dispatch::Result {
+) -> DispatchResult {
     TestForumModule::moderate_post(mock_origin(forum_sudo), post_id, rationale)
 }
 
-pub fn archive_category(forum_sudo: OriginType, category_id: CategoryId) -> dispatch::Result {
+pub fn archive_category(forum_sudo: OriginType, category_id: CategoryId) -> DispatchResult {
     TestForumModule::update_category(mock_origin(forum_sudo), category_id, Some(true), None)
 }
 
-pub fn unarchive_category(forum_sudo: OriginType, category_id: CategoryId) -> dispatch::Result {
+pub fn unarchive_category(forum_sudo: OriginType, category_id: CategoryId) -> DispatchResult {
     TestForumModule::update_category(mock_origin(forum_sudo), category_id, Some(false), None)
 }
 
-pub fn delete_category(forum_sudo: OriginType, category_id: CategoryId) -> dispatch::Result {
+pub fn delete_category(forum_sudo: OriginType, category_id: CategoryId) -> DispatchResult {
     TestForumModule::update_category(mock_origin(forum_sudo), category_id, None, Some(true))
 }
 
-pub fn undelete_category(forum_sudo: OriginType, category_id: CategoryId) -> dispatch::Result {
+pub fn undelete_category(forum_sudo: OriginType, category_id: CategoryId) -> DispatchResult {
     TestForumModule::update_category(mock_origin(forum_sudo), category_id, None, Some(false))
 }
 
 pub fn assert_not_forum_sudo_cannot_update_category(
-    update_operation: fn(OriginType, CategoryId) -> dispatch::Result,
+    update_operation: fn(OriginType, CategoryId) -> DispatchResult,
 ) {
     let config = default_genesis_config();
     let origin = OriginType::Signed(config.forum_sudo);
@@ -452,24 +456,26 @@ pub fn default_genesis_config() -> GenesisConfig<Runtime> {
 pub type RuntimeMap<K, V> = std::vec::Vec<(K, V)>;
 pub type RuntimeCategory = Category<
     <Runtime as system::Trait>::BlockNumber,
-    <Runtime as timestamp::Trait>::Moment,
+    <Runtime as pallet_timestamp::Trait>::Moment,
     <Runtime as system::Trait>::AccountId,
 >;
 pub type RuntimeThread = Thread<
     <Runtime as system::Trait>::BlockNumber,
-    <Runtime as timestamp::Trait>::Moment,
+    <Runtime as pallet_timestamp::Trait>::Moment,
     <Runtime as system::Trait>::AccountId,
     RuntimeThreadId,
 >;
 pub type RuntimePost = Post<
     <Runtime as system::Trait>::BlockNumber,
-    <Runtime as timestamp::Trait>::Moment,
+    <Runtime as pallet_timestamp::Trait>::Moment,
     <Runtime as system::Trait>::AccountId,
     RuntimeThreadId,
     RuntimePostId,
 >;
-pub type RuntimeBlockchainTimestamp =
-    BlockAndTime<<Runtime as system::Trait>::BlockNumber, <Runtime as timestamp::Trait>::Moment>;
+pub type RuntimeBlockchainTimestamp = BlockAndTime<
+    <Runtime as system::Trait>::BlockNumber,
+    <Runtime as pallet_timestamp::Trait>::Moment,
+>;
 
 pub type RuntimeThreadId = <Runtime as Trait>::ThreadId;
 pub type RuntimePostId = <Runtime as Trait>::PostId;
@@ -516,7 +522,7 @@ pub fn default_mock_forum_user_registry_genesis_config() -> registry::GenesisCon
 // NB!:
 // Wanted to have payload: a: &GenesisConfig<Test>
 // but borrow checker made my life miserabl, so giving up for now.
-pub fn build_test_externalities(config: GenesisConfig<Runtime>) -> runtime_io::TestExternalities {
+pub fn build_test_externalities(config: GenesisConfig<Runtime>) -> sp_io::TestExternalities {
     let mut t = system::GenesisConfig::default()
         .build_storage::<Runtime>()
         .unwrap();

+ 1 - 1
runtime-modules/forum/src/tests.rs

@@ -3,7 +3,7 @@
 use super::*;
 use crate::mock::*;
 
-use srml_support::{assert_err, assert_ok};
+use frame_support::{assert_err, assert_ok};
 
 /*
 * NB!: No test checks for event emission!!!!

+ 30 - 89
runtime-modules/governance/Cargo.toml

@@ -1,100 +1,41 @@
 [package]
-name = 'substrate-governance-module'
-version = '1.0.0'
+name = 'pallet-governance'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
+[dependencies]
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+membership = { package = 'pallet-membership', default-features = false, path = '../membership'}
+minting = { package = 'pallet-token-mint', default-features = false, path = '../token-minting'}
+recurringrewards = { package = 'pallet-recurring-reward', default-features = false, path = '../recurring-reward'}
+common = { package = 'pallet-common', default-features = false, path = '../common'}
+
+[dev-dependencies]
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+
 [features]
 default = ['std']
 std = [
-	'sr-primitives/std',
-	'srml-support/std',
-	'system/std',
 	'serde',
 	'codec/std',
-	'timestamp/std',
-	'primitives/std',
-	'rstd/std',
-	'common/std',
+	'sp-std/std',
+	'frame-support/std',
+	'system/std',
+	'sp-arithmetic/std',
+	'sp-runtime/std',
+	'pallet-timestamp/std',
 	'membership/std',
 	'minting/std',
-]
-
-[dependencies.sr-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.srml-support]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-support'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.system]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-system'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.rstd]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-std'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.serde]
-features = ['derive']
-optional = true
-version = '1.0.101'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dependencies.common]
-default_features = false
-package = 'substrate-common-module'
-path = '../common'
-
-[dependencies.membership]
-default_features = false
-package = 'substrate-membership-module'
-path = '../membership'
-
-[dev-dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dev-dependencies.balances]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-balances'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.minting]
-default_features = false
-package = 'substrate-token-mint-module'
-path = '../token-minting'
-
-[dependencies.recurringrewards]
-default_features = false
-package = 'substrate-recurring-reward-module'
-path = '../recurring-reward'
+	'recurringrewards/std',
+	'common/std',
+]

+ 33 - 22
runtime-modules/governance/src/council.rs

@@ -1,7 +1,8 @@
-use rstd::prelude::*;
-use sr_primitives::traits::{One, Zero};
-use srml_support::{debug, decl_event, decl_module, decl_storage, ensure};
-use system::{self, ensure_root};
+use frame_support::{debug, decl_event, decl_module, decl_storage, ensure};
+use sp_arithmetic::traits::{One, Zero};
+use sp_std::vec;
+use sp_std::vec::Vec;
+use system::ensure_root;
 
 pub use super::election::{self, CouncilElected, Seat, Seats};
 pub use common::currency::{BalanceOf, GovernanceCurrency};
@@ -29,28 +30,29 @@ pub trait Trait: system::Trait + recurringrewards::Trait + GovernanceCurrency {
 
 decl_storage! {
     trait Store for Module<T: Trait> as Council {
-        pub ActiveCouncil get(active_council) config(): Seats<T::AccountId, BalanceOf<T>>;
+        pub ActiveCouncil get(fn active_council) config(): Seats<T::AccountId, BalanceOf<T>>;
 
-        pub TermEndsAt get(term_ends_at) config() : T::BlockNumber = T::BlockNumber::from(1);
+        pub TermEndsAt get(fn term_ends_at) config() : T::BlockNumber = T::BlockNumber::from(1);
 
         /// The mint that funds council member rewards and spending proposals budget. It is an Option
         /// because it was introduced in a runtime upgrade. It will be automatically created when
         /// a successful call to set_council_mint_capacity() is made.
-        pub CouncilMint get(council_mint) : Option<<T as minting::Trait>::MintId>;
+        pub CouncilMint get(fn council_mint) : Option<<T as minting::Trait>::MintId>;
 
         /// The reward relationships currently in place. There may not necessarily be a 1-1 correspondance with
         /// the active council, since there are multiple ways of setting/adding/removing council members, some of which
         /// do not involve creating a relationship.
-        pub RewardRelationships get(reward_relationships) : map T::AccountId => T::RewardRelationshipId;
+        pub RewardRelationships get(fn reward_relationships) : map hasher(blake2_128_concat)
+            T::AccountId => T::RewardRelationshipId;
 
         /// Reward amount paid out at each PayoutInterval
-        pub AmountPerPayout get(amount_per_payout): minting::BalanceOf<T>;
+        pub AmountPerPayout get(fn amount_per_payout): minting::BalanceOf<T>;
 
         /// Optional interval in blocks on which a reward payout will be made to each council member
-        pub PayoutInterval get(payout_interval): Option<T::BlockNumber>;
+        pub PayoutInterval get(fn payout_interval): Option<T::BlockNumber>;
 
         /// How many blocks after the reward is created, the first payout will be made
-        pub FirstPayoutAfterRewardCreated get(first_payout_after_reward_created): T::BlockNumber;
+        pub FirstPayoutAfterRewardCreated get(fn first_payout_after_reward_created): T::BlockNumber;
     }
 }
 
@@ -128,7 +130,7 @@ impl<T: Trait> Module<T> {
 
     fn remove_reward_relationships() {
         for seat in Self::active_council().into_iter() {
-            if RewardRelationships::<T>::exists(&seat.member) {
+            if RewardRelationships::<T>::contains_key(&seat.member) {
                 let id = Self::reward_relationships(&seat.member);
                 <recurringrewards::Module<T>>::remove_reward_relationship(id);
             }
@@ -165,6 +167,7 @@ decl_module! {
         /// Existing council rewards are removed and new council members do NOT get any rewards.
         /// Avoid using this call if possible, will be deprecated. The term of the new council is
         /// not extended.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_council(origin, accounts: Vec<T::AccountId>) {
             ensure_root(origin)?;
 
@@ -189,6 +192,7 @@ decl_module! {
         }
 
         /// Adds a zero staked council member. A member added in this way does not get a recurring reward.
+        #[weight = 10_000_000] // TODO: adjust weight
         fn add_council_member(origin, account: T::AccountId) {
             ensure_root(origin)?;
 
@@ -209,12 +213,13 @@ decl_module! {
         }
 
         /// Remove a single council member and their reward.
+        #[weight = 10_000_000] // TODO: adjust weight
         fn remove_council_member(origin, account_to_remove: T::AccountId) {
             ensure_root(origin)?;
 
             ensure!(Self::is_councilor(&account_to_remove), "account is not a councilor");
 
-            if RewardRelationships::<T>::exists(&account_to_remove) {
+            if RewardRelationships::<T>::contains_key(&account_to_remove) {
                 let relationship_id = Self::reward_relationships(&account_to_remove);
                 <recurringrewards::Module<T>>::remove_reward_relationship(relationship_id);
             }
@@ -228,6 +233,7 @@ decl_module! {
         }
 
         /// Set blocknumber when council term will end
+        #[weight = 10_000_000] // TODO: adjust weight
         fn set_term_ends_at(origin, ends_at: T::BlockNumber) {
             ensure_root(origin)?;
             ensure!(ends_at > <system::Module<T>>::block_number(), "must set future block number");
@@ -236,28 +242,32 @@ decl_module! {
 
         /// Sets the capacity of the the council mint, if it doesn't exist, attempts to
         /// create a new one.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_council_mint_capacity(origin, capacity: minting::BalanceOf<T>) {
             ensure_root(origin)?;
 
             if let Some(mint_id) = Self::council_mint() {
-                minting::Module::<T>::set_mint_capacity(mint_id, capacity)?;
+                minting::Module::<T>::set_mint_capacity(mint_id, capacity).map_err(<&str>::from)?;
             } else {
                 Self::create_new_council_mint(capacity)?;
             }
         }
 
         /// Attempts to mint and transfer amount to destination account
+        #[weight = 10_000_000] // TODO: adjust weight
         fn spend_from_council_mint(origin, amount: minting::BalanceOf<T>, destination: T::AccountId) {
             ensure_root(origin)?;
 
             if let Some(mint_id) = Self::council_mint() {
-                minting::Module::<T>::transfer_tokens(mint_id, amount, &destination)?;
+                minting::Module::<T>::transfer_tokens(mint_id, amount, &destination)
+                    .map_err(<&str>::from)?;
             } else {
-                return Err("CouncilHasNoMint")
+                return Err("CouncilHasNoMint".into());
             }
         }
 
         /// Sets the council rewards which is only applied on new council being elected.
+        #[weight = 10_000_000] // TODO: adjust weight
         fn set_council_rewards(
             origin,
             amount_per_payout: minting::BalanceOf<T>,
@@ -282,10 +292,11 @@ decl_module! {
 mod tests {
     use super::*;
     use crate::mock::*;
-    use srml_support::*;
+    use crate::DispatchResult;
+    use frame_support::*;
 
-    fn add_council_member_as_root(account: <Test as system::Trait>::AccountId) -> dispatch::Result {
-        Council::add_council_member(system::RawOrigin::Root.into(), account)
+    fn add_council_member_as_root(account: <Test as system::Trait>::AccountId) -> DispatchResult {
+        Council::add_council_member(system::RawOrigin::Root.into(), account).map_err(|e| e.into())
     }
 
     #[test]
@@ -367,9 +378,9 @@ mod tests {
             assert!(Council::is_councilor(&6));
             assert!(Council::is_councilor(&7));
 
-            assert!(RewardRelationships::<Test>::exists(&5));
-            assert!(RewardRelationships::<Test>::exists(&6));
-            assert!(RewardRelationships::<Test>::exists(&7));
+            assert!(RewardRelationships::<Test>::contains_key(&5));
+            assert!(RewardRelationships::<Test>::contains_key(&6));
+            assert!(RewardRelationships::<Test>::contains_key(&7));
         });
     }
 }

+ 76 - 48
runtime-modules/governance/src/election.rs

@@ -29,17 +29,19 @@
 // Clippy linter warning
 #![allow(clippy::redundant_closure_call)] // disable it because of the substrate lib design
 
-use rstd::prelude::*;
-use srml_support::traits::{Currency, ReservableCurrency};
-use srml_support::{decl_event, decl_module, decl_storage, dispatch::Result, ensure};
-use system::{self, ensure_root, ensure_signed};
-
-use codec::{Decode, Encode};
-use rstd::collections::btree_map::BTreeMap;
-use rstd::ops::Add;
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
-use sr_primitives::traits::{Hash, Zero};
+
+use codec::{Decode, Encode};
+use frame_support::traits::{Currency, ReservableCurrency};
+use frame_support::{decl_event, decl_module, decl_storage, ensure};
+use sp_arithmetic::traits::Zero;
+use sp_runtime::traits::Hash;
+use sp_std::collections::btree_map::BTreeMap;
+use sp_std::ops::Add;
+use sp_std::vec;
+use sp_std::vec::Vec;
+use system::{ensure_root, ensure_signed};
 
 use super::sealed_vote::SealedVote;
 use super::stake::Stake;
@@ -48,6 +50,8 @@ use super::council;
 use crate::election_params::ElectionParameters;
 pub use common::currency::{BalanceOf, GovernanceCurrency};
 
+use crate::DispatchResult;
+
 pub trait Trait: system::Trait + council::Trait + GovernanceCurrency + membership::Trait {
     type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
 
@@ -132,37 +136,40 @@ pub type ElectionStake<T> = Stake<BalanceOf<T>>;
 decl_storage! {
     trait Store for Module<T: Trait> as CouncilElection {
         // Flag for wether to automatically start an election after a council term ends
-        AutoStart get(auto_start) config() : bool = true;
+        AutoStart get(fn auto_start) config() : bool = true;
 
         // Current stage if there is an election running
-        Stage get(stage): Option<ElectionStage<T::BlockNumber>>;
+        Stage get(fn stage): Option<ElectionStage<T::BlockNumber>>;
 
         // The election round
-        Round get(round): u32;
+        Round get(fn round): u32;
 
-        ExistingStakeHolders get(existing_stake_holders): Vec<T::AccountId>;
-        TransferableStakes get(transferable_stakes): map T::AccountId => TransferableStake<BalanceOf<T>>;
+        ExistingStakeHolders get(fn existing_stake_holders): Vec<T::AccountId>;
+        TransferableStakes get(fn transferable_stakes): map hasher(blake2_128_concat)
+            T::AccountId => TransferableStake<BalanceOf<T>>;
 
-        Applicants get(applicants): Vec<T::AccountId>;
-        ApplicantStakes get(applicant_stakes): map T::AccountId => ElectionStake<T>;
+        Applicants get(fn applicants): Vec<T::AccountId>;
+        ApplicantStakes get(fn applicant_stakes): map hasher(blake2_128_concat)
+            T::AccountId => ElectionStake<T>;
 
-        Commitments get(commitments): Vec<T::Hash>;
+        Commitments get(fn commitments): Vec<T::Hash>;
 
         // TODO value type of this map looks scary, is there any way to simplify the notation?
-        Votes get(votes): map T::Hash => SealedVote<T::AccountId, ElectionStake<T>, T::Hash, T::AccountId>;
+        Votes get(fn votes): map hasher(blake2_128_concat)
+            T::Hash => SealedVote<T::AccountId, ElectionStake<T>, T::Hash, T::AccountId>;
 
         // Current Election Parameters.
         // Should we replace all the individual values with a single ElectionParameters type?
         // Having them individually makes it more flexible to add and remove new parameters in future
         // without dealing with migration issues.
-        AnnouncingPeriod get(announcing_period): T::BlockNumber;
-        VotingPeriod get(voting_period): T::BlockNumber;
-        RevealingPeriod get(revealing_period): T::BlockNumber;
-        CouncilSize get(council_size): u32;
-        CandidacyLimit get (candidacy_limit): u32;
-        MinCouncilStake get(min_council_stake): BalanceOf<T>;
-        NewTermDuration get(new_term_duration): T::BlockNumber;
-        MinVotingStake get(min_voting_stake): BalanceOf<T>;
+        AnnouncingPeriod get(fn announcing_period): T::BlockNumber;
+        VotingPeriod get(fn voting_period): T::BlockNumber;
+        RevealingPeriod get(fn revealing_period): T::BlockNumber;
+        CouncilSize get(fn council_size): u32;
+        CandidacyLimit get (fn candidacy_limit): u32;
+        MinCouncilStake get(fn min_council_stake): BalanceOf<T>;
+        NewTermDuration get(fn new_term_duration): T::BlockNumber;
+        MinVotingStake get(fn min_voting_stake): BalanceOf<T>;
     }
     add_extra_genesis {
         config(election_parameters): ElectionParameters<BalanceOf<T>, T::BlockNumber>;
@@ -238,7 +245,7 @@ impl<T: Trait> Module<T> {
 
     /// Starts an election. Will fail if an election is already running
     /// Initializes transferable stakes. Assumes election parameters have already been set.
-    fn start_election(current_council: Seats<T::AccountId, BalanceOf<T>>) -> Result {
+    fn start_election(current_council: Seats<T::AccountId, BalanceOf<T>>) -> DispatchResult {
         ensure!(!Self::is_election_running(), "election already in progress");
         ensure!(
             Self::existing_stake_holders().is_empty(),
@@ -317,7 +324,7 @@ impl<T: Trait> Module<T> {
             Self::move_to_announcing_stage();
         } else {
             // upper limit on applicants that will move to voting stage
-            let limit = rstd::cmp::max(Self::council_size_usize(), Self::candidacy_limit_usize());
+            let limit = sp_std::cmp::max(Self::council_size_usize(), Self::candidacy_limit_usize());
             let applicants_to_drop = Self::find_least_staked_applicants(&mut applicants, limit);
 
             Self::drop_applicants(applicants_to_drop);
@@ -618,7 +625,7 @@ impl<T: Trait> Module<T> {
         for seat in current_council.into_iter() {
             let Seat { member, stake, .. } = seat;
 
-            if <TransferableStakes<T>>::exists(&member) {
+            if <TransferableStakes<T>>::contains_key(&member) {
                 <TransferableStakes<T>>::mutate(&member, |transferbale_stake| {
                     *transferbale_stake = TransferableStake {
                         seat: transferbale_stake.seat + stake,
@@ -640,7 +647,7 @@ impl<T: Trait> Module<T> {
             for backer in seat.backers.into_iter() {
                 let Backer { member, stake, .. } = backer;
 
-                if <TransferableStakes<T>>::exists(&member) {
+                if <TransferableStakes<T>>::contains_key(&member) {
                     <TransferableStakes<T>>::mutate(&member, |transferbale_stake| {
                         *transferbale_stake = TransferableStake {
                             seat: transferbale_stake.seat,
@@ -682,7 +689,7 @@ impl<T: Trait> Module<T> {
         }
     }
 
-    fn try_add_applicant(applicant: T::AccountId, stake: BalanceOf<T>) -> Result {
+    fn try_add_applicant(applicant: T::AccountId, stake: BalanceOf<T>) -> DispatchResult {
         let mut transferable_stake = <TransferableStakes<T>>::get(&applicant);
 
         let new_stake = Self::new_stake_reusing_transferable(&mut transferable_stake.seat, stake);
@@ -700,11 +707,11 @@ impl<T: Trait> Module<T> {
         let applicant_stake = <ApplicantStakes<T>>::get(&applicant);
         let total_stake = applicant_stake.add(&new_stake);
 
-        if <TransferableStakes<T>>::exists(&applicant) {
+        if <TransferableStakes<T>>::contains_key(&applicant) {
             <TransferableStakes<T>>::insert(&applicant, transferable_stake);
         }
 
-        if !<ApplicantStakes<T>>::exists(&applicant) {
+        if !<ApplicantStakes<T>>::contains_key(&applicant) {
             // insert element at the begining, this gives priority to early applicants
             // when ordering applicants by stake if stakes are equal
             <Applicants<T>>::mutate(|applicants| applicants.insert(0, applicant.clone()));
@@ -715,8 +722,15 @@ impl<T: Trait> Module<T> {
         Ok(())
     }
 
-    fn try_add_vote(voter: T::AccountId, stake: BalanceOf<T>, commitment: T::Hash) -> Result {
-        ensure!(!<Votes<T>>::exists(commitment), "duplicate commitment");
+    fn try_add_vote(
+        voter: T::AccountId,
+        stake: BalanceOf<T>,
+        commitment: T::Hash,
+    ) -> DispatchResult {
+        ensure!(
+            !<Votes<T>>::contains_key(commitment),
+            "duplicate commitment"
+        );
 
         let mut transferable_stake = <TransferableStakes<T>>::get(&voter);
 
@@ -740,7 +754,7 @@ impl<T: Trait> Module<T> {
             SealedVote::new(voter.clone(), vote_stake, commitment),
         );
 
-        if <TransferableStakes<T>>::exists(&voter) {
+        if <TransferableStakes<T>>::contains_key(&voter) {
             <TransferableStakes<T>>::insert(&voter, transferable_stake);
         }
 
@@ -752,8 +766,11 @@ impl<T: Trait> Module<T> {
         commitment: T::Hash,
         vote_for: T::AccountId,
         salt: Vec<u8>,
-    ) -> Result {
-        ensure!(<Votes<T>>::exists(&commitment), "commitment not found");
+    ) -> DispatchResult {
+        ensure!(
+            <Votes<T>>::contains_key(&commitment),
+            "commitment not found"
+        );
 
         let mut sealed_vote = <Votes<T>>::get(&commitment);
 
@@ -761,7 +778,7 @@ impl<T: Trait> Module<T> {
         // only voter can reveal their own votes
         ensure!(sealed_vote.is_owned_by(voter), "only voter can reveal vote");
         ensure!(
-            <ApplicantStakes<T>>::exists(&vote_for),
+            <ApplicantStakes<T>>::contains_key(&vote_for),
             "vote for non-applicant not allowed"
         );
 
@@ -799,6 +816,7 @@ decl_module! {
 
         // Member can apply during announcing stage only. On first call a minimum stake will need to be provided.
         // Member can make subsequent calls during announcing stage to increase their stake.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn apply(origin, stake: BalanceOf<T>) {
             let sender = ensure_signed(origin)?;
             ensure!(Self::can_participate(&sender), "Only members can apply to be on council");
@@ -813,7 +831,7 @@ decl_module! {
             ensure!(is_announcing, "election not in announcing stage");
 
             // minimum stake on first attempt to apply
-            if !<ApplicantStakes<T>>::exists(&sender) {
+            if !<ApplicantStakes<T>>::contains_key(&sender) {
                 ensure!(stake >= Self::min_council_stake(), "minimum stake must be provided");
             }
 
@@ -822,6 +840,7 @@ decl_module! {
             Self::deposit_event(RawEvent::Applied(sender));
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         fn vote(origin, commitment: T::Hash, stake: BalanceOf<T>) {
             let sender = ensure_signed(origin)?;
             ensure!(Self::can_participate(&sender), "Only members can vote for an applicant");
@@ -840,6 +859,7 @@ decl_module! {
             Self::deposit_event(RawEvent::Voted(sender, commitment));
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         fn reveal(origin, commitment: T::Hash, vote: T::AccountId, salt: Vec<u8>) {
             let sender = ensure_signed(origin)?;
 
@@ -858,18 +878,21 @@ decl_module! {
             Self::deposit_event(RawEvent::Revealed(sender, commitment, vote));
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         fn set_stage_announcing(origin, ends_at: T::BlockNumber) {
             ensure_root(origin)?;
             ensure!(ends_at > <system::Module<T>>::block_number(), "must end at future block number");
             <Stage<T>>::put(ElectionStage::Announcing(ends_at));
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         fn set_stage_revealing(origin, ends_at: T::BlockNumber) {
             ensure_root(origin)?;
             ensure!(ends_at > <system::Module<T>>::block_number(), "must end at future block number");
             <Stage<T>>::put(ElectionStage::Revealing(ends_at));
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         fn set_stage_voting(origin, ends_at: T::BlockNumber) {
             ensure_root(origin)?;
             ensure!(ends_at > <system::Module<T>>::block_number(), "must end at future block number");
@@ -881,6 +904,7 @@ decl_module! {
         /// The call will fail if an election is in progress. If a council is not being elected for some
         /// reaon after multiple rounds, force_stop_election() can be called to stop elections and followed by
         /// set_election_parameters().
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_election_parameters(origin, params: ElectionParameters<BalanceOf<T>, T::BlockNumber>) {
             ensure_root(origin)?;
             ensure!(!Self::is_election_running(), MSG_CANNOT_CHANGE_PARAMS_DURING_ELECTION);
@@ -888,6 +912,7 @@ decl_module! {
             Self::set_verified_election_parameters(params);
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         fn force_stop_election(origin) {
             ensure_root(origin)?;
             ensure!(Self::is_election_running(), "only running election can be stopped");
@@ -907,16 +932,17 @@ decl_module! {
             );
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn force_start_election(origin) {
             ensure_root(origin)?;
             Self::start_election(<council::Module<T>>::active_council())?;
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         fn set_auto_start (origin, flag: bool) {
             ensure_root(origin)?;
             AutoStart::put(flag);
         }
-
     }
 }
 
@@ -933,7 +959,9 @@ mod tests {
     use super::*;
     use crate::mock::*;
     use codec::Encode;
-    use srml_support::*;
+    use frame_support::traits::OnFinalize;
+    use frame_support::{assert_err, assert_ok};
+    use system::RawOrigin;
 
     #[test]
     fn election_starts_when_council_term_ends() {
@@ -1344,12 +1372,12 @@ mod tests {
             assert_eq!(Balances::free_balance(&1), 1000);
 
             //assert_eq!(Election::applicant_stakes(2), Default::default());
-            assert!(!<ApplicantStakes<Test>>::exists(2));
+            assert!(!<ApplicantStakes<Test>>::contains_key(2));
             assert_eq!(Election::transferable_stakes(2).seat, 400);
             assert_eq!(Balances::free_balance(&2), 2300);
 
             //assert_eq!(Election::applicant_stakes(3), Default::default());
-            assert!(!<ApplicantStakes<Test>>::exists(3));
+            assert!(!<ApplicantStakes<Test>>::contains_key(3));
             assert_eq!(Election::transferable_stakes(3).seat, 600);
             assert_eq!(Balances::free_balance(&3), 3500);
         });
@@ -1432,7 +1460,7 @@ mod tests {
 
             assert!(Election::try_add_vote(20, 1000, commitment).is_err());
             assert_eq!(Election::commitments(), vec![]);
-            assert!(!<Votes<Test>>::exists(commitment));
+            assert!(!<Votes<Test>>::contains_key(commitment));
             assert_eq!(Balances::free_balance(&20), 100);
         });
     }
@@ -1634,7 +1662,7 @@ mod tests {
 
     pub fn mock_votes(
         mock: Vec<(u64, u64, u64, u64)>,
-    ) -> Vec<SealedVote<u64, Stake<u64>, primitives::H256, u64>> {
+    ) -> Vec<SealedVote<u64, Stake<u64>, sp_core::H256, u64>> {
         let commitment = make_commitment_for_applicant(1, &mut vec![0u8]);
 
         mock.into_iter()
@@ -1806,7 +1834,7 @@ mod tests {
 
             // applicant dropped
             assert_eq!(Election::applicants(), vec![200, 300]);
-            assert!(!<ApplicantStakes<Test>>::exists(100));
+            assert!(!<ApplicantStakes<Test>>::contains_key(100));
 
             // and refunded
             assert_eq!(Election::transferable_stakes(100).seat, 150);
@@ -2095,7 +2123,7 @@ mod tests {
             };
 
             assert_ok!(Election::set_election_parameters(
-                Origin::ROOT,
+                RawOrigin::Root.into(),
                 new_parameters
             ));
 

+ 9 - 6
runtime-modules/governance/src/election_params.rs

@@ -1,8 +1,11 @@
-use codec::{Decode, Encode};
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
-use sr_primitives::traits::Zero;
-use srml_support::{dispatch::Result, ensure};
+
+use codec::{Decode, Encode};
+use frame_support::ensure;
+use sp_arithmetic::traits::Zero;
+
+use crate::DispatchResult;
 
 pub static MSG_PERIOD_CANNOT_BE_ZERO: &str = "PeriodCannotBeZero";
 pub static MSG_COUNCIL_SIZE_CANNOT_BE_ZERO: &str = "CouncilSizeCannotBeZero";
@@ -24,20 +27,20 @@ pub struct ElectionParameters<Balance, BlockNumber> {
 }
 
 impl<Balance, BlockNumber: PartialOrd + Zero> ElectionParameters<Balance, BlockNumber> {
-    pub fn ensure_valid(&self) -> Result {
+    pub fn ensure_valid(&self) -> DispatchResult {
         self.ensure_periods_are_valid()?;
         self.ensure_council_size_and_candidacy_limit_are_valid()?;
         Ok(())
     }
 
-    fn ensure_periods_are_valid(&self) -> Result {
+    fn ensure_periods_are_valid(&self) -> DispatchResult {
         ensure!(!self.announcing_period.is_zero(), MSG_PERIOD_CANNOT_BE_ZERO);
         ensure!(!self.voting_period.is_zero(), MSG_PERIOD_CANNOT_BE_ZERO);
         ensure!(!self.revealing_period.is_zero(), MSG_PERIOD_CANNOT_BE_ZERO);
         Ok(())
     }
 
-    fn ensure_council_size_and_candidacy_limit_are_valid(&self) -> Result {
+    fn ensure_council_size_and_candidacy_limit_are_valid(&self) -> DispatchResult {
         ensure!(self.council_size > 0, MSG_COUNCIL_SIZE_CANNOT_BE_ZERO);
         ensure!(
             self.council_size <= self.candidacy_limit,

+ 4 - 0
runtime-modules/governance/src/lib.rs

@@ -9,3 +9,7 @@ mod sealed_vote;
 mod stake;
 
 mod mock;
+
+//TODO: Convert errors to the Substrate decl_error! macro.
+/// Result with string error message. This exists for backward compatibility purpose.
+pub type DispatchResult = Result<(), &'static str>;

+ 21 - 27
runtime-modules/governance/src/mock.rs

@@ -2,17 +2,15 @@
 
 pub use super::{council, election};
 pub use common::currency::GovernanceCurrency;
-pub use system;
 
-pub use primitives::{Blake2Hasher, H256};
-pub use sr_primitives::{
-    testing::{Digest, DigestItem, Header, UintAuthorityId},
-    traits::{BlakeTwo256, Convert, IdentityLookup, OnFinalize},
-    weights::Weight,
-    BuildStorage, Perbill,
+use frame_support::{impl_outer_origin, parameter_types};
+use sp_core::H256;
+use sp_runtime::{
+    testing::Header,
+    traits::{BlakeTwo256, IdentityLookup},
+    Perbill,
 };
-
-use srml_support::{impl_outer_origin, parameter_types};
+pub use system;
 
 impl_outer_origin! {
     pub enum Origin for Test {}
@@ -30,10 +28,11 @@ parameter_types! {
 }
 
 impl system::Trait for Test {
+    type BaseCallFilter = ();
     type Origin = Origin;
+    type Call = ();
     type Index = u64;
     type BlockNumber = u64;
-    type Call = ();
     type Hash = H256;
     type Hashing = BlakeTwo256;
     type AccountId = u64;
@@ -42,12 +41,20 @@ impl system::Trait for Test {
     type Event = ();
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
-impl timestamp::Trait for Test {
+impl pallet_timestamp::Trait for Test {
     type Moment = u64;
     type OnTimestampSet = ();
     type MinimumPeriod = MinimumPeriod;
@@ -80,27 +87,14 @@ impl recurringrewards::Trait for Test {
 }
 parameter_types! {
     pub const ExistentialDeposit: u32 = 0;
-    pub const TransferFee: u32 = 0;
-    pub const CreationFee: u32 = 0;
-    pub const TransactionBaseFee: u32 = 1;
-    pub const TransactionByteFee: u32 = 0;
 }
 
 impl balances::Trait for Test {
-    /// The type for recording an account's balance.
     type Balance = u64;
-    /// What to do if an account's free balance gets zeroed.
-    type OnFreeBalanceZero = ();
-    /// What to do if a new account is created.
-    type OnNewAccount = ();
-    /// The ubiquitous event type.
-    type Event = ();
-
     type DustRemoval = ();
-    type TransferPayment = ();
+    type Event = ();
     type ExistentialDeposit = ExistentialDeposit;
-    type TransferFee = TransferFee;
-    type CreationFee = CreationFee;
+    type AccountStore = System;
 }
 
 impl GovernanceCurrency for Test {
@@ -111,7 +105,7 @@ impl GovernanceCurrency for Test {
 
 // This function basically just builds a genesis storage key/value store according to
 // our desired mockup.
-pub fn initial_test_ext() -> runtime_io::TestExternalities {
+pub fn initial_test_ext() -> sp_io::TestExternalities {
     let mut t = system::GenesisConfig::default()
         .build_storage::<Test>()
         .unwrap();

+ 2 - 2
runtime-modules/governance/src/sealed_vote.rs

@@ -1,6 +1,6 @@
 use codec::{Decode, Encode};
-use rstd::vec::Vec;
-use srml_support::ensure;
+use frame_support::ensure;
+use sp_std::vec::Vec;
 
 #[derive(Clone, Copy, Encode, Decode, Default)]
 pub struct SealedVote<AccountId, Stake, Hash, Vote>

+ 8 - 8
runtime-modules/governance/src/stake.rs

@@ -1,11 +1,11 @@
 use codec::{Decode, Encode};
-use rstd::cmp::Ordering;
-use sr_primitives::traits::SimpleArithmetic;
+use sp_arithmetic::traits::BaseArithmetic;
+use sp_std::cmp::Ordering;
 
 #[derive(Encode, Decode, Clone, Copy, Default, Debug)]
 pub struct Stake<Balance>
 where
-    Balance: Copy + SimpleArithmetic,
+    Balance: Copy + BaseArithmetic,
 {
     pub new: Balance,
     pub transferred: Balance,
@@ -13,7 +13,7 @@ where
 
 impl<Balance> Stake<Balance>
 where
-    Balance: Copy + SimpleArithmetic,
+    Balance: Copy + BaseArithmetic,
 {
     pub fn total(&self) -> Balance {
         self.new + self.transferred
@@ -27,25 +27,25 @@ where
     }
 }
 
-impl<T: Copy + SimpleArithmetic> PartialOrd for Stake<T> {
+impl<T: Copy + BaseArithmetic> PartialOrd for Stake<T> {
     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
         Some(self.cmp(&other))
     }
 }
 
-impl<T: Copy + SimpleArithmetic> Ord for Stake<T> {
+impl<T: Copy + BaseArithmetic> Ord for Stake<T> {
     fn cmp(&self, other: &Self) -> Ordering {
         self.total().cmp(&other.total())
     }
 }
 
-impl<T: Copy + SimpleArithmetic> PartialEq for Stake<T> {
+impl<T: Copy + BaseArithmetic> PartialEq for Stake<T> {
     fn eq(&self, other: &Self) -> bool {
         self.total() == other.total()
     }
 }
 
-impl<T: Copy + SimpleArithmetic> Eq for Stake<T> {}
+impl<T: Copy + BaseArithmetic> Eq for Stake<T> {}
 
 #[cfg(test)]
 mod tests {

+ 18 - 44
runtime-modules/hiring/Cargo.toml

@@ -1,60 +1,34 @@
 [package]
-name = 'substrate-hiring-module'
-version = '1.0.2'
+name = 'pallet-hiring'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
 [dependencies]
-hex-literal = '0.1.0'
-serde = { version = '1.0', optional = true }
-serde_derive = { version = '1.0', optional = true }
-rstd = { package = 'sr-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-runtime-primitives = { package = 'sr-primitives', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-srml-support = { package = 'srml-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-srml-support-procedural = { package = 'srml-support-procedural', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-system = { package = 'srml-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-balances = { package = 'srml-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-codec = { package = 'parity-scale-codec', version = '1.0.0', default-features = false, features = ['derive'] }
-mockall = {version = "0.7.1", optional = true}
-# https://users.rust-lang.org/t/failure-derive-compilation-error/39062
-quote = '<=1.0.2'
-
-[dependencies.stake]
-default_features = false
-package = 'substrate-stake-module'
-path = '../stake'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+stake = { package = 'pallet-stake', default-features = false, path = '../stake'}
 
 [dev-dependencies]
-runtime-io = { package = 'sr-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-primitives = { package = 'substrate-primitives', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
 mockall = "0.7.1"
-
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
 
 [features]
 default = ['std']
-test = ['mockall']
 std = [
 	'serde',
-	'serde_derive',
 	'codec/std',
-	'rstd/std',
-	'runtime-io/std',
-	'runtime-primitives/std',
-	'srml-support/std',
+	'sp-std/std',
+	'frame-support/std',
 	'system/std',
-  	'balances/std',
-	'timestamp/std',
+	'sp-arithmetic/std',
+	'sp-runtime/std',
 	'stake/std',
-]
+]

+ 2 - 2
runtime-modules/hiring/src/hiring/application.rs

@@ -1,6 +1,6 @@
 use codec::{Decode, Encode};
-use rstd::clone::Clone;
-use rstd::vec::Vec;
+use sp_std::clone::Clone;
+use sp_std::vec::Vec;
 
 use crate::hiring::StakePurpose;
 

+ 4 - 8
runtime-modules/hiring/src/hiring/opening.rs

@@ -1,7 +1,7 @@
-use rstd::clone::Clone;
-use rstd::collections::btree_set::BTreeSet;
-use rstd::prelude::*;
-use rstd::vec::Vec;
+use sp_std::clone::Clone;
+use sp_std::collections::btree_set::BTreeSet;
+use sp_std::prelude::*;
+use sp_std::vec::Vec;
 
 use codec::{Decode, Encode};
 #[cfg(feature = "std")]
@@ -191,8 +191,6 @@ pub enum OpeningStage<BlockNumber, ApplicationId> {
 
         /// Deactivated at any time for any cause.
         deactivated_application_count: u32,
-        // Removed at any time.
-        //removed_application_count: u32
     },
 }
 
@@ -401,6 +399,4 @@ pub enum ActivateOpeningAt<BlockNumber> {
 pub struct ApplicationRationingPolicy {
     /// The maximum number of applications that can be on the list at any time.
     pub max_active_applicants: u32,
-    // How applicants will be ranked, in order to respect the maximum simultaneous application limit
-    //pub applicant_ranking: ApplicationRankingPolicy
 }

+ 32 - 38
runtime-modules/hiring/src/lib.rs

@@ -18,31 +18,26 @@
 // Do not delete! Cannot be uncommented by default, because of Parity decl_module! issue.
 //#![warn(missing_docs)]
 
-// Test feature dependencies
-#[cfg(all(any(test, feature = "test"), not(target_arch = "wasm32")))]
+// Test dependencies
+#[cfg(all(test, not(target_arch = "wasm32")))]
 use mockall::predicate::*;
-#[cfg(all(any(test, feature = "test"), not(target_arch = "wasm32")))]
+#[cfg(all(test, not(target_arch = "wasm32")))]
 use mockall::*;
 
-use stake::{InitiateUnstakingError, Stake, StakeActionError, StakingError, Trait as StakeTrait};
-
 use codec::Codec;
+use frame_support::storage::IterableStorageMap;
+use frame_support::traits::{Currency, Imbalance};
+use frame_support::{decl_module, decl_storage, ensure, Parameter};
+use sp_arithmetic::traits::{BaseArithmetic, One, Zero};
+use sp_runtime::traits::{MaybeSerialize, Member};
+use sp_std::cell::RefCell;
+use sp_std::collections::btree_map::BTreeMap;
+use sp_std::collections::btree_set::BTreeSet;
+use sp_std::iter::Iterator;
+use sp_std::rc::Rc;
+use sp_std::vec::Vec;
 
-use runtime_primitives::traits::Zero;
-use runtime_primitives::traits::{MaybeSerialize, Member, One, SimpleArithmetic};
-
-use srml_support::traits::Currency;
-use srml_support::{decl_module, decl_storage, ensure, Parameter};
-
-use rstd::collections::btree_map::BTreeMap;
-use rstd::collections::btree_set::BTreeSet;
-use rstd::iter::Iterator;
-use rstd::prelude::*;
-
-use rstd::cell::RefCell;
-use rstd::rc::Rc;
-
-use crate::sr_api_hidden_includes_decl_storage::hidden_include::traits::Imbalance;
+use stake::{InitiateUnstakingError, Stake, StakeActionError, StakingError, Trait as StakeTrait};
 
 mod hiring;
 #[macro_use]
@@ -57,7 +52,7 @@ pub trait Trait: system::Trait + stake::Trait + Sized {
     /// OpeningId type
     type OpeningId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -67,7 +62,7 @@ pub trait Trait: system::Trait + stake::Trait + Sized {
     /// ApplicationId type
     type ApplicationId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -83,21 +78,23 @@ pub trait Trait: system::Trait + stake::Trait + Sized {
 
 decl_storage! {
     trait Store for Module<T: Trait> as Hiring {
-
         /// Openings.
-        pub OpeningById get(opening_by_id): linked_map T::OpeningId => Opening<BalanceOf<T>, T::BlockNumber, T::ApplicationId>;
+        pub OpeningById get(fn opening_by_id): map hasher(blake2_128_concat)
+            T::OpeningId => Opening<BalanceOf<T>, T::BlockNumber, T::ApplicationId>;
 
         /// Identifier for next opening to be added.
-        pub NextOpeningId get(next_opening_id): T::OpeningId;
+        pub NextOpeningId get(fn next_opening_id): T::OpeningId;
 
         /// Applications
-        pub ApplicationById get(application_by_id): linked_map T::ApplicationId => Application<T::OpeningId, T::BlockNumber, T::StakeId>;
+        pub ApplicationById get(fn application_by_id): map hasher(blake2_128_concat)
+            T::ApplicationId => Application<T::OpeningId, T::BlockNumber, T::StakeId>;
 
         /// Identifier for next application to be added.
-        pub NextApplicationId get(next_application_id): T::ApplicationId;
+        pub NextApplicationId get(fn next_application_id): T::ApplicationId;
 
         /// Internal purpose of given stake, i.e. fro what application, and whether for the role or for the application.
-        pub ApplicationIdByStakingId get(stake_purpose_by_staking_id): linked_map T::StakeId => T::ApplicationId;
+        pub ApplicationIdByStakingId get(fn stake_purpose_by_staking_id): map hasher(blake2_128_concat)
+            T::StakeId => T::ApplicationId;
     }
 }
 
@@ -769,14 +766,14 @@ impl<T: Trait> Module<T> {
     /// The stake, with the given id, was unstaked.
     pub fn unstaked(stake_id: T::StakeId) -> UnstakedResult {
         // Ignore unstaked
-        if !<ApplicationIdByStakingId<T>>::exists(stake_id) {
+        if !<ApplicationIdByStakingId<T>>::contains_key(stake_id) {
             return UnstakedResult::StakeIdNonExistent;
         }
 
         // Get application
         let application_id = <ApplicationIdByStakingId<T>>::get(stake_id);
 
-        assert!(<ApplicationById<T>>::exists(application_id));
+        assert!(<ApplicationById<T>>::contains_key(application_id));
 
         let application = <ApplicationById<T>>::get(application_id);
 
@@ -1005,7 +1002,7 @@ impl<T: Trait> Module<T> {
             Opening<BalanceOf<T>, T::BlockNumber, T::ApplicationId>,
         ),
     > {
-        <OpeningById<T>>::enumerate().filter_map(move |(opening_id, opening)| {
+        <OpeningById<T>>::iter().filter_map(move |(opening_id, opening)| {
             if let hiring::OpeningStage::WaitingToBegin { begins_at_block } = opening.stage {
                 if begins_at_block == now {
                     Some((opening_id, opening))
@@ -1028,7 +1025,7 @@ impl<T: Trait> Module<T> {
             (BTreeSet<T::ApplicationId>, T::BlockNumber, T::BlockNumber),
         ),
     > {
-        <OpeningById<T>>::enumerate().filter_map(move |(opening_id, opening)| {
+        <OpeningById<T>>::iter().filter_map(move |(opening_id, opening)| {
             if let hiring::OpeningStage::Active {
                 ref stage,
                 ref applications_added,
@@ -1282,7 +1279,7 @@ impl<T: Trait> Module<T> {
 
         // MUST never already be a key for new stake, false means code is broken.
         // But should we do panic in runtime? Is there safer way?
-        assert!(!<ApplicationIdByStakingId<T>>::exists(new_stake_id));
+        assert!(!<ApplicationIdByStakingId<T>>::contains_key(new_stake_id));
 
         <ApplicationIdByStakingId<T>>::insert(new_stake_id, application_id);
 
@@ -1476,10 +1473,7 @@ impl<T: Trait> Module<T> {
  */
 
 /// Defines stake module interface
-#[cfg_attr(
-    all(any(test, feature = "test"), not(target_arch = "wasm32")),
-    automock
-)]
+#[cfg_attr(all(test, not(target_arch = "wasm32")), automock)]
 pub trait StakeHandler<T: StakeTrait> {
     /// Adds a new Stake which is NotStaked, created at given block, into stakes map.
     fn create_stake(&self) -> T::StakeId;
@@ -1536,7 +1530,7 @@ impl<T: Trait> StakeHandler<T> for HiringStakeHandler {
     }
 
     fn stake_exists(&self, stake_id: T::StakeId) -> bool {
-        <stake::Stakes<T>>::exists(stake_id)
+        <stake::Stakes<T>>::contains_key(stake_id)
     }
 
     fn get_stake(&self, stake_id: T::StakeId) -> Stake<T::BlockNumber, BalanceOf<T>, T::SlashId> {

+ 1 - 1
runtime-modules/hiring/src/macroes.rs

@@ -10,7 +10,7 @@ macro_rules! ensure_eq {
 /// Ensure that a storage map, with a given name, has mapping for the given key value.
 macro_rules! ensure_map_key {
     ($map_variable_name:ident , $runtime_trait:tt, $key:expr, $error:expr) => {{
-        if <$map_variable_name<$runtime_trait>>::exists($key) {
+        if <$map_variable_name<$runtime_trait>>::contains_key($key) {
             let value = <$map_variable_name<$runtime_trait>>::get($key);
 
             Ok(value)

+ 25 - 30
runtime-modules/hiring/src/mock.rs

@@ -1,23 +1,21 @@
 #![cfg(test)]
 
-use primitives::H256;
-use runtime_primitives::{
+use frame_support::{impl_outer_origin, parameter_types};
+use sp_core::H256;
+use sp_runtime::{
     testing::Header,
     traits::{BlakeTwo256, IdentityLookup},
     Perbill,
 };
-use srml_support::{impl_outer_origin, parameter_types};
+use sp_std::cell::{Cell, RefCell};
+use sp_std::rc::Rc;
+use std::panic;
 
 use crate::hiring::ApplicationDeactivationCause;
 use crate::{Module, Trait};
 use balances;
 use stake;
 
-use std::cell::Cell;
-use std::cell::RefCell;
-use std::panic;
-use std::rc::Rc;
-
 impl_outer_origin! {
     pub enum Origin for Test {}
 }
@@ -27,7 +25,6 @@ parameter_types! {
     pub const MaximumBlockWeight: u32 = 1024;
     pub const MaximumBlockLength: u32 = 2 * 1024;
     pub const AvailableBlockRatio: Perbill = Perbill::one();
-    pub const MinimumPeriod: u64 = 5;
 }
 
 // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
@@ -35,10 +32,11 @@ parameter_types! {
 pub struct Test;
 
 impl system::Trait for Test {
+    type BaseCallFilter = ();
     type Origin = Origin;
+    type Call = ();
     type Index = u64;
     type BlockNumber = u64;
-    type Call = ();
     type Hash = H256;
     type Hashing = BlakeTwo256;
     type AccountId = u64;
@@ -47,44 +45,36 @@ impl system::Trait for Test {
     type Event = ();
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
 parameter_types! {
     pub const ExistentialDeposit: u32 = 100;
-    pub const TransferFee: u32 = 0;
-    pub const CreationFee: u32 = 0;
-    pub const TransactionBaseFee: u32 = 1;
-    pub const TransactionByteFee: u32 = 0;
     pub const StakePoolId: [u8; 8] = *b"joystake";
 }
 
 impl balances::Trait for Test {
-    /// The type for recording an account's balance.
     type Balance = u64;
-    /// What to do if an account's free balance gets zeroed.
-    type OnFreeBalanceZero = ();
-    /// What to do if a new account is created.
-    type OnNewAccount = ();
-    /// The ubiquitous event type.
-    type Event = ();
-
     type DustRemoval = ();
-    type TransferPayment = ();
+    type Event = ();
     type ExistentialDeposit = ExistentialDeposit;
-    type TransferFee = TransferFee;
-    type CreationFee = CreationFee;
+    type AccountStore = System;
 }
 
 impl Trait for Test {
     type OpeningId = u64;
-
     type ApplicationId = u64;
-
     type ApplicationDeactivatedHandler = TestApplicationDeactivatedHandler;
-
     type StakeHandlerProvider = TestStakeHandlerProvider;
 }
 
@@ -136,7 +126,9 @@ thread_local! {
 }
 
 // Sets stake handler implementation in hiring module. Mockall frameworks integration
-pub(crate) fn set_stake_handler_impl(mock: Rc<rstd::cell::RefCell<dyn crate::StakeHandler<Test>>>) {
+pub(crate) fn set_stake_handler_impl(
+    mock: Rc<sp_std::cell::RefCell<dyn crate::StakeHandler<Test>>>,
+) {
     // Hiring::staking.mock_safe(move || MockResult::Return(mock.clone()));
     THREAD_LOCAL_STAKE_HANDLER.with(|f| {
         *f.borrow_mut() = mock.clone();
@@ -148,7 +140,7 @@ pub(crate) fn test_expectation_and_clear_mock() {
     set_stake_handler_impl(Rc::new(RefCell::new(crate::HiringStakeHandler {})));
 }
 
-pub fn build_test_externalities() -> runtime_io::TestExternalities {
+pub fn build_test_externalities() -> sp_io::TestExternalities {
     let t = system::GenesisConfig::default()
         .build_storage::<Test>()
         .unwrap();
@@ -201,3 +193,6 @@ impl TestApplicationDeactivatedHandler {
         );
     }
 }
+
+// Test fixtures starting block.
+pub(crate) static FIRST_BLOCK_HEIGHT: <Test as system::Trait>::BlockNumber = 0;

+ 3 - 3
runtime-modules/hiring/src/test/mod.rs

@@ -8,8 +8,8 @@ use public_api::*;
 use crate::mock::Test;
 use crate::*;
 
-use rstd::cell::RefCell;
-use rstd::rc::Rc;
+use sp_std::cell::RefCell;
+use sp_std::rc::Rc;
 
 use std::panic;
 
@@ -22,6 +22,6 @@ pub(crate) type Balance =
 
 // Debug test object content. Recurring temporary usage - do not delete.
 #[allow(dead_code)]
-pub fn debug_print<T: rstd::fmt::Debug>(obj: T) {
+pub fn debug_print<T: sp_std::fmt::Debug>(obj: T) {
     println!("{:?}", obj);
 }

+ 10 - 6
runtime-modules/hiring/src/test/public_api/add_application.rs

@@ -1,6 +1,6 @@
 use crate::mock::*;
 use crate::test::*;
-use rstd::collections::btree_map::BTreeMap;
+use sp_std::collections::btree_map::BTreeMap;
 use stake::NegativeImbalance;
 
 use crate::test::public_api::*;
@@ -66,12 +66,16 @@ impl AddApplicationFixture {
             // Check next application id has been updated
             assert_eq!(Hiring::next_application_id(), expected_application_id + 1);
             // Check application exists
-            assert!(<ApplicationById<Test>>::exists(expected_application_id));
+            assert!(<ApplicationById<Test>>::contains_key(
+                expected_application_id
+            ));
         } else {
             // Check next application id has not been updated
             assert_eq!(Hiring::next_application_id(), expected_application_id);
             // Check application does not exist
-            assert!(!<ApplicationById<Test>>::exists(expected_application_id));
+            assert!(!<ApplicationById<Test>>::contains_key(
+                expected_application_id
+            ));
         };
 
         //Check application content
@@ -115,7 +119,7 @@ impl AddApplicationFixture {
             let expected_application = Application {
                 opening_id: self.opening_id,
                 application_index_in_opening: expected_application_index_in_opening,
-                add_to_opening_in_block: 1,
+                add_to_opening_in_block: 0,
                 active_role_staking_id: expected_active_role_staking_id,
                 active_application_staking_id: expected_active_application_staking_id,
                 stage: ApplicationStage::Active,
@@ -166,7 +170,7 @@ impl AddApplicationFixture {
         let expected_opening = Opening {
             stage: OpeningStage::Active {
                 stage: ActiveOpeningStage::AcceptingApplications {
-                    started_accepting_applicants_at_block: 1,
+                    started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
                 },
                 applications_added: expected_added_apps_in_opening,
                 active_application_count: expected_active_application_count,
@@ -289,7 +293,7 @@ fn add_application_succeeds_with_created_application_stake() {
 
         let stake = Hiring::staking().get_stake(application_stake_id);
         let expected_stake = stake::Stake {
-            created: 1,
+            created: FIRST_BLOCK_HEIGHT,
             staking_status: stake::StakingStatus::Staked(stake::StakedState {
                 staked_amount: 100,
                 staked_status: stake::StakedStatus::Normal,

+ 5 - 6
runtime-modules/hiring/src/test/public_api/add_opening.rs

@@ -1,4 +1,4 @@
-use crate::mock::{build_test_externalities, Hiring, Test};
+use crate::mock::{build_test_externalities, Hiring, Test, FIRST_BLOCK_HEIGHT};
 use crate::test::{BlockNumber, OpeningId};
 use crate::StakingAmountLimitMode::Exact;
 use crate::*;
@@ -6,9 +6,8 @@ use crate::{
     ActivateOpeningAt, ActiveOpeningStage, AddOpeningError, ApplicationRationingPolicy, Opening,
     OpeningStage, StakePurpose, StakingPolicy,
 };
-use rstd::collections::btree_set::BTreeSet;
+use sp_std::collections::btree_set::BTreeSet;
 
-static FIRST_BLOCK_HEIGHT: <Test as system::Trait>::BlockNumber = 1;
 pub static HUMAN_READABLE_TEXT: &[u8] = b"HUMAN_READABLE_TEXT!!!!";
 
 pub struct AddOpeningFixture<Balance> {
@@ -44,12 +43,12 @@ impl AddOpeningFixture<OpeningId> {
             // Check next opening id has been updated
             assert_eq!(Hiring::next_opening_id(), expected_opening_id + 1);
             // Check opening exists
-            assert!(<OpeningById<Test>>::exists(expected_opening_id));
+            assert!(<OpeningById<Test>>::contains_key(expected_opening_id));
         } else {
             // Check next opening id has not been updated
             assert_eq!(Hiring::next_opening_id(), expected_opening_id);
             // Check opening does not exist
-            assert!(!<OpeningById<Test>>::exists(expected_opening_id));
+            assert!(!<OpeningById<Test>>::contains_key(expected_opening_id));
         };
 
         //Check opening content
@@ -75,7 +74,7 @@ impl AddOpeningFixture<OpeningId> {
         };
 
         let expected_opening = Opening {
-            created: FIRST_BLOCK_HEIGHT,
+            created: mock::FIRST_BLOCK_HEIGHT,
             stage: expected_opening_stage,
             max_review_period_length: self.max_review_period_length,
             application_rationing_policy: self.application_rationing_policy.clone(),

+ 3 - 3
runtime-modules/hiring/src/test/public_api/begin_accepting_applications.rs

@@ -1,6 +1,6 @@
 use crate::mock::*;
 use crate::test::*;
-use rstd::collections::btree_set::BTreeSet;
+use sp_std::collections::btree_set::BTreeSet;
 
 #[test]
 fn begin_accepting_applications_fails_with_no_opening() {
@@ -42,10 +42,10 @@ fn begin_accepting_applications_succeeds() {
         let updated_opening = <OpeningById<Test>>::get(opening_id);
 
         let expected_opening_state = Opening {
-            created: 1,
+            created: FIRST_BLOCK_HEIGHT,
             stage: OpeningStage::Active {
                 stage: ActiveOpeningStage::AcceptingApplications {
-                    started_accepting_applicants_at_block: 1,
+                    started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
                 },
                 applications_added: BTreeSet::new(),
                 active_application_count: 0,

+ 2 - 2
runtime-modules/hiring/src/test/public_api/begin_review.rs

@@ -46,8 +46,8 @@ fn begin_review_succeeds() {
 
         let expected_opening_state =
             old_opening.clone_with_new_active_opening_stage(ActiveOpeningStage::ReviewPeriod {
-                started_accepting_applicants_at_block: 1,
-                started_review_period_at_block: 1,
+                started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
+                started_review_period_at_block: FIRST_BLOCK_HEIGHT,
             });
 
         assert_eq!(updated_opening, expected_opening_state);

+ 3 - 3
runtime-modules/hiring/src/test/public_api/cancel_opening.rs

@@ -2,7 +2,7 @@ use crate::mock::*;
 use crate::test::*;
 
 use crate::test::public_api::*;
-use rstd::collections::btree_map::BTreeMap;
+use sp_std::collections::btree_map::BTreeMap;
 
 /*
 Not covered:
@@ -96,7 +96,7 @@ impl CancelOpeningFixture {
                         started_accepting_applicants_at_block,
                     } => ActiveOpeningStage::Deactivated {
                         cause: OpeningDeactivationCause::CancelledAcceptingApplications,
-                        deactivated_at_block: 1,
+                        deactivated_at_block: FIRST_BLOCK_HEIGHT,
                         started_accepting_applicants_at_block,
                         started_review_period_at_block: None,
                     },
@@ -105,7 +105,7 @@ impl CancelOpeningFixture {
                         started_review_period_at_block,
                     } => ActiveOpeningStage::Deactivated {
                         cause: OpeningDeactivationCause::CancelledInReviewPeriod,
-                        deactivated_at_block: 1,
+                        deactivated_at_block: FIRST_BLOCK_HEIGHT,
                         started_accepting_applicants_at_block,
                         started_review_period_at_block: Some(started_review_period_at_block),
                     },

+ 5 - 5
runtime-modules/hiring/src/test/public_api/deactivate_application.rs

@@ -67,7 +67,7 @@ impl DeactivateApplicationFixture {
             {
                 Application {
                     stage: ApplicationStage::Unstaking {
-                        deactivation_initiated: 1,
+                        deactivation_initiated: FIRST_BLOCK_HEIGHT,
                         cause: ApplicationDeactivationCause::External,
                     },
                     ..old_application_state
@@ -75,8 +75,8 @@ impl DeactivateApplicationFixture {
             } else {
                 Application {
                     stage: ApplicationStage::Inactive {
-                        deactivation_initiated: 1,
-                        deactivated: 1,
+                        deactivation_initiated: FIRST_BLOCK_HEIGHT,
+                        deactivated: FIRST_BLOCK_HEIGHT,
                         cause: ApplicationDeactivationCause::External,
                     },
                     ..old_application_state
@@ -98,7 +98,7 @@ impl DeactivateApplicationFixture {
         // invalid opening stages are not supported
 
         // check for opening existence
-        if !<OpeningById<Test>>::exists(opening_id) {
+        if !<OpeningById<Test>>::contains_key(opening_id) {
             return;
         }
 
@@ -131,7 +131,7 @@ impl DeactivateApplicationFixture {
                 let expected_opening = Opening {
                     stage: OpeningStage::Active {
                         stage: ActiveOpeningStage::AcceptingApplications {
-                            started_accepting_applicants_at_block: 1,
+                            started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
                         },
                         applications_added,
                         active_application_count: expected_active_application_count,

+ 4 - 4
runtime-modules/hiring/src/test/public_api/ensure_can_add_application.rs

@@ -2,7 +2,7 @@ use crate::mock::*;
 use crate::test::*;
 
 use crate::hiring::*;
-use rstd::collections::btree_set::BTreeSet;
+use sp_std::collections::btree_set::BTreeSet;
 
 #[test]
 fn ensure_can_add_application_fails_with_no_opening() {
@@ -239,10 +239,10 @@ fn ensure_can_add_application_succeeds() {
             ensure_can_add_application_result,
             Ok(DestructuredApplicationCanBeAddedEvaluation {
                 opening: Opening {
-                    created: 1,
+                    created: FIRST_BLOCK_HEIGHT,
                     stage: hiring::OpeningStage::Active {
                         stage: hiring::ActiveOpeningStage::AcceptingApplications {
-                            started_accepting_applicants_at_block: 1
+                            started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT
                         },
                         applications_added: BTreeSet::new(),
                         active_application_count: 0,
@@ -266,7 +266,7 @@ fn ensure_can_add_application_succeeds() {
                     human_readable_text: HUMAN_READABLE_TEXT.to_vec()
                 },
                 active_stage: hiring::ActiveOpeningStage::AcceptingApplications {
-                    started_accepting_applicants_at_block: 1
+                    started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT
                 },
                 applications_added: BTreeSet::new(),
                 active_application_count: 0,

+ 5 - 5
runtime-modules/hiring/src/test/public_api/fill_opening.rs

@@ -2,8 +2,8 @@ use crate::mock::*;
 use crate::test::*;
 
 use crate::test::public_api::*;
-use rstd::collections::btree_set::BTreeSet;
-use rstd::result::Result;
+use sp_std::collections::btree_set::BTreeSet;
+use sp_std::result::Result;
 
 /*
 Not covered:
@@ -89,9 +89,9 @@ impl FillOpeningFixture {
                 // compose expected stage
                 let expected_active_stage = ActiveOpeningStage::Deactivated {
                     cause: OpeningDeactivationCause::Filled,
-                    deactivated_at_block: 1,
-                    started_accepting_applicants_at_block: 1,
-                    started_review_period_at_block: Some(1),
+                    deactivated_at_block: FIRST_BLOCK_HEIGHT,
+                    started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
+                    started_review_period_at_block: Some(FIRST_BLOCK_HEIGHT),
                 };
 
                 // calculate application counters

+ 4 - 4
runtime-modules/hiring/src/test/public_api/mod.rs

@@ -15,9 +15,9 @@ pub use add_opening::{AddOpeningFixture, HUMAN_READABLE_TEXT};
 pub use deactivate_application::DeactivateApplicationFixture;
 
 use crate::mock::Test;
-use rstd::cell::RefCell;
-use rstd::collections::btree_map::BTreeMap;
-use rstd::rc::Rc;
+use sp_std::cell::RefCell;
+use sp_std::collections::btree_map::BTreeMap;
+use sp_std::rc::Rc;
 
 fn default_mock_for_creating_stake() -> Rc<RefCell<crate::MockStakeHandler<Test>>> {
     let mut mock = crate::MockStakeHandler::<Test>::new();
@@ -25,7 +25,7 @@ fn default_mock_for_creating_stake() -> Rc<RefCell<crate::MockStakeHandler<Test>
     mock.expect_stake().times(1).returning(|_, _| Ok(()));
     mock.expect_create_stake().times(1).returning(|| 0);
 
-    Rc::new(rstd::cell::RefCell::new(mock))
+    Rc::new(sp_std::cell::RefCell::new(mock))
 }
 
 fn default_mock_for_unstaking() -> Rc<RefCell<crate::MockStakeHandler<Test>>> {

+ 1 - 1
runtime-modules/hiring/src/test/public_api/on_finalize.rs

@@ -1,7 +1,7 @@
 use crate::mock::*;
 use crate::test::*;
 
-use runtime_primitives::traits::{OnFinalize, OnInitialize};
+use frame_support::traits::{OnFinalize, OnInitialize};
 
 // Recommendation from Parity on testing on_finalize
 // https://substrate.dev/docs/en/next/development/module/tests

+ 1 - 1
runtime-modules/hiring/src/test/public_api/unstaked.rs

@@ -62,7 +62,7 @@ impl UnstakedFixture {
                 {
                     let expected_application_stage = ApplicationStage::Inactive {
                         deactivation_initiated,
-                        deactivated: 1,
+                        deactivated: FIRST_BLOCK_HEIGHT,
                         cause,
                     };
 

+ 17 - 19
runtime-modules/hiring/src/test/smoke.rs

@@ -1,9 +1,7 @@
 use super::*;
 use crate::mock::*;
 
-static FIRST_BLOCK_HEIGHT: <Test as system::Trait>::BlockNumber = 1;
-
-use rstd::collections::btree_set::BTreeSet;
+use sp_std::collections::btree_set::BTreeSet;
 
 /**
 Main hiring workflow:
@@ -52,7 +50,7 @@ fn full_hiring_workflow_successful_path() {
         assert_eq!(Hiring::next_opening_id(), expected_opening_id + 1);
 
         // Check that our opening actually was added
-        assert!(<OpeningById<Test>>::exists(expected_opening_id));
+        assert!(<OpeningById<Test>>::contains_key(expected_opening_id));
 
         let found_opening = Hiring::opening_by_id(expected_opening_id);
 
@@ -90,10 +88,10 @@ fn full_hiring_workflow_successful_path() {
         let destructured_app_data = ensure_can_add_application_result.unwrap();
         let expected = DestructuredApplicationCanBeAddedEvaluation {
             opening: Opening {
-                created: 1,
+                created: FIRST_BLOCK_HEIGHT,
                 stage: OpeningStage::Active {
                     stage: ActiveOpeningStage::AcceptingApplications {
-                        started_accepting_applicants_at_block: 1,
+                        started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
                     },
                     applications_added: BTreeSet::new(),
                     active_application_count: 0,
@@ -107,7 +105,7 @@ fn full_hiring_workflow_successful_path() {
                 human_readable_text: human_readable_text.clone(),
             },
             active_stage: ActiveOpeningStage::AcceptingApplications {
-                started_accepting_applicants_at_block: 1,
+                started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
             },
             applications_added: BTreeSet::new(),
             active_application_count: 0,
@@ -136,7 +134,7 @@ fn full_hiring_workflow_successful_path() {
         let new_application_id = app_added.application_id_added;
 
         // Check that our application actually was added
-        assert!(<ApplicationById<Test>>::exists(new_application_id));
+        assert!(<ApplicationById<Test>>::contains_key(new_application_id));
 
         let new_application = Hiring::application_by_id(new_application_id);
 
@@ -146,7 +144,7 @@ fn full_hiring_workflow_successful_path() {
             Application {
                 opening_id: 0,
                 application_index_in_opening: 0,
-                add_to_opening_in_block: 1,
+                add_to_opening_in_block: FIRST_BLOCK_HEIGHT,
                 active_role_staking_id: None,
                 active_application_staking_id: None,
                 stage: ApplicationStage::Active,
@@ -169,11 +167,11 @@ fn full_hiring_workflow_successful_path() {
         assert_eq!(
             updated_opening_after_begin_review,
             Opening {
-                created: 1,
+                created: FIRST_BLOCK_HEIGHT,
                 stage: OpeningStage::Active {
                     stage: ActiveOpeningStage::ReviewPeriod {
-                        started_accepting_applicants_at_block: 1,
-                        started_review_period_at_block: 1
+                        started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
+                        started_review_period_at_block: FIRST_BLOCK_HEIGHT
                     },
                     applications_added: expected_added_apps_in_opening.clone(),
                     active_application_count: 1,
@@ -204,13 +202,13 @@ fn full_hiring_workflow_successful_path() {
         assert_eq!(
             updated_opening_fill_opening,
             Opening {
-                created: 1,
+                created: FIRST_BLOCK_HEIGHT,
                 stage: OpeningStage::Active {
                     stage: ActiveOpeningStage::Deactivated {
                         cause: OpeningDeactivationCause::Filled,
-                        deactivated_at_block: 1,
-                        started_accepting_applicants_at_block: 1,
-                        started_review_period_at_block: Some(1)
+                        deactivated_at_block: FIRST_BLOCK_HEIGHT,
+                        started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
+                        started_review_period_at_block: Some(FIRST_BLOCK_HEIGHT)
                     },
                     applications_added: expected_added_apps_in_opening,
                     active_application_count: 0,
@@ -234,12 +232,12 @@ fn full_hiring_workflow_successful_path() {
             Application {
                 opening_id: 0,
                 application_index_in_opening: 0,
-                add_to_opening_in_block: 1,
+                add_to_opening_in_block: FIRST_BLOCK_HEIGHT,
                 active_role_staking_id: None,
                 active_application_staking_id: None,
                 stage: ApplicationStage::Inactive {
-                    deactivation_initiated: 1,
-                    deactivated: 1,
+                    deactivation_initiated: FIRST_BLOCK_HEIGHT,
+                    deactivated: FIRST_BLOCK_HEIGHT,
                     cause: ApplicationDeactivationCause::Hired
                 },
                 human_readable_text: application_readable_text.clone()

+ 5 - 5
runtime-modules/hiring/src/test/staking_module/try_to_initiate_application_deactivation.rs

@@ -56,15 +56,15 @@ impl<'a> TryToInitiateApplicationDeactivationFixture<'a> {
         let expected_application_state = match result {
             ApplicationDeactivationInitiationResult::Deactivated => Application {
                 stage: ApplicationStage::Inactive {
-                    deactivation_initiated: 1,
-                    deactivated: 1,
+                    deactivation_initiated: FIRST_BLOCK_HEIGHT,
+                    deactivated: FIRST_BLOCK_HEIGHT,
                     cause: self.cause,
                 },
                 ..old_application_state
             },
             ApplicationDeactivationInitiationResult::Unstaking => Application {
                 stage: ApplicationStage::Unstaking {
-                    deactivation_initiated: 1,
+                    deactivation_initiated: FIRST_BLOCK_HEIGHT,
                     cause: self.cause,
                 },
                 ..old_application_state
@@ -84,7 +84,7 @@ impl<'a> TryToInitiateApplicationDeactivationFixture<'a> {
         // invalid opening stages are not supported
 
         // check for opening existence
-        if !<OpeningById<Test>>::exists(opening_id) {
+        if !<OpeningById<Test>>::contains_key(opening_id) {
             return;
         }
 
@@ -118,7 +118,7 @@ impl<'a> TryToInitiateApplicationDeactivationFixture<'a> {
                 let expected_opening = Opening {
                     stage: OpeningStage::Active {
                         stage: ActiveOpeningStage::AcceptingApplications {
-                            started_accepting_applicants_at_block: 1,
+                            started_accepting_applicants_at_block: FIRST_BLOCK_HEIGHT,
                         },
                         applications_added,
                         active_application_count: expected_active_application_count,

+ 1 - 1
runtime-modules/hiring/src/test/staking_module/would_application_get_added.rs

@@ -108,7 +108,7 @@ fn would_application_get_added_with_too_low_stake_with_mocks() {
                     }),
                 });
 
-                Rc::new(rstd::cell::RefCell::new(mock))
+                Rc::new(sp_std::cell::RefCell::new(mock))
             };
 
             set_stake_handler_impl(mock.clone());

+ 26 - 74
runtime-modules/membership/Cargo.toml

@@ -1,83 +1,35 @@
 [package]
-name = 'substrate-membership-module'
-version = '1.1.0'
+name = 'pallet-membership'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
+[dependencies]
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+common = { package = 'pallet-common', default-features = false, path = '../common'}
+
+[dev-dependencies]
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+
 [features]
 default = ['std']
 std = [
-	'sr-primitives/std',
-	'srml-support/std',
-	'system/std',
-	'rstd/std',
-	'codec/std',
 	'serde',
-	'timestamp/std',
-	'primitives/std',
+	'codec/std',
+	'frame-support/std',
+	'system/std',
+	'sp-std/std',
+	'sp-arithmetic/std',
+	'sp-runtime/std',
+	'pallet-timestamp/std',
 	'common/std',
-]
-
-[dependencies.sr-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.srml-support]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-support'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.system]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-system'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.rstd]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-std'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dependencies.serde]
-features = ['derive']
-optional = true
-version = '1.0.101'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.common]
-default_features = false
-package = 'substrate-common-module'
-path = '../common'
-
-[dev-dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dev-dependencies.balances]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-balances'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
+]

+ 0 - 1
runtime-modules/membership/src/genesis.rs

@@ -1,7 +1,6 @@
 #![cfg(test)]
 
 use common::currency::BalanceOf;
-use rstd::prelude::*;
 
 use crate::{GenesisConfig, Trait};
 

+ 64 - 43
runtime-modules/membership/src/lib.rs

@@ -10,21 +10,27 @@ pub(crate) mod mock;
 mod tests;
 
 use codec::{Codec, Decode, Encode};
-use rstd::borrow::ToOwned;
-use rstd::prelude::*;
-use sr_primitives::traits::{MaybeSerialize, Member, One, SimpleArithmetic};
-use srml_support::traits::Currency;
-use srml_support::{decl_event, decl_module, decl_storage, dispatch, ensure, Parameter};
-use system::{self, ensure_root, ensure_signed};
+use frame_support::traits::Currency;
+use frame_support::{decl_event, decl_module, decl_storage, ensure, Parameter};
+use sp_arithmetic::traits::{BaseArithmetic, One};
+use sp_runtime::traits::{MaybeSerialize, Member};
+use sp_std::borrow::ToOwned;
+use sp_std::vec;
+use sp_std::vec::Vec;
+use system::{ensure_root, ensure_signed};
 
 use common::currency::{BalanceOf, GovernanceCurrency};
 
-pub trait Trait: system::Trait + GovernanceCurrency + timestamp::Trait {
+//TODO: Convert errors to the Substrate decl_error! macro.
+/// Result with string error message. This exists for backward compatibility purpose.
+pub type DispatchResult = Result<(), &'static str>;
+
+pub trait Trait: system::Trait + GovernanceCurrency + pallet_timestamp::Trait {
     type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
 
     type MemberId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -33,7 +39,7 @@ pub trait Trait: system::Trait + GovernanceCurrency + timestamp::Trait {
 
     type PaidTermId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -42,7 +48,7 @@ pub trait Trait: system::Trait + GovernanceCurrency + timestamp::Trait {
 
     type SubscriptionId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -52,7 +58,7 @@ pub trait Trait: system::Trait + GovernanceCurrency + timestamp::Trait {
     /// Describes the common type for the working group members (workers).
     type ActorId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -61,10 +67,10 @@ pub trait Trait: system::Trait + GovernanceCurrency + timestamp::Trait {
         + Ord;
 }
 
-const FIRST_PAID_TERMS_ID: u32 = 1;
+const FIRST_PAID_TERMS_ID: u8 = 1;
 
 // Default paid membership terms
-pub const DEFAULT_PAID_TERM_ID: u32 = 0;
+pub const DEFAULT_PAID_TERM_ID: u8 = 0;
 
 // Default user info constraints
 const DEFAULT_MIN_HANDLE_LENGTH: u32 = 5;
@@ -75,7 +81,7 @@ const DEFAULT_MAX_ABOUT_TEXT_LENGTH: u32 = 2048;
 /// Public membership object alias.
 pub type Membership<T> = MembershipObject<
     <T as system::Trait>::BlockNumber,
-    <T as timestamp::Trait>::Moment,
+    <T as pallet_timestamp::Trait>::Moment,
     <T as Trait>::PaidTermId,
     <T as Trait>::SubscriptionId,
     <T as system::Trait>::AccountId,
@@ -154,27 +160,32 @@ decl_storage! {
     trait Store for Module<T: Trait> as Membership {
         /// MemberId to assign to next member that is added to the registry, and is also the
         /// total number of members created. MemberIds start at Zero.
-        pub NextMemberId get(members_created) : T::MemberId;
+        pub NextMemberId get(fn members_created) : T::MemberId;
 
         /// Mapping of member's id to their membership profile
-        pub MembershipById get(membership) : map T::MemberId => Membership<T>;
+        pub MembershipById get(fn membership) : map hasher(blake2_128_concat)
+            T::MemberId => Membership<T>;
 
         /// Mapping of a root account id to vector of member ids it controls.
-        pub(crate) MemberIdsByRootAccountId : map T::AccountId => Vec<T::MemberId>;
+        pub(crate) MemberIdsByRootAccountId : map hasher(blake2_128_concat)
+            T::AccountId => Vec<T::MemberId>;
 
         /// Mapping of a controller account id to vector of member ids it controls
-        pub(crate) MemberIdsByControllerAccountId : map T::AccountId => Vec<T::MemberId>;
+        pub(crate) MemberIdsByControllerAccountId : map hasher(blake2_128_concat)
+            T::AccountId => Vec<T::MemberId>;
 
         /// Registered unique handles and their mapping to their owner
-        pub MemberIdByHandle get(handles) : map Vec<u8> => T::MemberId;
+        pub MemberIdByHandle get(fn handles) : map hasher(blake2_128_concat)
+            Vec<u8> => T::MemberId;
 
         /// Next paid membership terms id
-        pub NextPaidMembershipTermsId get(next_paid_membership_terms_id) : T::PaidTermId = T::PaidTermId::from(FIRST_PAID_TERMS_ID);
+        pub NextPaidMembershipTermsId get(fn next_paid_membership_terms_id) :
+            T::PaidTermId = T::PaidTermId::from(FIRST_PAID_TERMS_ID);
 
         /// Paid membership terms record
         // Remember to add _genesis_phantom_data: std::marker::PhantomData{} to membership
         // genesis config if not providing config() or extra_genesis
-        pub PaidMembershipTermsById get(paid_membership_terms_by_id) build(|config: &GenesisConfig<T>| {
+        pub PaidMembershipTermsById get(fn paid_membership_terms_by_id) build(|config: &GenesisConfig<T>| {
             // This method only gets called when initializing storage, and is
             // compiled as native code. (Will be called when building `raw` chainspec)
             // So it can't be relied upon to initialize storage for runtimes updates.
@@ -184,22 +195,23 @@ decl_storage! {
                 text: Vec::default(),
             };
             vec![(T::PaidTermId::from(DEFAULT_PAID_TERM_ID), terms)]
-        }) : map T::PaidTermId => PaidMembershipTerms<BalanceOf<T>>;
+        }) : map hasher(blake2_128_concat) T::PaidTermId => PaidMembershipTerms<BalanceOf<T>>;
 
         /// Active Paid membership terms
-        pub ActivePaidMembershipTerms get(active_paid_membership_terms) : Vec<T::PaidTermId> = vec![T::PaidTermId::from(DEFAULT_PAID_TERM_ID)];
+        pub ActivePaidMembershipTerms get(fn active_paid_membership_terms) :
+            Vec<T::PaidTermId> = vec![T::PaidTermId::from(DEFAULT_PAID_TERM_ID)];
 
         /// Is the platform is accepting new members or not
-        pub NewMembershipsAllowed get(new_memberships_allowed) : bool = true;
+        pub NewMembershipsAllowed get(fn new_memberships_allowed) : bool = true;
 
-        pub ScreeningAuthority get(screening_authority) : T::AccountId;
+        pub ScreeningAuthority get(fn screening_authority) : T::AccountId;
 
         // User Input Validation parameters - do these really need to be state variables
         // I don't see a need to adjust these in future?
-        pub MinHandleLength get(min_handle_length) : u32 = DEFAULT_MIN_HANDLE_LENGTH;
-        pub MaxHandleLength get(max_handle_length) : u32 = DEFAULT_MAX_HANDLE_LENGTH;
-        pub MaxAvatarUriLength get(max_avatar_uri_length) : u32 = DEFAULT_MAX_AVATAR_URI_LENGTH;
-        pub MaxAboutTextLength get(max_about_text_length) : u32 = DEFAULT_MAX_ABOUT_TEXT_LENGTH;
+        pub MinHandleLength get(fn min_handle_length) : u32 = DEFAULT_MIN_HANDLE_LENGTH;
+        pub MaxHandleLength get(fn max_handle_length) : u32 = DEFAULT_MAX_HANDLE_LENGTH;
+        pub MaxAvatarUriLength get(fn max_avatar_uri_length) : u32 = DEFAULT_MAX_AVATAR_URI_LENGTH;
+        pub MaxAboutTextLength get(fn max_about_text_length) : u32 = DEFAULT_MAX_ABOUT_TEXT_LENGTH;
 
     }
     add_extra_genesis {
@@ -238,6 +250,7 @@ decl_module! {
         fn deposit_event() = default;
 
         /// Non-members can buy membership
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn buy_membership(
             origin,
             paid_terms_id: T::PaidTermId,
@@ -268,6 +281,7 @@ decl_module! {
         }
 
         /// Change member's about text
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn change_member_about_text(origin, member_id: T::MemberId, text: Vec<u8>) {
             let sender = ensure_signed(origin)?;
 
@@ -279,6 +293,7 @@ decl_module! {
         }
 
         /// Change member's avatar
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn change_member_avatar(origin, member_id: T::MemberId, uri: Vec<u8>) {
             let sender = ensure_signed(origin)?;
 
@@ -291,6 +306,7 @@ decl_module! {
 
         /// Change member's handle. Will ensure new handle is unique and old one will be available
         /// for other members to use.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn change_member_handle(origin, member_id: T::MemberId, handle: Vec<u8>) {
             let sender = ensure_signed(origin)?;
 
@@ -302,6 +318,7 @@ decl_module! {
         }
 
         /// Update member's all or some of handle, avatar and about text.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn update_membership(
             origin,
             member_id: T::MemberId,
@@ -326,6 +343,7 @@ decl_module! {
             }
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_controller_account(origin, member_id: T::MemberId, new_controller_account: T::AccountId) {
             let sender = ensure_signed(origin)?;
 
@@ -349,6 +367,7 @@ decl_module! {
             }
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_root_account(origin, member_id: T::MemberId, new_root_account: T::AccountId) {
             let sender = ensure_signed(origin)?;
 
@@ -371,6 +390,7 @@ decl_module! {
             }
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn add_screened_member(
             origin,
             new_member_account: T::AccountId,
@@ -385,7 +405,7 @@ decl_module! {
                 ensure!(sender == Self::screening_authority(), "not screener");
             } else {
                 // no screening authority defined. Cannot accept this request
-                return Err("no screening authority defined");
+                return Err("no screening authority defined".into());
             }
 
             // make sure we are accepting new memberships
@@ -401,6 +421,7 @@ decl_module! {
             Self::deposit_event(RawEvent::MemberRegistered(member_id, new_member_account));
         }
 
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_screening_authority(origin, authority: T::AccountId) {
             ensure_root(origin)?;
             <ScreeningAuthority<T>>::put(authority);
@@ -432,7 +453,7 @@ pub enum MemberRootAccountMismatch {
 impl<T: Trait> Module<T> {
     /// Provided that the member_id exists return its membership. Returns error otherwise.
     pub fn ensure_membership(id: T::MemberId) -> Result<Membership<T>, &'static str> {
-        if <MembershipById<T>>::exists(&id) {
+        if <MembershipById<T>>::contains_key(&id) {
             Ok(Self::membership(&id))
         } else {
             Err("member profile not found")
@@ -444,7 +465,7 @@ impl<T: Trait> Module<T> {
         member_id: &T::MemberId,
         account: &T::AccountId,
     ) -> Result<Membership<T>, ControllerAccountForMemberCheckFailed> {
-        if MembershipById::<T>::exists(member_id) {
+        if MembershipById::<T>::contains_key(member_id) {
             let membership = MembershipById::<T>::get(member_id);
 
             if membership.controller_account == *account {
@@ -459,8 +480,8 @@ impl<T: Trait> Module<T> {
 
     /// Returns true if account is either a member's root or controller account
     pub fn is_member_account(who: &T::AccountId) -> bool {
-        <MemberIdsByRootAccountId<T>>::exists(who)
-            || <MemberIdsByControllerAccountId<T>>::exists(who)
+        <MemberIdsByRootAccountId<T>>::contains_key(who)
+            || <MemberIdsByControllerAccountId<T>>::contains_key(who)
     }
 
     fn ensure_active_terms_id(
@@ -472,7 +493,7 @@ impl<T: Trait> Module<T> {
             "paid terms id not active"
         );
 
-        if <PaidMembershipTermsById<T>>::exists(terms_id) {
+        if <PaidMembershipTermsById<T>>::contains_key(terms_id) {
             Ok(Self::paid_membership_terms_by_id(terms_id))
         } else {
             Err("paid membership term id does not exist")
@@ -480,15 +501,15 @@ impl<T: Trait> Module<T> {
     }
 
     #[allow(clippy::ptr_arg)] // cannot change to the "&[u8]" suggested by clippy
-    fn ensure_unique_handle(handle: &Vec<u8>) -> dispatch::Result {
+    fn ensure_unique_handle(handle: &Vec<u8>) -> DispatchResult {
         ensure!(
-            !<MemberIdByHandle<T>>::exists(handle),
+            !<MemberIdByHandle<T>>::contains_key(handle),
             "handle already registered"
         );
         Ok(())
     }
 
-    fn validate_handle(handle: &[u8]) -> dispatch::Result {
+    fn validate_handle(handle: &[u8]) -> DispatchResult {
         ensure!(
             handle.len() >= Self::min_handle_length() as usize,
             "handle too short"
@@ -506,7 +527,7 @@ impl<T: Trait> Module<T> {
         text
     }
 
-    fn validate_avatar(uri: &[u8]) -> dispatch::Result {
+    fn validate_avatar(uri: &[u8]) -> DispatchResult {
         ensure!(
             uri.len() <= Self::max_avatar_uri_length() as usize,
             "avatar uri too long"
@@ -547,7 +568,7 @@ impl<T: Trait> Module<T> {
             avatar_uri: user_info.avatar_uri.clone(),
             about: user_info.about.clone(),
             registered_at_block: <system::Module<T>>::block_number(),
-            registered_at_time: <timestamp::Module<T>>::now(),
+            registered_at_time: <pallet_timestamp::Module<T>>::now(),
             entry: entry_method,
             suspended: false,
             subscription: None,
@@ -569,7 +590,7 @@ impl<T: Trait> Module<T> {
         new_member_id
     }
 
-    fn _change_member_about_text(id: T::MemberId, text: &[u8]) -> dispatch::Result {
+    fn _change_member_about_text(id: T::MemberId, text: &[u8]) -> DispatchResult {
         let mut membership = Self::ensure_membership(id)?;
         let text = Self::validate_text(text);
         membership.about = text;
@@ -578,7 +599,7 @@ impl<T: Trait> Module<T> {
         Ok(())
     }
 
-    fn _change_member_avatar(id: T::MemberId, uri: &[u8]) -> dispatch::Result {
+    fn _change_member_avatar(id: T::MemberId, uri: &[u8]) -> DispatchResult {
         let mut membership = Self::ensure_membership(id)?;
         Self::validate_avatar(uri)?;
         membership.avatar_uri = uri.to_owned();
@@ -587,7 +608,7 @@ impl<T: Trait> Module<T> {
         Ok(())
     }
 
-    fn _change_member_handle(id: T::MemberId, handle: Vec<u8>) -> dispatch::Result {
+    fn _change_member_handle(id: T::MemberId, handle: Vec<u8>) -> DispatchResult {
         let mut membership = Self::ensure_membership(id)?;
         Self::validate_handle(&handle)?;
         Self::ensure_unique_handle(&handle)?;

+ 24 - 34
runtime-modules/membership/src/mock.rs

@@ -1,19 +1,18 @@
 #![cfg(test)]
 
 pub use crate::{GenesisConfig, Trait, DEFAULT_PAID_TERM_ID};
-pub use common::currency::GovernanceCurrency;
-pub use srml_support::traits::Currency;
-pub use system;
 
-pub use primitives::{Blake2Hasher, H256};
-pub use sr_primitives::{
-    testing::{Digest, DigestItem, Header, UintAuthorityId},
-    traits::{BlakeTwo256, Convert, IdentityLookup, OnFinalize},
-    weights::Weight,
-    BuildStorage, Perbill,
+pub use frame_support::traits::Currency;
+use frame_support::{impl_outer_origin, parameter_types};
+use sp_core::H256;
+use sp_runtime::{
+    testing::Header,
+    traits::{BlakeTwo256, IdentityLookup},
+    Perbill,
 };
+pub use system;
 
-use srml_support::{impl_outer_origin, parameter_types};
+pub use common::currency::GovernanceCurrency;
 
 impl_outer_origin! {
     pub enum Origin for Test {}
@@ -31,10 +30,11 @@ parameter_types! {
 }
 
 impl system::Trait for Test {
+    type BaseCallFilter = ();
     type Origin = Origin;
+    type Call = ();
     type Index = u64;
     type BlockNumber = u64;
-    type Call = ();
     type Hash = H256;
     type Hashing = BlakeTwo256;
     type AccountId = u64;
@@ -43,12 +43,20 @@ impl system::Trait for Test {
     type Event = ();
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
-impl timestamp::Trait for Test {
+impl pallet_timestamp::Trait for Test {
     type Moment = u64;
     type OnTimestampSet = ();
     type MinimumPeriod = MinimumPeriod;
@@ -56,27 +64,14 @@ impl timestamp::Trait for Test {
 
 parameter_types! {
     pub const ExistentialDeposit: u32 = 0;
-    pub const TransferFee: u32 = 0;
-    pub const CreationFee: u32 = 0;
-    pub const TransactionBaseFee: u32 = 1;
-    pub const TransactionByteFee: u32 = 0;
 }
 
 impl balances::Trait for Test {
-    /// The type for recording an account's balance.
     type Balance = u64;
-    /// What to do if an account's free balance gets zeroed.
-    type OnFreeBalanceZero = ();
-    /// What to do if a new account is created.
-    type OnNewAccount = ();
-    /// The ubiquitous event type.
-    type Event = ();
-
     type DustRemoval = ();
-    type TransferPayment = ();
+    type Event = ();
     type ExistentialDeposit = ExistentialDeposit;
-    type TransferFee = TransferFee;
-    type CreationFee = CreationFee;
+    type AccountStore = System;
 }
 
 impl GovernanceCurrency for Test {
@@ -106,17 +101,11 @@ impl<T: Trait> Default for TestExternalitiesBuilder<T> {
 }
 
 impl<T: Trait> TestExternalitiesBuilder<T> {
-    /*
-    pub fn set_system_config(mut self, system_config: system::GenesisConfig) -> Self {
-        self.system_config = Some(system_config);
-        self
-    }
-    */
     pub fn set_membership_config(mut self, membership_config: GenesisConfig<T>) -> Self {
         self.membership_config = Some(membership_config);
         self
     }
-    pub fn build(self) -> runtime_io::TestExternalities {
+    pub fn build(self) -> sp_io::TestExternalities {
         // Add system
         let mut t = self
             .system_config
@@ -136,3 +125,4 @@ impl<T: Trait> TestExternalitiesBuilder<T> {
 
 pub type Balances = balances::Module<Test>;
 pub type Members = crate::Module<Test>;
+pub type System = system::Module<Test>;

+ 12 - 10
runtime-modules/membership/src/tests.rs

@@ -3,10 +3,10 @@
 use super::genesis;
 use super::mock::*;
 
-use srml_support::*;
+use frame_support::*;
 
 fn get_membership_by_id(member_id: u32) -> crate::Membership<Test> {
-    if <crate::MembershipById<Test>>::exists(member_id) {
+    if <crate::MembershipById<Test>>::contains_key(member_id) {
         Members::membership(member_id)
     } else {
         panic!("member profile not created");
@@ -52,15 +52,16 @@ fn get_bob_info() -> TestUserInfo {
 
 const ALICE_ACCOUNT_ID: u64 = 1;
 
-fn buy_default_membership_as_alice() -> dispatch::Result {
+fn buy_default_membership_as_alice() -> crate::DispatchResult {
     let info = get_alice_info();
     Members::buy_membership(
         Origin::signed(ALICE_ACCOUNT_ID),
-        DEFAULT_PAID_TERM_ID,
+        DEFAULT_PAID_TERM_ID as u32,
         info.handle,
         info.avatar_uri,
         info.about,
     )
+    .map_err(|err| err.into())
 }
 
 fn set_alice_free_balance(balance: u64) {
@@ -81,12 +82,13 @@ fn initial_state() {
         )
         .build()
         .execute_with(|| {
-            let default_terms =
-                if <crate::PaidMembershipTermsById<Test>>::exists(DEFAULT_PAID_TERM_ID) {
-                    Members::paid_membership_terms_by_id(DEFAULT_PAID_TERM_ID)
-                } else {
-                    panic!("default terms not initialized");
-                };
+            let default_terms = if <crate::PaidMembershipTermsById<Test>>::contains_key(
+                DEFAULT_PAID_TERM_ID as u32,
+            ) {
+                Members::paid_membership_terms_by_id(DEFAULT_PAID_TERM_ID as u32)
+            } else {
+                panic!("default terms not initialized");
+            };
 
             assert_eq!(default_terms.fee, DEFAULT_FEE);
         });

+ 14 - 48
runtime-modules/memo/Cargo.toml

@@ -1,58 +1,24 @@
 [package]
-name = 'substrate-memo-module'
-version = '1.0.0'
+name = 'pallet-memo'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
+[dependencies]
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+common = { package = 'pallet-common', default-features = false, path = '../common'}
 
 [features]
 default = ['std']
 std = [
-	'sr-primitives/std',
-	'srml-support/std',
-	'system/std',
-	'rstd/std',
 	'codec/std',
-	'serde',
+	'sp-arithmetic/std',
+	'sp-std/std',
+	'frame-support/std',
+	'system/std',
 	'common/std',
-]
-
-[dependencies.sr-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.srml-support]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-support'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.system]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-system'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.rstd]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-std'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dependencies.serde]
-features = ['derive']
-optional = true
-version = '1.0.101'
-
-[dependencies.common]
-default_features = false
-package = 'substrate-common-module'
-path = '../common'
+]

+ 9 - 8
runtime-modules/memo/src/lib.rs

@@ -1,13 +1,13 @@
 // Ensure we're `no_std` when compiling for Wasm.
 #![cfg_attr(not(feature = "std"), no_std)]
 
-use common::currency::GovernanceCurrency;
-use rstd::prelude::*;
-use sr_primitives::traits::Zero;
-use srml_support::traits::Currency;
-use srml_support::{decl_event, decl_module, decl_storage, ensure};
+use frame_support::traits::Currency;
+use frame_support::{decl_event, decl_module, decl_storage, ensure};
+use sp_arithmetic::traits::Zero;
+use sp_std::vec::Vec;
+use system::ensure_signed;
 
-use system::{self, ensure_signed};
+use common::currency::GovernanceCurrency;
 
 pub trait Trait: system::Trait + GovernanceCurrency {
     type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
@@ -17,8 +17,8 @@ pub type MemoText = Vec<u8>;
 
 decl_storage! {
     trait Store for Module<T: Trait> as Memo {
-        Memo get(memo) : map T::AccountId => MemoText;
-        MaxMemoLength get(max_memo_length) : u32 = 4096;
+        Memo get(fn memo) : map hasher(blake2_128_concat) T::AccountId => MemoText;
+        MaxMemoLength get(fn max_memo_length) : u32 = 4096;
     }
 }
 
@@ -32,6 +32,7 @@ decl_module! {
     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
         fn deposit_event() = default;
 
+        #[weight = 10_000_000] // TODO: adjust weight
         fn update_memo(origin, memo: MemoText) {
             let sender = ensure_signed(origin)?;
 

+ 47 - 171
runtime-modules/proposals/codex/Cargo.toml

@@ -1,185 +1,61 @@
 [package]
-name = 'substrate-proposals-codex-module'
-version = '2.1.0'
+name = 'pallet-proposals-codex'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
+[dependencies]
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+staking = { package = 'pallet-staking', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+membership = { package = 'pallet-membership', default-features = false, path = '../../membership'}
+stake = { package = 'pallet-stake', default-features = false, path = '../../stake'}
+governance = { package = 'pallet-governance', default-features = false, path = '../../governance'}
+hiring = { package = 'pallet-hiring', default-features = false, path = '../../hiring'}
+minting = { package = 'pallet-token-mint', default-features = false, path = '../../token-minting'}
+working-group = { package = 'pallet-working-group', default-features = false, path = '../../working-group'}
+content-working-group = { package = 'pallet-content-working-group', default-features = false, path = '../../content-working-group'}
+common = { package = 'pallet-common', default-features = false, path = '../../common'}
+proposals-engine = { package = 'pallet-proposals-engine', default-features = false, path = '../engine'}
+proposals-discussion = { package = 'pallet-proposals-discussion', default-features = false, path = '../discussion'}
+
+[dev-dependencies]
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-staking = { package = 'sp-staking', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+pallet-staking-reward-curve = { package = 'pallet-staking-reward-curve', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+recurring-rewards = { package = 'pallet-recurring-reward', default-features = false, path = '../../recurring-reward'}
+versioned-store = { package = 'pallet-versioned-store', default-features = false, path = '../../versioned-store'}
+versioned-store-permissions = { package = 'pallet-versioned-store-permissions', default-features = false, path = '../../versioned-store-permissions'}
+
 [features]
 default = ['std']
-no_std = []
 std = [
+    'serde',
     'codec/std',
-    'rstd/std',
-    'srml-support/std',
-    'primitives/std',
-    'sr-primitives/std',
+    'sp-std/std',
+    'frame-support/std',
+    'sp-arithmetic/std',
+    'sp-runtime/std',
     'system/std',
-    'timestamp/std',
     'staking/std',
-    'serde',
-    'proposal_engine/std',
-    'proposal_discussion/std',
-    'stake/std',
+    'pallet-timestamp/std',
     'balances/std',
     'membership/std',
+    'stake/std',
     'governance/std',
-    'mint/std',
-    'common/std',
-    'content_working_group/std',
-    'working_group/std',
     'hiring/std',
-]
-
-
-[dependencies.num_enum]
-default_features = false
-version = "0.4.2"
-
-[dependencies.serde]
-features = ['derive']
-optional = true
-version = '1.0.101'
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dependencies.primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.rstd]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-std'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.sr-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.srml-support]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-support'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.system]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-system'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.balances]
-package = 'srml-balances'
-default-features = false
-git = 'https://github.com/paritytech/substrate.git'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.staking]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-staking'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.stake]
-default_features = false
-package = 'substrate-stake-module'
-path = '../../stake'
-
-[dependencies.membership]
-default_features = false
-package = 'substrate-membership-module'
-path = '../../membership'
-
-[dependencies.governance]
-default_features = false
-package = 'substrate-governance-module'
-path = '../../governance'
-
-[dependencies.mint]
-default_features = false
-package = 'substrate-token-mint-module'
-path = '../../token-minting'
-
-[dependencies.proposal_engine]
-default_features = false
-package = 'substrate-proposals-engine-module'
-path = '../engine'
-
-[dependencies.proposal_discussion]
-default_features = false
-package = 'substrate-proposals-discussion-module'
-path = '../discussion'
-
-[dependencies.common]
-default_features = false
-package = 'substrate-common-module'
-path = '../../common'
-
-[dependencies.content_working_group]
-default_features = false
-package = 'substrate-content-working-group-module'
-path = '../../content-working-group'
-
-[dependencies.working_group]
-default_features = false
-package = 'substrate-working-group-module'
-path = '../../working-group'
-
-[dependencies.hiring]
-default_features = false
-package = 'substrate-hiring-module'
-path = '../../hiring'
-
-[dev-dependencies.versioned_store]
-default_features = false
-package ='substrate-versioned-store'
-path = '../../versioned-store'
-
-[dependencies.versioned_store]
-default_features = false
-package ='substrate-versioned-store'
-path = '../../versioned-store'
-
-[dev-dependencies.versioned_store_permissions]
-default_features = false
-package = 'substrate-versioned-store-permissions-module'
-path = '../../versioned-store-permissions'
-
-[dev-dependencies.recurring_rewards]
-default_features = false
-package = 'substrate-recurring-reward-module'
-path = '../../recurring-reward'
-
-[dev-dependencies.sr-staking-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-staking-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dev-dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-# don't rename the dependency it is causing some strange compiler error:
-# https://github.com/rust-lang/rust/issues/64450
-[dev-dependencies.srml-staking-reward-curve]
-package = 'srml-staking-reward-curve'
-git = 'https://github.com/paritytech/substrate.git'
-default_features = false
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
+    'minting/std',
+    'content-working-group/std',
+    'working-group/std',
+    'common/std',
+    'proposals-engine/std',
+    'proposals-discussion/std',
+]

+ 99 - 112
runtime-modules/proposals/codex/src/lib.rs

@@ -65,19 +65,19 @@ mod proposal_types;
 #[cfg(test)]
 mod tests;
 
+use frame_support::dispatch::DispatchResult;
+use frame_support::traits::{Currency, Get};
+use frame_support::{decl_error, decl_module, decl_storage, ensure, print};
+use sp_arithmetic::traits::Zero;
+use sp_std::clone::Clone;
+use sp_std::str::from_utf8;
+use sp_std::vec::Vec;
+use system::ensure_root;
+
 use common::origin::ActorOriginValidator;
 use common::working_group::WorkingGroup;
 use governance::election_params::ElectionParameters;
-use proposal_engine::ProposalParameters;
-use rstd::clone::Clone;
-use rstd::prelude::*;
-use rstd::str::from_utf8;
-use rstd::vec::Vec;
-use sr_primitives::traits::Zero;
-use srml_support::dispatch::DispatchResult;
-use srml_support::traits::{Currency, Get};
-use srml_support::{decl_error, decl_module, decl_storage, ensure, print};
-use system::ensure_root;
+use proposals_engine::ProposalParameters;
 
 pub use crate::proposal_types::{
     AddOpeningParameters, FillOpeningParameters, ProposalsConfigParameters, TerminateRoleParameters,
@@ -141,8 +141,8 @@ struct CreateProposalParameters<T: Trait> {
 /// 'Proposals codex' substrate module Trait
 pub trait Trait:
     system::Trait
-    + proposal_engine::Trait
-    + proposal_discussion::Trait
+    + proposals_engine::Trait
+    + proposals_discussion::Trait
     + membership::Trait
     + governance::election::Trait
     + content_working_group::Trait
@@ -180,7 +180,7 @@ pub type BalanceOfGovernanceCurrency<T> =
 
 /// Balance alias for token mint balance from `token mint` module. TODO: replace with BalanceOf
 pub type BalanceOfMint<T> =
-    <<T as mint::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
+    <<T as minting::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
 
 /// Negative imbalance alias for staking
 pub type NegativeImbalance<T> =
@@ -190,7 +190,7 @@ type MemberId<T> = <T as membership::Trait>::MemberId;
 
 decl_error! {
     /// Codex module predefined errors
-    pub enum Error {
+    pub enum Error for Module<T: Trait> {
         /// The size of the provided text for text proposal exceeded the limit
         TextProposalSizeExceeded,
 
@@ -253,155 +253,125 @@ decl_error! {
     }
 }
 
-impl From<system::Error> for Error {
-    fn from(error: system::Error) -> Self {
-        match error {
-            system::Error::Other(msg) => Error::Other(msg),
-            system::Error::RequireRootOrigin => Error::RequireRootOrigin,
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
-impl From<proposal_engine::Error> for Error {
-    fn from(error: proposal_engine::Error) -> Self {
-        match error {
-            proposal_engine::Error::Other(msg) => Error::Other(msg),
-            proposal_engine::Error::RequireRootOrigin => Error::RequireRootOrigin,
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
-impl From<proposal_discussion::Error> for Error {
-    fn from(error: proposal_discussion::Error) -> Self {
-        match error {
-            proposal_discussion::Error::Other(msg) => Error::Other(msg),
-            proposal_discussion::Error::RequireRootOrigin => Error::RequireRootOrigin,
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
 // Storage for the proposals codex module
 decl_storage! {
     pub trait Store for Module<T: Trait> as ProposalCodex{
         /// Map proposal id to its discussion thread id
         pub ThreadIdByProposalId get(fn thread_id_by_proposal_id):
-            map T::ProposalId => T::ThreadId;
+            map hasher(blake2_128_concat) T::ProposalId => T::ThreadId;
 
         /// Map proposal id to proposal details
         pub ProposalDetailsByProposalId get(fn proposal_details_by_proposal_id):
-            map T::ProposalId => ProposalDetailsOf<T>;
+            map hasher(blake2_128_concat) T::ProposalId => ProposalDetailsOf<T>;
 
         /// Voting period for the 'set validator count' proposal
-        pub SetValidatorCountProposalVotingPeriod get(set_validator_count_proposal_voting_period)
+        pub SetValidatorCountProposalVotingPeriod get(fn set_validator_count_proposal_voting_period)
             config(): T::BlockNumber;
 
         /// Grace period for the 'set validator count' proposal
-        pub SetValidatorCountProposalGracePeriod get(set_validator_count_proposal_grace_period)
+        pub SetValidatorCountProposalGracePeriod get(fn set_validator_count_proposal_grace_period)
             config(): T::BlockNumber;
 
         /// Voting period for the 'runtime upgrade' proposal
-        pub RuntimeUpgradeProposalVotingPeriod get(runtime_upgrade_proposal_voting_period)
+        pub RuntimeUpgradeProposalVotingPeriod get(fn runtime_upgrade_proposal_voting_period)
             config(): T::BlockNumber;
 
         /// Grace period for the 'runtime upgrade' proposal
-        pub RuntimeUpgradeProposalGracePeriod get(runtime_upgrade_proposal_grace_period)
+        pub RuntimeUpgradeProposalGracePeriod get(fn runtime_upgrade_proposal_grace_period)
             config(): T::BlockNumber;
 
         /// Voting period for the 'set election parameters' proposal
-        pub SetElectionParametersProposalVotingPeriod get(set_election_parameters_proposal_voting_period)
+        pub SetElectionParametersProposalVotingPeriod get(fn set_election_parameters_proposal_voting_period)
             config(): T::BlockNumber;
 
         /// Grace period for the 'set election parameters' proposal
-        pub SetElectionParametersProposalGracePeriod get(set_election_parameters_proposal_grace_period)
+        pub SetElectionParametersProposalGracePeriod get(fn set_election_parameters_proposal_grace_period)
             config(): T::BlockNumber;
 
         /// Voting period for the 'text' proposal
-        pub TextProposalVotingPeriod get(text_proposal_voting_period) config(): T::BlockNumber;
+        pub TextProposalVotingPeriod get(fn text_proposal_voting_period) config(): T::BlockNumber;
 
         /// Grace period for the 'text' proposal
-        pub TextProposalGracePeriod get(text_proposal_grace_period) config(): T::BlockNumber;
+        pub TextProposalGracePeriod get(fn text_proposal_grace_period) config(): T::BlockNumber;
 
         /// Voting period for the 'set content working group mint capacity' proposal
-        pub SetContentWorkingGroupMintCapacityProposalVotingPeriod get(set_content_working_group_mint_capacity_proposal_voting_period)
+        pub SetContentWorkingGroupMintCapacityProposalVotingPeriod get(fn set_content_working_group_mint_capacity_proposal_voting_period)
             config(): T::BlockNumber;
 
         /// Grace period for the 'set content working group mint capacity' proposal
-        pub SetContentWorkingGroupMintCapacityProposalGracePeriod get(set_content_working_group_mint_capacity_proposal_grace_period)
+        pub SetContentWorkingGroupMintCapacityProposalGracePeriod get(fn set_content_working_group_mint_capacity_proposal_grace_period)
             config(): T::BlockNumber;
 
         /// Voting period for the 'set lead' proposal
-        pub SetLeadProposalVotingPeriod get(set_lead_proposal_voting_period)
+        pub SetLeadProposalVotingPeriod get(fn set_lead_proposal_voting_period)
             config(): T::BlockNumber;
 
         /// Grace period for the 'set lead' proposal
-        pub SetLeadProposalGracePeriod get(set_lead_proposal_grace_period)
+        pub SetLeadProposalGracePeriod get(fn set_lead_proposal_grace_period)
             config(): T::BlockNumber;
 
         /// Voting period for the 'spending' proposal
-        pub SpendingProposalVotingPeriod get(spending_proposal_voting_period) config(): T::BlockNumber;
+        pub SpendingProposalVotingPeriod get(fn spending_proposal_voting_period) config(): T::BlockNumber;
 
         /// Grace period for the 'spending' proposal
-        pub SpendingProposalGracePeriod get(spending_proposal_grace_period) config(): T::BlockNumber;
+        pub SpendingProposalGracePeriod get(fn spending_proposal_grace_period) config(): T::BlockNumber;
 
         /// Voting period for the 'add working group opening' proposal
-        pub AddWorkingGroupOpeningProposalVotingPeriod get(add_working_group_opening_proposal_voting_period) config(): T::BlockNumber;
+        pub AddWorkingGroupOpeningProposalVotingPeriod get(fn add_working_group_opening_proposal_voting_period) config(): T::BlockNumber;
 
         /// Grace period for the 'add working group opening' proposal
-        pub AddWorkingGroupOpeningProposalGracePeriod get(add_working_group_opening_proposal_grace_period) config(): T::BlockNumber;
+        pub AddWorkingGroupOpeningProposalGracePeriod get(fn add_working_group_opening_proposal_grace_period) config(): T::BlockNumber;
 
         /// Voting period for the 'begin review working group leader applications' proposal
-        pub BeginReviewWorkingGroupLeaderApplicationsProposalVotingPeriod get(begin_review_working_group_leader_applications_proposal_voting_period) config(): T::BlockNumber;
+        pub BeginReviewWorkingGroupLeaderApplicationsProposalVotingPeriod get(fn begin_review_working_group_leader_applications_proposal_voting_period) config(): T::BlockNumber;
 
         /// Grace period for the 'begin review working group leader applications' proposal
-        pub BeginReviewWorkingGroupLeaderApplicationsProposalGracePeriod get(begin_review_working_group_leader_applications_proposal_grace_period) config(): T::BlockNumber;
+        pub BeginReviewWorkingGroupLeaderApplicationsProposalGracePeriod get(fn begin_review_working_group_leader_applications_proposal_grace_period) config(): T::BlockNumber;
 
         /// Voting period for the 'fill working group leader opening' proposal
-        pub FillWorkingGroupLeaderOpeningProposalVotingPeriod get(fill_working_group_leader_opening_proposal_voting_period) config(): T::BlockNumber;
+        pub FillWorkingGroupLeaderOpeningProposalVotingPeriod get(fn fill_working_group_leader_opening_proposal_voting_period) config(): T::BlockNumber;
 
         /// Grace period for the 'fill working group leader opening' proposal
-        pub FillWorkingGroupLeaderOpeningProposalGracePeriod get(fill_working_group_leader_opening_proposal_grace_period) config(): T::BlockNumber;
+        pub FillWorkingGroupLeaderOpeningProposalGracePeriod get(fn fill_working_group_leader_opening_proposal_grace_period) config(): T::BlockNumber;
 
         /// Voting period for the 'set working group mint capacity' proposal
-        pub SetWorkingGroupMintCapacityProposalVotingPeriod get(set_working_group_mint_capacity_proposal_voting_period)
+        pub SetWorkingGroupMintCapacityProposalVotingPeriod get(fn set_working_group_mint_capacity_proposal_voting_period)
             config(): T::BlockNumber;
 
         /// Grace period for the 'set working group mint capacity' proposal
-        pub SetWorkingGroupMintCapacityProposalGracePeriod get(set_working_group_mint_capacity_proposal_grace_period)
+        pub SetWorkingGroupMintCapacityProposalGracePeriod get(fn set_working_group_mint_capacity_proposal_grace_period)
             config(): T::BlockNumber;
 
         /// Voting period for the 'decrease working group leader stake' proposal
-        pub DecreaseWorkingGroupLeaderStakeProposalVotingPeriod get(decrease_working_group_leader_stake_proposal_voting_period)
+        pub DecreaseWorkingGroupLeaderStakeProposalVotingPeriod get(fn decrease_working_group_leader_stake_proposal_voting_period)
             config(): T::BlockNumber;
 
         /// Grace period for the 'decrease working group leader stake' proposal
-        pub DecreaseWorkingGroupLeaderStakeProposalGracePeriod get(decrease_working_group_leader_stake_proposal_grace_period)
+        pub DecreaseWorkingGroupLeaderStakeProposalGracePeriod get(fn decrease_working_group_leader_stake_proposal_grace_period)
             config(): T::BlockNumber;
 
         /// Voting period for the 'slash working group leader stake' proposal
-        pub SlashWorkingGroupLeaderStakeProposalVotingPeriod get(slash_working_group_leader_stake_proposal_voting_period)
+        pub SlashWorkingGroupLeaderStakeProposalVotingPeriod get(fn slash_working_group_leader_stake_proposal_voting_period)
             config(): T::BlockNumber;
 
         /// Grace period for the 'slash working group leader stake' proposal
-        pub SlashWorkingGroupLeaderStakeProposalGracePeriod get(slash_working_group_leader_stake_proposal_grace_period)
+        pub SlashWorkingGroupLeaderStakeProposalGracePeriod get(fn slash_working_group_leader_stake_proposal_grace_period)
             config(): T::BlockNumber;
 
         /// Voting period for the 'set working group leader reward' proposal
-        pub SetWorkingGroupLeaderRewardProposalVotingPeriod get(set_working_group_leader_reward_proposal_voting_period)
+        pub SetWorkingGroupLeaderRewardProposalVotingPeriod get(fn set_working_group_leader_reward_proposal_voting_period)
             config(): T::BlockNumber;
 
         /// Grace period for the 'set working group leader reward' proposal
-        pub SetWorkingGroupLeaderRewardProposalGracePeriod get(set_working_group_leader_reward_proposal_grace_period)
+        pub SetWorkingGroupLeaderRewardProposalGracePeriod get(fn set_working_group_leader_reward_proposal_grace_period)
             config(): T::BlockNumber;
 
         /// Voting period for the 'terminate working group leader role' proposal
-        pub TerminateWorkingGroupLeaderRoleProposalVotingPeriod get(terminate_working_group_leader_role_proposal_voting_period)
+        pub TerminateWorkingGroupLeaderRoleProposalVotingPeriod get(fn terminate_working_group_leader_role_proposal_voting_period)
             config(): T::BlockNumber;
 
         /// Grace period for the 'terminate working group leader role' proposal
-        pub TerminateWorkingGroupLeaderRoleProposalGracePeriod get(terminate_working_group_leader_role_proposal_grace_period)
+        pub TerminateWorkingGroupLeaderRoleProposalGracePeriod get(fn terminate_working_group_leader_role_proposal_grace_period)
             config(): T::BlockNumber;
     }
 }
@@ -410,7 +380,7 @@ decl_module! {
     /// Proposal codex substrate module Call
     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
         /// Predefined errors
-        type Error = Error;
+        type Error = Error<T>;
 
         /// Exports max allowed text proposal length const.
         const TextProposalMaxLength: u32 = T::TextProposalMaxLength::get();
@@ -419,6 +389,7 @@ decl_module! {
         const RuntimeUpgradeWasmProposalMaxLength: u32 = T::RuntimeUpgradeWasmProposalMaxLength::get();
 
         /// Create 'Text (signal)' proposal type.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_text_proposal(
             origin,
             member_id: MemberId<T>,
@@ -427,9 +398,9 @@ decl_module! {
             stake_balance: Option<BalanceOf<T>>,
             text: Vec<u8>,
         ) {
-            ensure!(!text.is_empty(), Error::TextProposalIsEmpty);
+            ensure!(!text.is_empty(), Error::<T>::TextProposalIsEmpty);
             ensure!(text.len() as u32 <=  T::TextProposalMaxLength::get(),
-                Error::TextProposalSizeExceeded);
+                Error::<T>::TextProposalSizeExceeded);
 
             let proposal_details = ProposalDetails::Text(text);
             let params = CreateProposalParameters{
@@ -448,6 +419,7 @@ decl_module! {
 
         /// Create 'Runtime upgrade' proposal type. Runtime upgrade can be initiated only by
         /// members from the hardcoded list `RuntimeUpgradeProposalAllowedProposers`
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_runtime_upgrade_proposal(
             origin,
             member_id: MemberId<T>,
@@ -456,9 +428,9 @@ decl_module! {
             stake_balance: Option<BalanceOf<T>>,
             wasm: Vec<u8>,
         ) {
-            ensure!(!wasm.is_empty(), Error::RuntimeProposalIsEmpty);
+            ensure!(!wasm.is_empty(), Error::<T>::RuntimeProposalIsEmpty);
             ensure!(wasm.len() as u32 <= T::RuntimeUpgradeWasmProposalMaxLength::get(),
-                Error::RuntimeProposalSizeExceeded);
+                Error::<T>::RuntimeProposalSizeExceeded);
 
             let proposal_details = ProposalDetails::RuntimeUpgrade(wasm);
             let params = CreateProposalParameters{
@@ -477,6 +449,7 @@ decl_module! {
 
         /// Create 'Set election parameters' proposal type. This proposal uses `set_election_parameters()`
         /// extrinsic from the `governance::election module`.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_set_election_parameters_proposal(
             origin,
             member_id: MemberId<T>,
@@ -506,6 +479,7 @@ decl_module! {
 
         /// Create 'Set content working group mint capacity' proposal type.
         /// This proposal uses `set_mint_capacity()` extrinsic from the `content-working-group`  module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_set_content_working_group_mint_capacity_proposal(
             origin,
             member_id: MemberId<T>,
@@ -516,7 +490,7 @@ decl_module! {
         ) {
             ensure!(
                 mint_balance <= <BalanceOfMint<T>>::from(CONTENT_WORKING_GROUP_MINT_CAPACITY_MAX_VALUE),
-                Error::InvalidContentWorkingGroupMintCapacity
+                Error::<T>::InvalidContentWorkingGroupMintCapacity
             );
 
             let proposal_details = ProposalDetails::SetContentWorkingGroupMintCapacity(mint_balance);
@@ -536,6 +510,7 @@ decl_module! {
 
         /// Create 'Spending' proposal type.
         /// This proposal uses `spend_from_council_mint()` extrinsic from the `governance::council`  module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_spending_proposal(
             origin,
             member_id: MemberId<T>,
@@ -545,10 +520,10 @@ decl_module! {
             balance: BalanceOfMint<T>,
             destination: T::AccountId,
         ) {
-            ensure!(balance != BalanceOfMint::<T>::zero(), Error::InvalidSpendingProposalBalance);
+            ensure!(balance != BalanceOfMint::<T>::zero(), Error::<T>::InvalidSpendingProposalBalance);
             ensure!(
                 balance <= <BalanceOfMint<T>>::from(MAX_SPENDING_PROPOSAL_VALUE),
-                Error::InvalidSpendingProposalBalance
+                Error::<T>::InvalidSpendingProposalBalance
             );
 
             let proposal_details = ProposalDetails::Spending(balance, destination);
@@ -568,6 +543,7 @@ decl_module! {
 
         /// Create 'Set lead' proposal type.
         /// This proposal uses `replace_lead()` extrinsic from the `content_working_group`  module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_set_lead_proposal(
             origin,
             member_id: MemberId<T>,
@@ -580,7 +556,7 @@ decl_module! {
                 let account_id = lead.1;
                 ensure!(
                     !<governance::council::Module<T>>::is_councilor(&account_id),
-                    Error::InvalidSetLeadParameterCannotBeCouncilor
+                    Error::<T>::InvalidSetLeadParameterCannotBeCouncilor
                 );
             }
             let proposal_details = ProposalDetails::SetLead(new_lead);
@@ -600,6 +576,7 @@ decl_module! {
 
         /// Create 'Evict storage provider' proposal type.
         /// This proposal uses `set_validator_count()` extrinsic from the Substrate `staking`  module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_set_validator_count_proposal(
             origin,
             member_id: MemberId<T>,
@@ -610,12 +587,12 @@ decl_module! {
         ) {
             ensure!(
                 new_validator_count >= <staking::Module<T>>::minimum_validator_count(),
-                Error::InvalidValidatorCount
+                Error::<T>::InvalidValidatorCount
             );
 
             ensure!(
                 new_validator_count <= MAX_VALIDATOR_COUNT,
-                Error::InvalidValidatorCount
+                Error::<T>::InvalidValidatorCount
             );
 
             let proposal_details = ProposalDetails::SetValidatorCount(new_validator_count);
@@ -635,6 +612,7 @@ decl_module! {
 
         /// Create 'Add working group leader opening' proposal type.
         /// This proposal uses `add_opening()` extrinsic from the Joystream `working group` module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_add_working_group_leader_opening_proposal(
             origin,
             member_id: MemberId<T>,
@@ -661,6 +639,7 @@ decl_module! {
 
         /// Create 'Begin review working group leader applications' proposal type.
         /// This proposal uses `begin_applicant_review()` extrinsic from the Joystream `working group` module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_begin_review_working_group_leader_applications_proposal(
             origin,
             member_id: MemberId<T>,
@@ -688,6 +667,7 @@ decl_module! {
 
         /// Create 'Fill working group leader opening' proposal type.
         /// This proposal uses `fill_opening()` extrinsic from the Joystream `working group` module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_fill_working_group_leader_opening_proposal(
             origin,
             member_id: MemberId<T>,
@@ -719,6 +699,7 @@ decl_module! {
 
         /// Create 'Set working group mint capacity' proposal type.
         /// This proposal uses `set_mint_capacity()` extrinsic from the `working-group`  module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_set_working_group_mint_capacity_proposal(
             origin,
             member_id: MemberId<T>,
@@ -730,7 +711,7 @@ decl_module! {
         ) {
             ensure!(
                 mint_balance <= <BalanceOfMint<T>>::from(WORKING_GROUP_MINT_CAPACITY_MAX_VALUE),
-                Error::InvalidWorkingGroupMintCapacity
+                Error::<T>::InvalidWorkingGroupMintCapacity
             );
 
             let proposal_details = ProposalDetails::SetWorkingGroupMintCapacity(mint_balance, working_group);
@@ -750,6 +731,7 @@ decl_module! {
 
         /// Create 'decrease working group leader stake' proposal type.
         /// This proposal uses `decrease_stake()` extrinsic from the `working-group`  module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_decrease_working_group_leader_stake_proposal(
             origin,
             member_id: MemberId<T>,
@@ -761,7 +743,7 @@ decl_module! {
             working_group: WorkingGroup,
         ) {
 
-            ensure!(decreasing_stake != Zero::zero(), Error::DecreasingStakeIsZero);
+            ensure!(decreasing_stake != Zero::zero(), Error::<T>::DecreasingStakeIsZero);
 
             let proposal_details = ProposalDetails::DecreaseWorkingGroupLeaderStake(
                 worker_id,
@@ -785,6 +767,7 @@ decl_module! {
 
         /// Create 'slash working group leader stake' proposal type.
         /// This proposal uses `slash_stake()` extrinsic from the `working-group`  module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_slash_working_group_leader_stake_proposal(
             origin,
             member_id: MemberId<T>,
@@ -796,7 +779,7 @@ decl_module! {
             working_group: WorkingGroup,
         ) {
 
-            ensure!(slashing_stake != Zero::zero(), Error::SlashingStakeIsZero);
+            ensure!(slashing_stake != Zero::zero(), Error::<T>::SlashingStakeIsZero);
 
             let proposal_details = ProposalDetails::SlashWorkingGroupLeaderStake(
                 worker_id,
@@ -820,6 +803,7 @@ decl_module! {
 
         /// Create 'set working group leader reward' proposal type.
         /// This proposal uses `update_reward_amount()` extrinsic from the `working-group`  module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_set_working_group_leader_reward_proposal(
             origin,
             member_id: MemberId<T>,
@@ -853,6 +837,7 @@ decl_module! {
 
         /// Create 'terminate working group leader rolw' proposal type.
         /// This proposal uses `terminate_role()` extrinsic from the `working-group`  module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn create_terminate_working_group_leader_role_proposal(
             origin,
             member_id: MemberId<T>,
@@ -881,6 +866,7 @@ decl_module! {
 // *************** Extrinsic to execute
 
         /// Text proposal extrinsic. Should be used as callable object to pass to the `engine` module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn execute_text_proposal(
             origin,
             text: Vec<u8>,
@@ -895,6 +881,7 @@ decl_module! {
 
         /// Runtime upgrade proposal extrinsic.
         /// Should be used as callable object to pass to the `engine` module.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn execute_runtime_upgrade_proposal(
             origin,
             wasm: Vec<u8>,
@@ -913,28 +900,28 @@ decl_module! {
 
 impl<T: Trait> Module<T> {
     // Generic template proposal builder
-    fn create_proposal(params: CreateProposalParameters<T>) -> DispatchResult<Error> {
+    fn create_proposal(params: CreateProposalParameters<T>) -> DispatchResult {
         let account_id =
             T::MembershipOriginValidator::ensure_actor_origin(params.origin, params.member_id)?;
 
-        <proposal_engine::Module<T>>::ensure_create_proposal_parameters_are_valid(
+        <proposals_engine::Module<T>>::ensure_create_proposal_parameters_are_valid(
             &params.proposal_parameters,
             &params.title,
             &params.description,
             params.stake_balance,
         )?;
 
-        <proposal_discussion::Module<T>>::ensure_can_create_thread(
+        <proposals_discussion::Module<T>>::ensure_can_create_thread(
             params.member_id,
             &params.title,
         )?;
 
-        let discussion_thread_id = <proposal_discussion::Module<T>>::create_thread(
+        let discussion_thread_id = <proposals_discussion::Module<T>>::create_thread(
             params.member_id,
             params.title.clone(),
         )?;
 
-        let proposal_id = <proposal_engine::Module<T>>::create_proposal(
+        let proposal_id = <proposals_engine::Module<T>>::create_proposal(
             account_id,
             params.member_id,
             params.proposal_parameters,
@@ -953,85 +940,85 @@ impl<T: Trait> Module<T> {
     // validates council election parameters for the 'Set election parameters' proposal
     pub(crate) fn ensure_council_election_parameters_valid(
         election_parameters: &ElectionParameters<BalanceOfGovernanceCurrency<T>, T::BlockNumber>,
-    ) -> Result<(), Error> {
+    ) -> DispatchResult {
         ensure!(
             election_parameters.council_size >= ELECTION_PARAMETERS_COUNCIL_SIZE_MIN_VALUE,
-            Error::InvalidCouncilElectionParameterCouncilSize
+            Error::<T>::InvalidCouncilElectionParameterCouncilSize
         );
 
         ensure!(
             election_parameters.council_size <= ELECTION_PARAMETERS_COUNCIL_SIZE_MAX_VALUE,
-            Error::InvalidCouncilElectionParameterCouncilSize
+            Error::<T>::InvalidCouncilElectionParameterCouncilSize
         );
 
         ensure!(
             election_parameters.candidacy_limit >= ELECTION_PARAMETERS_CANDIDACY_LIMIT_MIN_VALUE,
-            Error::InvalidCouncilElectionParameterCandidacyLimit
+            Error::<T>::InvalidCouncilElectionParameterCandidacyLimit
         );
 
         ensure!(
             election_parameters.candidacy_limit <= ELECTION_PARAMETERS_CANDIDACY_LIMIT_MAX_VALUE,
-            Error::InvalidCouncilElectionParameterCandidacyLimit
+            Error::<T>::InvalidCouncilElectionParameterCandidacyLimit
         );
 
         ensure!(
             election_parameters.min_voting_stake
                 >= <BalanceOfGovernanceCurrency<T>>::from(ELECTION_PARAMETERS_MIN_STAKE_MIN_VALUE),
-            Error::InvalidCouncilElectionParameterMinVotingStake
+            Error::<T>::InvalidCouncilElectionParameterMinVotingStake
         );
 
         ensure!(
             election_parameters.min_voting_stake
                 <= <BalanceOfGovernanceCurrency<T>>::from(ELECTION_PARAMETERS_MIN_STAKE_MAX_VALUE),
-            Error::InvalidCouncilElectionParameterMinVotingStake
+            Error::<T>::InvalidCouncilElectionParameterMinVotingStake
         );
 
         ensure!(
             election_parameters.new_term_duration
                 >= T::BlockNumber::from(ELECTION_PARAMETERS_NEW_TERM_DURATION_MIN_VALUE),
-            Error::InvalidCouncilElectionParameterNewTermDuration
+            Error::<T>::InvalidCouncilElectionParameterNewTermDuration
         );
 
         ensure!(
             election_parameters.new_term_duration
                 <= T::BlockNumber::from(ELECTION_PARAMETERS_NEW_TERM_DURATION_MAX_VALUE),
-            Error::InvalidCouncilElectionParameterNewTermDuration
+            Error::<T>::InvalidCouncilElectionParameterNewTermDuration
         );
 
         ensure!(
             election_parameters.revealing_period
                 >= T::BlockNumber::from(ELECTION_PARAMETERS_REVEALING_PERIOD_MIN_VALUE),
-            Error::InvalidCouncilElectionParameterRevealingPeriod
+            Error::<T>::InvalidCouncilElectionParameterRevealingPeriod
         );
 
         ensure!(
             election_parameters.revealing_period
                 <= T::BlockNumber::from(ELECTION_PARAMETERS_REVEALING_PERIOD_MAX_VALUE),
-            Error::InvalidCouncilElectionParameterRevealingPeriod
+            Error::<T>::InvalidCouncilElectionParameterRevealingPeriod
         );
 
         ensure!(
             election_parameters.voting_period
                 >= T::BlockNumber::from(ELECTION_PARAMETERS_VOTING_PERIOD_MIN_VALUE),
-            Error::InvalidCouncilElectionParameterVotingPeriod
+            Error::<T>::InvalidCouncilElectionParameterVotingPeriod
         );
 
         ensure!(
             election_parameters.voting_period
                 <= T::BlockNumber::from(ELECTION_PARAMETERS_VOTING_PERIOD_MAX_VALUE),
-            Error::InvalidCouncilElectionParameterVotingPeriod
+            Error::<T>::InvalidCouncilElectionParameterVotingPeriod
         );
 
         ensure!(
             election_parameters.announcing_period
                 >= T::BlockNumber::from(ELECTION_PARAMETERS_ANNOUNCING_PERIOD_MIN_VALUE),
-            Error::InvalidCouncilElectionParameterAnnouncingPeriod
+            Error::<T>::InvalidCouncilElectionParameterAnnouncingPeriod
         );
 
         ensure!(
             election_parameters.announcing_period
                 <= T::BlockNumber::from(ELECTION_PARAMETERS_ANNOUNCING_PERIOD_MAX_VALUE),
-            Error::InvalidCouncilElectionParameterAnnouncingPeriod
+            Error::<T>::InvalidCouncilElectionParameterAnnouncingPeriod
         );
 
         ensure!(
@@ -1039,7 +1026,7 @@ impl<T: Trait> Module<T> {
                 >= <BalanceOfGovernanceCurrency<T>>::from(
                     ELECTION_PARAMETERS_MIN_COUNCIL_STAKE_MIN_VALUE
                 ),
-            Error::InvalidCouncilElectionParameterMinCouncilStake
+            Error::<T>::InvalidCouncilElectionParameterMinCouncilStake
         );
 
         ensure!(
@@ -1047,7 +1034,7 @@ impl<T: Trait> Module<T> {
                 <= <BalanceOfGovernanceCurrency<T>>::from(
                     ELECTION_PARAMETERS_MIN_COUNCIL_STAKE_MAX_VALUE
                 ),
-            Error::InvalidCouncilElectionParameterMinCouncilStake
+            Error::<T>::InvalidCouncilElectionParameterMinCouncilStake
         );
 
         Ok(())

+ 1 - 1
runtime-modules/proposals/codex/src/proposal_types/mod.rs

@@ -3,9 +3,9 @@
 pub(crate) mod parameters;
 
 use codec::{Decode, Encode};
-use rstd::vec::Vec;
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
+use sp_std::vec::Vec;
 
 use crate::ElectionParameters;
 use common::working_group::WorkingGroup;

+ 58 - 38
runtime-modules/proposals/codex/src/tests/mock.rs

@@ -1,22 +1,20 @@
 #![cfg(test)]
-// srml_staking_reward_curve::build! - substrate macro produces a warning.
-// TODO: remove after post-Rome substrate upgrade
-#![allow(array_into_iter)]
 
-use crate::{ProposalDetailsOf, ProposalEncoder};
-pub use primitives::{Blake2Hasher, H256};
-use proposal_engine::VotersParameters;
-use sr_primitives::curve::PiecewiseLinear;
-pub use sr_primitives::{
-    testing::{Digest, DigestItem, Header, UintAuthorityId},
-    traits::{BlakeTwo256, Convert, IdentityLookup, OnFinalize},
-    weights::Weight,
-    BuildStorage, DispatchError, Perbill,
+use frame_support::{impl_outer_dispatch, impl_outer_origin, parameter_types};
+use sp_core::H256;
+use sp_runtime::curve::PiecewiseLinear;
+use sp_runtime::{
+    testing::Header,
+    traits::{BlakeTwo256, IdentityLookup},
+    Perbill,
 };
-use sr_staking_primitives::SessionIndex;
-use srml_support::{impl_outer_dispatch, impl_outer_origin, parameter_types};
+use sp_staking::SessionIndex;
 pub use system;
 
+use crate::{ProposalDetailsOf, ProposalEncoder};
+use proposals_engine::VotersParameters;
+use sp_runtime::testing::TestXt;
+
 impl_outer_origin! {
     pub enum Origin for Test {}
 }
@@ -37,6 +35,8 @@ impl_outer_dispatch! {
     pub enum Call for Test where origin: Origin {
         codex::ProposalCodex,
         proposals::ProposalsEngine,
+        staking::Staking,
+        system::System,
     }
 }
 
@@ -54,25 +54,14 @@ impl membership::Trait for Test {
 
 parameter_types! {
     pub const ExistentialDeposit: u32 = 0;
-    pub const TransferFee: u32 = 0;
-    pub const CreationFee: u32 = 0;
 }
 
 impl balances::Trait for Test {
-    /// The type for recording an account's balance.
     type Balance = u64;
-    /// What to do if an account's free balance gets zeroed.
-    type OnFreeBalanceZero = ();
-    /// What to do if a new account is created.
-    type OnNewAccount = ();
-
-    type Event = ();
-
     type DustRemoval = ();
-    type TransferPayment = ();
+    type Event = ();
     type ExistentialDeposit = ExistentialDeposit;
-    type TransferFee = TransferFee;
-    type CreationFee = CreationFee;
+    type AccountStore = System;
 }
 
 impl stake::Trait for Test {
@@ -91,13 +80,13 @@ parameter_types! {
     pub const MaxActiveProposalLimit: u32 = 100;
 }
 
-impl proposal_engine::Trait for Test {
+impl proposals_engine::Trait for Test {
     type Event = ();
     type ProposerOriginValidator = ();
     type VoterOriginValidator = ();
     type TotalVotersCounter = MockVotersParameters;
     type ProposalId = u32;
-    type StakeHandlerProvider = proposal_engine::DefaultStakeHandlerProvider;
+    type StakeHandlerProvider = proposals_engine::DefaultStakeHandlerProvider;
     type CancellationFee = CancellationFee;
     type RejectionFee = RejectionFee;
     type TitleMaxLength = TitleMaxLength;
@@ -112,7 +101,7 @@ impl Default for crate::Call<Test> {
     }
 }
 
-impl mint::Trait for Test {
+impl minting::Trait for Test {
     type Currency = Balances;
     type MintId = u64;
 }
@@ -137,7 +126,7 @@ parameter_types! {
     pub const PostLengthLimit: u32 = 2000;
 }
 
-impl proposal_discussion::Trait for Test {
+impl proposals_discussion::Trait for Test {
     type Event = ();
     type PostAuthorOriginValidator = ();
     type ThreadId = u64;
@@ -192,7 +181,7 @@ impl hiring::Trait for Test {
     type StakeHandlerProvider = hiring::Module<Self>;
 }
 
-srml_staking_reward_curve::build! {
+pallet_staking_reward_curve::build! {
     const I_NPOS: PiecewiseLinear<'static> = curve!(
         min_inflation: 0_025_000,
         max_inflation: 0_100_000,
@@ -209,8 +198,8 @@ parameter_types! {
     pub const RewardCurve: &'static PiecewiseLinear<'static> = &I_NPOS;
 }
 impl staking::Trait for Test {
-    type Currency = balances::Module<Self>;
-    type Time = timestamp::Module<Self>;
+    type Currency = Balances;
+    type UnixTime = Timestamp;
     type CurrencyToVote = ();
     type RewardRemainder = ();
     type Event = ();
@@ -218,10 +207,29 @@ impl staking::Trait for Test {
     type Reward = ();
     type SessionsPerEra = SessionsPerEra;
     type BondingDuration = BondingDuration;
+    type SlashDeferDuration = ();
+    type SlashCancelOrigin = system::EnsureRoot<Self::AccountId>;
     type SessionInterface = Self;
     type RewardCurve = RewardCurve;
+    type NextNewSession = ();
+    type ElectionLookahead = ();
+    type Call = Call;
+    type MaxIterations = ();
+    type MinSolutionScoreBump = ();
+    type MaxNominatorRewardedPerValidator = ();
+    type UnsignedPriority = ();
 }
 
+impl<LocalCall> system::offchain::SendTransactionTypes<LocalCall> for Test
+where
+    Call: From<LocalCall>,
+{
+    type OverarchingCall = Call;
+    type Extrinsic = Extrinsic;
+}
+
+pub type Extrinsic = TestXt<Call, ()>;
+
 impl staking::SessionInterface<u64> for Test {
     fn disable_validator(_: &u64) -> Result<bool, ()> {
         unimplemented!()
@@ -250,10 +258,11 @@ impl ProposalEncoder<Test> for () {
 }
 
 impl system::Trait for Test {
+    type BaseCallFilter = ();
     type Origin = Origin;
+    type Call = Call;
     type Index = u64;
     type BlockNumber = u64;
-    type Call = ();
     type Hash = H256;
     type Hashing = BlakeTwo256;
     type AccountId = u64;
@@ -262,18 +271,26 @@ impl system::Trait for Test {
     type Event = ();
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
-impl timestamp::Trait for Test {
+impl pallet_timestamp::Trait for Test {
     type Moment = u64;
     type OnTimestampSet = ();
     type MinimumPeriod = MinimumPeriod;
 }
 
-pub fn initial_test_ext() -> runtime_io::TestExternalities {
+pub fn initial_test_ext() -> sp_io::TestExternalities {
     let t = system::GenesisConfig::default()
         .build_storage::<Test>()
         .unwrap();
@@ -281,6 +298,9 @@ pub fn initial_test_ext() -> runtime_io::TestExternalities {
     t.into()
 }
 
+pub type Staking = staking::Module<Test>;
 pub type ProposalCodex = crate::Module<Test>;
-pub type ProposalsEngine = proposal_engine::Module<Test>;
+pub type ProposalsEngine = proposals_engine::Module<Test>;
 pub type Balances = balances::Module<Test>;
+pub type Timestamp = pallet_timestamp::Module<Test>;
+pub type System = system::Module<Test>;

+ 54 - 52
runtime-modules/proposals/codex/src/tests/mod.rs

@@ -1,22 +1,21 @@
 mod mock;
 
-use governance::election_params::ElectionParameters;
-use srml_support::traits::Currency;
-use srml_support::StorageMap;
+use frame_support::dispatch::{DispatchError, DispatchResult};
+use frame_support::storage::StorageMap;
+use frame_support::traits::Currency;
 use system::RawOrigin;
 
-use crate::*;
-use crate::{BalanceOf, Error, ProposalDetails};
-use proposal_engine::ProposalParameters;
-use srml_support::dispatch::DispatchResult;
-
-use crate::proposal_types::ProposalsConfigParameters;
-pub use mock::*;
-
 use common::working_group::WorkingGroup;
+use governance::election_params::ElectionParameters;
 use hiring::ActivateOpeningAt;
+use proposals_engine::ProposalParameters;
 use working_group::OpeningPolicyCommitment;
 
+use crate::proposal_types::ProposalsConfigParameters;
+use crate::*;
+use crate::{BalanceOf, Error, ProposalDetails};
+pub use mock::*;
+
 pub(crate) fn increase_total_balance_issuance(balance: u64) {
     increase_total_balance_issuance_using_account_id(999, balance);
 }
@@ -31,10 +30,10 @@ pub(crate) fn increase_total_balance_issuance_using_account_id(account_id: u64,
 
 struct ProposalTestFixture<InsufficientRightsCall, EmptyStakeCall, InvalidStakeCall, SuccessfulCall>
 where
-    InsufficientRightsCall: Fn() -> DispatchResult<crate::Error>,
-    EmptyStakeCall: Fn() -> DispatchResult<crate::Error>,
-    InvalidStakeCall: Fn() -> DispatchResult<crate::Error>,
-    SuccessfulCall: Fn() -> DispatchResult<crate::Error>,
+    InsufficientRightsCall: Fn() -> DispatchResult,
+    EmptyStakeCall: Fn() -> DispatchResult,
+    InvalidStakeCall: Fn() -> DispatchResult,
+    SuccessfulCall: Fn() -> DispatchResult,
 {
     insufficient_rights_call: InsufficientRightsCall,
     empty_stake_call: EmptyStakeCall,
@@ -47,24 +46,27 @@ where
 impl<InsufficientRightsCall, EmptyStakeCall, InvalidStakeCall, SuccessfulCall>
     ProposalTestFixture<InsufficientRightsCall, EmptyStakeCall, InvalidStakeCall, SuccessfulCall>
 where
-    InsufficientRightsCall: Fn() -> DispatchResult<crate::Error>,
-    EmptyStakeCall: Fn() -> DispatchResult<crate::Error>,
-    InvalidStakeCall: Fn() -> DispatchResult<crate::Error>,
-    SuccessfulCall: Fn() -> DispatchResult<crate::Error>,
+    InsufficientRightsCall: Fn() -> DispatchResult,
+    EmptyStakeCall: Fn() -> DispatchResult,
+    InvalidStakeCall: Fn() -> DispatchResult,
+    SuccessfulCall: Fn() -> DispatchResult,
 {
     fn check_for_invalid_stakes(&self) {
-        assert_eq!((self.empty_stake_call)(), Err(Error::Other("EmptyStake")));
+        assert_eq!(
+            (self.empty_stake_call)(),
+            Err(proposals_engine::Error::<Test>::EmptyStake.into())
+        );
 
         assert_eq!(
             (self.invalid_stake_call)(),
-            Err(Error::Other("StakeDiffersFromRequired"))
+            Err(proposals_engine::Error::<Test>::StakeDiffersFromRequired.into())
         );
     }
 
     fn check_call_for_insufficient_rights(&self) {
         assert_eq!(
             (self.insufficient_rights_call)(),
-            Err(Error::Other("RequireSignedOrigin"))
+            Err(DispatchError::Other("Bad origin"))
         );
     }
 
@@ -163,7 +165,7 @@ fn create_text_proposal_codex_call_fails_with_incorrect_text_size() {
                 None,
                 long_text,
             ),
-            Err(Error::TextProposalSizeExceeded)
+            Err(Error::<Test>::TextProposalSizeExceeded.into())
         );
 
         assert_eq!(
@@ -175,7 +177,7 @@ fn create_text_proposal_codex_call_fails_with_incorrect_text_size() {
                 None,
                 Vec::new(),
             ),
-            Err(Error::TextProposalIsEmpty)
+            Err(Error::<Test>::TextProposalIsEmpty.into())
         );
     });
 }
@@ -248,7 +250,7 @@ fn create_upgrade_runtime_proposal_codex_call_fails_with_incorrect_wasm_size() {
                 None,
                 long_wasm,
             ),
-            Err(Error::RuntimeProposalSizeExceeded)
+            Err(Error::<Test>::RuntimeProposalSizeExceeded.into())
         );
 
         assert_eq!(
@@ -260,7 +262,7 @@ fn create_upgrade_runtime_proposal_codex_call_fails_with_incorrect_wasm_size() {
                 None,
                 Vec::new(),
             ),
-            Err(Error::RuntimeProposalIsEmpty)
+            Err(Error::<Test>::RuntimeProposalIsEmpty.into())
         );
     });
 }
@@ -323,7 +325,7 @@ fn create_set_election_parameters_proposal_common_checks_succeed() {
 
 fn assert_failed_election_parameters_call(
     election_parameters: ElectionParameters<u64, u64>,
-    error: Error,
+    error: DispatchError,
 ) {
     assert_eq!(
         ProposalCodex::create_set_election_parameters_proposal(
@@ -360,111 +362,111 @@ fn create_set_election_parameters_call_fails_with_incorrect_parameters() {
         election_parameters.council_size = 2;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterCouncilSize,
+            Error::<Test>::InvalidCouncilElectionParameterCouncilSize.into(),
         );
 
         election_parameters.council_size = 21;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterCouncilSize,
+            Error::<Test>::InvalidCouncilElectionParameterCouncilSize.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.candidacy_limit = 22;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterCandidacyLimit,
+            Error::<Test>::InvalidCouncilElectionParameterCandidacyLimit.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.candidacy_limit = 122;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterCandidacyLimit,
+            Error::<Test>::InvalidCouncilElectionParameterCandidacyLimit.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.min_voting_stake = 0;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterMinVotingStake,
+            Error::<Test>::InvalidCouncilElectionParameterMinVotingStake.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.min_voting_stake = 200000;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterMinVotingStake,
+            Error::<Test>::InvalidCouncilElectionParameterMinVotingStake.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.new_term_duration = 10000;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterNewTermDuration,
+            Error::<Test>::InvalidCouncilElectionParameterNewTermDuration.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.new_term_duration = 500000;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterNewTermDuration,
+            Error::<Test>::InvalidCouncilElectionParameterNewTermDuration.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.min_council_stake = 0;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterMinCouncilStake,
+            Error::<Test>::InvalidCouncilElectionParameterMinCouncilStake.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.min_council_stake = 200000;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterMinCouncilStake,
+            Error::<Test>::InvalidCouncilElectionParameterMinCouncilStake.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.voting_period = 10000;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterVotingPeriod,
+            Error::<Test>::InvalidCouncilElectionParameterVotingPeriod.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.voting_period = 50000;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterVotingPeriod,
+            Error::<Test>::InvalidCouncilElectionParameterVotingPeriod.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.revealing_period = 10000;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterRevealingPeriod,
+            Error::<Test>::InvalidCouncilElectionParameterRevealingPeriod.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.revealing_period = 50000;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterRevealingPeriod,
+            Error::<Test>::InvalidCouncilElectionParameterRevealingPeriod.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.announcing_period = 10000;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterAnnouncingPeriod,
+            Error::<Test>::InvalidCouncilElectionParameterAnnouncingPeriod.into(),
         );
 
         election_parameters = get_valid_election_parameters();
         election_parameters.announcing_period = 50000;
         assert_failed_election_parameters_call(
             election_parameters,
-            Error::InvalidCouncilElectionParameterAnnouncingPeriod,
+            Error::<Test>::InvalidCouncilElectionParameterAnnouncingPeriod.into(),
         );
     });
 }
@@ -483,7 +485,7 @@ fn create_content_working_group_mint_capacity_proposal_fails_with_invalid_parame
                 Some(<BalanceOf<Test>>::from(50000u32)),
                 (crate::CONTENT_WORKING_GROUP_MINT_CAPACITY_MAX_VALUE + 1) as u64,
             ),
-            Err(Error::InvalidContentWorkingGroupMintCapacity)
+            Err(Error::<Test>::InvalidContentWorkingGroupMintCapacity.into())
         );
     });
 }
@@ -613,7 +615,7 @@ fn create_spending_proposal_call_fails_with_incorrect_balance() {
                 0,
                 2,
             ),
-            Err(Error::InvalidSpendingProposalBalance)
+            Err(Error::<Test>::InvalidSpendingProposalBalance.into())
         );
 
         assert_eq!(
@@ -626,7 +628,7 @@ fn create_spending_proposal_call_fails_with_incorrect_balance() {
                 2000001,
                 2,
             ),
-            Err(Error::InvalidSpendingProposalBalance)
+            Err(Error::<Test>::InvalidSpendingProposalBalance.into())
         );
     });
 }
@@ -652,7 +654,7 @@ fn create_set_lead_proposal_fails_with_proposed_councilor() {
                 Some(<BalanceOf<Test>>::from(1250u32)),
                 Some((20, lead_account_id)),
             ),
-            Err(Error::InvalidSetLeadParameterCannotBeCouncilor)
+            Err(Error::<Test>::InvalidSetLeadParameterCannotBeCouncilor.into())
         );
     });
 }
@@ -777,7 +779,7 @@ fn create_set_validator_count_proposal_failed_with_invalid_validator_count() {
                 Some(<BalanceOf<Test>>::from(500u32)),
                 3,
             ),
-            Err(Error::InvalidValidatorCount)
+            Err(Error::<Test>::InvalidValidatorCount.into())
         );
 
         assert_eq!(
@@ -789,7 +791,7 @@ fn create_set_validator_count_proposal_failed_with_invalid_validator_count() {
                 Some(<BalanceOf<Test>>::from(1001u32)),
                 3,
             ),
-            Err(Error::InvalidValidatorCount)
+            Err(Error::<Test>::InvalidValidatorCount.into())
         );
     });
 }
@@ -1130,7 +1132,7 @@ fn create_working_group_mint_capacity_proposal_fails_with_invalid_parameters() {
                 (crate::WORKING_GROUP_MINT_CAPACITY_MAX_VALUE + 1) as u64,
                 WorkingGroup::Storage,
             ),
-            Err(Error::InvalidWorkingGroupMintCapacity)
+            Err(Error::<Test>::InvalidWorkingGroupMintCapacity.into())
         );
     });
 }
@@ -1356,7 +1358,7 @@ fn slash_stake_with_zero_staking_balance_fails() {
                 0,
                 WorkingGroup::Storage,
             ),
-            Err(Error::SlashingStakeIsZero)
+            Err(Error::<Test>::SlashingStakeIsZero.into())
         );
     });
 }
@@ -1384,7 +1386,7 @@ fn decrease_stake_with_zero_staking_balance_fails() {
                 0,
                 WorkingGroup::Storage,
             ),
-            Err(Error::DecreasingStakeIsZero)
+            Err(Error::<Test>::DecreasingStakeIsZero.into())
         );
     });
 }

+ 24 - 85
runtime-modules/proposals/discussion/Cargo.toml

@@ -1,94 +1,33 @@
 [package]
-name = 'substrate-proposals-discussion-module'
-version = '2.0.0'
+name = 'pallet-proposals-discussion'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
+[dependencies]
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+membership = { package = 'pallet-membership', default-features = false, path = '../../membership'}
+common = { package = 'pallet-common', default-features = false, path = '../../common'}
+
+[dev-dependencies]
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+
 [features]
 default = ['std']
-no_std = []
 std = [
-    'codec/std',
-    'rstd/std',
-    'srml-support/std',
-    'primitives/std',
-    'sr-primitives/std',
-    'system/std',
-    'timestamp/std',
-    'serde',
+	'serde',
+	'codec/std',
+	'sp-std/std',
+	'frame-support/std',
+	'system/std',
     'membership/std',
     'common/std',
-]
-
-[dependencies.num_enum]
-default_features = false
-version = "0.4.2"
-
-[dependencies.serde]
-features = ['derive']
-optional = true
-version = '1.0.101'
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dependencies.primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.rstd]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-std'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.sr-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.srml-support]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-support'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.system]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-system'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.membership]
-default_features = false
-package = 'substrate-membership-module'
-path = '../../membership'
-
-[dependencies.common]
-default_features = false
-package = 'substrate-common-module'
-path = '../../common'
-
-[dev-dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dev-dependencies.balances]
-package = 'srml-balances'
-default-features = false
-git = 'https://github.com/paritytech/substrate.git'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
+]

+ 33 - 45
runtime-modules/proposals/discussion/src/lib.rs

@@ -19,19 +19,19 @@
 //! ## Usage
 //!
 //! ```
-//! use srml_support::{decl_module, dispatch::Result};
+//! use frame_support::decl_module;
 //! use system::ensure_root;
-//! use substrate_proposals_discussion_module::{self as discussions};
+//! use pallet_proposals_discussion::{self as discussions};
 //!
 //! pub trait Trait: discussions::Trait + membership::Trait {}
 //!
 //! decl_module! {
 //!     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-//!         pub fn create_discussion(origin, title: Vec<u8>, author_id : T::MemberId) -> Result {
+//!         #[weight = 10_000_000]
+//!         pub fn create_discussion(origin, title: Vec<u8>, author_id : T::MemberId) {
 //!             ensure_root(origin)?;
 //!             <discussions::Module<T>>::ensure_can_create_thread(author_id, &title)?;
 //!             <discussions::Module<T>>::create_thread(author_id, title)?;
-//!             Ok(())
 //!         }
 //!     }
 //! }
@@ -48,16 +48,14 @@
 mod tests;
 mod types;
 
-use rstd::clone::Clone;
-use rstd::prelude::*;
-use rstd::vec::Vec;
-use srml_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
-
-use srml_support::traits::Get;
-use types::{DiscussionPost, DiscussionThread, ThreadCounter};
+use frame_support::dispatch::{DispatchError, DispatchResult};
+use frame_support::traits::Get;
+use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
+use sp_std::clone::Clone;
+use sp_std::vec::Vec;
 
 use common::origin::ActorOriginValidator;
-use srml_support::dispatch::DispatchResult;
+use types::{DiscussionPost, DiscussionThread, ThreadCounter};
 
 type MemberId<T> = <T as membership::Trait>::MemberId;
 
@@ -113,7 +111,7 @@ pub trait Trait: system::Trait + membership::Trait {
 
 decl_error! {
     /// Discussion module predefined errors
-    pub enum Error {
+    pub enum Error for Module<T: Trait> {
         /// Author should match the post creator
         NotAuthor,
 
@@ -146,29 +144,20 @@ decl_error! {
     }
 }
 
-impl From<system::Error> for Error {
-    fn from(error: system::Error) -> Self {
-        match error {
-            system::Error::Other(msg) => Error::Other(msg),
-            system::Error::RequireRootOrigin => Error::RequireRootOrigin,
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
 // Storage for the proposals discussion module
 decl_storage! {
     pub trait Store for Module<T: Trait> as ProposalDiscussion {
         /// Map thread identifier to corresponding thread.
-        pub ThreadById get(thread_by_id): map T::ThreadId =>
-            DiscussionThread<MemberId<T>, T::BlockNumber>;
+        pub ThreadById get(fn thread_by_id): map hasher(blake2_128_concat)
+            T::ThreadId => DiscussionThread<MemberId<T>, T::BlockNumber>;
 
         /// Count of all threads that have been created.
         pub ThreadCount get(fn thread_count): u64;
 
         /// Map thread id and post id to corresponding post.
-        pub PostThreadIdByPostId: double_map T::ThreadId, twox_128(T::PostId) =>
-             DiscussionPost<MemberId<T>, T::BlockNumber, T::ThreadId>;
+        pub PostThreadIdByPostId:
+            double_map hasher(blake2_128_concat) T::ThreadId, hasher(blake2_128_concat) T::PostId =>
+                DiscussionPost<MemberId<T>, T::BlockNumber, T::ThreadId>;
 
         /// Count of all posts that have been created.
         pub PostCount get(fn post_count): u64;
@@ -183,7 +172,7 @@ decl_module! {
     /// 'Proposal discussion' substrate module
     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
         /// Predefined errors
-        type Error = Error;
+        type Error = Error<T>;
 
         /// Emits an event. Default substrate implementation.
         fn deposit_event() = default;
@@ -201,6 +190,7 @@ decl_module! {
         const MaxThreadInARowNumber: u32 = T::MaxThreadInARowNumber::get();
 
         /// Adds a post with author origin check.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn add_post(
             origin,
             post_author_id: MemberId<T>,
@@ -211,12 +201,12 @@ decl_module! {
                 origin,
                 post_author_id,
             )?;
-            ensure!(<ThreadById<T>>::exists(thread_id), Error::ThreadDoesntExist);
+            ensure!(<ThreadById<T>>::contains_key(thread_id), Error::<T>::ThreadDoesntExist);
 
-            ensure!(!text.is_empty(),Error::EmptyPostProvided);
+            ensure!(!text.is_empty(),Error::<T>::EmptyPostProvided);
             ensure!(
                 text.len() as u32 <= T::PostLengthLimit::get(),
-                Error::PostIsTooLong
+                Error::<T>::PostIsTooLong
             );
 
             // mutation
@@ -240,6 +230,7 @@ decl_module! {
        }
 
         /// Updates a post with author origin check. Update attempts number is limited.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn update_post(
             origin,
             post_author_id: MemberId<T>,
@@ -252,20 +243,20 @@ decl_module! {
                 post_author_id,
             )?;
 
-            ensure!(<ThreadById<T>>::exists(thread_id), Error::ThreadDoesntExist);
-            ensure!(<PostThreadIdByPostId<T>>::exists(thread_id, post_id), Error::PostDoesntExist);
+            ensure!(<ThreadById<T>>::contains_key(thread_id), Error::<T>::ThreadDoesntExist);
+            ensure!(<PostThreadIdByPostId<T>>::contains_key(thread_id, post_id), Error::<T>::PostDoesntExist);
 
-            ensure!(!text.is_empty(), Error::EmptyPostProvided);
+            ensure!(!text.is_empty(), Error::<T>::EmptyPostProvided);
             ensure!(
                 text.len() as u32 <= T::PostLengthLimit::get(),
-                Error::PostIsTooLong
+                Error::<T>::PostIsTooLong
             );
 
             let post = <PostThreadIdByPostId<T>>::get(&thread_id, &post_id);
 
-            ensure!(post.author_id == post_author_id, Error::NotAuthor);
+            ensure!(post.author_id == post_author_id, Error::<T>::NotAuthor);
             ensure!(post.edition_number < T::MaxPostEditionNumber::get(),
-                Error::PostEditionNumberExceeded);
+                Error::<T>::PostEditionNumberExceeded);
 
             let new_post = DiscussionPost {
                 text,
@@ -288,7 +279,7 @@ impl<T: Trait> Module<T> {
     pub fn create_thread(
         thread_author_id: MemberId<T>,
         title: Vec<u8>,
-    ) -> Result<T::ThreadId, Error> {
+    ) -> Result<T::ThreadId, DispatchError> {
         Self::ensure_can_create_thread(thread_author_id, &title)?;
 
         let next_thread_count_value = Self::thread_count() + 1;
@@ -318,14 +309,11 @@ impl<T: Trait> Module<T> {
     /// Checks:
     /// - title is valid
     /// - max thread in a row by the same author
-    pub fn ensure_can_create_thread(
-        thread_author_id: MemberId<T>,
-        title: &[u8],
-    ) -> DispatchResult<Error> {
-        ensure!(!title.is_empty(), Error::EmptyTitleProvided);
+    pub fn ensure_can_create_thread(thread_author_id: MemberId<T>, title: &[u8]) -> DispatchResult {
+        ensure!(!title.is_empty(), Error::<T>::EmptyTitleProvided);
         ensure!(
             title.len() as u32 <= T::ThreadTitleLengthLimit::get(),
-            Error::TitleIsTooLong
+            Error::<T>::TitleIsTooLong
         );
 
         // get new 'threads in a row' counter for the author
@@ -333,7 +321,7 @@ impl<T: Trait> Module<T> {
 
         ensure!(
             current_thread_counter.counter as u32 <= T::MaxThreadInARowNumber::get(),
-            Error::MaxThreadInARowLimitExceeded
+            Error::<T>::MaxThreadInARowLimitExceeded
         );
 
         Ok(())

+ 32 - 15
runtime-modules/proposals/discussion/src/tests/mock.rs

@@ -2,16 +2,16 @@
 
 pub use system;
 
-pub use primitives::{Blake2Hasher, H256};
-pub use sr_primitives::{
-    testing::{Digest, DigestItem, Header, UintAuthorityId},
-    traits::{BlakeTwo256, Convert, IdentityLookup, OnFinalize},
-    weights::Weight,
-    BuildStorage, Perbill,
+use frame_support::traits::{OnFinalize, OnInitialize};
+use frame_support::{impl_outer_event, impl_outer_origin, parameter_types};
+use sp_core::H256;
+use sp_runtime::{
+    testing::Header,
+    traits::{BlakeTwo256, IdentityLookup},
+    Perbill,
 };
 
 use crate::ActorOriginValidator;
-use srml_support::{impl_outer_event, impl_outer_origin, parameter_types};
 
 impl_outer_origin! {
     pub enum Origin for Test {}
@@ -49,6 +49,7 @@ impl_outer_event! {
         discussion<T>,
         balances<T>,
         membership_mod<T>,
+        system<T>,
     }
 }
 
@@ -60,15 +61,10 @@ parameter_types! {
 
 impl balances::Trait for Test {
     type Balance = u64;
-    /// What to do if an account's free balance gets zeroed.
-    type OnFreeBalanceZero = ();
-    type OnNewAccount = ();
-    type TransferPayment = ();
     type DustRemoval = ();
     type Event = TestEvent;
     type ExistentialDeposit = ExistentialDeposit;
-    type TransferFee = TransferFee;
-    type CreationFee = CreationFee;
+    type AccountStore = System;
 }
 
 impl common::currency::GovernanceCurrency for Test {
@@ -109,6 +105,7 @@ impl ActorOriginValidator<Origin, u64, u64> for () {
 }
 
 impl system::Trait for Test {
+    type BaseCallFilter = ();
     type Origin = Origin;
     type Call = ();
     type Index = u64;
@@ -121,18 +118,26 @@ impl system::Trait for Test {
     type Event = TestEvent;
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
-impl timestamp::Trait for Test {
+impl pallet_timestamp::Trait for Test {
     type Moment = u64;
     type OnTimestampSet = ();
     type MinimumPeriod = MinimumPeriod;
 }
 
-pub fn initial_test_ext() -> runtime_io::TestExternalities {
+pub fn initial_test_ext() -> sp_io::TestExternalities {
     let t = system::GenesisConfig::default()
         .build_storage::<Test>()
         .unwrap();
@@ -142,3 +147,15 @@ pub fn initial_test_ext() -> runtime_io::TestExternalities {
 
 pub type Discussions = crate::Module<Test>;
 pub type System = system::Module<Test>;
+
+// Recommendation from Parity on testing on_finalize
+// https://substrate.dev/docs/en/next/development/module/tests
+pub fn run_to_block(n: u64) {
+    while System::block_number() < n {
+        <System as OnFinalize<u64>>::on_finalize(System::block_number());
+        <Discussions as OnFinalize<u64>>::on_finalize(System::block_number());
+        System::set_block_number(System::block_number() + 1);
+        <System as OnInitialize<u64>>::on_initialize(System::block_number());
+        <Discussions as OnInitialize<u64>>::on_initialize(System::block_number());
+    }
+}

+ 35 - 25
runtime-modules/proposals/discussion/src/tests/mod.rs

@@ -1,18 +1,19 @@
 mod mock;
 
-use mock::*;
-
-use crate::*;
+use frame_support::dispatch::{DispatchError, DispatchResult};
 use system::RawOrigin;
 use system::{EventRecord, Phase};
 
+use crate::*;
+use mock::*;
+
 struct EventFixture;
 impl EventFixture {
     fn assert_events(expected_raw_events: Vec<RawEvent<u64, u64, u64>>) {
         let expected_events = expected_raw_events
             .iter()
             .map(|ev| EventRecord {
-                phase: Phase::ApplyExtrinsic(0),
+                phase: Phase::Initialization,
                 event: TestEvent::discussion(ev.clone()),
                 topics: vec![],
             })
@@ -34,12 +35,12 @@ struct TestThreadEntry {
 }
 
 fn assert_thread_content(thread_entry: TestThreadEntry, post_entries: Vec<TestPostEntry>) {
-    assert!(<ThreadById<Test>>::exists(thread_entry.thread_id));
+    assert!(<ThreadById<Test>>::contains_key(thread_entry.thread_id));
 
     let actual_thread = <ThreadById<Test>>::get(thread_entry.thread_id);
     let expected_thread = DiscussionThread {
         title: thread_entry.title,
-        created_at: 1,
+        created_at: 0,
         author_id: 1,
     };
     assert_eq!(actual_thread, expected_thread);
@@ -49,8 +50,8 @@ fn assert_thread_content(thread_entry: TestThreadEntry, post_entries: Vec<TestPo
             <PostThreadIdByPostId<Test>>::get(thread_entry.thread_id, post_entry.post_id);
         let expected_post = DiscussionPost {
             text: post_entry.text,
-            created_at: 1,
-            updated_at: 1,
+            created_at: 0,
+            updated_at: 0,
             author_id: 1,
             thread_id: thread_entry.thread_id,
             edition_number: post_entry.edition_number,
@@ -81,7 +82,7 @@ impl DiscussionFixture {
         DiscussionFixture { title, ..self }
     }
 
-    fn create_discussion_and_assert(&self, result: Result<u64, Error>) -> Option<u64> {
+    fn create_discussion_and_assert(&self, result: Result<u64, DispatchError>) -> Option<u64> {
         let create_discussion_result =
             Discussions::create_thread(self.author_id, self.title.clone());
 
@@ -133,7 +134,7 @@ impl PostFixture {
         }
     }
 
-    fn add_post_and_assert(&mut self, result: Result<(), Error>) -> Option<u64> {
+    fn add_post_and_assert(&mut self, result: DispatchResult) -> Option<u64> {
         let add_post_result = Discussions::add_post(
             self.origin.clone().into(),
             self.author_id,
@@ -150,7 +151,7 @@ impl PostFixture {
         self.post_id
     }
 
-    fn update_post_with_text_and_assert(&mut self, new_text: Vec<u8>, result: Result<(), Error>) {
+    fn update_post_with_text_and_assert(&mut self, new_text: Vec<u8>, result: DispatchResult) {
         let add_post_result = Discussions::update_post(
             self.origin.clone().into(),
             self.author_id,
@@ -162,7 +163,7 @@ impl PostFixture {
         assert_eq!(add_post_result, result);
     }
 
-    fn update_post_and_assert(&mut self, result: Result<(), Error>) {
+    fn update_post_and_assert(&mut self, result: DispatchResult) {
         self.update_post_with_text_and_assert(self.text.clone(), result);
     }
 }
@@ -194,6 +195,13 @@ fn create_post_call_succeeds() {
 #[test]
 fn update_post_call_succeeds() {
     initial_test_ext().execute_with(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         let discussion_fixture = DiscussionFixture::default();
 
         let thread_id = discussion_fixture
@@ -230,7 +238,7 @@ fn update_post_call_fails_because_of_post_edition_limit() {
             post_fixture.update_post_and_assert(Ok(()));
         }
 
-        post_fixture.update_post_and_assert(Err(Error::PostEditionNumberExceeded));
+        post_fixture.update_post_and_assert(Err(Error::<Test>::PostEditionNumberExceeded.into()));
     });
 }
 
@@ -249,11 +257,11 @@ fn update_post_call_fails_because_of_the_wrong_author() {
 
         post_fixture = post_fixture.with_author(2);
 
-        post_fixture.update_post_and_assert(Err(Error::Other("Invalid author")));
+        post_fixture.update_post_and_assert(Err(DispatchError::Other("Invalid author")));
 
         post_fixture = post_fixture.with_origin(RawOrigin::None).with_author(2);
 
-        post_fixture.update_post_and_assert(Err(Error::NotAuthor));
+        post_fixture.update_post_and_assert(Err(Error::<Test>::NotAuthor.into()));
     });
 }
 
@@ -298,10 +306,11 @@ fn thread_content_check_succeeded() {
 fn create_discussion_call_with_bad_title_failed() {
     initial_test_ext().execute_with(|| {
         let mut discussion_fixture = DiscussionFixture::default().with_title(Vec::new());
-        discussion_fixture.create_discussion_and_assert(Err(Error::EmptyTitleProvided));
+        discussion_fixture
+            .create_discussion_and_assert(Err(Error::<Test>::EmptyTitleProvided.into()));
 
         discussion_fixture = DiscussionFixture::default().with_title([0; 201].to_vec());
-        discussion_fixture.create_discussion_and_assert(Err(Error::TitleIsTooLong));
+        discussion_fixture.create_discussion_and_assert(Err(Error::<Test>::TitleIsTooLong.into()));
     });
 }
 
@@ -314,7 +323,7 @@ fn add_post_call_with_invalid_thread_failed() {
             .unwrap();
 
         let mut post_fixture = PostFixture::default_for_thread(2);
-        post_fixture.add_post_and_assert(Err(Error::ThreadDoesntExist));
+        post_fixture.add_post_and_assert(Err(Error::<Test>::ThreadDoesntExist.into()));
     });
 }
 
@@ -330,7 +339,7 @@ fn update_post_call_with_invalid_post_failed() {
         post_fixture1.add_post_and_assert(Ok(())).unwrap();
 
         let mut post_fixture2 = post_fixture1.change_post_id(2);
-        post_fixture2.update_post_and_assert(Err(Error::PostDoesntExist));
+        post_fixture2.update_post_and_assert(Err(Error::<Test>::PostDoesntExist.into()));
     });
 }
 
@@ -346,7 +355,7 @@ fn update_post_call_with_invalid_thread_failed() {
         post_fixture1.add_post_and_assert(Ok(())).unwrap();
 
         let mut post_fixture2 = post_fixture1.change_thread_id(2);
-        post_fixture2.update_post_and_assert(Err(Error::ThreadDoesntExist));
+        post_fixture2.update_post_and_assert(Err(Error::<Test>::ThreadDoesntExist.into()));
     });
 }
 
@@ -359,11 +368,11 @@ fn add_post_call_with_invalid_text_failed() {
             .unwrap();
 
         let mut post_fixture1 = PostFixture::default_for_thread(thread_id).with_text(Vec::new());
-        post_fixture1.add_post_and_assert(Err(Error::EmptyPostProvided));
+        post_fixture1.add_post_and_assert(Err(Error::<Test>::EmptyPostProvided.into()));
 
         let mut post_fixture2 =
             PostFixture::default_for_thread(thread_id).with_text([0; 2001].to_vec());
-        post_fixture2.add_post_and_assert(Err(Error::PostIsTooLong));
+        post_fixture2.add_post_and_assert(Err(Error::<Test>::PostIsTooLong.into()));
     });
 }
 
@@ -379,10 +388,10 @@ fn update_post_call_with_invalid_text_failed() {
         post_fixture1.add_post_and_assert(Ok(()));
 
         let mut post_fixture2 = post_fixture1.with_text(Vec::new());
-        post_fixture2.update_post_and_assert(Err(Error::EmptyPostProvided));
+        post_fixture2.update_post_and_assert(Err(Error::<Test>::EmptyPostProvided.into()));
 
         let mut post_fixture3 = post_fixture2.with_text([0; 2001].to_vec());
-        post_fixture3.update_post_and_assert(Err(Error::PostIsTooLong));
+        post_fixture3.update_post_and_assert(Err(Error::<Test>::PostIsTooLong.into()));
     });
 }
 
@@ -396,7 +405,8 @@ fn add_discussion_thread_fails_because_of_max_thread_by_same_author_in_a_row_lim
                 .unwrap();
         }
 
-        discussion_fixture.create_discussion_and_assert(Err(Error::MaxThreadInARowLimitExceeded));
+        discussion_fixture
+            .create_discussion_and_assert(Err(Error::<Test>::MaxThreadInARowLimitExceeded.into()));
     });
 }
 

+ 1 - 2
runtime-modules/proposals/discussion/src/types.rs

@@ -3,8 +3,7 @@
 use codec::{Decode, Encode};
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
-
-use rstd::prelude::*;
+use sp_std::vec::Vec;
 
 /// Represents a discussion thread
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]

+ 31 - 96
runtime-modules/proposals/engine/Cargo.toml

@@ -1,105 +1,40 @@
 [package]
-name = 'substrate-proposals-engine-module'
-version = '2.0.0'
+name = 'pallet-proposals-engine'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
+[dependencies]
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+membership = { package = 'pallet-membership', default-features = false, path = '../../membership'}
+stake = { package = 'pallet-stake', default-features = false, path = '../../stake'}
+common = { package = 'pallet-common', default-features = false, path = '../../common'}
+
+[dev-dependencies]
+mockall = "0.7.1"
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+
 [features]
 default = ['std']
-no_std = []
 std = [
-    'codec/std',
-    'rstd/std',
-    'srml-support/std',
-    'primitives/std',
-    'system/std',
-    'timestamp/std',
-    'serde',
-    'stake/std',
-    'balances/std',
-    'sr-primitives/std',
+	'serde',
+	'codec/std',
+	'sp-std/std',
+	'frame-support/std',
+	'system/std',
+	'pallet-timestamp/std',
+	'sp-arithmetic/std',
+	'sp-runtime/std',
     'membership/std',
+    'stake/std',
     'common/std',
-]
-
-
-[dependencies.num_enum]
-default_features = false
-version = "0.4.2"
-
-[dependencies.serde]
-features = ['derive']
-optional = true
-version = '1.0.101'
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dependencies.primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.rstd]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-std'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.srml-support]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-support'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.system]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-system'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.balances]
-package = 'srml-balances'
-default-features = false
-git = 'https://github.com/paritytech/substrate.git'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.sr-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.stake]
-default_features = false
-package = 'substrate-stake-module'
-path = '../../stake'
-
-[dependencies.membership]
-default_features = false
-package = 'substrate-membership-module'
-path = '../../membership'
-
-[dependencies.common]
-default_features = false
-package = 'substrate-common-module'
-path = '../../common'
-
-[dev-dependencies]
-mockall = "0.7.1"
-
-[dev-dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
+]

+ 82 - 61
runtime-modules/proposals/engine/src/lib.rs

@@ -57,23 +57,25 @@
 //! ## Usage
 //!
 //! ```
-//! use srml_support::{decl_module, dispatch::Result, print};
+//! use frame_support::{decl_module, print};
 //! use system::ensure_signed;
 //! use codec::Encode;
-//! use substrate_proposals_engine_module::{self as engine, ProposalParameters};
+//! use pallet_proposals_engine::{self as engine, ProposalParameters};
 //!
 //! pub trait Trait: engine::Trait + membership::Trait {}
 //!
 //! decl_module! {
 //!     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+//!         #[weight = 10_000_000]
 //!         fn executable_proposal(origin) {
 //!             print("executed!");
 //!         }
 //!
+//!         #[weight = 10_000_000]
 //!         pub fn create_spending_proposal(
 //!             origin,
 //!             proposer_id: T::MemberId,
-//!         ) -> Result {
+//!         ) {
 //!             let account_id = ensure_signed(origin)?;
 //!             let parameters = ProposalParameters::default();
 //!             let title = b"Spending proposal".to_vec();
@@ -96,7 +98,6 @@
 //!                 None,
 //!                 encoded_proposal_code
 //!             )?;
-//!             Ok(())
 //!         }
 //!     }
 //! }
@@ -109,6 +110,7 @@
 // Do not delete! Cannot be uncommented by default, because of Parity decl_module! issue.
 //#![warn(missing_docs)]
 
+use crate::types::ApprovedProposalData;
 use types::FinalizedProposalData;
 use types::ProposalStakeManager;
 pub use types::{
@@ -126,22 +128,24 @@ pub(crate) mod types;
 mod tests;
 
 use codec::Decode;
-use rstd::prelude::*;
-use sr_primitives::traits::{DispatchResult, Zero};
-use srml_support::traits::{Currency, Get};
-use srml_support::{
+use frame_support::dispatch::{DispatchError, DispatchResult, UnfilteredDispatchable};
+use frame_support::storage::IterableStorageMap;
+use frame_support::traits::{Currency, Get};
+use frame_support::{
     decl_error, decl_event, decl_module, decl_storage, ensure, print, Parameter, StorageDoubleMap,
 };
+use sp_arithmetic::traits::Zero;
+use sp_std::vec::Vec;
 use system::{ensure_root, RawOrigin};
 
-use crate::types::ApprovedProposalData;
 use common::origin::ActorOriginValidator;
-use srml_support::dispatch::Dispatchable;
 
 type MemberId<T> = <T as membership::Trait>::MemberId;
 
 /// Proposals engine trait.
-pub trait Trait: system::Trait + timestamp::Trait + stake::Trait + membership::Trait {
+pub trait Trait:
+    system::Trait + pallet_timestamp::Trait + stake::Trait + membership::Trait
+{
     /// Engine event type.
     type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
 
@@ -180,7 +184,7 @@ pub trait Trait: system::Trait + timestamp::Trait + stake::Trait + membership::T
     type MaxActiveProposalLimit: Get<u32>;
 
     /// Proposals executable code. Can be instantiated by external module Call enum members.
-    type DispatchableCallCode: Parameter + Dispatchable<Origin = Self::Origin> + Default;
+    type DispatchableCallCode: Parameter + UnfilteredDispatchable<Origin = Self::Origin> + Default;
 }
 
 decl_event!(
@@ -216,7 +220,7 @@ decl_event!(
 
 decl_error! {
     /// Engine module predefined errors
-    pub enum Error {
+    pub enum Error for Module<T: Trait>{
         /// Proposal cannot have an empty title"
         EmptyTitleProvided,
 
@@ -264,43 +268,38 @@ decl_error! {
     }
 }
 
-impl From<system::Error> for Error {
-    fn from(error: system::Error) -> Self {
-        match error {
-            system::Error::Other(msg) => Error::Other(msg),
-            system::Error::RequireRootOrigin => Error::RequireRootOrigin,
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
 // Storage for the proposals engine module
 decl_storage! {
     pub trait Store for Module<T: Trait> as ProposalEngine{
         /// Map proposal by its id.
-        pub Proposals get(fn proposals): map T::ProposalId => ProposalOf<T>;
+        pub Proposals get(fn proposals): map hasher(blake2_128_concat)
+            T::ProposalId => ProposalOf<T>;
 
         /// Count of all proposals that have been created.
         pub ProposalCount get(fn proposal_count): u32;
 
         /// Map proposal executable code by proposal id.
-        pub DispatchableCallCode get(fn proposal_codes): map T::ProposalId =>  Vec<u8>;
+        pub DispatchableCallCode get(fn proposal_codes): map hasher(blake2_128_concat)
+            T::ProposalId =>  Vec<u8>;
 
         /// Count of active proposals.
         pub ActiveProposalCount get(fn active_proposal_count): u32;
 
         /// Ids of proposals that are open for voting (have not been finalized yet).
-        pub ActiveProposalIds get(fn active_proposal_ids): linked_map T::ProposalId=> ();
+        pub ActiveProposalIds get(fn active_proposal_ids): map hasher(blake2_128_concat)
+            T::ProposalId=> ();
 
         /// Ids of proposals that were approved and theirs grace period was not expired.
-        pub PendingExecutionProposalIds get(fn pending_proposal_ids): linked_map T::ProposalId=> ();
+        pub PendingExecutionProposalIds get(fn pending_proposal_ids): map hasher(blake2_128_concat)
+            T::ProposalId=> ();
 
         /// Double map for preventing duplicate votes. Should be cleaned after usage.
         pub VoteExistsByProposalByVoter get(fn vote_by_proposal_by_voter):
-            double_map T::ProposalId, twox_256(MemberId<T>) => VoteKind;
+            double_map hasher(blake2_128_concat)  T::ProposalId, hasher(blake2_128_concat) MemberId<T> => VoteKind;
 
         /// Map proposal id by stake id. Required by StakingEventsHandler callback call
-        pub StakesProposals get(fn stakes_proposals): map T::StakeId =>  T::ProposalId;
+        pub StakesProposals get(fn stakes_proposals): map hasher(blake2_128_concat)
+            T::StakeId =>  T::ProposalId;
     }
 }
 
@@ -308,7 +307,7 @@ decl_module! {
     /// 'Proposal engine' substrate module
     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
         /// Predefined errors
-        type Error = Error;
+        type Error = Error<T>;
 
         /// Emits an event. Default substrate implementation.
         fn deposit_event() = default;
@@ -329,23 +328,24 @@ decl_module! {
         const MaxActiveProposalLimit: u32 = T::MaxActiveProposalLimit::get();
 
         /// Vote extrinsic. Conditions:  origin must allow votes.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn vote(origin, voter_id: MemberId<T>, proposal_id: T::ProposalId, vote: VoteKind)  {
             T::VoterOriginValidator::ensure_actor_origin(
                 origin,
                 voter_id,
             )?;
 
-            ensure!(<Proposals<T>>::exists(proposal_id), Error::ProposalNotFound);
+            ensure!(<Proposals<T>>::contains_key(proposal_id), Error::<T>::ProposalNotFound);
             let mut proposal = Self::proposals(proposal_id);
 
-            ensure!(matches!(proposal.status, ProposalStatus::Active{..}), Error::ProposalFinalized);
+            ensure!(matches!(proposal.status, ProposalStatus::Active{..}), Error::<T>::ProposalFinalized);
 
-            let did_not_vote_before = !<VoteExistsByProposalByVoter<T>>::exists(
+            let did_not_vote_before = !<VoteExistsByProposalByVoter<T>>::contains_key(
                 proposal_id,
                 voter_id,
             );
 
-            ensure!(did_not_vote_before, Error::AlreadyVoted);
+            ensure!(did_not_vote_before, Error::<T>::AlreadyVoted);
 
             proposal.voting_results.add_vote(vote.clone());
 
@@ -357,17 +357,18 @@ decl_module! {
         }
 
         /// Cancel a proposal by its original proposer.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn cancel_proposal(origin, proposer_id: MemberId<T>, proposal_id: T::ProposalId) {
             T::ProposerOriginValidator::ensure_actor_origin(
                 origin,
                 proposer_id,
             )?;
 
-            ensure!(<Proposals<T>>::exists(proposal_id), Error::ProposalNotFound);
+            ensure!(<Proposals<T>>::contains_key(proposal_id), Error::<T>::ProposalNotFound);
             let proposal = Self::proposals(proposal_id);
 
-            ensure!(proposer_id == proposal.proposer_id, Error::NotAuthor);
-            ensure!(matches!(proposal.status, ProposalStatus::Active{..}), Error::ProposalFinalized);
+            ensure!(proposer_id == proposal.proposer_id, Error::<T>::NotAuthor);
+            ensure!(matches!(proposal.status, ProposalStatus::Active{..}), Error::<T>::ProposalFinalized);
 
             // mutation
 
@@ -375,18 +376,19 @@ decl_module! {
         }
 
         /// Veto a proposal. Must be root.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn veto_proposal(origin, proposal_id: T::ProposalId) {
             ensure_root(origin)?;
 
-            ensure!(<Proposals<T>>::exists(proposal_id), Error::ProposalNotFound);
+            ensure!(<Proposals<T>>::contains_key(proposal_id), Error::<T>::ProposalNotFound);
             let proposal = Self::proposals(proposal_id);
 
             // mutation
 
-            if <PendingExecutionProposalIds<T>>::exists(proposal_id) {
+            if <PendingExecutionProposalIds<T>>::contains_key(proposal_id) {
                 Self::veto_pending_execution_proposal(proposal_id, proposal);
             } else {
-                ensure!(matches!(proposal.status, ProposalStatus::Active{..}), Error::ProposalFinalized);
+                ensure!(matches!(proposal.status, ProposalStatus::Active{..}), Error::<T>::ProposalFinalized);
                 Self::finalize_proposal(proposal_id, ProposalDecisionStatus::Vetoed);
             }
         }
@@ -426,7 +428,7 @@ impl<T: Trait> Module<T> {
         description: Vec<u8>,
         stake_balance: Option<types::BalanceOf<T>>,
         encoded_dispatchable_call_code: Vec<u8>,
-    ) -> Result<T::ProposalId, Error> {
+    ) -> Result<T::ProposalId, DispatchError> {
         Self::ensure_create_proposal_parameters_are_valid(
             &parameters,
             &title,
@@ -490,32 +492,35 @@ impl<T: Trait> Module<T> {
         title: &[u8],
         description: &[u8],
         stake_balance: Option<types::BalanceOf<T>>,
-    ) -> DispatchResult<Error> {
-        ensure!(!title.is_empty(), Error::EmptyTitleProvided);
+    ) -> DispatchResult {
+        ensure!(!title.is_empty(), Error::<T>::EmptyTitleProvided);
         ensure!(
             title.len() as u32 <= T::TitleMaxLength::get(),
-            Error::TitleIsTooLong
+            Error::<T>::TitleIsTooLong
         );
 
-        ensure!(!description.is_empty(), Error::EmptyDescriptionProvided);
+        ensure!(
+            !description.is_empty(),
+            Error::<T>::EmptyDescriptionProvided
+        );
         ensure!(
             description.len() as u32 <= T::DescriptionMaxLength::get(),
-            Error::DescriptionIsTooLong
+            Error::<T>::DescriptionIsTooLong
         );
 
         ensure!(
             (Self::active_proposal_count()) < T::MaxActiveProposalLimit::get(),
-            Error::MaxActiveProposalNumberExceeded
+            Error::<T>::MaxActiveProposalNumberExceeded
         );
 
         ensure!(
             parameters.approval_threshold_percentage > 0,
-            Error::InvalidParameterApprovalThreshold
+            Error::<T>::InvalidParameterApprovalThreshold
         );
 
         ensure!(
             parameters.slashing_threshold_percentage > 0,
-            Error::InvalidParameterSlashingThreshold
+            Error::<T>::InvalidParameterSlashingThreshold
         );
 
         // check stake parameters
@@ -523,15 +528,15 @@ impl<T: Trait> Module<T> {
             if let Some(staked_balance) = stake_balance {
                 ensure!(
                     required_stake == staked_balance,
-                    Error::StakeDiffersFromRequired
+                    Error::<T>::StakeDiffersFromRequired
                 );
             } else {
-                return Err(Error::EmptyStake);
+                return Err(Error::<T>::EmptyStake.into());
             }
         }
 
         if stake_balance.is_some() && parameters.required_stake.is_none() {
-            return Err(Error::StakeShouldBeEmpty);
+            return Err(Error::<T>::StakeShouldBeEmpty.into());
         }
 
         Ok(())
@@ -541,10 +546,10 @@ impl<T: Trait> Module<T> {
     /// There can be a lot of invariant breaks in the scope of this proposal.
     /// Such situations are handled by adding error messages to the log.
     pub fn refund_proposal_stake(stake_id: T::StakeId, imbalance: NegativeImbalance<T>) {
-        if <StakesProposals<T>>::exists(stake_id) {
+        if <StakesProposals<T>>::contains_key(stake_id) {
             let proposal_id = Self::stakes_proposals(stake_id);
 
-            if <Proposals<T>>::exists(proposal_id) {
+            if <Proposals<T>>::contains_key(proposal_id) {
                 let proposal = Self::proposals(proposal_id);
 
                 if let ProposalStatus::Active(active_stake_result) = proposal.status {
@@ -572,7 +577,7 @@ impl<T: Trait> Module<T> {
     /// Resets voting results for active proposals.
     /// Possible application includes new council elections.
     pub fn reset_active_proposals() {
-        <ActiveProposalIds<T>>::enumerate().for_each(|(proposal_id, _)| {
+        <ActiveProposalIds<T>>::iter().for_each(|(proposal_id, _)| {
             <Proposals<T>>::mutate(proposal_id, |proposal| {
                 proposal.reset_proposal();
                 <VoteExistsByProposalByVoter<T>>::remove_prefix(&proposal_id);
@@ -592,7 +597,7 @@ impl<T: Trait> Module<T> {
     fn get_finalized_proposals() -> Vec<FinalizedProposal<T>> {
         // Enumerate active proposals id and gather finalization data.
         // Skip proposals with unfinished voting.
-        <ActiveProposalIds<T>>::enumerate()
+        <ActiveProposalIds<T>>::iter()
             .filter_map(|(proposal_id, _)| {
                 // load current proposal
                 let proposal = Self::proposals(proposal_id);
@@ -644,10 +649,12 @@ impl<T: Trait> Module<T> {
 
         let approved_proposal_status = match proposal_code_result {
             Ok(proposal_code) => {
-                if let Err(error) = proposal_code.dispatch(T::Origin::from(RawOrigin::Root)) {
-                    ApprovedProposalStatus::failed_execution(
-                        error.into().message.unwrap_or("Dispatch error"),
-                    )
+                if let Err(dispatch_error) =
+                    proposal_code.dispatch_bypass_filter(T::Origin::from(RawOrigin::Root))
+                {
+                    ApprovedProposalStatus::failed_execution(Self::parse_dispatch_error(
+                        dispatch_error.error,
+                    ))
                 } else {
                     ApprovedProposalStatus::Executed
                 }
@@ -756,7 +763,7 @@ impl<T: Trait> Module<T> {
 
     // Enumerates approved proposals and checks their grace period expiration
     fn get_approved_proposal_with_expired_grace_period() -> Vec<ApprovedProposal<T>> {
-        <PendingExecutionProposalIds<T>>::enumerate()
+        <PendingExecutionProposalIds<T>>::iter()
             .filter_map(|(proposal_id, _)| {
                 let proposal = Self::proposals(proposal_id);
 
@@ -793,6 +800,20 @@ impl<T: Trait> Module<T> {
             ActiveProposalCount::put(next_active_proposal_count_value);
         };
     }
+
+    // Parse dispatchable execution result.
+    fn parse_dispatch_error(error: DispatchError) -> &'static str {
+        match error {
+            DispatchError::BadOrigin => error.into(),
+            DispatchError::Other(msg) => msg,
+            DispatchError::CannotLookup => error.into(),
+            DispatchError::Module {
+                index: _,
+                error: _,
+                message: msg,
+            } => msg.unwrap_or("Dispatch error."),
+        }
+    }
 }
 
 // Simplification of the 'FinalizedProposalData' type

+ 2 - 2
runtime-modules/proposals/engine/src/tests/mock/balance_manager.rs

@@ -1,7 +1,7 @@
 #![cfg(test)]
 
-pub use sr_primitives::traits::Zero;
-use srml_support::traits::{Currency, Imbalance};
+use frame_support::traits::{Currency, Imbalance};
+pub use sp_arithmetic::traits::Zero;
 
 use super::*;
 

+ 20 - 21
runtime-modules/proposals/engine/src/tests/mock/mod.rs

@@ -7,14 +7,14 @@
 //!
 
 #![cfg(test)]
-pub use primitives::{Blake2Hasher, H256};
-pub use sr_primitives::{
-    testing::{Digest, DigestItem, Header, UintAuthorityId},
-    traits::{BlakeTwo256, Convert, IdentityLookup, OnFinalize, Zero},
-    weights::Weight,
-    BuildStorage, DispatchError, Perbill,
+
+use frame_support::{impl_outer_event, impl_outer_origin, parameter_types};
+use sp_core::H256;
+use sp_runtime::{
+    testing::Header,
+    traits::{BlakeTwo256, IdentityLookup},
+    Perbill,
 };
-use srml_support::{impl_outer_event, impl_outer_origin, parameter_types};
 pub use system;
 
 mod balance_manager;
@@ -46,30 +46,20 @@ impl_outer_event! {
         balances<T>,
         engine<T>,
         membership_mod<T>,
+        system<T>,
     }
 }
 
 parameter_types! {
     pub const ExistentialDeposit: u32 = 0;
-    pub const TransferFee: u32 = 0;
-    pub const CreationFee: u32 = 0;
 }
 
 impl balances::Trait for Test {
-    /// The type for recording an account's balance.
     type Balance = u64;
-    /// What to do if an account's free balance gets zeroed.
-    type OnFreeBalanceZero = ();
-    /// What to do if a new account is created.
-    type OnNewAccount = ();
-
-    type TransferPayment = ();
-
     type DustRemoval = ();
     type Event = TestEvent;
     type ExistentialDeposit = ExistentialDeposit;
-    type TransferFee = TransferFee;
-    type CreationFee = CreationFee;
+    type AccountStore = System;
 }
 
 impl common::currency::GovernanceCurrency for Test {
@@ -149,6 +139,7 @@ parameter_types! {
 }
 
 impl system::Trait for Test {
+    type BaseCallFilter = ();
     type Origin = Origin;
     type Call = ();
     type Index = u64;
@@ -161,18 +152,26 @@ impl system::Trait for Test {
     type Event = TestEvent;
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
-impl timestamp::Trait for Test {
+impl pallet_timestamp::Trait for Test {
     type Moment = u64;
     type OnTimestampSet = ();
     type MinimumPeriod = MinimumPeriod;
 }
 
-pub fn initial_test_ext() -> runtime_io::TestExternalities {
+pub fn initial_test_ext() -> sp_io::TestExternalities {
     let t = system::GenesisConfig::default()
         .build_storage::<Test>()
         .unwrap();

+ 4 - 3
runtime-modules/proposals/engine/src/tests/mock/proposals.rs

@@ -1,16 +1,17 @@
 //! Contains executable proposal extrinsic mocks
 
-use rstd::prelude::*;
-use rstd::vec::Vec;
-use srml_support::decl_module;
+use frame_support::decl_module;
+use sp_std::vec::Vec;
 pub trait Trait: system::Trait {}
 
 decl_module! {
     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
         /// Working extrinsic test
+        #[weight = 10_000_000]
         pub fn dummy_proposal(_origin, _title: Vec<u8>, _description: Vec<u8>) {}
 
         /// Broken extrinsic test
+        #[weight = 10_000_000]
         pub fn faulty_proposal(_origin, _title: Vec<u8>, _description: Vec<u8>,) {
              Err("ExecutionFailed")?
         }

+ 1 - 1
runtime-modules/proposals/engine/src/tests/mock/stakes.rs

@@ -1,6 +1,6 @@
 #![cfg(test)]
 
-use rstd::marker::PhantomData;
+use sp_std::marker::PhantomData;
 use std::cell::RefCell;
 use std::panic;
 use std::rc::Rc;

+ 115 - 92
runtime-modules/proposals/engine/src/tests/mod.rs

@@ -4,14 +4,13 @@ use crate::*;
 use mock::*;
 
 use codec::Encode;
-use rstd::rc::Rc;
-use sr_primitives::traits::{DispatchResult, OnFinalize, OnInitialize};
-use srml_support::{StorageDoubleMap, StorageMap, StorageValue};
+use frame_support::dispatch::DispatchResult;
+use frame_support::traits::{Currency, OnFinalize, OnInitialize};
+use frame_support::{StorageDoubleMap, StorageMap, StorageValue};
+use sp_std::rc::Rc;
 use system::RawOrigin;
 use system::{EventRecord, Phase};
 
-use srml_support::traits::Currency;
-
 pub(crate) fn increase_total_balance_issuance_using_account_id(account_id: u64, balance: u64) {
     let initial_balance = Balances::total_issuance();
     {
@@ -132,7 +131,7 @@ impl DummyProposalFixture {
         }
     }
 
-    fn create_proposal_and_assert(self, result: Result<u32, Error>) -> Option<u32> {
+    fn create_proposal_and_assert(self, result: Result<u32, DispatchError>) -> Option<u32> {
         let proposal_id_result = ProposalsEngine::create_proposal(
             self.account_id,
             self.proposer_id,
@@ -174,7 +173,7 @@ impl CancelProposalFixture {
         }
     }
 
-    fn cancel_and_assert(self, expected_result: DispatchResult<Error>) {
+    fn cancel_and_assert(self, expected_result: DispatchResult) {
         assert_eq!(
             ProposalsEngine::cancel_proposal(
                 self.origin.into(),
@@ -202,7 +201,7 @@ impl VetoProposalFixture {
         VetoProposalFixture { origin, ..self }
     }
 
-    fn veto_and_assert(self, expected_result: DispatchResult<Error>) {
+    fn veto_and_assert(self, expected_result: DispatchResult) {
         assert_eq!(
             ProposalsEngine::veto_proposal(self.origin.into(), self.proposal_id,),
             expected_result
@@ -230,11 +229,11 @@ impl VoteGenerator {
         self.vote_and_assert(vote_kind, Ok(()));
     }
 
-    fn vote_and_assert(&mut self, vote_kind: VoteKind, expected_result: DispatchResult<Error>) {
+    fn vote_and_assert(&mut self, vote_kind: VoteKind, expected_result: DispatchResult) {
         assert_eq!(self.vote(vote_kind.clone()), expected_result);
     }
 
-    fn vote(&mut self, vote_kind: VoteKind) -> DispatchResult<Error> {
+    fn vote(&mut self, vote_kind: VoteKind) -> DispatchResult {
         if self.auto_increment_voter_id {
             self.current_account_id += 1;
             self.current_voter_id += 1;
@@ -255,7 +254,7 @@ impl EventFixture {
         let expected_events = expected_raw_events
             .iter()
             .map(|ev| EventRecord {
-                phase: Phase::ApplyExtrinsic(0),
+                phase: Phase::Initialization,
                 event: TestEvent::engine(ev.clone()),
                 topics: vec![],
             })
@@ -307,7 +306,7 @@ fn vote_fails_with_insufficient_rights() {
     initial_test_ext().execute_with(|| {
         assert_eq!(
             ProposalsEngine::vote(system::RawOrigin::None.into(), 1, 1, VoteKind::Approve),
-            Err(Error::Other("RequireSignedOrigin"))
+            Err(DispatchError::Other("Bad origin"))
         );
     });
 }
@@ -338,8 +337,8 @@ fn proposal_execution_succeeds() {
             Proposal {
                 parameters: parameters_fixture.params(),
                 proposer_id: 1,
-                created_at: 1,
-                status: ProposalStatus::approved(ApprovedProposalStatus::Executed, 1),
+                created_at: 0,
+                status: ProposalStatus::approved(ApprovedProposalStatus::Executed, 0),
                 title: b"title".to_vec(),
                 description: b"description".to_vec(),
                 voting_results: VotingResults {
@@ -387,10 +386,10 @@ fn proposal_execution_failed() {
             Proposal {
                 parameters: parameters_fixture.params(),
                 proposer_id: 1,
-                created_at: 1,
+                created_at: 0,
                 status: ProposalStatus::approved(
                     ApprovedProposalStatus::failed_execution("ExecutionFailed"),
-                    1
+                    0
                 ),
                 title: b"title".to_vec(),
                 description: b"description".to_vec(),
@@ -457,7 +456,7 @@ fn rejected_voting_results_and_remove_proposal_id_from_active_succeeds() {
         vote_generator.vote_and_assert_ok(VoteKind::Abstain);
         vote_generator.vote_and_assert_ok(VoteKind::Abstain);
 
-        assert!(<ActiveProposalIds<Test>>::exists(proposal_id));
+        assert!(<ActiveProposalIds<Test>>::contains_key(proposal_id));
 
         // internal active proposal counter check
         assert_eq!(<ActiveProposalCount>::get(), 1);
@@ -478,9 +477,9 @@ fn rejected_voting_results_and_remove_proposal_id_from_active_succeeds() {
 
         assert_eq!(
             proposal.status,
-            ProposalStatus::finalized_successfully(ProposalDecisionStatus::Rejected, 1),
+            ProposalStatus::finalized_successfully(ProposalDecisionStatus::Rejected, 0),
         );
-        assert!(!<ActiveProposalIds<Test>>::exists(proposal_id));
+        assert!(!<ActiveProposalIds<Test>>::contains_key(proposal_id));
 
         // internal active proposal counter check
         assert_eq!(<ActiveProposalCount>::get(), 0);
@@ -492,21 +491,22 @@ fn create_proposal_fails_with_invalid_body_or_title() {
     initial_test_ext().execute_with(|| {
         let mut dummy_proposal =
             DummyProposalFixture::default().with_title_and_body(Vec::new(), b"body".to_vec());
-        dummy_proposal.create_proposal_and_assert(Err(Error::EmptyTitleProvided.into()));
+        dummy_proposal.create_proposal_and_assert(Err(Error::<Test>::EmptyTitleProvided.into()));
 
         dummy_proposal =
             DummyProposalFixture::default().with_title_and_body(b"title".to_vec(), Vec::new());
-        dummy_proposal.create_proposal_and_assert(Err(Error::EmptyDescriptionProvided.into()));
+        dummy_proposal
+            .create_proposal_and_assert(Err(Error::<Test>::EmptyDescriptionProvided.into()));
 
         let too_long_title = vec![0; 200];
         dummy_proposal =
             DummyProposalFixture::default().with_title_and_body(too_long_title, b"body".to_vec());
-        dummy_proposal.create_proposal_and_assert(Err(Error::TitleIsTooLong.into()));
+        dummy_proposal.create_proposal_and_assert(Err(Error::<Test>::TitleIsTooLong.into()));
 
         let too_long_body = vec![0; 11000];
         dummy_proposal =
             DummyProposalFixture::default().with_title_and_body(b"title".to_vec(), too_long_body);
-        dummy_proposal.create_proposal_and_assert(Err(Error::DescriptionIsTooLong.into()));
+        dummy_proposal.create_proposal_and_assert(Err(Error::<Test>::DescriptionIsTooLong.into()));
     });
 }
 
@@ -519,7 +519,10 @@ fn vote_fails_with_expired_voting_period() {
         run_to_block_and_finalize(6);
 
         let mut vote_generator = VoteGenerator::new(proposal_id);
-        vote_generator.vote_and_assert(VoteKind::Approve, Err(Error::ProposalFinalized));
+        vote_generator.vote_and_assert(
+            VoteKind::Approve,
+            Err(Error::<Test>::ProposalFinalized.into()),
+        );
     });
 }
 
@@ -538,7 +541,10 @@ fn vote_fails_with_not_active_proposal() {
         run_to_block_and_finalize(2);
 
         let mut vote_generator_to_fail = VoteGenerator::new(proposal_id);
-        vote_generator_to_fail.vote_and_assert(VoteKind::Approve, Err(Error::ProposalFinalized));
+        vote_generator_to_fail.vote_and_assert(
+            VoteKind::Approve,
+            Err(Error::<Test>::ProposalFinalized.into()),
+        );
     });
 }
 
@@ -546,7 +552,10 @@ fn vote_fails_with_not_active_proposal() {
 fn vote_fails_with_absent_proposal() {
     initial_test_ext().execute_with(|| {
         let mut vote_generator = VoteGenerator::new(2);
-        vote_generator.vote_and_assert(VoteKind::Approve, Err(Error::ProposalNotFound));
+        vote_generator.vote_and_assert(
+            VoteKind::Approve,
+            Err(Error::<Test>::ProposalNotFound.into()),
+        );
     });
 }
 
@@ -560,7 +569,7 @@ fn vote_fails_on_double_voting() {
         vote_generator.auto_increment_voter_id = false;
 
         vote_generator.vote_and_assert_ok(VoteKind::Approve);
-        vote_generator.vote_and_assert(VoteKind::Approve, Err(Error::AlreadyVoted));
+        vote_generator.vote_and_assert(VoteKind::Approve, Err(Error::<Test>::AlreadyVoted.into()));
     });
 }
 
@@ -588,8 +597,8 @@ fn cancel_proposal_succeeds() {
             Proposal {
                 parameters: parameters_fixture.params(),
                 proposer_id: 1,
-                created_at: 1,
-                status: ProposalStatus::finalized_successfully(ProposalDecisionStatus::Canceled, 1),
+                created_at: 0,
+                status: ProposalStatus::finalized_successfully(ProposalDecisionStatus::Canceled, 0),
                 title: b"title".to_vec(),
                 description: b"description".to_vec(),
                 voting_results: VotingResults::default(),
@@ -607,7 +616,7 @@ fn cancel_proposal_fails_with_not_active_proposal() {
         run_to_block_and_finalize(6);
 
         let cancel_proposal = CancelProposalFixture::new(proposal_id);
-        cancel_proposal.cancel_and_assert(Err(Error::ProposalFinalized));
+        cancel_proposal.cancel_and_assert(Err(Error::<Test>::ProposalFinalized.into()));
     });
 }
 
@@ -615,7 +624,7 @@ fn cancel_proposal_fails_with_not_active_proposal() {
 fn cancel_proposal_fails_with_not_existing_proposal() {
     initial_test_ext().execute_with(|| {
         let cancel_proposal = CancelProposalFixture::new(2);
-        cancel_proposal.cancel_and_assert(Err(Error::ProposalNotFound));
+        cancel_proposal.cancel_and_assert(Err(Error::<Test>::ProposalNotFound.into()));
     });
 }
 
@@ -628,7 +637,7 @@ fn cancel_proposal_fails_with_insufficient_rights() {
         let cancel_proposal = CancelProposalFixture::new(proposal_id)
             .with_origin(RawOrigin::Signed(2))
             .with_proposer(2);
-        cancel_proposal.cancel_and_assert(Err(Error::NotAuthor));
+        cancel_proposal.cancel_and_assert(Err(Error::<Test>::NotAuthor.into()));
     });
 }
 
@@ -656,8 +665,8 @@ fn veto_proposal_succeeds() {
             Proposal {
                 parameters: parameters_fixture.params(),
                 proposer_id: 1,
-                created_at: 1,
-                status: ProposalStatus::finalized_successfully(ProposalDecisionStatus::Vetoed, 1),
+                created_at: 0,
+                status: ProposalStatus::finalized_successfully(ProposalDecisionStatus::Vetoed, 0),
                 title: b"title".to_vec(),
                 description: b"description".to_vec(),
                 voting_results: VotingResults::default(),
@@ -678,7 +687,7 @@ fn veto_proposal_fails_with_not_active_proposal() {
         run_to_block_and_finalize(6);
 
         let veto_proposal = VetoProposalFixture::new(proposal_id);
-        veto_proposal.veto_and_assert(Err(Error::ProposalFinalized));
+        veto_proposal.veto_and_assert(Err(Error::<Test>::ProposalFinalized.into()));
     });
 }
 
@@ -686,7 +695,7 @@ fn veto_proposal_fails_with_not_active_proposal() {
 fn veto_proposal_fails_with_not_existing_proposal() {
     initial_test_ext().execute_with(|| {
         let veto_proposal = VetoProposalFixture::new(2);
-        veto_proposal.veto_and_assert(Err(Error::ProposalNotFound));
+        veto_proposal.veto_and_assert(Err(Error::<Test>::ProposalNotFound.into()));
     });
 }
 
@@ -697,13 +706,16 @@ fn veto_proposal_fails_with_insufficient_rights() {
         let proposal_id = dummy_proposal.create_proposal_and_assert(Ok(1)).unwrap();
 
         let veto_proposal = VetoProposalFixture::new(proposal_id).with_origin(RawOrigin::Signed(2));
-        veto_proposal.veto_and_assert(Err(Error::RequireRootOrigin));
+        veto_proposal.veto_and_assert(Err(DispatchError::BadOrigin));
     });
 }
 
 #[test]
 fn create_proposal_event_emitted() {
     initial_test_ext().execute_with(|| {
+        // Events start only from 1 first block. No events on block zero.
+        run_to_block_and_finalize(1);
+
         let dummy_proposal = DummyProposalFixture::default();
         dummy_proposal.create_proposal_and_assert(Ok(1));
 
@@ -714,6 +726,9 @@ fn create_proposal_event_emitted() {
 #[test]
 fn veto_proposal_event_emitted() {
     initial_test_ext().execute_with(|| {
+        // Events start only from 1 first block. No events on block zero.
+        run_to_block_and_finalize(1);
+
         let dummy_proposal = DummyProposalFixture::default();
         let proposal_id = dummy_proposal.create_proposal_and_assert(Ok(1)).unwrap();
 
@@ -733,6 +748,9 @@ fn veto_proposal_event_emitted() {
 #[test]
 fn cancel_proposal_event_emitted() {
     initial_test_ext().execute_with(|| {
+        // Events start only from 1 first block. No events on block zero.
+        run_to_block_and_finalize(1);
+
         let dummy_proposal = DummyProposalFixture::default();
         let proposal_id = dummy_proposal.create_proposal_and_assert(Ok(1)).unwrap();
 
@@ -757,6 +775,9 @@ fn cancel_proposal_event_emitted() {
 #[test]
 fn vote_proposal_event_emitted() {
     initial_test_ext().execute_with(|| {
+        // Events start only from 1 first block. No events on block zero.
+        run_to_block_and_finalize(1);
+
         let dummy_proposal = DummyProposalFixture::default();
         let proposal_id = dummy_proposal.create_proposal_and_assert(Ok(1)).unwrap();
 
@@ -787,8 +808,8 @@ fn create_proposal_and_expire_it() {
             Proposal {
                 parameters: parameters_fixture.params(),
                 proposer_id: 1,
-                created_at: 1,
-                status: ProposalStatus::finalized_successfully(ProposalDecisionStatus::Expired, 4),
+                created_at: 0,
+                status: ProposalStatus::finalized_successfully(ProposalDecisionStatus::Expired, 3),
                 title: b"title".to_vec(),
                 description: b"description".to_vec(),
                 voting_results: VotingResults::default(),
@@ -800,7 +821,7 @@ fn create_proposal_and_expire_it() {
 #[test]
 fn proposal_execution_postponed_because_of_grace_period() {
     initial_test_ext().execute_with(|| {
-        let parameters_fixture = ProposalParametersFixture::default().with_grace_period(2);
+        let parameters_fixture = ProposalParametersFixture::default().with_grace_period(3);
         let dummy_proposal =
             DummyProposalFixture::default().with_parameters(parameters_fixture.params());
 
@@ -815,10 +836,10 @@ fn proposal_execution_postponed_because_of_grace_period() {
         run_to_block_and_finalize(1);
         run_to_block_and_finalize(2);
 
-        // check internal cache for proposal_id presense
-        assert!(<PendingExecutionProposalIds<Test>>::enumerate()
-            .find(|(x, _)| *x == proposal_id)
-            .is_some());
+        // check internal cache for proposal_id presence
+        assert!(<PendingExecutionProposalIds<Test>>::contains_key(
+            proposal_id
+        ));
 
         let proposal = <crate::Proposals<Test>>::get(proposal_id);
 
@@ -827,8 +848,8 @@ fn proposal_execution_postponed_because_of_grace_period() {
             Proposal {
                 parameters: parameters_fixture.params(),
                 proposer_id: 1,
-                created_at: 1,
-                status: ProposalStatus::approved(ApprovedProposalStatus::PendingExecution, 1),
+                created_at: 0,
+                status: ProposalStatus::approved(ApprovedProposalStatus::PendingExecution, 0),
                 title: b"title".to_vec(),
                 description: b"description".to_vec(),
                 voting_results: VotingResults {
@@ -845,7 +866,7 @@ fn proposal_execution_postponed_because_of_grace_period() {
 #[test]
 fn proposal_execution_vetoed_successfully_during_the_grace_period() {
     initial_test_ext().execute_with(|| {
-        let parameters_fixture = ProposalParametersFixture::default().with_grace_period(2);
+        let parameters_fixture = ProposalParametersFixture::default().with_grace_period(3);
         let dummy_proposal =
             DummyProposalFixture::default().with_parameters(parameters_fixture.params());
 
@@ -860,10 +881,10 @@ fn proposal_execution_vetoed_successfully_during_the_grace_period() {
         run_to_block_and_finalize(1);
         run_to_block_and_finalize(2);
 
-        // check internal cache for proposal_id presense
-        assert!(<PendingExecutionProposalIds<Test>>::enumerate()
-            .find(|(x, _)| *x == proposal_id)
-            .is_some());
+        // check internal cache for proposal_id presence
+        assert!(<PendingExecutionProposalIds<Test>>::contains_key(
+            proposal_id
+        ));
 
         let proposal = <crate::Proposals<Test>>::get(proposal_id);
 
@@ -872,8 +893,8 @@ fn proposal_execution_vetoed_successfully_during_the_grace_period() {
             Proposal {
                 parameters: parameters_fixture.params(),
                 proposer_id: 1,
-                created_at: 1,
-                status: ProposalStatus::approved(ApprovedProposalStatus::PendingExecution, 1),
+                created_at: 0,
+                status: ProposalStatus::approved(ApprovedProposalStatus::PendingExecution, 0),
                 title: b"title".to_vec(),
                 description: b"description".to_vec(),
                 voting_results: VotingResults {
@@ -895,7 +916,7 @@ fn proposal_execution_vetoed_successfully_during_the_grace_period() {
             Proposal {
                 parameters: parameters_fixture.params(),
                 proposer_id: 1,
-                created_at: 1,
+                created_at: 0,
                 status: ProposalStatus::finalized_successfully(ProposalDecisionStatus::Vetoed, 2),
                 title: b"title".to_vec(),
                 description: b"description".to_vec(),
@@ -908,17 +929,17 @@ fn proposal_execution_vetoed_successfully_during_the_grace_period() {
             }
         );
 
-        // check internal cache for proposal_id presense
-        assert!(<PendingExecutionProposalIds<Test>>::enumerate()
-            .find(|(x, _)| *x == proposal_id)
-            .is_none());
+        // check internal cache for proposal_id absence
+        assert!(!<PendingExecutionProposalIds<Test>>::contains_key(
+            proposal_id
+        ));
     });
 }
 
 #[test]
 fn proposal_execution_succeeds_after_the_grace_period() {
     initial_test_ext().execute_with(|| {
-        let parameters_fixture = ProposalParametersFixture::default().with_grace_period(1);
+        let parameters_fixture = ProposalParametersFixture::default().with_grace_period(2);
         let dummy_proposal =
             DummyProposalFixture::default().with_parameters(parameters_fixture.params());
         let proposal_id = dummy_proposal.create_proposal_and_assert(Ok(1)).unwrap();
@@ -932,17 +953,17 @@ fn proposal_execution_succeeds_after_the_grace_period() {
         run_to_block_and_finalize(1);
 
         // check internal cache for proposal_id presence
-        assert!(<PendingExecutionProposalIds<Test>>::enumerate()
-            .find(|(x, _)| *x == proposal_id)
-            .is_some());
+        assert!(<PendingExecutionProposalIds<Test>>::contains_key(
+            proposal_id
+        ));
 
         let mut proposal = <crate::Proposals<Test>>::get(proposal_id);
 
         let mut expected_proposal = Proposal {
             parameters: parameters_fixture.params(),
             proposer_id: 1,
-            created_at: 1,
-            status: ProposalStatus::approved(ApprovedProposalStatus::PendingExecution, 1),
+            created_at: 0,
+            status: ProposalStatus::approved(ApprovedProposalStatus::PendingExecution, 0),
             title: b"title".to_vec(),
             description: b"description".to_vec(),
             voting_results: VotingResults {
@@ -959,14 +980,14 @@ fn proposal_execution_succeeds_after_the_grace_period() {
 
         proposal = <crate::Proposals<Test>>::get(proposal_id);
 
-        expected_proposal.status = ProposalStatus::approved(ApprovedProposalStatus::Executed, 1);
+        expected_proposal.status = ProposalStatus::approved(ApprovedProposalStatus::Executed, 0);
 
         assert_eq!(proposal, expected_proposal);
 
-        // check internal cache for proposal_id absense
-        assert!(<PendingExecutionProposalIds<Test>>::enumerate()
-            .find(|(x, _)| *x == proposal_id)
-            .is_none());
+        // check internal cache for proposal_id absence
+        assert!(!<PendingExecutionProposalIds<Test>>::contains_key(
+            proposal_id
+        ));
     });
 }
 
@@ -982,7 +1003,7 @@ fn create_proposal_fails_on_exceeding_max_active_proposals_count() {
 
         let dummy_proposal = DummyProposalFixture::default();
         dummy_proposal
-            .create_proposal_and_assert(Err(Error::MaxActiveProposalNumberExceeded.into()));
+            .create_proposal_and_assert(Err(Error::<Test>::MaxActiveProposalNumberExceeded.into()));
         // internal active proposal counter check
         assert_eq!(<ActiveProposalCount>::get(), 100);
     });
@@ -1004,7 +1025,7 @@ fn voting_internal_cache_exists_after_proposal_finalization() {
         vote_generator.vote_and_assert_ok(VoteKind::Abstain);
 
         // cache exists
-        assert!(<crate::VoteExistsByProposalByVoter<Test>>::exists(
+        assert!(<crate::VoteExistsByProposalByVoter<Test>>::contains_key(
             proposal_id,
             1
         ));
@@ -1012,7 +1033,7 @@ fn voting_internal_cache_exists_after_proposal_finalization() {
         run_to_block_and_finalize(2);
 
         // cache still exists and is not cleared
-        assert!(<crate::VoteExistsByProposalByVoter<Test>>::exists(
+        assert!(<crate::VoteExistsByProposalByVoter<Test>>::contains_key(
             proposal_id,
             1
         ));
@@ -1044,7 +1065,7 @@ fn create_dummy_proposal_succeeds_with_stake() {
             Proposal {
                 parameters: parameters_fixture.params(),
                 proposer_id: 1,
-                created_at: 1,
+                created_at: 0,
                 status: ProposalStatus::Active(Some(ActiveStake {
                     stake_id: 0, // valid stake_id
                     source_account_id: 1
@@ -1070,8 +1091,7 @@ fn create_dummy_proposal_fail_with_stake_on_empty_account() {
             .with_account_id(account_id)
             .with_stake(required_stake);
 
-        dummy_proposal
-            .create_proposal_and_assert(Err(Error::Other("too few free funds in account")));
+        dummy_proposal.create_proposal_and_assert(Err(DispatchError::Other("InsufficientBalance")));
     });
 }
 
@@ -1084,20 +1104,21 @@ fn create_proposal_fais_with_invalid_stake_parameters() {
             .with_parameters(parameters_fixture.params())
             .with_stake(200);
 
-        dummy_proposal.create_proposal_and_assert(Err(Error::StakeShouldBeEmpty.into()));
+        dummy_proposal.create_proposal_and_assert(Err(Error::<Test>::StakeShouldBeEmpty.into()));
 
         let parameters_fixture_stake_200 = parameters_fixture.with_required_stake(200);
         dummy_proposal =
             DummyProposalFixture::default().with_parameters(parameters_fixture_stake_200.params());
 
-        dummy_proposal.create_proposal_and_assert(Err(Error::EmptyStake.into()));
+        dummy_proposal.create_proposal_and_assert(Err(Error::<Test>::EmptyStake.into()));
 
         let parameters_fixture_stake_300 = parameters_fixture.with_required_stake(300);
         dummy_proposal = DummyProposalFixture::default()
             .with_parameters(parameters_fixture_stake_300.params())
             .with_stake(200);
 
-        dummy_proposal.create_proposal_and_assert(Err(Error::StakeDiffersFromRequired.into()));
+        dummy_proposal
+            .create_proposal_and_assert(Err(Error::<Test>::StakeDiffersFromRequired.into()));
     });
 }
 
@@ -1141,7 +1162,7 @@ fn finalize_expired_proposal_and_check_stake_removing_with_balance_checks_succee
         let mut expected_proposal = Proposal {
             parameters,
             proposer_id: 1,
-            created_at: 1,
+            created_at: 0,
             status: ProposalStatus::Active(Some(ActiveStake {
                 stake_id: 0,
                 source_account_id: 1,
@@ -1159,7 +1180,7 @@ fn finalize_expired_proposal_and_check_stake_removing_with_balance_checks_succee
 
         expected_proposal.status = ProposalStatus::Finalized(FinalizationData {
             proposal_status: ProposalDecisionStatus::Expired,
-            finalized_at: 4,
+            finalized_at: 3,
             encoded_unstaking_error_due_to_broken_runtime: None,
             stake_data_after_unstaking_error: None,
         });
@@ -1214,7 +1235,7 @@ fn proposal_cancellation_with_slashes_with_balance_checks_succeeds() {
         let mut expected_proposal = Proposal {
             parameters,
             proposer_id: 1,
-            created_at: 1,
+            created_at: 0,
             status: ProposalStatus::Active(Some(ActiveStake {
                 stake_id: 0,
                 source_account_id: 1,
@@ -1234,7 +1255,7 @@ fn proposal_cancellation_with_slashes_with_balance_checks_succeeds() {
 
         expected_proposal.status = ProposalStatus::Finalized(FinalizationData {
             proposal_status: ProposalDecisionStatus::Canceled,
-            finalized_at: 1,
+            finalized_at: 0,
             encoded_unstaking_error_due_to_broken_runtime: None,
             stake_data_after_unstaking_error: None,
         });
@@ -1302,7 +1323,7 @@ fn proposal_slashing_succeeds() {
         vote_generator.vote_and_assert_ok(VoteKind::Slash);
         vote_generator.vote_and_assert_ok(VoteKind::Slash);
 
-        assert!(<ActiveProposalIds<Test>>::exists(proposal_id));
+        assert!(<ActiveProposalIds<Test>>::contains_key(proposal_id));
 
         run_to_block_and_finalize(2);
 
@@ -1323,11 +1344,11 @@ fn proposal_slashing_succeeds() {
             ProposalStatus::Finalized(FinalizationData {
                 proposal_status: ProposalDecisionStatus::Slashed,
                 encoded_unstaking_error_due_to_broken_runtime: None,
-                finalized_at: 1,
+                finalized_at: 0,
                 stake_data_after_unstaking_error: None,
             }),
         );
-        assert!(!<ActiveProposalIds<Test>>::exists(proposal_id));
+        assert!(!<ActiveProposalIds<Test>>::contains_key(proposal_id));
     });
 }
 
@@ -1377,7 +1398,7 @@ fn finalize_proposal_using_stake_mocks_failed() {
                 Proposal {
                     parameters: parameters_fixture.params(),
                     proposer_id: 1,
-                    created_at: 1,
+                    created_at: 0,
                     status: ProposalStatus::finalized(
                         ProposalDecisionStatus::Expired,
                         Some("Cannot remove stake"),
@@ -1385,7 +1406,7 @@ fn finalize_proposal_using_stake_mocks_failed() {
                             stake_id: 1,
                             source_account_id: 1
                         }),
-                        4,
+                        3,
                     ),
                     title: b"title".to_vec(),
                     description: b"description".to_vec(),
@@ -1411,15 +1432,17 @@ fn create_proposal_fails_with_invalid_threshold_parameters() {
 
         let mut dummy_proposal = DummyProposalFixture::default().with_parameters(parameters);
 
-        dummy_proposal
-            .create_proposal_and_assert(Err(Error::InvalidParameterApprovalThreshold.into()));
+        dummy_proposal.create_proposal_and_assert(Err(
+            Error::<Test>::InvalidParameterApprovalThreshold.into(),
+        ));
 
         parameters.approval_threshold_percentage = 60;
         parameters.slashing_threshold_percentage = 0;
         dummy_proposal = DummyProposalFixture::default().with_parameters(parameters);
 
-        dummy_proposal
-            .create_proposal_and_assert(Err(Error::InvalidParameterSlashingThreshold.into()));
+        dummy_proposal.create_proposal_and_assert(Err(
+            Error::<Test>::InvalidParameterSlashingThreshold.into(),
+        ));
     });
 }
 
@@ -1434,7 +1457,7 @@ fn proposal_reset_succeeds() {
         vote_generator.vote_and_assert_ok(VoteKind::Abstain);
         vote_generator.vote_and_assert_ok(VoteKind::Slash);
 
-        assert!(<ActiveProposalIds<Test>>::exists(proposal_id));
+        assert!(<ActiveProposalIds<Test>>::contains_key(proposal_id));
         assert_eq!(
             <VoteExistsByProposalByVoter<Test>>::get(&proposal_id, &2),
             VoteKind::Abstain

+ 8 - 8
runtime-modules/proposals/engine/src/types/mod.rs

@@ -4,15 +4,15 @@
 #![warn(missing_docs)]
 
 use codec::{Decode, Encode};
-use rstd::cmp::PartialOrd;
-use rstd::ops::Add;
-use rstd::prelude::*;
-
+use frame_support::dispatch::DispatchResult;
+use frame_support::traits::Currency;
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
-use sr_primitives::Perbill;
-use srml_support::dispatch;
-use srml_support::traits::Currency;
+use sp_runtime::Perbill;
+use sp_std::boxed::Box;
+use sp_std::cmp::PartialOrd;
+use sp_std::ops::Add;
+use sp_std::vec::Vec;
 
 mod proposal_statuses;
 mod stakes;
@@ -304,7 +304,7 @@ where
 /// Proposal executable code wrapper
 pub trait ProposalExecutable {
     /// Executes proposal code
-    fn execute(&self) -> dispatch::Result;
+    fn execute(&self) -> DispatchResult;
 }
 
 /// Proposal code binary converter

+ 3 - 3
runtime-modules/proposals/engine/src/types/proposal_statuses.rs

@@ -1,11 +1,11 @@
 #![warn(missing_docs)]
 
 use codec::{Decode, Encode};
-use rstd::prelude::*;
-
-use crate::ActiveStake;
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
+use sp_std::vec::Vec;
+
+use crate::ActiveStake;
 
 /// Current status of the proposal
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]

+ 5 - 4
runtime-modules/proposals/engine/src/types/stakes.rs

@@ -2,10 +2,10 @@
 
 use super::{BalanceOf, CurrencyOf, NegativeImbalance};
 use crate::Trait;
-use rstd::convert::From;
-use rstd::marker::PhantomData;
-use rstd::rc::Rc;
-use srml_support::traits::{Currency, ExistenceRequirement, WithdrawReasons};
+use frame_support::traits::{Currency, ExistenceRequirement, WithdrawReasons};
+use sp_std::convert::From;
+use sp_std::marker::PhantomData;
+use sp_std::rc::Rc;
 
 // Mocking dependencies for testing
 #[cfg(test)]
@@ -123,6 +123,7 @@ impl<T: Trait> StakeHandler<T> for DefaultStakeHandler<T> {
             WithdrawReasons::all(),
             ExistenceRequirement::AllowDeath,
         )
+        .map_err(<&str>::from)
     }
 }
 

+ 14 - 41
runtime-modules/recurring-reward/Cargo.toml

@@ -1,56 +1,29 @@
 [package]
-name = 'substrate-recurring-reward-module'
-version = '1.0.1'
+name = 'pallet-recurring-reward'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
 [dependencies]
-hex-literal = '0.1.0'
-serde = { version = '1.0', optional = true }
-serde_derive = { version = '1.0', optional = true }
-rstd = { package = 'sr-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-runtime-primitives = { package = 'sr-primitives', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-srml-support = { package = 'srml-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-srml-support-procedural = { package = 'srml-support-procedural', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-system = { package = 'srml-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-balances = { package = 'srml-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-codec = { package = 'parity-scale-codec', version = '1.0.0', default-features = false, features = ['derive'] }
-# https://users.rust-lang.org/t/failure-derive-compilation-error/39062
-quote = '<=1.0.2'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.minting]
-default_features = false
-package = 'substrate-token-mint-module'
-path = '../token-minting'
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+minting = { package = 'pallet-token-mint', default-features = false, path = '../token-minting'}
 
 [dev-dependencies]
-runtime-io = { package = 'sr-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-primitives = { package = 'substrate-primitives', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
 
 [features]
 default = ['std']
 std = [
-	'serde',
-	'serde_derive',
 	'codec/std',
-	'rstd/std',
-	'runtime-io/std',
-	'runtime-primitives/std',
-	'srml-support/std',
+	'sp-arithmetic/std',
+	'sp-runtime/std',
+	'frame-support/std',
 	'system/std',
-  	'balances/std',
-	'timestamp/std',
 	'minting/std',
 ]

+ 19 - 16
runtime-modules/recurring-reward/src/lib.rs

@@ -7,13 +7,14 @@
 
 // Ensure we're `no_std` when compiling for Wasm.
 #![cfg_attr(not(feature = "std"), no_std)]
-use rstd::prelude::*;
 
 use codec::{Codec, Decode, Encode};
-use runtime_primitives::traits::{MaybeSerialize, Member, One, SimpleArithmetic, Zero};
-use srml_support::{decl_module, decl_storage, ensure, Parameter};
+use frame_support::storage::IterableStorageMap;
+use frame_support::{decl_module, decl_storage, ensure, Parameter};
+use sp_arithmetic::traits::{BaseArithmetic, One, Zero};
+use sp_runtime::traits::{MaybeSerialize, Member};
 
-use minting::{self, BalanceOf};
+use minting::BalanceOf;
 
 mod mock;
 mod tests;
@@ -24,7 +25,7 @@ pub trait Trait: system::Trait + minting::Trait {
     /// Type of identifier for recipients.
     type RecipientId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -34,7 +35,7 @@ pub trait Trait: system::Trait + minting::Trait {
     /// Type for identifier for relationship representing that a recipient recieves recurring reward from a token mint
     type RewardRelationshipId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -142,13 +143,15 @@ impl<AccountId: Clone, Balance: Clone, BlockNumber: Clone, MintId: Clone, Recipi
 
 decl_storage! {
     trait Store for Module<T: Trait> as RecurringReward {
-        Recipients get(recipients): linked_map T::RecipientId => Recipient<BalanceOf<T>>;
+        Recipients get(fn recipients): map hasher(blake2_128_concat)
+            T::RecipientId => Recipient<BalanceOf<T>>;
 
-        RecipientsCreated get(recipients_created): T::RecipientId;
+        RecipientsCreated get(fn recipients_created): T::RecipientId;
 
-        pub RewardRelationships get(reward_relationships): linked_map T::RewardRelationshipId => RewardRelationship<T::AccountId, BalanceOf<T>, T::BlockNumber, T::MintId, T::RecipientId>;
+        pub RewardRelationships get(fn reward_relationships): map hasher(blake2_128_concat)
+            T::RewardRelationshipId => RewardRelationship<T::AccountId, BalanceOf<T>, T::BlockNumber, T::MintId, T::RecipientId>;
 
-        RewardRelationshipsCreated get(reward_relationships_created): T::RewardRelationshipId;
+        RewardRelationshipsCreated get(fn reward_relationships_created): T::RewardRelationshipId;
     }
 }
 
@@ -192,7 +195,7 @@ impl<T: Trait> Module<T> {
             RewardsError::RewardSourceNotFound
         );
         ensure!(
-            <Recipients<T>>::exists(recipient),
+            <Recipients<T>>::contains_key(recipient),
             RewardsError::RecipientNotFound
         );
         ensure!(
@@ -220,7 +223,7 @@ impl<T: Trait> Module<T> {
 
     /// Removes a relationship from RewardRelashionships and its recipient.
     pub fn remove_reward_relationship(id: T::RewardRelationshipId) {
-        if <RewardRelationships<T>>::exists(&id) {
+        if <RewardRelationships<T>>::contains_key(&id) {
             <Recipients<T>>::remove(<RewardRelationships<T>>::take(&id).recipient);
         }
     }
@@ -282,7 +285,7 @@ impl<T: Trait> Module<T> {
         new_payout_interval: Option<Option<T::BlockNumber>>,
     ) -> Result<(), RewardsError> {
         ensure!(
-            <RewardRelationships<T>>::exists(&id),
+            <RewardRelationships<T>>::contains_key(&id),
             RewardsError::RewardRelationshipNotFound
         );
 
@@ -320,8 +323,8 @@ impl<T: Trait> Module<T> {
     Otherwise, analogous steps for failure.
     */
     fn do_payouts(now: T::BlockNumber) {
-        for (relationship_id, ref mut relationship) in <RewardRelationships<T>>::enumerate() {
-            assert!(<Recipients<T>>::exists(&relationship.recipient));
+        for (relationship_id, ref mut relationship) in <RewardRelationships<T>>::iter() {
+            assert!(<Recipients<T>>::contains_key(&relationship.recipient));
 
             let mut recipient = Self::recipients(relationship.recipient);
 
@@ -394,7 +397,7 @@ impl<T: Trait> Module<T> {
         RewardRelationship<T::AccountId, BalanceOf<T>, T::BlockNumber, T::MintId, T::RecipientId>,
         (),
     > {
-        ensure!(RewardRelationships::<T>::exists(id), ());
+        ensure!(RewardRelationships::<T>::contains_key(id), ());
 
         let relationship = RewardRelationships::<T>::get(id);
 

+ 16 - 22
runtime-modules/recurring-reward/src/mock/mod.rs

@@ -1,18 +1,16 @@
 #![cfg(test)]
 
-// use crate::*;
 use crate::{Module, Trait};
 
-use primitives::H256;
-
 use balances;
+use frame_support::{impl_outer_origin, parameter_types};
 use minting;
-use runtime_primitives::{
+use sp_core::H256;
+use sp_runtime::{
     testing::Header,
     traits::{BlakeTwo256, IdentityLookup},
     Perbill,
 };
-use srml_support::{impl_outer_origin, parameter_types};
 
 mod status_handler;
 pub use status_handler::MockStatusHandler;
@@ -33,10 +31,11 @@ parameter_types! {
 }
 
 impl system::Trait for Test {
+    type BaseCallFilter = ();
     type Origin = Origin;
+    type Call = ();
     type Index = u64;
     type BlockNumber = u64;
-    type Call = ();
     type Hash = H256;
     type Hashing = BlakeTwo256;
     type AccountId = u64;
@@ -45,34 +44,29 @@ impl system::Trait for Test {
     type Event = ();
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
 parameter_types! {
     pub const ExistentialDeposit: u32 = 0;
-    pub const TransferFee: u32 = 0;
-    pub const CreationFee: u32 = 0;
-    pub const TransactionBaseFee: u32 = 1;
-    pub const TransactionByteFee: u32 = 0;
 }
 
 impl balances::Trait for Test {
-    /// The type for recording an account's balance.
     type Balance = u64;
-    /// What to do if an account's free balance gets zeroed.
-    type OnFreeBalanceZero = ();
-    /// What to do if a new account is created.
-    type OnNewAccount = ();
-    /// The ubiquitous event type.
-    type Event = ();
-
     type DustRemoval = ();
-    type TransferPayment = ();
+    type Event = ();
     type ExistentialDeposit = ExistentialDeposit;
-    type TransferFee = TransferFee;
-    type CreationFee = CreationFee;
+    type AccountStore = System;
 }
 
 impl Trait for Test {
@@ -86,7 +80,7 @@ impl minting::Trait for Test {
     type MintId = u64;
 }
 
-pub fn build_test_externalities() -> runtime_io::TestExternalities {
+pub fn build_test_externalities() -> sp_io::TestExternalities {
     MockStatusHandler::reset();
 
     let t = system::GenesisConfig::default()

+ 4 - 4
runtime-modules/recurring-reward/src/tests.rs

@@ -2,7 +2,7 @@
 
 use super::*;
 use crate::mock::*;
-use srml_support::traits::Currency;
+use frame_support::traits::Currency;
 
 fn create_new_mint_with_capacity(capacity: u64) -> u64 {
     let mint_id = Minting::add_mint(capacity, None).ok().unwrap();
@@ -15,9 +15,9 @@ fn create_new_mint_with_capacity(capacity: u64) -> u64 {
 fn adding_recipients() {
     build_test_externalities().execute_with(|| {
         let next_id = Rewards::recipients_created();
-        assert!(!<Recipients<Test>>::exists(&next_id));
+        assert!(!<Recipients<Test>>::contains_key(&next_id));
         let recipient_id = Rewards::add_recipient();
-        assert!(<Recipients<Test>>::exists(&next_id));
+        assert!(<Recipients<Test>>::contains_key(&next_id));
         assert_eq!(recipient_id, next_id);
         assert_eq!(Rewards::recipients_created(), next_id + 1);
     });
@@ -49,7 +49,7 @@ fn adding_relationships() {
             Rewards::reward_relationships_created(),
             next_relationship_id + 1
         );
-        assert!(<RewardRelationships<Test>>::exists(&relationship_id));
+        assert!(<RewardRelationships<Test>>::contains_key(&relationship_id));
         let relationship = Rewards::reward_relationships(&relationship_id);
         assert_eq!(relationship.next_payment_at_block, Some(next_payment_at));
         assert_eq!(relationship.amount_per_payout, payout);

+ 30 - 104
runtime-modules/service-discovery/Cargo.toml

@@ -1,112 +1,38 @@
 [package]
-name = 'substrate-service-discovery-module'
-version = '2.0.0'
+name = 'pallet-service-discovery'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
+[dependencies]
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+working-group = { package = 'pallet-working-group', default-features = false, path = '../working-group'}
+
+[dev-dependencies]
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+membership = { package = 'pallet-membership', default-features = false, path = '../membership'}
+stake = { package = 'pallet-stake', default-features = false, path = '../stake'}
+hiring = { package = 'pallet-hiring', default-features = false, path = '../hiring'}
+minting = { package = 'pallet-token-mint', default-features = false, path = '../token-minting'}
+recurringrewards = { package = 'pallet-recurring-reward', default-features = false, path = '../recurring-reward'}
+common = { package = 'pallet-common', default-features = false, path = '../common'}
+
 [features]
 default = ['std']
 std = [
-	'sr-primitives/std',
-	'srml-support/std',
-	'system/std',
-	'rstd/std',
 	'serde',
-    'codec/std',
-    'primitives/std',
-    'working-group/std',
-]
-
-[dependencies.sr-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.srml-support]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-support'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.common]
-default_features = false
-package = 'substrate-common-module'
-path = '../common'
-
-[dependencies.system]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-system'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.rstd]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-std'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.serde]
-features = ['derive']
-optional = true
-version = '1.0.101'
-
-[dependencies.primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dev-dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.working-group]
-default_features = false
-package = 'substrate-working-group-module'
-path = '../working-group'
-
-[dev-dependencies.balances]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-balances'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dev-dependencies.recurringrewards]
-default_features = false
-package = 'substrate-recurring-reward-module'
-path = '../recurring-reward'
-
-[dev-dependencies.hiring]
-default_features = false
-package = 'substrate-hiring-module'
-path = '../hiring'
-
-[dev-dependencies.stake]
-default_features = false
-package = 'substrate-stake-module'
-path = '../stake'
-
-[dev-dependencies.minting]
-default_features = false
-package = 'substrate-token-mint-module'
-path = '../token-minting'
-
-[dev-dependencies.membership]
-default_features = false
-package = 'substrate-membership-module'
-path = '../membership'
-
-[dev-dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
+	'codec/std',
+	'sp-std/std',
+	'frame-support/std',
+	'system/std',
+	'sp-runtime/std',
+	'working-group/std',
+]

+ 21 - 17
runtime-modules/service-discovery/src/lib.rs

@@ -10,8 +10,8 @@
 //!
 //! ## Supported extrinsics
 //!
-//! - [set_ipns_id](./struct.Module.html#method.set_ipns_id) - Creates the AccountInfo to save an IPNS identity for the storage provider.
-//! - [unset_ipns_id](./struct.Module.html#method.unset_ipns_id) - Deletes the AccountInfo with the IPNS identity for the storage provider.
+//! - [set_ipns_id](./struct.Module.html#method.set_ipns_id) - Creates the ServiceProviderRecord to save an IPNS identity for the storage provider.
+//! - [unset_ipns_id](./struct.Module.html#method.unset_ipns_id) - Deletes the ServiceProviderRecord with the IPNS identity for the storage provider.
 //! - [set_default_lifetime](./struct.Module.html#method.set_default_lifetime) - Sets default lifetime for storage providers accounts info.
 //! - [set_bootstrap_endpoints](./struct.Module.html#method.set_bootstrap_endpoints) - Sets bootstrap endpoints for the Colossus.
 //!
@@ -23,12 +23,12 @@ mod mock;
 mod tests;
 
 use codec::{Decode, Encode};
-use rstd::prelude::*;
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
 
-use srml_support::{decl_event, decl_module, decl_storage, ensure};
-use system::{self, ensure_root};
+use frame_support::{decl_event, decl_module, decl_storage, ensure};
+use sp_std::vec::Vec;
+use system::ensure_root;
 /*
   Although there is support for ed25519 keys as the IPNS identity key and we could potentially
   reuse the same key for the role account and ipns (and make this discovery module obselete)
@@ -63,7 +63,7 @@ pub(crate) const DEFAULT_LIFETIME: u32 = MINIMUM_LIFETIME * 24; // 24hr
 /// Defines the expiration date for the storage provider.
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
 #[derive(Encode, Decode, Default, Clone, PartialEq, Eq)]
-pub struct AccountInfo<BlockNumber> {
+pub struct ServiceProviderRecord<BlockNumber> {
     /// IPNS Identity.
     pub identity: IPNSIdentity,
     /// Block at which information expires.
@@ -79,14 +79,14 @@ pub trait Trait: system::Trait + working_group::Trait<StorageWorkingGroupInstanc
 decl_storage! {
     trait Store for Module<T: Trait> as Discovery {
         /// Bootstrap endpoints maintained by root
-        pub BootstrapEndpoints get(bootstrap_endpoints): Vec<Url>;
+        pub BootstrapEndpoints get(fn bootstrap_endpoints): Vec<Url>;
 
-        /// Mapping of service providers' storage provider id to their AccountInfo
-        pub AccountInfoByStorageProviderId get(account_info_by_storage_provider_id):
-            map StorageProviderId<T> => AccountInfo<T::BlockNumber>;
+        /// Mapping of service providers' storage provider id to their ServiceProviderRecord
+        pub AccountInfoByStorageProviderId get(fn account_info_by_storage_provider_id):
+            map hasher(blake2_128_concat) StorageProviderId<T> => ServiceProviderRecord<T::BlockNumber>;
 
-        /// Lifetime of an AccountInfo record in AccountInfoByAccountId map
-        pub DefaultLifetime get(default_lifetime) config():
+        /// Lifetime of an ServiceProviderRecord record in AccountInfoByAccountId map
+        pub DefaultLifetime get(fn default_lifetime) config():
             T::BlockNumber = T::BlockNumber::from(DEFAULT_LIFETIME);
     }
 }
@@ -115,8 +115,9 @@ decl_module! {
         /// Default deposit_event() handler
         fn deposit_event() = default;
 
-        /// Creates the AccountInfo to save an IPNS identity for the storage provider.
+        /// Creates the ServiceProviderRecord to save an IPNS identity for the storage provider.
         /// Requires signed storage provider credentials.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_ipns_id(
             origin,
             storage_provider_id: StorageProviderId<T>,
@@ -130,7 +131,7 @@ decl_module! {
             // == MUTATION SAFE ==
             //
 
-            <AccountInfoByStorageProviderId<T>>::insert(storage_provider_id, AccountInfo {
+            <AccountInfoByStorageProviderId<T>>::insert(storage_provider_id, ServiceProviderRecord {
                 identity: id.clone(),
                 expires_at: <system::Module<T>>::block_number() + Self::default_lifetime(),
             });
@@ -138,14 +139,15 @@ decl_module! {
             Self::deposit_event(RawEvent::AccountInfoUpdated(storage_provider_id, id));
         }
 
-        /// Deletes the AccountInfo with the IPNS identity for the storage provider.
+        /// Deletes the ServiceProviderRecord with the IPNS identity for the storage provider.
         /// Requires signed storage provider credentials.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn unset_ipns_id(origin, storage_provider_id: StorageProviderId<T>) {
             <StorageWorkingGroup<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
 
             // == MUTATION SAFE ==
 
-            if <AccountInfoByStorageProviderId<T>>::exists(storage_provider_id) {
+            if <AccountInfoByStorageProviderId<T>>::contains_key(storage_provider_id) {
                 <AccountInfoByStorageProviderId<T>>::remove(storage_provider_id);
                 Self::deposit_event(RawEvent::AccountInfoRemoved(storage_provider_id));
             }
@@ -154,6 +156,7 @@ decl_module! {
         // Privileged methods
 
         /// Sets default lifetime for storage providers accounts info. Requires root privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_default_lifetime(origin, lifetime: T::BlockNumber) {
             ensure_root(origin)?;
             ensure!(lifetime >= T::BlockNumber::from(MINIMUM_LIFETIME),
@@ -165,6 +168,7 @@ decl_module! {
         }
 
         /// Sets bootstrap endpoints for the Colossus. Requires root privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_bootstrap_endpoints(origin, endpoints: Vec<Url>) {
             ensure_root(origin)?;
 
@@ -178,7 +182,7 @@ decl_module! {
 impl<T: Trait> Module<T> {
     /// Verifies that account info for the storage provider is still valid.
     pub fn is_account_info_expired(storage_provider_id: &StorageProviderId<T>) -> bool {
-        !<AccountInfoByStorageProviderId<T>>::exists(storage_provider_id)
+        !<AccountInfoByStorageProviderId<T>>::contains_key(storage_provider_id)
             || <system::Module<T>>::block_number()
                 > <AccountInfoByStorageProviderId<T>>::get(storage_provider_id).expires_at
     }

+ 21 - 18
runtime-modules/service-discovery/src/mock.rs

@@ -2,15 +2,14 @@
 
 pub use crate::*;
 
-pub use primitives::{Blake2Hasher, H256};
-pub use sr_primitives::{
-    testing::{Digest, DigestItem, Header, UintAuthorityId},
-    traits::{BlakeTwo256, IdentityLookup, OnFinalize},
-    BuildStorage, Perbill,
+use frame_support::{impl_outer_event, impl_outer_origin, parameter_types};
+use sp_core::H256;
+use sp_runtime::{
+    testing::Header,
+    traits::{BlakeTwo256, IdentityLookup},
+    Perbill,
 };
 
-use srml_support::{impl_outer_event, impl_outer_origin, parameter_types};
-
 // The storage working group instance alias.
 pub type StorageWorkingGroupInstance = working_group::Instance2;
 
@@ -37,7 +36,8 @@ impl_outer_event! {
         discovery<T>,
         balances<T>,
         membership_mod<T>,
-         working_group_mod StorageWorkingGroupInstance <T>,
+        working_group_mod StorageWorkingGroupInstance <T>,
+        system<T>,
     }
 }
 
@@ -52,15 +52,14 @@ parameter_types! {
     pub const MinimumPeriod: u64 = 5;
     pub const StakePoolId: [u8; 8] = *b"joystake";
     pub const ExistentialDeposit: u32 = 0;
-    pub const TransferFee: u32 = 0;
-    pub const CreationFee: u32 = 0;
 }
 
 impl system::Trait for Test {
+    type BaseCallFilter = ();
     type Origin = Origin;
+    type Call = ();
     type Index = u64;
     type BlockNumber = u64;
-    type Call = ();
     type Hash = H256;
     type Hashing = BlakeTwo256;
     type AccountId = u64;
@@ -69,9 +68,17 @@ impl system::Trait for Test {
     type Event = MetaEvent;
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
 impl Trait for Test {
@@ -112,14 +119,10 @@ impl common::currency::GovernanceCurrency for Test {
 
 impl balances::Trait for Test {
     type Balance = u64;
-    type OnFreeBalanceZero = ();
-    type OnNewAccount = ();
-    type TransferPayment = ();
     type DustRemoval = ();
     type Event = MetaEvent;
     type ExistentialDeposit = ExistentialDeposit;
-    type TransferFee = TransferFee;
-    type CreationFee = CreationFee;
+    type AccountStore = System;
 }
 
 impl recurringrewards::Trait for Test {
@@ -137,13 +140,13 @@ impl working_group::Trait<StorageWorkingGroupInstance> for Test {
     type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
 }
 
-impl timestamp::Trait for Test {
+impl pallet_timestamp::Trait for Test {
     type Moment = u64;
     type OnTimestampSet = ();
     type MinimumPeriod = MinimumPeriod;
 }
 
-pub fn initial_test_ext() -> runtime_io::TestExternalities {
+pub fn initial_test_ext() -> sp_io::TestExternalities {
     let t = system::GenesisConfig::default()
         .build_storage::<Test>()
         .unwrap();

+ 18 - 15
runtime-modules/service-discovery/src/tests.rs

@@ -2,8 +2,7 @@
 
 use super::mock::*;
 
-use srml_support::*;
-use system::{self, EventRecord, Phase};
+use system::{EventRecord, Phase, RawOrigin};
 
 #[test]
 fn set_ipns_id() {
@@ -22,13 +21,13 @@ fn set_ipns_id() {
         )
         .is_ok());
 
-        assert!(<AccountInfoByStorageProviderId<Test>>::exists(
+        assert!(<AccountInfoByStorageProviderId<Test>>::contains_key(
             &storage_provider_id
         ));
         let account_info = Discovery::account_info_by_storage_provider_id(&storage_provider_id);
         assert_eq!(
             account_info,
-            AccountInfo {
+            ServiceProviderRecord {
                 identity: identity.clone(),
                 expires_at: current_block_number + ttl
             }
@@ -37,7 +36,7 @@ fn set_ipns_id() {
         assert_eq!(
             *System::events().last().unwrap(),
             EventRecord {
-                phase: Phase::ApplyExtrinsic(0),
+                phase: Phase::Initialization,
                 event: MetaEvent::discovery(RawEvent::AccountInfoUpdated(
                     storage_provider_id,
                     identity.clone()
@@ -55,7 +54,7 @@ fn set_ipns_id() {
             identity.clone(),
         )
         .is_err());
-        assert!(!<AccountInfoByStorageProviderId<Test>>::exists(
+        assert!(!<AccountInfoByStorageProviderId<Test>>::contains_key(
             &invalid_storage_provider_id
         ));
     });
@@ -64,17 +63,20 @@ fn set_ipns_id() {
 #[test]
 fn unset_ipns_id() {
     initial_test_ext().execute_with(|| {
+        let current_block_number = 1000;
+        System::set_block_number(current_block_number);
+
         let (storage_provider_account_id, storage_provider_id) = hire_storage_provider();
 
         <AccountInfoByStorageProviderId<Test>>::insert(
             &storage_provider_id,
-            AccountInfo {
+            ServiceProviderRecord {
                 expires_at: 1000,
                 identity: "alice".as_bytes().to_vec(),
             },
         );
 
-        assert!(<AccountInfoByStorageProviderId<Test>>::exists(
+        assert!(<AccountInfoByStorageProviderId<Test>>::contains_key(
             &storage_provider_account_id
         ));
 
@@ -83,14 +85,14 @@ fn unset_ipns_id() {
             storage_provider_id
         )
         .is_ok());
-        assert!(!<AccountInfoByStorageProviderId<Test>>::exists(
+        assert!(!<AccountInfoByStorageProviderId<Test>>::contains_key(
             &storage_provider_account_id
         ));
 
         assert_eq!(
             *System::events().last().unwrap(),
             EventRecord {
-                phase: Phase::ApplyExtrinsic(0),
+                phase: Phase::Initialization,
                 event: MetaEvent::discovery(RawEvent::AccountInfoRemoved(storage_provider_id)),
                 topics: vec![]
             }
@@ -104,7 +106,7 @@ fn unset_ipns_id() {
             invalid_storage_provider_account_id,
         )
         .is_err());
-        assert!(!<AccountInfoByStorageProviderId<Test>>::exists(
+        assert!(!<AccountInfoByStorageProviderId<Test>>::contains_key(
             &invalid_storage_provider_id
         ));
     });
@@ -118,7 +120,7 @@ fn is_account_info_expired() {
         let id = "alice".as_bytes().to_vec();
         <AccountInfoByStorageProviderId<Test>>::insert(
             &storage_provider_id,
-            AccountInfo {
+            ServiceProviderRecord {
                 expires_at,
                 identity: id.clone(),
             },
@@ -142,7 +144,7 @@ fn set_default_lifetime() {
             ""
         );
         assert!(
-            Discovery::set_default_lifetime(Origin::ROOT, lifetime).is_ok(),
+            Discovery::set_default_lifetime(RawOrigin::Root.into(), lifetime).is_ok(),
             ""
         );
         assert_eq!(Discovery::default_lifetime(), lifetime, "");
@@ -151,7 +153,8 @@ fn set_default_lifetime() {
         let less_than_min_lifetime =
             <Test as system::Trait>::BlockNumber::from(MINIMUM_LIFETIME - 1);
         assert!(
-            Discovery::set_default_lifetime(Origin::ROOT, less_than_min_lifetime).is_err(),
+            Discovery::set_default_lifetime(RawOrigin::Root.into(), less_than_min_lifetime)
+                .is_err(),
             ""
         );
     });
@@ -167,7 +170,7 @@ fn set_bootstrap_endpoints() {
             ""
         );
         assert!(
-            Discovery::set_bootstrap_endpoints(Origin::ROOT, endpoints.clone()).is_ok(),
+            Discovery::set_bootstrap_endpoints(RawOrigin::Root.into(), endpoints.clone()).is_ok(),
             ""
         );
         assert_eq!(Discovery::bootstrap_endpoints(), endpoints, "");

+ 17 - 37
runtime-modules/stake/Cargo.toml

@@ -1,50 +1,30 @@
 [package]
-name = 'substrate-stake-module'
-version = '2.0.0'
+name = 'pallet-stake'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
 [dependencies]
-hex-literal = '0.1.0'
-serde = { version = '1.0', optional = true }
-serde_derive = { version = '1.0', optional = true }
-rstd = { package = 'sr-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-runtime-primitives = { package = 'sr-primitives', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-srml-support = { package = 'srml-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-srml-support-procedural = { package = 'srml-support-procedural', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-system = { package = 'srml-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-balances = { package = 'srml-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-codec = { package = 'parity-scale-codec', version = '1.0.0', default-features = false, features = ['derive'] }
-# https://users.rust-lang.org/t/failure-derive-compilation-error/39062
-quote = '<=1.0.2'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
 
 [dev-dependencies]
-runtime-io = { package = 'sr-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
-primitives = { package = 'substrate-primitives', git = 'https://github.com/paritytech/substrate.git', rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'}
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
 
 [features]
 default = ['std']
 std = [
-	'serde',
-	'serde_derive',
 	'codec/std',
-	'rstd/std',
-	'runtime-io/std',
-	'runtime-primitives/std',
-	'srml-support/std',
+	'sp-std/std',
+	'frame-support/std',
 	'system/std',
-  	'balances/std',
-	'timestamp/std',
-]
+	'sp-arithmetic/std',
+	'sp-runtime/std',
+]

+ 25 - 29
runtime-modules/stake/src/lib.rs

@@ -1,17 +1,15 @@
 // Ensure we're `no_std` when compiling for Wasm.
 #![cfg_attr(not(feature = "std"), no_std)]
 
-use rstd::prelude::*;
-
 use codec::{Codec, Decode, Encode};
-use runtime_primitives::traits::{
-    AccountIdConversion, MaybeSerialize, Member, One, SimpleArithmetic, Zero,
-};
-use runtime_primitives::ModuleId;
-use srml_support::traits::{Currency, ExistenceRequirement, Get, Imbalance, WithdrawReasons};
-use srml_support::{decl_module, decl_storage, ensure, Parameter};
-
-use rstd::collections::btree_map::BTreeMap;
+use frame_support::storage::IterableStorageMap;
+use frame_support::traits::{Currency, ExistenceRequirement, Get, Imbalance, WithdrawReasons};
+use frame_support::{decl_module, decl_storage, ensure, Parameter};
+use sp_arithmetic::traits::{BaseArithmetic, One, Zero};
+use sp_runtime::traits::{AccountIdConversion, MaybeSerialize, Member};
+use sp_runtime::ModuleId;
+use sp_std::collections::btree_map::BTreeMap;
+use sp_std::prelude::*;
 
 mod errors;
 pub use errors::*;
@@ -38,7 +36,7 @@ pub trait Trait: system::Trait + Sized {
     /// The type used as a stake identifier.
     type StakeId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -48,7 +46,7 @@ pub trait Trait: system::Trait + Sized {
     /// The type used as slash identifier.
     type SlashId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -201,8 +199,8 @@ pub struct StakedState<BlockNumber, Balance, SlashId: Ord> {
 
 impl<BlockNumber, Balance, SlashId> StakedState<BlockNumber, Balance, SlashId>
 where
-    BlockNumber: SimpleArithmetic + Copy,
-    Balance: SimpleArithmetic + Copy,
+    BlockNumber: BaseArithmetic + Copy,
+    Balance: BaseArithmetic + Copy,
     SlashId: Ord + Copy,
 {
     /// Iterates over all ongoing slashes and decrements blocks_remaining_in_active_period_for_slashing of active slashes (advancing the timer).
@@ -268,7 +266,7 @@ where
     /// For all slahes that should be executed, will apply the Slash to the staked amount, and drop it from the ongoing slashes map.
     /// Returns a vector of the executed slashes outcome: (SlashId, Slashed Amount, Remaining Staked Amount)
     fn finalize_slashes(&mut self, minimum_balance: Balance) -> Vec<(SlashId, Balance, Balance)> {
-        let mut finalized_slashes: Vec<(SlashId, Balance, Balance)> = vec![];
+        let mut finalized_slashes: Vec<(SlashId, Balance, Balance)> = Vec::new();
 
         for (slash_id, slash) in self.get_slashes_to_finalize().iter() {
             // apply the slashing and get back actual amount slashed
@@ -305,8 +303,8 @@ pub struct Stake<BlockNumber, Balance, SlashId: Ord> {
 
 impl<BlockNumber, Balance, SlashId> Stake<BlockNumber, Balance, SlashId>
 where
-    BlockNumber: Copy + SimpleArithmetic + Zero,
-    Balance: Copy + SimpleArithmetic,
+    BlockNumber: Copy + BaseArithmetic + Zero,
+    Balance: Copy + BaseArithmetic,
     SlashId: Copy + Ord + Zero + One,
 {
     fn new(created_at: BlockNumber) -> Self {
@@ -638,7 +636,7 @@ where
 
                 (did_update, slashed)
             }
-            _ => (false, vec![]),
+            _ => (false, Vec::new()),
         }
     }
 
@@ -711,11 +709,12 @@ pub struct SlashImmediateOutcome<Balance, NegativeImbalance> {
 decl_storage! {
     trait Store for Module<T: Trait> as StakePool {
         /// Maps identifiers to a stake.
-        pub Stakes get(stakes): linked_map T::StakeId => Stake<T::BlockNumber, BalanceOf<T>, T::SlashId>;
+        pub Stakes get(fn stakes): map hasher(blake2_128_concat)
+            T::StakeId => Stake<T::BlockNumber, BalanceOf<T>, T::SlashId>;
 
         /// Identifier value for next stake, and count of total stakes created (not necessarily the number of current
         /// stakes in the Stakes map as stakes can be removed.)
-        pub StakesCreated get(stakes_created): T::StakeId;
+        pub StakesCreated get(fn stakes_created): T::StakeId;
     }
 }
 
@@ -900,14 +899,11 @@ impl<T: Trait> Module<T> {
         source_account_id: &T::AccountId,
         value: BalanceOf<T>,
     ) -> Result<BalanceOf<T>, StakeActionError<IncreasingStakeFromAccountError>> {
-        // Compiler error when using macro: cannot infer type for `ErrorType`
-        // let mut stake = ensure_stake_exists!(T, stake_id, StakeActionError::StakeNotFound)?;
-        ensure!(
-            <Stakes<T>>::exists(stake_id),
-            StakeActionError::StakeNotFound
-        );
-
-        let mut stake = Self::stakes(stake_id);
+        let mut stake = ensure_stake_exists!(
+            T,
+            stake_id,
+            <StakeActionError<IncreasingStakeFromAccountError>>::StakeNotFound
+        )?;
 
         let total_staked_amount = stake.increase_stake(value)?;
 
@@ -1141,7 +1137,7 @@ impl<T: Trait> Module<T> {
     /// Finalised slashing results in the staked_balance in the given stake being correspondingly reduced, and the imbalance
     /// is provided to the slashed() hook in the StakingEventsHandler.
     fn finalize_slashing_and_unstaking() {
-        for (stake_id, ref mut stake) in <Stakes<T>>::enumerate() {
+        for (stake_id, ref mut stake) in <Stakes<T>>::iter() {
             let (updated, slashed, unstaked) =
                 stake.finalize_slashing_and_unstaking(T::Currency::minimum_balance());
 

+ 1 - 1
runtime-modules/stake/src/macroes.rs

@@ -1,7 +1,7 @@
 #[macro_export]
 macro_rules! ensure_map_has_mapping_with_key {
     ($map_variable_name:ident , $runtime_trait:tt, $key:expr, $error:expr) => {{
-        if <$map_variable_name<$runtime_trait>>::exists($key) {
+        if <$map_variable_name<$runtime_trait>>::contains_key($key) {
             let value = <$map_variable_name<$runtime_trait>>::get($key);
 
             Ok(value)

+ 16 - 36
runtime-modules/stake/src/mock.rs

@@ -1,17 +1,15 @@
 #![cfg(test)]
 
 use crate::*;
-
-use primitives::H256;
-
 use crate::{Module, Trait};
 use balances;
-use runtime_primitives::{
+use frame_support::{impl_outer_origin, parameter_types};
+use sp_core::H256;
+use sp_runtime::{
     testing::Header,
     traits::{BlakeTwo256, IdentityLookup},
     Perbill,
 };
-use srml_support::{impl_outer_origin, parameter_types};
 
 impl_outer_origin! {
     pub enum Origin for Test {}
@@ -25,14 +23,14 @@ parameter_types! {
     pub const MaximumBlockWeight: u32 = 1024;
     pub const MaximumBlockLength: u32 = 2 * 1024;
     pub const AvailableBlockRatio: Perbill = Perbill::one();
-    pub const MinimumPeriod: u64 = 5;
 }
 
 impl system::Trait for Test {
+    type BaseCallFilter = ();
     type Origin = Origin;
+    type Call = ();
     type Index = u64;
     type BlockNumber = u64;
-    type Call = ();
     type Hash = H256;
     type Hashing = BlakeTwo256;
     type AccountId = u64;
@@ -41,35 +39,30 @@ impl system::Trait for Test {
     type Event = ();
     type BlockHashCount = BlockHashCount;
     type MaximumBlockWeight = MaximumBlockWeight;
+    type DbWeight = ();
+    type BlockExecutionWeight = ();
+    type ExtrinsicBaseWeight = ();
+    type MaximumExtrinsicWeight = ();
     type MaximumBlockLength = MaximumBlockLength;
     type AvailableBlockRatio = AvailableBlockRatio;
     type Version = ();
+    type ModuleToIndex = ();
+    type AccountData = balances::AccountData<u64>;
+    type OnNewAccount = ();
+    type OnKilledAccount = ();
 }
 
 parameter_types! {
     pub const ExistentialDeposit: u32 = 500;
-    pub const TransferFee: u32 = 5;
-    pub const CreationFee: u32 = 5;
-    pub const TransactionBaseFee: u32 = 5;
-    pub const TransactionByteFee: u32 = 0;
     pub const StakePoolId: [u8; 8] = *b"joystake";
 }
 
 impl balances::Trait for Test {
-    /// The type for recording an account's balance.
     type Balance = u64;
-    /// What to do if an account's free balance gets zeroed.
-    type OnFreeBalanceZero = ();
-    /// What to do if a new account is created.
-    type OnNewAccount = ();
-    /// The ubiquitous event type.
-    type Event = ();
-
     type DustRemoval = ();
-    type TransferPayment = ();
+    type Event = ();
     type ExistentialDeposit = ExistentialDeposit;
-    type TransferFee = TransferFee;
-    type CreationFee = CreationFee;
+    type AccountStore = System;
 }
 
 impl Trait for Test {
@@ -80,7 +73,7 @@ impl Trait for Test {
     type SlashId = u64;
 }
 
-pub fn build_test_externalities() -> runtime_io::TestExternalities {
+pub fn build_test_externalities() -> sp_io::TestExternalities {
     let t = system::GenesisConfig::default()
         .build_storage::<Test>()
         .unwrap();
@@ -99,17 +92,4 @@ pub mod fixtures {
         <Test as Trait>::SlashId,
         Slash<<Test as system::Trait>::BlockNumber, BalanceOf<Test>>,
     >;
-    // pub enum StakeInState {
-    //     NotStaked,
-    //     StakedNormal(BalanceOf<Test>, OngoingSlashes),
-    //     StakedUnstaking(BalanceOf<Test>, OngoingSlashes, <Test as system::Trait>::BlockNumber),
-    // }
-    // fn get_next_slash_id() -> SlashId {
-    // }
-    // pub fn make_stake(state: StakeInState) -> StakeId {
-    //     let id = StakePool::create_stake();
-    //     <Stakes<Test>>::mutate(id, |stake| {});
-    //     id
-    // }
-    // fn stake_in_state_to_stake(StakeInState) -> StakedState {}
 }

+ 5 - 5
runtime-modules/stake/src/tests.rs

@@ -2,8 +2,8 @@
 
 use super::*;
 use crate::mock::*;
-use runtime_primitives::traits::OnFinalize;
-use srml_support::{assert_err, assert_ok};
+use frame_support::traits::OnFinalize;
+use frame_support::{assert_err, assert_ok};
 
 #[test]
 fn stake_pool_works() {
@@ -70,7 +70,7 @@ fn create_stake() {
     build_test_externalities().execute_with(|| {
         let stake_id = StakePool::create_stake();
         assert_eq!(stake_id, 0);
-        assert!(<Stakes<Test>>::exists(&stake_id));
+        assert!(<Stakes<Test>>::contains_key(&stake_id));
 
         assert_eq!(StakePool::stakes_created(), stake_id + 1);
 
@@ -91,7 +91,7 @@ fn remove_stake_in_not_staked_state() {
             },
         );
         assert_ok!(StakePool::remove_stake(&100));
-        assert!(!<Stakes<Test>>::exists(&100));
+        assert!(!<Stakes<Test>>::contains_key(&100));
 
         // when status is Staked, removing should fail
         <Stakes<Test>>::insert(
@@ -106,7 +106,7 @@ fn remove_stake_in_not_staked_state() {
             StakePool::remove_stake(&200),
             StakeActionError::Error(StakingError::AlreadyStaked)
         );
-        assert!(<Stakes<Test>>::exists(&200));
+        assert!(<Stakes<Test>>::contains_key(&200));
     });
 }
 

+ 32 - 105
runtime-modules/storage/Cargo.toml

@@ -1,116 +1,43 @@
 [package]
-name = 'substrate-storage-module'
-version = '2.0.0'
+name = 'pallet-storage'
+version = '3.0.0'
 authors = ['Joystream contributors']
 edition = '2018'
 
+[dependencies]
+serde = { version = "1.0.101", optional = true, features = ["derive"] }
+codec = { package = 'parity-scale-codec', version = '1.3.1', default-features = false, features = ['derive'] }
+sp-std = { package = 'sp-std', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+frame-support = { package = 'frame-support', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+system = { package = 'frame-system', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-arithmetic = { package = 'sp-arithmetic', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-runtime = { package = 'sp-runtime', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+membership = { package = 'pallet-membership', default-features = false, path = '../membership'}
+pallet-timestamp = { package = 'pallet-timestamp', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+working-group = { package = 'pallet-working-group', default-features = false, path = '../working-group'}
+common = { package = 'pallet-common', default-features = false, path = '../common'}
+
+[dev-dependencies]
+sp-io = { package = 'sp-io', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+sp-core = { package = 'sp-core', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+balances = { package = 'pallet-balances', default-features = false, git = 'https://github.com/paritytech/substrate.git', rev = '00768a1f21a579c478fe5d4f51e1fa71f7db9fd4'}
+stake = { package = 'pallet-stake', default-features = false, path = '../stake'}
+hiring = { package = 'pallet-hiring', default-features = false, path = '../hiring'}
+minting = { package = 'pallet-token-mint', default-features = false, path = '../token-minting'}
+recurringrewards = { package = 'pallet-recurring-reward', default-features = false, path = '../recurring-reward'}
+
 [features]
 default = ['std']
 std = [
-	'sr-primitives/std',
-	'srml-support/std',
-	'system/std',
-	'rstd/std',
-	'codec/std',
-	'timestamp/std',
 	'serde',
-	'primitives/std',
-	'common/std',
+	'codec/std',
+	'sp-std/std',
+	'frame-support/std',
+	'system/std',
+	'sp-arithmetic/std',
+	'sp-runtime/std',
 	'membership/std',
+	'pallet-timestamp/std',
 	'working-group/std',
+	'common/std',
 ]
-
-
-[dependencies.sr-primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.srml-support]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-support'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.system]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-system'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.rstd]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-std'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.codec]
-default-features = false
-features = ['derive']
-package = 'parity-scale-codec'
-version = '1.0.0'
-
-[dependencies.serde]
-features = ['derive']
-optional = true
-version = '1.0.101'
-
-[dependencies.primitives]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'substrate-primitives'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.timestamp]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-timestamp'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dependencies.membership]
-default_features = false
-package = 'substrate-membership-module'
-path = '../membership'
-
-[dependencies.common]
-default_features = false
-package = 'substrate-common-module'
-path = '../common'
-
-[dependencies.working-group]
-default_features = false
-package = 'substrate-working-group-module'
-path = '../working-group'
-
-[dev-dependencies.runtime-io]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'sr-io'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dev-dependencies.balances]
-default_features = false
-git = 'https://github.com/paritytech/substrate.git'
-package = 'srml-balances'
-rev = 'c37bb08535c49a12320af7facfd555ce05cce2e8'
-
-[dev-dependencies.recurringrewards]
-default_features = false
-package = 'substrate-recurring-reward-module'
-path = '../recurring-reward'
-
-[dev-dependencies.hiring]
-default_features = false
-package = 'substrate-hiring-module'
-path = '../hiring'
-
-[dev-dependencies.stake]
-default_features = false
-package = 'substrate-stake-module'
-path = '../stake'
-
-[dev-dependencies.minting]
-default_features = false
-package = 'substrate-token-mint-module'
-path = '../token-minting'

+ 31 - 40
runtime-modules/storage/src/data_directory.rs

@@ -22,12 +22,13 @@
 //#![warn(missing_docs)]
 
 use codec::{Decode, Encode};
-use rstd::collections::btree_map::BTreeMap;
-use rstd::prelude::*;
-use sr_primitives::traits::{MaybeSerialize, Member};
-use srml_support::traits::Get;
-use srml_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
-use system::{self, ensure_root};
+use frame_support::dispatch::DispatchResult;
+use frame_support::traits::Get;
+use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
+use sp_runtime::traits::{MaybeSerialize, Member};
+use sp_std::collections::btree_map::BTreeMap;
+use sp_std::vec::Vec;
+use system::ensure_root;
 
 use common::origin::ActorOriginValidator;
 pub(crate) use common::BlockAndTime;
@@ -38,7 +39,7 @@ use crate::{MemberId, StorageProviderId, StorageWorkingGroup, StorageWorkingGrou
 
 /// The _Data directory_ main _Trait_.
 pub trait Trait:
-    timestamp::Trait
+    pallet_timestamp::Trait
     + system::Trait
     + data_object_type_registry::Trait
     + membership::Trait
@@ -64,7 +65,7 @@ pub trait Trait:
 
 decl_error! {
     /// _Data object storage registry_ module predefined errors.
-    pub enum Error {
+    pub enum Error for Module<T: Trait>{
         /// Content with this ID not found.
         CidNotFound,
 
@@ -85,25 +86,6 @@ decl_error! {
     }
 }
 
-impl From<system::Error> for Error {
-    fn from(error: system::Error) -> Self {
-        match error {
-            system::Error::Other(msg) => Error::Other(msg),
-            system::Error::RequireRootOrigin => Error::RequireRootOrigin,
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
-impl From<working_group::Error> for Error {
-    fn from(error: working_group::Error) -> Self {
-        match error {
-            working_group::Error::Other(msg) => Error::Other(msg),
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
 /// The decision of the storage provider when it acts as liaison.
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
 pub enum LiaisonJudgement {
@@ -127,7 +109,7 @@ impl Default for LiaisonJudgement {
 pub type DataObject<T> = DataObjectInternal<
     MemberId<T>,
     <T as system::Trait>::BlockNumber,
-    <T as timestamp::Trait>::Moment,
+    <T as pallet_timestamp::Trait>::Moment,
     <T as data_object_type_registry::Trait>::DataObjectTypeId,
     StorageProviderId<T>,
 >;
@@ -163,11 +145,11 @@ pub type DataObjectsMap<T> = BTreeMap<<T as Trait>::ContentId, DataObject<T>>;
 decl_storage! {
     trait Store for Module<T: Trait> as DataDirectory {
         /// List of ids known to the system.
-        pub KnownContentIds get(known_content_ids): Vec<T::ContentId> = Vec::new();
+        pub KnownContentIds get(fn known_content_ids): Vec<T::ContentId> = Vec::new();
 
         /// Maps data objects by their content id.
-        pub DataObjectByContentId get(data_object_by_content_id):
-            map T::ContentId => Option<DataObject<T>>;
+        pub DataObjectByContentId get(fn data_object_by_content_id):
+            map hasher(blake2_128_concat) T::ContentId => Option<DataObject<T>>;
     }
 }
 
@@ -205,13 +187,14 @@ decl_module! {
         fn deposit_event() = default;
 
         /// Predefined errors.
-        type Error = Error;
+        type Error = Error<T>;
 
         /// Maximum objects allowed per inject_data_objects() transaction
         const MaxObjectsPerInjection: u32 = T::MaxObjectsPerInjection::get();
 
         /// Adds the content to the system. Member id should match its origin. The created DataObject
         /// awaits liaison to accept or reject it.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn add_content(
             origin,
             member_id: MemberId<T>,
@@ -226,10 +209,10 @@ decl_module! {
             )?;
 
             ensure!(T::IsActiveDataObjectType::is_active_data_object_type(&type_id),
-                Error::DataObjectTypeMustBeActive);
+                Error::<T>::DataObjectTypeMustBeActive);
 
-            ensure!(!<DataObjectByContentId<T>>::exists(content_id),
-                Error::DataObjectAlreadyAdded);
+            ensure!(!<DataObjectByContentId<T>>::contains_key(content_id),
+                Error::<T>::DataObjectAlreadyAdded);
 
             let liaison = T::StorageProviderHelper::get_random_storage_provider()?;
 
@@ -254,6 +237,7 @@ decl_module! {
 
         /// Storage provider accepts a content. Requires signed storage provider account and its id.
         /// The LiaisonJudgement can be updated, but only by the liaison.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub(crate) fn accept_content(
             origin,
             storage_provider_id: StorageProviderId<T>,
@@ -272,6 +256,7 @@ decl_module! {
 
         /// Storage provider rejects a content. Requires signed storage provider account and its id.
         /// The LiaisonJudgement can be updated, but only by the liaison.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub(crate) fn reject_content(
             origin,
             storage_provider_id: StorageProviderId<T>,
@@ -288,6 +273,7 @@ decl_module! {
         // Sudo methods
 
         /// Removes the content id from the list of known content ids. Requires root privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         fn remove_known_content_id(origin, content_id: T::ContentId) {
             ensure_root(origin)?;
 
@@ -305,11 +291,12 @@ decl_module! {
         /// The number of objects that can be added per call is limited to prevent the dispatch
         /// from causing the block production to fail if it takes too much time to process.
         /// Existing data objects will be overwritten.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub(crate) fn inject_data_objects(origin, objects: DataObjectsMap<T>) {
             ensure_root(origin)?;
 
             // Must provide something to inject
-            ensure!(objects.len() <= T::MaxObjectsPerInjection::get() as usize, Error::DataObjectsInjectionExceededLimit);
+            ensure!(objects.len() <= T::MaxObjectsPerInjection::get() as usize, Error::<T>::DataObjectsInjectionExceededLimit);
 
             for (id, object) in objects.into_iter() {
                 // append to known content ids
@@ -332,11 +319,15 @@ impl<T: Trait> Module<T> {
         storage_provider_id: &StorageProviderId<T>,
         content_id: T::ContentId,
         judgement: LiaisonJudgement,
-    ) -> Result<(), Error> {
-        let mut data = Self::data_object_by_content_id(&content_id).ok_or(Error::CidNotFound)?;
+    ) -> DispatchResult {
+        let mut data =
+            Self::data_object_by_content_id(&content_id).ok_or(Error::<T>::CidNotFound)?;
 
         // Make sure the liaison matches
-        ensure!(data.liaison == *storage_provider_id, Error::LiaisonRequired);
+        ensure!(
+            data.liaison == *storage_provider_id,
+            Error::<T>::LiaisonRequired
+        );
 
         data.liaison_judgement = judgement;
         <DataObjectByContentId<T>>::insert(content_id, data);
@@ -368,7 +359,7 @@ impl<T: Trait> ContentIdExists<T> for Module<T> {
     fn get_data_object(content_id: &T::ContentId) -> Result<DataObject<T>, &'static str> {
         match Self::data_object_by_content_id(*content_id) {
             Some(data) => Ok(data),
-            None => Err(Error::LiaisonRequired.into()),
+            None => Err(Error::<T>::LiaisonRequired.into()),
         }
     }
 }

+ 23 - 35
runtime-modules/storage/src/data_object_storage_registry.rs

@@ -23,18 +23,20 @@
 //#![warn(missing_docs)]
 
 use codec::{Codec, Decode, Encode};
-use rstd::prelude::*;
-use sr_primitives::traits::{MaybeSerialize, Member, SimpleArithmetic};
-use srml_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
+use frame_support::dispatch::DispatchResult;
+use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, Parameter};
+use sp_arithmetic::traits::BaseArithmetic;
+use sp_runtime::traits::{MaybeSerialize, Member};
+use sp_std::vec::Vec;
 
 use crate::data_directory::{self, ContentIdExists};
 use crate::{StorageProviderId, StorageWorkingGroup, StorageWorkingGroupInstance};
 
-const DEFAULT_FIRST_RELATIONSHIP_ID: u32 = 1;
+const DEFAULT_FIRST_RELATIONSHIP_ID: u8 = 1;
 
 /// The _Data object storage registry_ main _Trait_.
 pub trait Trait:
-    timestamp::Trait
+    pallet_timestamp::Trait
     + system::Trait
     + data_directory::Trait
     + working_group::Trait<StorageWorkingGroupInstance>
@@ -45,7 +47,7 @@ pub trait Trait:
     /// Type for data object storage relationship id
     type DataObjectStorageRelationshipId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -58,7 +60,7 @@ pub trait Trait:
 
 decl_error! {
     /// _Data object storage registry_ module predefined errors
-    pub enum Error {
+    pub enum Error for Module<T: Trait>{
         /// Content with this ID not found.
         CidNotFound,
 
@@ -73,25 +75,6 @@ decl_error! {
     }
 }
 
-impl From<system::Error> for Error {
-    fn from(error: system::Error) -> Self {
-        match error {
-            system::Error::Other(msg) => Error::Other(msg),
-            system::Error::RequireRootOrigin => Error::RequireRootOrigin,
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
-impl From<working_group::Error> for Error {
-    fn from(error: working_group::Error) -> Self {
-        match error {
-            working_group::Error::Other(msg) => Error::Other(msg),
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
 /// Defines a relationship between the content and the storage provider
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
 pub struct DataObjectStorageRelationship<T: Trait> {
@@ -109,17 +92,19 @@ decl_storage! {
     trait Store for Module<T: Trait> as DataObjectStorageRegistry {
 
         /// Defines first relationship id.
-        pub FirstRelationshipId get(first_relationship_id) config(first_relationship_id):
+        pub FirstRelationshipId get(fn first_relationship_id) config(first_relationship_id):
             T::DataObjectStorageRelationshipId = T::DataObjectStorageRelationshipId::from(DEFAULT_FIRST_RELATIONSHIP_ID);
 
         /// Defines next relationship id.
-        pub NextRelationshipId get(next_relationship_id) build(|config: &GenesisConfig<T>| config.first_relationship_id): T::DataObjectStorageRelationshipId = T::DataObjectStorageRelationshipId::from(DEFAULT_FIRST_RELATIONSHIP_ID);
+        pub NextRelationshipId get(fn next_relationship_id) build(|config: &GenesisConfig<T>| config.first_relationship_id): T::DataObjectStorageRelationshipId = T::DataObjectStorageRelationshipId::from(DEFAULT_FIRST_RELATIONSHIP_ID);
 
         /// Mapping of Data object types
-        pub Relationships get(relationships): map T::DataObjectStorageRelationshipId => Option<DataObjectStorageRelationship<T>>;
+        pub Relationships get(fn relationships): map hasher(blake2_128_concat)
+            T::DataObjectStorageRelationshipId => Option<DataObjectStorageRelationship<T>>;
 
         /// Keeps a list of storage relationships per content id.
-        pub RelationshipsByContentId get(relationships_by_content_id): map T::ContentId => Vec<T::DataObjectStorageRelationshipId>;
+        pub RelationshipsByContentId get(fn relationships_by_content_id): map hasher(blake2_128_concat)
+            T::ContentId => Vec<T::DataObjectStorageRelationshipId>;
     }
 }
 
@@ -152,16 +137,17 @@ decl_module! {
         fn deposit_event() = default;
 
         /// Predefined errors.
-        type Error = Error;
+        type Error = Error<T>;
 
         /// Add storage provider-to-content relationship. The storage provider should be registered
         /// in the storage working group.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn add_relationship(origin, storage_provider_id: StorageProviderId<T>, cid: T::ContentId) {
             // Origin should match storage provider.
             <StorageWorkingGroup<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
 
             // Content ID must exist
-            ensure!(T::ContentIdExists::has_content(&cid), Error::CidNotFound);
+            ensure!(T::ContentIdExists::has_content(&cid), Error::<T>::CidNotFound);
 
             // Create new ID, data.
             let new_id = Self::next_relationship_id();
@@ -194,6 +180,7 @@ decl_module! {
 
         /// Activates storage provider-to-content relationship. The storage provider should be registered
         /// in the storage working group. A storage provider may flip their own ready state, but nobody else.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn set_relationship_ready(
             origin,
             storage_provider_id: StorageProviderId<T>,
@@ -204,6 +191,7 @@ decl_module! {
 
         /// Deactivates storage provider-to-content relationship. The storage provider should be registered
         /// in the storage working group. A storage provider may flip their own ready state, but nobody else.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn unset_relationship_ready(
             origin,
             storage_provider_id: StorageProviderId<T>,
@@ -220,16 +208,16 @@ impl<T: Trait> Module<T> {
         storage_provider_id: StorageProviderId<T>,
         id: T::DataObjectStorageRelationshipId,
         ready: bool,
-    ) -> Result<(), Error> {
+    ) -> DispatchResult {
         <StorageWorkingGroup<T>>::ensure_worker_signed(origin, &storage_provider_id)?;
 
         // For that, we need to fetch the identified DOSR
         let mut dosr =
-            Self::relationships(id).ok_or(Error::DataObjectStorageRelationshipNotFound)?;
+            Self::relationships(id).ok_or(Error::<T>::DataObjectStorageRelationshipNotFound)?;
 
         ensure!(
             dosr.storage_provider_id == storage_provider_id,
-            Error::OnlyStorageProviderMayClaimReady
+            Error::<T>::OnlyStorageProviderMayClaimReady
         );
 
         // Flip to ready

+ 26 - 34
runtime-modules/storage/src/data_object_type_registry.rs

@@ -22,14 +22,18 @@
 // Do not delete! Cannot be uncommented by default, because of Parity decl_module! issue.
 //#![warn(missing_docs)]
 
-use crate::{StorageWorkingGroup, StorageWorkingGroupInstance};
 use codec::{Codec, Decode, Encode};
-use rstd::prelude::*;
-use sr_primitives::traits::{MaybeSerialize, Member, SimpleArithmetic};
-use srml_support::{decl_error, decl_event, decl_module, decl_storage, Parameter};
+use frame_support::dispatch::DispatchError;
+use frame_support::weights::Weight;
+use frame_support::{decl_error, decl_event, decl_module, decl_storage, Parameter};
+use sp_arithmetic::traits::BaseArithmetic;
+use sp_runtime::traits::{MaybeSerialize, Member};
+use sp_std::vec::Vec;
+
+use crate::{StorageWorkingGroup, StorageWorkingGroupInstance};
 
 const DEFAULT_TYPE_DESCRIPTION: &str = "Default data object type for audio and video content.";
-const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u32 = 1;
+const DEFAULT_FIRST_DATA_OBJECT_TYPE_ID: u8 = 1;
 
 /// The _Data object type registry_ main _Trait_.
 pub trait Trait: system::Trait + working_group::Trait<StorageWorkingGroupInstance> {
@@ -39,7 +43,7 @@ pub trait Trait: system::Trait + working_group::Trait<StorageWorkingGroupInstanc
     /// _Data object type id_ type
     type DataObjectTypeId: Parameter
         + Member
-        + SimpleArithmetic
+        + BaseArithmetic
         + Codec
         + Default
         + Copy
@@ -49,7 +53,7 @@ pub trait Trait: system::Trait + working_group::Trait<StorageWorkingGroupInstanc
 
 decl_error! {
     /// _Data object type registry_ module predefined errors
-    pub enum Error {
+    pub enum Error for Module<T: Trait> {
         /// Data Object Type with the given ID not found.
         DataObjectTypeNotFound,
 
@@ -58,25 +62,6 @@ decl_error! {
     }
 }
 
-impl From<system::Error> for Error {
-    fn from(error: system::Error) -> Self {
-        match error {
-            system::Error::Other(msg) => Error::Other(msg),
-            system::Error::RequireRootOrigin => Error::RequireRootOrigin,
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
-impl From<working_group::Error> for Error {
-    fn from(error: working_group::Error) -> Self {
-        match error {
-            working_group::Error::Other(msg) => Error::Other(msg),
-            _ => Error::Other(error.into()),
-        }
-    }
-}
-
 /// Contains description and constrains for the data object.
 #[derive(Clone, Encode, Decode, PartialEq, Debug)]
 pub struct DataObjectType {
@@ -99,15 +84,16 @@ impl Default for DataObjectType {
 decl_storage! {
     trait Store for Module<T: Trait> as DataObjectTypeRegistry {
         /// Data object type ids should start at this value.
-        pub FirstDataObjectTypeId get(first_data_object_type_id) config(first_data_object_type_id):
+        pub FirstDataObjectTypeId get(fn first_data_object_type_id) config(first_data_object_type_id):
             T::DataObjectTypeId = T::DataObjectTypeId::from(DEFAULT_FIRST_DATA_OBJECT_TYPE_ID);
 
         /// Provides id counter for the data object types.
-        pub NextDataObjectTypeId get(next_data_object_type_id) build(|config: &GenesisConfig<T>|
+        pub NextDataObjectTypeId get(fn next_data_object_type_id) build(|config: &GenesisConfig<T>|
             config.first_data_object_type_id): T::DataObjectTypeId = T::DataObjectTypeId::from(DEFAULT_FIRST_DATA_OBJECT_TYPE_ID);
 
         /// Mapping of Data object types.
-        pub DataObjectTypes get(data_object_types): map T::DataObjectTypeId => Option<DataObjectType>;
+        pub DataObjectTypes get(fn data_object_types): map hasher(blake2_128_concat)
+            T::DataObjectTypeId => Option<DataObjectType>;
     }
 }
 
@@ -134,20 +120,23 @@ decl_module! {
         fn deposit_event() = default;
 
         /// Predefined errors
-        type Error = Error;
+        type Error = Error<T>;
 
-        fn on_initialize() {
+        fn on_initialize() -> Weight{
             // Create a default data object type if it was not created yet.
-            if !<DataObjectTypes<T>>::exists(Self::first_data_object_type_id()) {
+            if !<DataObjectTypes<T>>::contains_key(Self::first_data_object_type_id()) {
                 let do_type: DataObjectType = DataObjectType::default();
                 let new_type_id = Self::next_data_object_type_id();
 
                 <DataObjectTypes<T>>::insert(new_type_id, do_type);
                 <NextDataObjectTypeId<T>>::mutate(|n| { *n += T::DataObjectTypeId::from(1); });
             }
+
+            10_000_000 //TODO: adjust weight
         }
 
         /// Registers the new data object type. Requires leader privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn register_data_object_type(origin, data_object_type: DataObjectType) {
             <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
 
@@ -168,6 +157,7 @@ decl_module! {
         }
 
         /// Updates existing data object type. Requires leader privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn update_data_object_type(origin, id: T::DataObjectTypeId, data_object_type: DataObjectType) {
             <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
 
@@ -186,6 +176,7 @@ decl_module! {
         }
 
         /// Activates existing data object type. Requires leader privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn activate_data_object_type(origin, id: T::DataObjectTypeId) {
             <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
 
@@ -203,6 +194,7 @@ decl_module! {
         }
 
         /// Deactivates existing data object type. Requires leader privileges.
+        #[weight = 10_000_000] // TODO: adjust weight
         pub fn deactivate_data_object_type(origin, id: T::DataObjectTypeId) {
             <StorageWorkingGroup<T>>::ensure_origin_is_active_leader(origin)?;
 
@@ -222,8 +214,8 @@ decl_module! {
 }
 
 impl<T: Trait> Module<T> {
-    fn ensure_data_object_type(id: T::DataObjectTypeId) -> Result<DataObjectType, Error> {
-        Self::data_object_types(&id).ok_or(Error::DataObjectTypeNotFound)
+    fn ensure_data_object_type(id: T::DataObjectTypeId) -> Result<DataObjectType, DispatchError> {
+        Self::data_object_types(&id).ok_or_else(|| Error::<T>::DataObjectTypeNotFound.into())
     }
 }
 

+ 30 - 8
runtime-modules/storage/src/tests/data_directory.rs

@@ -1,10 +1,11 @@
 #![cfg(test)]
 
-use super::mock::*;
-use crate::data_directory::Error;
-use rstd::collections::btree_map::BTreeMap;
+use frame_support::dispatch::DispatchError;
+use sp_std::collections::btree_map::BTreeMap;
 use system::RawOrigin;
 
+use super::mock::*;
+
 #[test]
 fn succeed_adding_content() {
     with_default_mock_builder(|| {
@@ -36,13 +37,20 @@ fn add_content_fails_with_invalid_origin() {
             0,
             vec![1, 3, 3, 7],
         );
-        assert_eq!(res, Err(Error::Other("RequireSignedOrigin")));
+        assert_eq!(res, Err(DispatchError::Other("Bad origin")));
     });
 }
 
 #[test]
 fn accept_and_reject_content_fail_with_invalid_storage_provider() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         let sender = 1u64;
         let member_id = 1u64;
 
@@ -72,20 +80,27 @@ fn accept_and_reject_content_fail_with_invalid_storage_provider() {
             storage_provider_id,
             content_id,
         );
-        assert_eq!(res, Err(Error::Other("WorkerDoesNotExist")));
+        assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
 
         let res = TestDataDirectory::reject_content(
             Origin::signed(storage_provider_account_id),
             storage_provider_id,
             content_id,
         );
-        assert_eq!(res, Err(Error::Other("WorkerDoesNotExist")));
+        assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
     });
 }
 
 #[test]
 fn accept_content_as_liaison() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         let sender = 1u64;
         let member_id = 1u64;
 
@@ -130,6 +145,13 @@ fn accept_content_as_liaison() {
 #[test]
 fn reject_content_as_liaison() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         let sender = 1u64;
         let member_id = 1u64;
 
@@ -199,7 +221,7 @@ fn data_object_injection_works() {
         let content_id_2 = 2;
         objects.insert(content_id_2, object.clone());
 
-        let res = TestDataDirectory::inject_data_objects(Origin::ROOT, objects);
+        let res = TestDataDirectory::inject_data_objects(RawOrigin::Root.into(), objects);
         assert!(res.is_ok());
 
         assert_eq!(
@@ -279,7 +301,7 @@ fn data_object_injection_overwrites_and_removes_duplicate_ids() {
         objects.insert(content_id_1, object1.clone());
         objects.insert(content_id_2, object2.clone());
 
-        let res = TestDataDirectory::inject_data_objects(Origin::ROOT, objects);
+        let res = TestDataDirectory::inject_data_objects(RawOrigin::Root.into(), objects);
         assert!(res.is_ok());
 
         assert_eq!(

+ 10 - 3
runtime-modules/storage/src/tests/data_object_storage_registry.rs

@@ -22,7 +22,7 @@ fn add_relationship_fails_with_invalid_authorization() {
             storage_provider_id,
             TEST_MOCK_EXISTING_CID,
         );
-        assert_eq!(res, Err(working_group::Error::WorkerDoesNotExist.into()));
+        assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
     });
 }
 
@@ -44,7 +44,7 @@ fn set_relationship_ready_fails_with_invalid_authorization() {
             invalid_storage_provider_id,
             TEST_MOCK_EXISTING_CID,
         );
-        assert_eq!(res, Err(working_group::Error::WorkerDoesNotExist.into()));
+        assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
     });
 }
 
@@ -66,7 +66,7 @@ fn unset_relationship_ready_fails_with_invalid_authorization() {
             invalid_storage_provider_id,
             TEST_MOCK_EXISTING_CID,
         );
-        assert_eq!(res, Err(working_group::Error::WorkerDoesNotExist.into()));
+        assert_eq!(res, Err(working_group::Error::<Test, crate::StorageWorkingGroupInstance>::WorkerDoesNotExist.into()));
     });
 }
 
@@ -100,6 +100,13 @@ fn test_fail_adding_relationship_with_bad_content() {
 #[test]
 fn test_toggle_ready() {
     with_default_mock_builder(|| {
+        /*
+           Events are not emitted on block 0.
+           So any dispatchable calls made during genesis block formation will have no events emitted.
+           https://substrate.dev/recipes/2-appetizers/4-events.html
+        */
+        run_to_block(1);
+
         let (account_id, storage_provider_id) = hire_storage_provider();
         // Create a DOSR
         let res = TestDataObjectStorageRegistry::add_relationship(

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff