diff --git a/Cargo.lock b/Cargo.lock index c16b095b3609a..03e76eb979b8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1409,24 +1409,24 @@ dependencies = [ [[package]] name = "jsonrpc-client-transports" -version = "12.1.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "websocket 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)", + "websocket 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-core" -version = "12.1.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1438,15 +1438,15 @@ dependencies = [ [[package]] name = "jsonrpc-core-client" -version = "12.1.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-client-transports 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-client-transports 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-derive" -version = "12.1.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1457,37 +1457,37 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" -version = "12.1.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-pubsub" -version = "12.1.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-server-utils" -version = "12.1.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1498,13 +1498,13 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "12.1.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "ws 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2286,9 +2286,11 @@ dependencies = [ "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "node-executor 2.0.0", "node-primitives 2.0.0", + "node-rpc 2.0.0", "node-runtime 2.0.0", "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2316,6 +2318,7 @@ dependencies = [ "substrate-keystore 2.0.0", "substrate-network 2.0.0", "substrate-primitives 2.0.0", + "substrate-rpc 2.0.0", "substrate-service 2.0.0", "substrate-service-test 2.0.0", "substrate-telemetry 2.0.0", @@ -2331,6 +2334,7 @@ version = "2.0.0" dependencies = [ "node-primitives 2.0.0", "node-runtime 2.0.0", + "node-testing 2.0.0", "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", @@ -2339,13 +2343,11 @@ dependencies = [ "srml-grandpa 2.0.0", "srml-indices 2.0.0", "srml-session 2.0.0", - "srml-staking 2.0.0", "srml-support 2.0.0", "srml-system 2.0.0", "srml-timestamp 2.0.0", "srml-treasury 2.0.0", "substrate-executor 2.0.0", - "substrate-keyring 2.0.0", "substrate-primitives 2.0.0", "substrate-state-machine 2.0.0", "substrate-test-client 2.0.0", @@ -2363,10 +2365,33 @@ dependencies = [ "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", + "substrate-client 2.0.0", "substrate-primitives 2.0.0", "substrate-serializer 2.0.0", ] +[[package]] +name = "node-rpc" +version = "2.0.0" +dependencies = [ + "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "node-primitives 2.0.0", + "node-runtime 2.0.0", + "node-testing 2.0.0", + "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 2.0.0", + "substrate-client 2.0.0", + "substrate-keyring 2.0.0", + "substrate-primitives 2.0.0", + "substrate-transaction-pool 2.0.0", +] + [[package]] name = "node-rpc-client" version = "2.0.0" @@ -2374,7 +2399,7 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "substrate-rpc 2.0.0", @@ -2485,6 +2510,34 @@ dependencies = [ "substrate-wasm-builder-runner 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "node-testing" +version = "2.0.0" +dependencies = [ + "node-executor 2.0.0", + "node-primitives 2.0.0", + "node-runtime 2.0.0", + "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", + "sr-primitives 2.0.0", + "srml-balances 2.0.0", + "srml-contracts 2.0.0", + "srml-grandpa 2.0.0", + "srml-indices 2.0.0", + "srml-session 2.0.0", + "srml-staking 2.0.0", + "srml-support 2.0.0", + "srml-system 2.0.0", + "srml-timestamp 2.0.0", + "srml-treasury 2.0.0", + "substrate-client 2.0.0", + "substrate-executor 2.0.0", + "substrate-keyring 2.0.0", + "substrate-primitives 2.0.0", + "substrate-test-client 2.0.0", + "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "nodrop" version = "0.1.13" @@ -4882,10 +4935,10 @@ dependencies = [ "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4911,13 +4964,13 @@ dependencies = [ name = "substrate-rpc-servers" version = "2.0.0" dependencies = [ - "jsonrpc-http-server 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-ws-server 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ws-server 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", - "substrate-rpc 2.0.0", ] [[package]] @@ -4972,6 +5025,7 @@ dependencies = [ "substrate-network 2.0.0", "substrate-offchain 2.0.0", "substrate-primitives 2.0.0", + "substrate-rpc 2.0.0", "substrate-rpc-servers 2.0.0", "substrate-session 2.0.0", "substrate-telemetry 2.0.0", @@ -5977,7 +6031,7 @@ dependencies = [ [[package]] name = "websocket" -version = "0.22.4" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6305,14 +6359,14 @@ dependencies = [ "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum js-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "da3ea71161651a4cd97d999b2da139109c537b15ab33abc8ae4ead38deac8a03" -"checksum jsonrpc-client-transports 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6be24a8de4ced80f6fd8b6ace54aa610823a7642976a0e8e00e3bb2f4d8c33f0" -"checksum jsonrpc-core 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0216cf4c95fb373d89c63572672097b8aa74cfcdd77054accbf545d840be5bd7" -"checksum jsonrpc-core-client 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1603b6cc05060de7794c2962edd705e1ad2698bd2b0d2ddd4489f8c85df122b7" -"checksum jsonrpc-derive 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8afff172177878850d133ccdcd93cad794e85d7779ab334998d669ef80e13180" -"checksum jsonrpc-http-server 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a24e140242e0d2e9a694cf8db513a2bd739d24c392e0ad15e0d6d7ee8851e3a2" -"checksum jsonrpc-pubsub 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3c45f7cdb1bb28a3bfb3a0a5184bf99669c9ffe8cf8d7b8a582f2a52bf9944a" -"checksum jsonrpc-server-utils 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7aac8e0029d19582b68c9fd498d18bdcf0846612c968acc93b6e5ae67eea4e0" -"checksum jsonrpc-ws-server 12.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "698fee4fcaf09a5927b7e39dd8a8136a102b343cebacaa351fc4def01a050a5b" +"checksum jsonrpc-client-transports 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0bb6fd4acf48d1f17eb7b0e27ab7043c16f063ad0aa7020ec92a431648286c2f" +"checksum jsonrpc-core 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d379861584fe4e3678f6ae9ee60b41726df2989578c1dc0f90190dfc92dbe0" +"checksum jsonrpc-core-client 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6b0a3dc76953d88cdb47f5fe4ae21abcabc8d7edf4951ebce42db5c722d6698" +"checksum jsonrpc-derive 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9e2d4475549bc0126690788ed5107573c8917f97db5298f0043fb73d46fc498" +"checksum jsonrpc-http-server 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad55e8dd67c2c5b16436738b0baf319a6b353feba7401dbc1508a0bd8bd451f" +"checksum jsonrpc-pubsub 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "583f5930821dbc043236fe5d672d496ead7ff83d21351146598386c66fe8722a" +"checksum jsonrpc-server-utils 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04f18ca34046c249751fe90428e77e9570beaa03b33a108e74418a586063d07d" +"checksum jsonrpc-ws-server 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aee1265de937bd53ad0fc95ff5817314922ce009fa99a04a09fdf449b140ddf6" "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" "checksum keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3468207deea1359a0e921591ae9b4c928733d94eb9d6a2eeda994cfd59f42cf8" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -6595,7 +6649,7 @@ dependencies = [ "checksum web-sys 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "86d515d2f713d3a6ab198031d2181b7540f8e319e4637ec2d4a41a208335ef29" "checksum webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f7e1cd7900a3a6b65a3e8780c51a3e6b59c0e2c55c6dc69578c288d69f7d082" "checksum webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10fa4212003ba19a564f25cd8ab572c6791f99a03cc219c13ed35ccab00de0e" -"checksum websocket 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0adcd2a64c5746c9702b354a1b992802b0c363df1dfa324a74cb7aebe10e0cbf" +"checksum websocket 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b255b190f412e45000c35be7fe9b48b39a2ac5eb90d093d421694e5dae8b335c" "checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" "checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/Cargo.toml b/Cargo.toml index 65ec37073edb6..eb75ac19f7443 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,8 +96,10 @@ members = [ "node/cli", "node/executor", "node/primitives", - "node/runtime", + "node/rpc", "node/rpc-client", + "node/runtime", + "node/testing", "node-template", "subkey", "test-utils/chain-spec-builder", diff --git a/core/rpc-servers/Cargo.toml b/core/rpc-servers/Cargo.toml index 64a494f65ffe7..54a4b68eab9bf 100644 --- a/core/rpc-servers/Cargo.toml +++ b/core/rpc-servers/Cargo.toml @@ -5,12 +5,12 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -pubsub = { package = "jsonrpc-pubsub", version = "12.0.0" } +jsonrpc-core = "13.0.0" +pubsub = { package = "jsonrpc-pubsub", version = "13.0.0" } log = "0.4" serde = "1.0" -substrate-rpc = { path = "../rpc" } sr-primitives = { path = "../sr-primitives" } [target.'cfg(not(target_os = "unknown"))'.dependencies] -http = { package = "jsonrpc-http-server", version = "12.0.0" } -ws = { package = "jsonrpc-ws-server", version = "12.0.0" } +http = { package = "jsonrpc-http-server", version = "13.0.0" } +ws = { package = "jsonrpc-ws-server", version = "13.0.0" } diff --git a/core/rpc-servers/src/lib.rs b/core/rpc-servers/src/lib.rs index a33f726747149..05d24a2302339 100644 --- a/core/rpc-servers/src/lib.rs +++ b/core/rpc-servers/src/lib.rs @@ -18,11 +18,10 @@ #[warn(missing_docs)] -pub use substrate_rpc as apis; - use std::io; +use jsonrpc_core::IoHandlerExtension; use log::error; -use sr_primitives::{traits::{Block as BlockT, NumberFor}, generic::SignedBlock}; +use pubsub::PubSubMetadata; /// Maximal payload accepted by RPC servers. const MAX_PAYLOAD: usize = 15 * 1024 * 1024; @@ -30,30 +29,17 @@ const MAX_PAYLOAD: usize = 15 * 1024 * 1024; /// Default maximum number of connections for WS RPC servers. const WS_MAX_CONNECTIONS: usize = 100; -pub type Metadata = apis::metadata::Metadata; -pub type RpcHandler = pubsub::PubSubHandler; +/// The RPC IoHandler containing all requested APIs. +pub type RpcHandler = pubsub::PubSubHandler; pub use self::inner::*; /// Construct rpc `IoHandler` -pub fn rpc_handler( - state: S, - chain: C, - author: A, - system: Y, -) -> RpcHandler where - Block: BlockT + 'static, - ExHash: Send + Sync + 'static + sr_primitives::Serialize + sr_primitives::DeserializeOwned, - S: apis::state::StateApi, - C: apis::chain::ChainApi, Block::Hash, Block::Header, SignedBlock, Metadata=Metadata>, - A: apis::author::AuthorApi, - Y: apis::system::SystemApi>, -{ +pub fn rpc_handler( + extension: impl IoHandlerExtension +) -> RpcHandler { let mut io = pubsub::PubSubHandler::default(); - io.extend_with(state.to_delegate()); - io.extend_with(chain.to_delegate()); - io.extend_with(author.to_delegate()); - io.extend_with(system.to_delegate()); + extension.augment(&mut io); io } @@ -67,10 +53,10 @@ mod inner { /// Start HTTP server listening on given address. /// /// **Note**: Only available if `not(target_os = "unknown")`. - pub fn start_http( + pub fn start_http( addr: &std::net::SocketAddr, cors: Option<&Vec>, - io: RpcHandler, + io: RpcHandler, ) -> io::Result { http::ServerBuilder::new(io) .threads(4) @@ -89,13 +75,13 @@ mod inner { /// Start WS server listening on given address. /// /// **Note**: Only available if `not(target_os = "unknown")`. - pub fn start_ws( + pub fn start_ws>> ( addr: &std::net::SocketAddr, max_connections: Option, cors: Option<&Vec>, - io: RpcHandler, + io: RpcHandler, ) -> io::Result { - ws::ServerBuilder::with_meta_extractor(io, |context: &ws::RequestContext| Metadata::new(context.sender())) + ws::ServerBuilder::with_meta_extractor(io, |context: &ws::RequestContext| context.sender().into()) .max_payload(MAX_PAYLOAD) .max_connections(max_connections.unwrap_or(WS_MAX_CONNECTIONS)) .allowed_origins(map_cors(cors)) diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 957fe5be0b327..0a9cf108c9ede 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -7,11 +7,11 @@ edition = "2018" [dependencies] derive_more = "0.14.0" futures = "0.1" -futures03 = { package = "futures-preview", version = "=0.3.0-alpha.17", features = ["compat"] } -jsonrpc-core = "12.0.0" -jsonrpc-core-client = "12.0.0" -jsonrpc-pubsub = "12.0.0" -jsonrpc-derive = "12.0.0" +futures03 = { package = "futures-preview", version = "0.3.0-alpha.17", features = ["compat"] } +jsonrpc-core = "13.0.0" +jsonrpc-core-client = "13.0.0" +jsonrpc-pubsub = "13.0.0" +jsonrpc-derive = "13.0.0" log = "0.4" parking_lot = "0.9.0" codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/core/rpc/src/lib.rs b/core/rpc/src/lib.rs index 6488ea5f49c54..7ca3fde01de46 100644 --- a/core/rpc/src/lib.rs +++ b/core/rpc/src/lib.rs @@ -15,19 +15,23 @@ // along with Substrate. If not, see . //! Substrate RPC interfaces. +//! +//! A collection of RPC methods and subscriptions supported by all substrate clients. #![warn(missing_docs)] mod errors; mod helpers; +mod metadata; mod subscriptions; +use jsonrpc_core as rpc; + +pub use metadata::Metadata; +pub use rpc::IoHandlerExtension as RpcExtension; pub use subscriptions::Subscriptions; pub mod author; pub mod chain; -pub mod metadata; pub mod state; pub mod system; - -use jsonrpc_core as rpc; diff --git a/core/rpc/src/metadata.rs b/core/rpc/src/metadata.rs index e6af4ef94bc1a..4567b8fabc784 100644 --- a/core/rpc/src/metadata.rs +++ b/core/rpc/src/metadata.rs @@ -52,3 +52,9 @@ impl Metadata { (rx, Self::new(tx)) } } + +impl From> for Metadata { + fn from(sender: mpsc::Sender) -> Self { + Self::new(sender) + } +} diff --git a/core/rpc/src/system/mod.rs b/core/rpc/src/system/mod.rs index 59ed73b588a5d..9e347c6503fb8 100644 --- a/core/rpc/src/system/mod.rs +++ b/core/rpc/src/system/mod.rs @@ -29,8 +29,8 @@ use network; use sr_primitives::traits::{self, Header as HeaderT}; use self::error::Result; -pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; +pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; pub use self::gen_client::Client as SystemClient; /// Substrate system RPC API diff --git a/core/service/Cargo.toml b/core/service/Cargo.toml index bd04cd670e5b2..7afd59ebc0679 100644 --- a/core/service/Cargo.toml +++ b/core/service/Cargo.toml @@ -32,7 +32,8 @@ client_db = { package = "substrate-client-db", path = "../../core/client/db", fe codec = { package = "parity-scale-codec", version = "1.0.0" } substrate-executor = { path = "../../core/executor" } transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } -rpc = { package = "substrate-rpc-servers", path = "../../core/rpc-servers" } +rpc-servers = { package = "substrate-rpc-servers", path = "../../core/rpc-servers" } +rpc = { package = "substrate-rpc", path = "../../core/rpc" } tel = { package = "substrate-telemetry", path = "../../core/telemetry" } offchain = { package = "substrate-offchain", path = "../../core/offchain" } parity-multiaddr = { package = "parity-multiaddr", version = "0.5.0" } diff --git a/core/service/src/components.rs b/core/service/src/components.rs index b88abd4a98b03..a9aa2129f2498 100644 --- a/core/service/src/components.rs +++ b/core/service/src/components.rs @@ -34,7 +34,7 @@ use sr_primitives::{ }; use crate::config::Configuration; use primitives::{Blake2Hasher, H256, traits::BareCryptoStorePtr}; -use rpc::{self, apis::system::SystemInfo}; +use rpc::{self, system::SystemInfo}; use futures::{prelude::*, future::Executor}; use futures03::{FutureExt as _, channel::mpsc, compat::Compat}; @@ -145,6 +145,9 @@ pub type PoolApi = ::TransactionPoolApi; pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} impl RuntimeGenesis for T {} +/// A transport-agnostic handler of the RPC queries. +pub type RpcHandler = rpc_servers::RpcHandler; + /// Something that can create and store initial session keys from given seeds. pub trait InitialSessionKeys { /// Generate the initial session keys for the given seeds and store them in @@ -168,46 +171,51 @@ impl InitialSessionKeys for C where } /// Something that can start the RPC service. -pub trait StartRPC { +pub trait StartRpc { fn start_rpc( client: Arc>, - system_send_back: mpsc::UnboundedSender>>, + system_send_back: mpsc::UnboundedSender>>, system_info: SystemInfo, task_executor: TaskExecutor, transaction_pool: Arc>, + rpc_extensions: impl rpc::RpcExtension, keystore: KeyStorePtr, - ) -> rpc::RpcHandler; + ) -> RpcHandler; } -impl StartRPC for C where +impl StartRpc for C where ComponentClient: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: runtime_api::Metadata> + session::SessionKeys>, { fn start_rpc( client: Arc>, - system_send_back: mpsc::UnboundedSender>>, + system_send_back: mpsc::UnboundedSender>>, rpc_system_info: SystemInfo, task_executor: TaskExecutor, transaction_pool: Arc>, + rpc_extensions: impl rpc::RpcExtension, keystore: KeyStorePtr, - ) -> rpc::RpcHandler { - let subscriptions = rpc::apis::Subscriptions::new(task_executor.clone()); - let chain = rpc::apis::chain::Chain::new(client.clone(), subscriptions.clone()); - let state = rpc::apis::state::State::new(client.clone(), subscriptions.clone()); - let author = rpc::apis::author::Author::new( + ) -> RpcHandler { + use rpc::{chain, state, author, system}; + let subscriptions = rpc::Subscriptions::new(task_executor.clone()); + let chain = chain::Chain::new(client.clone(), subscriptions.clone()); + let state = state::State::new(client.clone(), subscriptions.clone()); + let author = rpc::author::Author::new( client, transaction_pool, subscriptions, keystore, ); - let system = rpc::apis::system::System::new(rpc_system_info, system_send_back); - rpc::rpc_handler::, ComponentExHash, _, _, _, _>( - state, - chain, - author, - system, - ) + let system = system::System::new(rpc_system_info, system_send_back); + + rpc_servers::rpc_handler(( + state::StateApi::to_delegate(state), + chain::ChainApi::to_delegate(chain), + author::AuthorApi::to_delegate(author), + system::SystemApi::to_delegate(system), + rpc_extensions, + )) } } @@ -299,7 +307,7 @@ pub trait ServiceTrait: Deref> + Send + 'static - + StartRPC + + StartRpc + MaintainTransactionPool + OffchainWorker + InitialSessionKeys @@ -308,7 +316,7 @@ impl ServiceTrait for T where T: Deref> + Send + 'static - + StartRPC + + StartRpc + MaintainTransactionPool + OffchainWorker + InitialSessionKeys @@ -335,6 +343,8 @@ pub trait ServiceFactory: 'static + Sized { type Genesis: RuntimeGenesis; /// Other configuration for service members. type Configuration: Default; + /// RPC initialisation. + type RpcExtensions: rpc::RpcExtension; /// Extended full service type. type FullService: ServiceTrait>; /// Extended light service type. @@ -407,6 +417,18 @@ pub trait ServiceFactory: 'static + Sized { Err("Chain Specification doesn't contain any consensus_engine name".into()) } } + + /// Create custom RPC method handlers for full node. + fn build_full_rpc_extensions( + client: Arc>, + transaction_pool: Arc>, + ) -> Self::RpcExtensions; + + /// Create custom RPC method handlers for light node. + fn build_light_rpc_extensions( + client: Arc>, + transaction_pool: Arc>, + ) -> Self::RpcExtensions; } /// A collection of types and function to generalize over full / light client type. @@ -419,8 +441,10 @@ pub trait Components: Sized + 'static { type Executor: 'static + client::CallExecutor, Blake2Hasher> + Send + Sync + Clone; /// The type that implements the runtime API. type RuntimeApi: Send + Sync; - /// A type that can start all runtime-dependent services. + /// The type that can start all runtime-dependent services. type RuntimeServices: ServiceTrait; + /// The type that can extend the RPC methods. + type RpcExtensions: rpc::RpcExtension; // TODO: Traitify transaction pool and allow people to implement their own. (#1242) /// Extrinsic pool type. type TransactionPoolApi: 'static + txpool::ChainApi< @@ -468,6 +492,12 @@ pub trait Components: Sized + 'static { config: &mut FactoryFullConfiguration, client: Arc> ) -> Result, error::Error>; + + /// Build RPC extensions + fn build_rpc_extensions( + client: Arc>, + transaction_pool: Arc>, + ) -> Self::RpcExtensions; } /// A struct that implement `Components` for the full client. @@ -529,6 +559,7 @@ impl Components for FullComponents { type ImportQueue = Factory::FullImportQueue; type RuntimeApi = Factory::RuntimeApi; type RuntimeServices = Factory::FullService; + type RpcExtensions = Factory::RpcExtensions; type SelectChain = Factory::SelectChain; fn build_client( @@ -594,6 +625,13 @@ impl Components for FullComponents { ) -> Result::Block>>>, error::Error> { Factory::build_finality_proof_provider(client) } + + fn build_rpc_extensions( + client: Arc>, + transaction_pool: Arc>, + ) -> Self::RpcExtensions { + Factory::build_full_rpc_extensions(client, transaction_pool) + } } /// A struct that implement `Components` for the light client. @@ -655,6 +693,7 @@ impl Components for LightComponents { type ImportQueue = ::LightImportQueue; type RuntimeApi = Factory::RuntimeApi; type RuntimeServices = Factory::LightService; + type RpcExtensions = Factory::RpcExtensions; type SelectChain = Factory::SelectChain; fn build_client( @@ -709,12 +748,20 @@ impl Components for LightComponents { ) -> Result::Block>>>, error::Error> { Ok(None) } + fn build_select_chain( _config: &mut FactoryFullConfiguration, _client: Arc> ) -> Result, error::Error> { Ok(None) } + + fn build_rpc_extensions( + client: Arc>, + transaction_pool: Arc>, + ) -> Self::RpcExtensions { + Factory::build_light_rpc_extensions(client, transaction_pool) + } } #[cfg(test)] diff --git a/core/service/src/lib.rs b/core/service/src/lib.rs index 98f4daf97e4d4..33a42e87fe04a 100644 --- a/core/service/src/lib.rs +++ b/core/service/src/lib.rs @@ -63,7 +63,7 @@ pub use components::{ FactoryFullConfiguration, RuntimeGenesis, FactoryGenesis, ComponentExHash, ComponentExtrinsic, FactoryExtrinsic, InitialSessionKeys, }; -use components::{StartRPC, MaintainTransactionPool, OffchainWorker}; +use components::{StartRpc, MaintainTransactionPool, OffchainWorker}; #[doc(hidden)] pub use std::{ops::Deref, result::Result, sync::Arc}; #[doc(hidden)] @@ -101,7 +101,7 @@ pub struct Service { to_poll: Vec + Send>>, /// Configuration of this Service config: FactoryFullConfiguration, - rpc_handlers: rpc::RpcHandler, + rpc_handlers: components::RpcHandler, _rpc: Box, _telemetry: Option, _telemetry_on_connect_sinks: Arc>>>, @@ -373,7 +373,7 @@ impl Service { // RPC let (system_rpc_tx, system_rpc_rx) = futures03::channel::mpsc::unbounded(); let gen_handler = || { - let system_info = rpc::apis::system::SystemInfo { + let system_info = rpc::system::SystemInfo { chain_name: config.chain_spec.name().into(), impl_name: config.impl_name.into(), impl_version: config.impl_version.into(), @@ -385,6 +385,7 @@ impl Service { system_info.clone(), Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone() }), transaction_pool.clone(), + Components::build_rpc_extensions(client.clone(), transaction_pool.clone()), keystore.clone(), ) }; @@ -630,7 +631,7 @@ fn build_network_future< mut network: network::NetworkWorker, client: Arc, status_sinks: Arc, NetworkState)>>>>, - rpc_rx: futures03::channel::mpsc::UnboundedReceiver>, + rpc_rx: futures03::channel::mpsc::UnboundedReceiver>, should_have_peers: bool, ) -> impl Future { // Compatibility shim while we're transitionning to stable Futures. @@ -666,16 +667,16 @@ fn build_network_future< // Poll the RPC requests and answer them. while let Ok(Async::Ready(Some(request))) = rpc_rx.poll() { match request { - rpc::apis::system::Request::Health(sender) => { - let _ = sender.send(rpc::apis::system::Health { + rpc::system::Request::Health(sender) => { + let _ = sender.send(rpc::system::Health { peers: network.peers_debug_info().len(), is_syncing: network.service().is_major_syncing(), should_have_peers, }); }, - rpc::apis::system::Request::Peers(sender) => { + rpc::system::Request::Peers(sender) => { let _ = sender.send(network.peers_debug_info().into_iter().map(|(peer_id, p)| - rpc::apis::system::PeerInfo { + rpc::system::PeerInfo { peer_id: peer_id.to_base58(), roles: format!("{:?}", p.roles), protocol_version: p.protocol_version, @@ -684,7 +685,7 @@ fn build_network_future< } ).collect()); } - rpc::apis::system::Request::NetworkState(sender) => { + rpc::system::Request::NetworkState(sender) => { let _ = sender.send(network.network_state()); } }; @@ -756,7 +757,7 @@ impl Drop for Service where Components: components::Comp /// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive. #[cfg(not(target_os = "unknown"))] -fn start_rpc_servers rpc::RpcHandler>( +fn start_rpc_servers components::RpcHandler>( config: &Configuration, mut gen_handler: H ) -> Result, error::Error> { @@ -781,11 +782,11 @@ fn start_rpc_servers rpc::RpcHandler>( Ok(Box::new(( maybe_start_server( config.rpc_http, - |address| rpc::start_http(address, config.rpc_cors.as_ref(), gen_handler()), + |address| rpc_servers::start_http(address, config.rpc_cors.as_ref(), gen_handler()), )?, maybe_start_server( config.rpc_ws, - |address| rpc::start_ws( + |address| rpc_servers::start_ws( address, config.rpc_ws_max_connections, config.rpc_cors.as_ref(), @@ -797,7 +798,7 @@ fn start_rpc_servers rpc::RpcHandler>( /// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive. #[cfg(target_os = "unknown")] -fn start_rpc_servers rpc::RpcHandler>( +fn start_rpc_servers components::RpcHandler>( _: &Configuration, _: H ) -> Result, error::Error> { @@ -819,7 +820,7 @@ impl RpcSession { /// The `RpcSession` must be kept alive in order to receive messages on the sender. pub fn new(sender: mpsc::Sender) -> RpcSession { RpcSession { - metadata: rpc::Metadata::new(sender), + metadata: sender.into(), } } } @@ -989,6 +990,7 @@ where /// FinalityProofProvider = { |client: Arc>| { /// Ok(Some(Arc::new(grandpa::FinalityProofProvider::new(client.clone(), client)) as _)) /// }}, +/// RpcExtensions = (), /// } /// } /// ``` @@ -1015,6 +1017,8 @@ macro_rules! construct_service_factory { SelectChain = $select_chain:ty { $( $select_chain_init:tt )* }, FinalityProofProvider = { $( $finality_proof_provider_init:tt )* }, + RpcExtensions = $rpc_extensions_ty:ty + $( { $( $rpc_extensions:tt )* } )?, } ) => { $( #[$attr] )* @@ -1035,6 +1039,7 @@ macro_rules! construct_service_factory { type FullImportQueue = $full_import_queue; type LightImportQueue = $light_import_queue; type SelectChain = $select_chain; + type RpcExtensions = $rpc_extensions_ty; fn build_full_transaction_pool( config: $crate::TransactionPoolOptions, @@ -1102,6 +1107,20 @@ macro_rules! construct_service_factory { ($( $authority_setup )*)(service) }) } + + fn build_full_rpc_extensions( + client: Arc<$crate::FullClient>, + transaction_pool: Arc<$crate::TransactionPool>, + ) -> Self::RpcExtensions { + $( ( $( $rpc_extensions )* ) (client, transaction_pool) )? + } + + fn build_light_rpc_extensions( + client: Arc<$crate::LightClient>, + transaction_pool: Arc<$crate::TransactionPool>, + ) -> Self::RpcExtensions { + $( ( $( $rpc_extensions )* ) (client, transaction_pool) )? + } } } } diff --git a/core/test-client/src/lib.rs b/core/test-client/src/lib.rs index d0d4a54b0f4ae..79e1027b9547e 100644 --- a/core/test-client/src/lib.rs +++ b/core/test-client/src/lib.rs @@ -67,7 +67,7 @@ impl GenesisInit for () { } /// A builder for creating a test client instance. -pub struct TestClientBuilder { +pub struct TestClientBuilder { execution_strategies: ExecutionStrategies, genesis_init: G, child_storage_extension: HashMap, Vec<(Vec, Vec)>>, @@ -76,9 +76,10 @@ pub struct TestClientBuilder { keystore: Option, } -impl Default for TestClientBuilder< +impl Default for TestClientBuilder< Executor, Backend, + G, > where Block: BlockT::Out>, { diff --git a/node-template/src/service.rs b/node-template/src/service.rs index b4a1a96413cfa..2baa0c7631373 100644 --- a/node-template/src/service.rs +++ b/node-template/src/service.rs @@ -263,5 +263,6 @@ construct_service_factory! { FinalityProofProvider = { |client: Arc>| { Ok(Some(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _)) }}, + RpcExtensions = (), } } diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index c266427439d78..c8aaf576dc68f 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -11,6 +11,7 @@ log = "0.4" tokio = "0.1.7" futures = "0.1" exit-future = "0.1" +jsonrpc-core = "13.0.0" cli = { package = "substrate-cli", path = "../../core/cli" } codec = { package = "parity-scale-codec", version = "1.0.0" } sr-io = { path = "../../core/sr-io" } @@ -18,8 +19,10 @@ client = { package = "substrate-client", path = "../../core/client" } primitives = { package = "substrate-primitives", path = "../../core/primitives" } inherents = { package = "substrate-inherents", path = "../../core/inherents" } node-runtime = { path = "../runtime" } +node-rpc = { path = "../rpc" } node-primitives = { path = "../primitives" } hex-literal = "0.2" +substrate-rpc = { package = "substrate-rpc", path = "../../core/rpc" } substrate-basic-authorship = { path = "../../core/basic-authorship" } substrate-service = { path = "../../core/service" } transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index b691b508fd470..7022d12d69a0f 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -278,6 +278,17 @@ construct_service_factory! { FinalityProofProvider = { |client: Arc>| { Ok(Some(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _)) }}, + + RpcExtensions = jsonrpc_core::IoHandler + { |client, pool| { + use node_rpc::accounts::{Accounts, AccountsApi}; + + let mut io = jsonrpc_core::IoHandler::default(); + io.extend_with( + AccountsApi::to_delegate(Accounts::new(client, pool)) + ); + io + }}, } } diff --git a/node/executor/Cargo.toml b/node/executor/Cargo.toml index 1cc9a2f559b95..a9ff25890e30a 100644 --- a/node/executor/Cargo.toml +++ b/node/executor/Cargo.toml @@ -17,13 +17,12 @@ node-primitives = { path = "../primitives" } node-runtime = { path = "../runtime" } [dev-dependencies] +node-testing = { path = "../testing" } test-client = { package = "substrate-test-client", path = "../../core/test-client" } -keyring = { package = "substrate-keyring", path = "../../core/keyring" } sr-primitives = { path = "../../core/sr-primitives" } runtime_support = { package = "srml-support", path = "../../srml/support" } balances = { package = "srml-balances", path = "../../srml/balances" } session = { package = "srml-session", path = "../../srml/session" } -staking = { package = "srml-staking", path = "../../srml/staking" } system = { package = "srml-system", path = "../../srml/system" } timestamp = { package = "srml-timestamp", path = "../../srml/timestamp" } treasury = { package = "srml-treasury", path = "../../srml/treasury" } diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 448ab9d8b6fa9..874c5a1b6db1c 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -37,30 +37,30 @@ native_executor_instance!( #[cfg(test)] mod tests { use super::Executor; - use {balances, contracts, indices, staking, system, timestamp}; + use {balances, contracts, indices, system, timestamp}; use runtime_io; use substrate_executor::WasmExecutor; use codec::{Encode, Decode, Joiner}; - use keyring::{AccountKeyring, Ed25519Keyring, Sr25519Keyring}; use runtime_support::{Hashable, StorageValue, StorageMap, assert_eq_error_rate, traits::Currency}; use state_machine::{CodeExecutor, Externalities, TestExternalities as CoreTestExternalities}; - use primitives::{twox_128, blake2_256, Blake2Hasher, ChangesTrieConfiguration, NeverNativeValue, NativeOrEncoded}; - use node_primitives::{Hash, BlockNumber, AccountId, Balance, Index}; + use primitives::{ + twox_128, blake2_256, Blake2Hasher, NeverNativeValue, NativeOrEncoded, map + }; use sr_primitives::traits::{Header as HeaderT, Hash as HashT, Convert}; - use sr_primitives::{generic::Era, ApplyOutcome, ApplyError, ApplyResult, Perbill}; + use sr_primitives::{ApplyOutcome, ApplyError, ApplyResult}; use sr_primitives::weights::{WeightMultiplier, GetDispatchInfo}; use contracts::ContractAddressFor; use system::{EventRecord, Phase}; + use node_primitives::{Hash, BlockNumber, Balance}; use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage, - GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, System, SystemConfig, - GrandpaConfig, IndicesConfig, ContractsConfig, Event, SessionKeys, SignedExtra, - TransferFee, TransactionBaseFee, TransactionByteFee + System, Event, + TransferFee, TransactionBaseFee, TransactionByteFee, }; use node_runtime::constants::currency::*; use node_runtime::impls::WeightToFee; + use node_testing::keyring::*; use wabt; - use primitives::map; /// The wasm runtime code. /// @@ -83,6 +83,10 @@ mod tests { type TestExternalities = CoreTestExternalities; + fn sign(xt: CheckedExtrinsic) -> UncheckedExtrinsic { + node_testing::keyring::sign(xt, VERSION, GENESIS_HASH) + } + /// Default transfer fee fn transfer_fee(extrinsic: &E) -> Balance { let length_fee = TransactionBaseFee::get() + @@ -97,65 +101,6 @@ mod tests { length_fee + weight_fee + TransferFee::get() } - fn alice() -> AccountId { - AccountKeyring::Alice.into() - } - - fn bob() -> AccountId { - AccountKeyring::Bob.into() - } - - fn charlie() -> AccountId { - AccountKeyring::Charlie.into() - } - - fn dave() -> AccountId { - AccountKeyring::Dave.into() - } - - fn eve() -> AccountId { - AccountKeyring::Eve.into() - } - - fn ferdie() -> AccountId { - AccountKeyring::Ferdie.into() - } - - fn sign(xt: CheckedExtrinsic) -> UncheckedExtrinsic { - match xt.signed { - Some((signed, extra)) => { - let payload = (xt.function, extra.clone(), VERSION, GENESIS_HASH, GENESIS_HASH); - let key = AccountKeyring::from_public(&signed).unwrap(); - let signature = payload.using_encoded(|b| { - if b.len() > 256 { - key.sign(&runtime_io::blake2_256(b)) - } else { - key.sign(b) - } - }).into(); - UncheckedExtrinsic { - signature: Some((indices::address::Address::Id(signed), signature, extra)), - function: payload.0, - } - } - None => UncheckedExtrinsic { - signature: None, - function: xt.function, - }, - } - } - - fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { - ( - system::CheckVersion::new(), - system::CheckGenesis::new(), - system::CheckEra::from(Era::mortal(256, 0)), - system::CheckNonce::from(nonce), - system::CheckWeight::new(), - balances::TakeFees::from(extra_fee) - ) - } - fn default_transfer_call() -> balances::Call { balances::Call::transfer::(bob().into(), 69 * DOLLARS) } @@ -319,85 +264,11 @@ mod tests { }); } - fn to_session_keys( - ed25519_keyring: &Ed25519Keyring, - sr25519_keyring: &Sr25519Keyring, - ) -> SessionKeys { - SessionKeys { - grandpa: ed25519_keyring.to_owned().public().into(), - babe: sr25519_keyring.to_owned().public().into(), - im_online: sr25519_keyring.to_owned().public().into(), - } - } - fn new_test_ext(code: &[u8], support_changes_trie: bool) -> TestExternalities { - let mut ext = TestExternalities::new_with_code(code, GenesisConfig { - system: Some(SystemConfig { - changes_trie_config: if support_changes_trie { Some(ChangesTrieConfiguration { - digest_interval: 2, - digest_levels: 2, - }) } else { None }, - .. Default::default() - }), - indices: Some(IndicesConfig { - ids: vec![alice(), bob(), charlie(), dave(), eve(), ferdie()], - }), - balances: Some(BalancesConfig { - balances: vec![ - (alice(), 111 * DOLLARS), - (bob(), 100 * DOLLARS), - (charlie(), 100_000_000 * DOLLARS), - (dave(), 111 * DOLLARS), - (eve(), 101 * DOLLARS), - (ferdie(), 100 * DOLLARS), - ], - vesting: vec![], - }), - session: Some(SessionConfig { - keys: vec![ - (alice(), to_session_keys( - &Ed25519Keyring::Alice, - &Sr25519Keyring::Alice, - )), - (bob(), to_session_keys( - &Ed25519Keyring::Bob, - &Sr25519Keyring::Bob, - )), - (charlie(), to_session_keys( - &Ed25519Keyring::Charlie, - &Sr25519Keyring::Charlie, - )), - ] - }), - staking: Some(StakingConfig { - current_era: 0, - stakers: vec![ - (dave(), alice(), 111 * DOLLARS, staking::StakerStatus::Validator), - (eve(), bob(), 100 * DOLLARS, staking::StakerStatus::Validator), - (ferdie(), charlie(), 100 * DOLLARS, staking::StakerStatus::Validator) - ], - validator_count: 3, - minimum_validator_count: 0, - slash_reward_fraction: Perbill::from_percent(10), - invulnerables: vec![alice(), bob(), charlie()], - .. Default::default() - }), - contracts: Some(ContractsConfig { - current_schedule: Default::default(), - gas_price: 1 * MILLICENTS, - }), - babe: Some(Default::default()), - grandpa: Some(GrandpaConfig { - authorities: vec![], - }), - im_online: Some(Default::default()), - democracy: Some(Default::default()), - collective_Instance1: Some(Default::default()), - collective_Instance2: Some(Default::default()), - membership_Instance1: Some(Default::default()), - elections: Some(Default::default()), - sudo: Some(Default::default()), - }.build_storage().unwrap()); + let mut ext = TestExternalities::new_with_code( + code, + node_testing::genesis::config(support_changes_trie, Some(code)).build_storage().unwrap(), + ); ext.changes_trie_storage().insert(0, GENESIS_HASH.into(), Default::default()); ext } @@ -955,15 +826,12 @@ mod tests { #[test] fn should_import_block_with_test_client() { - use test_client::{ClientExt, TestClientBuilder, consensus::BlockOrigin}; - - let client = TestClientBuilder::default() - .build_with_native_executor::(executor()) - .0; + use node_testing::client::{ClientExt, TestClientBuilderExt, TestClientBuilder, consensus::BlockOrigin}; + let client = TestClientBuilder::new().build(); let block1 = changes_trie_block(); let block_data = block1.0; - let block = Block::decode(&mut &block_data[..]).unwrap(); + let block = node_primitives::Block::decode(&mut &block_data[..]).unwrap(); client.import(BlockOrigin::Own, block).unwrap(); } diff --git a/node/primitives/Cargo.toml b/node/primitives/Cargo.toml index 654347273fb71..248713a8888f6 100644 --- a/node/primitives/Cargo.toml +++ b/node/primitives/Cargo.toml @@ -5,10 +5,11 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -serde = { version = "1.0", optional = true, features = ["derive"] } +client = { package = "substrate-client", path = "../../core/client", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false } rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false } +serde = { version = "1.0", optional = true, features = ["derive"] } sr-primitives = { path = "../../core/sr-primitives", default-features = false } [dev-dependencies] @@ -18,9 +19,10 @@ pretty_assertions = "0.6.1" [features] default = ["std"] std = [ + "client/std", "codec/std", "primitives/std", "rstd/std", - "sr-primitives/std", "serde", + "sr-primitives/std", ] diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index 431ba17c00bbe..a8c045aea7c58 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -66,3 +66,11 @@ pub type BlockId = generic::BlockId; /// Opaque, encoded, unchecked extrinsic. pub type UncheckedExtrinsic = OpaqueExtrinsic; + +client::decl_runtime_apis! { + /// The API to query account account nonce (aka index). + pub trait AccountNonceApi { + /// Get current account nonce of given `AccountId`. + fn account_nonce(account: AccountId) -> Index; + } +} diff --git a/node/rpc-client/Cargo.toml b/node/rpc-client/Cargo.toml index ea255808e463e..bc492bc003394 100644 --- a/node/rpc-client/Cargo.toml +++ b/node/rpc-client/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" env_logger = "0.6" futures = "0.1.26" hyper = "0.12" -jsonrpc-core-client = { version = "12.0.0", features = ["http", "ws"] } +jsonrpc-core-client = { version = "13.0.0", features = ["http", "ws"] } log = "0.4" node-primitives = { path = "../primitives" } substrate-rpc = { path = "../../core/rpc", version = "2.0.0" } diff --git a/node/rpc/Cargo.toml b/node/rpc/Cargo.toml new file mode 100644 index 0000000000000..6042380c8379f --- /dev/null +++ b/node/rpc/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "node-rpc" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +client = { package = "substrate-client", path = "../../core/client" } +jsonrpc-core = "13.0.0" +jsonrpc-core-client = "13.0.0" +jsonrpc-derive = "13.0.0" +jsonrpc-pubsub = "13.0.0" +keyring = { package = "substrate-keyring", path = "../../core/keyring" } +log = "0.4" +node-primitives = { path = "../primitives" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +serde = { version = "1.0", features = ["derive"] } +sr-primitives = { path = "../../core/sr-primitives" } +substrate-primitives = { path = "../../core/primitives" } +transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } + +[dev-dependencies] +node-testing = { path = "../testing" } +node-runtime = { path = "../runtime" } +env_logger = "0.6" diff --git a/node/rpc/src/accounts.rs b/node/rpc/src/accounts.rs new file mode 100644 index 0000000000000..09d4a5144228c --- /dev/null +++ b/node/rpc/src/accounts.rs @@ -0,0 +1,156 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Node-specific RPC methods for Accounts. + +use std::sync::Arc; + +use client::blockchain::HeaderBackend; +use jsonrpc_core::{Result, Error, ErrorCode}; +use jsonrpc_derive::rpc; +use node_primitives::{ + AccountId, Index, AccountNonceApi, Block, BlockId, +}; +use codec::Encode; +use sr_primitives::traits; +use substrate_primitives::hexdisplay::HexDisplay; +use transaction_pool::txpool::{self, Pool}; + +pub use self::gen_client::Client as AccountsClient; + +const RUNTIME_ERROR: i64 = 1; + +/// Accounts RPC methods. +#[rpc] +pub trait AccountsApi { + /// Returns the next valid index (aka nonce) for given account. + /// + /// This method takes into consideration all pending transactions + /// currently in the pool and if no transactions are found in the pool + /// it fallbacks to query the index from the runtime (aka. state nonce). + #[rpc(name = "account_nextIndex")] + fn nonce(&self, account: AccountId) -> Result; +} + +/// An implementation of Accounts specific RPC methods. +pub struct Accounts { + client: Arc, + pool: Arc>, +} + +impl Accounts { + /// Create new `Accounts` given client and transaction pool. + pub fn new(client: Arc, pool: Arc>) -> Self { + Accounts { + client, + pool + } + } +} + +impl AccountsApi for Accounts +where + C: traits::ProvideRuntimeApi, + C: HeaderBackend, + C: Send + Sync + 'static, + C::Api: AccountNonceApi, + P: txpool::ChainApi + Sync + Send + 'static, +{ + fn nonce(&self, account: AccountId) -> Result { + let api = self.client.runtime_api(); + let best = self.client.info().best_hash; + let at = BlockId::hash(best); + + let nonce = api.account_nonce(&at, account.clone()).map_err(|e| Error { + code: ErrorCode::ServerError(RUNTIME_ERROR), + message: "Unable to query nonce.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + log::debug!(target: "rpc", "State nonce for {}: {}", account, nonce); + // Now we need to query the transaction pool + // and find transactions originating from the same sender. + // + // Since extrinsics are opaque to us, we look for them using + // `provides` tag. And increment the nonce if we find a transaction + // that matches the current one. + let mut current_nonce = nonce; + let mut current_tag = (account.clone(), nonce).encode(); + for tx in self.pool.ready() { + log::debug!( + target: "rpc", + "Current nonce to {:?}, checking {} vs {:?}", + current_nonce, + HexDisplay::from(¤t_tag), + tx.provides.iter().map(|x| format!("{}", HexDisplay::from(x))).collect::>(), + ); + // since transactions in `ready()` need to be ordered by nonce + // it's fine to continue with current iterator. + if tx.provides.get(0) == Some(¤t_tag) { + current_nonce += 1; + current_tag = (account.clone(), current_nonce).encode(); + } + } + + Ok(current_nonce) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use node_runtime::{CheckedExtrinsic, Call, TimestampCall}; + use codec::Decode; + use node_testing::{ + client::{ClientExt, TestClientBuilder, TestClientBuilderExt}, + keyring::{self, alice, signed_extra}, + }; + + const VERSION: u32 = node_runtime::VERSION.spec_version; + + #[test] + fn should_return_next_nonce_for_some_account() { + // given + let _ = env_logger::try_init(); + let client = Arc::new(TestClientBuilder::new().build()); + let pool = Arc::new(Pool::new(Default::default(), transaction_pool::ChainApi::new(client.clone()))); + + let new_transaction = |extra| { + let ex = CheckedExtrinsic { + signed: Some((alice().into(), extra)), + function: Call::Timestamp(TimestampCall::set(5)), + }; + let xt = keyring::sign(ex, VERSION, client.genesis_hash().into()); + // Convert to OpaqueExtrinsic + let encoded = xt.encode(); + node_primitives::UncheckedExtrinsic::decode(&mut &*encoded).unwrap() + }; + // Populate the pool + let ext0 = new_transaction(signed_extra(0, 0)); + pool.submit_one(&BlockId::number(0), ext0).unwrap(); + let ext1 = new_transaction(signed_extra(1, 0)); + pool.submit_one(&BlockId::number(0), ext1).unwrap(); + + let accounts = Accounts::new(client, pool); + + // when + let nonce = accounts.nonce(alice().into()); + + // then + assert_eq!(nonce.unwrap(), 2); + } +} diff --git a/node/rpc/src/lib.rs b/node/rpc/src/lib.rs new file mode 100644 index 0000000000000..e25424397d6cf --- /dev/null +++ b/node/rpc/src/lib.rs @@ -0,0 +1,32 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! 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 `substrate-rpc` crate. +//! It means that `core/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 `SRML` modules +//! are part of it. Therefore all node-runtime-specific RPCs can +//! be placed here. + +#![warn(missing_docs)] + +pub mod accounts; diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index e8cb78eb93861..7507609b3b2fa 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -576,6 +576,12 @@ impl_runtime_apis! { } } + impl node_primitives::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Index { + System::account_nonce(account) + } + } + impl consensus_primitives::ConsensusApi for Runtime { fn authorities() -> Vec { Babe::authorities().into_iter().map(|(a, _)| a).collect() diff --git a/node/testing/Cargo.toml b/node/testing/Cargo.toml new file mode 100644 index 0000000000000..7f473d1be9b50 --- /dev/null +++ b/node/testing/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "node-testing" +version = "2.0.0" +authors = ["Parity Technologies "] +description = "Test utilities for Substrate node." +edition = "2018" + +[dependencies] +balances = { package = "srml-balances", path = "../../srml/balances" } +client = { package = "substrate-client", path = "../../core/client" } +contracts = { package = "srml-contracts", path = "../../srml/contracts" } +grandpa = { package = "srml-grandpa", path = "../../srml/grandpa" } +indices = { package = "srml-indices", path = "../../srml/indices" } +keyring = { package = "substrate-keyring", path = "../../core/keyring" } +node-executor = { path = "../executor" } +node-primitives = { path = "../primitives" } +node-runtime = { path = "../runtime" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +primitives = { package = "substrate-primitives", path = "../../core/primitives" } +sr-io = { path = "../../core/sr-io" } +sr-primitives = { path = "../../core/sr-primitives" } +runtime_support = { package = "srml-support", path = "../../srml/support" } +session = { package = "srml-session", path = "../../srml/session" } +staking = { package = "srml-staking", path = "../../srml/staking" } +substrate-executor = { path = "../../core/executor" } +system = { package = "srml-system", path = "../../srml/system" } +test-client = { package = "substrate-test-client", path = "../../core/test-client" } +timestamp = { package = "srml-timestamp", path = "../../srml/timestamp" } +treasury = { package = "srml-treasury", path = "../../srml/treasury" } +wabt = "~0.7.4" diff --git a/node/testing/src/client.rs b/node/testing/src/client.rs new file mode 100644 index 0000000000000..3b16f2cbcb97d --- /dev/null +++ b/node/testing/src/client.rs @@ -0,0 +1,73 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Utilites to build a `TestClient` for `node-runtime`. + +use sr_primitives::BuildStorage; + +/// Re-export test-client utilities. +pub use test_client::*; + +/// Call executor for `node-runtime` `TestClient`. +pub type Executor = substrate_executor::NativeExecutor; + +/// Default backend type. +pub type Backend = client_db::Backend; + +/// Test client type. +pub type Client = client::Client< + Backend, + client::LocalCallExecutor, + node_primitives::Block, + node_runtime::RuntimeApi, +>; + +/// Genesis configuration parameters for `TestClient`. +#[derive(Default)] +pub struct GenesisParameters { + support_changes_trie: bool, +} + +impl test_client::GenesisInit for GenesisParameters { + fn genesis_storage(&self) -> (StorageOverlay, ChildrenStorageOverlay) { + crate::genesis::config(self.support_changes_trie, None).build_storage().unwrap() + } +} + +/// A `test-runtime` extensions to `TestClientBuilder`. +pub trait TestClientBuilderExt: Sized { + /// Create test client builder. + fn new() -> Self; + + /// Build the test client. + fn build(self) -> Client; +} + +impl TestClientBuilderExt for test_client::TestClientBuilder< + client::LocalCallExecutor, + Backend, + GenesisParameters, +> { + fn new() -> Self{ + Self::default() + } + + fn build(self) -> Client { + self.build_with_native_executor(None).0 + } +} + + diff --git a/node/testing/src/genesis.rs b/node/testing/src/genesis.rs new file mode 100644 index 0000000000000..a7df99da145b1 --- /dev/null +++ b/node/testing/src/genesis.rs @@ -0,0 +1,99 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Genesis Configuration. + +use crate::keyring::*; +use keyring::{Ed25519Keyring, Sr25519Keyring}; +use node_runtime::{ + GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, SystemConfig, + GrandpaConfig, IndicesConfig, ContractsConfig, WASM_BINARY, +}; +use node_runtime::constants::currency::*; +use primitives::ChangesTrieConfiguration; +use sr_primitives::Perbill; + + +/// Create genesis runtime configuration for tests. +pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig { + GenesisConfig { + system: Some(SystemConfig { + changes_trie_config: if support_changes_trie { Some(ChangesTrieConfiguration { + digest_interval: 2, + digest_levels: 2, + }) } else { None }, + code: code.map(|x| x.to_vec()).unwrap_or_else(|| WASM_BINARY.to_vec()), + }), + indices: Some(IndicesConfig { + ids: vec![alice(), bob(), charlie(), dave(), eve(), ferdie()], + }), + balances: Some(BalancesConfig { + balances: vec![ + (alice(), 111 * DOLLARS), + (bob(), 100 * DOLLARS), + (charlie(), 100_000_000 * DOLLARS), + (dave(), 111 * DOLLARS), + (eve(), 101 * DOLLARS), + (ferdie(), 100 * DOLLARS), + ], + vesting: vec![], + }), + session: Some(SessionConfig { + keys: vec![ + (alice(), to_session_keys( + &Ed25519Keyring::Alice, + &Sr25519Keyring::Alice, + )), + (bob(), to_session_keys( + &Ed25519Keyring::Bob, + &Sr25519Keyring::Bob, + )), + (charlie(), to_session_keys( + &Ed25519Keyring::Charlie, + &Sr25519Keyring::Charlie, + )), + ] + }), + staking: Some(StakingConfig { + current_era: 0, + stakers: vec![ + (dave(), alice(), 111 * DOLLARS, staking::StakerStatus::Validator), + (eve(), bob(), 100 * DOLLARS, staking::StakerStatus::Validator), + (ferdie(), charlie(), 100 * DOLLARS, staking::StakerStatus::Validator) + ], + validator_count: 3, + minimum_validator_count: 0, + slash_reward_fraction: Perbill::from_percent(10), + invulnerables: vec![alice(), bob(), charlie()], + .. Default::default() + }), + contracts: Some(ContractsConfig { + current_schedule: Default::default(), + gas_price: 1 * MILLICENTS, + }), + babe: Some(Default::default()), + grandpa: Some(GrandpaConfig { + authorities: vec![], + }), + im_online: Some(Default::default()), + democracy: Some(Default::default()), + collective_Instance1: Some(Default::default()), + collective_Instance2: Some(Default::default()), + membership_Instance1: Some(Default::default()), + elections: Some(Default::default()), + sudo: Some(Default::default()), + } +} diff --git a/node/testing/src/keyring.rs b/node/testing/src/keyring.rs new file mode 100644 index 0000000000000..12a3e7c2d4d43 --- /dev/null +++ b/node/testing/src/keyring.rs @@ -0,0 +1,103 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Test accounts. + +use keyring::{AccountKeyring, Sr25519Keyring, Ed25519Keyring}; +use node_primitives::{AccountId, Balance, Index}; +use node_runtime::{CheckedExtrinsic, UncheckedExtrinsic, SessionKeys, SignedExtra}; +use sr_primitives::generic::Era; +use codec::Encode; + +/// Alice's account id. +pub fn alice() -> AccountId { + AccountKeyring::Alice.into() +} + +/// Bob's account id. +pub fn bob() -> AccountId { + AccountKeyring::Bob.into() +} + +/// Charlie's account id. +pub fn charlie() -> AccountId { + AccountKeyring::Charlie.into() +} + +/// Dave's account id. +pub fn dave() -> AccountId { + AccountKeyring::Dave.into() +} + +/// Eve's account id. +pub fn eve() -> AccountId { + AccountKeyring::Eve.into() +} + +/// Ferdie's account id. +pub fn ferdie() -> AccountId { + AccountKeyring::Ferdie.into() +} + +/// Convert keyrings into `SessionKeys`. +pub fn to_session_keys( + ed25519_keyring: &Ed25519Keyring, + sr25519_keyring: &Sr25519Keyring, +) -> SessionKeys { + SessionKeys { + grandpa: ed25519_keyring.to_owned().public().into(), + babe: sr25519_keyring.to_owned().public().into(), + im_online: sr25519_keyring.to_owned().public().into(), + } +} + +/// Returns transaction extra. +pub fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { + ( + system::CheckVersion::new(), + system::CheckGenesis::new(), + system::CheckEra::from(Era::mortal(256, 0)), + system::CheckNonce::from(nonce), + system::CheckWeight::new(), + balances::TakeFees::from(extra_fee) + ) +} + +/// Sign given `CheckedExtrinsic`. +pub fn sign(xt: CheckedExtrinsic, version: u32, genesis_hash: [u8; 32]) -> UncheckedExtrinsic { + match xt.signed { + Some((signed, extra)) => { + let payload = (xt.function, extra.clone(), version, genesis_hash, genesis_hash); + let key = AccountKeyring::from_public(&signed).unwrap(); + let signature = payload.using_encoded(|b| { + if b.len() > 256 { + key.sign(&sr_io::blake2_256(b)) + } else { + key.sign(b) + } + }).into(); + UncheckedExtrinsic { + signature: Some((indices::address::Address::Id(signed), signature, extra)), + function: payload.0, + } + } + None => UncheckedExtrinsic { + signature: None, + function: xt.function, + }, + } +} + diff --git a/node/testing/src/lib.rs b/node/testing/src/lib.rs new file mode 100644 index 0000000000000..71a22d9b57f25 --- /dev/null +++ b/node/testing/src/lib.rs @@ -0,0 +1,24 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! A set of testing utilities for Substrate Node. + +#![warn(missing_docs)] + +pub mod client; +pub mod genesis; +pub mod keyring; +