diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 7024d67425..7dfdee6590 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -21,6 +21,15 @@ name = "ansi_term" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "arrayvec" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "assert_matches" version = "1.1.0" @@ -60,6 +69,18 @@ dependencies = [ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bigint" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.1 (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)", +] + [[package]] name = "bitflags" version = "0.7.0" @@ -124,6 +145,14 @@ name = "dtoa" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "elastic-array" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "env_logger" version = "0.4.3" @@ -141,6 +170,40 @@ dependencies = [ "backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ethcore-bigint" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (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.18 (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 = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ethcore-logger" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "isatty 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fixed-hash" version = "0.1.0" @@ -167,11 +230,48 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hashdb" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "heapsize" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "isatty" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "keccak-hash" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -204,11 +304,90 @@ dependencies = [ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "memorydb" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nodrop" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "num-traits" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "odds" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "owning_ref" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "patricia-trie" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-logger 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (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.18 (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)", +] + +[[package]] +name = "plain_hasher" +version = "0.1.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)", +] + [[package]] name = "polkadot" version = "0.1.0" @@ -265,7 +444,12 @@ dependencies = [ name = "polkadot-state-machine" version = "0.1.0" dependencies = [ + "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", + "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -321,6 +505,18 @@ name = "regex-syntax" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rlp" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.9 (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 = "rustc-demangle" version = "0.1.5" @@ -387,6 +583,16 @@ dependencies = [ "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "smallvec" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "stable_deref_trait" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "strsim" version = "0.6.0" @@ -437,11 +643,32 @@ dependencies = [ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "time" +version = "0.1.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tiny-keccak" version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "triehash" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "uint" version = "0.1.0" @@ -503,10 +730,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" +"checksum arrayvec 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e003cbf6e0e1c43a0fc8df2ea8ea24174514d35cbcf60c35ca6112e0139f65e2" "checksum assert_matches 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e772942dccdf11b368c31e044e4fca9189f80a773d2f0808379de65894cbf57" "checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" "checksum backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99f2ce94e22b8e664d95c57fff45b98a966c2252b60691d0b7aeeccd88d70983" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" +"checksum bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5442186ef6560f30f1ee4b9c1e4c87a35a6879d3644550cc248ec2b955eb5fcd" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" @@ -517,18 +746,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" +"checksum elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258ff6a9a94f648d0379dbd79110e057edbb53eb85cc237e33eadf8e5a30df85" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" +"checksum ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb5af77e74a8f70e9c3337e069c37bc82178ef1b459c02091f73c4ad5281eb5" +"checksum ethcore-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3977c772cd6c5c22e1c7cfa208e4c3b746bd6c3a6c8eeec0999a6b2103015ad5" +"checksum ethcore-logger 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fd5813e49546030be7d134e775088d56b8ff4ab60617b90e93d4f0513da4c5b" "checksum fixed-hash 0.1.0 (git+https://github.com/paritytech/primitives.git)" = "" "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" "checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" +"checksum hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d97be07c358c5b461268b4ce60304024c5fa5acfd4bd8cd743639f0252003cf5" +"checksum heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "54fab2624374e5137ae4df13bf32b0b269cb804df42d13a51221bbd431d1a237" +"checksum isatty 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "00c9301a947a2eaee7ce2556b80285dcc89558d07088962e6e8b9c25730f9dc6" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" +"checksum keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f300c1f149cd9ca5214eed24f6e713a597517420fb8b15499824aa916259ec1" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9e5e58fa1a4c3b915a561a78a22ee0cac6ab97dca2504428bc1cb074375f8d5" "checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2" "checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" +"checksum memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "013b7e4c5e10c764936ebc6bd3662d8e3c92292d267bf6a42ef3f5cad9c793ee" +"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0" +"checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba" +"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" +"checksum parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f610cb9664da38e417ea3225f23051f589851999535290e077939838ab7a595" +"checksum patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2f638d79aba5c4a71a4f373df6e3cd702250a53b7f0ed4da1e2a7be9737ae" +"checksum plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83ae80873992f511142c07d0ec6c44de5636628fdb7e204abd655932ea79d995" "checksum pretty_assertions 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94b6bbc8a323d89a019c4cdde21850522fb8405e97add70827177fc2f86c1495" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" @@ -536,6 +781,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" +"checksum rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "babe6fce20c0ca9b1582998734c4569082d0ad08e43772a1c6c40aef4f106ef9" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" "checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69" @@ -545,13 +791,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3bdafe3e71710131a919735916caa5b18c2754ad0d33d8ae5d586ccc804a403e" "checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab" "checksum serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e4586746d1974a030c48919731ecffd0ed28d0c40749d0d18d43b3a7d6c9b20e" +"checksum smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4f357e8cd37bf8822e1b964e96fd39e2cb5a0424f8aaa284ccaccc2162411c" +"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 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" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" "checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" +"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" "checksum tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52d12ad79e4063e0cb0ca5efa202ed7244b6ce4d25f4d3abe410b2a66128292" +"checksum triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9291c7f0fae44858b5e087dd462afb382354120003778f1695b44aab98c7abd7" "checksum uint 0.1.0 (git+https://github.com/paritytech/primitives.git)" = "" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" diff --git a/substrate/contracts/src/auth.rs b/substrate/contracts/src/auth.rs index 641290c6c9..a244526ddd 100644 --- a/substrate/contracts/src/auth.rs +++ b/substrate/contracts/src/auth.rs @@ -15,7 +15,7 @@ // along with Polkadot. If not, see . use primitives::Address; -use state_machine::Externalities; +use state_machine::StaticExternalities; use error::Result; use executor::RustExecutor; @@ -32,7 +32,7 @@ impl Contract { /// Given Message and Authentication Data verifies it and returns: /// 1. None in case it doesn't match (i.e. signature is invalid) /// 2. A address who signed that Message. - pub fn check_auth>(&self, _ext: &E, _data: DataAndAuth) -> Result> { + pub fn check_auth>(&self, _ext: &E, _data: DataAndAuth) -> Result> { unimplemented!() } } diff --git a/substrate/contracts/src/balances.rs b/substrate/contracts/src/balances.rs index c93999c24a..d5e3fd6b66 100644 --- a/substrate/contracts/src/balances.rs +++ b/substrate/contracts/src/balances.rs @@ -16,7 +16,7 @@ use primitives::Address; use primitives::uint::U256; -use state_machine::Externalities; +use state_machine::{Externalities, StaticExternalities}; use error::Result; use executor::RustExecutor; @@ -38,12 +38,12 @@ pub struct Transfer { pub struct Contract; impl Contract { /// Returns a balance of given address. - pub fn balance_of>(&self, _ext: &E, _data: Address) -> Result { + pub fn balance_of>(&self, _ext: &E, _data: Address) -> Result { unimplemented!() } /// Returns the next nonce to authorize the transfer from given address. - pub fn next_nonce>(&self, _ext: &E, _data: Address) -> Result { + pub fn next_nonce>(&self, _ext: &E, _data: Address) -> Result { unimplemented!() } @@ -52,7 +52,7 @@ impl Contract { /// - signature /// - replay protection /// - enough balance - pub fn transfer_preconditions>(&self, _db: &E, _data: Transfer) -> Result { + pub fn transfer_preconditions>(&self, _db: &E, _data: Transfer) -> Result { unimplemented!() } diff --git a/substrate/contracts/src/error.rs b/substrate/contracts/src/error.rs index a792ba6378..6280953e45 100644 --- a/substrate/contracts/src/error.rs +++ b/substrate/contracts/src/error.rs @@ -46,5 +46,3 @@ error_chain! { } } } - -impl state_machine::Error for Error {} diff --git a/substrate/contracts/src/executor.rs b/substrate/contracts/src/executor.rs index 819bc37350..ec617cfb54 100644 --- a/substrate/contracts/src/executor.rs +++ b/substrate/contracts/src/executor.rs @@ -18,7 +18,7 @@ use primitives::contract::{CallData, OutData}; use serializer::{from_slice as de, to_vec as ser}; -use state_machine::{Externalities, Executor}; +use state_machine::{StaticExternalities, Externalities, Executor}; use error::{Error, ErrorKind, Result}; use auth; @@ -45,7 +45,7 @@ impl RustExecutor { impl Executor for RustExecutor { type Error = Error; - fn static_call>( + fn call_static>( &self, ext: &E, code: &[u8], @@ -95,11 +95,31 @@ impl Executor for RustExecutor { #[cfg(test)] mod tests { use super::*; + use primitives::Address; + use primitives::hash::H256; #[derive(Debug, Default)] struct TestExternalities; impl Externalities for TestExternalities { + fn set_storage(&mut self, _key: H256, _value: Vec) { + unimplemented!() + } + + fn call(&mut self, _address: &Address, _method: &str, _data: &CallData) -> Result { + unimplemented!() + } + } + + impl StaticExternalities for TestExternalities { type Error = Error; + + fn storage(&self, _key: &H256) -> Result<&[u8]> { + unimplemented!() + } + + fn call_static(&self, _address: &Address, _method: &str, _data: &CallData) -> Result { + unimplemented!() + } } #[test] diff --git a/substrate/contracts/src/validator_set.rs b/substrate/contracts/src/validator_set.rs index b495ac7588..7462781c6b 100644 --- a/substrate/contracts/src/validator_set.rs +++ b/substrate/contracts/src/validator_set.rs @@ -15,7 +15,7 @@ // along with Polkadot. If not, see . use primitives::Address; -use state_machine::Externalities; +use state_machine::StaticExternalities; use error::Result; use executor::RustExecutor; @@ -25,7 +25,7 @@ use executor::RustExecutor; pub struct Contract; impl Contract { /// Returns current validator set. - pub fn validator_set>(&self, _db: &E, _data: ()) -> Result> { + pub fn validator_set>(&self, _db: &E, _data: ()) -> Result> { unimplemented!() } } diff --git a/substrate/state_machine/Cargo.toml b/substrate/state_machine/Cargo.toml index f7ccdc93b4..cdcec9d6a0 100644 --- a/substrate/state_machine/Cargo.toml +++ b/substrate/state_machine/Cargo.toml @@ -1,7 +1,13 @@ [package] name = "polkadot-state-machine" version = "0.1.0" -authors = ["Parity Team "] +authors = ["Parity Technologies "] +description = "Polkadot State Machine" [dependencies] -polkadot-primitives = { path = "../primitives", version = "0.1" } +polkadot-primitives = { path = "../primitives", version = "0.1.0" } +hashdb = "0.1.1" +keccak-hash = "0.1.0" +patricia-trie = "0.1.0" +memorydb = "0.1.1" +triehash = "0.1" diff --git a/substrate/state_machine/src/backend.rs b/substrate/state_machine/src/backend.rs new file mode 100644 index 0000000000..f513ed2451 --- /dev/null +++ b/substrate/state_machine/src/backend.rs @@ -0,0 +1,108 @@ +// 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 . + +//! State machine backends. These manage the code and storage of contracts. + +use std::fmt; + +use primitives::Address; +use primitives::hash::H256; +use triehash::sec_trie_root; + +use super::{Update, MemoryState}; + +/// Output of a commit. +pub struct Committed { + /// Root of the code tree after changes committed. + pub code_tree_root: H256, + /// Root of the storage tree after changes committed. + pub storage_tree_root: H256, +} + +/// A state backend is used to read state data and can have changes committed +/// to it. +pub trait Backend { + /// An error type when fetching data is not possible. + type Error: super::Error; + + /// Get code associated with specific address. + fn code(&self, address: &Address) -> Result<&[u8], Self::Error>; + + /// Get keyed storage associated with specific address. + fn storage(&self, address: &Address, key: &H256) -> Result<&[u8], Self::Error>; + + /// Commit updates to the backend and get new state. + fn commit(&mut self, changes: I) -> Committed + where I: IntoIterator; +} + +/// Error impossible. +// TODO: use `!` type when stabilized. +#[derive(Debug)] +pub enum Void {} + +impl fmt::Display for Void { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + match *self {} + } +} + +/// In-memory backend. Fully recomputes tries on each commit but useful for +/// tests. +#[derive(Default)] +pub struct InMemory { + inner: MemoryState, // keeps all the state in memory. +} + +impl Backend for InMemory { + type Error = Void; + + fn code(&self, address: &Address) -> Result<&[u8], Void> { + Ok(self.inner.code(address).unwrap_or(&[])) + } + + fn storage(&self, address: &Address, key: &H256) -> Result<&[u8], Void> { + Ok(self.inner.storage(address, key).unwrap_or(&[])) + } + + fn commit(&mut self, changes: I) -> Committed + where I: IntoIterator + { + self.inner.update(changes); + + // fully recalculate trie roots. + + let storage_roots = self.inner.storage.iter().map(|(addr, storage)| { + let flat_trie = storage.iter().map(|(k, v)| (k.to_vec(), v.clone())).collect(); + (addr.to_vec(), sec_trie_root(flat_trie).to_vec()) + }).collect(); + + let storage_tree_root = H256(sec_trie_root(storage_roots).0); + + let code_tree_root = sec_trie_root( + self.inner.code.iter().map(|(k, v)| (k.to_vec(), v.clone())).collect() + ); + + let code_tree_root = H256(code_tree_root.0); + + Committed { + code_tree_root, + storage_tree_root, + } + } +} + +// TODO: DB-based backend diff --git a/substrate/state_machine/src/ext.rs b/substrate/state_machine/src/ext.rs new file mode 100644 index 0000000000..1820e6a091 --- /dev/null +++ b/substrate/state_machine/src/ext.rs @@ -0,0 +1,164 @@ +// 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 . + +//! Conrete externalities implementation. + +use std::fmt; + +use backend::Backend; +use primitives::Address; +use primitives::contract::{CallData, OutData}; +use primitives::hash::H256; +use {Externalities, Executor, StaticExternalities, OverlayedChanges}; + +/// Errors that can occur when interacting with the externalities. +#[derive(Debug, Copy, Clone)] +pub enum Error { + /// Failure to load state data from the backend. + Backend(B), + /// Failure to execute a function. + Executor(E), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Error::Backend(ref e) => write!(f, "Storage backend error: {}", e), + Error::Executor(ref e) => write!(f, "Sub-call execution error: {}", e), + } + } +} + +/// Wraps a read-only backend, call executor, and current overlayed changes. +pub struct Ext<'a, B: 'a, E: 'a> { + /// The overlayed changes to write to. + pub overlay: &'a mut OverlayedChanges, + /// The storage backend to read from. + pub backend: &'a B, + /// Contract code executor. + pub exec: &'a E, + /// Contract address. + pub local: Address, +} + +impl<'a, B: 'a, E: 'a> StaticExternalities for Ext<'a, B, E> + where B: Backend, E: Executor +{ + type Error = Error; + + fn storage(&self, key: &H256) -> Result<&[u8], Self::Error> { + match self.overlay.storage(&self.local, key) { + Some(x) => Ok(x), + None => self.backend.storage(&self.local, key).map_err(Error::Backend) + } + } + + fn call_static(&self, address: &Address, method: &str, data: &CallData) -> Result { + let inner_ext = StaticExt { + backend: self.backend, + exec: self.exec, + local: address.clone(), + overlay: self.overlay, + }; + + let code = match self.overlay.code(address) { + Some(x) => x, + None => self.backend.code(address).map_err(Error::Backend)?, + }; + + self.exec.call_static( + &inner_ext, + code, + method, + data, + ).map_err(Error::Executor) + } +} + +impl<'a, B: 'a, E: 'a> Externalities for Ext<'a, B, E> + where B: Backend, E: Executor +{ + fn set_storage(&mut self, key: H256, value: Vec) { + self.overlay.set_storage(self.local, key, value); + } + + fn call(&mut self, address: &Address, method: &str, data: &CallData) -> Result { + let code = { + let code = match self.overlay.code(address) { + Some(x) => x, + None => self.backend.code(address).map_err(Error::Backend)?, + }; + + code.to_owned() + }; + + let mut inner_ext = Ext { + backend: self.backend, + exec: self.exec, + local: address.clone(), + overlay: &mut *self.overlay, + }; + + self.exec.call( + &mut inner_ext, + &code[..], + method, + data, + ).map_err(Error::Executor) + } +} + +// Static externalities +struct StaticExt<'a, B: 'a, E: 'a> { + overlay: &'a OverlayedChanges, + backend: &'a B, + exec: &'a E, + local: Address, +} + +impl<'a, B: 'a, E: 'a> StaticExternalities for StaticExt<'a, B, E> + where B: Backend, E: Executor +{ + type Error = Error; + + fn storage(&self, key: &H256) -> Result<&[u8], Self::Error> { + match self.overlay.storage(&self.local, key) { + Some(x) => Ok(x), + None => self.backend.storage(&self.local, key).map_err(Error::Backend) + } + } + + fn call_static(&self, address: &Address, method: &str, data: &CallData) -> Result { + let inner_ext = StaticExt { + backend: self.backend, + exec: self.exec, + local: address.clone(), + overlay: self.overlay, + }; + + let code = match self.overlay.code(address) { + Some(x) => x, + None => self.backend.code(address).map_err(Error::Backend)?, + }; + + self.exec.call_static( + &inner_ext, + code, + method, + data, + ).map_err(Error::Executor) + } +} diff --git a/substrate/state_machine/src/lib.rs b/substrate/state_machine/src/lib.rs index e6ac3df345..a97861170f 100644 --- a/substrate/state_machine/src/lib.rs +++ b/substrate/state_machine/src/lib.rs @@ -14,25 +14,182 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Polkadot state machine +//! Polkadot state machine implementation. #![warn(missing_docs)] extern crate polkadot_primitives as primitives; +extern crate hashdb; +extern crate memorydb; +extern crate keccak_hash; + +extern crate patricia_trie; +extern crate triehash; + +use std::collections::HashMap; use std::fmt; +use primitives::Address; use primitives::contract::{CallData, OutData}; +use primitives::hash::H256; + +pub mod backend; +mod ext; + +/// Updates to be committed to the state. +pub enum Update { + /// Set storage of address at given key -- empty is deletion. + Storage(Address, H256, Vec), + /// Set code of address -- empty is deletion. + Code(Address, Vec), +} + +// in-memory section of the state. +#[derive(Default)] +struct MemoryState { + code: HashMap>, + storage: HashMap>>, +} + +impl MemoryState { + fn code(&self, address: &Address) -> Option<&[u8]> { + self.code.get(address).map(|v| &v[..]) + } + + fn storage(&self, address: &Address, key: &H256) -> Option<&[u8]> { + self.storage.get(address) + .and_then(|m| m.get(key)) + .map(|v| &v[..]) + } + + #[allow(unused)] + fn set_code(&mut self, address: Address, code: Vec) { + self.code.insert(address, code); + } + + fn set_storage(&mut self, address: Address, key: H256, val: Vec) { + self.storage.entry(address) + .or_insert_with(HashMap::new) + .insert(key, val); + } + + fn update(&mut self, changes: I) where I: IntoIterator { + for update in changes { + match update { + Update::Storage(addr, key, val) => { + if val.is_empty() { + let mut empty = false; + if let Some(s) = self.storage.get_mut(&addr) { + s.remove(&key); + empty = s.is_empty(); + }; + + if empty { self.storage.remove(&addr); } + } else { + self.storage.entry(addr) + .or_insert_with(HashMap::new) + .insert(key, val); + } + } + Update::Code(addr, code) => { + if code.is_empty() { + self.code.remove(&addr); + } else { + self.code.insert(addr, code); + } + } + } + } + } +} + +/// The overlayed changes to state to be queried on top of the backend. +/// +/// A transaction shares all prospective changes within an inner overlay +/// that can be cleared. +#[derive(Default)] +pub struct OverlayedChanges { + prospective: MemoryState, + committed: MemoryState, +} + +impl OverlayedChanges { + fn code(&self, address: &Address) -> Option<&[u8]> { + self.prospective.code(address) + .or_else(|| self.committed.code(address)) + .and_then(|v| if v.is_empty() { None } else { Some(v) }) + } + + fn storage(&self, address: &Address, key: &H256) -> Option<&[u8]> { + self.prospective.storage(address, key) + .or_else(|| self.committed.storage(address, key)) + .and_then(|v| if v.is_empty() { None } else { Some(v) }) + } + + #[allow(unused)] + fn set_code(&mut self, address: Address, code: Vec) { + self.prospective.set_code(address, code); + } + + fn set_storage(&mut self, address: Address, key: H256, val: Vec) { + self.prospective.set_storage(address, key, val); + } + + /// Discard prospective changes to state. + pub fn discard_prospective(&mut self) { + self.prospective.code.clear(); + self.prospective.storage.clear(); + } + + /// Commit prospective changes to state. + pub fn commit_prospective(&mut self) { + let code_updates = self.prospective.code.drain() + .map(|(addr, code)| Update::Code(addr, code)); + + let storage_updates = self.prospective.storage.drain() + .flat_map(|(addr, storages)| storages.into_iter().map(move |(k, v)| (addr, k, v))) + .map(|(addr, key, value)| Update::Storage(addr, key, value)); + + self.committed.update(code_updates.chain(storage_updates)); + } +} /// State Machine Error bound. /// /// This should reflect WASM error type bound for future compatibility. pub trait Error: 'static + fmt::Debug + fmt::Display + Send {} +impl Error for E where E: 'static + fmt::Debug + fmt::Display + Send {} -/// Externalities -pub trait Externalities { +/// Externalities: pinned to specific active address. +pub trait Externalities: StaticExternalities { + /// Read storage of current contract being called. + fn storage(&self, key: &H256) -> Result<&[u8], Self::Error> { + StaticExternalities::storage(self, key) + } + + /// Set storage of current contract being called. + fn set_storage(&mut self, key: H256, value: Vec); + + /// Make a sub-call to another contract. + fn call(&mut self, address: &Address, method: &str, data: &CallData) -> Result; + + /// Make a static (read-only) call to another contract. + fn call_static(&self, address: &Address, method: &str, data: &CallData) -> Result { + StaticExternalities::call_static(self, address, method, data) + } +} + +/// Static externalities: used only for read-only requests. +pub trait StaticExternalities { /// Externalities error type. type Error: Error; + + /// Read storage of current contract being called. + fn storage(&self, key: &H256) -> Result<&[u8], Self::Error>; + + /// Make a static (read-only) call to another contract. + fn call_static(&self, address: &Address, method: &str, data: &CallData) -> Result; } /// Contract code executor. @@ -42,7 +199,7 @@ pub trait Executor: Sized { /// Execute a contract in read-only mode. /// The execution is not allowed to modify the state. - fn static_call>( + fn call_static>( &self, ext: &E, code: &[u8], @@ -59,3 +216,106 @@ pub trait Executor: Sized { data: &CallData, ) -> Result; } + +/// Execute a call using the given state backend, overlayed changes, and call executor. +/// +/// On an error, no prospective changes are written to the overlay. +pub fn execute( + backend: &B, + overlay: &mut OverlayedChanges, + exec: &Exec, + address: &Address, + method: &str, + call_data: &CallData, +) -> Result> { + let code = match overlay.code(address) { + Some(x) => x.to_owned(), + None => backend.code(address).map_err(|e| Box::new(e) as _)?.to_owned(), + }; + + let result = { + let mut externalities = ext::Ext { + backend, + exec, + overlay: &mut *overlay, + local: *address, + }; + + exec.call( + &mut externalities, + &code[..], + method, + call_data, + ) + }; + + match result { + Ok(out) => { + overlay.commit_prospective(); + Ok(out) + } + Err(e) => { + overlay.discard_prospective(); + Err(Box::new(e)) + } + } +} + +#[cfg(test)] +mod tests { + use super::OverlayedChanges; + + use primitives::hash::H256; + use primitives::Address; + + #[test] + fn overlayed_storage_works() { + let mut overlayed = OverlayedChanges::default(); + + let key = H256::random(); + let addr = Address::random(); + + assert!(overlayed.storage(&addr, &key).is_none()); + + overlayed.set_storage(addr, key, vec![1, 2, 3]); + assert_eq!(overlayed.storage(&addr, &key).unwrap(), &[1, 2, 3]); + + overlayed.commit_prospective(); + assert_eq!(overlayed.storage(&addr, &key).unwrap(), &[1, 2, 3]); + + overlayed.set_storage(addr, key, vec![]); + assert!(overlayed.storage(&addr, &key).is_none()); + + overlayed.discard_prospective(); + assert_eq!(overlayed.storage(&addr, &key).unwrap(), &[1, 2, 3]); + + overlayed.set_storage(addr, key, vec![]); + overlayed.commit_prospective(); + assert!(overlayed.storage(&addr, &key).is_none()); + } + + #[test] + fn overlayed_code_works() { + let mut overlayed = OverlayedChanges::default(); + + let addr = Address::random(); + + assert!(overlayed.code(&addr).is_none()); + + overlayed.set_code(addr, vec![1, 2, 3]); + assert_eq!(overlayed.code(&addr).unwrap(), &[1, 2, 3]); + + overlayed.commit_prospective(); + assert_eq!(overlayed.code(&addr).unwrap(), &[1, 2, 3]); + + overlayed.set_code(addr, vec![]); + assert!(overlayed.code(&addr).is_none()); + + overlayed.discard_prospective(); + assert_eq!(overlayed.code(&addr).unwrap(), &[1, 2, 3]); + + overlayed.set_code(addr, vec![]); + overlayed.commit_prospective(); + assert!(overlayed.code(&addr).is_none()); + } +}