From 22fc4951909c9e612f0079fe992586aba981e5f1 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Thu, 29 Aug 2019 17:44:46 +0200 Subject: [PATCH] Initial node-template --- .gitignore | 7 + substrate-node-rename.sh | 60 + substrate-node-template.tar.gz | Bin 0 -> 51917 bytes substrate-node-template/Cargo.lock | 5527 +++++++++++++++++ substrate-node-template/Cargo.toml | 103 + substrate-node-template/LICENSE | 24 + substrate-node-template/README.md | 70 + substrate-node-template/build.rs | 24 + substrate-node-template/runtime/Cargo.toml | 155 + substrate-node-template/runtime/build.rs | 27 + substrate-node-template/runtime/src/lib.rs | 409 ++ .../runtime/src/template.rs | 133 + substrate-node-template/scripts/init.sh | 16 + substrate-node-template/src/chain_spec.rs | 135 + substrate-node-template/src/cli.rs | 112 + substrate-node-template/src/main.rs | 28 + substrate-node-template/src/service.rs | 230 + 17 files changed, 7060 insertions(+) create mode 100644 .gitignore create mode 100644 substrate-node-rename.sh create mode 100644 substrate-node-template.tar.gz create mode 100644 substrate-node-template/Cargo.lock create mode 100644 substrate-node-template/Cargo.toml create mode 100644 substrate-node-template/LICENSE create mode 100644 substrate-node-template/README.md create mode 100644 substrate-node-template/build.rs create mode 100644 substrate-node-template/runtime/Cargo.toml create mode 100644 substrate-node-template/runtime/build.rs create mode 100644 substrate-node-template/runtime/src/lib.rs create mode 100644 substrate-node-template/runtime/src/template.rs create mode 100755 substrate-node-template/scripts/init.sh create mode 100644 substrate-node-template/src/chain_spec.rs create mode 100644 substrate-node-template/src/cli.rs create mode 100644 substrate-node-template/src/main.rs create mode 100644 substrate-node-template/src/service.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4969d2e --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +# Generated by Cargo +# will have compiled files and executables +**/target/ +# These are backup files generated by rustfmt +**/*.rs.bk + +.DS_Store \ No newline at end of file diff --git a/substrate-node-rename.sh b/substrate-node-rename.sh new file mode 100644 index 0000000..583041d --- /dev/null +++ b/substrate-node-rename.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +name=$1 +shift +author=$1 +shift + +if [[ "$name" == "" || "$name" == "-"* ]] +then + echo "Usage: substrate-node-rename " + exit 1 +fi +if [[ "$author" == "" || "$author" == "-"* ]] +then + echo "Usage: substrate-node-rename " + exit 1 +fi + +lname="$(echo $name | tr '[:upper:]' '[:lower:]')" +dirname="${lname// /-}" + +bold=$(tput bold) +normal=$(tput sgr0) + +if [ -d "$dirname" ]; then + echo "Directory '$name' already exists!" + exit 1 +fi + +echo "${bold}Moving project folder...${normal}" + +git mv substrate-node-template $dirname + +pushd $dirname >/dev/null + +echo "${bold}Customizing project...${normal}" +function replace { + find_this="$1" + shift + replace_with="$1" + shift + IFS=$'\n' + TEMP=$(mktemp -d "${TMPDIR:-/tmp}/.XXXXXXXXXXXX") + rmdir $TEMP + for item in `find . -not -path '*/\.*' -type f \( -name "*.rs" -o -name "*.md" -o -name "build.sh" -o -name "Cargo.toml" -o -name "Cargo.lock" \)` + do + sed "s/$find_this/$replace_with/g" "$item" > $TEMP + cat $TEMP > "$item" + done + rm -f $TEMP +} + +replace "Template Node" "${name}" +replace node-template "${lname//[_ ]/-}" +replace node_template "${lname//[- ]/_}" +replace Anonymous "$author" + +echo "Rename Complete" + +popd >/dev/null diff --git a/substrate-node-template.tar.gz b/substrate-node-template.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..7037f7ece4613b559c00fd34c215dd674d107aca GIT binary patch literal 51917 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 pevkuzYHe~|!9in+iAZ" +"checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869" +"checksum futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "21c71ed547606de08e9ae744bb3c6d80f5627527ef31ecf2a7210d0e67bc8fae" +"checksum futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4b141ccf9b7601ef987f36f1c0d9522f76df3bba1cf2e63bfacccc044c4558f5" +"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" +"checksum futures-executor-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "87ba260fe51080ba37f063ad5b0732c4ff1f737ea18dcb67833d282cdc2c6f14" +"checksum futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "082e402605fcb8b1ae1e5ba7d7fdfd3e31ef510e2a8367dd92927bb41ae41b3a" +"checksum futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "bf25f91c8a9a1f64c451e91b43ba269ed359b9f52d35ed4b3ce3f9c842435867" +"checksum futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4309a25a1069a1f3c10647b227b9afe6722b67a030d3f00a9cbdc171fc038de4" +"checksum futures-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb4a32e84935678650944c6ebd0d912db46405d37bf94f1a058435c5080abcb1" +"checksum futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "af8198c48b222f02326940ce2b3aa9e6e91a32886eeaad7ca3b8e4c70daa3f4e" +"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" +"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +"checksum generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fceb69994e330afed50c93524be68c42fa898c2d9fd4ee8da03bd7363acd26f2" +"checksum get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" +"checksum get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" +"checksum getrandom 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fc344b02d3868feb131e8b5fe2b9b0a1cc42942679af493061fc13b853243872" +"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" +"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" +"checksum hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" +"checksum hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +"checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" +"checksum hashbrown 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bcea5b597dd98e6d1f1ec171744cc5dee1a30d1c23c5b98e3cf9d4fbdf8a526" +"checksum hashmap_core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6852e5a86250521973b0c1d39677166d8a9c0047c908d7e04f1aa04177973c" +"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" +"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" +"checksum hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" +"checksum hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d" +"checksum hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a13f4163aa0c5ca1be584aace0e2212b2e41be5478218d4f657f5f778b2ae2a" +"checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +"checksum hmac-drbg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe727d41d2eec0a6574d887914347e5ff96a3b87177817e2a9820c5c87fecc2" +"checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4" +"checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" +"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" +"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" +"checksum hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)" = "7cb44cbce9d8ee4fb36e4c0ad7b794ac44ebaad924b9c8291a63215bb44c2c8f" +"checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" +"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" +"checksum impl-codec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78c441b3d2b5e24b407161e76d482b7bbd29b5da357707839ac40d95152f031f" +"checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" +"checksum impl-serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d26be4b97d738552ea423f76c4f681012ff06c3fa36fa968656b3679f60b4a1" +"checksum indexmap 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4d6d89e0948bf10c08b9ecc8ac5b83f07f857ebe2c0cbe38de15b4e4f510356" +"checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" +"checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" +"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum ipnet 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e61c2da0d0f700c77d2d313dbf4f93e41d235fa12c6681fee06621036df4c2af" +"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum js-sys 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "1efc4f2a556c58e79c5500912e221dd826bec64ff4aabd8ce71ccef6da02d7d4" +"checksum jsonrpc-client-transports 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39577db48b004cffb4c5b8e5c9b993c177c52599ecbee88711e815acf65144db" +"checksum jsonrpc-core 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd42951eb35079520ee29b7efbac654d85821b397ef88c8151600ef7e2d00217" +"checksum jsonrpc-core-client 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f047c10738edee7c3c6acf5241a0ce33df32ef9230c1a7fb03e4a77ee72c992f" +"checksum jsonrpc-derive 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29f9149f785deaae92a4c834a9a1a83a4313b8cfedccf15362cd4cf039a64501" +"checksum jsonrpc-http-server 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4edd28922653d79e4f6c0f5d0a1034a4edbc5f9cf6cad8ec85e2a685713e3708" +"checksum jsonrpc-pubsub 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c08b444cc0ed70263798834343d0ac875e664257df8079160f23ac1ea79446" +"checksum jsonrpc-server-utils 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44561bfdd31401bad790527f1e951dde144f2341ddc3e1b859d32945e1a34eff" +"checksum jsonrpc-ws-server 13.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d230ff76a8e4a3fb068aab6ba23d0c4e7d6e3b41bca524daa33988b04b065265" +"checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" +"checksum kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" +"checksum kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" +"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" +"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" +"checksum libp2p 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4183fb4be621d97baebbbe0c499d6ae337e9e6ec955f9fa3cb29e55547dfacdb" +"checksum libp2p-core 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a7ebd9d597299512e096cc1bd58e955c03ef28f33214a33b9c7e4ace109ff41" +"checksum libp2p-core-derive 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baffb3527eac95b717e5ebcd6539007152019a06b00548352cbd74474c07db27" +"checksum libp2p-deflate 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84bb91afe976893b9822103522cc178bd66eb7aa8e54c69ddd9e1825a3d894ab" +"checksum libp2p-dns 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b43d79936984b46a5ef4d7b070eaf786f6fab2d1a57e07646306b492e38b2d7f" +"checksum libp2p-floodsub 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "798615b01761454818788dafe61b4fe2bda4306bfa5378cbe8715f57b752235f" +"checksum libp2p-identify 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0a630d5ab928403e426672187514884a9ed0ea2065970ef0ec64971770be6d5" +"checksum libp2p-kad 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66d2214dd47fa67878eaf0d76d19fd129eff65c45f83617829eb177b7285f97" +"checksum libp2p-mdns 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbd443101542670935b6e6863b7bb88c10ac04393062e662201a3c104d80ae00" +"checksum libp2p-mplex 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59f283e603b078aa88e65c66c5d4f842f67bfbe4d016b0ae345b7e3bb78fe0af" +"checksum libp2p-noise 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ab3c7b36cde3bfe18a1d7a0a5693361115066365d32c60f210acc8224b88017" +"checksum libp2p-ping 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006bbfcb7d6ca7e617cb2924d99fff0e391d4c6e42e7047e226692c8c3e1f6a0" +"checksum libp2p-plaintext 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4e673668e5ef47689ca832c33f2dc1e321ede245ee50b6084e4c45cce10fff6" +"checksum libp2p-ratelimit 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "838538f6df5941626047903d14edc3112afb2807fc139535a8ca78469ccaf1ac" +"checksum libp2p-secio 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a99533cb55b9554d2927ad8a220c87b4e0bbfdec22b738eb6030b03e6a722fa1" +"checksum libp2p-swarm 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541f66cc794e522fb8072d35dba6be3fe4c3ffeadbed39bf4a6939d0695b4134" +"checksum libp2p-tcp 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4e56f7c7e31d303898d51b293f8d95dcb99e6293fefebe184df03e82dd37571" +"checksum libp2p-uds 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "180fa5ceb2f986786b4fca9582f6ffb98772db2e44df07c800693c97205e3310" +"checksum libp2p-wasm-ext 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a806f0e4985ae2dbac2cbebadb72d586ffe2e1f62a265f5e019e57a3f02aa481" +"checksum libp2p-websocket 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e0dd3cb203aaa1736a38cdd157709153f90bfaed06b87f4dc3ebb62b5d79a643" +"checksum libp2p-yamux 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a37bed07c8ee0ceeecdfb90d703aa6b1cec99a69b4157e5f7f2c03acacbfca15" +"checksum librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d19778314deaa7048f2ea7d07b8aa12e1c227acebe975a37eeab6d2f8c74e41b" +"checksum libsecp256k1 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "688e8d65e495567c2c35ea0001b26b9debf0b4ea11f8cccc954233b75fc3428a" +"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" +"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" +"checksum linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c" +"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" +"checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" +"checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" +"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +"checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +"checksum malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "35adee9ed962cf7d07d62cb58bc45029f3227f5b5b86246caa8632f06c187bc3" +"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" +"checksum memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ef49315991403ba5fa225a70399df5e115f57b274cb0b1b4bcd6e734fa5bd783" +"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" +"checksum merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "66448a173ad394ef5ebf734efa724f3644dcffda083b1e89979da4461ddac079" +"checksum miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" +"checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10" +"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" +"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" +"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" +"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum multistream-select 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f3cb4c93f2d79811fc11fa01faab99d8b7b8cbe024b602c27434ff2b08a59d" +"checksum names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da" +"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" +"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum nohash-hasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d138afcce92d219ccb6eb53d9b1e8a96ac0d633cfd3c53cd9856d96d1741bb8" +"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" +"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718" +"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" +"checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454" +"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" +"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" +"checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" +"checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" +"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +"checksum openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)" = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15" +"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" +"checksum openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)" = "f4fad9e54bd23bd4cbbe48fdc08a1b8091707ac869ef8508edea2fec77dcc884" +"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" +"checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" +"checksum parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "045b3c7af871285146300da35b1932bb6e4639b66c7c98e85d06a32cbc4e8fa7" +"checksum parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" +"checksum parity-scale-codec 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "65582b5c02128a4b0fa60fb3e070216e9c84be3e4a8f1b74bc37e15a25e58daf" +"checksum parity-scale-codec-derive 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a81f3cd93ed368a8e41c4e79538e99ca6e8f536096de23e3a0bc3e782093ce28" +"checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" +"checksum parity-util-mem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2005637ccf93dbb60c85081ccaaf3f945f573da48dcc79f27f9646caa3ec1dc" +"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" +"checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac" +"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" +"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" +"checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" +"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" +"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" +"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" +"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" +"checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" +"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +"checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49" +"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" +"checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" +"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" +"checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af" +"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" +"checksum primitive-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e44400d651ca5276415dc8e00541c5c9d03844f1f0a87ad28f0a8fadcb2300bc" +"checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" +"checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8" +"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +"checksum proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c5c2380ae88876faae57698be9e9775e3544decad214599c3a6266cca6ac802" +"checksum protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8aefcec9f142b524d98fc81d07827743be89dd6586a1ba6ab21fa66a500b3fa5" +"checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" +"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" +"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" +"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" +"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +"checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4" +"checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +"checksum regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88c3d9193984285d544df4a30c23a4e62ead42edf70a4452ceb76dac1ce05c26" +"checksum regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b143cceb2ca5e56d5671988ef8b15615733e7ee16cd348e064333b251b89343f" +"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" +"checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" +"checksum rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1651697fefd273bfb4fd69466cc2a9d20de557a0213b97233b22b5e95924b5e" +"checksum rpassword 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c34fa7bcae7fca3c8471e8417088bbc3ad9af8066b0ecf4f3c0d98a0d772716e" +"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" +"checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f271e3552cd835fa28c541c34a7e8fdd8cdff09d77fe4eb8f6c42e87a11b096e" +"checksum rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9cbe61c20455d3015b2bb7be39e1872310283b8e5a52f5b242b0ac7581fe78" +"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" +"checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" +"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" +"checksum schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" +"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" +"checksum sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f5adf8fbd58e1b1b52699dc8bed2630faecb6d8c7bee77d009d6bbe4af569b9" +"checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2" +"checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" +"checksum serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f" +"checksum serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4dc18c61206b08dc98216c98faa0232f4337e1e1b8574551d5bad29ea1b425" +"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" +"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" +"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +"checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" +"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" +"checksum sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" +"checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" +"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +"checksum slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cc9c640a4adbfbcc11ffb95efe5aa7af7309e002adab54b185507dbf2377b99" +"checksum slog-async 2.3.0 (git+https://github.com/paritytech/slog-async)" = "" +"checksum slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a" +"checksum slog-scope 4.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d1d3ec6214d46e57a7ec87c1972bbca66c59172a0cfffa5233c54726afb946bf" +"checksum slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eff3b513cf2e0d1a60e1aba152dc72bedc5b05585722bb3cebd7bcb1e31b98f" +"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" +"checksum snow 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5a64f02fd208ef15bd2d1a65861df4707e416151e1272d02c8faafad1c138100" +"checksum soketto 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bceb1a3a15232d013d9a3b7cac9e5ce8e2313f348f01d4bc1097e5e53aa07095" +"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" +"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +"checksum sr-api-macros 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum sr-io 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum sr-staking-primitives 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum sr-std 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum sr-version 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-authorship 0.1.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-babe 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-balances 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-executive 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-finality-tracker 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-grandpa 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-indices 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-metadata 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-session 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-sudo 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-support 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-support-procedural 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-support-procedural-tools 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-support-procedural-tools-derive 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-system 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum srml-timestamp 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" +"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" +"checksum static_slice 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "92a7e0c5e3dfb52e8fbe0e63a1b947bbb17b4036408b151353c4491374931362" +"checksum stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c" +"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" +"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" +"checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" +"checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" +"checksum strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1c33039533f051704951680f1adfd468fd37ac46816ded0d9ee068e60f05f" +"checksum strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47cd23f5c7dee395a00fa20135e2ec0fffcdfa151c56182966d7a3261343432e" +"checksum substrate-application-crypto 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-basic-authorship 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" +"checksum substrate-cli 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-client 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-client-db 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-consensus-babe 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-consensus-babe-primitives 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-consensus-common 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-consensus-slots 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-consensus-uncles 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-executor 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-finality-grandpa 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-finality-grandpa-primitives 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-inherents 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-keyring 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-keystore 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-network 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-offchain 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-offchain-primitives 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-panic-handler 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-peerset 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-primitives 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-rpc 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-rpc-api 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-rpc-servers 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-serializer 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-service 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-session 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-state-db 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-state-machine 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-telemetry 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-transaction-graph 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-transaction-pool 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-trie 2.0.0 (git+https://github.com/paritytech/substrate.git?rev=3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90)" = "" +"checksum substrate-wasm-builder-runner 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af21b27fad38b212c1919f700cb0def33c88cde14d22e0d1b17d4521f4eb8b40" +"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" +"checksum subtle 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "01f40907d9ffc762709e4ff3eb4a6f6b41b650375a3f09ac92b641942b7fb082" +"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" +"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" +"checksum sysinfo 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ee7d12b854e48e680bf4b10856a7867e843845158fa8226e6c2f6cc38539cb01" +"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" +"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" +"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +"checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" +"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" +"checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" +"checksum tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" +"checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" +"checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" +"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" +"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" +"checksum tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82c65483db54eb91b4ef3a9389a3364558590faf30ce473141707c0e16fda975" +"checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" +"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" +"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" +"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce" +"checksum tokio-rustls 0.10.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3e5cebc3ca33110e460c4d2e7c5e863b159fadcbf125449d896720695b2af709" +"checksum tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2162248ff317e2bc713b261f242b69dbb838b85248ed20bb21df56d60ea4cae7" +"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" +"checksum tokio-threadpool 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "90ca01319dea1e376a001e8dc192d42ebde6dd532532a5bad988ac37db365b19" +"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" +"checksum tokio-udp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "56775b287cda0fd8ca0c5d2f5b1d0646afbd360101e2eef91cd89365fcfc2f5f" +"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" +"checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" +"checksum trie-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0b62d27e8aa1c07414549ac872480ac82380bab39e730242ab08d82d7cc098a" +"checksum trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b779f7c1c8fe9276365d9d5be5c4b5adeacf545117bb3f64c974305789c5c0b" +"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" +"checksum twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" +"checksum twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" +"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" +"checksum uint 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8f0f47ed099f0db671ce82c66548c5de012e3c0cba3963514d1db15c7588701" +"checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6" +"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" +"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" +"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum unsigned-varint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c64cdf40b4a9645534a943668681bcb219faf51874d4b65d2e0abda1b10a2ab" +"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" +"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" +"checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba" +"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" +"checksum wasi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd5442abcac6525a045cc8c795aedb60da7a2e5e89c7bf18a0d5357849bb23c7" +"checksum wasm-bindgen 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "dcddca308b16cd93c2b67b126c688e5467e4ef2e28200dc7dfe4ae284f2faefc" +"checksum wasm-bindgen-backend 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "f805d9328b5fc7e5c6399960fd1889271b9b58ae17bdb2417472156cc9fafdd0" +"checksum wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c" +"checksum wasm-bindgen-macro 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "3ff88201a482abfc63921621f6cb18eb1efd74f136b05e5841e7f8ca434539e9" +"checksum wasm-bindgen-macro-support 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "6a433d89ecdb9f77d46fcf00c8cf9f3467b7de9954d8710c175f61e2e245bb0e" +"checksum wasm-bindgen-shared 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "d41fc1bc3570cdf8d108c15e014045fd45a95bb5eb36605f96a90461fc34027d" +"checksum wasm-bindgen-webidl 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "be53d289bf2fa7645a089cfd5c7a34bf4fe94221f58cf86ee42a7b4bc854ff14" +"checksum wasm-timer 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3d6101df9a5987df809216bdda7289f52b58128e6b6a6546e9ee3e6b632b4921" +"checksum wasmi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48437c526d40a6a593c50c5367dac825b8d6a04411013e866eca66123fb56faa" +"checksum wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab380192444b3e8522ae79c0a1976e42a82920916ccdfbce3def89f456ea33f3" +"checksum web-sys 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "6435c477200ad486089a7a72c2bd6c9bdf9740bd7fff868806076218076d8c51" +"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 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" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" +"checksum ws 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6f5bb86663ff4d1639408410f50bf6050367a8525d644d49a6894cd618a631" +"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +"checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" +"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" +"checksum yamux 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "01bd67889938c48f0049fc60a77341039e6c3eaf16cb7693e6ead7c0ba701295" +"checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" +"checksum zeroize_derive 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "080616bd0e31f36095288bb0acdf1f78ef02c2fa15527d7e993f2a6c7591643e" diff --git a/substrate-node-template/Cargo.toml b/substrate-node-template/Cargo.toml new file mode 100644 index 0000000..d350cfa --- /dev/null +++ b/substrate-node-template/Cargo.toml @@ -0,0 +1,103 @@ +[build-dependencies] +vergen = '3' +[profile.release] +panic = 'unwind' + +[workspace] +members = ['runtime'] + +[dependencies] +derive_more = '0.14.0' +exit-future = '0.1' +futures = '0.1' +log = '0.4' +parking_lot = '0.9.0' +tokio = '0.1' +trie-root = '0.15.2' + +[dependencies.babe] +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-consensus-babe' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.babe-primitives] +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-consensus-babe-primitives' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.basic-authorship] +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-basic-authorship' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.codec] +package = 'parity-scale-codec' +version = '1.0.0' + +[dependencies.ctrlc] +features = ['termination'] +version = '3.0' + +[dependencies.grandpa] +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-finality-grandpa' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.grandpa-primitives] +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-finality-grandpa-primitives' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.inherents] +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-inherents' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.network] +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-network' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.node-template-runtime] +path = 'runtime' + +[dependencies.primitives] +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-primitives' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.sr-io] +git = 'https://github.com/paritytech/substrate.git' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.substrate-cli] +git = 'https://github.com/paritytech/substrate.git' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.substrate-client] +git = 'https://github.com/paritytech/substrate.git' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.substrate-executor] +git = 'https://github.com/paritytech/substrate.git' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.substrate-service] +git = 'https://github.com/paritytech/substrate.git' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.transaction-pool] +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-transaction-pool' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[package] +authors = ['Anonymous'] +build = 'build.rs' +edition = '2018' +name = 'node-template' +version = '2.0.0' + +[[bin]] +name = 'node-template' +path = 'src/main.rs' diff --git a/substrate-node-template/LICENSE b/substrate-node-template/LICENSE new file mode 100644 index 0000000..cf1ab25 --- /dev/null +++ b/substrate-node-template/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/substrate-node-template/README.md b/substrate-node-template/README.md new file mode 100644 index 0000000..5a59652 --- /dev/null +++ b/substrate-node-template/README.md @@ -0,0 +1,70 @@ +# Substrate Node Template + +A new SRML-based Substrate node, ready for hacking. + +## Build + +Install Rust: + +```bash +curl https://sh.rustup.rs -sSf | sh +``` + +Install required tools: + +```bash +./scripts/init.sh +``` + +Build Wasm and native code: + +```bash +cargo build +``` + +## Run + +### Single node development chain + +You can start a development chain with: + +```bash +cargo run -- --dev +``` + +Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`. + +### Multi-node local testnet + +If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with testnet units. + +Optionally, give each node a name and expose them so they are listed on the Polkadot [telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet). + +You'll need two terminal windows open. + +We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The bootnode ID of her node is `QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR`, which is generated from the `--node-key` value that we specify below: + +```bash +cargo run -- \ + --base-path /tmp/alice \ + --chain=local \ + --alice \ + --node-key 0000000000000000000000000000000000000000000000000000000000000001 \ + --telemetry-url ws://telemetry.polkadot.io:1024 \ + --validator +``` + +In the second terminal, we'll start Bob's substrate node on a different TCP port of 30334, and with his chain database stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's bootnode ID on TCP port 30333: + +```bash +cargo run -- \ + --base-path /tmp/bob \ + --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR \ + --chain=local \ + --bob \ + --port 30334 \ + --telemetry-url ws://telemetry.polkadot.io:1024 \ + --validator +``` + +Additional CLI usage options are available and may be shown by running `cargo run -- --help`. diff --git a/substrate-node-template/build.rs b/substrate-node-template/build.rs new file mode 100644 index 0000000..bab46f5 --- /dev/null +++ b/substrate-node-template/build.rs @@ -0,0 +1,24 @@ +use std::{env, path::PathBuf}; + +use vergen::{ConstantsFlags, generate_cargo_keys}; + +const ERROR_MSG: &str = "Failed to generate metadata files"; + +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 + } + + manifest_dir.pop(); + } + + println!("cargo:warning=Could not find `.git/HEAD` from manifest dir!"); +} diff --git a/substrate-node-template/runtime/Cargo.toml b/substrate-node-template/runtime/Cargo.toml new file mode 100644 index 0000000..5ff9644 --- /dev/null +++ b/substrate-node-template/runtime/Cargo.toml @@ -0,0 +1,155 @@ +[package] +authors = ['Anonymous'] +edition = '2018' +name = 'node-template-runtime' +version = '2.0.0' +[dependencies.babe] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'srml-babe' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.babe-primitives] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-consensus-babe-primitives' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.balances] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'srml-balances' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.client] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-client' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.codec] +default-features = false +features = ['derive'] +package = 'parity-scale-codec' +version = '1.0.0' + +[dependencies.executive] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'srml-executive' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.grandpa] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'srml-grandpa' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.indices] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'srml-indices' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.offchain-primitives] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-offchain-primitives' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.primitives] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'substrate-primitives' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.rstd] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'sr-std' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.runtime-io] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'sr-io' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.safe-mix] +default-features = false +version = '1.0' + +[dependencies.serde] +features = ['derive'] +optional = true +version = '1.0' + +[dependencies.sr-primitives] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.substrate-session] +default-features = false +git = 'https://github.com/paritytech/substrate.git' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.sudo] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'srml-sudo' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.support] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'srml-support' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.system] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'srml-system' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.timestamp] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'srml-timestamp' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' + +[dependencies.version] +default_features = false +git = 'https://github.com/paritytech/substrate.git' +package = 'sr-version' +rev = '3ba0f2a2dbd37c31851a0ff1c1c0c47aa940de90' +[build-dependencies.wasm-builder-runner] +package = 'substrate-wasm-builder-runner' +version = '1.0.2' + +[features] +default = ['std'] +no_std = [] +std = [ + 'codec/std', + 'client/std', + 'rstd/std', + 'runtime-io/std', + 'support/std', + 'balances/std', + 'babe/std', + 'babe-primitives/std', + 'executive/std', + 'indices/std', + 'grandpa/std', + 'primitives/std', + 'sr-primitives/std', + 'system/std', + 'timestamp/std', + 'sudo/std', + 'version/std', + 'serde', + 'safe-mix/std', + 'offchain-primitives/std', + 'substrate-session/std', +] diff --git a/substrate-node-template/runtime/build.rs b/substrate-node-template/runtime/build.rs new file mode 100644 index 0000000..1ed109d --- /dev/null +++ b/substrate-node-template/runtime/build.rs @@ -0,0 +1,27 @@ +// 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 . + +use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSource}; + +fn main() { + build_current_project_with_rustflags( + "wasm_binary.rs", + WasmBuilderSource::Crates("1.0.5"), + // This instructs LLD to export __heap_base as a global variable, which is used by the + // external memory allocator. + "-Clink-arg=--export=__heap_base", + ); +} diff --git a/substrate-node-template/runtime/src/lib.rs b/substrate-node-template/runtime/src/lib.rs new file mode 100644 index 0000000..6a73a47 --- /dev/null +++ b/substrate-node-template/runtime/src/lib.rs @@ -0,0 +1,409 @@ +//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm. + +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. +#![recursion_limit="256"] + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +use rstd::prelude::*; +use primitives::{OpaqueMetadata, crypto::key_types}; +use sr_primitives::{ + ApplyResult, transaction_validity::TransactionValidity, generic, create_runtime_str, + impl_opaque_keys, AnySignature +}; +use sr_primitives::traits::{NumberFor, BlakeTwo256, Block as BlockT, DigestFor, StaticLookup, Verify, ConvertInto}; +use sr_primitives::weights::Weight; +use babe::{AuthorityId as BabeId}; +use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight}; +use grandpa::fg_primitives::{self, ScheduledChange}; +use client::{ + block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api}, + runtime_api as client_api, impl_runtime_apis +}; +use version::RuntimeVersion; +#[cfg(feature = "std")] +use version::NativeVersion; + +// A few exports that help ease life for downstream crates. +#[cfg(any(feature = "std", test))] +pub use sr_primitives::BuildStorage; +pub use timestamp::Call as TimestampCall; +pub use balances::Call as BalancesCall; +pub use sr_primitives::{Permill, Perbill}; +pub use support::{StorageValue, construct_runtime, parameter_types}; + +/// An index to a block. +pub type BlockNumber = u32; + +/// Alias to 512-bit hash when used in the context of a transaction signature on the chain. +pub type Signature = AnySignature; + +/// Some way of identifying an account on the chain. We intentionally make it equivalent +/// to the public key of our transaction signing scheme. +pub type AccountId = ::Signer; + +/// The type for looking up accounts. We don't expect more than 4 billion of them, but you +/// never know... +pub type AccountIndex = u32; + +/// Balance of an account. +pub type Balance = u128; + +/// Index of a transaction in the chain. +pub type Index = u32; + +/// A hash of some data used by the chain. +pub type Hash = primitives::H256; + +/// Digest item type. +pub type DigestItem = generic::DigestItem; + +/// Used for the module template in `./template.rs` +mod template; + +/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know +/// the specifics of the runtime. They can then be made to be agnostic over specific formats +/// of data like extrinsics, allowing for them to continue syncing the network through upgrades +/// to even the core datastructures. +pub mod opaque { + use super::*; + + pub use sr_primitives::OpaqueExtrinsic as UncheckedExtrinsic; + + /// Opaque block header type. + pub type Header = generic::Header; + /// Opaque block type. + pub type Block = generic::Block; + /// Opaque block identifier type. + pub type BlockId = generic::BlockId; + + pub type SessionHandlers = (Grandpa, Babe); + + impl_opaque_keys! { + pub struct SessionKeys { + #[id(key_types::GRANDPA)] + pub grandpa: GrandpaId, + #[id(key_types::BABE)] + pub babe: BabeId, + } + } +} + +/// This runtime version. +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("node-template"), + impl_name: create_runtime_str!("node-template"), + authoring_version: 3, + spec_version: 4, + impl_version: 4, + apis: RUNTIME_API_VERSIONS, +}; + +/// Constants for Babe. + +/// Since BABE is probabilistic this is the average expected block time that +/// we are targetting. Blocks will be produced at a minimum duration defined +/// by `SLOT_DURATION`, but some slots will not be allocated to any +/// authority and hence no block will be produced. We expect to have this +/// block time on average following the defined slot duration and the value +/// of `c` configured for BABE (where `1 - c` represents the probability of +/// a slot being empty). +/// This value is only used indirectly to define the unit constants below +/// that are expressed in blocks. The rest of the code should use +/// `SLOT_DURATION` instead (like the timestamp module for calculating the +/// minimum period). +/// +pub const MILLISECS_PER_BLOCK: u64 = 6000; + +pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + +pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES; + +// These time units are defined in number of blocks. +pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); +pub const HOURS: BlockNumber = MINUTES * 60; +pub const DAYS: BlockNumber = HOURS * 24; + +// 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks. +pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); + +/// The version infromation used to identify this runtime when compiled natively. +#[cfg(feature = "std")] +pub fn native_version() -> NativeVersion { + NativeVersion { + runtime_version: VERSION, + can_author_with: Default::default(), + } +} + +parameter_types! { + pub const BlockHashCount: BlockNumber = 250; + pub const MaximumBlockWeight: Weight = 1_000_000; + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; + pub const Version: RuntimeVersion = VERSION; +} + +impl system::Trait for Runtime { + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The aggregated dispatch type that is available for extrinsics. + type Call = Call; + /// The lookup mechanism to get account ID from whatever is passed in dispatchers. + type Lookup = Indices; + /// The index type for storing how many extrinsics an account has signed. + type Index = Index; + /// The index type for blocks. + type BlockNumber = BlockNumber; + /// The type for hashing blocks and tries. + type Hash = Hash; + /// The hashing algorithm used. + type Hashing = BlakeTwo256; + /// The header type. + type Header = generic::Header; + /// The ubiquitous event type. + type Event = Event; + /// Update weight (to fee) multiplier per-block. + type WeightMultiplierUpdate = (); + /// The ubiquitous origin type. + type Origin = Origin; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok. + type MaximumBlockWeight = MaximumBlockWeight; + /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. + type MaximumBlockLength = MaximumBlockLength; + /// Portion of the block weight that is available to all normal transactions. + type AvailableBlockRatio = AvailableBlockRatio; + type Version = Version; +} + +parameter_types! { + pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64; + pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK; +} + +impl babe::Trait for Runtime { + type EpochDuration = EpochDuration; + type ExpectedBlockTime = ExpectedBlockTime; +} + +impl grandpa::Trait for Runtime { + type Event = Event; +} + +impl indices::Trait for Runtime { + /// The type for recording indexing into the account enumeration. If this ever overflows, there + /// will be problems! + type AccountIndex = u32; + /// Use the standard means of resolving an index hint from an id. + type ResolveHint = indices::SimpleResolveHint; + /// Determine whether an account is dead. + type IsDeadAccount = Balances; + /// The ubiquitous event type. + type Event = Event; +} + +parameter_types! { + pub const MinimumPeriod: u64 = 5000; +} + +impl timestamp::Trait for Runtime { + /// A timestamp: milliseconds since the unix epoch. + type Moment = u64; + type OnTimestampSet = Babe; + type MinimumPeriod = MinimumPeriod; +} + +parameter_types! { + pub const ExistentialDeposit: u128 = 500; + pub const TransferFee: u128 = 0; + pub const CreationFee: u128 = 0; + pub const TransactionBaseFee: u128 = 0; + pub const TransactionByteFee: u128 = 1; +} + +impl balances::Trait for Runtime { + /// The type for recording an account's balance. + type Balance = Balance; + /// What to do if an account's free balance gets zeroed. + type OnFreeBalanceZero = (); + /// What to do if a new account is created. + type OnNewAccount = Indices; + /// The ubiquitous event type. + type Event = Event; + + type TransactionPayment = (); + type DustRemoval = (); + type TransferPayment = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = ConvertInto; +} + +impl sudo::Trait for Runtime { + type Event = Event; + type Proposal = Call; +} + +/// Used for the module template in `./template.rs` +impl template::Trait for Runtime { + type Event = Event; +} + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = opaque::Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system::{Module, Call, Storage, Config, Event}, + Timestamp: timestamp::{Module, Call, Storage, Inherent}, + Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, + Grandpa: grandpa::{Module, Call, Storage, Config, Event}, + Indices: indices::{default, Config}, + Balances: balances, + Sudo: sudo, + // Used for the module template in `./template.rs` + TemplateModule: template::{Module, Call, Storage, Event}, + } +); + +/// The address format for describing accounts. +pub type Address = ::Source; +/// Block header type as expected by this runtime. +pub type Header = generic::Header; +/// Block type as expected by this runtime. +pub type Block = generic::Block; +/// A Block signed with a Justification +pub type SignedBlock = generic::SignedBlock; +/// BlockId type as expected by this runtime. +pub type BlockId = generic::BlockId; +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( + system::CheckVersion, + system::CheckGenesis, + system::CheckEra, + system::CheckNonce, + system::CheckWeight, + balances::TakeFees +); +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; +/// Extrinsic type that has already been checked. +pub type CheckedExtrinsic = generic::CheckedExtrinsic; +/// Executive: handles dispatch to the various modules. +pub type Executive = executive::Executive, Runtime, AllModules>; + +impl_runtime_apis! { + impl client_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block) + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl client_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + Runtime::metadata().into() + } + } + + impl block_builder_api::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult { + data.check_extrinsics(&block) + } + + fn random_seed() -> ::Hash { + System::random_seed() + } + } + + impl client_api::TaggedTransactionQueue for Runtime { + fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity { + Executive::validate_transaction(tx) + } + } + + impl offchain_primitives::OffchainWorkerApi for Runtime { + fn offchain_worker(number: NumberFor) { + Executive::offchain_worker(number) + } + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_pending_change(digest: &DigestFor) + -> Option>> + { + Grandpa::pending_change(digest) + } + + fn grandpa_forced_change(digest: &DigestFor) + -> Option<(NumberFor, ScheduledChange>)> + { + Grandpa::forced_change(digest) + } + + fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> { + Grandpa::grandpa_authorities() + } + } + + impl babe_primitives::BabeApi for Runtime { + fn startup_data() -> babe_primitives::BabeConfiguration { + // The choice of `c` parameter (where `1 - c` represents the + // probability of a slot being empty), is done in accordance to the + // slot duration and expected target block time, for safely + // resisting network delays of maximum two seconds. + // + babe_primitives::BabeConfiguration { + median_required_blocks: 1000, + slot_duration: Babe::slot_duration(), + c: PRIMARY_PROBABILITY, + } + } + + fn epoch() -> babe_primitives::Epoch { + babe_primitives::Epoch { + start_slot: Babe::epoch_start_slot(), + authorities: Babe::authorities(), + epoch_index: Babe::epoch_index(), + randomness: Babe::randomness(), + duration: EpochDuration::get(), + secondary_slots: Babe::secondary_slots().0, + } + } + } + + impl substrate_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + let seed = seed.as_ref().map(|s| rstd::str::from_utf8(&s).expect("Seed is an utf8 string")); + opaque::SessionKeys::generate(seed) + } + } +} diff --git a/substrate-node-template/runtime/src/template.rs b/substrate-node-template/runtime/src/template.rs new file mode 100644 index 0000000..c1fa6f2 --- /dev/null +++ b/substrate-node-template/runtime/src/template.rs @@ -0,0 +1,133 @@ +/// A runtime module template with necessary imports + +/// Feel free to remove or edit this file as needed. +/// If you change the name of this file, make sure to update its references in runtime/src/lib.rs +/// If you remove this file, you can remove those references + + +/// For more guidance on Substrate modules, see the example module +/// https://github.com/paritytech/substrate/blob/master/srml/example/src/lib.rs + +use support::{decl_module, decl_storage, decl_event, StorageValue, dispatch::Result}; +use system::ensure_signed; + +/// The module's configuration trait. +pub trait Trait: system::Trait { + // TODO: Add other types and constants required configure this module. + + /// The overarching event type. + type Event: From> + Into<::Event>; +} + +// This module's storage items. +decl_storage! { + trait Store for Module as TemplateModule { + // Just a dummy storage item. + // Here we are declaring a StorageValue, `Something` as a Option + // `get(something)` is the default getter which returns either the stored `u32` or `None` if nothing stored + Something get(something): Option; + } +} + +// The module's dispatchable functions. +decl_module! { + /// The module declaration. + pub struct Module for enum Call where origin: T::Origin { + // Initializing events + // this is needed only if you are using events in your module + fn deposit_event() = default; + + // Just a dummy entry point. + // function that can be called by the external world as an extrinsics call + // takes a parameter of the type `AccountId`, stores it and emits an event + pub fn do_something(origin, something: u32) -> Result { + // TODO: You only need this if you want to check it was signed. + let who = ensure_signed(origin)?; + + // TODO: Code to execute when something calls this. + // For example: the following line stores the passed in u32 in the storage + Something::put(something); + + // here we are raising the Something event + Self::deposit_event(RawEvent::SomethingStored(something, who)); + Ok(()) + } + } +} + +decl_event!( + pub enum Event where AccountId = ::AccountId { + // Just a dummy event. + // Event `Something` is declared with a parameter of the type `u32` and `AccountId` + // To emit this event, we call the deposit funtion, from our runtime funtions + SomethingStored(u32, AccountId), + } +); + +/// tests for this module +#[cfg(test)] +mod tests { + use super::*; + + use runtime_io::with_externalities; + use primitives::{H256, Blake2Hasher}; + use support::{impl_outer_origin, assert_ok, parameter_types}; + use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + use sr_primitives::weights::Weight; + use sr_primitives::Perbill; + + impl_outer_origin! { + pub enum Origin for Test {} + } + + // For testing the module, we construct most of a mock runtime. This means + // first constructing a configuration type (`Test`) which `impl`s each of the + // configuration traits of modules we want to use. + #[derive(Clone, Eq, PartialEq)] + pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + } + impl system::Trait for Test { + type Origin = Origin; + type Call = (); + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type WeightMultiplierUpdate = (); + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + } + impl Trait for Test { + type Event = (); + } + type TemplateModule = Module; + + // This function basically just builds a genesis storage key/value store according to + // our desired mockup. + fn new_test_ext() -> runtime_io::TestExternalities { + system::GenesisConfig::default().build_storage::().unwrap().into() + } + + #[test] + fn it_works_for_default_value() { + with_externalities(&mut new_test_ext(), || { + // Just a dummy test for the dummy funtion `do_something` + // calling the `do_something` function with a value 42 + assert_ok!(TemplateModule::do_something(Origin::signed(1), 42)); + // asserting that the stored value is equal to what we stored + assert_eq!(TemplateModule::something(), Some(42)); + }); + } +} diff --git a/substrate-node-template/scripts/init.sh b/substrate-node-template/scripts/init.sh new file mode 100755 index 0000000..cf5ecf9 --- /dev/null +++ b/substrate-node-template/scripts/init.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +set -e + +echo "*** Initializing WASM build environment" + +if [ -z $CI_PROJECT_NAME ] ; then + rustup update nightly + rustup update stable +fi + +rustup target add wasm32-unknown-unknown --toolchain nightly + +# Install wasm-gc. It's useful for stripping slimming down wasm binaries. +command -v wasm-gc || \ + cargo +nightly install --git https://github.com/alexcrichton/wasm-gc --force diff --git a/substrate-node-template/src/chain_spec.rs b/substrate-node-template/src/chain_spec.rs new file mode 100644 index 0000000..9fdc6ee --- /dev/null +++ b/substrate-node-template/src/chain_spec.rs @@ -0,0 +1,135 @@ +use primitives::{Pair, Public}; +use node_template_runtime::{ + AccountId, BabeConfig, BalancesConfig, GenesisConfig, GrandpaConfig, + SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, +}; +use babe_primitives::{AuthorityId as BabeId}; +use grandpa_primitives::{AuthorityId as GrandpaId}; +use substrate_service; + +// Note this is the URL for the telemetry server +//const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; + +/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type. +pub type ChainSpec = substrate_service::ChainSpec; + +/// 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 +/// from a string (`--chain=...`) into a `ChainSpec`. +#[derive(Clone, Debug)] +pub enum Alternative { + /// Whatever the current runtime is, with just Alice as an auth. + Development, + /// Whatever the current runtime is, with simple Alice/Bob auths. + LocalTestnet, +} + +/// Helper function to generate a crypto pair from seed +pub fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() +} + +/// Helper function to generate stash, controller and session key from seed +pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, GrandpaId, BabeId) { + ( + get_from_seed::(&format!("{}//stash", seed)), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + ) +} + +impl Alternative { + /// Get an actual chain config from one of the alternatives. + pub(crate) fn load(self) -> Result { + Ok(match self { + Alternative::Development => ChainSpec::from_genesis( + "Development", + "dev", + || testnet_genesis(vec![ + get_authority_keys_from_seed("Alice"), + ], + get_from_seed::("Alice"), + vec![ + get_from_seed::("Alice"), + get_from_seed::("Bob"), + get_from_seed::("Alice//stash"), + get_from_seed::("Bob//stash"), + ], + true), + vec![], + None, + None, + None, + None + ), + Alternative::LocalTestnet => ChainSpec::from_genesis( + "Local Testnet", + "local_testnet", + || testnet_genesis(vec![ + get_authority_keys_from_seed("Alice"), + get_authority_keys_from_seed("Bob"), + ], + get_from_seed::("Alice"), + vec![ + get_from_seed::("Alice"), + get_from_seed::("Bob"), + get_from_seed::("Charlie"), + get_from_seed::("Dave"), + get_from_seed::("Eve"), + get_from_seed::("Ferdie"), + get_from_seed::("Alice//stash"), + get_from_seed::("Bob//stash"), + get_from_seed::("Charlie//stash"), + get_from_seed::("Dave//stash"), + get_from_seed::("Eve//stash"), + get_from_seed::("Ferdie//stash"), + ], + true), + vec![], + None, + None, + None, + None + ), + }) + } + + pub(crate) fn from(s: &str) -> Option { + match s { + "dev" => Some(Alternative::Development), + "" | "local" => Some(Alternative::LocalTestnet), + _ => None, + } + } +} + +fn testnet_genesis(initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId)>, + root_key: AccountId, + endowed_accounts: Vec, + _enable_println: bool) -> GenesisConfig { + GenesisConfig { + system: Some(SystemConfig { + code: WASM_BINARY.to_vec(), + changes_trie_config: Default::default(), + }), + indices: Some(IndicesConfig { + ids: endowed_accounts.clone(), + }), + balances: Some(BalancesConfig { + balances: endowed_accounts.iter().cloned().map(|k|(k, 1 << 60)).collect(), + vesting: vec![], + }), + sudo: Some(SudoConfig { + key: root_key, + }), + babe: Some(BabeConfig { + authorities: initial_authorities.iter().map(|x| (x.3.clone(), 1)).collect(), + }), + grandpa: Some(GrandpaConfig { + authorities: initial_authorities.iter().map(|x| (x.2.clone(), 1)).collect(), + }), + } +} diff --git a/substrate-node-template/src/cli.rs b/substrate-node-template/src/cli.rs new file mode 100644 index 0000000..f6edbb2 --- /dev/null +++ b/substrate-node-template/src/cli.rs @@ -0,0 +1,112 @@ +use crate::service; +use futures::{future, Future, sync::oneshot}; +use std::cell::RefCell; +use tokio::runtime::Runtime; +pub use substrate_cli::{VersionInfo, IntoExit, error}; +use substrate_cli::{informant, parse_and_prepare, ParseAndPrepare, NoCustom}; +use substrate_service::{AbstractService, Roles as ServiceRoles}; +use crate::chain_spec; +use log::info; + +/// Parse command line arguments into service configuration. +pub fn run(args: I, exit: E, version: VersionInfo) -> error::Result<()> where + I: IntoIterator, + T: Into + Clone, + E: IntoExit, +{ + match parse_and_prepare::(&version, "substrate-node", args) { + ParseAndPrepare::Run(cmd) => cmd.run::<(), _, _, _, _>(load_spec, exit, + |exit, _cli_args, _custom_args, config| { + info!("{}", version.name); + info!(" version {}", config.full_version()); + info!(" by {}, 2017, 2018", 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(load_spec), + ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|config| + Ok(new_full_start!(config).0), load_spec, exit), + ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder::<(), _, _, _, _, _>(|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| + Ok(new_full_start!(config).0), load_spec), + ParseAndPrepare::CustomCommand(_) => Ok(()) + }?; + + Ok(()) +} + +fn load_spec(id: &str) -> Result, String> { + Ok(match chain_spec::Alternative::from(id) { + Some(spec) => Some(spec.load()?), + None => None, + }) +} + +fn run_until_exit( + 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(|err| error::Error::Service(err)); + 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 +} + +// handles ctrl-c +pub struct Exit; +impl IntoExit for Exit { + type Exit = future::MapErr, 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) + } +} diff --git a/substrate-node-template/src/main.rs b/substrate-node-template/src/main.rs new file mode 100644 index 0000000..024efcc --- /dev/null +++ b/substrate-node-template/src/main.rs @@ -0,0 +1,28 @@ +//! Substrate Node Template CLI library. + +#![warn(missing_docs)] +#![warn(unused_extern_crates)] + +mod chain_spec; +#[macro_use] +mod service; +mod cli; + +pub use substrate_cli::{VersionInfo, IntoExit, error}; + +fn main() { + let version = VersionInfo { + name: "Substrate Node", + commit: env!("VERGEN_SHA_SHORT"), + version: env!("CARGO_PKG_VERSION"), + executable_name: "node-template", + author: "Anonymous", + description: "Template Node", + support_url: "support.anonymous.an", + }; + + if let Err(e) = cli::run(::std::env::args(), cli::Exit, version) { + eprintln!("Fatal error: {}\n\n{:?}", e, e); + std::process::exit(1) + } +} diff --git a/substrate-node-template/src/service.rs b/substrate-node-template/src/service.rs new file mode 100644 index 0000000..7bb4cc8 --- /dev/null +++ b/substrate-node-template/src/service.rs @@ -0,0 +1,230 @@ +//! Service and ServiceFactory implementation. Specialized wrapper over substrate service. + +use std::sync::Arc; +use std::time::Duration; +use substrate_client::LongestChain; +use babe::{import_queue, start_babe, Config}; +use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; +use futures::prelude::*; +use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi, WASM_BINARY}; +use substrate_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder}; +use transaction_pool::{self, txpool::{Pool as TransactionPool}}; +use inherents::InherentDataProviders; +use network::construct_simple_protocol; +use substrate_executor::native_executor_instance; +pub use substrate_executor::NativeExecutor; + +// Our native executor instance. +native_executor_instance!( + pub Executor, + node_template_runtime::api::dispatch, + node_template_runtime::native_version +); + +construct_simple_protocol! { + /// Demo protocol attachment for substrate. + pub struct NodeProtocol where Block = Block { } +} + +/// 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_rules! new_full_start { + ($config:expr) => {{ + let mut import_setup = None; + let inherent_data_providers = inherents::InherentDataProviders::new(); + let mut tasks_to_spawn = None; + + let builder = substrate_service::ServiceBuilder::new_full::< + node_template_runtime::opaque::Block, node_template_runtime::RuntimeApi, crate::service::Executor + >($config)? + .with_select_chain(|_config, client| { + #[allow(deprecated)] + Ok(substrate_client::LongestChain::new(client.backend().clone())) + })? + .with_transaction_pool(|config, client| + Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::ChainApi::new(client))) + )? + .with_import_queue(|_config, client, mut select_chain, transaction_pool| { + let select_chain = select_chain.take() + .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; + let (block_import, link_half) = + grandpa::block_import::<_, _, _, node_template_runtime::RuntimeApi, _, _>( + client.clone(), client.clone(), select_chain + )?; + let justification_import = block_import.clone(); + + let (import_queue, babe_link, babe_block_import, pruning_task) = babe::import_queue( + babe::Config::get_or_compute(&*client)?, + block_import, + Some(Box::new(justification_import)), + None, + client.clone(), + client, + inherent_data_providers.clone(), + Some(transaction_pool) + )?; + + import_setup = Some((babe_block_import.clone(), link_half, babe_link)); + tasks_to_spawn = Some(vec![Box::new(pruning_task)]); + + Ok(import_queue) + })?; + + (builder, import_setup, inherent_data_providers, tasks_to_spawn) + }} +} + +/// Builds a new service for a full client. +pub fn new_full(config: Configuration) + -> Result +{ + + let (builder, mut import_setup, inherent_data_providers, mut tasks_to_spawn) = new_full_start!(config); + + let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))? + .with_finality_proof_provider(|client| + Ok(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _) + )? + .build()?; + + let (block_import, link_half, babe_link) = + import_setup.take() + .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); + + // spawn any futures that were created in the previous setup steps + if let Some(tasks) = tasks_to_spawn.take() { + for task in tasks { + service.spawn_task( + task.select(service.on_exit()) + .map(|_| ()) + .map_err(|_| ()) + ); + } + } + + if service.config().roles.is_authority() { + let proposer = basic_authorship::ProposerFactory { + client: service.client(), + transaction_pool: service.transaction_pool(), + }; + + let client = service.client(); + let select_chain = service.select_chain() + .ok_or(ServiceError::SelectChainRequired)?; + + let babe_config = babe::BabeParams { + config: Config::get_or_compute(&*client)?, + keystore: service.keystore(), + client, + select_chain, + block_import, + env: proposer, + sync_oracle: service.network(), + inherent_data_providers: inherent_data_providers.clone(), + force_authoring: service.config().force_authoring, + time_source: babe_link, + }; + + let babe = start_babe(babe_config)?; + let select = babe.select(service.on_exit()).then(|_| Ok(())); + + // the BABE authoring task is considered infallible, i.e. if it + // fails we take down the service with it. + service.spawn_essential_task(select); + } + + let config = grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: Duration::from_millis(333), + justification_period: 4096, + name: Some(service.config().name.clone()), + keystore: Some(service.keystore()), + }; + + match (service.config().roles.is_authority(), service.config().disable_grandpa) { + (false, false) => { + // start the lightweight GRANDPA observer + service.spawn_task(Box::new(grandpa::run_grandpa_observer( + config, + link_half, + service.network(), + service.on_exit(), + )?)); + }, + (true, false) => { + // start the full GRANDPA voter + let grandpa_config = grandpa::GrandpaParams { + config: config, + link: link_half, + network: service.network(), + inherent_data_providers: inherent_data_providers.clone(), + on_exit: service.on_exit(), + telemetry_on_connect: Some(service.telemetry_on_connect_stream()), + }; + + // 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(), + )?; + }, + } + + Ok(service) +} + +/// Builds a new service for a light client. +pub fn new_light(config: Configuration) + -> Result +{ + let inherent_data_providers = InherentDataProviders::new(); + + ServiceBuilder::new_light::(config)? + .with_select_chain(|_config, client| { + #[allow(deprecated)] + Ok(LongestChain::new(client.backend().clone())) + })? + .with_transaction_pool(|config, client| + Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) + )? + .with_import_queue_and_fprb(|_config, client, _select_chain, transaction_pool| { + #[allow(deprecated)] + let fetch_checker = client.backend().blockchain().fetcher() + .upgrade() + .map(|fetcher| fetcher.checker().clone()) + .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; + let block_import = grandpa::light_block_import::<_, _, _, RuntimeApi, _>( + client.clone(), Arc::new(fetch_checker), client.clone() + )?; + + let finality_proof_import = block_import.clone(); + let finality_proof_request_builder = + finality_proof_import.create_finality_proof_request_builder(); + + // FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`. + let (import_queue, ..) = import_queue( + Config::get_or_compute(&*client)?, + block_import, + None, + Some(Box::new(finality_proof_import)), + client.clone(), + client, + inherent_data_providers.clone(), + Some(transaction_pool) + )?; + + Ok((import_queue, finality_proof_request_builder)) + })? + .with_network_protocol(|_| Ok(NodeProtocol::new()))? + .with_finality_proof_provider(|client| + Ok(Arc::new(GrandpaFinalityProofProvider::new(client.clone(), client)) as _) + )? + .build() +}