diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 140b21dbda..0e3641737f 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -144,13 +144,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "clap" -version = "2.29.2" +version = "2.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -243,12 +243,12 @@ dependencies = [ [[package]] name = "eth-secp256k1" version = "0.5.7" -source = "git+https://github.com/paritytech/rust-secp256k1#6370d63adf4e8c91e2eae9225eef4b4e0294c5d0" +source = "git+https://github.com/paritytech/rust-secp256k1#c1fc9daedee67e1b4028ad1b3669275ed49c22cf" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -258,7 +258,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -271,14 +271,14 @@ dependencies = [ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ethcore-bytes" version = "0.1.0" -source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +source = "git+https://github.com/paritytech/parity.git#0a7cebe316c4dea69cd619908246ae13816adfc8" [[package]] name = "ethcore-bytes" @@ -288,11 +288,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ethcore-io" version = "1.9.0" -source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +source = "git+https://github.com/paritytech/parity.git#0a7cebe316c4dea69cd619908246ae13816adfc8" dependencies = [ "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -300,7 +300,7 @@ dependencies = [ [[package]] name = "ethcore-logger" version = "1.9.0" -source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +source = "git+https://github.com/paritytech/parity.git#0a7cebe316c4dea69cd619908246ae13816adfc8" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -332,7 +332,7 @@ dependencies = [ [[package]] name = "ethcore-network" version = "1.9.0" -source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +source = "git+https://github.com/paritytech/parity.git#0a7cebe316c4dea69cd619908246ae13816adfc8" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -348,10 +348,10 @@ dependencies = [ "keccak-hash 0.1.0 (git+https://github.com/paritytech/parity.git)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "path 0.1.0 (git+https://github.com/paritytech/parity.git)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.1 (git+https://github.com/paritytech/parity.git)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -367,7 +367,7 @@ dependencies = [ [[package]] name = "ethcrypto" version = "0.1.0" -source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +source = "git+https://github.com/paritytech/parity.git#0a7cebe316c4dea69cd619908246ae13816adfc8" dependencies = [ "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", "ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -384,15 +384,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "ethbloom 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ethkey" version = "0.3.0" -source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +source = "git+https://github.com/paritytech/parity.git#0a7cebe316c4dea69cd619908246ae13816adfc8" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "edit-distance 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -401,7 +401,7 @@ dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -409,11 +409,9 @@ dependencies = [ [[package]] name = "fixed-hash" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.1.3" +source = "git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm#8dc457899afdaf968ff7f16140b03d1e37b01d71" dependencies = [ - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -421,8 +419,10 @@ dependencies = [ [[package]] name = "fixed-hash" version = "0.1.3" -source = "git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm#853bb53158497914f1837f5186e31e5b29f77cee" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -539,7 +539,7 @@ dependencies = [ [[package]] name = "hyper" -version = "0.11.16" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -577,7 +577,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "xmltree 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -638,7 +638,7 @@ name = "jsonrpc-http-server" version = "8.0.0" source = "git+https://github.com/paritytech/jsonrpc.git#d1e2cc48d962510328f7373509fb494a85dbeae8" dependencies = [ - "hyper 0.11.16 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.17 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git)", "jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -682,7 +682,7 @@ dependencies = [ [[package]] name = "keccak-hash" version = "0.1.0" -source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +source = "git+https://github.com/paritytech/parity.git#0a7cebe316c4dea69cd619908246ae13816adfc8" dependencies = [ "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -794,7 +794,7 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.12" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -892,7 +892,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -919,7 +919,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -927,7 +927,7 @@ dependencies = [ [[package]] name = "path" version = "0.1.0" -source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +source = "git+https://github.com/paritytech/parity.git#0a7cebe316c4dea69cd619908246ae13816adfc8" [[package]] name = "patricia-trie" @@ -942,7 +942,7 @@ dependencies = [ "keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -982,7 +982,7 @@ dependencies = [ name = "polkadot-cli" version = "0.1.0" dependencies = [ - "clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.29.4 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -997,11 +997,15 @@ name = "polkadot-client" version = "0.1.0" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "native-runtime 0.1.0", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "polkadot-executor 0.1.0", "polkadot-primitives 0.1.0", "polkadot-serializer 0.1.0", "polkadot-state-machine 0.1.0", + "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1020,6 +1024,8 @@ dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "ed25519 0.1.0", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "native-runtime 0.1.0", "parity-wasm 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", @@ -1050,7 +1056,7 @@ dependencies = [ "polkadot-primitives 0.1.0", "polkadot-serializer 0.1.0", "polkadot-state-machine 0.1.0", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1190,11 +1196,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rand" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1224,7 +1231,7 @@ dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1280,7 +1287,7 @@ dependencies = [ [[package]] name = "rlp" version = "0.2.1" -source = "git+https://github.com/paritytech/parity.git#4763887a68d78f12f0f8e39d353e9d852ab95c7a" +source = "git+https://github.com/paritytech/parity.git#0a7cebe316c4dea69cd619908246ae13816adfc8" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1308,7 +1315,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1462,7 +1469,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "strsim" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1547,7 +1554,7 @@ dependencies = [ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1571,7 +1578,7 @@ dependencies = [ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1617,7 +1624,7 @@ name = "twox-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1627,11 +1634,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "uint" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.1.2" +source = "git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm#8dc457899afdaf968ff7f16140b03d1e37b01d71" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1639,9 +1645,10 @@ dependencies = [ [[package]] name = "uint" version = "0.1.2" -source = "git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm#853bb53158497914f1837f5186e31e5b29f77cee" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1807,7 +1814,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" "checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4151c5790817c7d21bbdc6c3530811f798172915f93258244948b93ba19604a6" +"checksum clap 2.29.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7b8f59bcebcfe4269b09f71dab0da15b355c75916a8f975d3876ce81561893ee" "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" @@ -1831,8 +1838,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ethcrypto 0.1.0 (git+https://github.com/paritytech/parity.git)" = "" "checksum ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2adaa5b8ceafcce0bc3a68ef116ca5702958cc97d70a6eb008aeddb569b092b3" "checksum ethkey 0.3.0 (git+https://github.com/paritytech/parity.git)" = "" -"checksum fixed-hash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4b54d107faeb66084eca7c506aa50b6b7cb9eb9a1f1f633ae2ca3af55620c191" "checksum fixed-hash 0.1.3 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)" = "" +"checksum fixed-hash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21c520ebc46522d519aec9cba2b7115d49cea707d771b772c46bec61aa0daeb8" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "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" @@ -1846,7 +1853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2ea76da4c7f1a54d01d54985566d3fdd960b2bbd7b970da024821c883c2d9631" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" "checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" -"checksum hyper 0.11.16 (registry+https://github.com/rust-lang/crates.io-index)" = "6a82c41828dd6f271f4d6ebc3f1db78239a4b2b3d355dfdb5f8bbf55f004463a" +"checksum hyper 0.11.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4de6edd503089841ebfa88341e1c00fb19b6bf93d820d908db15960fd31226" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum igd 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "356a0dc23a4fa0f8ce4777258085d00a01ea4923b2efd93538fc44bf5e1bda76" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" @@ -1874,7 +1881,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "013b7e4c5e10c764936ebc6bd3662d8e3c92292d267bf6a42ef3f5cad9c793ee" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" -"checksum mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "75f72a93f046f1517e3cfddc0a096eb756a2ba727d36edc8227dee769a50a9b0" +"checksum mio 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7da01a5e23070d92d99b1ecd1cd0af36447c6fd44b0fe283c2db199fa136724f" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" @@ -1895,7 +1902,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0" "checksum proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5cb6f960ad471404618e9817c0e5d10b1ae74cfdf01fab89ea0641fe7fb2892" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" +"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" "checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53" @@ -1931,7 +1938,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "" "checksum snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "" "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" -"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" +"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum subtle 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b811576c12506ff3f6da145585dc833edc32ee34c9fc021127d90e8134cc05c" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" @@ -1950,8 +1957,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9291c7f0fae44858b5e087dd462afb382354120003778f1695b44aab98c7abd7" "checksum twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "475352206e7a290c5fccc27624a163e8d0d115f7bb60ca18a64fc9ce056d7435" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -"checksum uint 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91ed1e25ded4e37e0967b1f12d5f910b32f979768d4f48e2f6ca7b6e7130b44e" "checksum uint 0.1.2 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)" = "" +"checksum uint 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53a4340c35703f926ec365c6797bb4a7a10bb6b9affe29ca385c9d804401f5e3" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" diff --git a/substrate/client/Cargo.toml b/substrate/client/Cargo.toml index 8b5f728a2b..06bfaf97b3 100644 --- a/substrate/client/Cargo.toml +++ b/substrate/client/Cargo.toml @@ -9,4 +9,8 @@ log = "0.3" parking_lot = "0.4" polkadot-primitives = { path = "../primitives", version = "0.1" } polkadot-state-machine = { path = "../state-machine", version = "0.1" } -polkadot-serializer = { path = "../serializer", version = "0.1" } +polkadot-serializer = { path = "../serializer" } +polkadot-executor = { path = "../executor" } +native-runtime = { path = "../native-runtime" } +triehash = "0.1" +hex-literal = "0.1" diff --git a/substrate/client/src/genesis.rs b/substrate/client/src/genesis.rs new file mode 100644 index 0000000000..6e560a91d1 --- /dev/null +++ b/substrate/client/src/genesis.rs @@ -0,0 +1,143 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tool for creating the genesis block. + +use std::collections::HashMap; +use primitives::block::{Block, Header}; +use primitives::H256; +use triehash::trie_root; + +/// Create a genesis block, given the initial storage. +pub fn construct_genesis_block(storage: &HashMap, Vec>) -> Block { + let state_root = H256(trie_root(storage.clone().into_iter()).0); + let header = Header { + parent_hash: Default::default(), + number: 0, + state_root, + transaction_root: H256(trie_root(vec![].into_iter()).0), + digest: Default::default(), + }; + Block { + header, + transactions: vec![], + } +} + +#[cfg(test)] +mod tests { + use super::*; + use native_runtime::codec::{Slicable, Joiner}; + use native_runtime::support::{one, two, Hashable}; + use native_runtime::runtime::genesismap::{GenesisConfig, additional_storage_with_genesis}; + use native_runtime::primitives::{AccountID, Hash, BlockNumber, Transaction, + UncheckedTransaction, Digest, Function}; + use state_machine::execute; + use state_machine::OverlayedChanges; + use state_machine::backend::InMemory; + use polkadot_executor::executor; + use primitives::contract::CallData; + use primitives::ed25519::Pair; + + fn secret_for(who: &AccountID) -> Option { + match who { + x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")), + x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()), + _ => None, + } + } + + fn construct_block(backend: &InMemory, number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec) -> (Vec, Hash) { + use triehash::ordered_trie_root; + + let transactions = txs.into_iter().map(|transaction| { + let signature = secret_for(&transaction.signed).unwrap() + .sign(&transaction.to_vec()) + .inner(); + UncheckedTransaction { transaction, signature } + }).collect::>(); + + let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0; + + let mut header = Header { + parent_hash, + number, + state_root, + transaction_root, + digest: Digest { logs: vec![], }, + }; + let hash = header.blake2_256(); + + let mut overlay = OverlayedChanges::default(); + + for tx in transactions.iter() { + header = Header::from_slice(&execute( + backend, + &mut overlay, + &executor(), + "execute_transaction", + &CallData(vec![].join(&header).join(tx)) + ).unwrap()).unwrap(); + } + + header = Header::from_slice(&execute( + backend, + &mut overlay, + &executor(), + "finalise_block", + &CallData(vec![].join(&header)) + ).unwrap()).unwrap(); + + (vec![].join(&Block { header, transactions }), hash) + } + + fn block1(genesis_hash: Hash, backend: &InMemory) -> (Vec, Hash) { + construct_block( + backend, + 1, + genesis_hash, + hex!("25e5b37074063ab75c889326246640729b40d0c86932edc527bc80db0e04fe5c"), + vec![Transaction { + signed: one(), + nonce: 0, + function: Function::StakingTransfer, + input_data: vec![].join(&two()).join(&69u64), + }] + ) + } + + #[test] + fn construct_genesis_should_work() { + let mut storage = GenesisConfig::new_simple( + vec![one(), two()], 1000 + ).genesis_map(); + let block = construct_genesis_block(&storage); + let genesis_hash = block.header.blake2_256(); + storage.extend(additional_storage_with_genesis(&block).into_iter()); + + let mut overlay = OverlayedChanges::default(); + let backend = InMemory::from(storage); + let (b1data, _b1hash) = block1(genesis_hash, &backend); + + let _ = execute( + &backend, + &mut overlay, + &executor(), + "execute_block", + &CallData(b1data) + ).unwrap(); + } +} diff --git a/substrate/client/src/lib.rs b/substrate/client/src/lib.rs index 5ce710c886..6eff92226f 100644 --- a/substrate/client/src/lib.rs +++ b/substrate/client/src/lib.rs @@ -21,16 +21,27 @@ extern crate polkadot_primitives as primitives; extern crate polkadot_state_machine as state_machine; extern crate polkadot_serializer as ser; +extern crate polkadot_executor; +extern crate native_runtime; +extern crate triehash; extern crate parking_lot; #[macro_use] extern crate error_chain; #[macro_use] extern crate log; +#[cfg(test)] +#[macro_use] +extern crate hex_literal; + pub mod error; pub mod blockchain; pub mod backend; pub mod in_mem; +mod genesis; + +pub use genesis::construct_genesis_block; + pub use blockchain::Info as ChainInfo; pub use blockchain::BlockId; diff --git a/substrate/executor/Cargo.toml b/substrate/executor/Cargo.toml index da5854e854..eb6e46e6e2 100644 --- a/substrate/executor/Cargo.toml +++ b/substrate/executor/Cargo.toml @@ -18,6 +18,8 @@ rustc-hex = "1.0.0" native-runtime = { path = "../native-runtime", version = "0.1" } triehash = "0.1.0" ed25519 = { path = "../ed25519", version = "0.1" } +hex-literal = "0.1.0" +log = "0.3" [dev-dependencies] assert_matches = "1.1" diff --git a/substrate/executor/src/lib.rs b/substrate/executor/src/lib.rs index 7f63fd64f9..27d26f7adb 100644 --- a/substrate/executor/src/lib.rs +++ b/substrate/executor/src/lib.rs @@ -40,6 +40,11 @@ extern crate byteorder; extern crate rustc_hex; extern crate native_runtime; extern crate triehash; +#[macro_use] extern crate log; + +#[cfg(test)] +#[macro_use] +extern crate hex_literal; #[macro_use] extern crate error_chain; diff --git a/substrate/executor/src/native_executor.rs b/substrate/executor/src/native_executor.rs index 3f1600554a..3b86627437 100644 --- a/substrate/executor/src/native_executor.rs +++ b/substrate/executor/src/native_executor.rs @@ -29,6 +29,7 @@ impl CodeExecutor for NativeExecutor { runtime_std::with_externalities(ext, || match method { "execute_block" => safe_call(|| runtime::execute_block(&data.0)), "execute_transaction" => safe_call(|| runtime::execute_transaction(&data.0)), + "finalise_block" => safe_call(|| runtime::finalise_block(&data.0)), _ => Err(ErrorKind::MethodNotFound(method.to_owned()).into()), }) } else { @@ -41,15 +42,28 @@ impl CodeExecutor for NativeExecutor { #[cfg(test)] mod tests { use super::*; - use codec::KeyedVec; - use native_runtime::support::{one, two, StaticHexInto}; + use codec::{KeyedVec, Slicable}; + use native_runtime::support::{one, two, Hashable}; + use runtime_std::TestExternalities; + use native_runtime::support::{one, two, Hashable}; use native_runtime::runtime::staking::balance; use state_machine::TestExternalities; use primitives::twox_128; const BLOATY_CODE: &[u8] = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm"); const COMPACT_CODE: &[u8] = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm"); - fn tx() -> Vec { "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee000000000000000002d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000b543b41e4b7a0270eddf57ed6c435df04bb63f71c79f6ae2530ab26c734bb4e8cd57b1c190c41d5791bcdea66a16c7339b1e883e5d0538ea2d9acea800d60a00".convert() } + + fn tx() -> UncheckedTransaction { + let transaction = Transaction { + signed: one(), + nonce: 0, + function: Function::StakingTransfer(two(), 69), + }; + let signature = secret_for(&transaction.signed).unwrap() + .sign(&transaction.to_vec()) + .inner(); + UncheckedTransaction { transaction, signature } + } #[test] fn panic_execution_with_foreign_code_gives_error() { @@ -58,7 +72,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = NativeExecutor.call(&mut t, BLOATY_CODE, "execute_transaction", &CallData(tx())); + let r = NativeExecutor.call(&mut t, BLOATY_CODE, "execute_transaction", &CallData(vec![].join(&Header::from_block_number(1u64)).join(&tx()))); assert!(r.is_err()); } @@ -69,7 +83,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = NativeExecutor.call(&mut t, COMPACT_CODE, "execute_transaction", &CallData(tx())); + let r = NativeExecutor.call(&mut t, COMPACT_CODE, "execute_transaction", &CallData(vec![].join(&Header::from_block_number(1u64)).join(&tx()))); assert!(r.is_err()); } @@ -82,7 +96,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = NativeExecutor.call(&mut t, COMPACT_CODE, "execute_transaction", &CallData(tx())); + let r = NativeExecutor.call(&mut t, COMPACT_CODE, "execute_transaction", &CallData(vec![].join(&Header::from_block_number(1u64)).join(&tx()))); assert!(r.is_ok()); runtime_std::with_externalities(&mut t, || { @@ -100,7 +114,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = NativeExecutor.call(&mut t, BLOATY_CODE, "execute_transaction", &CallData(tx())); + let r = NativeExecutor.call(&mut t, BLOATY_CODE, "execute_transaction", &CallData(vec![].join(&Header::from_block_number(1u64)).join(&tx()))); assert!(r.is_ok()); runtime_std::with_externalities(&mut t, || { @@ -108,4 +122,143 @@ mod tests { assert_eq!(balance(&two), 69); }); } + + fn new_test_ext() -> TestExternalities { + let one = one(); + let two = two(); + let three = [3u8; 32]; + + TestExternalities { storage: map![ + twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].to_vec(), + twox_128(b"gov:apr").to_vec() => vec![].join(&667u32), + twox_128(b"ses:len").to_vec() => vec![].join(&2u64), + twox_128(b"ses:val:len").to_vec() => vec![].join(&3u32), + twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => one.to_vec(), + twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => two.to_vec(), + twox_128(&2u32.to_keyed_vec(b"ses:val:")).to_vec() => three.to_vec(), + twox_128(b"sta:wil:len").to_vec() => vec![].join(&3u32), + twox_128(&0u32.to_keyed_vec(b"sta:wil:")).to_vec() => one.to_vec(), + twox_128(&1u32.to_keyed_vec(b"sta:wil:")).to_vec() => two.to_vec(), + twox_128(&2u32.to_keyed_vec(b"sta:wil:")).to_vec() => three.to_vec(), + twox_128(b"sta:spe").to_vec() => vec![].join(&2u64), + twox_128(b"sta:vac").to_vec() => vec![].join(&3u64), + twox_128(b"sta:era").to_vec() => vec![].join(&0u64), + twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + ], } + } + + use primitives::ed25519::Pair; + fn secret_for(who: &AccountID) -> Option { + match who { + x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")), + x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()), + _ => None, + } + } + + fn construct_block(number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec) -> (Vec, Hash) { + use triehash::ordered_trie_root; + + let transactions = txs.into_iter().map(|transaction| { + let signature = secret_for(&transaction.signed).unwrap() + .sign(&transaction.to_vec()) + .inner(); + UncheckedTransaction { transaction, signature } + }).collect::>(); + + let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0; + + let header = Header { + parent_hash, + number, + state_root, + transaction_root, + digest: Digest { logs: vec![], }, + }; + let hash = header.blake2_256(); + + (Block { header, transactions }.to_vec(), hash) + } + + fn block1() -> (Vec, Hash) { + construct_block( + 1, + [69u8; 32], + hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db"), + vec![Transaction { + signed: one(), + nonce: 0, + function: Function::StakingTransfer, + input_data: vec![].join(&two()).join(&69u64), + }] + ) + } + + fn block2() -> (Vec, Hash) { + construct_block( + 2, + block1().1, + hex!("2e69e4405a13981224078ad5355c68401bf56d0fe3f14a3536734666e6a8a047"), + vec![ + Transaction { + signed: two(), + nonce: 0, + function: Function::StakingTransfer, + input_data: vec![].join(&one()).join(&5u64), + }, + Transaction { + signed: one(), + nonce: 1, + function: Function::StakingTransfer, + input_data: vec![].join(&two()).join(&15u64), + } + ] + ) + } + + #[test] + fn test_execution_works() { + let mut t = new_test_ext(); + println!("Testing Wasm..."); + let r = WasmExecutor.call(&mut t, COMPACT_CODE, "run_tests", &CallData(block2().0)); + assert!(r.is_ok()); + } + + #[test] + fn full_native_block_import_works() { + let mut t = new_test_ext(); + + NativeExecutor.call(&mut t, COMPACT_CODE, "execute_block", &CallData(block1().0)).unwrap(); + + runtime_std::with_externalities(&mut t, || { + assert_eq!(balance(&one()), 42); + assert_eq!(balance(&two()), 69); + }); + + NativeExecutor.call(&mut t, COMPACT_CODE, "execute_block", &CallData(block2().0)).unwrap(); + + runtime_std::with_externalities(&mut t, || { + assert_eq!(balance(&one()), 32); + assert_eq!(balance(&two()), 79); + }); + } + + #[test] + fn full_wasm_block_import_works() { + let mut t = new_test_ext(); + + WasmExecutor.call(&mut t, COMPACT_CODE, "execute_block", &CallData(block1().0)).unwrap(); + + runtime_std::with_externalities(&mut t, || { + assert_eq!(balance(&one()), 42); + assert_eq!(balance(&two()), 69); + }); + + WasmExecutor.call(&mut t, COMPACT_CODE, "execute_block", &CallData(block2().0)).unwrap(); + + runtime_std::with_externalities(&mut t, || { + assert_eq!(balance(&one()), 32); + assert_eq!(balance(&two()), 79); + }); + } } diff --git a/substrate/executor/src/wasm_executor.rs b/substrate/executor/src/wasm_executor.rs index c7f9073aab..68353e99b8 100644 --- a/substrate/executor/src/wasm_executor.rs +++ b/substrate/executor/src/wasm_executor.rs @@ -38,7 +38,7 @@ struct Heap { impl Heap { fn new() -> Self { Heap { - end: 1024, + end: 32768, } } fn allocate(&mut self, size: u32) -> u32 { @@ -94,17 +94,17 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, ext_print_utf8(utf8_data: *const u8, utf8_len: u32) => { if let Ok(utf8) = this.memory.get(utf8_data, utf8_len as usize) { if let Ok(message) = String::from_utf8(utf8) { - println!("Runtime: {}", message); + info!(target: "runtime", "{}", message); } } }, ext_print_hex(data: *const u8, len: u32) => { if let Ok(hex) = this.memory.get(data, len as usize) { - println!("Runtime: {}", HexDisplay::from(&hex)); + info!(target: "runtime", "{}", HexDisplay::from(&hex)); } }, ext_print_num(number: u64) => { - println!("Runtime: {}", number); + info!(target: "runtime", "{}", number); }, ext_memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 => { let sl1 = this.memory.get(s1, n as usize).map_err(|_| DummyUserError)?; @@ -118,34 +118,35 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, ext_memcpy(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 => { this.memory.copy_nonoverlapping(src as usize, dest as usize, count as usize) .map_err(|_| DummyUserError)?; - println!("memcpy {} from {}, {} bytes", dest, src, count); + trace!(target: "runtime-std", "memcpy {} from {}, {} bytes", dest, src, count); dest }, ext_memmove(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 => { this.memory.copy(src as usize, dest as usize, count as usize) .map_err(|_| DummyUserError)?; - println!("memmove {} from {}, {} bytes", dest, src, count); + trace!(target: "runtime-std", "memmove {} from {}, {} bytes", dest, src, count); dest }, ext_memset(dest: *mut u8, val: u32, count: usize) -> *mut u8 => { this.memory.clear(dest as usize, val as u8, count as usize) .map_err(|_| DummyUserError)?; - println!("memset {} with {}, {} bytes", dest, val, count); + trace!(target: "runtime-std", "memset {} with {}, {} bytes", dest, val, count); dest }, ext_malloc(size: usize) -> *mut u8 => { let r = this.heap.allocate(size); - println!("malloc {} bytes at {}", size, r); + trace!(target: "runtime-std", "malloc {} bytes at {}", size, r); r }, ext_free(addr: *mut u8) => { this.heap.deallocate(addr); - println!("free {}", addr) + trace!(target: "runtime-std", "free {}", addr) }, ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32) => { - if let (Ok(key), Ok(value)) = (this.memory.get(key_data, key_len as usize), this.memory.get(value_data, value_len as usize)) { - this.ext.set_storage(key, value); - } + let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; + let value = this.memory.get(value_data, value_len as usize).map_err(|_| DummyUserError)?; + info!(target: "runtime", "Setting storage: {} -> {}", HexDisplay::from(&key), HexDisplay::from(&value)); + this.ext.set_storage(key, value); }, ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8 => { let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; @@ -160,6 +161,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32 => { let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; let value = this.ext.storage(&key).map_err(|_| DummyUserError)?; + info!(target: "runtime", "Getting storage: {} ( -> {})", HexDisplay::from(&key), HexDisplay::from(&value)); let value = &value[value_offset as usize..]; let written = ::std::cmp::min(value_len as usize, value.len()); this.memory.set(value_data, &value[..written]).map_err(|_| DummyUserError)?; @@ -169,7 +171,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, let r = this.ext.storage_root(); this.memory.set(result, &r[..]).map_err(|_| DummyUserError)?; }, - ext_enumerated_trie_root(values_data: *const u8, _values_len: u32, lens_data: *const u32, lens_len: u32, result: *mut u8) => { + ext_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8) => { let values = (0..lens_len) .map(|i| this.memory.read_primitive(lens_data + i * 4)) .collect::<::std::result::Result, DummyUserError>>()? @@ -188,9 +190,17 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, }, ext_twox_128(data: *const u8, len: u32, out: *mut u8) => { let result = if len == 0 { + info!(target: "runtime", "XXhash: ''"); twox_128(&[0u8; 0]) } else { - twox_128(&this.memory.get(data, len as usize).map_err(|_| DummyUserError)?) + let key = this.memory.get(data, len as usize).map_err(|_| DummyUserError)?; + let hashed_key = twox_128(&key); + if let Ok(skey) = ::std::str::from_utf8(&key) { + info!(target: "runtime", "XXhash: {} -> {}", skey, HexDisplay::from(&hashed_key)); + } else { + info!(target: "runtime", "XXhash: {} -> {}", HexDisplay::from(&key), HexDisplay::from(&hashed_key)); + } + hashed_key }; this.memory.set(out, &result).map_err(|_| DummyUserError)?; }, @@ -280,14 +290,38 @@ mod tests { use super::*; use rustc_hex::FromHex; - use primitives::{blake2_256, twox_128}; - use runtime_std; + use primitives::{AccountId, blake2_256, twox_128}; + use primitives::block::Header; + use primitives::transaction::{Transaction, UncheckedTransaction}; use codec::KeyedVec; use state_machine::TestExternalities; - use native_runtime::support::{one, two, StaticHexInto}; + use runtime_std; + use native_runtime::support::{one, two}; use native_runtime::runtime::staking::balance; + use ed25519::Pair; - fn tx() -> Vec { "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee000000000000000002d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000b543b41e4b7a0270eddf57ed6c435df04bb63f71c79f6ae2530ab26c734bb4e8cd57b1c190c41d5791bcdea66a16c7339b1e883e5d0538ea2d9acea800d60a00".convert() } + fn secret_for(who: &AccountId) -> Option { + match who { + x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")), + x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()), + _ => None, + } + } + + fn tx() -> UncheckedTransaction { + use native_runtime::codec::Slicable; + + let transaction = Transaction { + signed: one(), + nonce: 0, + function: Function::StakingTransfer(two(), 69), + }; + let signature = secret_for(&transaction.signed).unwrap() + .sign(&transaction.to_vec()) + .inner(); + + UncheckedTransaction { transaction, signature } + } #[test] fn returning_should_work() { @@ -403,7 +437,7 @@ mod tests { ], }; let foreign_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm"); - let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(tx())); + let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(vec![].join(&Header::from_block_number(1u64)).join(&tx()))); assert!(r.is_err()); } @@ -417,7 +451,7 @@ mod tests { ], }; let foreign_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm"); - let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(tx())); + let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(vec![].join(&Header::from_block_number(1u64)).join(&tx()))); assert!(r.is_ok()); runtime_std::with_externalities(&mut t, || { diff --git a/substrate/network/src/service.rs b/substrate/network/src/service.rs index 11b4cae18e..e3832249db 100644 --- a/substrate/network/src/service.rs +++ b/substrate/network/src/service.rs @@ -148,7 +148,7 @@ impl SyncProvider for Service { }; Some(PeerInfo { - id: session_info.id.map(|id| id.hex()), + id: session_info.id.map(|id| format!("{:x}", id)), client_version: session_info.client_version, capabilities: session_info.peer_capabilities.into_iter().map(|c| c.to_string()).collect(), remote_address: session_info.remote_address, diff --git a/substrate/runtime-std/without_std.rs b/substrate/runtime-std/without_std.rs index efe6249812..f599f6c3d2 100644 --- a/substrate/runtime-std/without_std.rs +++ b/substrate/runtime-std/without_std.rs @@ -36,7 +36,7 @@ extern "C" { fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32; fn ext_storage_root(result: *mut u8); - fn ext_enumerated_trie_root(values_data: *const u8, values_len: u32, lens_data: *const u32, lens_len: u32, result: *mut u8); + fn ext_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8); fn ext_chain_id() -> u64; fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8); fn ext_twox_128(data: *const u8, len: u32, out: *mut u8); @@ -87,7 +87,7 @@ pub fn enumerated_trie_root(values: &[&[u8]]) -> [u8; 32] { let mut result: [u8; 32] = Default::default(); unsafe { ext_enumerated_trie_root( - values.as_ptr(), values.len() as u32, + values.as_ptr(), lens.as_ptr(), lens.len() as u32, result.as_mut_ptr() ); diff --git a/substrate/state-machine/src/backend.rs b/substrate/state-machine/src/backend.rs index 5057339ce9..2ad10e44d3 100644 --- a/substrate/state-machine/src/backend.rs +++ b/substrate/state-machine/src/backend.rs @@ -17,16 +17,11 @@ //! State machine backends. These manage the code and storage of contracts. use std::{error, fmt}; -use primitives::hash::H256; -use triehash::sec_trie_root; use super::{Update, MemoryState}; /// Output of a commit. -pub struct Committed { - /// Root of the storage tree after changes committed. - pub storage_tree_root: H256, -} +pub struct Committed {} /// A state backend is used to read state data and can have changes committed /// to it. @@ -67,7 +62,6 @@ pub struct InMemory { inner: MemoryState, // keeps all the state in memory. } -#[cfg(test)] impl InMemory { /// Create a new instance from a given storage map. pub fn from(storage: ::std::collections::HashMap, Vec>) -> Self { @@ -90,17 +84,7 @@ impl Backend for InMemory { where I: IntoIterator { self.inner.update(changes); - - // fully recalculate trie roots. - let storage_tree_root = H256(sec_trie_root( - self.inner.storage.iter() - .map(|(k, v)| (k.to_vec(), v.clone())) - .collect() - ).0); - - Committed { - storage_tree_root, - } + Committed {} } fn pairs(&self) -> Vec<(&[u8], &[u8])> { diff --git a/substrate/state-machine/src/lib.rs b/substrate/state-machine/src/lib.rs index f0c1d17b8b..386c5da20a 100644 --- a/substrate/state-machine/src/lib.rs +++ b/substrate/state-machine/src/lib.rs @@ -34,13 +34,14 @@ extern crate byteorder; use std::collections::HashMap; use std::fmt; -use primitives::contract::{CallData}; +use primitives::contract::CallData; pub mod backend; mod ext; mod testing; pub use testing::TestExternalities; +pub use ext::Ext; /// Updates to be committed to the state. pub enum Update { @@ -152,12 +153,17 @@ pub trait Externalities { /// Get the current set of authorities from storage. fn authorities(&self) -> Result, ExternalitiesError> { - (0..self.storage(b"con:aut:len")?.into_iter() + (0..self.storage(b":auth:len")?.into_iter() .rev() .fold(0, |acc, &i| (acc << 8) + (i as u32))) - .map(|i| self.storage(&to_keyed_vec(i, b"con:aut:".to_vec()))) + .map(|i| self.storage(&to_keyed_vec(i, b":auth:".to_vec()))) .collect() } + + /// Get the runtime code. + fn code(&self) -> Result<&[u8], ExternalitiesError> { + self.storage(b":code") + } } /// Code execution engine. @@ -254,17 +260,17 @@ mod tests { assert_eq!(ext.authorities(), Ok(vec![])); - ext.set_storage(b"con:aut:len".to_vec(), vec![0u8; 4]); + ext.set_storage(b":auth:len".to_vec(), vec![0u8; 4]); assert_eq!(ext.authorities(), Ok(vec![])); - ext.set_storage(b"con:aut:len".to_vec(), vec![1u8, 0, 0, 0]); + ext.set_storage(b":auth:len".to_vec(), vec![1u8, 0, 0, 0]); assert_eq!(ext.authorities(), Ok(vec![&[][..]])); - ext.set_storage(b"con:aut:\0\0\0\0".to_vec(), b"first".to_vec()); + ext.set_storage(b":auth:\0\0\0\0".to_vec(), b"first".to_vec()); assert_eq!(ext.authorities(), Ok(vec![&b"first"[..]])); - ext.set_storage(b"con:aut:len".to_vec(), vec![2u8, 0, 0, 0]); - ext.set_storage(b"con:aut:\x01\0\0\0".to_vec(), b"second".to_vec()); + ext.set_storage(b":auth:len".to_vec(), vec![2u8, 0, 0, 0]); + ext.set_storage(b":auth:\x01\0\0\0".to_vec(), b"second".to_vec()); assert_eq!(ext.authorities(), Ok(vec![&b"first"[..], &b"second"[..]])); } diff --git a/substrate/wasm-runtime/polkadot/src/lib.rs b/substrate/wasm-runtime/polkadot/src/lib.rs index 8e565179e3..a4c8fb99ae 100644 --- a/substrate/wasm-runtime/polkadot/src/lib.rs +++ b/substrate/wasm-runtime/polkadot/src/lib.rs @@ -38,7 +38,7 @@ pub mod runtime; use runtime_std::prelude::*; use codec::Slicable; use primitives::transaction::UncheckedTransaction; -use primitives::block::Block; +use primitives::block::{Header, Block}; /// Execute a block, with `input` being the canonical serialisation of the block. Returns the /// empty vector. @@ -49,9 +49,29 @@ pub fn execute_block(mut input: &[u8]) -> Vec { /// Execute a given, serialised, transaction. Returns the empty vector. pub fn execute_transaction(mut input: &[u8]) -> Vec { + let header = Header::from_slice(&mut input).unwrap(); let utx = UncheckedTransaction::from_slice(&mut input).unwrap(); - runtime::system::internal::execute_transaction(utx); - Vec::new() + let header = runtime::system::internal::execute_transaction(utx, header); + header.to_vec() } -impl_stubs!(execute_block, execute_transaction); +/// Execute a given, serialised, transaction. Returns the empty vector. +pub fn finalise_block(mut input: &[u8]) -> Vec { + let header = Header::from_slice(&mut input).unwrap(); + let header = runtime::system::internal::finalise_block(header); + header.to_vec() +} + +/// Run whatever tests we have. +pub fn run_tests(mut input: &[u8]) -> Vec { + use runtime_std::print; + + print("run_tests..."); + let block = Block::from_slice(&mut input).unwrap(); + print("deserialised block."); + let stxs = block.transactions.iter().map(Slicable::to_vec).collect::>(); + print("reserialised transactions."); + [stxs.len() as u8].to_vec() +} + +impl_stubs!(execute_block, execute_transaction, finalise_block, run_tests); diff --git a/substrate/wasm-runtime/polkadot/src/runtime/consensus.rs b/substrate/wasm-runtime/polkadot/src/runtime/consensus.rs index 51666666cf..83e59d0684 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/consensus.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/consensus.rs @@ -17,13 +17,13 @@ //! Conensus module for runtime; manages the authority set ready for the native code. use runtime_std::prelude::*; -use support::StorageVec; +use support::storage::unhashed::StorageVec; use primitives::SessionKey; struct AuthorityStorageVec {} impl StorageVec for AuthorityStorageVec { type Item = SessionKey; - const PREFIX: &'static[u8] = b"con:aut:"; + const PREFIX: &'static[u8] = b":auth:"; } /// Get the current set of authorities. These are the session keys. diff --git a/substrate/wasm-runtime/polkadot/src/runtime/genesismap.rs b/substrate/wasm-runtime/polkadot/src/runtime/genesismap.rs new file mode 100644 index 0000000000..a56d03bd04 --- /dev/null +++ b/substrate/wasm-runtime/polkadot/src/runtime/genesismap.rs @@ -0,0 +1,91 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +//! Tool for creating the genesis block. + +use std::collections::HashMap; +use runtime_std::twox_128; +use codec::{KeyedVec, Joiner}; +use support::Hashable; +use primitives::{AccountID, BlockNumber, Block}; +use runtime::staking::Balance; + +/// Configuration of a general Polkadot genesis block. +pub struct GenesisConfig { + pub validators: Vec, + pub authorities: Vec, + pub balances: Vec<(AccountID, Balance)>, + pub block_time: u64, + pub session_length: BlockNumber, + pub sessions_per_era: BlockNumber, + pub bonding_duration: BlockNumber, + pub approval_ratio: u32, +} + +impl GenesisConfig { + pub fn new_simple(authorities_validators: Vec, balance: Balance) -> Self { + GenesisConfig { + validators: authorities_validators.clone(), + authorities: authorities_validators.clone(), + balances: authorities_validators.iter().map(|v| (v.clone(), balance)).collect(), + block_time: 5, // 5 second block time. + session_length: 720, // that's 1 hour per session. + sessions_per_era: 24, // 24 hours per era. + bonding_duration: 90, // 90 days per bond. + approval_ratio: 667, // 66.7% approvals required for legislation. + } + } + + pub fn genesis_map(&self) -> HashMap, Vec> { + let wasm_runtime = include_bytes!("../../../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm").to_vec(); + vec![ + (&b"gov:apr"[..], vec![].join(&self.approval_ratio)), + (&b"ses:len"[..], vec![].join(&self.session_length)), + (&b"ses:val:len"[..], vec![].join(&(self.validators.len() as u32))), + (&b"sta:wil:len"[..], vec![].join(&0u32)), + (&b"sta:spe"[..], vec![].join(&self.sessions_per_era)), + (&b"sta:vac"[..], vec![].join(&(self.validators.len() as u32))), + (&b"sta:era"[..], vec![].join(&0u64)), + ].into_iter() + .map(|(k, v)| (k.into(), v)) + .chain(self.validators.iter() + .enumerate() + .map(|(i, account)| ((i as u32).to_keyed_vec(b"ses:val:"), vec![].join(account))) + ).chain(self.authorities.iter() + .enumerate() + .map(|(i, account)| ((i as u32).to_keyed_vec(b":auth:"), vec![].join(account))) + ).chain(self.balances.iter() + .map(|&(account, balance)| (account.to_keyed_vec(b"sta:bal:"), vec![].join(&balance))) + ) + .map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec())) + .chain(vec![ + (b":code"[..].into(), wasm_runtime), + (b":auth:len"[..].into(), vec![].join(&(self.authorities.len() as u32))), + ].into_iter()) + .chain(self.authorities.iter() + .enumerate() + .map(|(i, account)| ((i as u32).to_keyed_vec(b":auth:"), vec![].join(account))) + ) + .collect() + } +} + +pub fn additional_storage_with_genesis(genesis_block: &Block) -> HashMap, Vec> { + use codec::Slicable; + map![ + twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => genesis_block.header.blake2_256().to_vec() + ] +} diff --git a/substrate/wasm-runtime/polkadot/src/runtime/mod.rs b/substrate/wasm-runtime/polkadot/src/runtime/mod.rs index 9befa9bd42..ad870dba49 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/mod.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/mod.rs @@ -31,3 +31,7 @@ pub mod governance; // TODO: polkadao // TODO: parachains + + +#[cfg(feature = "std")] +pub mod genesismap; diff --git a/substrate/wasm-runtime/polkadot/src/runtime/session.rs b/substrate/wasm-runtime/polkadot/src/runtime/session.rs index b5ed28eb3a..8d55f122ff 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/session.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/session.rs @@ -78,6 +78,11 @@ pub mod privileged { pub fn set_length(new: BlockNumber) { storage::put(NEXT_SESSION_LENGTH, &new); } + + /// Forces a new session. + pub fn force_new_session() { + rotate_session(); + } } // INTERNAL API (available to other runtime modules) @@ -146,9 +151,9 @@ mod tests { twox_128(&0u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![10; 32], twox_128(&1u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![20; 32], // initial session keys (11, 21, ...) - twox_128(b"con:aut:len").to_vec() => vec![].join(&2u32), - twox_128(&0u32.to_keyed_vec(b"con:aut:")).to_vec() => vec![11; 32], - twox_128(&1u32.to_keyed_vec(b"con:aut:")).to_vec() => vec![21; 32] + b":auth:len".to_vec() => vec![].join(&2u32), + 0u32.to_keyed_vec(b":auth:") => vec![11; 32], + 1u32.to_keyed_vec(b":auth:") => vec![21; 32] ], } } diff --git a/substrate/wasm-runtime/polkadot/src/runtime/staking.rs b/substrate/wasm-runtime/polkadot/src/runtime/staking.rs index cedcdcddfd..f503ee7363 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/staking.rs @@ -18,6 +18,7 @@ use runtime_std::prelude::*; use runtime_std::cell::RefCell; +use runtime_std::print; use codec::KeyedVec; use support::{storage, StorageVec}; use primitives::{BlockNumber, AccountId}; @@ -150,6 +151,12 @@ pub mod privileged { pub fn set_validator_count(new: u32) { storage::put(VALIDATOR_COUNT, &new); } + + /// Force there to be a new era. This also forces a new session immediately after. + pub fn force_new_era() { + new_era(); + session::privileged::force_new_session(); + } } pub mod internal { diff --git a/substrate/wasm-runtime/polkadot/src/runtime/system.rs b/substrate/wasm-runtime/polkadot/src/runtime/system.rs index 6bced06c64..262e001154 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/system.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/system.rs @@ -18,15 +18,16 @@ //! and depositing logs. use runtime_std::prelude::*; -use runtime_std::{mem, print, storage_root, enumerated_trie_root}; +use runtime_std::{mem, storage_root, enumerated_trie_root}; use codec::{KeyedVec, Slicable}; use support::{Hashable, storage, with_env}; -use primitives::{AccountId, Hash, TxOrder}; -use primitives::block::{Block, Number as BlockNumber}; +use primitives::{AccountId, Hash, H256, TxOrder}; +use primitives::block::{Block, Header, Number as BlockNumber}; use primitives::transaction::UncheckedTransaction; use primitives::runtime_function::Function; use runtime::{staking, session}; +const NONCE_OF: &[u8] = b"sys:non:"; const BLOCK_HASH_AT: &[u8] = b"sys:old:"; const CODE: &[u8] = b"sys:cod"; @@ -45,7 +46,7 @@ pub mod privileged { /// Set the new code. pub fn set_code(new: &[u8]) { - storage::put_raw(CODE, new); + storage::unhashed::put_raw(b":code", new); } } @@ -55,11 +56,8 @@ pub mod internal { struct CheckedTransaction(UncheckedTransaction); /// Deposits a log and ensures it matches the blocks log data. - pub fn deposit_log(log: &[u8]) { - with_env(|e| { - assert_eq!(log, &e.digest.logs[e.next_log_index].0[..]); - e.next_log_index += 1; - }); + pub fn deposit_log(log: ::primitives::block::Log) { + with_env(|e| e.digest.logs.push(log)); } /// Actually execute all transitioning for `block`. @@ -67,8 +65,6 @@ pub mod internal { // populate environment from header. with_env(|e| { e.block_number = block.header.number; - mem::swap(&mut e.digest, &mut block.header.digest); - e.next_log_index = 0; }); let ref header = block.header; @@ -81,11 +77,15 @@ pub mod internal { // check transaction trie root represents the transactions. let txs = block.transactions.iter().map(Slicable::to_vec).collect::>(); - let txs_root = enumerated_trie_root(&txs.iter().map(Vec::as_slice).collect::>()); - assert!(header.transaction_root.0 == txs_root, "Transaction trie root must be valid."); + let txs = txs.iter().map(Vec::as_slice).collect::>(); + let txs_root = H256(enumerated_trie_root(&txs)); + debug_assert_hash(&header.transaction_root, &txs_root); + assert!(header.transaction_root == txs_root, "Transaction trie root must be valid."); // execute transactions - block.transactions.iter().cloned().for_each(execute_transaction); + for tx in &block.transactions { + super::execute_transaction(tx.clone()); + } staking::internal::check_new_era(); session::internal::check_rotate_session(); @@ -93,39 +93,50 @@ pub mod internal { // any final checks final_checks(&block); - // check storage root. - assert!(header.state_root.0 == storage_root(), "Storage root must match that calculated."); + let storage_root = H256(storage_root()); + debug_assert_hash(&header.state_root, &storage_root); + assert!(header.state_root == storage_root, "Storage root must match that calculated."); - // store the header hash in storage; we can't do it before otherwise there would be a - // cyclic dependency. - let header_hash_key = header.number.to_keyed_vec(BLOCK_HASH_AT); - storage::put(&header_hash_key, &header.blake2_256()); + // any stuff that we do after taking the storage root. + post_finalise(header); } - /// Execute a given transaction. - pub fn execute_transaction(utx: UncheckedTransaction) { - use runtime_std::transaction; + /// Execute a transaction outside of the block execution function. + /// This doesn't attempt to validate anything regarding the block. + pub fn execute_transaction(utx: UncheckedTransaction, mut header: Header) -> Header { + // populate environment from header. + with_env(|e| { + e.block_number = header.number; + mem::swap(&mut header.digest, &mut e.digest); + }); - // Verify the signature is good. - let tx = match transaction::check(utx) { - Ok(tx) => tx, - Err(_) => panic!("All transactions should be properly signed"), - }; + super::execute_transaction(utx); - // check nonce - let nonce_key = tx.signed.to_keyed_vec(b"sys:non:"); - let expected_nonce: TxOrder = storage::get_or_default(&nonce_key); - assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce"); - - // increment nonce in storage - storage::put(&nonce_key, &(expected_nonce + 1)); - - // decode parameters and dispatch - dispatch_function(&tx.function, &tx.signed); + with_env(|e| { + mem::swap(&mut header.digest, &mut e.digest); + }); + header } - fn dispatch_function(function: &Function, transactor: &AccountId) { + /// Finalise the block - it is up the caller to ensure that all header fields are valid + /// except state-root. + pub fn finalise_block(mut header: Header) -> Header { + staking::internal::check_new_era(); + session::internal::check_rotate_session(); + + header.state_root = H256(storage_root()); + with_env(|e| { + mem::swap(&mut header.digest, &mut e.digest); + }); + + post_finalise(&header); + + header + } + + /// Dispatch a function. + pub fn dispatch_function(function: &Function, transactor: &AccountId) { match *function { Function::StakingStake => { ::runtime::staking::public::stake(transactor); @@ -150,14 +161,52 @@ pub mod internal { } } } + + #[cfg(feature = "with-std")] + fn debug_assert_hash(given: &Hash, expected: &Hash) { + use support::HexDisplay; + if given != expected { + println!("Hash: given={}, expected={}", HexDisplay::from(given), HexDisplay::from(expected)); + } + } + + #[cfg(not(feature = "with-std"))] + fn debug_assert_hash(_given: &Hash, _expected: &Hash) {} +} + +fn execute_transaction(utx: UncheckedTransaction) { + use runtime_std::transaction; + + // Verify the signature is good. + let tx = match transaction::check(utx) { + Ok(tx) => tx, + Err(_) => panic!("All transactions should be properly signed"), + }; + + // check nonce + let nonce_key = tx.signed.to_keyed_vec(NONCE_OF); + let expected_nonce: TxOrder = storage::get_or(&nonce_key, 0); + assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce"); + + // increment nonce in storage + storage::put(&nonce_key, &(expected_nonce + 1)); + + // decode parameters and dispatch + internal::dispatch_function(&tx.function, &tx.signed); } fn final_checks(_block: &Block) { with_env(|e| { - assert_eq!(e.next_log_index, e.digest.logs.len()); + assert!(_block.header.digest == e.digest); }); } +fn post_finalise(header: &Header) { + // store the header hash in storage; we can't do it before otherwise there would be a + // cyclic dependency. + storage::put(&header.number.to_keyed_vec(BLOCK_HASH_AT), &header.blake2_256()); +} + #[cfg(test)] mod tests { use super::*; @@ -193,7 +242,7 @@ mod tests { // sig: b543b41e4b7a0270eddf57ed6c435df04bb63f71c79f6ae2530ab26c734bb4e8cd57b1c190c41d5791bcdea66a16c7339b1e883e5d0538ea2d9acea800d60a00 with_externalities(&mut t, || { - execute_transaction(tx); + internal::execute_transaction(tx, Header::from_block_number(1)); assert_eq!(staking::balance(&one), 42); assert_eq!(staking::balance(&two), 69); }); @@ -230,15 +279,6 @@ mod tests { let mut t = new_test_ext(); - let tx = UncheckedTransaction { - transaction: Transaction { - signed: one.clone(), - nonce: 0, - function: Function::StakingTransfer(two, 69), - }, - signature: "b543b41e4b7a0270eddf57ed6c435df04bb63f71c79f6ae2530ab26c734bb4e8cd57b1c190c41d5791bcdea66a16c7339b1e883e5d0538ea2d9acea800d60a00".parse().unwrap(), - }; - let h = Header { parent_hash: H256([69u8; 32]), number: 1, @@ -249,13 +289,11 @@ mod tests { let b = Block { header: h, - transactions: vec![tx], + transactions: vec![], }; with_externalities(&mut t, || { execute_block(b); - assert_eq!(staking::balance(&one), 42); - assert_eq!(staking::balance(&two), 69); }); } @@ -267,34 +305,47 @@ mod tests { let mut t = new_test_ext(); - let tx = UncheckedTransaction { - transaction: Transaction { - signed: one.clone(), - nonce: 0, - function: Function::StakingTransfer(two, 69), - }, - signature: "b543b41e4b7a0270eddf57ed6c435df04bb63f71c79f6ae2530ab26c734bb4e8cd57b1c190c41d5791bcdea66a16c7339b1e883e5d0538ea2d9acea800d60a00".parse().unwrap(), - }; - // tx: 2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000 - // sig: b543b41e4b7a0270eddf57ed6c435df04bb63f71c79f6ae2530ab26c734bb4e8cd57b1c190c41d5791bcdea66a16c7339b1e883e5d0538ea2d9acea800d60a00 - let h = Header { - parent_hash: H256([69u8; 32]), + parent_hash: [69u8; 32], number: 1, - state_root: H256([0u8; 32]), - transaction_root: H256([0u8; 32]), // Unchecked currently. + state_root: [0u8; 32], + transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), digest: Digest { logs: vec![], }, }; let b = Block { header: h, - transactions: vec![tx], + transactions: vec![], + }; + + with_externalities(&mut t, || { + execute_block(b); + }); + } + + #[test] + #[should_panic] + fn block_import_of_bad_transaction_root_fails() { + let one = one(); + let two = two(); + + let mut t = new_test_ext(); + + let h = Header { + parent_hash: H256([69u8; 32]), + number: 1, + state_root: H256(hex!("1ab2dbb7d4868a670b181327b0b6a58dc64b10cfb9876f737a5aa014b8da31e0")), + transaction_root: H256([0u8; 32]), + digest: Digest { logs: vec![], }, + }; + + let b = Block { + header: h, + transactions: vec![], }; with_externalities(&mut t, || { execute_block(b); - assert_eq!(staking::balance(&one), 42); - assert_eq!(staking::balance(&two), 69); }); } } diff --git a/substrate/wasm-runtime/polkadot/src/support/environment.rs b/substrate/wasm-runtime/polkadot/src/support/environment.rs index a41e0d37a6..eaae898f52 100644 --- a/substrate/wasm-runtime/polkadot/src/support/environment.rs +++ b/substrate/wasm-runtime/polkadot/src/support/environment.rs @@ -30,8 +30,6 @@ pub struct Environment { pub block_number: BlockNumber, /// The current block digest. pub digest: Digest, - /// The number of log items in this block that have been accounted for so far. - pub next_log_index: usize, } /// Do something with the environment and return its value. Keep the function short. diff --git a/substrate/wasm-runtime/polkadot/src/support/storage.rs b/substrate/wasm-runtime/polkadot/src/support/storage.rs index 5e6ab402b8..71c6a77e87 100644 --- a/substrate/wasm-runtime/polkadot/src/support/storage.rs +++ b/substrate/wasm-runtime/polkadot/src/support/storage.rs @@ -141,6 +141,129 @@ pub trait StorageVec { } } +pub mod unhashed { + use super::{runtime_std, Slicable, KeyedVec, Vec}; + + /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. + pub fn get(key: &[u8]) -> Option { + let raw = runtime_std::storage(key); + T::from_slice(&mut &raw[..]) + } + + /// Return the value of the item in storage under `key`, or the type's default if there is no + /// explicit entry. + pub fn get_or_default(key: &[u8]) -> T { + get(key).unwrap_or_else(Default::default) + } + + /// Return the value of the item in storage under `key`, or `default_value` if there is no + /// explicit entry. + pub fn get_or(key: &[u8], default_value: T) -> T { + get(key).unwrap_or(default_value) + } + + /// Return the value of the item in storage under `key`, or `default_value()` if there is no + /// explicit entry. + pub fn get_or_else T>(key: &[u8], default_value: F) -> T { + get(key).unwrap_or_else(default_value) + } + + /// Please `value` in storage under `key`. + pub fn put(key: &[u8], value: &T) { + value.as_slice_then(|slice| runtime_std::set_storage(key, slice)); + } + + /// Please `value` in storage under `key`. + pub fn place(key: &[u8], value: T) { + value.as_slice_then(|slice| runtime_std::set_storage(key, slice)); + } + + /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. + pub fn take(key: &[u8]) -> Option { + let r = get(key); + if r.is_some() { + kill(key); + } + r + } + + /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, + /// the default for its type. + pub fn take_or_default(key: &[u8]) -> T { + take(key).unwrap_or_else(Default::default) + } + + /// Return the value of the item in storage under `key`, or `default_value` if there is no + /// explicit entry. Ensure there is no explicit entry on return. + pub fn take_or(key: &[u8], default_value: T) -> T { + take(key).unwrap_or(default_value) + } + + /// Return the value of the item in storage under `key`, or `default_value()` if there is no + /// explicit entry. Ensure there is no explicit entry on return. + pub fn take_or_else T>(key: &[u8], default_value: F) -> T { + take(key).unwrap_or_else(default_value) + } + + /// Check to see if `key` has an explicit entry in storage. + pub fn exists(key: &[u8]) -> bool { + let mut x = [0u8; 1]; + runtime_std::read_storage(key, &mut x[..], 0) >= 1 + } + + /// Ensure `key` has no explicit entry in storage. + pub fn kill(key: &[u8]) { + runtime_std::set_storage(key, b""); + } + + /// Get a Vec of bytes from storage. + pub fn get_raw(key: &[u8]) -> Vec { + runtime_std::storage(key) + } + + /// Put a raw byte slice into storage. + pub fn put_raw(key: &[u8], value: &[u8]) { + runtime_std::set_storage(key, value) + } + + /// A trait to conveniently store a vector of storable data. + // TODO: add iterator support + pub trait StorageVec { + type Item: Default + Sized + Slicable; + const PREFIX: &'static [u8]; + + /// Get the current set of items. + fn items() -> Vec { + (0..Self::count()).into_iter().map(Self::item).collect() + } + + /// Set the current set of items. + fn set_items(items: &[Self::Item]) { + Self::set_count(items.len() as u32); + items.iter().enumerate().for_each(|(v, ref i)| Self::set_item(v as u32, i)); + } + + fn set_item(index: u32, item: &Self::Item) { + if index < Self::count() { + put(&index.to_keyed_vec(Self::PREFIX), item); + } + } + + fn item(index: u32) -> Self::Item { + get_or_default(&index.to_keyed_vec(Self::PREFIX)) + } + + fn set_count(count: u32) { + (count..Self::count()).for_each(|i| Self::set_item(i, &Self::Item::default())); + put(&b"len".to_keyed_vec(Self::PREFIX), &count); + } + + fn count() -> u32 { + get_or_default(&b"len".to_keyed_vec(Self::PREFIX)) + } + } +} + #[cfg(test)] mod tests { use super::*;